컨버터 플러그인
문서를 45개의 대상 형식으로 변환
컨버터 플러그인은 Doconut을 문서 변환 서비스로 전환합니다. 공개 DocumentConverter 파사드 뒤의 엔진을 제공하며, 선택적으로 자체 HTTP 계약을 가진 삽입형 위젯을 제공하므로 C#, 위젯, 또는 직접 작성한 프런트엔드에서 문서를 변환할 수 있습니다.
패키지 설치
최신 안정 버전 컨버터 플러그인을 설치합니다:
dotnet add package Doconut.NETStandard.Converter플러그인을 현재 26.8.0 릴리스에 고정하려면 버전을 별도로 전달하세요:
dotnet add package Doconut.NETStandard.Converter --version 26.8.0컨버터 패키지를 Doconut.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입니다. 임시 Demo/NFR 등록은 허용되며, 기간이 만료된 후에도 워터마크가 있는 출력으로 변환 기능은 계속 사용할 수 있습니다. 무음 무료 티어는 없습니다. 라이선스 로드 방법은 라이선스 설정을 참고하십시오.
C#에서 변환
각 변환은 0 위치에 설정된 탐색 가능한 MemoryStream를 반환하며, 즉시 읽거나 복사할 수 있습니다. 필요에 따라 DI에서 DocumentConverter를 해결하십시오 — 설계상 상태가 없으므로 단일 인스턴스를 요청 간에 안전하게 재사용할 수 있습니다.
viewer.Converter.GetConverter()는 여기서 존재하지 않습니다. 변환은 더 이상 뷰어 인스턴스를 통해 접근되지 않으며, 대신 Doconut.DocumentConverter를 주입하십시오.
// DocumentConverter를 주입합니다; 생성자는 internal이므로 절대 `new` 하지 마세요.
Stream pdf = await converter.ConvertAsync("contract.docx", ConversionTarget.Pdf, ct: ct);// sourceExtension에는 앞에 점이 포함됩니다. 문서가 보호되지 않은 경우 password는 null입니다.
Stream png = await converter.ConvertAsync(stream, ".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로 삽입)를 스트림으로 얻으며, 이는 다른 모든 변환 결과와 동일합니다.
대상 형식
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 열거형이 있었습니다. 이 모든 것이 사라졌으며, 마이그레이션 가이드를 참고하십시오.
모든 소스가 모든 대상으로 변환되는 것은 아닙니다 — 플러그인은 각 소스의 형식 패밀리(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 }) | 열기 또는 실행 요청이 실패했을 때 | phase 은 'open' 또는 'run'; message 은 정제된 서버 오류(또는 업로드 크기 사전 검사에 대한 클라이언트 측 메시지)입니다 |
Doconut.convert() 은 위젯 인스턴스 자체를 반환합니다 — 이를 보관하여 위젯을 프로그래밍 방식으로 제어하십시오:
const conv = Doconut.convert('#doconut-convert', { basePath: '/doconut' });
conv.reset(); // idle/drop 화면으로 돌아갑니다; onReady를 다시 호출하지 않습니다
conv.loadFile(file); // File 객체로 흐름을 시작합니다; 현재 idle 상태가 아닐 경우 아무 동작도 하지 않습니다
conv.destroy(); // 리스너를 제거하고, 마운트를 비웁니다; 이후 인스턴스를 사용할 수 없습니다자체 프론트엔드 구축
위젯은 이 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 — 파일 바이트, 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 | 멀티파트 본문 없음, 파일 없음, 또는 변환할 수 없는 소스 확장자 | { "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인 seekable 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 필드를 채웁니다. 구매 전 평가 라이선스로 통합을 구축하고 엔드투엔드 테스트를 수행할 수 있습니다 — 출력 바이트만 변경됩니다.
이 페이지가 도움이 되었나요?