Πρόσθετο Μετατροπέα
Μετατρέψτε έγγραφα σε 24 μορφές-στόχους
Το πρόσθετο Μετατροπέα μετατρέπει το Doconut σε μια υπηρεσία μετατροπής εγγράφων. Συνεισφέρει τη μηχανή πίσω από τη δημόσια DocumentConverter προσέγγιση, και — με επιλογή — ένα ενσωματωμένο widget με το δικό του συμβόλαιο HTTP, ώστε να μπορείτε να μετατρέπετε έγγραφα από C#, από το widget, ή από ένα frontend που γράφετε εσείς.
Εγκατάσταση του πακέτου
Εγκαταστήστε το πιο πρόσφατο σταθερό πρόσθετο Μετατροπέα:
dotnet add package Doconut.NET8.ConverterΓια να κλειδώσετε το πρόσθετο στην τρέχουσα έκδοση 26.7.0, περάστε την έκδοση ξεχωριστά:
dotnet add package Doconut.NET8.Converter --version 26.7.0Διατηρήστε το πακέτο Μετατροπέα στην ίδια έκδοση με το Doconut.NET8. Το αναγνωριστικό του πακέτου είναι
Doconut.NET8.Converter; το .26.7.0 εμφανίζεται μόνο στο ληφθέν όνομα αρχείου .nupkg.
Καταχώριση του πρόσθετου
Δεν υπάρχει μέθοδος AddConverter() — το μοντέλο πρόσθετων του Doconut είναι ενιαίο. Κάθε πρόσθετο, συμπεριλαμβανομένου του Μετατροπέα, καταχωρίζεται με τον ίδιο τρόπο: καλέστε το AddPlugin<TPlugin>() μέσα στο AddDoconut(). Το ConverterPlugin διανέμεται στο δικό του πακέτο NuGet, Doconut.NET8.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 για οποιοδήποτε αρχείο μόλις ανέβηκε, και αυτό είναι ό,τι πρέπει να καθοδηγεί έναν επιλογέα.
Drop-in 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 — δεν παρέχει δικαιώματα μετατροπής από μόνο του.
Customize the widget
Αρχικές επιλογές που περνιούνται στο Doconut.convert(selector, options):
| Option | Type | Default | Notes |
|---|---|---|---|
basePath | string | /doconut | Βασική διαδρομή για τα ?convert= endpoints· πρέπει να ταιριάζει με το κλάδο ASP.NET όπου το UseDoconut() είναι πραγματικά τοποθετημένο (συνήθως συντονίζεται μέσω του MiddlewarePath) |
resPath | string | /doconut-res | Αποδεκτό για συνέπεια ρυθμίσεων με άλλα widgets Doconut· το widget μετατροπής αυτή τη στιγμή δεν δημιουργεί κανένα URL από αυτό |
maxUploadMb | number | 25 | Προέλεγχος μόνο στην πλευρά του πελάτη — απορρίπτει ένα υπερμεγέθες αρχείο πριν τη μεταφόρτωση. Ο διακομιστής επιβάλλει το δικό του όριο ανεξάρτητα και απαντά με 413 εάν το υπερβεί |
licenseUrl | string | null | null | Όταν οριστεί, μετατρέπει την ειδοποίηση υδατογράμματος στην οθόνη αποτελέσματος σε σύνδεσμο προς αυτή τη διεύθυνση URL |
labels | object | {} | Αντικαθιστά οποιοδήποτε υποσύνολο των προεπιλεγμένων αγγλικών συμβολοσειρών του widget (κείμενο ρίψης, κουμπιά, ανακοινώσεις aria‑live, μηνύματα σφάλματος) |
Ανακλήσεις:
| Callback | Fires when | Payload |
|---|---|---|
onReady() | Το widget έχει αποδώσει την οθόνη αδράνειας/ρίψης | — |
onSourceLoaded({ token, pages, sourceExt, allowedTargets }) | Το ?convert=open ολοκληρώνεται επιτυχώς | token συνεδρίας πηγής, αριθμός σελίδων, επέκταση πηγής (χωρίς αρχική τελεία), λίστα επιτρεπόμενων στόχων |
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 δεν είναι χρήσιμη μετά από αυτόBuild your own frontend
Το widget είναι απλώς ένας πελάτης για αυτό το HTTP συμβόλαιο — δημιουργήστε το δικό σας frontend απευθείας εναντίον του για διαφορετική εμπειρία χρήστη. Όλες οι τρεις διαδρομές βρίσκονται κάτω από το κλάδο ASP.NET όπου το UseDoconut() είναι τοποθετημένο (συνήθως /doconut):
| Route | Purpose | Success response |
|---|---|---|
POST ?convert=open (multipart, field 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 είναι ένα συνηθισμένο token συνεδρίας προβολέα του οποίου η διάρκεια ζωής ακολουθεί την κρυφή μνήμη συνεδρίας του προβολέα, ανεξάρτητα από την αποθήκη.
Το sourceExt στην απάντηση open δεν έχει αρχική τελεία (π.χ. "docx") — το αντίστροφο σύμβατο από την παράμετρο sourceExtension στο DocumentConverter.ConvertAsync, η οποία απαιτεί μία.
Λειτουργίες αποτυχίας, ομαδοποιημένες ανά διαδρομή:
| Route | Status | When | Body |
|---|---|---|---|
| any | 404 | Το widget δεν είναι ενεργοποιημένο (το AddConverterWidget() δεν κλήθηκε ποτέ) — ελέγχεται πριν την εκκίνηση οποιασδήποτε από τις τρεις διαδρομές | status only |
| any | 405 | Λάθος μέθοδος HTTP (το open/run απαιτούν POST· το download απαιτεί GET) | status only |
open | 413 | Το ανεβασμένο αρχείο υπερβαίνει το MaxUploadMb | { "error": "File is too large." } |
open | 400 | Δεν υπάρχει σώμα multipart, κανένα αρχείο, ή μια επέκταση πηγής που δεν μπορεί να μετατραπεί | { "error": "..." } |
run | 400 | Κακοδιαμορφωμένο token (δεν είναι 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 λεπτών) ή το token δεν άνοιξε ποτέ | { "error": "Upload expired — please re-open the file." } |
open, run | 500 | Η επεξεργασία απέτυχε εσωτερικά | { "error": "<sanitized message>" } — αποκατεστημένο με τον ίδιο τρόπο όπως κάθε άλλη διαδρομή σφάλματος Doconut· δεν διαρρέει ποτέ εσωτερικά ονόματα μηχανής |
download | 400 | Κακοδιαμορφωμένο token (δεν είναι GUID) | status only |
download | 404 | Άγνωστο ή ληγμένο token λήψης | status only |
Κάτοχος πόρων
Ο μετατροπέας επιστρέφει ένα seekable MemoryStream τοποθετημένο στο μηδέν. Ο καλών έχει την ιδιοκτησία αυτού του ρεύματος και πρέπει να το απελευθερώσει μετά την αντιγραφή ή την επιστροφή των περιεχομένων του. Η υπηρεσία DocumentConverter είναι χωρίς κατάσταση και λαμβάνεται από την εξάρτηση injection· μην δημιουργείτε ή απελευθερώνετε την υπηρεσία χειροκίνητα.
Για το web widget, τα αποθηκευμένα upload και download έχουν ανεξάρτητα TTL 30 λεπτών. Ένας viewer resultToken ακολουθεί τη διάρκεια της συνεδρίας του viewer αντί αυτού. Το κλείσιμο ενός αποτελέσματος viewer δεν διαγράφει ένα ακόμη έγκυρο stash λήψης, και η επαναφορά του widget του προγράμματος περιήγησης δεν επεκτείνει κανένα από τα TTL.
Επίλυση προβλημάτων
| Συμπτωμα | Έλεγχος |
|---|---|
Αποτυχία ανάλυσης του DocumentConverter | Η εγγραφή ConverterPlugin συνέβη μέσα στο AddDoconut() |
| Η εφαρμογή αποτυγχάνει κατά την εκκίνηση | Η φορτωμένη άδεια χορηγεί Converter |
| Η μετατροπή ρεύματος λέει ότι η μορφή δεν υποστηρίζεται | Το sourceExtension περιλαμβάνει την αρχική τελεία |
| Το JavaScript του widget φορτώνεται αλλά τα αιτήματα επιστρέφουν 404 | Το AddConverterWidget() δεν κλήθηκε |
| Τα αιτήματα του widget χρησιμοποιούν λανθασμένο URL | Το basePath ταιριάζει με το κλαδί όπου το UseDoconut() είναι αντιστοιχισμένο |
| Ο προορισμός λείπει | Χρησιμοποιήστε το allowedTargets που επιστρέφεται από το convert=open· δεν υποστηρίζει κάθε πηγή κάθε enum στόχο |
| Η λήψη έληξε | Επαναλάβετε convert=open/convert=run· τα διακριτικά αποθήκευσης είναι σκόπιμα προσωρινά |
Υδατογράφημα
Με την εγγραφή του ConverterPlugin, η άδεια του κεντρικού είναι σε μία από τις τρεις καταστάσεις:
| Κατάσταση άδειας | Πύλη εκκίνησης | Έξοδος μετατροπής |
|---|---|---|
Άδεια πληρωμένου θεατή που χορηγεί Converter, εντός της περιόδου ισχύος της | Περνά | Καθαρό — watermarked: false |
| Ενεργή άδεια αξιολόγησης (demo/NFR) | Περνά | Μετατρέπει επιτυχώς, σφραγισμένο με το υδατογράφημα αξιολόγησης — watermarked: true |
Χωρίς άδεια, ένα παλιό αρχείο TRIAL, ή μια μη προσωρινή άδεια που δεν χορηγεί Converter | Η εφαρμογή δεν ξεκινά ποτέ — η παραπάνω πύλη εκκίνησης πετάει | — |
| Ληγμένη προσωρινή/δωρεάν άδεια | Η εγγραφή επιβιώνει μετά τη λήξη | Μετατρέπει με το υδατογράφημα αξιολόγησης — watermarked: true |
Και οι δύο διαδρομές κλήσης υπολογίζουν τη σημαία από τον ίδιο κανόνα: η C# πρόσοψη DocumentConverter την παράγει εσωτερικά από την κατάσταση IsViewerLicensed και IsTemporary της άδειας, και ο χειριστής ?convert=run του widget εκτελεί τον ισοδύναμο έλεγχο (IsViewerLicensed && !IsTrial && !IsTemporary) για να γεμίσει το πεδίο watermarked που επιστρέφει. Μια ενσωμάτωση μπορεί να δημιουργηθεί και να δοκιμαστεί end-to-end με άδεια αξιολόγησης πριν από την αγορά — μόνο τα bytes εξόδου αλλάζουν.
Ήταν αυτή η σελίδα χρήσιμη;