ปลั๊กอินแปลงไฟล์
แปลงเอกสารเป็น 24 รูปแบบเป้าหมาย
ปลั๊กอิน Converter ทำให้ Doconut กลายเป็นบริการแปลงเอกสาร. มันเป็นส่วนประกอบของเอนจินที่อยู่เบื้องหลังส่วนหน้าสาธารณะ DocumentConverter, และ — ตามต้องการ — วิดเจ็ตแบบ drop‑in ที่มีสัญญา HTTP ของตนเอง, เพื่อให้คุณสามารถแปลงเอกสารจาก C#, จากวิดเจ็ต, หรือจากส่วนหน้า (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 ที่ใดก็ได้ที่คุณต้องการ — มันไม่มีสถานะตามการออกแบบ, ดังนั้นอินสแตนซ์เดียวจึงปลอดภัยต่อการใช้ซ้ำในหลายคำขอ.
// Inject DocumentConverter; ตัวสร้างของมันเป็น internal, ดังนั้นห้าม `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 บน overload ของสตรีมต้องรวมจุดนำหน้า (".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, เอกสารเว็บ) ไปยังชุดเป้าหมายที่อนุญาตแบบคงที่ของมันเอง. อย่า hardcode enum นี้เป็นรายการเป้าหมายของ UI ของคุณ: ?convert=open คืนค่า allowedTargets ที่แท้จริงสำหรับไฟล์ที่เพิ่งอัปโหลด, และนั่นควรเป็นตัวกำหนดตัวเลือก.
วิดเจ็ตแบบ Drop‑in
เอ็นด์พอยต์ ?convert=open|run|download ของวิดเจ็ตเป็นแบบเลือกใช้และถูกปิดใช้งานโดยค่าเริ่มต้น — ปลอดภัยโดยอัตโนมัติ เปิดใช้งานพวกมันบนเซิร์ฟเวอร์พร้อมกับการลงทะเบียนปลั๊กอิน:
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= ทั้งสามจะตอบกลับด้วย 404 — แต่ไฟล์ JS เองยังคงให้บริการอยู่ (เป็นทรัพยากรสแตติกแบบฝังธรรมดา; มีเพียงเอ็นด์พอยต์ที่มันสื่อสารที่ถูกจำกัด). AddConverterWidget() ยังต้องการให้ปลั๊กอิน Converter ถูกลงทะเบียนและใบอนุญาตที่ให้สิทธิ์ Converter — ซึ่งไม่ได้ให้สิทธิ์การแปลงโดยตัวเอง.
ปรับแต่งวิดเจ็ต
ตัวเลือกการเริ่มต้นที่ส่งไปยัง Doconut.convert(selector, options):
| ตัวเลือก | ประเภท | ค่าเริ่มต้น | หมายเหตุ |
|---|---|---|---|
basePath | string | /doconut | เส้นทางฐานสำหรับเอ็นด์พอยต์ ?convert=; ต้องตรงกับสาขา ASP.NET ที่ UseDoconut() ถูกเมานท์จริง (โดยปกติประสานงานผ่าน MiddlewarePath) |
resPath | string | /doconut-res | รับเพื่อความสอดคล้องของการกำหนดค่ากับวิดเจ็ต Doconut อื่น ๆ; วิดเจ็ตตัวแปลงในขณะนี้ไม่ได้สร้าง URL ใด ๆ จากมัน |
maxUploadMb | number | 25 | ตรวจสอบล่วงหน้าที่ฝั่งไคลเอนต์เท่านั้น — ปฏิเสธไฟล์ที่ใหญ่เกินขนาดก่อนอัปโหลด. เซิร์ฟเวอร์บังคับใช้ขีดจำกัดของตนเองอย่างอิสระและตอบกลับด้วย 413 หากเกิน |
licenseUrl | string | null | null | เมื่อกำหนดค่า จะเปลี่ยนข้อความลายน้ำบนหน้าจอผลลัพธ์ให้เป็นลิงก์ไปยัง URL นี้ |
labels | object | {} | แทนที่ส่วนใดส่วนหนึ่งของสตริงค่าเริ่มต้นภาษาอังกฤษของวิดเจ็ต (ข้อความดรอป, ปุ่ม, การประกาศ aria‑live, ข้อความแสดงข้อผิดพลาด) |
คอลแบ็ก:
| คอลแบ็ก | เกิดเมื่อ | ข้อมูลที่ส่ง |
|---|---|---|
onReady() | วิดเจ็ตได้แสดงหน้าจอว่าง/ดรอป | — |
onSourceLoaded({ token, pages, sourceExt, allowedTargets }) | ?convert=open succeeds | โทเค็นเซสชันของแหล่ง, จำนวนหน้า, ส่วนขยายของแหล่ง (ไม่มีจุดนำหน้า), รายการเป้าหมายที่อนุญาต |
onConverted({ downloadToken, resultToken, resultPages, downloadName, watermarked, target }) | ?convert=run succeeds | ฟิลด์เดียวกันกับการตอบกลับการรัน, พร้อมกับ target ที่ร้องขอ |
onDownload({ downloadName, downloadToken }) | ผู้ใช้คลิกลิงก์ดาวน์โหลด | ทำงานพร้อมกับการดาวน์โหลดโดยเนทีฟของเบราว์เซอร์ — ไม่ดักจับหรือแทนที่ |
onError({ phase, message }) | คำขอเปิดหรือรันล้มเหลว | phase คือ 'open' หรือ 'run'; message คือข้อผิดพลาดจากเซิร์ฟเวอร์ที่ทำความสะอาดแล้ว (หรือข้อความจากไคลเอนต์สำหรับการตรวจสอบขนาดอัปโหลดล่วงหน้า) |
Doconut.convert() คืนค่าอินสแตนซ์ของวิดเจ็ตเอง — เก็บไว้เพื่อควบคุมวิดเจ็ตโดยโปรแกรม:
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 จะไม่สามารถใช้งานได้หลังจากนี้สร้างส่วนหน้าของคุณเอง
วิดเจ็ตเป็นเพียงไคลเอนต์สำหรับสัญญา HTTP นี้ — สร้างส่วนหน้าของคุณเองโดยตรงเพื่อประสบการณ์ผู้ใช้ที่แตกต่าง. ทั้งสามเส้นทางอยู่ภายใต้สาขา ASP.NET ที่ UseDoconut() ถูกเมานท์ (โดยปกติ /doconut):
| เส้นทาง | วัตถุประสงค์ | การตอบสนองสำเร็จ |
|---|---|---|
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 — ไบต์ของไฟล์, Content-Disposition: attachment, Cache-Control: no-store |
ไบต์ของแหล่งที่อัปโหลดจะถูกเก็บไว้บนเซิร์ฟเวอร์ด้วย TTL 30 นาที; เมื่อช่วงเวลานั้นหมด, run จะตอบกลับด้วย 404 และไฟล์ต้องถูกเปิดใหม่. ผลลัพธ์ที่แปลงแล้วอยู่ใน stash เดียวกัน — downloadToken จะได้รับหน้าต่าง 30 นาทีใหม่เมื่อการแปลงเสร็จ — ในขณะที่ resultToken เป็นโทเค็นเซสชันของผู้ชมทั่วไปที่อายุการใช้งานตามแคชเซสชันของผู้ชม, แยกจาก stash.
sourceExt ในการตอบกลับ open ไม่มีจุดนำหน้า (เช่น "docx") — เป็นแนวปฏิบัติที่ตรงกันข้ามกับพารามิเตอร์ sourceExtension บน DocumentConverter.ConvertAsync ซึ่งต้องมีจุดนำหน้า.
โหมดความล้มเหลว, แบ่งตามเส้นทาง:
| เส้นทาง | สถานะ | เมื่อ | เนื้อหา |
|---|---|---|---|
| ใดๆ | 404 | วิดเจ็ตไม่ได้เปิดใช้งาน (AddConverterWidget() ไม่เคยถูกเรียก) — ตรวจสอบก่อนที่เส้นทางใด ๆ จะถูกส่ง | เพียงสถานะ |
| ใดๆ | 405 | HTTP verb ไม่ถูกต้อง (open/run ต้องการ POST; download ต้องการ GET) | เพียงสถานะ |
open | 413 | ไฟล์ที่อัปโหลดเกิน MaxUploadMb | { "error": "File is too large." } |
open | 400 | ไม่มี multipart body, ไม่มีไฟล์, หรือส่วนขยายของแหล่งที่ไม่สามารถแปลงได้ | { "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 | โทเค็นการดาวน์โหลดไม่ทราบหรือหมดอายุ | เพียงสถานะ |
การเป็นเจ้าของทรัพยากร
ตัวแปลงจะคืนค่า MemoryStream ที่สามารถเลื่อนตำแหน่งได้และอยู่ที่ศูนย์ ผู้เรียกเป็นเจ้าของสตรีมนี้และควรทำการ dispose หลังจากคัดลอกหรือคืนค่าเนื้อหาของมัน บริการ DocumentConverter เองเป็นแบบไม่มีสถานะและได้รับการแก้ไขจาก dependency injection; อย่าสร้างหรือทำการ dispose บริการด้วยตนเอง.
สำหรับเว็บวิดเจ็ต, ค่าซ่อนการอัปโหลดและดาวน์โหลดมี TTL แยกกันเป็นเวลา 30 นาที ตัวดู resultToken จะปฏิบัติตามอายุเซสชันของผู้ดูแทน การปิดผลลัพธ์ของผู้ดูจะไม่ลบค่าซ่อนการดาวน์โหลดที่ยังคงมีอายุอยู่, และการรีเซ็ตวิดเจ็ตของเบราว์เซอร์จะไม่ขยาย TTL ใด ๆ
การแก้ไขปัญหา
| อาการ | การตรวจสอบ |
|---|---|
การแก้ไข DocumentConverter ล้มเหลว | การลงทะเบียน ConverterPlugin เกิดขึ้นภายใน AddDoconut() |
| แอปพลิเคชันล้มเหลวระหว่างการเริ่มต้น | ใบอนุญาตที่โหลดมามอบสิทธิ์ Converter |
| การแปลงสตรีมบอกว่ารูปแบบไม่รองรับ | sourceExtension มีจุดนำหน้า |
| JavaScript ของวิดเจ็ตโหลดได้แต่คำขอคืนค่า 404 | AddConverterWidget() ไม่ได้ถูกเรียก |
| คำขอของวิดเจ็ตใช้ 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 ของวิดเจ็ตทำการตรวจสอบเทียบเท่า (IsViewerLicensed && !IsTrial && !IsTemporary) เพื่อเติมฟิลด์ watermarked ที่มันคืนค่า การบูรณาการสามารถสร้างและทดสอบแบบ end-to-end บนใบอนุญาตการประเมินก่อนการซื้อ — เพียงแค่ไบต์ผลลัพธ์ที่เปลี่ยนแปลง
หน้านี้เป็นประโยชน์หรือไม่?