컨버터 플러그인
문서를 45개의 대상 형식으로 변환
컨버터 플러그인은 Doconut을 문서 변환 서비스로 전환합니다. 공개 DocumentConverter 파사드 뒤의 엔진을 제공하고, 선택적으로 자체 HTTP 계약을 가진 드롭인 위젯을 제공하므로 C#에서, 위젯에서, 혹은 직접 작성한 프런트엔드에서 문서를 변환할 수 있습니다.
패키지 설치
최신 안정 버전 컨버터 플러그인을 설치합니다:
dotnet add package Doconut.NETStandard.Converter플러그인을 현재 26.8.0 릴리스에 고정하려면 버전을 별도로 지정합니다:
dotnet add package Doconut.NETStandard.Converter --version 26.8.0Doconut.NETStandard와 동일한 버전으로 컨버터 패키지를 유지하십시오. 패키지 ID는 Doconut.NETStandard.Converter이며, .26.8.0은 다운로드된 .nupkg 파일 이름에만 나타납니다.
플러그인 등록
AddConverter() 메서드는 존재하지 않습니다 — Doconut의 플러그인 모델은 일관됩니다. 컨버터를 포함한 모든 플러그인은 동일한 방식으로 등록됩니다: AddDoconut() 내부에서 AddPlugin<TPlugin>()를 호출합니다. ConverterPlugin은 자체 NuGet 패키지 Doconut.NETStandard.Converter에 포함되어 기본 뷰어 패키지와 함께 설치됩니다.
builder.Services.AddDoconut(options =>
{
options.LicensePath = "Doconut.Viewer.lic";
options.AddPlugin<Doconut.Plugins.Converter.ConverterPlugin>();
});이 호출은 라이선스가 없거나, 레거시
TRIAL파일이 있거나,Converter기능을 부여하지 않는 비임시 라이선스가 있을 경우 시작 시 예외를 발생시킵니다 —AddDoconut()내부에서 발생한InvalidOperationException이며, 애플리케이션이 요청을 처리하기 전에 발생합니다. 임시 데모/NFR 등록은 허용되며, 해당 기간이 만료된 후에도 워터마크가 있는 출력으로 변환은 계속 사용할 수 있습니다. 무제한 무료 티어는 없습니다. 라이선스 로드 방법은 License Setup 를 참조하십시오.
C#에서 변환
각 변환은 0 위치에 설정된 탐색 가능한 MemoryStream을 반환하며, 즉시 읽거나 복사할 수 있습니다. 필요에 따라 DI에서 DocumentConverter를 해결하십시오 — 설계상 상태가 없으므로 단일 인스턴스를 요청 간에 안전하게 재사용할 수 있습니다.
viewer.Converter.GetConverter()는 여기서 존재하지 않습니다. 변환은 더 이상 뷰어 인스턴스를 통해 접근되지 않으며, 대신 Doconut.DocumentConverter를 주입하십시오.
// 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<string>이 아니라 Task<Stream>을 반환합니다 — HTML 문서(이미지는 Base64로 삽입)를 스트림으로 받게 되며, 이는 다른 모든 변환 결과와 동일합니다.
대상 형식
ConversionTarget (네임스페이스 Doconut.Configs.Conversion)에는 45개의 멤버가 있습니다:
Pdf, Docx, Doc, Html, Xlsx, Pptx, Png, Jpeg, Csv, Tiff, Bmp, Gif, Svg, Xml,
Txt, Xls, Jp2, Rtf, Odt, Ods, Odp, Epub, Xps, Webp, Msg, Eml, Emlx, Mhtml,
Xlsm, Xlsb, Ppt, Docm, Dot, Dotx, Dotm, Vsdx, Vssx, Vstx, Vsdm, Vssm, Vstm,
Vdx, Vsx, Vtx, Ico이 단일 열거형은 모든 소스 패밀리를 포괄합니다. 이전 라이브러리에는 패밀리별 *ConfigConverter 타입이 있었으며 — WordConfigConverter, ExcelConfigConverter 등 — 각각 자체 중첩 EnTargetFormat 열거형과 입력을 위한 SourceFormatConverter 열거형을 가지고 있었습니다. 이 모든 것이 사라졌으며, 자세한 내용은 migration guide 를 참고하십시오.
모든 소스가 모든 대상으로 변환되는 것은 아닙니다 — 플러그인은 각 소스의 포맷 패밀리(Word, Excel, PowerPoint, PDF, CAD, Image, Email, Diagram, Project/Task, PSD, 웹 문서)를 고정된 허용 대상 집합에 매핑합니다. 이 열거형을 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= 엔드포인트의 기본 경로; 실제로 UseDoconut()가 마운트된 ASP.NET 브랜치와 일치해야 합니다 (보통 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 성공 | 소스 세션 토큰, 페이지 수, 소스 확장자(점 없이), 허용된 대상 목록 |
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()는 위젯 인스턴스를 반환합니다 — 이를 보관하여 프로그래밍 방식으로 위젯을 제어하세요:
const conv = Doconut.convert('#doconut-convert', { basePath: '/doconut' });
conv.reset(); // back to the idle/drop screen; does not re-fire onReady
conv.loadFile(file); // starts the flow with a File object; no-op unless currently idle
conv.destroy(); // removes listeners, empties the mount; the instance is unusable after this자체 프론트엔드 구축
위젯은 이 HTTP 계약을 위한 클라이언트에 불과합니다 — 다른 UX를 위해 직접 프론트엔드를 구축할 수 있습니다. 세 개의 라우트는 모두 UseDoconut()가 마운트된 ASP.NET 브랜치(보통 /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 — file bytes, Content-Disposition: attachment, Cache-Control: no-store |
업로드된 소스 바이트는 서버 측에 30분 TTL로 저장됩니다; 이 기간이 지나면 run은 404를 반환하고 파일을 다시 열어야 합니다. 변환된 결과도 동일한 저장소에 보관되며 — 변환이 완료되면 downloadToken에 새로운 30분 창이 부여됩니다 — resultToken은 뷰어 세션 캐시의 수명을 따르는 일반적인 뷰어 세션 토큰으로, 저장소와는 별개입니다.
open 응답의 sourceExt는 앞에 점이 없습니다 (예: "docx"). 이는 DocumentConverter.ConvertAsync의 sourceExtension 매개변수가 점을 요구하는 것과 반대되는 규칙입니다.
실패 모드 (라우트별)
| 라우트 | 상태 | 조건 | 본문 |
|---|---|---|---|
| any | 404 | 위젯이 활성화되지 않음 (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 | 토큰 형식이 잘못됨(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)되었거나 토큰이 열리지 않음 | { "error": "Upload expired — please re-open the file." } |
open, run | 500 | 내부 처리 오류 | { "error": "<sanitized message>" } — 다른 Doconut 오류 경로와 동일하게 정제되며 내부 엔진 이름이 노출되지 않음 |
download | 400 | 토큰 형식이 잘못됨(GUID 아님) | status only |
download | 404 | 다운로드 토큰이 없거나 만료됨 | status only |
리소스 소유권
컨버터는 위치가 0으로 설정된 탐색 가능한 MemoryStream을 반환합니다. 호출자는 해당 스트림을 소유하며 복사하거나 내용을 반환한 후에 이를 폐기해야 합니다. DocumentConverter 서비스 자체는 상태가 없으며 의존성 주입을 통해 해결됩니다; 서비스를 직접 생성하거나 폐기하지 마세요.
웹 위젯의 경우, 업로드와 다운로드 스태시는 각각 독립적인 30분 TTL을 가집니다. 뷰어 resultToken은 대신 뷰어 세션 수명에 따릅니다. 뷰어 결과를 닫아도 아직 유효한 다운로드 스태시가 삭제되지 않으며, 브라우저 위젯을 재설정해도 두 TTL이 연장되지 않습니다.
문제 해결
| 증상 | 확인 사항 |
|---|---|
DocumentConverter 해결 실패 | ConverterPlugin 등록이 AddDoconut() 내부에서 이루어졌음 |
| 시작 시 애플리케이션 실패 | 로드된 라이선스가 Converter를 부여함 |
| 스트림 변환에서 형식이 지원되지 않음 | sourceExtension에 앞점이 포함됨 |
| 위젯 JavaScript는 로드되지만 요청이 404 반환 | AddConverterWidget()이 호출되지 않음 |
| 위젯 요청이 잘못된 URL 사용 | basePath가 UseDoconut()이 매핑된 브랜치와 일치함 |
| 대상이 누락됨 | convert=open에서 반환된 allowedTargets 사용; 모든 소스가 모든 enum 대상을 지원하는 것은 아님 |
| 다운로드 만료 | convert=open/convert=run을 반복; 스태시 토큰은 의도적으로 일시적임 |
워터마킹
ConverterPlugin이 등록된 경우, 호스트 라이선스는 세 가지 상태 중 하나에 있습니다:
| 라이선스 상태 | 시작 게이트 | 변환 출력 |
|---|---|---|
Converter를 부여하는 유료 뷰어 라이선스이며, 유효 기간 내 | 통과 | 깨끗함 — watermarked: false |
| 활성 평가(데모/NFR) 라이선스 | 통과 | 성공적으로 변환되며, 평가 워터마크가 찍힘 — watermarked: true |
라이선스 없음, 레거시 TRIAL 파일, 또는 Converter를 부여하지 않는 비임시 라이선스 | 앱이 시작되지 않음 — 위에서 설명한 시작 게이트가 예외 발생 | — |
| 만료된 임시/데모 라이선스 | 등록은 만료 후에도 유지 | 평가 워터마크와 함께 변환 — watermarked: true |
두 호출 경로는 동일한 규칙으로 플래그를 계산합니다: DocumentConverter C# 파사드는 라이선스의 IsViewerLicensed와 IsTemporary 상태에서 내부적으로 이를 도출하며, 위젯의 ?convert=run 핸들러는 동등한 검사(IsViewerLicensed && !IsTrial && !IsTemporary)를 수행해 반환되는 watermarked 필드를 채웁니다. 구매 전 평가 라이선스로 통합을 구축하고 엔드‑투‑엔드 테스트를 수행할 수 있으며 — 변경되는 것은 출력 바이트뿐입니다.
이 페이지가 도움이 되었나요?