Plugin Konverter

Ubah dokumen menjadi 24 format target

Plugin Konverter mengubah Doconut menjadi layanan konversi dokumen. Ia menyediakan mesin di balik fasad publik DocumentConverter dan — opsional — widget drop-in yang disajikan oleh DocImage.axd, sehingga Anda dapat mengonversi dokumen dari C#, dari widget, atau dari frontend yang Anda buat sendiri.

Instal paket

powershell
Install-Package Doconut.NETFramework.Converter

Pastikan paket Konverter berada pada versi yang sama dengan Doconut.NETFramework.

Daftarkan plugin

Setiap plugin didaftarkan dengan cara yang sama: AddPlugin<TPlugin>() di DoconutHost.Initialize.

csharp
Doconut.DoconutHost.Initialize(options =>
{
    options.LicensePath = HostingEnvironment.MapPath("~/wwwroot/Doconut.Viewer.lic");
    options.AddPlugin<Doconut.Plugins.Converter.ConverterPlugin>();
});

Jika tidak ada lisensi aktif yang memberikan kemampuan Converter — tidak ada lisensi, file TRIAL lama, atau lisensi tanpa kemampuan tersebut — DoconutHost.Initialize melempar dari Application_Start. Di System.Web ini berarti setiap permintaan menjawab 500 kosong, dan alasannya hanya ada di log peristiwa Windows (sumber ASP.NET). Lisensi Demo/NFR sementara diterima. Lihat Pengaturan Lisensi.

Konversi dari C#

Setiap konversi mengembalikan MemoryStream yang dapat dicari dengan posisi 0. DocumentConverter tidak memiliki status: dapatkan dari DoconutHost.Services di mana pun Anda membutuhkannya dan gunakan kembali secara bebas.

csharp
// Resolusi DocumentConverter dari DoconutHost.Services; konstruktornya internal, jadi jangan pernah `new`-kan.
Stream pdf = await converter.ConvertAsync("contract.docx", ConversionTarget.Pdf, ct: ct);
csharp
// sourceExtension mencakup titik di depan. password bernilai null kecuali dokumen dilindungi.
Stream png = await converter.ConvertAsync(upload, ".xlsx", ConversionTarget.Png, password: null, ct: ct);
csharp
Stream html = await converter.WordToHtmlAsync("report.docx", ct);
csharp
Stream docx = await converter.HtmlToWordAsync(html, ConversionTarget.Docx, ct);

Dua detail yang mudah salah: sourceExtension pada overload stream harus menyertakan titik di depan (".xlsx", bukan "xlsx"), atau tidak akan terresolusi. Dan meskipun namanya, WordToHtmlAsync mengembalikan Task<Stream>, bukan Task<string> — dokumen HTML (gambar tersemat sebagai Base64) datang sebagai stream, seperti setiap hasil lainnya.

Di kontroler MVC 5

Buat aksi menjadi asynchronous dan await konversi:

csharp
[HttpPost]
public async Task<ActionResult> ToPdf(HttpPostedFileBase file)
{
    var converter = Doconut.DoconutHost.Services.GetRequiredService<DocumentConverter>();
    Stream pdf = await converter.ConvertAsync(
        file.InputStream, Path.GetExtension(file.FileName), ConversionTarget.Pdf,
        password: null, ct: Response.ClientDisconnectedToken);
    return File(pdf, "application/pdf", Path.GetFileNameWithoutExtension(file.FileName) + ".pdf");
}

Di Web Forms: jangan pernah memblokir konversi

Sebuah halaman Web Forms berjalan pada konteks permintaan single-threaded. ConvertAsync melanjutkan pada konteks itu ketika selesai, sehingga halaman yang menunggu secara sinkron — .Result, .Wait(), .GetAwaiter().GetResult() — menahan thread yang dibutuhkan konversi untuk selesai. Permintaan tidak pernah kembali. Browser terus berputar, log IIS tidak mencatat apa‑apa, dan bagian lain situs tetap berfungsi, sehingga tampak seperti konversi lambat bukan deadlock.

Tandai halaman dengan Async="true" dan jalankan konversi sebagai tugas async halaman:

aspx
<%@ Page Language="C#" Async="true" CodeBehind="Convert.aspx.cs" Inherits="MyApp.Convert" %>
csharp
// Web Forms: direktif @Page memerlukan Async="true", dan konversi berjalan sebagai tugas async halaman.
// Memblokirnya dengan cara itu (.Result, .Wait(), .GetAwaiter().GetResult()) menyebabkan deadlock pada permintaan:
// permintaan tidak pernah kembali, dan tidak ada yang tercatat.
protected void Page_Load(object sender, EventArgs e)
{
    if (!IsPostBack) return;

    RegisterAsyncTask(new PageAsyncTask(async ct =>
    {
        var converter = Doconut.DoconutHost.Services.GetRequiredService<DocumentConverter>();

        using (var pdf = await converter.ConvertAsync(
                   Server.MapPath("~/App_Data/contract.docx"), ConversionTarget.Pdf, ct: ct))
        using (var ms = new MemoryStream())
        {
            if (pdf.CanSeek) pdf.Position = 0;
            await pdf.CopyToAsync(ms);

            Response.ContentType = "application/pdf";
            Response.AddHeader("Content-Disposition", "attachment; filename=contract.pdf");
            Response.BinaryWrite(ms.ToArray());
            // Context, bukan HttpContext.Current: setelah await yang terakhir dapat menjadi null.
            Context.ApplicationInstance.CompleteRequest();
        }
    }));
}

