Konverteringsplugin

Konvertera dokument till 24 målformat

Converter‑pluginet förvandlar Doconut till en dokumentkonverteringstjänst. Det bidrar med motorn bakom det offentliga DocumentConverter‑gränssnittet och — på begäran — en inbyggd widget som levereras av DocImage.axd, så att du kan konvertera dokument från C#, från widgeten eller från ett front‑end du själv skriver.

Installera paketet

powershell
Install-Package Doconut.NETFramework.Converter

Behåll Converter‑paketet på samma version som Doconut.NETFramework.

Registrera pluginet

Varje plugin registreras på samma sätt: AddPlugin<TPlugin>() i DoconutHost.Initialize.

csharp
Doconut.DoconutHost.Initialize(options =>
{
    options.LicensePath = HostingEnvironment.MapPath("~/wwwroot/Doconut.Viewer.lic");
    options.AddPlugin<Doconut.Plugins.Converter.ConverterPlugin>();
});

Om ingen aktiv licens ger Converter‑kapaciteten — ingen licens, en äldre TRIAL‑fil eller en licens utan den — DoconutHost.Initialize kastar från Application_Start. I System.Web betyder det att varje begäran svarar med en tom 500, och orsaken finns bara i Windows‑händelseloggen (källa ASP.NET). Tillfälliga Demo/NFR‑licenser accepteras. Se License Setup.

Konvertera från C#

Varje konvertering returnerar en sökbar MemoryStream placerad på 0. DocumentConverter är stateless: hämta den från DoconutHost.Services där du än behöver den och återanvänd den fritt.

csharp
// Hämta DocumentConverter från DoconutHost.Services; dess konstruktor är intern, så `new` den aldrig.
Stream pdf = await converter.ConvertAsync("contract.docx", ConversionTarget.Pdf, ct: ct);
csharp
// sourceExtension inkluderar den inledande punkten. password är null om inte dokumentet är skyddat.
Stream png = await converter.ConvertAsync(upload, ".xlsx", ConversionTarget.Png, password: null, ct: ct);
csharp
Stream html = await converter.WordToHtmlAsync("report.docx", ct);
csharp
Stream docx = await converter.HtmlToWordAsync(html, ConversionTarget.Docx, ct);

Två detaljer som är lätta att göra fel på: sourceExtension på stream‑överladdningen måste inkludera den inledande punkten (".xlsx", inte "xlsx"), annars löser den inte upp. Och trots sitt namn returnerar WordToHtmlAsync Task<Stream>, inte Task<string> — HTML‑dokumentet (bilder inbäddade som Base64) levereras som en stream, precis som alla andra resultat.

I en MVC 5‑controller

Gör åtgärden asynkron och await konverteringen:

csharp
[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");
}

I Web Forms: blockera aldrig en konvertering

En Web Forms‑sida körs i ett enkeltrådat begärandekontext. ConvertAsync återupptas i den kontexten när den är klar, så en sida som väntar på den synkront — .Result, .Wait(), .GetAwaiter().GetResult() — håller fast den tråd som konverteringen behöver för att slutföras. Begäran returnerar aldrig. Webbläsaren snurrar vidare, IIS loggar inget, och resten av webbplatsen fortsätter att fungera, så det ser ut som en långsam konvertering snarare än ett dödläge.

Markera sidan Async="true" och kör konverteringen som en asynkron siduppgift:

aspx
<%@ Page Language="C#" Async="true" CodeBehind="Convert.aspx.cs" Inherits="MyApp.Convert" %>
csharp
// Web Forms: @Page-direktivet behöver Async="true", och konverteringen körs som en asynkron siduppgift.
// Att blockera på den istället (.Result, .Wait(), .GetAwaiter().GetResult()) låser förfrågan:
// den returnerar aldrig, och inget loggas.
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, inte HttpContext.Current: efter en await kan den senare vara null.
            Context.ApplicationInstance.CompleteRequest();
        }
    }));
}

Utan Async="true" i @Page‑direktivet ignoreras RegisterAsyncTask tyst. Efter en await, använd sidans Context; HttpContext.Current kan vara null där.

