Wtyczka konwertera
Konwertuj dokumenty do 24 formatów docelowych
Wtyczka Converter przekształca Doconut w usługę konwersji dokumentów. Dostarcza silnik stojący za publiczną fasadą DocumentConverter oraz — opcjonalnie — gotowy widget udostępniany przez DocImage.axd, dzięki czemu możesz konwertować dokumenty z C#, z widgetu lub z własnego interfejsu front‑endowego.
Zainstaluj pakiet
Install-Package Doconut.NETFramework.ConverterUtrzymuj pakiet Converter w tej samej wersji co Doconut.NETFramework.
Zarejestruj wtyczkę
Każda wtyczka rejestruje się w ten sam sposób: AddPlugin<TPlugin>() w DoconutHost.Initialize.
Doconut.DoconutHost.Initialize(options =>
{
options.LicensePath = HostingEnvironment.MapPath("~/wwwroot/Doconut.Viewer.lic");
options.AddPlugin<Doconut.Plugins.Converter.ConverterPlugin>();
});Jeśli żadne aktywne licencje nie przyznają możliwości
Converter— brak licencji, starszy plikTRIALlub licencja bez tej funkcji —DoconutHost.Initializezgłasza wyjątek wApplication_Start. W System.Web oznacza to, że każde żądanie zwraca pusty kod500, a przyczyna jest widoczna jedynie w dzienniku zdarzeń Windows (źródło ASP.NET). Tymczasowe licencje Demo/NFR są akceptowane. Zobacz Konfiguracja licencji.
Konwertuj z C#
Każda konwersja zwraca przeszukiwalny MemoryStream ustawiony na pozycję 0. DocumentConverter jest bezstanowy: pobierz go z DoconutHost.Services tam, gdzie jest potrzebny i używaj wielokrotnie.
// Resolve DocumentConverter from DoconutHost.Services; its constructor is internal, so never `new` it.
Stream pdf = await converter.ConvertAsync("contract.docx", ConversionTarget.Pdf, ct: ct);// sourceExtension includes the leading dot. password is null unless the document is protected.
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);Dwa szczegóły, które łatwo pomylić: sourceExtension w przeciążeniu przyjmującym strumień musi zawierać początkową kropkę (".xlsx", a nie "xlsx"), w przeciwnym razie nie zostanie rozpoznany. I pomimo nazwy, WordToHtmlAsync zwraca Task<Stream>, a nie Task<string> — dokument HTML (obrazy osadzone jako Base64) przychodzi jako strumień, tak jak każdy inny wynik.
W kontrolerze MVC 5
Uczyń akcję asynchroniczną i użyj await przy konwersji:
[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");
}W Web Forms: nigdy nie blokuj konwersji
Strona Web Forms działa w jednowątkowym kontekście żądania. ConvertAsync wznawia się w tym kontekście po zakończeniu, więc strona, która czeka na wynik synchronicznie — .Result, .Wait(), .GetAwaiter().GetResult() — blokuje wątek, którego konwersja potrzebuje do zakończenia. Żądanie nigdy nie powraca. Przeglądarka wciąż się kręci, IIS nie zapisuje żadnych logów, a reszta witryny działa, więc wygląda to jak wolna konwersja, a nie zakleszczenie.
Oznacz stronę Async="true" i uruchom konwersję jako asynchroniczne zadanie strony:
<%@ Page Language="C#" Async="true" CodeBehind="Convert.aspx.cs" Inherits="MyApp.Convert" %>// Web Forms: the @Page directive needs Async="true", and the conversion runs as a page async task.
// Blocking on it instead (.Result, .Wait(), .GetAwaiter().GetResult()) deadlocks the request:
// it never returns, and nothing is logged.
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, not HttpContext.Current: after an await the latter can be null.
Context.ApplicationInstance.CompleteRequest();
}
}));
}Bez Async="true" w dyrektywie @Page, RegisterAsyncTask jest cicho pomijany. Po await użyj Context strony; HttpContext.Current może być w tym miejscu null.
Formaty docelowe
Pdf, Docx, Doc, Html, Xlsx, Pptx, Png, Jpeg, Csv, Tiff, Bmp, Gif, Svg, Xml,
Txt, Xls, Jp2, Rtf, Odt, Ods, Odp, Epub, Xps, WebpNie każdy źródłowy format konwertuje na każdy docelowy: każda rodzina formatów źródłowych (Word, Excel, PowerPoint, PDF, CAD, Image, Email, Diagram, Project, PSD, dokument internetowy) ma własny zestaw dozwolonych celów. Nie koduj na sztywno tego wyliczenia jako listy docelowej w interfejsie użytkownika: ?convert=open zwraca allowedTargets dla przesłanego pliku i to powinno sterować wyborem.
Wbudowany widżet
Endpointy widżetu ?convert=open|run|download są obsługiwane przez DocImage.axd i są wyłączone domyślnie. Włącz je obok rejestracji wtyczki:
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>Dwie rzeczy do sprawdzenia, gdy widżet zachowuje się nieprawidłowo:
basePath: '/DocImage.axd'. DomyślnybasePathwidżetu,/doconut, jest punktem końcowym ASP.NET Core. W tym pakiecie endpointy są obsługiwane przez handlerDocImage.axdzWeb.config.- Skrypt i endpointy są niezależne. Moduł zasobów serwuje
doconutConverter.jsniezależnie od tego, czy widżet jest włączony. BezAddConverterWidget(), widżet ładuje się, rysuje swoją strefę upuszczania i wygląda całkowicie poprawnie — a jego pierwsza akcja zwraca404.
Limity przesyłania
ASP.NET odczytuje całe ciało żądania przed uruchomieniem DocImage.axd. Przesył powyżej MaxUploadMb, ale poniżej limitów hosta, powoduje zwrócenie przez widżet własnego JSON 413 („Plik jest za duży.”). Przesył powyżej limitów hosta jest najpierw odrzucany przez IIS, z stroną błędu, której widżet nie może odczytać. Zachowaj oba limity hosta w Web.config powyżej limitu widżetu:
<system.web>
<httpRuntime maxRequestLength="30720" /> <!-- KILOBYTES: 30 MB -->
</system.web>
<system.webServer>
<security>
<requestFiltering>
<requestLimits maxAllowedContentLength="31457280" /> <!-- BYTES: 30 MB -->
</requestFiltering>
</security>
</system.webServer>Dostosowanie widżetu
Opcje przekazywane do Doconut.convert(selector, options):
| Opcja | Typ | Domyślnie | Uwagi |
|---|---|---|---|
basePath | string | /doconut | Adres URL punktu końcowego. Ustaw '/DocImage.axd' w tym pakiecie |
resPath | string | /doconut-res | Akceptowane dla spójności z innymi widżetami Doconut; widżet konwertera nie buduje żadnego URL z tego |
maxUploadMb | number | 25 | Tylko wstępna weryfikacja po stronie klienta; serwer wymusza własny limit |
licenseUrl | string | null | null | Zamienia powiadomienie o znakowaniu wodnym na ekranie wyniku w link |
labels | object | {} | Zastępuje dowolny podzbiór angielskich ciągów widżetu |
Wywołania zwrotne:
| Wywołanie zwrotne | Wywoływane gdy | Dane |
|---|---|---|
onReady() | Widżet wyrenderował ekran upuszczania | — |
onSourceLoaded({ token, pages, sourceExt, allowedTargets }) | ?convert=open zakończyło się sukcesem | Token źródła, liczba stron, rozszerzenie źródła (bez kropki), dozwolone cele |
onConverted({ downloadToken, resultToken, resultPages, downloadName, watermarked, target }) | ?convert=run zakończyło się sukcesem | Odpowiedź po uruchomieniu plus żądany target |
onDownload({ downloadName, downloadToken }) | Użytkownik kliknął Pobierz | Wywoływane równocześnie z własnym pobieraniem przeglądarki |
onError({ phase, message }) | Żądanie open lub run nie powiodło się | phase to 'open' lub 'run'; message to oczyszczony błąd serwera |
Doconut.convert() zwraca instancję widżetu: reset() przywraca ekran upuszczania, loadFile(file) rozpoczyna proces z File, a destroy() usuwa go.
Zbuduj własny frontend
Widżet jest klientem tego kontraktu HTTP na DocImage.axd:
| Ścieżka | Cel | Odpowiedź sukcesu |
|---|---|---|
POST /DocImage.axd?convert=open (multipart, pole file) | Prześlij i otwórz dokument źródłowy | 200 — { token, pages, sourceExt, allowedTargets } |
POST /DocImage.axd?token=<token>&convert=run&target=<ext> | Konwertuj przesłany dokument źródłowy na target | 200 — { downloadToken, resultToken, resultPages, downloadName, watermarked } |
GET /DocImage.axd?convert=download&token=<downloadToken> | Strumieniuj skonwertowany plik | 200 — plik, Content-Disposition: attachment |
Przesłane źródła są przechowywane przez 30 minut; po tym czasie run zwraca 404 i plik musi zostać ponownie otwarty. downloadToken otrzymuje własne 30‑minutowe okno po zakończeniu konwersji. resultToken jest zwykłym tokenem przeglądarki, który obowiązuje przez cały czas trwania sesji przeglądarki.
sourceExt w odpowiedzi open nie zawiera wiodącej kropki ("docx") — w przeciwieństwie do parametru sourceExtension w ConvertAsync.
| Ścieżka | Status | Kiedy | Treść |
|---|---|---|---|
| dowolna | 404 | Widżet nie jest włączony (AddConverterWidget() nigdy nie został wywołany) | tylko status |
| dowolna | 405 | Nieprawidłowa metoda (open/run wymagają POST, download wymaga GET) | tylko status |
open | 413 | Przesyłanie przekracza MaxUploadMb (ale nie limity IIS) | { "error": "File is too large." } |
open | 400 | Brak ciała multipart, brak pliku lub typ, którego nie można skonwertować | { "error": "..." } |
open | 403 | Typ pliku wymaga funkcji, której licencja nie przyznaje | { "error": "..." } |
run | 400 | Nieprawidłowy token, nieznany target lub cel nieobecny w allowedTargets | { "error": "..." } |
run | 404 | Przesyłanie wygasło lub nigdy nie zostało otwarte | { "error": "Upload expired — please re-open the file." } |
open, run | 500 | Przetwarzanie nie powiodło się | { "error": "<sanitized message>" } |
download | 400 / 404 | Nieprawidłowy, nieznany lub wygasły token pobrania | tylko status |
Własność zasobów
Wywołujący jest właścicielem MemoryStream zwracanego przez konwersję i powinien go zwolnić po skopiowaniu lub zwróceniu (MVC File(stream, …) zwalnia go za Ciebie). Nie twórz ani nie zwalniaj DocumentConverter samodzielnie — jego konstruktor jest wewnętrzny.
Dodawanie znaków wodnych
| Stan licencji | Uruchomienie | Wynik konwersji |
|---|---|---|
Płatna licencja przeglądarki przyznająca Converter | Uruchamia się | Czysty — watermarked: false |
| Aktywna licencja tymczasowa/demo | Uruchamia się | Konwertuje z znakiem wodnym oceny — watermarked: true |
Brak licencji, starszy plik TRIAL lub licencja bez Converter | Application_Start rzuca wyjątek; każde żądanie zwraca pusty 500 | — |
| Wygasła licencja tymczasowa/demo | Uruchamia się | Konwertuje z znakiem wodnym oceny — watermarked: true |
Integrację można zbudować i przetestować od początku do końca na licencji ewaluacyjnej przed zakupem — zmieniają się tylko bajty wyjściowe.
Rozwiązywanie problemów
| Objaw | Sprawdź |
|---|---|
Każde żądanie zwraca pusty 500 po dodaniu wtyczki | Licencja przyznaje Converter — dziennik zdarzeń Windows, źródło ASP.NET |
Rozwiązywanie DocumentConverter rzuca wyjątek | AddPlugin<ConverterPlugin>() znajduje się w DoconutHost.Initialize |
| Konwersja Web Forms nigdy nie zwraca | Strona blokuje się na ConvertAsync — użyj Async="true" i RegisterAsyncTask |
| Strumieniowa konwersja informuje, że format nie jest obsługiwany | sourceExtension zawiera wiodącą kropkę |
Widżet ładuje się, ale jego żądania zwracają 404 | AddConverterWidget() nie został wywołany lub basePath nie jest '/DocImage.axd' |
| Duży upload wyświetla stronę błędu IIS zamiast komunikatu widżetu | maxRequestLength / maxAllowedContentLength są niższe niż MaxUploadMb |
| Brak docelowego formatu | Użyj allowedTargets z convert=open |
| Pobranie wygasło | Powtórz convert=open / convert=run; tokeny są celowo tymczasowe |
Czy ta strona była pomocna?