jsPDF는 가벼운 브라우저 내보내기에 강합니다
jsPDF는 실제 제품 문제를 해결하기 때문에 널리 쓰입니다. 백엔드 서비스를 운영하지 않고도 브라우저 안에서 텍스트, 선, 이미지, 간단한 표를 그리고 같은 페이지에서 다운로드를 시작할 수 있습니다. 프로토타입, 작은 관리자 화면, 로컬 영수증, 오프라인 PWA에는 잘 맞습니다.
문제는 jsPDF가 유용한가가 아닙니다. 브라우저 경계가 언제 생산 문서의 경계로 부족해지는가입니다. PDF가 고객이 스캔하거나, 보관하거나, 이메일로 보내거나, 다른 시스템에 제출하는 업무 문서가 되면 작업은 더 이상 “파일을 그리는 것”에 그치지 않습니다. 폰트 관리, 바코드 정확도, 모바일 안정성, 결정적 출력, 때로는 PDF/A 또는 전자 인보이스 패키징까지 포함됩니다.
같은 PDF라도 제품 경계가 다릅니다
jsPDF에서는 프런트엔드 애플리케이션이 렌더러입니다. 각 브라우저 탭이 라이브러리, 커스텀 폰트, 중간 이미지, 바코드 출력, 최종 PDF 바이트를 모두 들고 있어야 합니다. 라이브러리 비용은 0이지만, 운영 책임은 각 사용자 기기로 이동합니다.
gPdf에서는 브라우저나 백엔드가 구조화된 DocumentRequest 또는 template_id + data 요청을 보냅니다. gPdf가 Edge 렌더 환경, 번들 폰트, 바코드 기하 구조, 바이너리 PDF 생성을 담당합니다. 애플리케이션은 데이터와 템플릿 로직에 집중합니다.
제품 적합성: 오프라인 내보내기 vs 운영 문서
PDF가 로컬 편의 기능이면 jsPDF가 잘 맞습니다. 작은 내보내기 버튼, 간단한 라틴 문자 영수증, 대시보드 스냅샷, 네트워크 없이 동작해야 하는 PWA가 여기에 속합니다.
PDF가 운영 작업 흐름의 일부라면 gPdf가 더 맞습니다. 배송 라벨, 창고 태그, 인보이스, 티켓, 명세서, 통관 서류, 크로스보더 영수증은 현재 브라우저 탭이 어떻게든 조립한 파일이 아니라 모든 기기에서 같은 출력이어야 합니다.
비용 모델: 무료 라이브러리 vs 직접 떠안는 운영 책임
jsPDF의 가격 장점은 분명합니다. 라이브러리 자체는 오픈소스이고 브라우저 CPU는 클라우드 청구서에 보이지 않습니다. 작은 내부 기능에는 가장 저렴한 선택일 수 있습니다.
운영 비용은 라이브러리 주변의 작업에서 나타납니다.
- CJK를 표시할 수 있는 폰트 파일 또는 생성된 base64 폰트 모듈.
- 바코드 인코딩과 변환 라이브러리.
- 브라우저별 메모리와 다운로드 버그.
- 스캐너와 열전사 프린터에 대한 인쇄 QA.
- 데스크톱, iOS Safari, Android WebView, 임베디드 브라우저 회귀 테스트.
gPdf는 이를 사용량 청구로 바꿉니다. 공개 Basic 플랜은 월 5달러에 10만 페이지를 포함하고, 표준 초과 사용은 페이지당 0.00005달러부터입니다. 공급사 비용은 생기지만, 모든 프런트엔드 번들과 모든 사용자 기기를 생산 PDF 서비스처럼 만들 필요가 없어집니다.
CJK는 단순 표시 문제가 아닙니다
CJK는 중국어, 일본어, 한국어입니다. jsPDF의 기본 표준 PDF 폰트는 단순 라틴 문자 출력에는 쓸 수 있지만 모든 Unicode 글리프를 포함하지 않습니다. CJK가 들어가면 애플리케이션은 실제로 해당 글리프를 포함한 폰트를 필요로 합니다. 실제 구현에서는 TTF 파일을 패키징하거나 base64 JavaScript 모듈로 변환하거나 PDF 생성 전에 폰트 데이터를 가져오는 경우가 많습니다.
이 비용은 두 번 지불됩니다. 먼저 더 큰 프런트엔드 번들로, 다시 PDF 생성 중 브라우저 메모리로 지불합니다. 모바일에서는 같은 탭이 웹 앱, 폰트, 바코드 버퍼, 이미지, 최종 PDF 바이트를 동시에 들고 있을 수 있습니다.
gPdf는 이 작업을 서버 측에 둡니다. 브라우저는 구조화 JSON을 보내고 렌더러는 라틴, 그리스, 키릴, CJK, 아랍, 데바나가리, 벵골, 태국 문자와 고정폭 텍스트를 지원하는 번들 폰트를 선택합니다. 2 KB 주문 요청 데이터가 12 MB 폰트 전달 경로가 될 필요는 없습니다.
바코드는 두 번째 운영 문제입니다
물류, 이커머스, 제조, 의료, 티켓팅, 리테일에서는 바코드가 보이는 글자보다 더 중요할 수 있습니다. 사람은 주문 번호를 읽지만 운영은 Code 128, GS1-128, QR, DataMatrix, PDF417을 읽습니다.
jsPDF에서는 바코드 생성이 보통 별도 제품 결정입니다. 팀은 jsPDF를 다른 인코더와 조합하고, 바코드를 SVG, Canvas 또는 이미지로 렌더링한 뒤 PDF에 넣습니다. 쿠폰 QR이나 개념 검증에는 충분할 수 있습니다.
하지만 인쇄된 바코드가 운영에 중요해지면 이 방식은 쉽게 깨집니다.
- Canvas 바코드가 잘못된 해상도로 래스터화될 수 있습니다.
- 스케일된 이미지가 막대, 모듈, 여백 구역을 흐리게 만들 수 있습니다.
- 브라우저, CSS transform, 내보내기 경로가 최종 물리 크기를 바꿀 수 있습니다.
- 형식별로 다른 라이브러리나 변환 경로가 필요할 수 있습니다.
- 203 DPI 열전사 프린터는 작은 크기 오류를 빠르게 드러냅니다.
gPdf는 바코드를 문서 요소로 처리합니다. 요청은 type: "barcode", format, 입력 데이터, 밀리미터 단위 물리 크기를 지정합니다. 렌더러는 지원되는 1D/2D 형식에 대해 PDF 내부에 벡터 바코드 기하를 출력하므로 텍스트, 도형, 표, 이미지, 바코드가 같은 좌표계에 남습니다.
Studio와 템플릿 반복 수정
jsPDF는 코드 우선입니다. 레이아웃 변경은 보통 JavaScript 그리기 명령, 좌표, 폰트 등록, 이미지 변환, 바코드 배치를 수정하는 일이 됩니다.
gPdf도 API 우선 처리 방식을 지원하지만, PDF 레이아웃을 위한 무료 시각 디자이너인 gPdf Studio를 제공합니다. 텍스트, 이미지, 표, 도형, 머리글, 바닥글, 바코드를 추가하고 드래그한 뒤 디자인을 template_id + data 생성에 연결할 수 있습니다. 라벨, 인보이스, 영수증 형식이 자주 바뀌고 PDF 전문가가 아닌 사람도 레이아웃에 참여해야 할 때 중요합니다.
무거운 PDF 작업은 모바일 브라우저에 맞지 않습니다
클라이언트 측 PDF 생성은 서버 청구서가 없어 저렴해 보입니다. 실제로는 비용이 사용자 기기로 이동합니다.
데스크톱에서는 괜찮을 수 있습니다. 모바일 브라우저에서는 CJK 폰트 데이터, base64 이미지, Canvas 버퍼, 바코드 이미지, 생성된 PDF 바이트, 실행 중인 애플리케이션이 동시에 메모리를 경쟁합니다. iOS Safari와 저메모리 Android 기기는 개발자 노트북보다 훨씬 덜 관대합니다.
gPdf로 옮기면 브라우저는 작은 JSON 요청을 만들고, 바이너리 응답을 기다린 뒤 완성된 PDF를 다운로드합니다. 사용자 탭이 폰트 관리자, 바코드 렌더러, 레이아웃 엔진, 바이너리 PDF 작성기를 동시에 맡지 않아도 됩니다.
jsPDF가 여전히 맞는 경우
jsPDF를 유지할 강한 이유도 있습니다.
사용자가 반드시 오프라인에서 내보내야 한다면 jsPDF가 더 잘 맞습니다. 데이터가 기기 밖으로 절대 나가면 안 된다면 브라우저 측 생성이 더 명확한 개인정보 경계입니다. 문서가 작고 라틴 문자만 포함하며 가끔 쓰인다면 API를 도입하는 운영 비용이 과할 수 있습니다. 프로토타입과 내부 도구에서는 jsPDF가 실제로 가장 빠른 길인 경우가 많습니다.
출력이 운영 흐름에 들어가면 판단은 달라집니다. 반드시 스캔되어야 하는 배송 라벨, 보관되어야 하는 인보이스, 검증되어야 하는 티켓, CJK 이름을 정확히 렌더링해야 하는 크로스보더 주문 문서가 그렇습니다. 이때는 “브라우저에서 PDF를 생성한다”보다 “동일한 생산 PDF를 안정적으로 생성한다”가 더 중요합니다.
마이그레이션 형태
마이그레이션은 “함수 호출 하나를 바꾸는 것”이 아닙니다. 명령형 브라우저 그리기에서 구조화된 문서 요청으로 이동하는 일입니다.
- // Before: browser-side drawing with jsPDF plus extra font/barcode setup.
- import { jsPDF } from "jspdf";
- import JsBarcode from "jsbarcode";
-
- const doc = new jsPDF({ unit: "mm", format: [100, 150] });
- // Load a CJK-capable TTF and register it before drawing CJK text.
- doc.addFileToVFS("NotoSansCJK-Regular.ttf", base64Font);
- doc.addFont("NotoSansCJK-Regular.ttf", "NotoSansCJK", "normal");
- doc.setFont("NotoSansCJK");
- doc.text("跨境订单 / Cross-border order", 6, 10);
-
- // Generate a barcode separately, then place it into the PDF.
- JsBarcode(canvas, "PDN0003507278", { format: "CODE128" });
- doc.addImage(canvas.toDataURL("image/png"), "PNG", 6, 72, 72, 20);
- doc.save("label.pdf");
+
+ // After: send one structured DocumentRequest to gPdf.
+ const res = await fetch("https://api.gpdf.com/api/v1/pdf/render", {
+ method: "POST",
+ headers: {
+ Authorization: `Bearer ${KEY}`,
+ "Content-Type": "application/json"
+ },
+ body: JSON.stringify({
+ settings: {
+ defaults: {
+ text: {
+ font_family: "NotoSans-Regular",
+ font_mode: "prefer",
+ font_size: 9,
+ color: "#111827"
+ }
+ }
+ },
+ pages: [{
+ width: 100,
+ height: 150,
+ elements: [
+ {
+ type: "text",
+ x: 6,
+ y: 8,
+ content: "跨境订单 / Cross-border order",
+ style: { width: 88, font_size: 12, font_weight: "bold" }
+ },
+ {
+ type: "barcode",
+ x: 6,
+ y: 70,
+ width: 72,
+ height: 18,
+ format: "code128",
+ content: "PDN0003507278",
+ barcode_text: { enabled: true, position: "bottom", offset: 1 }
+ },
+ {
+ type: "barcode",
+ x: 80,
+ y: 8,
+ width: 14,
+ height: 14,
+ format: "qrcode",
+ content: "https://track.example/PDN0003507278",
+ barcode_text: { enabled: false, position: "bottom" }
+ }
+ ]
+ }]
+ })
+ });
+ const pdf = await res.arrayBuffer();
중요한 변화는 책임 경계입니다. jsPDF에서는 웹 앱이 CJK 폰트 경로, 바코드 생성 경로, 브라우저 메모리 특성, 내보내기 동작을 직접 맡습니다. gPdf에서는 애플리케이션이 데이터와 템플릿을 맡고, Edge 렌더러가 문서 생성 메커니즘을 맡습니다.
관련 PDF 생성 시나리오
브라우저 PDF 내보내기에서 시작한 평가라면 먼저 오프라인이 필수인지 판단하세요. 오프라인 내보내기와 로컬 전용 문서는 여전히 jsPDF에 잘 맞습니다. 안정적인 생산 문서가 필요하다면 JSON-PDF 변환 API, 인보이스 PDF API, 배송 라벨 API, GS1 바코드 API, 템플릿 PDF API를 비교하세요. 보관 또는 전자 인보이스 요구가 있다면 PDF/A API와 Factur-X API도 함께 보세요.
FAQ
jsPDF는 무료인가요?
라이브러리 자체는 오픈소스입니다. 생산 비용은 주변 작업인 CJK 폰트, 바코드 라이브러리, 브라우저 품질 확인, 인쇄 품질 확인, 저메모리 기기 지원에서 발생합니다.
gPdf가 모든 jsPDF 사용 사례를 대체하나요?
아니요. 오프라인 브라우저 내보내기와 로컬 전용 문서는 여전히 jsPDF의 자연스러운 영역입니다. gPdf는 제어된 렌더러가 API 호출의 가치가 있는 생산 문서용입니다.
왜 바코드 비용을 별도로 보나요?
화면에서 멀쩡해 보이는 바코드도 스케일링, 래스터화, 열전사 인쇄 이후에는 실패할 수 있습니다. 운영 문서에는 보이는 패턴이 아니라 스캐너 신뢰성이 필요합니다.
관련 페이지
- gPdf API 레퍼런스 - DocumentRequest, 바코드 요소, 폰트 대체 경로, 렌더 엔드포인트.
- PDF의 벡터 바코드 vs 래스터 바코드 - 인쇄 후 기하 구조가 중요한 이유.
- JSON에서 0.1 mm 정밀도의 GS1-128 - 라벨용 바코드 크기 세부 사항.
- 엔지니어를 위한 PDF/A와 Factur-X - 보관과 전자 인보이스 요구가 PDF 파이프라인에 들어오는 시점.