Plugin Chuyển Đổi
Chuyển đổi tài liệu sang 24 định dạng đích
Plugin Converter biến Doconut thành một dịch vụ chuyển đổi tài liệu. Nó cung cấp động cơ phía sau giao diện công cộng DocumentConverter, và — khi chọn — một widget có thể chèn sẵn với hợp đồng HTTP riêng, cho phép bạn chuyển đổi tài liệu từ C#, từ widget, hoặc từ giao diện phía trước mà bạn tự viết.
Cài đặt gói
Cài đặt plugin Converter mới nhất và ổn định:
dotnet add package Doconut.NET6.ConverterĐể cố định plugin vào bản phát hành 26.7.0 hiện tại, truyền phiên bản riêng:
dotnet add package Doconut.NET6.Converter --version 26.7.0Giữ gói Converter ở cùng phiên bản với Doconut.NET6. ID gói là
Doconut.NET6.Converter; .26.7.0 chỉ xuất hiện trong tên tệp .nupkg đã tải xuống.
Đăng ký plugin
Không có phương thức AddConverter() — mô hình plugin của Doconut là đồng nhất. Mỗi plugin, bao gồm Converter, đều đăng ký theo cùng một cách: gọi AddPlugin<TPlugin>() trong AddDoconut(). ConverterPlugin được cung cấp trong gói NuGet riêng, Doconut.NET6.Converter, được cài đặt cùng với gói trình xem cơ bản.
builder.Services.AddDoconut(options =>
{
options.LicensePath = "Doconut.Viewer.lic";
options.AddPlugin<Doconut.Plugins.Converter.ConverterPlugin>();
});Lệnh này sẽ ném lỗi khi khởi động nếu thiếu giấy phép, tệp
TRIALcũ, hoặc giấy phép không tạm thời không cung cấp khả năngConverter— mộtInvalidOperationExceptionđược phát sinh từ bên trongAddDoconut(), trước khi ứng dụng phục vụ yêu cầu. Đăng ký Demo/NFR tạm thời được chấp nhận; sau khi hết hạn theo lịch, việc chuyển đổi vẫn khả dụng với đầu ra có watermark. Không có mức miễn phí ẩn. Xem Cài đặt giấy phép để biết cách tải giấy phép.
Chuyển đổi từ C#
Mỗi lần chuyển đổi trả về một MemoryStream có thể tìm kiếm, vị trí tại 0, sẵn sàng đọc hoặc sao chép ngay lập tức. Lấy DocumentConverter từ DI ở bất kỳ nơi nào bạn cần — nó không có trạng thái theo thiết kế, vì vậy một thể hiện duy nhất có thể tái sử dụng an toàn giữa các yêu cầu.
// Tiêm DocumentConverter; constructor của nó là internal, vì vậy không bao giờ `new` nó.
Stream pdf = await converter.ConvertAsync("contract.docx", ConversionTarget.Pdf, ct: ct);// sourceExtension bao gồm dấu chấm đầu tiên. password là null trừ khi tài liệu được bảo vệ.
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);Hai chi tiết dễ bị nhầm lẫn: sourceExtension trên phương thức quá tải stream phải bao gồm dấu chấm đầu tiên (".xlsx", không phải "xlsx") — trình chuyển đổi sẽ so sánh nó với danh mục định dạng và một phần mở rộng không có dấu chấm sẽ không được giải quyết. Và mặc dù tên gọi, WordToHtmlAsync trả về Task<Stream>, không phải Task<string> — bạn nhận được tài liệu HTML (hình ảnh được nhúng dưới dạng Base64) dưới dạng stream, giống như mọi kết quả chuyển đổi khác.
Định dạng mục tiêu
Pdf, Docx, Doc, Html, Xlsx, Pptx, Png, Jpeg, Csv, Tiff, Bmp, Gif, Svg, Xml,
Txt, Xls, Jp2, Rtf, Odt, Ods, Odp, Epub, Xps, WebpKhông phải mọi nguồn đều chuyển đổi sang mọi mục tiêu — plugin ánh xạ mỗi họ định dạng nguồn (Word, Excel, PowerPoint, PDF, CAD, Image, Email, Diagram, Project/Task, PSD, tài liệu web) tới bộ mục tiêu cho phép cố định của nó. Đừng mã cứng enum này làm danh sách mục tiêu cho UI của bạn: ?convert=open trả về allowedTargets thực tế cho bất kỳ tệp nào vừa được tải lên, và đó là gì nên điều khiển bộ chọn.
Tiện ích nhúng
Các endpoint ?convert=open|run|download của tiện ích được thiết lập theo chế độ chọn lựa và bị vô hiệu hoá mặc định — an toàn theo mặc định. Hãy bật chúng phía máy chủ, cùng với việc đăng ký 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>Nếu không có AddConverterWidget(), ba endpoint ?convert= sẽ trả lời 404 — nhưng tệp JS vẫn được phục vụ bất kể (đó là một tài nguyên tĩnh nhúng thuần; chỉ các endpoint mà nó giao tiếp mới bị giới hạn). AddConverterWidget() vẫn yêu cầu plugin Converter được đăng ký và một giấy phép cung cấp Converter — nó không tự động cấp quyền chuyển đổi.
Tùy chỉnh tiện ích
Các tùy chọn khởi tạo được truyền cho Doconut.convert(selector, options):
| Tùy chọn | Kiểu | Mặc định | Ghi chú |
|---|---|---|---|
basePath | string | /doconut | Đường dẫn cơ sở cho các endpoint ?convert=; nó phải khớp với nhánh ASP.NET nơi UseDoconut() thực sự được gắn (thông thường được điều phối qua MiddlewarePath) |
resPath | string | /doconut-res | Được chấp nhận để duy trì tính nhất quán cấu hình với các tiện ích Doconut khác; tiện ích chuyển đổi hiện không tạo URL nào từ nó |
maxUploadMb | number | 25 | Chỉ kiểm tra trước phía client — từ chối tệp quá lớn trước khi tải lên. Máy chủ áp dụng giới hạn riêng của mình một cách độc lập và trả lời 413 nếu vượt quá |
licenseUrl | string | null | null | Khi được đặt, chuyển thông báo watermark trên màn hình kết quả thành một liên kết tới URL này |
labels | object | {} | Ghi đè bất kỳ phần nào của các chuỗi mặc định tiếng Anh của tiện ích (văn bản thả, nút, thông báo aria-live, thông báo lỗi) |
Các callback:
| Hàm gọi lại | Khi nào kích hoạt | Dữ liệu |
|---|---|---|
onReady() | Tiện ích đã hiển thị màn hình chờ/đổ | — |
onSourceLoaded({ token, pages, sourceExt, allowedTargets }) | ?convert=open thành công | token phiên nguồn, số trang, phần mở rộng nguồn (không có dấu chấm đầu), danh sách mục tiêu cho phép |
onConverted({ downloadToken, resultToken, resultPages, downloadName, watermarked, target }) | ?convert=run thành công | các trường giống như phản hồi chạy, cộng thêm target được yêu cầu |
onDownload({ downloadName, downloadToken }) | Người dùng nhấp vào liên kết Tải xuống | được kích hoạt cùng với việc tải xuống gốc của trình duyệt — không can thiệp hay thay thế nó |
onError({ phase, message }) | Yêu cầu mở hoặc chạy thất bại | phase là 'open' hoặc 'run'; message là lỗi máy chủ đã được làm sạch (hoặc thông báo phía client cho kiểm tra kích thước tải lên) |
Doconut.convert() trả về chính thể hiện của tiện ích — giữ lại để điều khiển tiện ích bằng chương trình:
const conv = Doconut.convert('#doconut-convert', { basePath: '/doconut' });
conv.reset(); // quay lại màn hình idle/drop; không kích hoạt lại onReady
conv.loadFile(file); // bắt đầu luồng với một đối tượng File; không làm gì trừ khi hiện đang ở trạng thái idle
conv.destroy(); // gỡ bỏ các listener, làm trống mount; thể hiện này không thể sử dụng được sau đâyXây dựng giao diện người dùng của riêng bạn
Tiện ích chỉ là một client cho hợp đồng HTTP này — hãy xây dựng giao diện người dùng riêng của bạn trực tiếp trên đó để có trải nghiệm khác. Ba route đều nằm dưới nhánh ASP.NET nơi UseDoconut() được gắn (thông thường /doconut):
| Đường dẫn | Mục đích | Phản hồi thành công |
|---|---|---|
POST ?convert=open (multipart, field file) | Tải lên và mở tài liệu nguồn để xem trước | 200 — { token, pages, sourceExt, allowedTargets } |
POST ?token=<token>&convert=run&target=<ext> | Chuyển đổi nguồn đã lưu thành target | 200 — { downloadToken, resultToken, resultPages, downloadName, watermarked } |
GET ?convert=download&token=<downloadToken> | Phát luồng tệp đã chuyển đổi | 200 — byte tệp, Content-Disposition: attachment, Cache-Control: no-store |
Các byte nguồn đã tải lên được lưu tạm phía máy chủ với thời gian sống (TTL) 30 phút; khi khoảng thời gian này hết, run trả lời 404 và tệp phải được mở lại. Kết quả đã chuyển đổi tồn tại trong cùng kho lưu — downloadToken nhận được cửa sổ 30‑phút mới khi quá trình chuyển đổi hoàn tất — trong khi resultToken là một token phiên xem thông thường, thời gian tồn tại của nó theo bộ nhớ đệm phiên của viewer, độc lập với kho lưu.
sourceExt trong phản hồi open không có dấu chấm đầu (ví dụ "docx") — ngược lại với quy ước của tham số sourceExtension trên DocumentConverter.ConvertAsync, yêu cầu có dấu chấm.
Các chế độ lỗi, được nhóm theo đường dẫn:
| Đường dẫn | Trạng thái | Khi nào | Nội dung |
|---|---|---|---|
| bất kỳ | 404 | Tiện ích chưa được bật (AddConverterWidget() chưa bao giờ được gọi) — được kiểm tra trước khi bất kỳ ba route nào được xử lý | chỉ trạng thái |
| bất kỳ | 405 | Phương thức HTTP sai (open/run yêu cầu POST; download yêu cầu GET) | chỉ trạng thái |
open | 413 | Tệp tải lên vượt quá MaxUploadMb | { "error": "File is too large." } |
open | 400 | Không có body multipart, không có tệp, hoặc phần mở rộng nguồn không thể chuyển đổi | { "error": "..." } |
run | 400 | Token dạng sai (không phải GUID), hoặc target không phân tích được thành ConversionTarget | { "error": "Invalid token." } / { "error": "Unknown target format." } |
run | 400 | target không có trong allowedTargets của nguồn | { "error": "That target format is not available for this file." } |
run | 404 | Tải lên đã lưu đã hết hạn (TTL 30‑phút) hoặc token chưa bao giờ được mở | { "error": "Upload expired — please re-open the file." } |
open, run | 500 | Xử lý thất bại nội bộ | { "error": "<sanitized message>" } — đã được làm sạch giống như mọi đường lỗi Doconut khác; không bao giờ rò rỉ tên engine nội bộ |
download | 400 | Token dạng sai (không phải GUID) | chỉ trạng thái |
download | 404 | Token tải xuống không xác định hoặc đã hết hạn | chỉ trạng thái |
Quyền sở hữu tài nguyên
Bộ chuyển đổi trả về một MemoryStream có thể tìm kiếm được, được đặt ở vị trí zero. Người gọi sở hữu luồng đó và nên giải phóng nó sau khi sao chép hoặc trả lại nội dung. Dịch vụ DocumentConverter tự nó không có trạng thái và được lấy từ dependency injection; không tự tạo hoặc giải phóng dịch vụ này một cách thủ công.
Đối với widget web, các kho lưu tải lên và tải xuống có TTL độc lập 30 phút. Một resultToken của người xem tuân theo thời gian sống của phiên người xem. Đóng kết quả của người xem không xóa kho tải xuống vẫn còn hợp lệ, và việc đặt lại widget trình duyệt không kéo dài TTL nào cả.
Khắc phục sự cố
| Triệu chứng | Kiểm tra |
|---|---|
Giải quyết DocumentConverter thất bại | Đăng ký ConverterPlugin đã xảy ra bên trong AddDoconut() |
| Ứng dụng thất bại khi khởi động | Giấy phép đã tải cho phép Converter |
| Chuyển đổi luồng cho biết định dạng không được hỗ trợ | sourceExtension bao gồm dấu chấm đầu |
| JavaScript của widget tải nhưng các yêu cầu trả về 404 | AddConverterWidget() không được gọi |
| Các yêu cầu widget sử dụng URL sai | basePath khớp với nhánh mà UseDoconut() được ánh xạ |
| Mục tiêu bị thiếu | Sử dụng allowedTargets được trả về bởi convert=open; không phải mọi nguồn đều hỗ trợ mọi mục tiêu enum |
| Tải xuống đã hết hạn | Lặp lại convert=open/convert=run; các token lưu tạm được tạo có tính tạm thời cố ý |
Đánh dấu nước
Khi đã đăng ký ConverterPlugin, giấy phép của máy chủ nằm trong một trong ba trạng thái:
| Trạng thái giấy phép | Cổng khởi động | Kết quả chuyển đổi |
|---|---|---|
Giấy phép người xem trả phí cho phép Converter, trong thời gian hiệu lực | Đạt | Sạch — watermarked: false |
| Giấy phép đánh giá hoạt động (demo/NFR) | Đạt | Chuyển đổi thành công, được dán dấu watermark đánh giá — watermarked: true |
Không có giấy phép, một tệp TRIAL cũ, hoặc một giấy phép không tạm thời không cho phép Converter | Ứng dụng không bao giờ khởi động — cổng khởi động mô tả ở trên ném lỗi | — |
| Giấy phép tạm thời/Demo đã hết hạn | Đăng ký tồn tại sau khi hết hạn | Chuyển đổi với dấu watermark đánh giá — watermarked: true |
Cả hai đường gọi đều tính cờ từ cùng một quy tắc: lớp façade C# DocumentConverter suy ra nó nội bộ từ trạng thái IsViewerLicensed và IsTemporary của giấy phép, và trình xử lý ?convert=run của widget thực hiện kiểm tra tương đương (IsViewerLicensed && !IsTrial && !IsTemporary) để điền trường watermarked mà nó trả về. Một tích hợp có thể được xây dựng và kiểm thử đầu cuối trên giấy phép đánh giá trước khi mua — chỉ có các byte đầu ra thay đổi.
Trang này có hữu ích không?