Tanpa Async="true" pada direktif @Page, RegisterAsyncTask diabaikan secara diam-diam. Setelah await, gunakan Context halaman; HttpContext.Current dapat menjadi null di sana.

Format Target

text
Pdf, Docx, Doc, Html, Xlsx, Pptx, Png, Jpeg, Csv, Tiff, Bmp, Gif, Svg, Xml,
Txt, Xls, Jp2, Rtf, Odt, Ods, Odp, Epub, Xps, Webp

Tidak setiap sumber dapat dikonversi ke setiap target: setiap keluarga format sumber (Word, Excel, PowerPoint, PDF, CAD, Image, Email, Diagram, Project, PSD, dokumen web) memiliki set target yang diizinkan masing‑masing. Jangan menghardcode enum ini sebagai daftar target UI Anda: ?convert=open mengembalikan allowedTargets untuk file yang diunggah, dan itulah yang harus mengendalikan pemilih.

Widget Drop-in

Endpoint ?convert=open|run|download pada widget dilayani oleh DocImage.axd dan nonaktif secara default. Aktifkan mereka di samping pendaftaran plugin:

csharp
Doconut.DoconutHost.Initialize(options =>
{
    options.LicensePath = HostingEnvironment.MapPath("~/wwwroot/Doconut.Viewer.lic");
    options.AddPlugin<Doconut.Plugins.Converter.ConverterPlugin>();
    options.AddConverterWidget(widget =>
    {
        widget.MaxUploadMb = 25;
    });
});
// System.Web membaca seluruh unggahan sebelum Doconut melihatnya: pertahankan maxRequestLength (KB) dan
// maxAllowedContentLength (bytes) di Web.config di atas MaxUploadMb widget.
html
<div id="doconut-convert"></div>
<script src="/doconut-res/js/doconutConverter.js"></script>
<script>
  Doconut.convert('#doconut-convert', { basePath: '/DocImage.axd', maxUploadMb: 25 });
</script>

Dua hal yang perlu diperiksa ketika widget tidak berfungsi dengan baik:

  • basePath: '/DocImage.axd'. Default widget, /doconut, adalah endpoint ASP.NET Core. Pada paket ini, endpoint adalah handler DocImage.axd dari Web.config.
  • Skrip dan endpoint bersifat independen. Modul sumber daya menyajikan doconutConverter.js baik widget diaktifkan atau tidak. Tanpa AddConverterWidget(), widget memuat, menggambar zona drop, dan tampak sepenuhnya benar — namun aksi pertamanya menjawab 404.

Batas Unggah

ASP.NET membaca seluruh isi permintaan sebelum DocImage.axd dijalankan. Unggahan di atas MaxUploadMb namun di bawah batas host menghasilkan JSON 413 milik widget ("File is too large."). Unggahan di atas batas host ditolak oleh IIS terlebih dahulu, dengan halaman error yang tidak dapat dibaca widget. Simpan kedua batas host di Web.config di atas batas widget:

xml
<system.web>
  <httpRuntime maxRequestLength="30720" />           <!-- KILOBAIT: 30 MB -->
</system.web>
<system.webServer>
  <security>
    <requestFiltering>
      <requestLimits maxAllowedContentLength="31457280" />  <!-- BYTE: 30 MB -->
    </requestFiltering>
  </security>
</system.webServer>

Sesuaikan widget

Opsi yang diteruskan ke Doconut.convert(selector, options):

OpsiTipeDefaultCatatan
basePathstring/doconutURL endpoint. Atur '/DocImage.axd' pada paket ini
resPathstring/doconut-resDiterima untuk konsistensi dengan widget Doconut lainnya; widget konverter tidak membangun URL apa pun darinya
maxUploadMbnumber25Hanya pemeriksaan pra-sisi klien; server menegakkan batasnya sendiri
licenseUrlstring | nullnullMengubah pemberitahuan watermark pada layar hasil menjadi tautan
labelsobject{}Menimpa subset apapun dari string bahasa Inggris widget

Callbacks:

