Πρόσθετο Μετατροπέα
Μετατρέψτε έγγραφα σε 24 μορφές προορισμού
Το πρόσθετο Converter μετατρέπει το Doconut σε υπηρεσία μετατροπής εγγράφων. Συνεισφέρει τη μηχανή πίσω από τη δημόσια DocumentConverter όψη και — με επιλογή — ένα ενσωματωμένο συστατικό που παρέχεται από DocImage.axd, ώστε να μπορείτε να μετατρέπετε έγγραφα από C#, από το συστατικό ή από μια πρόσοψη που γράφετε μόνοι σας.
Εγκατάσταση του πακέτου
Install-Package Doconut.NETFramework.ConverterΔιατηρήστε το πακέτο Converter στην ίδια έκδοση με το Doconut.NETFramework.
Καταχώριση του πρόσθετου
Κάθε πρόσθετο καταχωρίζεται με τον ίδιο τρόπο: AddPlugin<TPlugin>() στο DoconutHost.Initialize.
Doconut.DoconutHost.Initialize(options =>
{
options.LicensePath = HostingEnvironment.MapPath("~/wwwroot/Doconut.Viewer.lic");
options.AddPlugin<Doconut.Plugins.Converter.ConverterPlugin>();
});Αν καμία ενεργή άδεια δεν παρέχει τη δυνατότητα
Converter— καμία άδεια, ένα παλιό αρχείοTRIAL, ή μια άδεια χωρίς αυτή — τοDoconutHost.Initializeρίχνει εξαίρεση από τοApplication_Start. Στο System.Web αυτό σημαίνει ότι κάθε αίτηση απαντά με ένα κενό500, και ο λόγος είναι μόνο στο αρχείο καταγραφής των Windows (πηγή ASP.NET). Δέχονται προσωρινές άδειες Demo/NFR. Δείτε το Ρύθμιση Άδειας.
Μετατροπή από C#
Κάθε μετατροπή επιστρέφει ένα αναζητήσιμο MemoryStream τοποθετημένο στο 0. Το DocumentConverter είναι χωρίς κατάσταση: επιλύστε το από το DoconutHost.Services όπου το χρειάζεστε και επαναχρησιμοποιήστε το ελεύθερα.
// Ανακτήστε το DocumentConverter από το DoconutHost.Services· ο κατασκευαστής του είναι εσωτερικός, οπότε ποτέ μην το `new` it.
Stream pdf = await converter.ConvertAsync("contract.docx", ConversionTarget.Pdf, ct: ct);// Το sourceExtension περιλαμβάνει την αρχική τελεία. Το password είναι null εκτός αν το έγγραφο είναι προστατευμένο.
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);Δύο λεπτομέρειες που είναι εύκολο να καταλάβετε λανθασμένα: το sourceExtension στην υπερφόρτωση ροής πρέπει να περιλαμβάνει την αρχική τελεία (".xlsx", όχι "xlsx"), αλλιώς δεν επιλύεται. Και παρά το όνομά του, το WordToHtmlAsync επιστρέφει Task<Stream>, όχι Task<string> — το έγγραφο HTML (εικόνες ενσωματωμένες ως Base64) φτάνει ως ροή, όπως κάθε άλλο αποτέλεσμα.
Σε έναν ελεγκτή MVC 5
Κάντε τη δράση ασύγχρονη και await τη μετατροπή:
[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");
}Στα Web Forms: ποτέ μην μπλοκάρετε μια μετατροπή
Μια σελίδα Web Forms εκτελείται σε ένα μονονηματικό πλαίσιο αίτησης. Το ConvertAsync συνεχίζει σε αυτό το πλαίσιο όταν ολοκληρωθεί, έτσι μια σελίδα που περιμένει συγχρονισμένα — .Result, .Wait(), .GetAwaiter().GetResult() — κρατά το ίδιο νήμα που χρειάζεται η μετατροπή για να ολοκληρωθεί. Το αίτημα δεν επιστρέφει ποτέ. Ο περιηγητής συνεχίζει να περιστρέφεται, τα αρχεία καταγραφής IIS δεν δείχνουν τίποτα, και το υπόλοιπο του ιστότοπου συνεχίζει να λειτουργεί, οπότε φαίνεται σαν αργή μετατροπή αντί για αδιέξοδο.
Σημειώστε τη σελίδα Async="true" και εκτελέστε τη μετατροπή ως ασύγχρονη εργασία της σελίδας:
<%@ Page Language="C#" Async="true" CodeBehind="Convert.aspx.cs" Inherits="MyApp.Convert" %>// Web Forms: η οδηγία @Page χρειάζεται Async="true", και η μετατροπή εκτελείται ως ασύγχρονη εργασία σελίδας.
// Το μπλοκάρισμα σε αυτό (.Result, .Wait(), .GetAwaiter().GetResult()) προκαλεί αδιέξοδο του αιτήματος:
// Δεν επιστρέφει ποτέ και δεν καταγράφεται τίποτα.
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, όχι HttpContext.Current: μετά από await το δεύτερο μπορεί να είναι null.
Context.ApplicationInstance.CompleteRequest();
}
}));
}Χωρίς το Async="true" στην οδηγία @Page, το RegisterAsyncTask αγνοείται σιωπηρά. Μετά ένα await, χρησιμοποιήστε το Context της σελίδας· το HttpContext.Current μπορεί να είναι null εκεί.
Μορφές προορισμού
Pdf, Docx, Doc, Html, Xlsx, Pptx, Png, Jpeg, Csv, Tiff, Bmp, Gif, Svg, Xml,
Txt, Xls, Jp2, Rtf, Odt, Ods, Odp, Epub, Xps, WebpΔεν μετατρέπει κάθε πηγή σε κάθε προορισμό: η οικογένεια μορφών κάθε πηγής (Word, Excel, PowerPoint, PDF, CAD, Image, Email, Diagram, Project, PSD, web document) έχει το δικό της σύνολο επιτρεπτών προορισμών. Μην κωδικοποιείτε σκληρά αυτό το enum ως τη λίστα στόχων του UI σας: ?convert=open επιστρέφει το allowedTargets για το ανεβασμένο αρχείο, και αυτό είναι ό,τι πρέπει να καθοδηγεί έναν επιλογέα.
Widget ενσωμάτωσης
Τα ?convert=open|run|download endpoints του widget εξυπηρετούνται από DocImage.axd και είναι απενεργοποιημένα από προεπιλογή. Ενεργοποιήστε τα δίπλα στην εγγραφή του plugin:
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 διαβάζει ολόκληρη τη μεταφόρτωση πριν το Doconut τη δει: διατηρήστε το maxRequestLength (KB) και
// maxAllowedContentLength (bytes) στο Web.config πάνω από το MaxUploadMb του widget.<div id="doconut-convert"></div>
<script src="/doconut-res/js/doconutConverter.js"></script>
<script>
Doconut.convert('#doconut-convert', { basePath: '/DocImage.axd', maxUploadMb: 25 });
</script>Δύο πράγματα που πρέπει να ελέγξετε όταν το widget συμπεριφέρεται ακατάλληλα:
basePath: '/DocImage.axd'. Η προεπιλογή του widget,/doconut, είναι το endpoint του ASP.NET Core. Σε αυτό το πακέτο, τα endpoints είναι ο χειριστήςDocImage.axdαπό τοWeb.config.- Το script και τα endpoints είναι ανεξάρτητα. Το resource module εξυπηρετεί
doconutConverter.jsείτε το widget είναι ενεργοποιημένο είτε όχι. ΧωρίςAddConverterWidget(), το widget φορτώνει, σχεδιάζει τη ζώνη απόθεσής του και φαίνεται εντελώς σωστό — και η πρώτη του ενέργεια απαντά404.
Όρια μεταφόρτωσης
Το ASP.NET διαβάζει ολόκληρο το σώμα του αιτήματος πριν τρέξει το DocImage.axd. Μια μεταφόρτωση πάνω από MaxUploadMb αλλά κάτω από τα όρια του host λαμβάνει το δικό του JSON 413 του widget ("File is too large."). Μια μεταφόρτωση πάνω από τα όρια του host απορρίπτεται πρώτα από το IIS, με μια σελίδα σφάλματος που το widget δεν μπορεί να διαβάσει. Διατηρήστε και τα δύο όρια του host στο Web.config πάνω από το όριο του widget:
<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
Επιλογές που περνούν στο Doconut.convert(selector, options):
| Επιλογή | Τύπος | Προεπιλογή | Σημειώσεις |
|---|---|---|---|
basePath | string | /doconut | Το URL του endpoint. Ορίστε '/DocImage.axd' σε αυτό το πακέτο |
resPath | string | /doconut-res | Αποδεκτό για συνέπεια με άλλα Doconut widgets· το widget μετατροπής δεν δημιουργεί κανένα URL από αυτό |
maxUploadMb | number | 25 | Μόνο προ-έλεγχος στην πλευρά του πελάτη· ο διακομιστής επιβάλλει το δικό του όριο |
licenseUrl | string | null | null | Μετατρέπει την ειδοποίηση υδατογράφησης στην οθόνη αποτελεσμάτων σε σύνδεσμο |
labels | object | {} | Αντικαθιστά οποιοδήποτε υποσύνολο των αγγλικών συμβολοσειρών του widget |
Κλήσεις επιστροφής:
| Κλήση | Συμβαίνει όταν | Δεδομένα |
|---|---|---|
onReady() | Το widget έχει αποδώσει την οθόνη απόθεσης | — |
onSourceLoaded({ token, pages, sourceExt, allowedTargets }) | ?convert=open επιτυγχάνει | Διακριτικό πηγής, αριθμός σελίδων, επέκταση πηγής (χωρίς την αρχική τελεία), επιτρεπτοί προορισμοί |
onConverted({ downloadToken, resultToken, resultPages, downloadName, watermarked, target }) | ?convert=run επιτυγχάνει | Η απάντηση εκτέλεσης συν το ζητούμενο target |
onDownload({ downloadName, downloadToken }) | Ο χρήστης κάνει κλικ στο Κατέβασμα | Ενεργοποιείται παράλληλα με τη δική του λήψη του προγράμματος περιήγησης |
onError({ phase, message }) | Αποτυγχάνει ένα αίτημα ανοίγματος ή εκτέλεσης | phase είναι 'open' ή 'run'· message είναι το καθαρισμένο σφάλμα διακομιστή |
Doconut.convert() επιστρέφει την παρουσία του widget: reset() επιστρέφει στην οθόνη απόθεσης, loadFile(file) ξεκινά τη ροή με ένα File, και destroy() το αφαιρεί.
Δημιουργήστε το δικό σας frontend
Το widget είναι ένας πελάτης για αυτή τη σύμβαση HTTP στο DocImage.axd:
| Διαδρομή | Σκοπός | Απάντηση επιτυχίας |
|---|---|---|
POST /DocImage.axd?convert=open (πολλαπλής μορφής, πεδίο file) | Ανέβασμα και άνοιγμα ενός πηγαίου εγγράφου | 200 — { token, pages, sourceExt, allowedTargets } |
POST /DocImage.axd?token=<token>&convert=run&target=<ext> | Μετατροπή του ανεβασμένου πηγαίου σε target | 200 — { downloadToken, resultToken, resultPages, downloadName, watermarked } |
GET /DocImage.axd?convert=download&token=<downloadToken> | Ροή του μετατρεπόμενου αρχείου | 200 — το αρχείο, Content-Disposition: attachment |
Τα ανεβασμένα πηγαία διατηρούνται για 30 λεπτά· μετά από αυτό, run απαντά 404 και το αρχείο πρέπει να ανοίξει ξανά. downloadToken λαμβάνει το δικό του παράθυρο 30 λεπτών όταν ολοκληρωθεί η μετατροπή. resultToken είναι ένα συνηθισμένο viewer token που ακολουθεί τη διάρκεια της συνεδρίας προβολέα.
sourceExt στην απάντηση open δεν έχει αρχική τελεία ("docx") — το αντίστροφο της παραμέτρου sourceExtension του ConvertAsync.
| Διαδρομή | Κατάσταση | Πότε | Σώμα |
|---|---|---|---|
| οποιοδήποτε | 404 | Το widget δεν είναι ενεργοποιημένο (AddConverterWidget() δεν κλήθηκε ποτέ) | μόνο κατάσταση |
| οποιοδήποτε | 405 | Λάθος ρήμα (open/run απαιτούν POST, download απαιτεί GET) | μόνο κατάσταση |
open | 413 | Το ανέβασμα υπερβαίνει το MaxUploadMb (αλλά όχι τα όρια του IIS) | { "error": "File is too large." } |
open | 400 | Δεν υπάρχει σώμα πολλαπλής μορφής, κανένα αρχείο, ή τύπος που δεν μπορεί να μετατραπεί | { "error": "..." } |
open | 403 | Ο τύπος αρχείου απαιτεί δυνατότητα που η άδεια δεν παρέχει | { "error": "..." } |
run | 400 | Ένα κακοδιατυπωμένο token, ένα άγνωστο target, ή ένας προορισμός που δεν υπάρχει στο allowedTargets | { "error": "..." } |
run | 404 | Το ανέβασμα έληξε ή δεν ανοίχθηκε ποτέ | { "error": "Upload expired — please re-open the file." } |
open, run | 500 | Η επεξεργασία απέτυχε | { "error": "<sanitized message>" } |
download | 400 / 404 | Ένα κακοδιατυπωμένο, άγνωστο ή ληγμένο token λήψης | μόνο κατάσταση |
Ιδιοκτησία πόρων
Ο καλούντας κατέχει το MemoryStream που επιστρέφει μια μετατροπή και πρέπει να το αποδεσμεύσει μετά την αντιγραφή ή την επιστροφή του (το File(stream, …) του MVC το αποδεσμεύει για εσάς). Μην δημιουργείτε ή αποδεσμεύετε το DocumentConverter μόνοι σας — ο κατασκευαστής του είναι εσωτερικός.
Υδατογράφημα
| Κατάσταση άδειας | Έναρξη | Αποτέλεσμα μετατροπής |
|---|---|---|
Πληρωμένη άδεια προβολέα που παρέχει Converter | Ξεκινά | Καθαρό — watermarked: false |
| Ενεργή προσωρινή/δωρητική άδεια | Ξεκινά | Μετατρέπει, με το υδατογράφημα αξιολόγησης — watermarked: true |
Χωρίς άδεια, ένα παλιό αρχείο TRIAL, ή άδεια χωρίς Converter | Application_Start προκαλεί εξαίρεση· κάθε αίτηση απαντά ένα κενό 500 | — |
| Ληγμένη προσωρινή/δωρητική άδεια | Ξεκινά | Μετατρέπει, με το υδατογράφημα αξιολόγησης — watermarked: true |
Μια ενσωμάτωση μπορεί να δημιουργηθεί και να δοκιμαστεί από άκρη σε άκρη με μια άδεια αξιολόγησης πριν από την αγορά — μόνο τα bytes εξόδου αλλάζουν.
Επίλυση προβλημάτων
| Σύμπτωμα | Έλεγχος |
|---|---|
Κάθε αίτηση απαντά ένα κενό 500 μετά την προσθήκη του plugin | Η άδεια παρέχει Converter — αρχείο καταγραφής Windows, πηγή ASP.NET |
Η επίλυση του DocumentConverter προκαλεί εξαίρεση | AddPlugin<ConverterPlugin>() βρίσκεται στο DoconutHost.Initialize |
| Μια μετατροπή Web Forms δεν επιστρέφει ποτέ | Η σελίδα μπλοκάρει στο ConvertAsync — χρησιμοποιήστε Async="true" και RegisterAsyncTask |
| Η μετατροπή ροής λέει ότι η μορφή δεν υποστηρίζεται | sourceExtension περιλαμβάνει την αρχική τελεία |
Το widget φορτώνει αλλά τα αιτήματά του επιστρέφουν 404 | AddConverterWidget() δεν κλήθηκε, ή basePath δεν είναι '/DocImage.axd' |
| Ένα μεγάλο ανέβασμα εμφανίζει μια σελίδα σφάλματος IIS αντί για το μήνυμα του widget | maxRequestLength / maxAllowedContentLength είναι κάτω από MaxUploadMb |
| Λείπει ένας προορισμός | Χρησιμοποιήστε το allowedTargets από το convert=open |
| Η λήψη έληξε | Επαναλάβετε convert=open / convert=run· τα tokens είναι προσωρινά επίτηδες |
Ήταν αυτή η σελίδα χρήσιμη;