Målformat

text
Pdf, Docx, Doc, Html, Xlsx, Pptx, Png, Jpeg, Csv, Tiff, Bmp, Gif, Svg, Xml,
Txt, Xls, Jp2, Rtf, Odt, Ods, Odp, Epub, Xps, Webp

Inte varje källa konverteras till varje mål: varje källas formatfamilj (Word, Excel, PowerPoint, PDF, CAD, Image, Email, Diagram, Project, PSD, web document) har sin egen uppsättning tillåtna mål. Hardkoda inte den här uppräkningen som ditt UI:s mållista: ?convert=open returnerar allowedTargets för den uppladdade filen, och det är vad som bör styra en väljare.

Inbäddningswidget

Widgetens ?convert=open|run|download-endpunkter levereras av DocImage.axd och är avstängda som standard. Aktivera dem bredvid pluginregistreringen:

csharp
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 läser hela uppladdningen innan Doconut ser den: behåll maxRequestLength (KB) och
// maxAllowedContentLength (bytes) i Web.config ovanför widgetens MaxUploadMb.
html
<div id="doconut-convert"></div>
<script src="/doconut-res/js/doconutConverter.js"></script>
<script>
  Doconut.convert('#doconut-convert', { basePath: '/DocImage.axd', maxUploadMb: 25 });
</script>

Två saker att kontrollera när widgeten beter sig fel:

  • basePath: '/DocImage.axd'. Widgetens standard, /doconut, är ASP.NET Core-endpunkten. I detta paket är endpunkterna DocImage.axd-hanteraren från Web.config.
  • Skriptet och endpunkterna är oberoende. Resursmodulen levererar doconutConverter.js oavsett om widgeten är aktiverad eller inte. Utan AddConverterWidget() laddas widgeten, målar sin släppzon och ser helt korrekt ut — och dess första åtgärd svarar med 404.

Uppladdningsgränser

ASP.NET läser hela begärans kropp innan DocImage.axd körs. En uppladdning över MaxUploadMb men under värdens gränser får widgetens egna JSON 413 ("File is too large."). En uppladdning över värdens gränser avvisas först av IIS, med en felsida som widgeten inte kan läsa. Håll båda värdens gränser i Web.config över widgetens tak:

xml
<system.web>
  <httpRuntime maxRequestLength="30720" />           <!-- KILOBYTE: 30 MB -->
</system.web>
<system.webServer>
  <security>
    <requestFiltering>
      <requestLimits maxAllowedContentLength="31457280" />  <!-- BYTE: 30 MB -->
    </requestFiltering>
  </security>
</system.webServer>

Anpassa widgeten

Alternativ som skickas till Doconut.convert(selector, options):

AlternativTypStandardAnteckningar
basePathstring/doconutEndpoint‑URL:en. Ställ in '/DocImage.axd' i detta paket
resPathstring/doconut-resAccepterad för konsistens med andra Doconut‑widgetar; konverteringswidgeten bygger ingen URL från den
maxUploadMbnumber25Endast förhandskontroll på klienten; servern upprätthåller sin egen gräns
licenseUrlstring | nullnullGör vattenmärkesmeddelandet på resultatskärmen till en länk
labelsobject{}Åsidosätter någon delmängd av widgetens engelska strängar

Callbacks:

CallbackUtlöses närPayload
onReady()Widgeten har renderat sin släppsida—
onSourceLoaded({ token, pages, sourceExt, allowedTargets })?convert=open lyckasKälltoken, sidantal, källa‑filändelse (utan inledande punkt), tillåtna mål
onConverted({ downloadToken, resultToken, resultPages, downloadName, watermarked, target })?convert=run lyckasKörningssvaret plus den begärda target
onDownload({ downloadName, downloadToken })Användaren klickar på Ladda nerUtlöser samtidigt som webbläsarens egen nedladdning
onError({ phase, message })En öppnings‑ eller körningsbegäran misslyckasphase är 'open' eller 'run'; message är det sanerade serverfelet