CallbackTerjadi ketikaData
onReady()Widget telah merender layar drop-nya—
onSourceLoaded({ token, pages, sourceExt, allowedTargets })?convert=open berhasilToken sumber, jumlah halaman, ekstensi sumber (tanpa titik di depan), target yang diizinkan
onConverted({ downloadToken, resultToken, resultPages, downloadName, watermarked, target })?convert=run berhasilRespons run ditambah target yang diminta
onDownload({ downloadName, downloadToken })Pengguna mengklik DownloadTerjadi bersamaan dengan unduhan bawaan browser
onError({ phase, message })Permintaan open atau run gagalphase adalah 'open' atau 'run'; message adalah error server yang telah disanitasi

Doconut.convert() mengembalikan instance widget: reset() kembali ke layar drop, loadFile(file) memulai alur dengan sebuah File, dan destroy() menghapusnya.

Bangun frontend Anda sendiri

Widget ini adalah klien untuk kontrak HTTP ini pada DocImage.axd:

RuteTujuanRespons sukses
POST /DocImage.axd?convert=open (multipart, field file)Unggah dan buka dokumen sumber200 — { token, pages, sourceExt, allowedTargets }
POST /DocImage.axd?token=<token>&convert=run&target=<ext>Konversi sumber yang diunggah ke target200 — { downloadToken, resultToken, resultPages, downloadName, watermarked }
GET /DocImage.axd?convert=download&token=<downloadToken>Alirkan file yang telah dikonversi200 — file, Content-Disposition: attachment

Sumber yang diunggah disimpan selama 30 menit; setelah itu, run menjawab 404 dan file harus dibuka kembali. downloadToken mendapatkan jendela 30 menitnya sendiri ketika konversi selesai. resultToken adalah token penampil biasa yang mengikuti masa hidup sesi penampil.

sourceExt dalam respons open tidak memiliki titik di depan ("docx") — berlawanan dengan parameter sourceExtension pada ConvertAsync.

RuteStatusKapanBadan
semua404Widget tidak diaktifkan (AddConverterWidget() tidak pernah dipanggil)hanya status
semua405Verb salah (open/run memerlukan POST, download memerlukan GET)hanya status
open413Unggahan melebihi MaxUploadMb (tetapi tidak melebihi batas IIS){ "error": "File is too large." }
open400Tidak ada badan multipart, tidak ada file, atau tipe yang tidak dapat dikonversi{ "error": "..." }
open403Tipe file membutuhkan kemampuan yang tidak diberikan oleh lisensi{ "error": "..." }
run400Token tidak terbentuk dengan benar, target tidak dikenal, atau target tidak ada dalam allowedTargets{ "error": "..." }
run404Unggahan kedaluwarsa atau tidak pernah dibuka{ "error": "Upload expired — please re-open the file." }
open, run500Pemrosesan gagal{ "error": "<sanitized message>" }
download400 / 404Token unduhan yang tidak terbentuk, tidak dikenal, atau kedaluwarsahanya status

Kepemilikan sumber daya

Pemanggil memiliki MemoryStream yang dikembalikan oleh konversi dan harus membuangnya setelah menyalin atau mengembalikannya (MVC's File(stream, …) membuangnya untuk Anda). Jangan membuat atau membuang DocumentConverter sendiri — konstruktornya bersifat internal.

Penambahan watermark

Status lisensiMulaiOutput konversi
Lisensi penampil berbayar yang memberikan ConverterMulaiBersih — watermarked: false
Lisensi Sementara/Demo yang aktifMulaiMengonversi, dengan watermark evaluasi — watermarked: true
Tidak ada lisensi, file TRIAL warisan, atau lisensi tanpa ConverterApplication_Start melempar; setiap permintaan menjawab 500 kosong—
Lisensi Sementara/Demo yang kedaluwarsaMulaiMengonversi, dengan watermark evaluasi — watermarked: true

Integrasi dapat dibangun dan diuji secara menyeluruh dengan lisensi evaluasi sebelum pembelian — hanya byte output yang berubah.

Pemecahan Masalah

GejalaPemeriksaan
Setiap permintaan menjawab 500 kosong setelah menambahkan pluginLisensi memberikan Converter — log peristiwa Windows, sumber ASP.NET
Menyelesaikan DocumentConverter melemparAddPlugin<ConverterPlugin>() berada di DoconutHost.Initialize
Konversi Web Forms tidak pernah kembaliHalaman terblokir pada ConvertAsync — gunakan Async="true" dan RegisterAsyncTask
Konversi aliran mengatakan format tidak didukungsourceExtension menyertakan titik di depan
Widget dimuat tetapi permintaannya mengembalikan 404AddConverterWidget() tidak dipanggil, atau basePath bukan '/DocImage.axd'
Unggahan besar menampilkan halaman error IIS alih-alih pesan widgetmaxRequestLength / maxAllowedContentLength berada di bawah MaxUploadMb
Target tidak adaGunakan allowedTargets dari convert=open
Unduhan kedaluwarsaUlangi convert=open / convert=run; token bersifat sementara dengan sengaja

Apakah halaman ini membantu?