Plugin převodníku
Převádějte dokumenty do 24 cílových formátů
Plugin Converter promění Doconut na službu pro převod dokumentů. Přispívá k enginu za veřejnou fasádou DocumentConverter a — po zapnutí — k vložitelného widgetu poskytovanému DocImage.axd, takže můžete převádět dokumenty z C#, z widgetu nebo z frontendu, který si vytvoříte sami.
Instalace balíčku
Install-Package Doconut.NETFramework.ConverterUdržujte balíček Converter ve stejné verzi jako Doconut.NETFramework.
Zaregistrujte plugin
Každý plugin se registruje stejným způsobem: AddPlugin<TPlugin>() v DoconutHost.Initialize.
Doconut.DoconutHost.Initialize(options =>
{
options.LicensePath = HostingEnvironment.MapPath("~/wwwroot/Doconut.Viewer.lic");
options.AddPlugin<Doconut.Plugins.Converter.ConverterPlugin>();
});Pokud žádná aktivní licence nepřiděluje schopnost
Converter— žádná licence, starý souborTRIALnebo licence bez ní —DoconutHost.Initializevyhodí výjimku zApplication_Start. V System.Web to znamená, že každá žádost vrátí prázdný500a důvod je pouze v protokolu událostí Windows (zdroj ASP.NET). Dočasné Demo/NFR licence jsou akceptovány. Viz Nastavení licence.
Převod z C#
Každý převod vrací vyhledávatelný MemoryStream nastavený na pozici 0. DocumentConverter je bezstavový: získáte jej z DoconutHost.Services kdekoliv jej potřebujete a můžete jej volně znovu použít.
// Získejte DocumentConverter z DoconutHost.Services; jeho konstruktor je interní, takže jej nikdy neinstanciujte pomocí `new`.
Stream pdf = await converter.ConvertAsync("contract.docx", ConversionTarget.Pdf, ct: ct);// sourceExtension obsahuje úvodní tečku. password je null, pokud dokument není chráněn.
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);Dva detaily, které se snadno špatně pochopí: sourceExtension u přetížení se streamem musí obsahovat úvodní tečku (".xlsx", ne "xlsx"), jinak se nevyřeší. A navzdory názvu WordToHtmlAsync vrací Task<Stream>, nikoli Task<string> — HTML dokument (obrázky vložené jako Base64) přichází jako stream, stejně jako každý jiný výsledek.
V MVC 5 kontroleru
Udělejte akci asynchronní a await převod:
[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");
}Ve Web Forms: nikdy neblokujte převod
Stránka Web Forms běží v jednovláknovém kontextu požadavku. ConvertAsync se po dokončení obnoví v tomto kontextu, takže stránka, která na něj čeká synchronně — .Result, .Wait(), .GetAwaiter().GetResult() — drží právě ten vlákno, které převod potřebuje k dokončení. Požadavek se nikdy nevrátí. Prohlížeč stále otáčí, IIS nic neukládá a zbytek webu funguje, takže to vypadá jako pomalý převod místo zablokování.
Označte stránku Async="true" a spusťte převod jako asynchronní úlohu stránky:
<%@ Page Language="C#" Async="true" CodeBehind="Convert.aspx.cs" Inherits="MyApp.Convert" %>// Web Forms: direktiva @Page vyžaduje Async="true" a převod běží jako asynchronní úloha stránky.
// Blokování na něj místo toho (.Result, .Wait(), .GetAwaiter().GetResult()) způsobí deadlock požadavku:
// nikdy se nevrátí a nic se nezaznamená.
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, ne HttpContext.Current: po await může být ten druhý null.
Context.ApplicationInstance.CompleteRequest();
}
}));
}Bez Async="true" v direktivě @Page je RegisterAsyncTask tiše ignorováno. Po await použijte Context stránky; HttpContext.Current může být v tomto okamžiku null.
Cílové formáty
Pdf, Docx, Doc, Html, Xlsx, Pptx, Png, Jpeg, Csv, Tiff, Bmp, Gif, Svg, Xml,
Txt, Xls, Jp2, Rtf, Odt, Ods, Odp, Epub, Xps, WebpNe každý zdroj se převádí na každý cíl: každá rodina formátů zdroje (Word, Excel, PowerPoint, PDF, CAD, Image, Email, Diagram, Project, PSD, webový dokument) má vlastní sadu povolených cílů. Nezakódovávejte tento výčet jako pevný seznam cílů ve vašem UI: ?convert=open vrací allowedTargets pro nahraný soubor a to by mělo řídit výběr.
Vkládací widget
Endpointy widgetu ?convert=open|run|download jsou poskytovány pomocí DocImage.axd a jsou ve výchozím nastavení vypnuté. Povolit je můžete vedle registrace pluginu:
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 reads the whole upload before Doconut sees it: keep maxRequestLength (KB) and
// maxAllowedContentLength (bytes) in Web.config above the widget's MaxUploadMb.<div id="doconut-convert"></div>
<script src="/doconut-res/js/doconutConverter.js"></script>
<script>
Doconut.convert('#doconut-convert', { basePath: '/DocImage.axd', maxUploadMb: 25 });
</script>Dvě věci, které je třeba zkontrolovat, když widget nefunguje správně:
basePath: '/DocImage.axd'. Výchozí hodnota widgetu,/doconut, je endpoint ASP.NET Core. V tomto balíčku jsou endpointy obsluhovány handleremDocImage.axdzWeb.config.- Skript a endpointy jsou nezávislé. Modul zdrojů poskytuje
doconutConverter.jsbez ohledu na to, zda je widget povolen. BezAddConverterWidget()se widget načte, vykreslí svou oblast pro přetažení a vypadá naprosto správně — a jeho první akce vrátí404.
Limity nahrávání
ASP.NET načte celé tělo požadavku před tím, než se spustí DocImage.axd. Nahrání nad MaxUploadMb, ale pod limity hostitele, vrátí widgetu vlastní JSON 413 („Soubor je příliš velký.“). Nahrání nad limity hostitele je nejprve odmítnuto IIS, s chybovou stránkou, kterou widget nedokáže přečíst. Ponechte oba limity hostitele v Web.config nad limitem widgetu:
<system.web>
<httpRuntime maxRequestLength="30720" /> <!-- KILOBYTES: 30 MB -->
</system.web>
<system.webServer>
<security>
<requestFiltering>
<requestLimits maxAllowedContentLength="31457280" /> <!-- BYTES: 30 MB -->
</requestFiltering>
</security>
</system.webServer>Přizpůsobení widgetu
Možnosti předávané do Doconut.convert(selector, options):
| Možnost | Typ | Výchozí | Poznámky |
|---|---|---|---|
basePath | string | /doconut | URL endpointu. Na tomto balíčku nastavte '/DocImage.axd' |
resPath | string | /doconut-res | Přijato pro konzistenci s ostatními Doconut widgety; konvertorový widget nevyužívá tuto hodnotu k sestavení žádné URL. |
maxUploadMb | number | 25 | Pouze předběžná kontrola na klientovi; server vynutí svůj vlastní limit. |
licenseUrl | string | null | null | Přemění upozornění na vodoznak na výsledné obrazovce na odkaz. |
labels | object | {} | Přepíše libovolnou podmnožinu anglických řetězců widgetu. |
Zpětné volání:
| Zpětné volání | Spustí se, když | Data |
|---|---|---|
onReady() | Widget vykreslil svou výchozí obrazovku | — |
onSourceLoaded({ token, pages, sourceExt, allowedTargets }) | ?convert=open uspěje | Token zdroje, počet stránek, přípona zdroje (bez úvodní tečky), povolené cíle |
onConverted({ downloadToken, resultToken, resultPages, downloadName, watermarked, target }) | ?convert=run uspěje | Odpověď běhu plus požadovaný target |
onDownload({ downloadName, downloadToken }) | Uživatel klikne na Stáhnout | Spustí se spolu s vlastním stažením prohlížeče |
onError({ phase, message }) | Požadavek open nebo run selže | phase je 'open' nebo 'run'; message je ošetřená chyba serveru |
Doconut.convert() vrací instanci widgetu: reset() vrátí na výchozí obrazovku, loadFile(file) spustí proces s File, a destroy() jej odstraní.
Vytvořte si vlastní frontend
Widget je klientem pro tuto HTTP smlouvu na DocImage.axd:
| Cesta | Účel | Úspěšná odpověď |
|---|---|---|
POST /DocImage.axd?convert=open (multipart, field file) | Nahrát a otevřít zdrojový dokument | 200 — { token, pages, sourceExt, allowedTargets } |
POST /DocImage.axd?token=<token>&convert=run&target=<ext> | Převést nahraný zdroj na target | 200 — { downloadToken, resultToken, resultPages, downloadName, watermarked } |
GET /DocImage.axd?convert=download&token=<downloadToken> | Streamovat převedený soubor | 200 — soubor, Content-Disposition: attachment |
Nahrané zdroje jsou uchovávány po dobu 30 minut; po uplynutí této doby run vrací 404 a soubor je nutné znovu otevřít. downloadToken získá vlastní 30‑minutové okno po dokončení konverze. resultToken je běžný token pro prohlížeč, který platí po celou dobu životnosti relace prohlížeče.
sourceExt v odpovědi open nemá úvodní tečku ("docx") — naopak oproti parametru sourceExtension metody ConvertAsync.
| Cesta | Stav | Kdy | Tělo |
|---|---|---|---|
| libovolná | 404 | Widget není povolen (AddConverterWidget() nebylo nikdy zavoláno) | pouze stav |
| libovolná | 405 | Špatná metoda (open/run vyžadují POST, download vyžaduje GET) | pouze stav |
open | 413 | Nahrání překračuje MaxUploadMb (ale ne limity IIS) | { "error": "File is too large." } |
open | 400 | Chybí multipart tělo, soubor nebo typ, který nelze převést | { "error": "..." } |
open | 403 | Typ souboru vyžaduje schopnost, kterou licence neposkytuje | { "error": "..." } |
run | 400 | Poškozený token, neznámý target nebo cíl, který není v allowedTargets | { "error": "..." } |
run | 404 | Nahrání vypršelo nebo nebylo nikdy otevřeno | { "error": "Upload expired — please re-open the file." } |
open, run | 500 | Zpracování selhalo | { "error": "<sanitized message>" } |
download | 400 / 404 | Poškozený, neznámý nebo vypršelý token pro stažení | pouze stav |
Vlastnictví zdrojů
Volající vlastní MemoryStream, který konverze vrací, a měl by jej uvolnit po zkopírování nebo vrácení (MVC metoda File(stream, …) jej uvolní za vás). Nevytvářejte ani neuvolňujte DocumentConverter sami — jeho konstruktor je interní.
Vodoznakování
| Stav licence | Spuštění | Výstup konverze |
|---|---|---|
Placená licence pro prohlížeč poskytující Converter | Spouští se | Čistý — watermarked: false |
| Aktivní dočasná/demo licence | Spouští se | Převádí, s evaluačním vodoznakem — watermarked: true |
Žádná licence, starý soubor TRIAL nebo licence bez Converter | Application_Start vyhodí výjimku; každá žádost vrátí prázdný 500 | — |
| Vypršená dočasná/demo licence | Spouští se | Převádí, s evaluačním vodoznakem — watermarked: true |
Integraci lze postavit a otestovat od začátku do konce na evaluační licenci před nákupem — mění se pouze výstupní bajty.
Řešení problémů
| Problém | Kontrola |
|---|---|
Každá žádost vrací prázdný 500 po přidání pluginu | Licence poskytuje Converter — Windows Event Log, zdrojový ASP.NET |
Vyřešení DocumentConverter vyvolá výjimku | AddPlugin<ConverterPlugin>() je v DoconutHost.Initialize |
| Konverze Web Forms se nikdy nevrátí | Stránka blokuje na ConvertAsync — použijte Async="true" a RegisterAsyncTask |
| Streamová konverze uvádí, že formát není podporován | sourceExtension obsahuje úvodní tečku |
Widget se načte, ale jeho požadavky vrací 404 | AddConverterWidget() nebylo zavoláno, nebo basePath není '/DocImage.axd' |
| Velké nahrání zobrazí chybovou stránku IIS místo zprávy widgetu | maxRequestLength / maxAllowedContentLength jsou pod MaxUploadMb |
| Chybí cíl | Použijte allowedTargets z convert=open |
| Stahování vypršelo | Opakujte convert=open / convert=run; tokeny jsou úmyslně dočasné |
Byla tato stránka užitečná?