[{"data":1,"prerenderedAt":1848},["ShallowReactive",2],{"blog-ko-go-pdf-library-showdown-2026":3},{"id":4,"title":5,"author":6,"body":9,"date":1835,"description":1836,"draft":1837,"extension":1838,"howTo":1839,"image":1839,"meta":1840,"navigation":812,"path":1841,"seo":1842,"stem":1843,"tags":1844,"updated":1839,"__hash__":1847},"blogKo/ko/blog/002.go-pdf-library-showdown-2026.md","2026 년 Go PDF 라이브러리 비교 쇼다운",{"name":7,"url":8},"gpdf team","https://gpdf.dev",{"type":10,"value":11,"toc":1817},"minimark",[12,17,26,48,51,59,63,66,103,106,109,112,303,310,313,329,332,358,364,368,475,484,488,495,504,510,516,523,526,537,614,617,619,673,676,682,686,727,731,734,775,778,782,785,1652,1662,1666,1669,1707,1711,1717,1727,1733,1739,1745,1749,1752,1769,1782,1786,1813],[13,14,16],"h2",{"id":15},"tldr","TL;DR",[18,19,20,21,25],"p",{},"5 년 전에 \"Go PDF\"를 검색하면 거의 틀림없이 ",[22,23,24],"strong",{},"jung-kurt/gofpdf"," 로 연결됐다. 지금 그 저장소는 아카이브 상태. 커뮤니티 포크 go-pdf/fpdf 도 마찬가지. 검색 결과가 암시하는 것보다 현재 선택지는 훨씬 좁다.",[27,28,29,36,42],"ul",{},[30,31,32,35],"li",{},[22,33,34],{},"활발히 유지보수 중",": gpdf (본 팀), signintech/gopdf, johnfercher/maroto v2 — 단 Maroto 는 아카이브된 gofpdf 에 의존한다.",[30,37,38,41],{},[22,39,40],{},"아카이브",": jung-kurt/gofpdf (2021), go-pdf/fpdf (2025).",[30,43,44,47],{},[22,45,46],{},"상용 / AGPL",": unidoc/unipdf.",[18,49,50],{},"이 글에서는 현역 라이브러리 4 개를 4 가지 워크로드로 벤치마크하고, 라이선스와 의존성 그래프, 유지보수 상태를 표로 정리한다. 용례별 선택 가이드도 끝에 둔다. 내년에 다시 돌린다.",[18,52,53,54,58],{},"편향 공개: 우리는 gpdf 팀. 벤치마크 코드는 공개 (",[55,56,57],"code",{},"_benchmark/benchmark_test.go","). 직접 클론해서 다시 측정해 주고, 숫자가 다르면 알려 달라.",[13,60,62],{"id":61},"go-pdf-라이브러리는-세-종류다","\"Go PDF 라이브러리\"는 세 종류다",[18,64,65],{},"\"Go PDF 라이브러리\" 라는 말이 사실은 세 가지 서로 다른 도구를 한 선반에 올려놓고 있다:",[67,68,69,82,94],"ol",{},[30,70,71,74,75,77,78,81],{},[22,72,73],{},"저수준 PDF 라이터"," — 바이트를 밀고 프리미티브로 그린다. ",[55,76,24],{},", ",[55,79,80],{},"signintech/gopdf",".",[30,83,84,87,88,77,91,81],{},[22,85,86],{},"라이터를 감싼 레이아웃 라이브러리"," — 선언적 행/열. ",[55,89,90],{},"johnfercher/maroto v2",[55,92,93],{},"gpdf",[30,95,96,99,100,81],{},[22,97,98],{},"전체 문서 스위트"," — 파싱, 서명, PDF/A, OCR, 블랙아웃. ",[55,101,102],{},"unidoc/unipdf",[18,104,105],{},"\"가장 좋은 Go PDF 라이브러리는 뭔가요?\" 같은 질문이 Reddit/인프런 댓글에서 엇나가는 이유가 여기다. 아래 비교에서는 계속 이 구분을 살려 둔다.",[18,107,108],{},"라인업에서 빠진 것: headless Chromium 을 띄우는 쪽 (go-rod, chromedp). 그건 PDF 라이브러리가 아니고 \"인쇄 기능을 가진 브라우저\". CSS 가 무거운 디자인 재현엔 좋지만 콜드스타트/메모리/distroless 배포 어디든 무겁다. \"디자이너가 준 HTML+CSS 를 픽셀 단위로 재현\" 이 목표라면 그 도구들이 답이고, 여기서는 그쪽과 경쟁하지 않는다.",[13,110,111],{"id":111},"스코어보드",[113,114,115,145],"table",{},[116,117,118],"thead",{},[119,120,121,125,128,130,133,136,139,142],"tr",{},[122,123,124],"th",{},"라이브러리",[122,126,127],{},"마지막 릴리스",[122,129,40],{},[122,131,132],{},"라이선스",[122,134,135],{},"코어 의존",[122,137,138],{},"CJK",[122,140,141],{},"레이아웃 그리드",[122,143,144],{},"2026 상태",[146,147,148,181,201,225,252,279],"tbody",{},[119,149,150,156,159,162,165,170,173,176],{},[151,152,153,155],"td",{},[22,154,93],{}," (본 팀)",[151,157,158],{},"활발",[151,160,161],{},"—",[151,163,164],{},"MIT",[151,166,167],{},[22,168,169],{},"0",[151,171,172],{},"네이티브",[151,174,175],{},"12 컬럼",[151,177,178],{},[22,179,180],{},"유지보수 중",[119,182,183,185,187,189,191,193,196,199],{},[151,184,80],{},[151,186,158],{},[151,188,161],{},[151,190,164],{},[151,192,169],{},[151,194,195],{},"TTF 수동",[151,197,198],{},"없음",[151,200,180],{},[119,202,203,205,207,209,211,216,219,222],{},[151,204,90],{},[151,206,158],{},[151,208,161],{},[151,210,164],{},[151,212,213],{},[22,214,215],{},"gofpdf (아카이브)",[151,217,218],{},"gofpdf 경유",[151,220,221],{},"행/열",[151,223,224],{},"기반이 죽은 상태",[119,226,227,229,232,237,239,241,246,248],{},[151,228,24],{},[151,230,231],{},"2021",[151,233,234],{},[22,235,236],{},"2021-09-08",[151,238,164],{},[151,240,169],{},[151,242,243],{},[55,244,245],{},"AddUTF8Font",[151,247,198],{},[151,249,250],{},[22,251,40],{},[119,253,254,257,260,265,267,269,273,275],{},[151,255,256],{},"go-pdf/fpdf",[151,258,259],{},"2023",[151,261,262],{},[22,263,264],{},"2025",[151,266,164],{},[151,268,169],{},[151,270,271],{},[55,272,245],{},[151,274,198],{},[151,276,277],{},[22,278,40],{},[119,280,281,283,285,287,292,295,298,300],{},[151,282,102],{},[151,284,158],{},[151,286,161],{},[151,288,289],{},[22,290,291],{},"AGPL-3.0 / 상용",[151,293,294],{},"다수",[151,296,297],{},"있음",[151,299,198],{},[151,301,302],{},"상용",[18,304,305,306,309],{},"주목할 점 셋. 절반이 아카이브됐다. Maroto 는 본체는 활발하지만 기반이 죽어 — 오늘 빌드가 통과해도 공급망 리스크가 있다. AGPL 을 수용 못 하는 조직에서 unidoc 선택은 기술 문제가 아니라 ",[22,307,308],{},"상용 라이선스 조달 문제","다.",[13,311,312],{"id":312},"벤치마크",[18,314,315,316,324,325,328],{},"코드: gpdf 저장소의 ",[317,318,322],"a",{"href":319,"rel":320},"https://github.com/gpdf-dev/gpdf/tree/main/_benchmark",[321],"nofollow",[55,323,57],{},". 환경은 Apple M1 (Max, 32 GB, macOS 14.5), Go 1.25, CGO 없음. 각 케이스는 최소 5 초 실시간으로 돌렸고, ",[55,326,327],{},"-benchmem"," 을 켜서 ns/op 와 할당 횟수를 기록했다.",[18,330,331],{},"4 가지 케이스를 고른 이유는 실제 프로덕션에서 생성되는 모양에 가깝기 때문:",[67,333,334,340,346,352],{},[30,335,336,339],{},[22,337,338],{},"단일 페이지 hello world",". 1 페이지 / 1 줄 / 1 폰트. 문서당 고정 오버헤드의 하한.",[30,341,342,345],{},[22,343,344],{},"4×10 인보이스 테이블",". 헤더 1 행 + 바디 10 행 + 컬럼 정렬 + 얇은 테두리. \"인보이스 생성\" 형.",[30,347,348,351],{},[22,349,350],{},"100 페이지 페이지 구분 리포트",". 반복 헤더, 푸터, 페이지 번호, 본문. 페이지 구분 비용 측정.",[30,353,354,357],{},[22,355,356],{},"복잡한 CJK 인보이스",". 일본어 (히라가나·가타카나·한자) 혼합, 4×15 명세 표, 헤더, 페이지 번호 포함 푸터, NotoSansJP TrueType 서브셋 임베드.",[18,359,360,361,363],{},"포함 안 함: ",[55,362,102],{},". 바이너리가 라이선스로 게이트돼 있어서, 그들의 공개 벤치 방법론을 공개 벤치 저장소에서 재현하는 건 오해 소지를 만든다. unidoc 를 검토 중이라면 자체 공식 벤치를 돌려 보라.",[365,366,367],"h3",{"id":367},"결과",[113,369,370,389],{},[116,371,372],{},[119,373,374,377,379,381,384,387],{},[122,375,376],{},"워크로드",[122,378,93],{},[122,380,80],{},[122,382,383],{},"Maroto v2",[122,385,386],{},"gofpdf",[122,388,256],{},[146,390,391,412,433,454],{},[119,392,393,395,400,403,406,409],{},[151,394,338],{},[151,396,397],{},[22,398,399],{},"13 µs",[151,401,402],{},"423 µs",[151,404,405],{},"237 µs",[151,407,408],{},"132 µs",[151,410,411],{},"135 µs",[119,413,414,416,421,424,427,430],{},[151,415,344],{},[151,417,418],{},[22,419,420],{},"108 µs",[151,422,423],{},"835 µs",[151,425,426],{},"8,600 µs",[151,428,429],{},"241 µs",[151,431,432],{},"243 µs",[119,434,435,438,443,445,448,451],{},[151,436,437],{},"100 페이지 리포트",[151,439,440],{},[22,441,442],{},"683 µs",[151,444,426],{},[151,446,447],{},"19,800 µs",[151,449,450],{},"11,700 µs",[151,452,453],{},"11,900 µs",[119,455,456,458,463,466,469,472],{},[151,457,356],{},[151,459,460],{},[22,461,462],{},"133 µs",[151,464,465],{},"997 µs",[151,467,468],{},"10,400 µs",[151,470,471],{},"254 µs",[151,473,474],{},"n/a",[18,476,477,478,480,481,483],{},"go-pdf/fpdf 의 CJK 칸이 ",[55,479,474],{}," 인 이유: 테스트한 버전에서 ",[55,482,245],{}," 경로가 NotoSansJP 의 cmap format 12 테이블을 읽을 때 panic. 패치로 고칠 수 있지만 포크 자체가 아카이브 — 아무도 수정을 릴리스하지 않는다.",[365,485,487],{"id":486},"숫자-읽는-법","숫자 읽는 법",[18,489,490,491,494],{},"순서는 워크로드를 넘나들어도 안정적이다. 모든 케이스에서 gpdf 는 2 위보다 ",[22,492,493],{},"10–30 배 빠르다",". 기묘한 기술이 아니라, 3 가지 설계가 누적된 결과:",[18,496,497,500,501,81],{},[22,498,499],{},"단일 패스 레이아웃",". gpdf 는 중간 AST 를 만들었다가 직렬화하지 않는다. 빌더가 해석된 시점에 PDF content stream 에 직접 쓰기 때문에 다른 라이브러리 대비 할당이 대략 절반으로 준다. 100 페이지 벤치에서 683 µs 대 19,800 µs 차이가 나는 건 튜닝 차이가 아니라 ",[22,502,503],{},"아키텍처가 다르다",[18,505,506,509],{},[22,507,508],{},"핫패스에 리플렉션 없음",". 레이아웃 엔진이 닿는 타입은 전부 구체 타입. 개별로는 미세 최적화이지만 100 페이지 리포트 프로파일에선 인터페이스 디스패치가 보이기 시작. 우리는 피했다.",[18,511,512,515],{},[22,513,514],{},"cmap 을 캐시하는 TrueType 서브세터",". gofpdf 는 글리프 조회마다 cmap 테이블을 다시 읽는다; gpdf 는 한 번 해석 후 캐시. Latin 전용이면 거의 차이 없지만 CJK 는 한 문단에 한자 + 가나 + 구두점으로 150 글리프를 건드릴 수 있고, \"동기 생성 가능\" 과 \"큐에 넣어야 함\" 의 경계가 된다.",[18,517,518,519,522],{},"벤치 표에는 안 나오는 주의 하나: ",[22,520,521],{},"대부분의 PDF 워크로드에서 절대 속도는 생각만큼 중요하지 않다",". 의미 있는 경계는 \"요청 경로에서 동기 생성해도 괜찮은가\" 다. hello world 한 페이지라면 모든 라이브러리가 통과. 반복 chrome 이 있는 100 페이지 리포트에선 gpdf 만 통과. 최대 문서가 영수증 한 장이라면 현역 4 개 모두 괜찮고, API 와 라이선스로 고르면 된다.",[13,524,525],{"id":525},"의존성",[18,527,528,529,532,533,536],{},"각각 방금 ",[55,530,531],{},"go get"," 한 후 ",[55,534,535],{},"go mod graph"," 결과:",[113,538,539,551],{},[116,540,541],{},[119,542,543,545,548],{},[122,544,124],{},[122,546,547],{},"외부 모듈",[122,549,550],{},"전이적 아카이브 의존",[146,552,553,566,574,584,592,604],{},[119,554,555,560,564],{},[151,556,557,559],{},[22,558,93],{}," (코어)",[151,561,562],{},[22,563,169],{},[151,565,161],{},[119,567,568,570,572],{},[151,569,80],{},[151,571,169],{},[151,573,161],{},[119,575,576,578,581],{},[151,577,386],{},[151,579,580],{},"0 (자신이 아카이브)",[151,582,583],{},"자신",[119,585,586,588,590],{},[151,587,256],{},[151,589,580],{},[151,591,583],{},[119,593,594,596,601],{},[151,595,90],{},[151,597,598],{},[22,599,600],{},"gofpdf (2021 아카이브)",[151,602,603],{},"있음 — gofpdf",[119,605,606,608,611],{},[151,607,102],{},[151,609,610],{},"다수 (이미지, 암호, 압축)",[151,612,613],{},"아카이브 없음",[18,615,616],{},"\"프로덕션 의존에 아카이브 레포 금지\" 린트 룰이 있는 팀이라면 오늘의 Maroto v2 는 이 규칙에 걸린다. Maroto 메인테이너들은 1 년 이상 gofpdf 제거 작업을 해왔고, 완료되면 이 행은 바뀐다. 판단 전에 Maroto 레포 현황을 확인하는 편이 좋다.",[13,618,132],{"id":132},[113,620,621,629],{},[116,622,623],{},[119,624,625,627],{},[122,626,124],{},[122,628,132],{},[146,630,631,638,644,650,656,662],{},[119,632,633,636],{},[151,634,635],{},"gpdf (코어)",[151,637,164],{},[119,639,640,642],{},[151,641,80],{},[151,643,164],{},[119,645,646,648],{},[151,647,90],{},[151,649,164],{},[119,651,652,654],{},[151,653,386],{},[151,655,164],{},[119,657,658,660],{},[151,659,256],{},[151,661,164],{},[119,663,664,668],{},[151,665,666],{},[22,667,102],{},[151,669,670],{},[22,671,672],{},"AGPL-3.0 또는 상용 라이선스",[18,674,675],{},"unidoc 의 AGPL 은 꽤 강한 편. 사용자가 네트워크로 접속하는 서버에서 사용한다면 서버 쪽 코드도 AGPL 로 공개해야 한다 — 대부분의 클로즈드 SaaS 에는 성립하지 않는다. 결국 상용 라이선스가 유일한 현실적 선택이 되고, 가격은 공개되지 않았다. 영업 상담이 전제.",[18,677,678,679,681],{},"GitHub 스타 수 비교에서 가장 자주 놓치는 지점이 여기. unidoc 는 기능도 가장 많고 스타도 가장 많지만, 상용 용례 대부분에 문을 닫는 라이선스를 가지고 있다 (구매 전제). unidoc 를 깎아내리는 게 아니다 — 비즈니스 모델은 정당하고 제품도 훌륭하다. 다만 ",[55,680,531],{}," 전에 알고 있어야 한다.",[13,683,685],{"id":684},"유지보수-상태","유지보수 상태",[27,687,688,693,698,703,713,722],{},[30,689,690,692],{},[22,691,93],{}," — 주 메인테이너는 본 팀 (gpdf-dev). 2–4 주마다 릴리스, 로드맵은 레포 내, CI 는 Go 1.22–1.26 에서 돌고, 메인 레포 이슈는 며칠 안에 응답. 진지하게 투자하고 있다.",[30,694,695,697],{},[22,696,80],{}," — 활발하지만 커밋 템포는 낮다. 이슈는 읽히고 PR 은 수 주 내 병합. 주 용도는 여전히 저수준 생성.",[30,699,700,702],{},[22,701,383],{}," — 활발. 2023 년 v2 재작성 이후 안정. gofpdf 의존은 알려져 있고 교체 작업 중. 결정 전에 레포 확인.",[30,704,705,707,708,712],{},[22,706,386],{}," — 2021-09-08 아카이브. 레포 배너: ",[709,710,711],"em",{},"\"This repository has been archived by the owner. It is now read-only.\""," 보안 패치도 버그 수정도 없음.",[30,714,715,717,718,81],{},[22,716,256],{}," — 2025 년 아카이브. README 가 다른 라이브러리 사용을 권장. 별도 마이그레이션 가이드를 썼다: ",[317,719,721],{"href":720},"/ko/blog/gofpdf-migration","gofpdf 에서 gpdf 로 마이그레이션",[30,723,724,726],{},[22,725,102],{}," — 활발, 상용 팀, 리소스 풍부, 엔터프라이즈 지원 제공.",[13,728,730],{"id":729},"고르는-법","고르는 법",[18,732,733],{},"기능 매트릭스 대신 의사결정 트리로 쓴다. \"기능 많음 = 정답\" 은 대개 맞는 질문이 아니다.",[27,735,736,742,748,754,760,769],{},[30,737,738,741],{},[22,739,740],{},"\"Go 코드베이스에서 인보이스·리포트·문서를 생성한다. MIT 선호, 의존 0 선호, CJK 가 섞이기도 한다.\""," → gpdf.",[30,743,744,747],{},[22,745,746],{},"\"맞춤 지오메트리까지 저수준으로 생성한다. 작고 안정적이며 수동 컨트롤이 강한 라이브러리가 좋다.\""," → signintech/gopdf.",[30,749,750,753],{},[22,751,752],{},"\"이미 Maroto 스타일 레이아웃 코드가 돌고 있다.\""," → gofpdf 제거 완료까지 Maroto v2 유지 후 재평가. API 자체가 문제는 아니다.",[30,755,756,759],{},[22,757,758],{},"\"PDF/A, OCR, 블랙아웃, 전자서명이 필요하고 회사가 상용 라이선스를 낼 수 있다.\""," → unidoc/unipdf. 라이선스 협의부터.",[30,761,762,765,766,81],{},[22,763,764],{},"\"여전히 gofpdf, 잘 돌고 있다.\""," → 오늘은 괜찮다. 다음 관련 의존의 CVE 가 터지기 전에 마이그레이션 계획. ",[317,767,768],{"href":720},"마이그레이션 가이드",[30,770,771,774],{},[22,772,773],{},"\"픽셀 단위 HTML/CSS→PDF 가 필요하다.\""," → 위 어느 것도 아님. go-rod / chromedp + headless Chromium, 콜드스타트 감수.",[18,776,777],{},"우리는 gpdf 팀이라 1 번과 5 번 다수 케이스에서 gpdf 가 합리적 기본값이라 생각한다 — 당연한 편향. 벤치 코드를 읽고 로컬에서 돌리고, 이 표를 곧이곧대로 믿지 말기를.",[13,779,781],{"id":780},"_30-줄짜리-gpdf-예제","30 줄짜리 gpdf 예제",[18,783,784],{},"\"가장 빠름\" 과 \"의존 그래프 최소\" 는 코드가 읽을 만할 때 의미가 있다. 완전히 실행되는 인보이스 한 페이지, 가짜 코드/생략 import 없음:",[786,787,792],"pre",{"className":788,"code":789,"language":790,"meta":791,"style":791},"language-go shiki shiki-themes material-theme-lighter material-theme material-theme-palenight","package main\n\nimport (\n    \"log\"\n    \"os\"\n\n    \"github.com/gpdf-dev/gpdf\"\n    \"github.com/gpdf-dev/gpdf/document\"\n    \"github.com/gpdf-dev/gpdf/pdf\"\n    \"github.com/gpdf-dev/gpdf/template\"\n)\n\nfunc main() {\n    doc := gpdf.NewDocument(\n        gpdf.WithPageSize(document.A4),\n        gpdf.WithMargins(document.UniformEdges(document.Mm(20))),\n    )\n\n    page := doc.AddPage()\n    page.AutoRow(func(r *template.RowBuilder) {\n        r.Col(12, func(c *template.ColBuilder) {\n            c.Text(\"청구서 #2026-0042\", template.Bold(), template.FontSize(20))\n            c.Spacer(document.Mm(6))\n            c.Table(\n                []string{\"항목\", \"수량\", \"단가\", \"금액\"},\n                [][]string{\n                    {\"프론트엔드 개발\", \"40 시간\", \"₩200,000\", \"₩8,000,000\"},\n                    {\"백엔드 개발\",     \"60 시간\", \"₩200,000\", \"₩12,000,000\"},\n                    {\"UI 디자인\",       \"20 시간\", \"₩160,000\", \"₩3,200,000\"},\n                },\n                template.ColumnWidths(50, 15, 15, 20),\n                template.TableHeaderStyle(\n                    template.Bold(),\n                    template.TextColor(pdf.White),\n                    template.BgColor(pdf.RGBHex(0x1A237E)),\n                ),\n            )\n        })\n    })\n\n    data, err := doc.Generate()\n    if err != nil {\n        log.Fatal(err)\n    }\n    if err := os.WriteFile(\"invoice.pdf\", data, 0o644); err != nil {\n        log.Fatal(err)\n    }\n}\n","go","",[55,793,794,807,814,824,836,846,851,861,871,881,891,897,902,918,939,964,1001,1007,1012,1031,1065,1103,1152,1177,1189,1240,1251,1293,1334,1376,1382,1414,1426,1439,1461,1488,1494,1500,1506,1512,1517,1539,1555,1573,1579,1626,1641,1646],{"__ignoreMap":791},[795,796,799,803],"span",{"class":797,"line":798},"line",1,[795,800,802],{"class":801},"sMK4o","package",[795,804,806],{"class":805},"sBMFI"," main\n",[795,808,810],{"class":797,"line":809},2,[795,811,813],{"emptyLinePlaceholder":812},true,"\n",[795,815,817,821],{"class":797,"line":816},3,[795,818,820],{"class":819},"s7zQu","import",[795,822,823],{"class":801}," (\n",[795,825,827,830,833],{"class":797,"line":826},4,[795,828,829],{"class":801},"    \"",[795,831,832],{"class":805},"log",[795,834,835],{"class":801},"\"\n",[795,837,839,841,844],{"class":797,"line":838},5,[795,840,829],{"class":801},[795,842,843],{"class":805},"os",[795,845,835],{"class":801},[795,847,849],{"class":797,"line":848},6,[795,850,813],{"emptyLinePlaceholder":812},[795,852,854,856,859],{"class":797,"line":853},7,[795,855,829],{"class":801},[795,857,858],{"class":805},"github.com/gpdf-dev/gpdf",[795,860,835],{"class":801},[795,862,864,866,869],{"class":797,"line":863},8,[795,865,829],{"class":801},[795,867,868],{"class":805},"github.com/gpdf-dev/gpdf/document",[795,870,835],{"class":801},[795,872,874,876,879],{"class":797,"line":873},9,[795,875,829],{"class":801},[795,877,878],{"class":805},"github.com/gpdf-dev/gpdf/pdf",[795,880,835],{"class":801},[795,882,884,886,889],{"class":797,"line":883},10,[795,885,829],{"class":801},[795,887,888],{"class":805},"github.com/gpdf-dev/gpdf/template",[795,890,835],{"class":801},[795,892,894],{"class":797,"line":893},11,[795,895,896],{"class":801},")\n",[795,898,900],{"class":797,"line":899},12,[795,901,813],{"emptyLinePlaceholder":812},[795,903,905,908,912,915],{"class":797,"line":904},13,[795,906,907],{"class":801},"func",[795,909,911],{"class":910},"s2Zo4"," main",[795,913,914],{"class":801},"()",[795,916,917],{"class":801}," {\n",[795,919,921,925,928,931,933,936],{"class":797,"line":920},14,[795,922,924],{"class":923},"sTEyZ","    doc ",[795,926,927],{"class":801},":=",[795,929,930],{"class":923}," gpdf",[795,932,81],{"class":801},[795,934,935],{"class":910},"NewDocument",[795,937,938],{"class":801},"(\n",[795,940,942,945,947,950,953,956,958,961],{"class":797,"line":941},15,[795,943,944],{"class":923},"        gpdf",[795,946,81],{"class":801},[795,948,949],{"class":910},"WithPageSize",[795,951,952],{"class":801},"(",[795,954,955],{"class":923},"document",[795,957,81],{"class":801},[795,959,960],{"class":923},"A4",[795,962,963],{"class":801},"),\n",[795,965,967,969,971,974,976,978,980,983,985,987,989,992,994,998],{"class":797,"line":966},16,[795,968,944],{"class":923},[795,970,81],{"class":801},[795,972,973],{"class":910},"WithMargins",[795,975,952],{"class":801},[795,977,955],{"class":923},[795,979,81],{"class":801},[795,981,982],{"class":910},"UniformEdges",[795,984,952],{"class":801},[795,986,955],{"class":923},[795,988,81],{"class":801},[795,990,991],{"class":910},"Mm",[795,993,952],{"class":801},[795,995,997],{"class":996},"sbssI","20",[795,999,1000],{"class":801},"))),\n",[795,1002,1004],{"class":797,"line":1003},17,[795,1005,1006],{"class":801},"    )\n",[795,1008,1010],{"class":797,"line":1009},18,[795,1011,813],{"emptyLinePlaceholder":812},[795,1013,1015,1018,1020,1023,1025,1028],{"class":797,"line":1014},19,[795,1016,1017],{"class":923},"    page ",[795,1019,927],{"class":801},[795,1021,1022],{"class":923}," doc",[795,1024,81],{"class":801},[795,1026,1027],{"class":910},"AddPage",[795,1029,1030],{"class":801},"()\n",[795,1032,1034,1037,1039,1042,1045,1049,1052,1055,1057,1060,1063],{"class":797,"line":1033},20,[795,1035,1036],{"class":923},"    page",[795,1038,81],{"class":801},[795,1040,1041],{"class":910},"AutoRow",[795,1043,1044],{"class":801},"(func(",[795,1046,1048],{"class":1047},"sHdIc","r",[795,1050,1051],{"class":801}," *",[795,1053,1054],{"class":805},"template",[795,1056,81],{"class":801},[795,1058,1059],{"class":805},"RowBuilder",[795,1061,1062],{"class":801},")",[795,1064,917],{"class":801},[795,1066,1068,1071,1073,1076,1078,1081,1084,1087,1090,1092,1094,1096,1099,1101],{"class":797,"line":1067},21,[795,1069,1070],{"class":923},"        r",[795,1072,81],{"class":801},[795,1074,1075],{"class":910},"Col",[795,1077,952],{"class":801},[795,1079,1080],{"class":996},"12",[795,1082,1083],{"class":801},",",[795,1085,1086],{"class":801}," func(",[795,1088,1089],{"class":1047},"c",[795,1091,1051],{"class":801},[795,1093,1054],{"class":805},[795,1095,81],{"class":801},[795,1097,1098],{"class":805},"ColBuilder",[795,1100,1062],{"class":801},[795,1102,917],{"class":801},[795,1104,1106,1109,1111,1114,1116,1119,1123,1125,1127,1130,1132,1135,1138,1140,1142,1145,1147,1149],{"class":797,"line":1105},22,[795,1107,1108],{"class":923},"            c",[795,1110,81],{"class":801},[795,1112,1113],{"class":910},"Text",[795,1115,952],{"class":801},[795,1117,1118],{"class":801},"\"",[795,1120,1122],{"class":1121},"sfazB","청구서 #2026-0042",[795,1124,1118],{"class":801},[795,1126,1083],{"class":801},[795,1128,1129],{"class":923}," template",[795,1131,81],{"class":801},[795,1133,1134],{"class":910},"Bold",[795,1136,1137],{"class":801},"(),",[795,1139,1129],{"class":923},[795,1141,81],{"class":801},[795,1143,1144],{"class":910},"FontSize",[795,1146,952],{"class":801},[795,1148,997],{"class":996},[795,1150,1151],{"class":801},"))\n",[795,1153,1155,1157,1159,1162,1164,1166,1168,1170,1172,1175],{"class":797,"line":1154},23,[795,1156,1108],{"class":923},[795,1158,81],{"class":801},[795,1160,1161],{"class":910},"Spacer",[795,1163,952],{"class":801},[795,1165,955],{"class":923},[795,1167,81],{"class":801},[795,1169,991],{"class":910},[795,1171,952],{"class":801},[795,1173,1174],{"class":996},"6",[795,1176,1151],{"class":801},[795,1178,1180,1182,1184,1187],{"class":797,"line":1179},24,[795,1181,1108],{"class":923},[795,1183,81],{"class":801},[795,1185,1186],{"class":910},"Table",[795,1188,938],{"class":801},[795,1190,1192,1195,1199,1202,1204,1207,1209,1211,1214,1217,1219,1221,1223,1226,1228,1230,1232,1235,1237],{"class":797,"line":1191},25,[795,1193,1194],{"class":801},"                []",[795,1196,1198],{"class":1197},"spNyl","string",[795,1200,1201],{"class":801},"{",[795,1203,1118],{"class":801},[795,1205,1206],{"class":1121},"항목",[795,1208,1118],{"class":801},[795,1210,1083],{"class":801},[795,1212,1213],{"class":801}," \"",[795,1215,1216],{"class":1121},"수량",[795,1218,1118],{"class":801},[795,1220,1083],{"class":801},[795,1222,1213],{"class":801},[795,1224,1225],{"class":1121},"단가",[795,1227,1118],{"class":801},[795,1229,1083],{"class":801},[795,1231,1213],{"class":801},[795,1233,1234],{"class":1121},"금액",[795,1236,1118],{"class":801},[795,1238,1239],{"class":801},"},\n",[795,1241,1243,1246,1248],{"class":797,"line":1242},26,[795,1244,1245],{"class":801},"                [][]",[795,1247,1198],{"class":1197},[795,1249,1250],{"class":801},"{\n",[795,1252,1254,1257,1259,1262,1264,1266,1268,1271,1273,1275,1277,1280,1282,1284,1286,1289,1291],{"class":797,"line":1253},27,[795,1255,1256],{"class":801},"                    {",[795,1258,1118],{"class":801},[795,1260,1261],{"class":1121},"프론트엔드 개발",[795,1263,1118],{"class":801},[795,1265,1083],{"class":801},[795,1267,1213],{"class":801},[795,1269,1270],{"class":1121},"40 시간",[795,1272,1118],{"class":801},[795,1274,1083],{"class":801},[795,1276,1213],{"class":801},[795,1278,1279],{"class":1121},"₩200,000",[795,1281,1118],{"class":801},[795,1283,1083],{"class":801},[795,1285,1213],{"class":801},[795,1287,1288],{"class":1121},"₩8,000,000",[795,1290,1118],{"class":801},[795,1292,1239],{"class":801},[795,1294,1296,1298,1300,1303,1305,1307,1310,1313,1315,1317,1319,1321,1323,1325,1327,1330,1332],{"class":797,"line":1295},28,[795,1297,1256],{"class":801},[795,1299,1118],{"class":801},[795,1301,1302],{"class":1121},"백엔드 개발",[795,1304,1118],{"class":801},[795,1306,1083],{"class":801},[795,1308,1309],{"class":801},"     \"",[795,1311,1312],{"class":1121},"60 시간",[795,1314,1118],{"class":801},[795,1316,1083],{"class":801},[795,1318,1213],{"class":801},[795,1320,1279],{"class":1121},[795,1322,1118],{"class":801},[795,1324,1083],{"class":801},[795,1326,1213],{"class":801},[795,1328,1329],{"class":1121},"₩12,000,000",[795,1331,1118],{"class":801},[795,1333,1239],{"class":801},[795,1335,1337,1339,1341,1344,1346,1348,1351,1354,1356,1358,1360,1363,1365,1367,1369,1372,1374],{"class":797,"line":1336},29,[795,1338,1256],{"class":801},[795,1340,1118],{"class":801},[795,1342,1343],{"class":1121},"UI 디자인",[795,1345,1118],{"class":801},[795,1347,1083],{"class":801},[795,1349,1350],{"class":801},"       \"",[795,1352,1353],{"class":1121},"20 시간",[795,1355,1118],{"class":801},[795,1357,1083],{"class":801},[795,1359,1213],{"class":801},[795,1361,1362],{"class":1121},"₩160,000",[795,1364,1118],{"class":801},[795,1366,1083],{"class":801},[795,1368,1213],{"class":801},[795,1370,1371],{"class":1121},"₩3,200,000",[795,1373,1118],{"class":801},[795,1375,1239],{"class":801},[795,1377,1379],{"class":797,"line":1378},30,[795,1380,1381],{"class":801},"                },\n",[795,1383,1385,1388,1390,1393,1395,1398,1400,1403,1405,1407,1409,1412],{"class":797,"line":1384},31,[795,1386,1387],{"class":923},"                template",[795,1389,81],{"class":801},[795,1391,1392],{"class":910},"ColumnWidths",[795,1394,952],{"class":801},[795,1396,1397],{"class":996},"50",[795,1399,1083],{"class":801},[795,1401,1402],{"class":996}," 15",[795,1404,1083],{"class":801},[795,1406,1402],{"class":996},[795,1408,1083],{"class":801},[795,1410,1411],{"class":996}," 20",[795,1413,963],{"class":801},[795,1415,1417,1419,1421,1424],{"class":797,"line":1416},32,[795,1418,1387],{"class":923},[795,1420,81],{"class":801},[795,1422,1423],{"class":910},"TableHeaderStyle",[795,1425,938],{"class":801},[795,1427,1429,1432,1434,1436],{"class":797,"line":1428},33,[795,1430,1431],{"class":923},"                    template",[795,1433,81],{"class":801},[795,1435,1134],{"class":910},[795,1437,1438],{"class":801},"(),\n",[795,1440,1442,1444,1446,1449,1451,1454,1456,1459],{"class":797,"line":1441},34,[795,1443,1431],{"class":923},[795,1445,81],{"class":801},[795,1447,1448],{"class":910},"TextColor",[795,1450,952],{"class":801},[795,1452,1453],{"class":923},"pdf",[795,1455,81],{"class":801},[795,1457,1458],{"class":923},"White",[795,1460,963],{"class":801},[795,1462,1464,1466,1468,1471,1473,1475,1477,1480,1482,1485],{"class":797,"line":1463},35,[795,1465,1431],{"class":923},[795,1467,81],{"class":801},[795,1469,1470],{"class":910},"BgColor",[795,1472,952],{"class":801},[795,1474,1453],{"class":923},[795,1476,81],{"class":801},[795,1478,1479],{"class":910},"RGBHex",[795,1481,952],{"class":801},[795,1483,1484],{"class":996},"0x1A237E",[795,1486,1487],{"class":801},")),\n",[795,1489,1491],{"class":797,"line":1490},36,[795,1492,1493],{"class":801},"                ),\n",[795,1495,1497],{"class":797,"line":1496},37,[795,1498,1499],{"class":801},"            )\n",[795,1501,1503],{"class":797,"line":1502},38,[795,1504,1505],{"class":801},"        })\n",[795,1507,1509],{"class":797,"line":1508},39,[795,1510,1511],{"class":801},"    })\n",[795,1513,1515],{"class":797,"line":1514},40,[795,1516,813],{"emptyLinePlaceholder":812},[795,1518,1520,1523,1525,1528,1530,1532,1534,1537],{"class":797,"line":1519},41,[795,1521,1522],{"class":923},"    data",[795,1524,1083],{"class":801},[795,1526,1527],{"class":923}," err ",[795,1529,927],{"class":801},[795,1531,1022],{"class":923},[795,1533,81],{"class":801},[795,1535,1536],{"class":910},"Generate",[795,1538,1030],{"class":801},[795,1540,1542,1545,1547,1550,1553],{"class":797,"line":1541},42,[795,1543,1544],{"class":819},"    if",[795,1546,1527],{"class":923},[795,1548,1549],{"class":801},"!=",[795,1551,1552],{"class":801}," nil",[795,1554,917],{"class":801},[795,1556,1558,1561,1563,1566,1568,1571],{"class":797,"line":1557},43,[795,1559,1560],{"class":923},"        log",[795,1562,81],{"class":801},[795,1564,1565],{"class":910},"Fatal",[795,1567,952],{"class":801},[795,1569,1570],{"class":923},"err",[795,1572,896],{"class":801},[795,1574,1576],{"class":797,"line":1575},44,[795,1577,1578],{"class":801},"    }\n",[795,1580,1582,1584,1586,1588,1591,1593,1596,1598,1600,1603,1605,1607,1610,1612,1615,1618,1620,1622,1624],{"class":797,"line":1581},45,[795,1583,1544],{"class":819},[795,1585,1527],{"class":923},[795,1587,927],{"class":801},[795,1589,1590],{"class":923}," os",[795,1592,81],{"class":801},[795,1594,1595],{"class":910},"WriteFile",[795,1597,952],{"class":801},[795,1599,1118],{"class":801},[795,1601,1602],{"class":1121},"invoice.pdf",[795,1604,1118],{"class":801},[795,1606,1083],{"class":801},[795,1608,1609],{"class":923}," data",[795,1611,1083],{"class":801},[795,1613,1614],{"class":996}," 0o644",[795,1616,1617],{"class":801},");",[795,1619,1527],{"class":923},[795,1621,1549],{"class":801},[795,1623,1552],{"class":801},[795,1625,917],{"class":801},[795,1627,1629,1631,1633,1635,1637,1639],{"class":797,"line":1628},46,[795,1630,1560],{"class":923},[795,1632,81],{"class":801},[795,1634,1565],{"class":910},[795,1636,952],{"class":801},[795,1638,1570],{"class":923},[795,1640,896],{"class":801},[795,1642,1644],{"class":797,"line":1643},47,[795,1645,1578],{"class":801},[795,1647,1649],{"class":797,"line":1648},48,[795,1650,1651],{"class":801},"}\n",[18,1653,1654,1657,1658,1661],{},[55,1655,1656],{},"SetXY"," 0 개. 수동 컬럼 폭 계산 0 개. 문서 옵션에 ",[55,1659,1660],{},"gpdf.WithFont(\"NotoSansKR\", ttfBytes)"," 를 더하면 위 한국어가 그대로 렌더링된다. 두부 현상 없음.",[13,1663,1665],{"id":1664},"싣지-않은-것","싣지 않은 것",[18,1667,1668],{},"모든 비교 글에는 \"X 때문에 제외\" 섹션이 있다. 우리 쪽:",[27,1670,1671,1677,1689,1698],{},[30,1672,1673,1676],{},[22,1674,1675],{},"사내 gofpdf 포크",". 프로덕션에서 돌고 있는 비공개 포크가 있다. 볼 수 없는 코드는 벤치할 수 없다.",[30,1678,1679,1684,1685,1688],{},[22,1680,1681],{},[55,1682,1683],{},"pdfcpu",". \"Go PDF 라이브러리\" 목록에 늘 보이지만 주 용도는 ",[22,1686,1687],{},"PDF 프로세서"," (병합·분할·암호화·스탬프) 로 생성이 아니다. 이 글 범위 밖; 프로세싱 지향 별도 글을 계획.",[30,1690,1691,1697],{},[22,1692,1693,1696],{},[55,1694,1695],{},"gotenberg"," 이나 headless 브라우저 서비스 래퍼",". 라이브러리가 아니고 공평한 비교도 아니다.",[30,1699,1700,1706],{},[22,1701,1702,1703,1705],{},"자체 ",[55,1704,93],{}," 벤치",". 비교의 초점은 코어 수치.",[13,1708,1710],{"id":1709},"faq","FAQ",[18,1712,1713,1716],{},[22,1714,1715],{},"gpdf 는 왜 gofpdf 보다 10× 빠른가? 어떤 트릭?","\n단일 트릭은 없다. 3 가지 설계가 누적: 단일 패스 레이아웃 (빌더-라이터 간 AST 없음), 핫패스의 구체 타입, cmap 을 캐시하는 TrueType 서브세터. 하나당 2× 가량 기여. 누적해서 자릿수가 바뀐다.",[18,1718,1719,1722,1723,1726],{},[22,1720,1721],{},"이 벤치 직접 재현 가능한가?","\n가능. ",[55,1724,1725],{},"git clone https://github.com/gpdf-dev/gpdf && cd gpdf/_benchmark && go test -bench=. -benchmem",". 같은 CPU 아키, 같은 Go 버전에서 숫자가 안 맞으면 이슈를 열어 달라. 벤치 드리프트는 발생하고 알고 싶다.",[18,1728,1729,1732],{},[22,1730,1731],{},"gofpdf 는 돌아오나?","\n현실적으로는 아니다. 마지막 커밋은 2021 년. 이슈 트래커는 닫혔다. 누가 다시 열어도 커서 + 싱글바이트 폰트 + 그리드 없음 의 아키텍처는 2026 년 출발점으로 맞지 않는다. 유물 취급 후 마이그레이션이 실용적.",[18,1734,1735,1738],{},[22,1736,1737],{},"Java iText / Python ReportLab / Node pdfkit 는?","\n언어 교차 벤치는 별도 글. 짧게: Go 는 처리량과 콜드스타트에서 대체로 이기고, 기능 폭 (특히 HTML→PDF 충실도) 에서 진다. 이미 Go 팀이면 gpdf 가 더 빠르고 작음. Python / Node 팀이 Go 로 옮길 땐 마이그레이션 비용이 커서 대용량일 때만 투자 회수.",[18,1740,1741,1744],{},[22,1742,1743],{},"경쟁사가 개선되면 이 비교는 공평성을 유지하나?","\n유지한다. 매년 돌린다. signintech/gopdf 가 테이블 API 를 내서 시간을 절반으로 줄이면 2027 판에 반영한다. Maroto v2 가 gofpdf 제거를 끝내면 그 행은 바뀐다. 벤치 코드를 공개한 건 어떤 누구도 우리 말을 믿을 필요 없게 하기 위해서다.",[13,1746,1748],{"id":1747},"gpdf-써-보기","gpdf 써 보기",[18,1750,1751],{},"gpdf 는 Go 의 PDF 생성 라이브러리. MIT, 의존 0, 네이티브 CJK.",[786,1753,1757],{"className":1754,"code":1755,"language":1756,"meta":791,"style":791},"language-bash shiki shiki-themes material-theme-lighter material-theme material-theme-palenight","go get github.com/gpdf-dev/gpdf\n","bash",[55,1758,1759],{"__ignoreMap":791},[795,1760,1761,1763,1766],{"class":797,"line":798},[795,1762,790],{"class":805},[795,1764,1765],{"class":1121}," get",[795,1767,1768],{"class":1121}," github.com/gpdf-dev/gpdf\n",[18,1770,1771,1776,1777],{},[317,1772,1775],{"href":1773,"rel":1774},"https://github.com/gpdf-dev/gpdf",[321],"⭐ GitHub 에서 스타"," · ",[317,1778,1781],{"href":1779,"rel":1780},"https://gpdf.dev/ko/docs/quickstart",[321],"문서 읽기",[13,1783,1785],{"id":1784},"이어서-읽기","이어서 읽기",[27,1787,1788,1794,1805],{},[30,1789,1790,1793],{},[317,1791,1792],{"href":720},"gofpdf 가 아카이브됐다. gpdf 로의 마이그레이션 가이드"," — 5 쌍의 Before/After 로 전체 API 매핑.",[30,1795,1796,1800,1801,1804],{},[317,1797,1799],{"href":1779,"rel":1798},[321],"Quickstart"," — ",[55,1802,1803],{},"go.mod"," 포함 5 분 세팅.",[30,1806,1807,1808,81],{},"벤치마크 코드 그 자체: ",[317,1809,1811],{"href":319,"rel":1810},[321],[55,1812,57],{},[1814,1815,1816],"style",{},"html pre.shiki code .sMK4o, html code.shiki .sMK4o{--shiki-light:#39ADB5;--shiki-default:#89DDFF;--shiki-dark:#89DDFF}html pre.shiki code .sBMFI, html code.shiki .sBMFI{--shiki-light:#E2931D;--shiki-default:#FFCB6B;--shiki-dark:#FFCB6B}html pre.shiki code .s7zQu, html code.shiki .s7zQu{--shiki-light:#39ADB5;--shiki-light-font-style:italic;--shiki-default:#89DDFF;--shiki-default-font-style:italic;--shiki-dark:#89DDFF;--shiki-dark-font-style:italic}html pre.shiki code .s2Zo4, html code.shiki .s2Zo4{--shiki-light:#6182B8;--shiki-default:#82AAFF;--shiki-dark:#82AAFF}html pre.shiki code .sTEyZ, html code.shiki .sTEyZ{--shiki-light:#90A4AE;--shiki-default:#EEFFFF;--shiki-dark:#BABED8}html pre.shiki code .sbssI, html code.shiki .sbssI{--shiki-light:#F76D47;--shiki-default:#F78C6C;--shiki-dark:#F78C6C}html pre.shiki code .sHdIc, html code.shiki .sHdIc{--shiki-light:#90A4AE;--shiki-light-font-style:italic;--shiki-default:#EEFFFF;--shiki-default-font-style:italic;--shiki-dark:#BABED8;--shiki-dark-font-style:italic}html pre.shiki code .sfazB, html code.shiki .sfazB{--shiki-light:#91B859;--shiki-default:#C3E88D;--shiki-dark:#C3E88D}html pre.shiki code .spNyl, html code.shiki .spNyl{--shiki-light:#9C3EDA;--shiki-default:#C792EA;--shiki-dark:#C792EA}html .light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html.light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html.dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}",{"title":791,"searchDepth":809,"depth":809,"links":1818},[1819,1820,1821,1822,1826,1827,1828,1829,1830,1831,1832,1833,1834],{"id":15,"depth":809,"text":16},{"id":61,"depth":809,"text":62},{"id":111,"depth":809,"text":111},{"id":312,"depth":809,"text":312,"children":1823},[1824,1825],{"id":367,"depth":816,"text":367},{"id":486,"depth":816,"text":487},{"id":525,"depth":809,"text":525},{"id":132,"depth":809,"text":132},{"id":684,"depth":809,"text":685},{"id":729,"depth":809,"text":730},{"id":780,"depth":809,"text":781},{"id":1664,"depth":809,"text":1665},{"id":1709,"depth":809,"text":1710},{"id":1747,"depth":809,"text":1748},{"id":1784,"depth":809,"text":1785},"2026-04-15","2026 년에도 살아있는 Go PDF 라이브러리를 4 가지 워크로드에서 벤치마크. 라이선스·의존성·유지보수 상태를 정리.",false,"md",null,{},"/ko/blog/go-pdf-library-showdown-2026",{"title":5,"description":1836},"ko/blog/002.go-pdf-library-showdown-2026",[1845,1846],"comparison","benchmark","teHAfEI1uOobKueYaAVVayAsI2HPDNPhHDNAT5xQYo4",1776529266912]