Converter-Plugin
Dokumente in 24 Zielformate konvertieren
Das Converter-Plugin verwandelt Doconut in einen Dokumentkonvertierungsdienst. Es stellt die Engine hinter der öffentlichen DocumentConverter‑Fassade bereit und – optional – ein Drop‑in‑Widget, das von DocImage.axd bereitgestellt wird, sodass Sie Dokumente aus C#, aus dem Widget oder aus einem Frontend, das Sie selbst schreiben, konvertieren können.
Paket installieren
Install-Package Doconut.NETFramework.ConverterHalten Sie das Converter‑Paket in derselben Version wie Doconut.NETFramework.
Plugin registrieren
Jedes Plugin wird auf dieselbe Weise registriert: AddPlugin<TPlugin>() in DoconutHost.Initialize.
Doconut.DoconutHost.Initialize(options =>
{
options.LicensePath = HostingEnvironment.MapPath("~/wwwroot/Doconut.Viewer.lic");
options.AddPlugin<Doconut.Plugins.Converter.ConverterPlugin>();
});Wenn keine aktive Lizenz die
Converter‑Fähigkeit gewährt — keine Lizenz, eine alteTRIAL‑Datei oder eine Lizenz ohne diese — wirftDoconutHost.InitializebeimApplication_Starteine Ausnahme. In System.Web bedeutet das, dass jede Anforderung einen leeren500zurückgibt und die Ursache nur im Windows‑Ereignisprotokoll (Quelle ASP.NET) zu finden ist. Temporäre Demo‑/NFR‑Lizenzen werden akzeptiert. Siehe Lizenzsetup.
Konvertierung aus C#
Jede Konvertierung liefert einen seek‑fähigen MemoryStream, der bei 0 positioniert ist. DocumentConverter ist zustandslos: Lösen Sie ihn aus DoconutHost.Services auf, wo immer Sie ihn benötigen, und verwenden Sie ihn wiederholt.
// Löst DocumentConverter aus DoconutHost.Services auf; sein Konstruktor ist intern, daher niemals `new` verwenden.
Stream pdf = await converter.ConvertAsync("contract.docx", ConversionTarget.Pdf, ct: ct);// sourceExtension enthält den führenden Punkt. password ist null, sofern das Dokument nicht geschützt ist.
Stream png = await converter.ConvertAsync(upload, ".xlsx", ConversionTarget.Png, password: null, ct: ct);Stream html = await converter.WordToHtmlAsync("report.docx", ct);Stream docx = await converter.HtmlToWordAsync(html, ConversionTarget.Docx, ct);Zwei Details, die leicht zu übersehen sind: sourceExtension bei der Stream‑Überladung muss den führenden Punkt enthalten (".xlsx", nicht "xlsx"), sonst wird sie nicht aufgelöst. Und trotz ihres Namens gibt WordToHtmlAsync ein Task<Stream> zurück, nicht ein Task<string> — das HTML‑Dokument (Bilder eingebettet als Base64) kommt als Stream, wie jedes andere Ergebnis.
In einem MVC‑5‑Controller
Machen Sie die Aktion asynchron und await‑en Sie die Konvertierung:
[HttpPost]
public async Task<ActionResult> ToPdf(HttpPostedFileBase file)
{
var converter = Doconut.DoconutHost.Services.GetRequiredService<DocumentConverter>();
Stream pdf = await converter.ConvertAsync(
file.InputStream, Path.GetExtension(file.FileName), ConversionTarget.Pdf,
password: null, ct: Response.ClientDisconnectedToken);
return File(pdf, "application/pdf", Path.GetFileNameWithoutExtension(file.FileName) + ".pdf");
}In Web Forms: Nie bei einer Konvertierung blockieren
Eine Web‑Forms‑Seite läuft in einem single‑threaded Request‑Context. ConvertAsync setzt die Ausführung in diesem Kontext fort, wenn sie fertig ist, sodass eine Seite, die synchron darauf wartet — .Result, .Wait(), .GetAwaiter().GetResult() — den einzigen Thread blockiert, den die Konvertierung zum Abschluss benötigt. Die Anforderung kehrt nie zurück. Der Browser dreht sich weiter, IIS protokolliert nichts und der Rest der Site funktioniert weiter, sodass es wie eine langsame Konvertierung und nicht wie ein Deadlock aussieht.
Markieren Sie die Seite mit Async="true" und führen Sie die Konvertierung als asynchronen Seiten‑Task aus:
<%@ Page Language="C#" Async="true" CodeBehind="Convert.aspx.cs" Inherits="MyApp.Convert" %>// Web Forms: Die @Page-Direktive benötigt Async="true" und die Konvertierung läuft als asynchroner Seiten-Task.
// Das Blockieren darauf (.Result, .Wait(), .GetAwaiter().GetResult()) führt zu einem Deadlock der Anforderung:
// sie kehrt nie zurück und es wird nichts protokolliert.
protected void Page_Load(object sender, EventArgs e)
{
if (!IsPostBack) return;
RegisterAsyncTask(new PageAsyncTask(async ct =>
{
var converter = Doconut.DoconutHost.Services.GetRequiredService<DocumentConverter>();
using (var pdf = await converter.ConvertAsync(
Server.MapPath("~/App_Data/contract.docx"), ConversionTarget.Pdf, ct: ct))
using (var ms = new MemoryStream())
{
if (pdf.CanSeek) pdf.Position = 0;
await pdf.CopyToAsync(ms);
Response.ContentType = "application/pdf";
Response.AddHeader("Content-Disposition", "attachment; filename=contract.pdf");
Response.BinaryWrite(ms.ToArray());
// Context, nicht HttpContext.Current: nach einem await kann Letzteres null sein.
Context.ApplicationInstance.CompleteRequest();
}
}));
}Ohne Async="true" in der @Page‑Direktive wird RegisterAsyncTask stillschweigend ignoriert. Nach einem await verwenden Sie das Context der Seite; HttpContext.Current kann dort null sein.
Zielformate
Pdf, Docx, Doc, Html, Xlsx, Pptx, Png, Jpeg, Csv, Tiff, Bmp, Gif, Svg, Xml,
Txt, Xls, Jp2, Rtf, Odt, Ods, Odp, Epub, Xps, WebpNicht jede Quelle lässt sich in jedes Ziel konvertieren: jede Formatfamilie der Quelle (Word, Excel, PowerPoint, PDF, CAD, Bild, E‑Mail, Diagramm, Projekt, PSD, Webdokument) hat ihr eigenes Set zulässiger Ziele. Kodieren Sie diese Aufzählung nicht fest in die Ziel‑Liste Ihrer Benutzeroberfläche: ?convert=open liefert die allowedTargets für die hochgeladene Datei, und diese sollten die Auswahl steuern.
Drop‑in‑Widget
Die Endpunkte des Widgets ?convert=open|run|download werden von DocImage.axd bereitgestellt und sind standardmäßig deaktiviert. Aktivieren Sie sie neben der Plugin‑Registrierung:
Doconut.DoconutHost.Initialize(options =>
{
options.LicensePath = HostingEnvironment.MapPath("~/wwwroot/Doconut.Viewer.lic");
options.AddPlugin<Doconut.Plugins.Converter.ConverterPlugin>();
options.AddConverterWidget(widget =>
{
widget.MaxUploadMb = 25;
});
});
// System.Web liest den gesamten Upload, bevor Doconut ihn sieht: Behalten Sie maxRequestLength (KB) und
// maxAllowedContentLength (Bytes) in Web.config über dem MaxUploadMb des Widgets bei.<div id="doconut-convert"></div>
<script src="/doconut-res/js/doconutConverter.js"></script>
<script>
Doconut.convert('#doconut-convert', { basePath: '/DocImage.axd', maxUploadMb: 25 });
</script>Zwei Dinge, die Sie prüfen sollten, wenn das Widget nicht korrekt funktioniert:
basePath: '/DocImage.axd'. Der Standardwert des Widgets,/doconut, ist der ASP.NET‑Core‑Endpunkt. In diesem Paket sind die Endpunkte derDocImage.axd‑Handler ausWeb.config.- Das Skript und die Endpunkte sind unabhängig. Das Ressourcenmodul liefert
doconutConverter.js, unabhängig davon, ob das Widget aktiviert ist. OhneAddConverterWidget()wird das Widget geladen, zeichnet seine Drop‑Zone und sieht völlig korrekt aus – und seine erste Aktion liefert404.
Upload‑Grenzen
ASP.NET liest den gesamten Anforderungstext, bevor DocImage.axd ausgeführt wird. Ein Upload, der MaxUploadMb überschreitet, aber unter den Host‑Grenzen liegt, führt zu dem eigenen JSON‑Fehler 413 („Datei ist zu groß.“) des Widgets. Ein Upload, der die Host‑Grenzen überschreitet, wird zuerst von IIS abgelehnt, mit einer Fehlermeldungsseite, die das Widget nicht lesen kann. Halten Sie beide Host‑Grenzen in Web.config über dem Limit des Widgets fest:
<system.web>
<httpRuntime maxRequestLength="30720" /> <!-- KILOBYTES: 30 MB -->
</system.web>
<system.webServer>
<security>
<requestFiltering>
<requestLimits maxAllowedContentLength="31457280" /> <!-- BYTES: 30 MB -->
</requestFiltering>
</security>
</system.webServer>Widget anpassen
Optionen, die an Doconut.convert(selector, options) übergeben werden:
| Option | Typ | Standard | Hinweise |
|---|---|---|---|
basePath | string | /doconut | Die URL des Endpunkts. Setzen Sie '/DocImage.axd' in diesem Paket |
resPath | string | /doconut-res | Akzeptiert zur Konsistenz mit anderen Doconut‑Widgets; das Converter‑Widget erzeugt daraus keine URL |
maxUploadMb | number | 25 | Nur clientseitige Vorprüfung; der Server erzwingt sein eigenes Limit |
licenseUrl | string | null | null | Wandelt den Wasserzeichen‑Hinweis auf dem Ergebnisbildschirm in einen Link um |
labels | object | {} | Überschreibt beliebige Teilmenge der englischen Zeichenketten des Widgets |
Callbacks:
| Callback | Wird ausgelöst, wenn | Daten |
|---|---|---|
onReady() | Das Widget hat seinen Drop‑Screen gerendert | — |
onSourceLoaded({ token, pages, sourceExt, allowedTargets }) | ?convert=open erfolgreich | Quell‑Token, Seitenanzahl, Quell‑Erweiterung (ohne führenden Punkt), zulässige Ziele |
onConverted({ downloadToken, resultToken, resultPages, downloadName, watermarked, target }) | ?convert=run erfolgreich | Die Run‑Antwort plus das angeforderte target |
onDownload({ downloadName, downloadToken }) | Der Benutzer klickt auf Download | Wird zusammen mit dem eigenen Download des Browsers ausgelöst |
onError({ phase, message }) | Eine open‑ oder run‑Anfrage schlägt fehl | phase ist 'open' oder 'run'; message ist der bereinigte Server‑Fehler |
Doconut.convert() gibt die Widget‑Instanz zurück: reset() kehrt zum Drop‑Screen zurück, loadFile(file) startet den Ablauf mit einer File, und destroy() entfernt sie.
Erstelle dein eigenes Frontend
Das Widget ist ein Client für diesen HTTP-Vertrag auf DocImage.axd:
| Route | Zweck | Erfolgsantwort |
|---|---|---|
POST /DocImage.axd?convert=open (multipart, field file) | Hochladen und Öffnen eines Quelldokuments | 200 — { token, pages, sourceExt, allowedTargets } |
POST /DocImage.axd?token=<token>&convert=run&target=<ext> | Konvertiere die hochgeladene Quelle zu target | 200 — { downloadToken, resultToken, resultPages, downloadName, watermarked } |
GET /DocImage.axd?convert=download&token=<downloadToken> | Stelle die konvertierte Datei als Stream bereit | 200 — die Datei, Content-Disposition: attachment |
Hochgeladene Quellen werden 30 Minuten lang aufbewahrt; danach gibt run 404 zurück und die Datei muss erneut geöffnet werden. downloadToken erhält ein eigenes 30‑Minuten‑Fenster, wenn die Konvertierung abgeschlossen ist. resultToken ist ein gewöhnliches Viewer‑Token, das der Lebensdauer der Viewer‑Sitzung folgt.
sourceExt in der open‑Antwort hat keinen führenden Punkt ("docx") — das Gegenteil des Parameters sourceExtension von ConvertAsync.
| Route | Status | Wann | Inhalt |
|---|---|---|---|
| beliebig | 404 | Das Widget ist nicht aktiviert (AddConverterWidget() wurde nie aufgerufen) | nur Status |
| beliebig | 405 | Falsches Verb (open/run erfordern POST, download erfordert GET) | nur Status |
open | 413 | Der Upload überschreitet MaxUploadMb (aber nicht die IIS‑Grenzen) | { "error": "File is too large." } |
open | 400 | Kein Multipart‑Body, keine Datei oder ein Typ, der nicht konvertiert werden kann | { "error": "..." } |
open | 403 | Der Dateityp erfordert eine Fähigkeit, die die Lizenz nicht gewährt | { "error": "..." } |
run | 400 | Ein fehlerhaftes Token, ein unbekanntes target oder ein Ziel, das nicht in allowedTargets enthalten ist | { "error": "..." } |
run | 404 | Der Upload ist abgelaufen oder wurde nie geöffnet | { "error": "Upload expired — please re-open the file." } |
open, run | 500 | Verarbeitung fehlgeschlagen | { "error": "<sanitized message>" } |
download | 400 / 404 | Ein fehlerhaftes, unbekanntes oder abgelaufenes Download‑Token | nur Status |
Ressourcenbesitz
Der Aufrufer besitzt den MemoryStream, den eine Konvertierung zurückgibt, und sollte ihn nach dem Kopieren oder Zurückgeben freigeben (MVCs File(stream, …) gibt ihn für Sie frei). Erstellen oder entsorgen Sie DocumentConverter nicht selbst — sein Konstruktor ist intern.
Wasserzeichen
| Lizenzstatus | Start | Konvertierungsausgabe |
|---|---|---|
Bezahlte Viewer‑Lizenz, die Converter gewährt | Startet | Sauber — watermarked: false |
| Aktive temporäre/Demo‑Lizenz | Startet | Konvertiert mit dem Evaluationswasserzeichen — watermarked: true |
Keine Lizenz, eine veraltete TRIAL‑Datei oder eine Lizenz ohne Converter | Application_Start wirft eine Ausnahme; jede Anfrage liefert ein leeres 500 | — |
| Abgelaufene temporäre/Demo‑Lizenz | Startet | Konvertiert mit dem Evaluationswasserzeichen — watermarked: true |
Eine Integration kann End‑zu‑Ende auf einer Evaluationslizenz vor dem Kauf aufgebaut und getestet werden — nur die Ausgabebytes ändern sich.
Fehlerbehebung
| Symptom | Prüfung |
|---|---|
Jede Anfrage liefert nach dem Hinzufügen des Plugins ein leeres 500 | Die Lizenz gewährt Converter — Windows‑Ereignisprotokoll, Quell‑ASP.NET |
Auflösen von DocumentConverter wirft eine Ausnahme | AddPlugin<ConverterPlugin>() befindet sich in DoconutHost.Initialize |
| Eine Web‑Forms‑Konvertierung gibt nie zurück | Die Seite blockiert bei ConvertAsync — verwenden Sie Async="true" und RegisterAsyncTask |
| Stream‑Konvertierung meldet, dass das Format nicht unterstützt wird | sourceExtension enthält den führenden Punkt |
Das Widget lädt, aber seine Anfragen liefern 404 | AddConverterWidget() wurde nicht aufgerufen, oder basePath ist nicht '/DocImage.axd' |
| Ein großer Upload zeigt eine IIS‑Fehlerseite anstelle der Widget‑Nachricht | maxRequestLength / maxAllowedContentLength liegen unter MaxUploadMb |
| Ein Ziel fehlt | Verwenden Sie die allowedTargets aus convert=open |
| Der Download ist abgelaufen | Wiederholen Sie convert=open / convert=run; die Tokens sind bewusst temporär |
War diese Seite hilfreich?