Πρόσθετο Converter
Μετατρέψτε έγγραφα σε 24 μορφές προορισμού
Το πρόσθετο Converter μετατρέπει το Doconut σε μια υπηρεσία μετατροπής εγγράφων. Παρέχει τη μηχανή πίσω από τη δημόσια διεπαφή DocumentConverter και, με επιλογή, ένα ενσωματωμένο widget με το δικό του συμβόλαιο HTTP, ώστε να μπορείτε να μετατρέπετε έγγραφα από C#, από το widget ή από ένα frontend που γράφετε εσείς.
Εγκατάσταση του πακέτου
Εγκαταστήστε το πιο πρόσφατο σταθερό πρόσθετο Converter:
dotnet add package Doconut.NET8.ConverterΓια να «καρφώσετε» το πρόσθετο στην τρέχουσα έκδοση 26.7.0, περάστε την έκδοση ξεχωριστά:
dotnet add package Doconut.NET8.Converter --version 26.7.0Διατηρήστε το πακέτο Converter στην ίδια έκδοση με το Doconut.NET8. Το αναγνωριστικό του πακέτου είναι
Doconut.NET8.Converter; το .26.7.0 εμφανίζεται μόνο στο όνομα του ληφθέντος αρχείου .nupkg.
Καταχώριση του πρόσθετου
Δεν υπάρχει μέθοδος AddConverter() — το μοντέλο πρόσθετων του Doconut είναι ομοιόμορφο. Κάθε πρόσθετο, συμπεριλαμβανομένου του Converter, καταχωρίζεται με τον ίδιο τρόπο: καλέστε 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 όπου το χρειάζεστε — είναι χωρίς κατάσταση (stateless) κατά σχεδίαση, επομένως ένα μόνο στιγμιότυπο είναι ασφαλές για επαναχρησιμοποίηση μεταξύ αιτήσεων.
// Inject DocumentConverter; 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);Δύο λεπτομέρειες που συχνά παραβλέπουμε: το 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 για το αρχείο που μόλις ανεβάστηκε, και αυτά πρέπει να τροφοδοτούν το selector.
Ενσωματωμένο widget
Τα endpoints του widget ?convert=open|run|download είναι προαιρετικά και είναι απενεργοποιημένα από προεπιλογή — ασφαλή από την αρχή. Ενεργοποιήστε τα στο server, μαζί με την καταχώριση του πρόσθετου:
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(), τα τρία endpoints ?convert= επιστρέφουν 404 — αλλά το αρχείο JS εξακολουθεί να σερβίρεται (είναι απλός ενσωματωμένος στατικός πόρος· μόνο τα endpoints που χρησιμοποιεί είναι περιορισμένα). Το AddConverterWidget() απαιτεί ακόμη να είναι καταχωρημένο το πρόσθετο Converter και μια άδεια που παρέχει Converter — δεν παρέχει δικαιώματα μετατροπής από μόνο του.
Προσαρμογή του widget
Αρχικές επιλογές που περνιούνται στο Doconut.convert(selector, options):
| Επιλογή | Τύπος | Προεπιλογή | Σημειώσεις |
|---|---|---|---|
basePath | string | /doconut | Βασική διαδρομή για τα endpoints ?convert=· πρέπει να ταιριάζει με το κλαδί 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, μηνύματα σφάλματος) |
Αντιδράσεις (Callbacks):
| Αντίδραση | Συμβαίνει όταν | Φορτίο |
|---|---|---|
onReady() | Το widget έχει αποδώσει την οθόνη αδράνειας/πτώσης | — |
onSourceLoaded({ token, pages, sourceExt, allowedTargets }) | Η κλήση ?convert=open είναι επιτυχής | token συνεδρίας πηγής, αριθμός σελίδων, επέκταση πηγής (χωρίς την αρχική τελεία), λίστα επιτρεπόμενων στόχων |
onConverted({ downloadToken, resultToken, resultPages, downloadName, watermarked, target }) | Η κλήση ?convert=run είναι επιτυχής | ίδια πεδία με την απόκριση run, συν το target που ζητήθηκε |
onDownload({ downloadName, downloadToken }) | Ο χρήστης κάνει κλικ στον σύνδεσμο Λήψης | πυροδοτείται μαζί με τη φυσική λήψη του προγράμματος περιήγησης — δεν παρεμβαίνει ή την αντικαθιστά |
onError({ phase, message }) | Αποτυχία αίτησης open ή run | phase είναι 'open' ή 'run'; message είναι το αποκατεστημένο σφάλμα του διακομιστή (ή μήνυμα στην πλευρά του πελάτη για τον προ‑έλεγχο μεγέθους) |
Το Doconut.convert() επιστρέφει το ίδιο το στιγμιότυπο του widget — κρατήστε το για προγραμματιστικό έλεγχο του widget:
const conv = Doconut.convert('#doconut-convert', { basePath: '/doconut' });
conv.reset(); // επιστρέφει στην οθόνη αδράνειας/πτώσης· δεν ξαναπυροδοτεί το onReady
conv.loadFile(file); // ξεκινά τη ροή με ένα αντικείμενο File· δεν κάνει τίποτα αν δεν είναι σε κατάσταση αδράνειας
conv.destroy(); // αφαιρεί listeners, αδειάζει το mount· το στιγμιότυπο δεν μπορεί να ξαναχρησιμοποιηθείΔημιουργήστε το δικό σας 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 της πηγής αποθηκεύονται προσωρινά στον διακομιστή με διάρκεια ζωής 30 λεπτών. Όταν λήξει αυτό το παράθυρο, το run επιστρέφει 404 και το αρχείο πρέπει να ξαναανοίξει. Το μετατρεπόμενο αποτέλεσμα παραμένει στην ίδια προσωρινή αποθήκη — το downloadToken παίρνει το δικό του φρέσκο παράθυρο 30 λεπτών όταν ολοκληρωθεί η μετατροπή — ενώ το resultToken είναι ένα συνηθισμένο token συνεδρίας προβολέα, του οποίου η διάρκεια ακολουθεί την κρυφή μνήμη του προβολέα, ανεξάρτητα από την προσωρινή αποθήκη.
Το sourceExt στην απόκριση open δεν περιλαμβάνει την αρχική τελεία (π.χ. "docx"), το αντίθετο του sourceExtension που απαιτείται στη μέθοδο DocumentConverter.ConvertAsync.
Λειτουργίες αποτυχίας, ομαδοποιημένες ανά διαδρομή
| Διαδρομή | Κατάσταση | Πότε | Σώμα |
|---|---|---|---|
| οποιαδήποτε | 404 | Το widget δεν είναι ενεργοποιημένο (AddConverterWidget() δεν κλήθηκε) — ελέγχεται πριν από οποιαδήποτε από τις τρεις διαδρομές | μόνο status |
| οποιαδήποτε | 405 | Λάθος HTTP verb (open/run απαιτούν POST; download απαιτεί GET) | μόνο status |
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 | Η αποθηκευμένη μεταφόρτωση έχει λήξει (30‑λεπτο TTL) ή το token δεν είχε ποτέ ανοίξει | { "error": "Upload expired — please re-open the file." } |
open, run | 500 | Εσωτερική αποτυχία επεξεργασίας | { "error": "<sanitized message>" } — sanitized με τον ίδιο τρόπο όπως κάθε άλλη διαδρομή σφάλματος Doconut· δεν διαρρέει εσωτερικά ονόματα μηχανής |
download | 400 | Κακοδιαμορφωμένο token (δεν είναι GUID) | μόνο status |
download | 404 | Άγνωστο ή ληγμένο token λήψης | μόνο status |
Ιδιοκτησία πόρων
Ο μετατροπέας επιστρέφει ένα αναζητήσιμο MemoryStream τοποθετημένο στο 0. Ο καλούντας είναι υπεύθυνος για το stream και πρέπει να το διαγράψει (dispose) μετά την αντιγραφή ή την επιστροφή του περιεχομένου. Η υπηρεσία DocumentConverter είναι χωρίς κατάσταση και λαμβάνεται μέσω dependency injection· μην τη δημιουργείτε ή τη διαγράφετε χειροκίνητα.
Για το web widget, οι προσωρινές αποθήκες ανεβάσματος και λήψης έχουν ανεξάρτητες διάρκειες 30 λεπτών. Ένα resultToken προβολέα ακολουθεί τη διάρκεια ζωής της συνεδρίας του προβολέα. Το κλείσιμο ενός αποτελέσματος προβολέα δεν διαγράφει μια ακόμη έγκυρη αποθήκη λήψης, και η επαναφορά του widget στον περιηγητή δεν επεκτείνει κανένα από τα δύο TTL.
Επίλυση προβλημάτων
| Συμπτωμα | Έλεγχος |
|---|---|
Αποτυχία ανάκτησης DocumentConverter | Η καταχώριση ConverterPlugin έγινε μέσα στο AddDoconut() |
| Η εφαρμογή αποτυγχάνει κατά την εκκίνηση | Η φορτωμένη άδεια παρέχει Converter |
| Η μετατροπή ροής αναφέρει ότι η μορφή δεν υποστηρίζεται | Το sourceExtension περιλαμβάνει την αρχική τελεία |
| Το JavaScript του widget φορτώνεται αλλά τα αιτήματα επιστρέφουν 404 | Το AddConverterWidget() δεν κλήθηκε |
| Τα αιτήματα του widget χρησιμοποιούν λάθος URL | Το basePath ταιριάζει με το κλαδί όπου το UseDoconut() είναι προσαρτημένο |
| Λείπει στόχος | Χρησιμοποιήστε τα allowedTargets που επιστρέφει το convert=open; δεν υποστηρίζεται κάθε στόχος για κάθε πηγή |
| Η λήψη έληξε | Επαναλάβετε convert=open/convert=run; τα tokens αποθήκευσης είναι σκόπιμα προσωρινά |
Υδατογράφημα
Με το ConverterPlugin καταχωρημένο, η άδεια του κεντρικού συστήματος βρίσκεται σε μία από τις τρεις καταστάσεις:
| Κατάσταση άδειας | Πύλη εκκίνησης | Έξοδος μετατροπής |
|---|---|---|
Πληρωμένη άδεια προβολέα που παρέχει Converter, εντός της περιόδου ισχύος | Επιτυγχάνει | Καθαρή — watermarked: false |
| Ενεργή αξιολόγηση (demo/NFR) άδεια | Επιτυγχάνει | Μετατρέπει επιτυχώς, με υδατογράφημα αξιολόγησης — watermarked: true |
Χωρίς άδεια, παλαιό αρχείο TRIAL, ή μη‑προσωρινή άδεια που δεν παρέχει Converter | Η εφαρμογή δεν εκκινεί — η πύλη εκκίνησης που περιγράφηκε παραπάνω ρίχνει εξαίρεση | — |
| Ληγμένη προσωρινή/demo άδεια | Η καταχώριση παραμένει μετά τη λήξη | Μετατρέπει με υδατογράφημα αξιολόγησης — watermarked: true |
Και οι δύο διαδρομές υπολογίζουν τη σημαία από τον ίδιο κανόνα: η C# διεπαφή DocumentConverter την παράγει εσωτερικά από τις ιδιότητες IsViewerLicensed και IsTemporary της άδειας, ενώ ο χειριστής του widget για ?convert=run κάνει τον ισοδύναμο έλεγχο (IsViewerLicensed && !IsTrial && !IsTemporary) για να συμπληρώσει το πεδίο watermarked που επιστρέφει. Μια ενσωμάτωση μπορεί να χτιστεί και να δοκιμαστεί από άκρη σε άκρη με μια άδεια αξιολόγησης πριν από την αγορά — μόνο τα bytes εξόδου αλλάζουν.
Ήταν αυτή η σελίδα χρήσιμη;