Πρόσθετο Μετατροπέα
Μετατρέψτε έγγραφα σε 24 μορφές προορισμού
Το πρόσθετο Converter μετατρέπει το Doconut σε υπηρεσία μετατροπής εγγράφων. Συνεισφέρει τη μηχανή πίσω από τη δημόσια DocumentConverter πρόσοψη, και — με επιλογή — ένα ενσωματωμένο widget με το δικό του συμβόλαιο HTTP, ώστε να μπορείτε να μετατρέπετε έγγραφα από C#, από το widget, ή από ένα frontend που γράφετε εσείς.
Εγκατάσταση του πακέτου
Εγκαταστήστε το πιο πρόσφατο σταθερό πρόσθετο Converter:
dotnet add package Doconut.NET6.ConverterΓια να κλειδώσετε το πρόσθετο στην τρέχουσα έκδοση 26.7.0, περάστε την έκδοση ξεχωριστά:
dotnet add package Doconut.NET6.Converter --version 26.7.0Διατηρήστε το πακέτο Converter στην ίδια έκδοση με το Doconut.NET6. Το αναγνωριστικό του πακέτου είναι
Doconut.NET6.Converter· .26.7.0 εμφανίζεται μόνο στο ληφθέν όνομα αρχείου .nupkg.
Καταχώρηση του πρόσθετου
Δεν υπάρχει μέθοδος AddConverter() — το μοντέλο πρόσθετων του Doconut είναι ενιαίο. Κάθε πρόσθετο, συμπεριλαμβανομένου του Converter, καταχωρείται με τον ίδιο τρόπο: καλέστε το AddPlugin<TPlugin>() μέσα στο AddDoconut(). Το ConverterPlugin διανέμεται στο δικό του πακέτο NuGet, Doconut.NET6.Converter, εγκατεστημένο παράλληλα με το βασικό πακέτο προβολής.
builder.Services.AddDoconut(options =>
{
options.LicensePath = "Doconut.Viewer.lic";
options.AddPlugin<Doconut.Plugins.Converter.ConverterPlugin>();
});Αυτή η κλήση αποτυγχάνει κατά την εκκίνηση λόγω έλλειψης άδειας, ενός παλαιού αρχείου
TRIAL, ή μη προσωρινής άδειας που δεν παρέχει τη δυνατότηταConverter— έναInvalidOperationExceptionπου προέρχεται από τοAddDoconut(), πριν η εφαρμογή εξυπηρετήσει αιτήματα. Δέχονται προσωρινές εγγραφές Demo/NFR· μετά τη λήξη του ημερολογίου τους, η μετατροπή παραμένει διαθέσιμη με υδατογράφημα στην έξοδο. Δεν υπάρχει σιωπηλό δωρεάν επίπεδο. Δείτε το Ρύθμιση Άδειας για το πώς φορτώνονται οι άδειες.
Μετατροπή από C#
Κάθε μετατροπή επιστρέφει ένα αναζητήσιμο MemoryStream τοποθετημένο στο 0, έτοιμο για ανάγνωση ή αντιγραφή αμέσως. Ανάκτηση του DocumentConverter από DI όπου το χρειάζεστε — είναι χωρίς κατάσταση κατά σχεδίαση, έτσι ένα μόνο αντίγραφο είναι ασφαλές για επαναχρησιμοποίηση σε πολλαπλά αιτήματα.
// Ενσωματώστε το DocumentConverter· ο κατασκευαστής του είναι εσωτερικός, οπότε ποτέ μην το `new`.
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) ως ροή, το ίδιο όπως κάθε άλλο αποτέλεσμα μετατροπής.
Μορφές προορισμού
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/Task, PSD, web document) στο δικό του σταθερό σύνολο επιτρεπτών προορισμών. Μην κωδικοποιείτε σκληρά αυτό το enum ως λίστα προορισμών του UI σας: το ?convert=open επιστρέφει το πραγματικό allowedTargets για οποιοδήποτε αρχείο μόλις ανέβηκε, και αυτό πρέπει να καθοδηγεί έναν επιλογέα.
Widget ενσωμάτωσης
Το widget's ?convert=open|run|download endpoints είναι προαιρετικά και απενεργοποιημένα από προεπιλογή — ασφαλή από προεπιλογή. Ενεργοποιήστε τα από την πλευρά του διακομιστή, μαζί με την καταγραφή του plugin:
builder.Services.AddDoconut(options =>
{
options.LicensePath = "Doconut.Viewer.lic";
options.AddPlugin<Doconut.Plugins.Converter.ConverterPlugin>();
options.AddConverterWidget(widget =>
{
widget.MaxUploadMb = 25;
});
});<div id="doconut-convert"></div>
<script src="/doconut-res/js/doconutConverter.js"></script>
<script>
Doconut.convert('#doconut-convert', { basePath: '/doconut', resPath: '/doconut-res', maxUploadMb: 25 });
</script>Χωρίς AddConverterWidget(), τα τρία ?convert= endpoints απαντούν 404 — αλλά το αρχείο JS εξακολουθεί να σερβίρεται ανεξάρτητα (είναι ένας απλός ενσωματωμένος στατικός πόρος· μόνο τα endpoints στα οποία επικοινωνεί είναι περιορισμένα). Το AddConverterWidget() εξακολουθεί να απαιτεί την καταγραφή του plugin Converter και μια άδεια που παρέχει Converter — δεν παρέχει δικαιώματα μετατροπής από μόνο του.
Προσαρμογή του widget
Αρχικές επιλογές που περνιούνται στο Doconut.convert(selector, options):
| Επιλογή | Τύπος | Προεπιλογή | Σημειώσεις |
|---|---|---|---|
basePath | string | /doconut | Βασική διαδρομή για τα ?convert= endpoints· πρέπει να ταιριάζει με το κλάδο ASP.NET όπου το UseDoconut() είναι πραγματικά προσαρτημένο (συνήθως συντονίζεται μέσω του MiddlewarePath) |
resPath | string | /doconut-res | Αποδεκτό για συνέπεια ρυθμίσεων με άλλα Doconut widgets· το widget μετατροπέα αυτή τη στιγμή δεν δημιουργεί καμία URL από αυτό |
maxUploadMb | number | 25 | Μόνο προέλεγχος στην πλευρά του πελάτη — απορρίπτει ένα υπερμεγέθες αρχείο πριν τη μεταφόρτωση. Ο διακομιστής επιβάλλει το δικό του όριο ανεξάρτητα και απαντά 413 αν το υπερβεί |
licenseUrl | string | null | null | Όταν οριστεί, μετατρέπει την ειδοποίηση υδατογραφήματος στην οθόνη αποτελεσμάτων σε σύνδεσμο προς αυτή τη διεύθυνση URL |
labels | object | {} | Αντικαθιστά οποιοδήποτε υποσύνολο των προεπιλεγμένων αγγλικών συμβολοσειρών του widget (κείμενο ρίψης, κουμπιά, ανακοινώσεις aria‑live, μηνύματα σφάλματος) |
Ανακλήσεις:
| Ανακλήση | Ενεργοποιείται όταν | Δεδομένα |
|---|---|---|
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 — κρατήστε το για να ελέγχετε το widget προγραμματιστικά:
const conv = Doconut.convert('#doconut-convert', { basePath: '/doconut' });
conv.reset(); // επιστροφή στην οθόνη idle/drop; δεν επανεκκινεί το onReady
conv.loadFile(file); // εκκινεί τη ροή με ένα αντικείμενο File; no-op εκτός εάν είναι τρέχουσα η κατάσταση idle
conv.destroy(); // αφαιρεί τους listeners, αδειάζει το mount; η instance δεν είναι χρησιμοποιήσιμη μετά από αυτόΔημιουργήστε το δικό σας frontend
Το widget είναι απλώς ένας πελάτης για αυτή τη σύμβαση HTTP — δημιουργήστε το δικό σας frontend απευθείας εναντίον της για διαφορετική εμπειρία χρήστη. Όλες οι τρεις διαδρομές βρίσκονται κάτω από το κλάδο ASP.NET όπου το UseDoconut() είναι προσαρτημένο (συνήθως /doconut):
| Διαδρομή | Σκοπός | Απάντηση επιτυχίας |
|---|---|---|
POST ?convert=open (multipart, πεδίο file) | Μεταφόρτωση και άνοιγμα ενός πηγαίου εγγράφου για προεπισκόπηση | 200 — { token, pages, sourceExt, allowedTargets } |
POST ?token=<token>&convert=run&target=<ext> | Μετατροπή της αποθηκευμένης πηγής σε target | 200 — { downloadToken, resultToken, resultPages, downloadName, watermarked } |
GET ?convert=download&token=<downloadToken> | Ροή του μετατρεπόμενου αρχείου | 200 — bytes αρχείου, Content-Disposition: attachment, Cache-Control: no-store |
Τα μεταφορτωμένα bytes της πηγής αποθηκεύονται στην πλευρά του διακομιστή με TTL 30 λεπτών· όταν αυτό το παράθυρο λήξει, το run απαντά 404 και το αρχείο πρέπει να ξαναανοιχτεί. Το μετατρεπόμενο αποτέλεσμα ζει στην ίδια αποθήκη — το downloadToken λαμβάνει το δικό του φρέσκο παράθυρο 30 λεπτών όταν ολοκληρωθεί η μετατροπή — ενώ το resultToken είναι ένα συνηθισμένο διακριτικό συνεδρίας προβολέα του οποίου η διάρκεια ζωής ακολουθεί την κρυφή μνήμη συνεδρίας του προβολέα, ανεξάρτητα από την αποθήκη.
Το sourceExt στην απόκριση open δεν έχει αρχική τελεία (π.χ. "docx") — η αντίθετη σύμβαση από την παράμετρο sourceExtension στο DocumentConverter.ConvertAsync, η οποία απαιτεί μία.
Τρόποι αποτυχίας, ομαδοποιημένοι ανά διαδρομή:
| Διαδρομή | Κατάσταση | Πότε | Σώμα |
|---|---|---|---|
| οποιοδήποτε | 404 | Το widget δεν είναι ενεργοποιημένο (το AddConverterWidget() δεν κλήθηκε ποτέ) — ελέγχεται πριν την εκτέλεση οποιασδήποτε από τις τρεις διαδρομές | μόνο κατάσταση |
| οποιοδήποτε | 405 | Λάθος HTTP μέθοδος (το open/run απαιτούν POST· το download απαιτεί GET) | μόνο κατάσταση |
open | 413 | Το μεταφορτωμένο αρχείο υπερβαίνει το MaxUploadMb | { "error": "File is too large." } |
open | 400 | Δεν υπάρχει σώμα multipart, κανένα αρχείο, ή μια επέκταση πηγής που δεν μπορεί να μετατραπεί | { "error": "..." } |
run | 400 | Κακοδιατυπωμένο διακριτικό (δεν είναι GUID), ή ένα target που δεν μπορεί να αναλυθεί σε ConversionTarget | { "error": "Invalid token." } / { "error": "Unknown target format." } |
run | 400 | Το target δεν βρίσκεται στο allowedTargets της πηγής | { "error": "That target format is not available for this file." } |
run | 404 | Η αποθηκευμένη μεταφόρτωση έχει λήξει (TTL 30 λεπτών) ή το διακριτικό δεν ανοίχθηκε ποτέ | { "error": "Upload expired — please re-open the file." } |
open, run | 500 | Η επεξεργασία απέτυχε εσωτερικά | { "error": "<sanitized message>" } — αποκατεστημένο με τον ίδιο τρόπο όπως κάθε άλλη διαδρομή σφάλματος Doconut· δεν διαρρέει ποτέ εσωτερικά ονόματα μηχανής |
download | 400 | Κακοδιατυπωμένο διακριτικό (δεν είναι GUID) | μόνο κατάσταση |
download | 404 | Άγνωστο ή ληγμένο διακριτικό λήψης | μόνο κατάσταση |
Ιδιοκτησία πόρων
Ο μετατροπέας επιστρέφει ένα seekable MemoryStream τοποθετημένο στο μηδέν. Ο καλών έχει την ιδιοκτησία αυτού του ρεύματος και θα πρέπει να το διαγράψει μετά την αντιγραφή ή την επιστροφή των περιεχομένων του. Η υπηρεσία DocumentConverter είναι χωρίς κατάσταση και λαμβάνεται από την εξάρτηση injection· μην δημιουργείτε ή διαγράφετε την υπηρεσία χειροκίνητα.
Για το web widget, τα αποθηκευμένα upload και download έχουν ανεξάρτητα TTL 30 λεπτών. Ένας viewer resultToken ακολουθεί τη διάρκεια της συνεδρίας του viewer αντί αυτού. Το κλείσιμο ενός αποτελέσματος viewer δεν διαγράφει ένα ακόμη έγκυρο download stash, και η επαναφορά του widget του προγράμματος περιήγησης δεν επεκτείνει κανένα από τα TTL.
Επίλυση προβλημάτων
| Συμπτωμα | Έλεγχος |
|---|---|
Αποτυχία επίλυσης του DocumentConverter | Η εγγραφή ConverterPlugin έγινε μέσα στο AddDoconut() |
| Η εφαρμογή αποτυγχάνει κατά την εκκίνηση | Η φορτωμένη άδεια παρέχει Converter |
| Η μετατροπή ρεύματος αναφέρει ότι η μορφή δεν υποστηρίζεται | Το sourceExtension περιλαμβάνει την αρχική τελεία |
| Το JavaScript του widget φορτώνει αλλά τα αιτήματα επιστρέφουν 404 | Το AddConverterWidget() δεν κλήθηκε |
| Τα αιτήματα του widget χρησιμοποιούν λανθασμένο URL | Το basePath ταιριάζει με το κλαδί όπου το UseDoconut() είναι αντιστοιχισμένο |
| Ο προορισμός λείπει | Χρησιμοποιήστε το allowedTargets που επιστρέφεται από το convert=open· δεν υποστηρίζει κάθε πηγή κάθε στόχο enum |
| Η λήψη έληξε | Επαναλάβετε convert=open/convert=run· τα διακριτικά stash είναι σκόπιμα προσωρινά |
Υδατογράφημα
Με εγγεγραμμένο το ConverterPlugin, η άδεια του κεντρικού είναι σε μία από τις τρεις καταστάσεις:
| Κατάσταση άδειας | Πύλη εκκίνησης | Έξοδος μετατροπής |
|---|---|---|
Άδεια πληρωμένου viewer που παρέχει Converter, εντός της περιόδου ισχύος της | Περνά | Καθαρό — watermarked: false |
| Ενεργή άδεια αξιολόγησης (demo/NFR) | Περνά | Μετατρέπει επιτυχώς, σφραγισμένο με το υδατογράφημα αξιολόγησης — watermarked: true |
Χωρίς άδεια, ένα παλιό αρχείο TRIAL, ή μια μη προσωρινή άδεια που δεν παρέχει Converter | Η εφαρμογή δεν εκκινεί ποτέ — η πύλη εκκίνησης που περιγράφηκε παραπάνω ρίχνει | — |
| Ληγμένη προσωρινή/δοκιμαστική άδεια | Η εγγραφή επιβιώνει μετά τη λήξη | Μετατρέπει με το υδατογράφημα αξιολόγησης — watermarked: true |
Και οι δύο διαδρομές κλήσης υπολογίζουν τη σημαία από τον ίδιο κανόνα: η προσκηνή DocumentConverter C# εξάγει τη σημαία εσωτερικά από την κατάσταση IsViewerLicensed και IsTemporary της άδειας, και ο χειριστής ?convert=run του widget κάνει τον ισοδύναμο έλεγχο (IsViewerLicensed && !IsTrial && !IsTemporary) για να γεμίσει το πεδίο watermarked που επιστρέφει. Μια ενσωμάτωση μπορεί να δημιουργηθεί και να δοκιμαστεί από άκρη σε άκρη με μια άδεια αξιολόγησης πριν από την αγορά — μόνο τα bytes εξόδου αλλάζουν.
Ήταν αυτή η σελίδα χρήσιμη;