Doconut.convert() returnerar widget‑instansen: reset() återgår till släppsidan, loadFile(file) startar flödet med en File, och destroy() tar bort den.

Bygg ditt eget frontend

Widgeten är en klient för detta HTTP‑avtal på DocImage.axd:

RuttSyfteLyckat svar
POST /DocImage.axd?convert=open (multipart, field file)Ladda upp och öppna ett källdokument200 — { token, pages, sourceExt, allowedTargets }
POST /DocImage.axd?token=<token>&convert=run&target=<ext>Konvertera den uppladdade källan till target200 — { downloadToken, resultToken, resultPages, downloadName, watermarked }
GET /DocImage.axd?convert=download&token=<downloadToken>Strömma den konverterade filen200 — filen, Content-Disposition: attachment

Uppladdade källor behålls i 30 minuter; därefter svarar run med 404 och filen måste öppnas igen. downloadToken får sitt eget 30‑minutersfönster när konverteringen är klar. resultToken är en vanlig visartoken som följer visningssessionens livstid.

sourceExt i open‑svaret har ingen inledande punkt ("docx") — motsatsen till sourceExtension‑parametern i ConvertAsync.

RuttStatusNärKropp
valfri404Widgeten är inte aktiverad (AddConverterWidget() anropades aldrig)endast status
valfri405Fel HTTP‑verb (open/run kräver POST, download kräver GET)endast status
open413Uppladdningen överskrider MaxUploadMb (men inte IIS‑gränserna){ "error": "File is too large." }
open400Ingen multipart‑kropp, ingen fil, eller en typ som inte kan konverteras{ "error": "..." }
open403Filtypen kräver en funktion som licensen inte beviljar{ "error": "..." }
run400En felaktig token, en okänd target, eller ett mål som inte finns i allowedTargets{ "error": "..." }
run404Uppladdningen har gått ut eller öppnades aldrig{ "error": "Upload expired — please re-open the file." }
open, run500Bearbetning misslyckades{ "error": "<sanitized message>" }
download400 / 404En felaktig, okänd eller utgången nedladdningstokenendast status

Resursägande

Anroparen äger den MemoryStream som en konvertering returnerar och bör avyttra den efter att ha kopierat eller returnerat den (MVC:s File(stream, …) avyttrar den åt dig). Konstruera eller avyttra inte DocumentConverter själv — dess konstruktor är intern.

Vattenstämpling

LicensstatusStartKonverteringsutdata
Betald visningslicens som beviljar ConverterStartarRen — watermarked: false
Aktiv tillfällig/demo‑licensStartarKonverterar, med utvärderingsvattenstämpel — watermarked: true
Ingen licens, en äldre TRIAL‑fil, eller en licens utan ConverterApplication_Start kastar; varje begäran svarar med en tom 500—
Utgången tillfällig/demo‑licensStartarKonverterar, med utvärderingsvattenstämpel — watermarked: true

En integration kan byggas och testas från början till slut med en utvärderingslicens innan köp — endast utdata‑bytena förändras.

Felsökning

SymptomKontroll
Varje begäran svarar med en tom 500 efter att ha lagt till pluginetLicensen beviljar Converter — Windows händelselog, källa ASP.NET
Uppslagning av DocumentConverter kastarAddPlugin<ConverterPlugin>() finns i DoconutHost.Initialize
En Web Forms‑konvertering returnerar aldrigSidan blockerar på ConvertAsync — använd Async="true" och RegisterAsyncTask
Strömkonvertering säger att formatet inte stödssourceExtension innehåller den inledande punkten
Widgeten laddas men dess begäranden returnerar 404AddConverterWidget() anropades inte, eller basePath är inte '/DocImage.axd'
En stor uppladdning visar en IIS‑felssida istället för widgetens meddelandemaxRequestLength / maxAllowedContentLength är under MaxUploadMb
Ett mål saknasAnvänd allowedTargets från convert=open
Nedladdningen har gått utUpprepa convert=open / convert=run; tokenarna är avsiktligt temporära

Var den här sidan hjälpsam?