[{"data":1,"prerenderedAt":5103},["ShallowReactive",2],{"blog-ja-gofpdf-migration":3},{"id":4,"title":5,"author":6,"body":9,"date":5064,"description":5065,"draft":5066,"extension":5067,"howTo":5068,"image":5092,"meta":5093,"navigation":511,"path":5094,"seo":5095,"stem":5096,"tags":5097,"updated":5092,"__hash__":5102},"blogJa/ja/blog/001.gofpdf-migration.md","アーカイブされた gofpdf から gpdf へ移行する完全ガイド",{"name":7,"url":8},"gpdf team","https://gpdf.dev",{"type":10,"value":11,"toc":5048},"minimark",[12,17,38,49,52,70,73,77,83,86,93,100,103,107,110,138,144,148,151,431,445,472,476,479,484,715,720,1184,1194,1208,1212,1222,1226,1977,1980,1984,2365,2382,2385,2389,2395,2399,2562,2575,2579,3032,3035,3045,3048,3051,3055,3076,3080,3402,3408,3412,4089,4104,4108,4122,4126,4404,4408,4728,4745,4749,4759,4855,4858,4861,4864,4867,4907,4910,4914,4920,4942,4952,4963,4972,4978,4982,4985,5002,5017,5020,5044],[13,14,16],"h2",{"id":15},"tldr","TL;DR",[18,19,20,24,25,29,30,33,34,37],"p",{},[21,22,23],"strong",{},"gpdf"," は純 Go・外部依存ゼロ・ネイティブ CJK 対応の PDF ライブラリ。",[26,27,28],"code",{},"AddUTF8Font"," のお作法も、",[26,31,32],{},"SetXY"," で座標を押し回す必要もない。Bootstrap 風の 12 カラムグリッドで宣言的に書ける。ベンチマークでは ",[21,35,36],{},"gofpdf より約 10 倍速い","。移行はだいたい「命令型のカーソル操作」を「宣言的なビルダー」に置き換える作業で、5 つの Before/After で全体像を示す。",[18,39,40,41,44,45,48],{},"先週、社内の同僚が新規プロジェクトで ",[26,42,43],{},"go get github.com/jung-kurt/gofpdf"," を叩いて、10 分後に GitHub のバナーのスクリーンショットを送ってきた。",[21,46,47],{},"「This repository has been archived by the owner. It is now read-only.」"," 続けて一言、「フォークもアーカイブされてるんだけど」。",[18,50,51],{},"両方ともそうです。",[18,53,54,57,58,61,62,65,66,69],{},[26,55,56],{},"jung-kurt/gofpdf"," がアーカイブされたのは ",[21,59,60],{},"2021 年 9 月 8 日","。コミュニティフォークの ",[26,63,64],{},"go-pdf/fpdf"," も最終リリースは 2023 年で、",[21,67,68],{},"2025 年に正式にアーカイブ"," された。Stack Overflow や Qiita の Go PDF 記事の 7 割が今も指している先は、4 年以上 read-only。後継として推されていたフォークも消えた。",[18,71,72],{},"すでに gofpdf 製のコードが本番にあるなら、この記事は移行マップ。新規に「Go で PDF どうすればいい?」で gofpdf に手が伸びかけているなら、これがそのまま代替案。",[13,74,76],{"id":75},"なぜ-gofpdf-は本当に死んだままなのか","なぜ gofpdf は本当に死んだままなのか",[18,78,79,80,82],{},"OSS は必ずしも死なない。メンテナが手を引いても誰かが拾うことはある。gofpdf もそのパターンになるはずだった。実際 ",[26,81,64],{}," はコードを再編成し、長年の bug を直し、PR を受け入れていた。普通に「後継」として機能していた。",[18,84,85],{},"それが 2025 年に止まった。README には「このプロジェクトは積極的にメンテナンスされていません。別のライブラリを検討してください」という一文。",[18,87,88,89,92],{},"理由はどうでもいい。問題は結果のほうだ。",[21,90,91],{},"gofpdf 依存の Go プロジェクトは、今や 2 段重ねの未メンテコードの上に座っている","。脆弱性が出ても誰も直さない。PDF 2.0 仕様は 2020 年に出たが、gofpdf はその大半に未対応。Go 1.25 のループ変数セマンティクスは今は gofpdf でも問題なく動くが、明日壊れたらフォークするのはあなたの仕事。",[18,94,95,96,99],{},"これは「ライブラリにバグがある」問題ではなく、",[21,97,98],{},"サプライチェーンの問題","。",[18,101,102],{},"日本のチームには特に効く。電子帳簿保存法対応で「PDF/A-3 で保存しろ」と言われたとき、未メンテのライブラリを根拠に出すのはきつい。監査も通らない。",[13,104,106],{"id":105},"日本のチームが-gofpdf-で実際にやってきたこと","日本のチームが gofpdf で実際にやってきたこと",[18,108,109],{},"GitHub Issues や Qiita 投稿を眺めると、gofpdf の主用途はだいたい次の 4 つに集約される:",[111,112,113,120,126,132],"ol",{},[114,115,116,119],"li",{},[21,117,118],{},"請求書・領収書・納品書"," — ヘッダ、宛先、明細表、合計、フッタ",[114,121,122,125],{},[21,123,124],{},"帳票・レポート"," — ヘッダとページ番号が繰り返される複数ページの文書",[114,127,128,131],{},[21,129,130],{},"証明書・チケット類"," — テンプレ画像の上に固定位置でテキストを乗せる",[114,133,134,137],{},[21,135,136],{},"日本語・中国語・韓国語の PDF"," — 明細・配送ラベル・領収書",[18,139,140,141,143],{},"最初の 3 つは gpdf のビルダー API で素直に書ける。問題は 4 つ目。gofpdf は ",[26,142,28],{}," を呼び、TTF のパスを管理し、文字が基本面の外に出ないことを祈る、というお作法だった。gpdf は CJK を最初からファーストクラスとして扱う — TrueType を登録して日本語を書く、それで終わり。",[13,145,147],{"id":146},"api-対応表","API 対応表",[18,149,150],{},"下の表がチートシート。後ろの章で 5 つの具体的な Before/After を見せる。",[152,153,154,169],"table",{},[155,156,157],"thead",{},[158,159,160,164,167],"tr",{},[161,162,163],"th",{},"やりたいこと",[161,165,166],{},"gofpdf",[161,168,23],{},[170,171,172,188,212,234,252,267,285,303,318,333,352,367,382,401,416],"tbody",{},[158,173,174,178,183],{},[175,176,177],"td",{},"文書の作成",[175,179,180],{},[26,181,182],{},"gofpdf.New(\"P\", \"mm\", \"A4\", \"\")",[175,184,185],{},[26,186,187],{},"gpdf.NewDocument(gpdf.WithPageSize(document.A4))",[158,189,190,193,198],{},[175,191,192],{},"ページ追加",[175,194,195],{},[26,196,197],{},"pdf.AddPage()",[175,199,200,203,204],{},[26,201,202],{},"doc.AddPage()"," ",[205,206,207,208,211],"em",{},"(",[26,209,210],{},"*PageBuilder"," を返す)",[158,213,214,217,222],{},[175,215,216],{},"フォント指定",[175,218,219],{},[26,220,221],{},"pdf.SetFont(\"Arial\", \"B\", 16)",[175,223,224,227,228,227,231],{},[26,225,226],{},"template.FontFamily(...)"," / ",[26,229,230],{},"template.Bold()",[26,232,233],{},"template.FontSize(16)",[158,235,236,239,244],{},[175,237,238],{},"TTF 登録 (CJK)",[175,240,241],{},[26,242,243],{},"pdf.AddUTF8Font(\"noto\", \"\", \"NotoSansJP-Regular.ttf\")",[175,245,246,203,249],{},[26,247,248],{},"gpdf.WithFont(\"NotoSansJP\", ttfBytes)",[205,250,251],{},"(構築時に渡す)",[158,253,254,257,262],{},[175,255,256],{},"1 行テキスト",[175,258,259],{},[26,260,261],{},"pdf.Cell(40, 10, \"hi\")",[175,263,264],{},[26,265,266],{},"c.Text(\"hi\")",[158,268,269,272,277],{},[175,270,271],{},"折り返しテキスト",[175,273,274],{},[26,275,276],{},"pdf.MultiCell(0, 10, body, \"\", \"L\", false)",[175,278,279,203,282],{},[26,280,281],{},"c.Text(body)",[205,283,284],{},"(自動で折り返し)",[158,286,287,290,295],{},[175,288,289],{},"テキスト色",[175,291,292],{},[26,293,294],{},"pdf.SetTextColor(255, 0, 0)",[175,296,297,203,300],{},[26,298,299],{},"template.TextColor(pdf.Red)",[205,301,302],{},"(テキスト単位のオプション)",[158,304,305,308,313],{},[175,306,307],{},"横線",[175,309,310],{},[26,311,312],{},"pdf.Line(x1, y1, x2, y2)",[175,314,315],{},[26,316,317],{},"c.Line(template.LineThickness(document.Pt(1)))",[158,319,320,323,328],{},[175,321,322],{},"画像埋め込み",[175,324,325],{},[26,326,327],{},"pdf.ImageOptions(\"logo.png\", x, y, w, h, ...)",[175,329,330],{},[26,331,332],{},"c.Image(imgBytes, template.FitWidth(document.Mm(50)))",[158,334,335,338,343],{},[175,336,337],{},"カーソル位置",[175,339,340],{},[26,341,342],{},"pdf.SetXY(x, y)",[175,344,345],{},[205,346,347,348,351],{},"(なし — 行/列で書く、または ",[26,349,350],{},"page.Absolute(x, y, fn)",")",[158,353,354,357,362],{},[175,355,356],{},"全ページ共通のヘッダ",[175,358,359],{},[26,360,361],{},"pdf.SetHeaderFunc(fn)",[175,363,364],{},[26,365,366],{},"doc.Header(fn)",[158,368,369,372,377],{},[175,370,371],{},"全ページ共通のフッタ",[175,373,374],{},[26,375,376],{},"pdf.SetFooterFunc(fn)",[175,378,379],{},[26,380,381],{},"doc.Footer(fn)",[158,383,384,387,393],{},[175,385,386],{},"ページ番号",[175,388,389,392],{},[26,390,391],{},"pdf.PageNo()","（手動）",[175,394,395,227,398],{},[26,396,397],{},"c.PageNumber()",[26,399,400],{},"c.TotalPages()",[158,402,403,406,411],{},[175,404,405],{},"ファイル出力",[175,407,408],{},[26,409,410],{},"pdf.OutputFileAndClose(\"out.pdf\")",[175,412,413],{},[26,414,415],{},"data, _ := doc.Generate(); os.WriteFile(\"out.pdf\", data, 0o644)",[158,417,418,421,426],{},[175,419,420],{},"io.Writer に出力",[175,422,423],{},[26,424,425],{},"pdf.Output(w)",[175,427,428],{},[26,429,430],{},"doc.Render(w)",[18,432,433,434,437,438,441,442,444],{},"一番大きな変化は API の形。gofpdf は ",[21,435,436],{},"命令型"," で、カーソルを動かして書く。gpdf は ",[21,439,440],{},"宣言的"," で、行と列のツリーを記述してレイアウトエンジンに任せる。最初の数本は gpdf のほうが長く感じる。3 本目あたりで ",[26,443,32],{}," が恋しくなくなる。",[18,446,447,448,227,451,227,454,457,458,227,461,227,464,467,468,471],{},"単位の話。gofpdf は構築時に基準単位 (",[26,449,450],{},"\"mm\"",[26,452,453],{},"\"pt\"",[26,455,456],{},"\"in\"",") を選ぶ。gpdf は内部はすべて pt で固定し、呼び出し側で ",[26,459,460],{},"document.Mm(20)",[26,462,463],{},"document.Pt(12)",[26,465,466],{},"document.Cm(1)"," などのヘルパを使う。CSS に近い感覚で、ヘッダのマージンを ",[26,469,470],{},"document.Mm(15)"," で切ったあとは単位のことを意識しなくなる。",[13,473,475],{"id":474},"before-after-1-一番シンプルな-pdf","Before / After 1: 一番シンプルな PDF",[18,477,478],{},"「Hello, World」のペア。gofpdf の短さこそが流行った理由なのは間違いない。gpdf 版は数行多い — カーソルを動かしているのではなく、ツリーを組んでいるからだ。",[18,480,481],{},[21,482,483],{},"Before — gofpdf:",[485,486,491],"pre",{"className":487,"code":488,"language":489,"meta":490,"style":490},"language-go shiki shiki-themes material-theme-lighter material-theme material-theme-palenight","package main\n\nimport \"github.com/jung-kurt/gofpdf\"\n\nfunc main() {\n    pdf := gofpdf.New(\"P\", \"mm\", \"A4\", \"\")\n    pdf.AddPage()\n    pdf.SetFont(\"Arial\", \"B\", 24)\n    pdf.Cell(40, 10, \"Hello, World!\")\n    pdf.OutputFileAndClose(\"hello.pdf\")\n}\n","go","",[26,492,493,506,513,529,534,550,607,621,657,688,709],{"__ignoreMap":490},[494,495,498,502],"span",{"class":496,"line":497},"line",1,[494,499,501],{"class":500},"sMK4o","package",[494,503,505],{"class":504},"sBMFI"," main\n",[494,507,509],{"class":496,"line":508},2,[494,510,512],{"emptyLinePlaceholder":511},true,"\n",[494,514,516,520,523,526],{"class":496,"line":515},3,[494,517,519],{"class":518},"s7zQu","import",[494,521,522],{"class":500}," \"",[494,524,525],{"class":504},"github.com/jung-kurt/gofpdf",[494,527,528],{"class":500},"\"\n",[494,530,532],{"class":496,"line":531},4,[494,533,512],{"emptyLinePlaceholder":511},[494,535,537,540,544,547],{"class":496,"line":536},5,[494,538,539],{"class":500},"func",[494,541,543],{"class":542},"s2Zo4"," main",[494,545,546],{"class":500},"()",[494,548,549],{"class":500}," {\n",[494,551,553,557,560,563,566,569,571,574,578,580,583,585,588,590,592,594,597,599,601,604],{"class":496,"line":552},6,[494,554,556],{"class":555},"sTEyZ","    pdf ",[494,558,559],{"class":500},":=",[494,561,562],{"class":555}," gofpdf",[494,564,565],{"class":500},".",[494,567,568],{"class":542},"New",[494,570,207],{"class":500},[494,572,573],{"class":500},"\"",[494,575,577],{"class":576},"sfazB","P",[494,579,573],{"class":500},[494,581,582],{"class":500},",",[494,584,522],{"class":500},[494,586,587],{"class":576},"mm",[494,589,573],{"class":500},[494,591,582],{"class":500},[494,593,522],{"class":500},[494,595,596],{"class":576},"A4",[494,598,573],{"class":500},[494,600,582],{"class":500},[494,602,603],{"class":500}," \"\"",[494,605,606],{"class":500},")\n",[494,608,610,613,615,618],{"class":496,"line":609},7,[494,611,612],{"class":555},"    pdf",[494,614,565],{"class":500},[494,616,617],{"class":542},"AddPage",[494,619,620],{"class":500},"()\n",[494,622,624,626,628,631,633,635,638,640,642,644,647,649,651,655],{"class":496,"line":623},8,[494,625,612],{"class":555},[494,627,565],{"class":500},[494,629,630],{"class":542},"SetFont",[494,632,207],{"class":500},[494,634,573],{"class":500},[494,636,637],{"class":576},"Arial",[494,639,573],{"class":500},[494,641,582],{"class":500},[494,643,522],{"class":500},[494,645,646],{"class":576},"B",[494,648,573],{"class":500},[494,650,582],{"class":500},[494,652,654],{"class":653},"sbssI"," 24",[494,656,606],{"class":500},[494,658,660,662,664,667,669,672,674,677,679,681,684,686],{"class":496,"line":659},9,[494,661,612],{"class":555},[494,663,565],{"class":500},[494,665,666],{"class":542},"Cell",[494,668,207],{"class":500},[494,670,671],{"class":653},"40",[494,673,582],{"class":500},[494,675,676],{"class":653}," 10",[494,678,582],{"class":500},[494,680,522],{"class":500},[494,682,683],{"class":576},"Hello, World!",[494,685,573],{"class":500},[494,687,606],{"class":500},[494,689,691,693,695,698,700,702,705,707],{"class":496,"line":690},10,[494,692,612],{"class":555},[494,694,565],{"class":500},[494,696,697],{"class":542},"OutputFileAndClose",[494,699,207],{"class":500},[494,701,573],{"class":500},[494,703,704],{"class":576},"hello.pdf",[494,706,573],{"class":500},[494,708,606],{"class":500},[494,710,712],{"class":496,"line":711},11,[494,713,714],{"class":500},"}\n",[18,716,717],{},[21,718,719],{},"After — gpdf:",[485,721,723],{"className":487,"code":722,"language":489,"meta":490,"style":490},"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/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(\"Hello, World!\", template.FontSize(24), template.Bold())\n        })\n    })\n\n    data, err := doc.Generate()\n    if err != nil {\n        log.Fatal(err)\n    }\n    if err := os.WriteFile(\"hello.pdf\", data, 0o644); err != nil {\n        log.Fatal(err)\n    }\n}\n",[26,724,725,731,735,742,752,761,765,774,783,792,796,800,811,830,853,889,895,900,917,950,987,1034,1040,1046,1051,1073,1089,1107,1113,1159,1174,1179],{"__ignoreMap":490},[494,726,727,729],{"class":496,"line":497},[494,728,501],{"class":500},[494,730,505],{"class":504},[494,732,733],{"class":496,"line":508},[494,734,512],{"emptyLinePlaceholder":511},[494,736,737,739],{"class":496,"line":515},[494,738,519],{"class":518},[494,740,741],{"class":500}," (\n",[494,743,744,747,750],{"class":496,"line":531},[494,745,746],{"class":500},"    \"",[494,748,749],{"class":504},"log",[494,751,528],{"class":500},[494,753,754,756,759],{"class":496,"line":536},[494,755,746],{"class":500},[494,757,758],{"class":504},"os",[494,760,528],{"class":500},[494,762,763],{"class":496,"line":552},[494,764,512],{"emptyLinePlaceholder":511},[494,766,767,769,772],{"class":496,"line":609},[494,768,746],{"class":500},[494,770,771],{"class":504},"github.com/gpdf-dev/gpdf",[494,773,528],{"class":500},[494,775,776,778,781],{"class":496,"line":623},[494,777,746],{"class":500},[494,779,780],{"class":504},"github.com/gpdf-dev/gpdf/document",[494,782,528],{"class":500},[494,784,785,787,790],{"class":496,"line":659},[494,786,746],{"class":500},[494,788,789],{"class":504},"github.com/gpdf-dev/gpdf/template",[494,791,528],{"class":500},[494,793,794],{"class":496,"line":690},[494,795,606],{"class":500},[494,797,798],{"class":496,"line":711},[494,799,512],{"emptyLinePlaceholder":511},[494,801,803,805,807,809],{"class":496,"line":802},12,[494,804,539],{"class":500},[494,806,543],{"class":542},[494,808,546],{"class":500},[494,810,549],{"class":500},[494,812,814,817,819,822,824,827],{"class":496,"line":813},13,[494,815,816],{"class":555},"    doc ",[494,818,559],{"class":500},[494,820,821],{"class":555}," gpdf",[494,823,565],{"class":500},[494,825,826],{"class":542},"NewDocument",[494,828,829],{"class":500},"(\n",[494,831,833,836,838,841,843,846,848,850],{"class":496,"line":832},14,[494,834,835],{"class":555},"        gpdf",[494,837,565],{"class":500},[494,839,840],{"class":542},"WithPageSize",[494,842,207],{"class":500},[494,844,845],{"class":555},"document",[494,847,565],{"class":500},[494,849,596],{"class":555},[494,851,852],{"class":500},"),\n",[494,854,856,858,860,863,865,867,869,872,874,876,878,881,883,886],{"class":496,"line":855},15,[494,857,835],{"class":555},[494,859,565],{"class":500},[494,861,862],{"class":542},"WithMargins",[494,864,207],{"class":500},[494,866,845],{"class":555},[494,868,565],{"class":500},[494,870,871],{"class":542},"UniformEdges",[494,873,207],{"class":500},[494,875,845],{"class":555},[494,877,565],{"class":500},[494,879,880],{"class":542},"Mm",[494,882,207],{"class":500},[494,884,885],{"class":653},"20",[494,887,888],{"class":500},"))),\n",[494,890,892],{"class":496,"line":891},16,[494,893,894],{"class":500},"    )\n",[494,896,898],{"class":496,"line":897},17,[494,899,512],{"emptyLinePlaceholder":511},[494,901,903,906,908,911,913,915],{"class":496,"line":902},18,[494,904,905],{"class":555},"    page ",[494,907,559],{"class":500},[494,909,910],{"class":555}," doc",[494,912,565],{"class":500},[494,914,617],{"class":542},[494,916,620],{"class":500},[494,918,920,923,925,928,931,935,938,941,943,946,948],{"class":496,"line":919},19,[494,921,922],{"class":555},"    page",[494,924,565],{"class":500},[494,926,927],{"class":542},"AutoRow",[494,929,930],{"class":500},"(func(",[494,932,934],{"class":933},"sHdIc","r",[494,936,937],{"class":500}," *",[494,939,940],{"class":504},"template",[494,942,565],{"class":500},[494,944,945],{"class":504},"RowBuilder",[494,947,351],{"class":500},[494,949,549],{"class":500},[494,951,953,956,958,961,963,966,968,971,974,976,978,980,983,985],{"class":496,"line":952},20,[494,954,955],{"class":555},"        r",[494,957,565],{"class":500},[494,959,960],{"class":542},"Col",[494,962,207],{"class":500},[494,964,965],{"class":653},"12",[494,967,582],{"class":500},[494,969,970],{"class":500}," func(",[494,972,973],{"class":933},"c",[494,975,937],{"class":500},[494,977,940],{"class":504},[494,979,565],{"class":500},[494,981,982],{"class":504},"ColBuilder",[494,984,351],{"class":500},[494,986,549],{"class":500},[494,988,990,993,995,998,1000,1002,1004,1006,1008,1011,1013,1016,1018,1021,1024,1026,1028,1031],{"class":496,"line":989},21,[494,991,992],{"class":555},"            c",[494,994,565],{"class":500},[494,996,997],{"class":542},"Text",[494,999,207],{"class":500},[494,1001,573],{"class":500},[494,1003,683],{"class":576},[494,1005,573],{"class":500},[494,1007,582],{"class":500},[494,1009,1010],{"class":555}," template",[494,1012,565],{"class":500},[494,1014,1015],{"class":542},"FontSize",[494,1017,207],{"class":500},[494,1019,1020],{"class":653},"24",[494,1022,1023],{"class":500},"),",[494,1025,1010],{"class":555},[494,1027,565],{"class":500},[494,1029,1030],{"class":542},"Bold",[494,1032,1033],{"class":500},"())\n",[494,1035,1037],{"class":496,"line":1036},22,[494,1038,1039],{"class":500},"        })\n",[494,1041,1043],{"class":496,"line":1042},23,[494,1044,1045],{"class":500},"    })\n",[494,1047,1049],{"class":496,"line":1048},24,[494,1050,512],{"emptyLinePlaceholder":511},[494,1052,1054,1057,1059,1062,1064,1066,1068,1071],{"class":496,"line":1053},25,[494,1055,1056],{"class":555},"    data",[494,1058,582],{"class":500},[494,1060,1061],{"class":555}," err ",[494,1063,559],{"class":500},[494,1065,910],{"class":555},[494,1067,565],{"class":500},[494,1069,1070],{"class":542},"Generate",[494,1072,620],{"class":500},[494,1074,1076,1079,1081,1084,1087],{"class":496,"line":1075},26,[494,1077,1078],{"class":518},"    if",[494,1080,1061],{"class":555},[494,1082,1083],{"class":500},"!=",[494,1085,1086],{"class":500}," nil",[494,1088,549],{"class":500},[494,1090,1092,1095,1097,1100,1102,1105],{"class":496,"line":1091},27,[494,1093,1094],{"class":555},"        log",[494,1096,565],{"class":500},[494,1098,1099],{"class":542},"Fatal",[494,1101,207],{"class":500},[494,1103,1104],{"class":555},"err",[494,1106,606],{"class":500},[494,1108,1110],{"class":496,"line":1109},28,[494,1111,1112],{"class":500},"    }\n",[494,1114,1116,1118,1120,1122,1125,1127,1130,1132,1134,1136,1138,1140,1143,1145,1148,1151,1153,1155,1157],{"class":496,"line":1115},29,[494,1117,1078],{"class":518},[494,1119,1061],{"class":555},[494,1121,559],{"class":500},[494,1123,1124],{"class":555}," os",[494,1126,565],{"class":500},[494,1128,1129],{"class":542},"WriteFile",[494,1131,207],{"class":500},[494,1133,573],{"class":500},[494,1135,704],{"class":576},[494,1137,573],{"class":500},[494,1139,582],{"class":500},[494,1141,1142],{"class":555}," data",[494,1144,582],{"class":500},[494,1146,1147],{"class":653}," 0o644",[494,1149,1150],{"class":500},");",[494,1152,1061],{"class":555},[494,1154,1083],{"class":500},[494,1156,1086],{"class":500},[494,1158,549],{"class":500},[494,1160,1162,1164,1166,1168,1170,1172],{"class":496,"line":1161},30,[494,1163,1094],{"class":555},[494,1165,565],{"class":500},[494,1167,1099],{"class":542},[494,1169,207],{"class":500},[494,1171,1104],{"class":555},[494,1173,606],{"class":500},[494,1175,1177],{"class":496,"line":1176},31,[494,1178,1112],{"class":500},[494,1180,1182],{"class":496,"line":1181},32,[494,1183,714],{"class":500},[18,1185,1186,1187,1189,1190,1193],{},"グリッドが仕事をしている。",[26,1188,927],{}," は中身の高さで決まる行を追加し、",[26,1191,1192],{},"r.Col(12, ...)"," は「12 グリッド全部を占める列」。Bootstrap と同じ発想を PDF ページに適用しただけ。",[18,1195,1196,1199,1200,1203,1204,1207],{},[26,1197,1198],{},"Generate()"," はバイト列を返す。",[26,1201,1202],{},"io.Writer"," に流したいなら ",[26,1205,1206],{},"Render(w)","。「ファイルを閉じる」処理がないのは gpdf がファイルハンドルを所有していないから。",[13,1209,1211],{"id":1210},"before-after-2-明細表","Before / After 2: 明細表",[18,1213,1214,1215,1217,1218,1221],{},"請求書の明細表は gofpdf が一番饒舌になる場所。built-in のテーブルがないので、",[26,1216,666],{}," を二重ループで叩き、列幅を自分で管理し、",[26,1219,1220],{},"Ln(-1)"," で改行する。gofpdf の請求書チュートリアル記事は半分が表のボイラープレートで埋まっている。",[18,1223,1224],{},[21,1225,483],{},[485,1227,1229],{"className":487,"code":1228,"language":489,"meta":490,"style":490},"pdf.SetFont(\"Arial\", \"B\", 11)\npdf.SetFillColor(220, 220, 220)\npdf.CellFormat(80, 8, \"品目\",   \"1\", 0, \"L\", true, 0, \"\")\npdf.CellFormat(20, 8, \"数量\",   \"1\", 0, \"C\", true, 0, \"\")\npdf.CellFormat(30, 8, \"単価\",   \"1\", 0, \"R\", true, 0, \"\")\npdf.CellFormat(30, 8, \"金額\",   \"1\", 1, \"R\", true, 0, \"\")\n\npdf.SetFont(\"Arial\", \"\", 11)\nitems := [][]string{\n    {\"フロントエンド開発\", \"40h\", \"¥15,000\", \"¥600,000\"},\n    {\"バックエンド開発\",  \"60h\", \"¥15,000\", \"¥900,000\"},\n    {\"UI デザイン\",      \"20h\", \"¥12,000\", \"¥240,000\"},\n}\nfor _, row := range items {\n    pdf.CellFormat(80, 8, row[0], \"1\", 0, \"L\", false, 0, \"\")\n    pdf.CellFormat(20, 8, row[1], \"1\", 0, \"C\", false, 0, \"\")\n    pdf.CellFormat(30, 8, row[2], \"1\", 0, \"R\", false, 0, \"\")\n    pdf.CellFormat(30, 8, row[3], \"1\", 1, \"R\", false, 0, \"\")\n}\n",[26,1230,1231,1263,1288,1356,1416,1477,1537,1541,1567,1584,1626,1666,1707,1711,1734,1797,1855,1914,1973],{"__ignoreMap":490},[494,1232,1233,1236,1238,1240,1242,1244,1246,1248,1250,1252,1254,1256,1258,1261],{"class":496,"line":497},[494,1234,1235],{"class":555},"pdf",[494,1237,565],{"class":500},[494,1239,630],{"class":542},[494,1241,207],{"class":500},[494,1243,573],{"class":500},[494,1245,637],{"class":576},[494,1247,573],{"class":500},[494,1249,582],{"class":500},[494,1251,522],{"class":500},[494,1253,646],{"class":576},[494,1255,573],{"class":500},[494,1257,582],{"class":500},[494,1259,1260],{"class":653}," 11",[494,1262,606],{"class":500},[494,1264,1265,1267,1269,1272,1274,1277,1279,1282,1284,1286],{"class":496,"line":508},[494,1266,1235],{"class":555},[494,1268,565],{"class":500},[494,1270,1271],{"class":542},"SetFillColor",[494,1273,207],{"class":500},[494,1275,1276],{"class":653},"220",[494,1278,582],{"class":500},[494,1280,1281],{"class":653}," 220",[494,1283,582],{"class":500},[494,1285,1281],{"class":653},[494,1287,606],{"class":500},[494,1289,1290,1292,1294,1297,1299,1302,1304,1307,1309,1311,1314,1316,1318,1321,1324,1326,1328,1331,1333,1335,1338,1340,1342,1346,1348,1350,1352,1354],{"class":496,"line":515},[494,1291,1235],{"class":555},[494,1293,565],{"class":500},[494,1295,1296],{"class":542},"CellFormat",[494,1298,207],{"class":500},[494,1300,1301],{"class":653},"80",[494,1303,582],{"class":500},[494,1305,1306],{"class":653}," 8",[494,1308,582],{"class":500},[494,1310,522],{"class":500},[494,1312,1313],{"class":576},"品目",[494,1315,573],{"class":500},[494,1317,582],{"class":500},[494,1319,1320],{"class":500},"   \"",[494,1322,1323],{"class":576},"1",[494,1325,573],{"class":500},[494,1327,582],{"class":500},[494,1329,1330],{"class":653}," 0",[494,1332,582],{"class":500},[494,1334,522],{"class":500},[494,1336,1337],{"class":576},"L",[494,1339,573],{"class":500},[494,1341,582],{"class":500},[494,1343,1345],{"class":1344},"sfNiH"," true",[494,1347,582],{"class":500},[494,1349,1330],{"class":653},[494,1351,582],{"class":500},[494,1353,603],{"class":500},[494,1355,606],{"class":500},[494,1357,1358,1360,1362,1364,1366,1368,1370,1372,1374,1376,1379,1381,1383,1385,1387,1389,1391,1393,1395,1397,1400,1402,1404,1406,1408,1410,1412,1414],{"class":496,"line":531},[494,1359,1235],{"class":555},[494,1361,565],{"class":500},[494,1363,1296],{"class":542},[494,1365,207],{"class":500},[494,1367,885],{"class":653},[494,1369,582],{"class":500},[494,1371,1306],{"class":653},[494,1373,582],{"class":500},[494,1375,522],{"class":500},[494,1377,1378],{"class":576},"数量",[494,1380,573],{"class":500},[494,1382,582],{"class":500},[494,1384,1320],{"class":500},[494,1386,1323],{"class":576},[494,1388,573],{"class":500},[494,1390,582],{"class":500},[494,1392,1330],{"class":653},[494,1394,582],{"class":500},[494,1396,522],{"class":500},[494,1398,1399],{"class":576},"C",[494,1401,573],{"class":500},[494,1403,582],{"class":500},[494,1405,1345],{"class":1344},[494,1407,582],{"class":500},[494,1409,1330],{"class":653},[494,1411,582],{"class":500},[494,1413,603],{"class":500},[494,1415,606],{"class":500},[494,1417,1418,1420,1422,1424,1426,1429,1431,1433,1435,1437,1440,1442,1444,1446,1448,1450,1452,1454,1456,1458,1461,1463,1465,1467,1469,1471,1473,1475],{"class":496,"line":536},[494,1419,1235],{"class":555},[494,1421,565],{"class":500},[494,1423,1296],{"class":542},[494,1425,207],{"class":500},[494,1427,1428],{"class":653},"30",[494,1430,582],{"class":500},[494,1432,1306],{"class":653},[494,1434,582],{"class":500},[494,1436,522],{"class":500},[494,1438,1439],{"class":576},"単価",[494,1441,573],{"class":500},[494,1443,582],{"class":500},[494,1445,1320],{"class":500},[494,1447,1323],{"class":576},[494,1449,573],{"class":500},[494,1451,582],{"class":500},[494,1453,1330],{"class":653},[494,1455,582],{"class":500},[494,1457,522],{"class":500},[494,1459,1460],{"class":576},"R",[494,1462,573],{"class":500},[494,1464,582],{"class":500},[494,1466,1345],{"class":1344},[494,1468,582],{"class":500},[494,1470,1330],{"class":653},[494,1472,582],{"class":500},[494,1474,603],{"class":500},[494,1476,606],{"class":500},[494,1478,1479,1481,1483,1485,1487,1489,1491,1493,1495,1497,1500,1502,1504,1506,1508,1510,1512,1515,1517,1519,1521,1523,1525,1527,1529,1531,1533,1535],{"class":496,"line":552},[494,1480,1235],{"class":555},[494,1482,565],{"class":500},[494,1484,1296],{"class":542},[494,1486,207],{"class":500},[494,1488,1428],{"class":653},[494,1490,582],{"class":500},[494,1492,1306],{"class":653},[494,1494,582],{"class":500},[494,1496,522],{"class":500},[494,1498,1499],{"class":576},"金額",[494,1501,573],{"class":500},[494,1503,582],{"class":500},[494,1505,1320],{"class":500},[494,1507,1323],{"class":576},[494,1509,573],{"class":500},[494,1511,582],{"class":500},[494,1513,1514],{"class":653}," 1",[494,1516,582],{"class":500},[494,1518,522],{"class":500},[494,1520,1460],{"class":576},[494,1522,573],{"class":500},[494,1524,582],{"class":500},[494,1526,1345],{"class":1344},[494,1528,582],{"class":500},[494,1530,1330],{"class":653},[494,1532,582],{"class":500},[494,1534,603],{"class":500},[494,1536,606],{"class":500},[494,1538,1539],{"class":496,"line":609},[494,1540,512],{"emptyLinePlaceholder":511},[494,1542,1543,1545,1547,1549,1551,1553,1555,1557,1559,1561,1563,1565],{"class":496,"line":623},[494,1544,1235],{"class":555},[494,1546,565],{"class":500},[494,1548,630],{"class":542},[494,1550,207],{"class":500},[494,1552,573],{"class":500},[494,1554,637],{"class":576},[494,1556,573],{"class":500},[494,1558,582],{"class":500},[494,1560,603],{"class":500},[494,1562,582],{"class":500},[494,1564,1260],{"class":653},[494,1566,606],{"class":500},[494,1568,1569,1572,1574,1577,1581],{"class":496,"line":659},[494,1570,1571],{"class":555},"items ",[494,1573,559],{"class":500},[494,1575,1576],{"class":500}," [][]",[494,1578,1580],{"class":1579},"spNyl","string",[494,1582,1583],{"class":500},"{\n",[494,1585,1586,1589,1591,1594,1596,1598,1600,1603,1605,1607,1609,1612,1614,1616,1618,1621,1623],{"class":496,"line":690},[494,1587,1588],{"class":500},"    {",[494,1590,573],{"class":500},[494,1592,1593],{"class":576},"フロントエンド開発",[494,1595,573],{"class":500},[494,1597,582],{"class":500},[494,1599,522],{"class":500},[494,1601,1602],{"class":576},"40h",[494,1604,573],{"class":500},[494,1606,582],{"class":500},[494,1608,522],{"class":500},[494,1610,1611],{"class":576},"¥15,000",[494,1613,573],{"class":500},[494,1615,582],{"class":500},[494,1617,522],{"class":500},[494,1619,1620],{"class":576},"¥600,000",[494,1622,573],{"class":500},[494,1624,1625],{"class":500},"},\n",[494,1627,1628,1630,1632,1635,1637,1639,1642,1645,1647,1649,1651,1653,1655,1657,1659,1662,1664],{"class":496,"line":711},[494,1629,1588],{"class":500},[494,1631,573],{"class":500},[494,1633,1634],{"class":576},"バックエンド開発",[494,1636,573],{"class":500},[494,1638,582],{"class":500},[494,1640,1641],{"class":500},"  \"",[494,1643,1644],{"class":576},"60h",[494,1646,573],{"class":500},[494,1648,582],{"class":500},[494,1650,522],{"class":500},[494,1652,1611],{"class":576},[494,1654,573],{"class":500},[494,1656,582],{"class":500},[494,1658,522],{"class":500},[494,1660,1661],{"class":576},"¥900,000",[494,1663,573],{"class":500},[494,1665,1625],{"class":500},[494,1667,1668,1670,1672,1675,1677,1679,1682,1685,1687,1689,1691,1694,1696,1698,1700,1703,1705],{"class":496,"line":802},[494,1669,1588],{"class":500},[494,1671,573],{"class":500},[494,1673,1674],{"class":576},"UI デザイン",[494,1676,573],{"class":500},[494,1678,582],{"class":500},[494,1680,1681],{"class":500},"      \"",[494,1683,1684],{"class":576},"20h",[494,1686,573],{"class":500},[494,1688,582],{"class":500},[494,1690,522],{"class":500},[494,1692,1693],{"class":576},"¥12,000",[494,1695,573],{"class":500},[494,1697,582],{"class":500},[494,1699,522],{"class":500},[494,1701,1702],{"class":576},"¥240,000",[494,1704,573],{"class":500},[494,1706,1625],{"class":500},[494,1708,1709],{"class":496,"line":813},[494,1710,714],{"class":500},[494,1712,1713,1716,1719,1721,1724,1726,1729,1732],{"class":496,"line":832},[494,1714,1715],{"class":518},"for",[494,1717,1718],{"class":555}," _",[494,1720,582],{"class":500},[494,1722,1723],{"class":555}," row ",[494,1725,559],{"class":500},[494,1727,1728],{"class":518}," range",[494,1730,1731],{"class":555}," items ",[494,1733,1583],{"class":500},[494,1735,1736,1738,1740,1742,1744,1746,1748,1750,1752,1755,1758,1761,1764,1766,1768,1770,1772,1774,1776,1778,1780,1782,1784,1787,1789,1791,1793,1795],{"class":496,"line":855},[494,1737,612],{"class":555},[494,1739,565],{"class":500},[494,1741,1296],{"class":542},[494,1743,207],{"class":500},[494,1745,1301],{"class":653},[494,1747,582],{"class":500},[494,1749,1306],{"class":653},[494,1751,582],{"class":500},[494,1753,1754],{"class":555}," row",[494,1756,1757],{"class":500},"[",[494,1759,1760],{"class":653},"0",[494,1762,1763],{"class":500},"],",[494,1765,522],{"class":500},[494,1767,1323],{"class":576},[494,1769,573],{"class":500},[494,1771,582],{"class":500},[494,1773,1330],{"class":653},[494,1775,582],{"class":500},[494,1777,522],{"class":500},[494,1779,1337],{"class":576},[494,1781,573],{"class":500},[494,1783,582],{"class":500},[494,1785,1786],{"class":1344}," false",[494,1788,582],{"class":500},[494,1790,1330],{"class":653},[494,1792,582],{"class":500},[494,1794,603],{"class":500},[494,1796,606],{"class":500},[494,1798,1799,1801,1803,1805,1807,1809,1811,1813,1815,1817,1819,1821,1823,1825,1827,1829,1831,1833,1835,1837,1839,1841,1843,1845,1847,1849,1851,1853],{"class":496,"line":891},[494,1800,612],{"class":555},[494,1802,565],{"class":500},[494,1804,1296],{"class":542},[494,1806,207],{"class":500},[494,1808,885],{"class":653},[494,1810,582],{"class":500},[494,1812,1306],{"class":653},[494,1814,582],{"class":500},[494,1816,1754],{"class":555},[494,1818,1757],{"class":500},[494,1820,1323],{"class":653},[494,1822,1763],{"class":500},[494,1824,522],{"class":500},[494,1826,1323],{"class":576},[494,1828,573],{"class":500},[494,1830,582],{"class":500},[494,1832,1330],{"class":653},[494,1834,582],{"class":500},[494,1836,522],{"class":500},[494,1838,1399],{"class":576},[494,1840,573],{"class":500},[494,1842,582],{"class":500},[494,1844,1786],{"class":1344},[494,1846,582],{"class":500},[494,1848,1330],{"class":653},[494,1850,582],{"class":500},[494,1852,603],{"class":500},[494,1854,606],{"class":500},[494,1856,1857,1859,1861,1863,1865,1867,1869,1871,1873,1875,1877,1880,1882,1884,1886,1888,1890,1892,1894,1896,1898,1900,1902,1904,1906,1908,1910,1912],{"class":496,"line":897},[494,1858,612],{"class":555},[494,1860,565],{"class":500},[494,1862,1296],{"class":542},[494,1864,207],{"class":500},[494,1866,1428],{"class":653},[494,1868,582],{"class":500},[494,1870,1306],{"class":653},[494,1872,582],{"class":500},[494,1874,1754],{"class":555},[494,1876,1757],{"class":500},[494,1878,1879],{"class":653},"2",[494,1881,1763],{"class":500},[494,1883,522],{"class":500},[494,1885,1323],{"class":576},[494,1887,573],{"class":500},[494,1889,582],{"class":500},[494,1891,1330],{"class":653},[494,1893,582],{"class":500},[494,1895,522],{"class":500},[494,1897,1460],{"class":576},[494,1899,573],{"class":500},[494,1901,582],{"class":500},[494,1903,1786],{"class":1344},[494,1905,582],{"class":500},[494,1907,1330],{"class":653},[494,1909,582],{"class":500},[494,1911,603],{"class":500},[494,1913,606],{"class":500},[494,1915,1916,1918,1920,1922,1924,1926,1928,1930,1932,1934,1936,1939,1941,1943,1945,1947,1949,1951,1953,1955,1957,1959,1961,1963,1965,1967,1969,1971],{"class":496,"line":902},[494,1917,612],{"class":555},[494,1919,565],{"class":500},[494,1921,1296],{"class":542},[494,1923,207],{"class":500},[494,1925,1428],{"class":653},[494,1927,582],{"class":500},[494,1929,1306],{"class":653},[494,1931,582],{"class":500},[494,1933,1754],{"class":555},[494,1935,1757],{"class":500},[494,1937,1938],{"class":653},"3",[494,1940,1763],{"class":500},[494,1942,522],{"class":500},[494,1944,1323],{"class":576},[494,1946,573],{"class":500},[494,1948,582],{"class":500},[494,1950,1514],{"class":653},[494,1952,582],{"class":500},[494,1954,522],{"class":500},[494,1956,1460],{"class":576},[494,1958,573],{"class":500},[494,1960,582],{"class":500},[494,1962,1786],{"class":1344},[494,1964,582],{"class":500},[494,1966,1330],{"class":653},[494,1968,582],{"class":500},[494,1970,603],{"class":500},[494,1972,606],{"class":500},[494,1974,1975],{"class":496,"line":919},[494,1976,714],{"class":500},[18,1978,1979],{},"列幅を頭で計算しながら書く。品目名が折り返したら破綻する。",[18,1981,1982],{},[21,1983,719],{},[485,1985,1987],{"className":487,"code":1986,"language":489,"meta":490,"style":490},"page.AutoRow(func(r *template.RowBuilder) {\n    r.Col(12, func(c *template.ColBuilder) {\n        c.Table(\n            []string{\"品目\", \"数量\", \"単価\", \"金額\"},\n            [][]string{\n                {\"フロントエンド開発\", \"40h\", \"¥15,000\", \"¥600,000\"},\n                {\"バックエンド開発\",  \"60h\", \"¥15,000\", \"¥900,000\"},\n                {\"UI デザイン\",      \"20h\", \"¥12,000\", \"¥240,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            template.TableStripe(pdf.RGBHex(0xF5F5F5)),\n        )\n    })\n})\n",[26,1988,1989,2014,2045,2057,2099,2108,2145,2181,2217,2222,2253,2264,2276,2296,2322,2327,2351,2356,2360],{"__ignoreMap":490},[494,1990,1991,1994,1996,1998,2000,2002,2004,2006,2008,2010,2012],{"class":496,"line":497},[494,1992,1993],{"class":555},"page",[494,1995,565],{"class":500},[494,1997,927],{"class":542},[494,1999,930],{"class":500},[494,2001,934],{"class":933},[494,2003,937],{"class":500},[494,2005,940],{"class":504},[494,2007,565],{"class":500},[494,2009,945],{"class":504},[494,2011,351],{"class":500},[494,2013,549],{"class":500},[494,2015,2016,2019,2021,2023,2025,2027,2029,2031,2033,2035,2037,2039,2041,2043],{"class":496,"line":508},[494,2017,2018],{"class":555},"    r",[494,2020,565],{"class":500},[494,2022,960],{"class":542},[494,2024,207],{"class":500},[494,2026,965],{"class":653},[494,2028,582],{"class":500},[494,2030,970],{"class":500},[494,2032,973],{"class":933},[494,2034,937],{"class":500},[494,2036,940],{"class":504},[494,2038,565],{"class":500},[494,2040,982],{"class":504},[494,2042,351],{"class":500},[494,2044,549],{"class":500},[494,2046,2047,2050,2052,2055],{"class":496,"line":515},[494,2048,2049],{"class":555},"        c",[494,2051,565],{"class":500},[494,2053,2054],{"class":542},"Table",[494,2056,829],{"class":500},[494,2058,2059,2062,2064,2067,2069,2071,2073,2075,2077,2079,2081,2083,2085,2087,2089,2091,2093,2095,2097],{"class":496,"line":531},[494,2060,2061],{"class":500},"            []",[494,2063,1580],{"class":1579},[494,2065,2066],{"class":500},"{",[494,2068,573],{"class":500},[494,2070,1313],{"class":576},[494,2072,573],{"class":500},[494,2074,582],{"class":500},[494,2076,522],{"class":500},[494,2078,1378],{"class":576},[494,2080,573],{"class":500},[494,2082,582],{"class":500},[494,2084,522],{"class":500},[494,2086,1439],{"class":576},[494,2088,573],{"class":500},[494,2090,582],{"class":500},[494,2092,522],{"class":500},[494,2094,1499],{"class":576},[494,2096,573],{"class":500},[494,2098,1625],{"class":500},[494,2100,2101,2104,2106],{"class":496,"line":536},[494,2102,2103],{"class":500},"            [][]",[494,2105,1580],{"class":1579},[494,2107,1583],{"class":500},[494,2109,2110,2113,2115,2117,2119,2121,2123,2125,2127,2129,2131,2133,2135,2137,2139,2141,2143],{"class":496,"line":552},[494,2111,2112],{"class":500},"                {",[494,2114,573],{"class":500},[494,2116,1593],{"class":576},[494,2118,573],{"class":500},[494,2120,582],{"class":500},[494,2122,522],{"class":500},[494,2124,1602],{"class":576},[494,2126,573],{"class":500},[494,2128,582],{"class":500},[494,2130,522],{"class":500},[494,2132,1611],{"class":576},[494,2134,573],{"class":500},[494,2136,582],{"class":500},[494,2138,522],{"class":500},[494,2140,1620],{"class":576},[494,2142,573],{"class":500},[494,2144,1625],{"class":500},[494,2146,2147,2149,2151,2153,2155,2157,2159,2161,2163,2165,2167,2169,2171,2173,2175,2177,2179],{"class":496,"line":609},[494,2148,2112],{"class":500},[494,2150,573],{"class":500},[494,2152,1634],{"class":576},[494,2154,573],{"class":500},[494,2156,582],{"class":500},[494,2158,1641],{"class":500},[494,2160,1644],{"class":576},[494,2162,573],{"class":500},[494,2164,582],{"class":500},[494,2166,522],{"class":500},[494,2168,1611],{"class":576},[494,2170,573],{"class":500},[494,2172,582],{"class":500},[494,2174,522],{"class":500},[494,2176,1661],{"class":576},[494,2178,573],{"class":500},[494,2180,1625],{"class":500},[494,2182,2183,2185,2187,2189,2191,2193,2195,2197,2199,2201,2203,2205,2207,2209,2211,2213,2215],{"class":496,"line":623},[494,2184,2112],{"class":500},[494,2186,573],{"class":500},[494,2188,1674],{"class":576},[494,2190,573],{"class":500},[494,2192,582],{"class":500},[494,2194,1681],{"class":500},[494,2196,1684],{"class":576},[494,2198,573],{"class":500},[494,2200,582],{"class":500},[494,2202,522],{"class":500},[494,2204,1693],{"class":576},[494,2206,573],{"class":500},[494,2208,582],{"class":500},[494,2210,522],{"class":500},[494,2212,1702],{"class":576},[494,2214,573],{"class":500},[494,2216,1625],{"class":500},[494,2218,2219],{"class":496,"line":659},[494,2220,2221],{"class":500},"            },\n",[494,2223,2224,2227,2229,2232,2234,2237,2239,2242,2244,2246,2248,2251],{"class":496,"line":690},[494,2225,2226],{"class":555},"            template",[494,2228,565],{"class":500},[494,2230,2231],{"class":542},"ColumnWidths",[494,2233,207],{"class":500},[494,2235,2236],{"class":653},"50",[494,2238,582],{"class":500},[494,2240,2241],{"class":653}," 15",[494,2243,582],{"class":500},[494,2245,2241],{"class":653},[494,2247,582],{"class":500},[494,2249,2250],{"class":653}," 20",[494,2252,852],{"class":500},[494,2254,2255,2257,2259,2262],{"class":496,"line":711},[494,2256,2226],{"class":555},[494,2258,565],{"class":500},[494,2260,2261],{"class":542},"TableHeaderStyle",[494,2263,829],{"class":500},[494,2265,2266,2269,2271,2273],{"class":496,"line":802},[494,2267,2268],{"class":555},"                template",[494,2270,565],{"class":500},[494,2272,1030],{"class":542},[494,2274,2275],{"class":500},"(),\n",[494,2277,2278,2280,2282,2285,2287,2289,2291,2294],{"class":496,"line":813},[494,2279,2268],{"class":555},[494,2281,565],{"class":500},[494,2283,2284],{"class":542},"TextColor",[494,2286,207],{"class":500},[494,2288,1235],{"class":555},[494,2290,565],{"class":500},[494,2292,2293],{"class":555},"White",[494,2295,852],{"class":500},[494,2297,2298,2300,2302,2305,2307,2309,2311,2314,2316,2319],{"class":496,"line":832},[494,2299,2268],{"class":555},[494,2301,565],{"class":500},[494,2303,2304],{"class":542},"BgColor",[494,2306,207],{"class":500},[494,2308,1235],{"class":555},[494,2310,565],{"class":500},[494,2312,2313],{"class":542},"RGBHex",[494,2315,207],{"class":500},[494,2317,2318],{"class":653},"0x1A237E",[494,2320,2321],{"class":500},")),\n",[494,2323,2324],{"class":496,"line":855},[494,2325,2326],{"class":500},"            ),\n",[494,2328,2329,2331,2333,2336,2338,2340,2342,2344,2346,2349],{"class":496,"line":891},[494,2330,2226],{"class":555},[494,2332,565],{"class":500},[494,2334,2335],{"class":542},"TableStripe",[494,2337,207],{"class":500},[494,2339,1235],{"class":555},[494,2341,565],{"class":500},[494,2343,2313],{"class":542},[494,2345,207],{"class":500},[494,2347,2348],{"class":653},"0xF5F5F5",[494,2350,2321],{"class":500},[494,2352,2353],{"class":496,"line":897},[494,2354,2355],{"class":500},"        )\n",[494,2357,2358],{"class":496,"line":902},[494,2359,1045],{"class":500},[494,2361,2362],{"class":496,"line":919},[494,2363,2364],{"class":500},"})\n",[18,2366,2367,2370,2371,2374,2375,2378,2379,2381],{},[26,2368,2369],{},"ColumnWidths(50, 15, 15, 20)"," の数字は ",[21,2372,2373],{},"絶対 mm ではなく、表が乗っている列の中での割合","。同じ表を ",[26,2376,2377],{},"r.Col(6, ...)"," の中に入れても、この割合のままうまく収まる。",[26,2380,1296],{}," をラップしないと届かなかった抽象。",[18,2383,2384],{},"折り返しは自動。改ページも自動 — 表が下マージンを越えたら、次のページにヘッダ行が再描画される。",[13,2386,2388],{"id":2387},"before-after-3-お作法なしで日本語を書く","Before / After 3: お作法なしで日本語を書く",[18,2390,2391,2392,2394],{},"gofpdf を捨てる決め手はここだった。gofpdf で日本語を出すには ",[26,2393,28],{}," を呼び、ディスク上の TTF を指し、フォントをセットして、祈る。サブセット化はだいたい動く。一部の TTF はグリッド ID 衝突を起こして文字化けを吐く。エラーメッセージは何の役にも立たない。",[18,2396,2397],{},[21,2398,483],{},[485,2400,2402],{"className":487,"code":2401,"language":489,"meta":490,"style":490},"pdf := gofpdf.New(\"P\", \"mm\", \"A4\", \"\")\npdf.AddUTF8Font(\"notosansjp\", \"\", \"NotoSansJP-Regular.ttf\")\npdf.AddPage()\npdf.SetFont(\"notosansjp\", \"\", 14)\npdf.Cell(0, 10, \"こんにちは、世界。\")\npdf.OutputFileAndClose(\"ja.pdf\")\n",[26,2403,2404,2447,2479,2489,2516,2543],{"__ignoreMap":490},[494,2405,2406,2409,2411,2413,2415,2417,2419,2421,2423,2425,2427,2429,2431,2433,2435,2437,2439,2441,2443,2445],{"class":496,"line":497},[494,2407,2408],{"class":555},"pdf ",[494,2410,559],{"class":500},[494,2412,562],{"class":555},[494,2414,565],{"class":500},[494,2416,568],{"class":542},[494,2418,207],{"class":500},[494,2420,573],{"class":500},[494,2422,577],{"class":576},[494,2424,573],{"class":500},[494,2426,582],{"class":500},[494,2428,522],{"class":500},[494,2430,587],{"class":576},[494,2432,573],{"class":500},[494,2434,582],{"class":500},[494,2436,522],{"class":500},[494,2438,596],{"class":576},[494,2440,573],{"class":500},[494,2442,582],{"class":500},[494,2444,603],{"class":500},[494,2446,606],{"class":500},[494,2448,2449,2451,2453,2455,2457,2459,2462,2464,2466,2468,2470,2472,2475,2477],{"class":496,"line":508},[494,2450,1235],{"class":555},[494,2452,565],{"class":500},[494,2454,28],{"class":542},[494,2456,207],{"class":500},[494,2458,573],{"class":500},[494,2460,2461],{"class":576},"notosansjp",[494,2463,573],{"class":500},[494,2465,582],{"class":500},[494,2467,603],{"class":500},[494,2469,582],{"class":500},[494,2471,522],{"class":500},[494,2473,2474],{"class":576},"NotoSansJP-Regular.ttf",[494,2476,573],{"class":500},[494,2478,606],{"class":500},[494,2480,2481,2483,2485,2487],{"class":496,"line":515},[494,2482,1235],{"class":555},[494,2484,565],{"class":500},[494,2486,617],{"class":542},[494,2488,620],{"class":500},[494,2490,2491,2493,2495,2497,2499,2501,2503,2505,2507,2509,2511,2514],{"class":496,"line":531},[494,2492,1235],{"class":555},[494,2494,565],{"class":500},[494,2496,630],{"class":542},[494,2498,207],{"class":500},[494,2500,573],{"class":500},[494,2502,2461],{"class":576},[494,2504,573],{"class":500},[494,2506,582],{"class":500},[494,2508,603],{"class":500},[494,2510,582],{"class":500},[494,2512,2513],{"class":653}," 14",[494,2515,606],{"class":500},[494,2517,2518,2520,2522,2524,2526,2528,2530,2532,2534,2536,2539,2541],{"class":496,"line":536},[494,2519,1235],{"class":555},[494,2521,565],{"class":500},[494,2523,666],{"class":542},[494,2525,207],{"class":500},[494,2527,1760],{"class":653},[494,2529,582],{"class":500},[494,2531,676],{"class":653},[494,2533,582],{"class":500},[494,2535,522],{"class":500},[494,2537,2538],{"class":576},"こんにちは、世界。",[494,2540,573],{"class":500},[494,2542,606],{"class":500},[494,2544,2545,2547,2549,2551,2553,2555,2558,2560],{"class":496,"line":552},[494,2546,1235],{"class":555},[494,2548,565],{"class":500},[494,2550,697],{"class":542},[494,2552,207],{"class":500},[494,2554,573],{"class":500},[494,2556,2557],{"class":576},"ja.pdf",[494,2559,573],{"class":500},[494,2561,606],{"class":500},[18,2563,2564,2565,2568,2569,2571,2572,2574],{},"地雷が 2 つある。TTF が ",[21,2566,2567],{},"実行時に"," 指定パスに存在している必要があり、Docker イメージにフォントを同梱する手間が発生する。",[26,2570,666],{}," の幅を ",[26,2573,1760],{}," にすると「右マージンまで」になるが、CJK では幅推定が全角を正しく数えず、はみ出してクリップされることがある。",[18,2576,2577],{},[21,2578,719],{},[485,2580,2582],{"className":487,"code":2581,"language":489,"meta":490,"style":490},"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/template\"\n)\n\nfunc main() {\n    fontData, err := os.ReadFile(\"NotoSansJP-Regular.ttf\")\n    if err != nil {\n        log.Fatal(err)\n    }\n\n    doc := gpdf.NewDocument(\n        gpdf.WithPageSize(document.A4),\n        gpdf.WithMargins(document.UniformEdges(document.Mm(20))),\n        gpdf.WithFont(\"NotoSansJP\", fontData),\n        gpdf.WithDefaultFont(\"NotoSansJP\", 14),\n    )\n\n    page := doc.AddPage()\n    page.AutoRow(func(r *template.RowBuilder) {\n        r.Col(12, func(c *template.ColBuilder) {\n            c.Text(\"こんにちは、世界。\")\n            c.Text(\"吾輩は猫である。名前はまだ無い。\")\n            c.Text(\"東京都渋谷区神宮前1-2-3\")\n        })\n    })\n\n    data, _ := doc.Generate()\n    os.WriteFile(\"ja.pdf\", data, 0o644)\n}\n",[26,2583,2584,2590,2594,2600,2608,2616,2620,2628,2636,2644,2648,2652,2662,2690,2702,2716,2720,2724,2738,2756,2786,2811,2834,2838,2842,2856,2880,2910,2928,2947,2966,2970,2974,2979,2999,3027],{"__ignoreMap":490},[494,2585,2586,2588],{"class":496,"line":497},[494,2587,501],{"class":500},[494,2589,505],{"class":504},[494,2591,2592],{"class":496,"line":508},[494,2593,512],{"emptyLinePlaceholder":511},[494,2595,2596,2598],{"class":496,"line":515},[494,2597,519],{"class":518},[494,2599,741],{"class":500},[494,2601,2602,2604,2606],{"class":496,"line":531},[494,2603,746],{"class":500},[494,2605,749],{"class":504},[494,2607,528],{"class":500},[494,2609,2610,2612,2614],{"class":496,"line":536},[494,2611,746],{"class":500},[494,2613,758],{"class":504},[494,2615,528],{"class":500},[494,2617,2618],{"class":496,"line":552},[494,2619,512],{"emptyLinePlaceholder":511},[494,2621,2622,2624,2626],{"class":496,"line":609},[494,2623,746],{"class":500},[494,2625,771],{"class":504},[494,2627,528],{"class":500},[494,2629,2630,2632,2634],{"class":496,"line":623},[494,2631,746],{"class":500},[494,2633,780],{"class":504},[494,2635,528],{"class":500},[494,2637,2638,2640,2642],{"class":496,"line":659},[494,2639,746],{"class":500},[494,2641,789],{"class":504},[494,2643,528],{"class":500},[494,2645,2646],{"class":496,"line":690},[494,2647,606],{"class":500},[494,2649,2650],{"class":496,"line":711},[494,2651,512],{"emptyLinePlaceholder":511},[494,2653,2654,2656,2658,2660],{"class":496,"line":802},[494,2655,539],{"class":500},[494,2657,543],{"class":542},[494,2659,546],{"class":500},[494,2661,549],{"class":500},[494,2663,2664,2667,2669,2671,2673,2675,2677,2680,2682,2684,2686,2688],{"class":496,"line":813},[494,2665,2666],{"class":555},"    fontData",[494,2668,582],{"class":500},[494,2670,1061],{"class":555},[494,2672,559],{"class":500},[494,2674,1124],{"class":555},[494,2676,565],{"class":500},[494,2678,2679],{"class":542},"ReadFile",[494,2681,207],{"class":500},[494,2683,573],{"class":500},[494,2685,2474],{"class":576},[494,2687,573],{"class":500},[494,2689,606],{"class":500},[494,2691,2692,2694,2696,2698,2700],{"class":496,"line":832},[494,2693,1078],{"class":518},[494,2695,1061],{"class":555},[494,2697,1083],{"class":500},[494,2699,1086],{"class":500},[494,2701,549],{"class":500},[494,2703,2704,2706,2708,2710,2712,2714],{"class":496,"line":855},[494,2705,1094],{"class":555},[494,2707,565],{"class":500},[494,2709,1099],{"class":542},[494,2711,207],{"class":500},[494,2713,1104],{"class":555},[494,2715,606],{"class":500},[494,2717,2718],{"class":496,"line":891},[494,2719,1112],{"class":500},[494,2721,2722],{"class":496,"line":897},[494,2723,512],{"emptyLinePlaceholder":511},[494,2725,2726,2728,2730,2732,2734,2736],{"class":496,"line":902},[494,2727,816],{"class":555},[494,2729,559],{"class":500},[494,2731,821],{"class":555},[494,2733,565],{"class":500},[494,2735,826],{"class":542},[494,2737,829],{"class":500},[494,2739,2740,2742,2744,2746,2748,2750,2752,2754],{"class":496,"line":919},[494,2741,835],{"class":555},[494,2743,565],{"class":500},[494,2745,840],{"class":542},[494,2747,207],{"class":500},[494,2749,845],{"class":555},[494,2751,565],{"class":500},[494,2753,596],{"class":555},[494,2755,852],{"class":500},[494,2757,2758,2760,2762,2764,2766,2768,2770,2772,2774,2776,2778,2780,2782,2784],{"class":496,"line":952},[494,2759,835],{"class":555},[494,2761,565],{"class":500},[494,2763,862],{"class":542},[494,2765,207],{"class":500},[494,2767,845],{"class":555},[494,2769,565],{"class":500},[494,2771,871],{"class":542},[494,2773,207],{"class":500},[494,2775,845],{"class":555},[494,2777,565],{"class":500},[494,2779,880],{"class":542},[494,2781,207],{"class":500},[494,2783,885],{"class":653},[494,2785,888],{"class":500},[494,2787,2788,2790,2792,2795,2797,2799,2802,2804,2806,2809],{"class":496,"line":989},[494,2789,835],{"class":555},[494,2791,565],{"class":500},[494,2793,2794],{"class":542},"WithFont",[494,2796,207],{"class":500},[494,2798,573],{"class":500},[494,2800,2801],{"class":576},"NotoSansJP",[494,2803,573],{"class":500},[494,2805,582],{"class":500},[494,2807,2808],{"class":555}," fontData",[494,2810,852],{"class":500},[494,2812,2813,2815,2817,2820,2822,2824,2826,2828,2830,2832],{"class":496,"line":1036},[494,2814,835],{"class":555},[494,2816,565],{"class":500},[494,2818,2819],{"class":542},"WithDefaultFont",[494,2821,207],{"class":500},[494,2823,573],{"class":500},[494,2825,2801],{"class":576},[494,2827,573],{"class":500},[494,2829,582],{"class":500},[494,2831,2513],{"class":653},[494,2833,852],{"class":500},[494,2835,2836],{"class":496,"line":1042},[494,2837,894],{"class":500},[494,2839,2840],{"class":496,"line":1048},[494,2841,512],{"emptyLinePlaceholder":511},[494,2843,2844,2846,2848,2850,2852,2854],{"class":496,"line":1053},[494,2845,905],{"class":555},[494,2847,559],{"class":500},[494,2849,910],{"class":555},[494,2851,565],{"class":500},[494,2853,617],{"class":542},[494,2855,620],{"class":500},[494,2857,2858,2860,2862,2864,2866,2868,2870,2872,2874,2876,2878],{"class":496,"line":1075},[494,2859,922],{"class":555},[494,2861,565],{"class":500},[494,2863,927],{"class":542},[494,2865,930],{"class":500},[494,2867,934],{"class":933},[494,2869,937],{"class":500},[494,2871,940],{"class":504},[494,2873,565],{"class":500},[494,2875,945],{"class":504},[494,2877,351],{"class":500},[494,2879,549],{"class":500},[494,2881,2882,2884,2886,2888,2890,2892,2894,2896,2898,2900,2902,2904,2906,2908],{"class":496,"line":1091},[494,2883,955],{"class":555},[494,2885,565],{"class":500},[494,2887,960],{"class":542},[494,2889,207],{"class":500},[494,2891,965],{"class":653},[494,2893,582],{"class":500},[494,2895,970],{"class":500},[494,2897,973],{"class":933},[494,2899,937],{"class":500},[494,2901,940],{"class":504},[494,2903,565],{"class":500},[494,2905,982],{"class":504},[494,2907,351],{"class":500},[494,2909,549],{"class":500},[494,2911,2912,2914,2916,2918,2920,2922,2924,2926],{"class":496,"line":1109},[494,2913,992],{"class":555},[494,2915,565],{"class":500},[494,2917,997],{"class":542},[494,2919,207],{"class":500},[494,2921,573],{"class":500},[494,2923,2538],{"class":576},[494,2925,573],{"class":500},[494,2927,606],{"class":500},[494,2929,2930,2932,2934,2936,2938,2940,2943,2945],{"class":496,"line":1115},[494,2931,992],{"class":555},[494,2933,565],{"class":500},[494,2935,997],{"class":542},[494,2937,207],{"class":500},[494,2939,573],{"class":500},[494,2941,2942],{"class":576},"吾輩は猫である。名前はまだ無い。",[494,2944,573],{"class":500},[494,2946,606],{"class":500},[494,2948,2949,2951,2953,2955,2957,2959,2962,2964],{"class":496,"line":1161},[494,2950,992],{"class":555},[494,2952,565],{"class":500},[494,2954,997],{"class":542},[494,2956,207],{"class":500},[494,2958,573],{"class":500},[494,2960,2961],{"class":576},"東京都渋谷区神宮前1-2-3",[494,2963,573],{"class":500},[494,2965,606],{"class":500},[494,2967,2968],{"class":496,"line":1176},[494,2969,1039],{"class":500},[494,2971,2972],{"class":496,"line":1181},[494,2973,1045],{"class":500},[494,2975,2977],{"class":496,"line":2976},33,[494,2978,512],{"emptyLinePlaceholder":511},[494,2980,2982,2984,2986,2989,2991,2993,2995,2997],{"class":496,"line":2981},34,[494,2983,1056],{"class":555},[494,2985,582],{"class":500},[494,2987,2988],{"class":555}," _ ",[494,2990,559],{"class":500},[494,2992,910],{"class":555},[494,2994,565],{"class":500},[494,2996,1070],{"class":542},[494,2998,620],{"class":500},[494,3000,3002,3005,3007,3009,3011,3013,3015,3017,3019,3021,3023,3025],{"class":496,"line":3001},35,[494,3003,3004],{"class":555},"    os",[494,3006,565],{"class":500},[494,3008,1129],{"class":542},[494,3010,207],{"class":500},[494,3012,573],{"class":500},[494,3014,2557],{"class":576},[494,3016,573],{"class":500},[494,3018,582],{"class":500},[494,3020,1142],{"class":555},[494,3022,582],{"class":500},[494,3024,1147],{"class":653},[494,3026,606],{"class":500},[494,3028,3030],{"class":496,"line":3029},36,[494,3031,714],{"class":500},[18,3033,3034],{},"違いは 2 つ。",[18,3036,3037,3038,99,3041,3044],{},"ひとつめ。",[21,3039,3040],{},"パスではなくバイト列を渡す",[26,3042,3043],{},"//go:embed NotoSansJP-Regular.ttf"," で TTF を埋め込めば、バイナリだけで完結する。本番で「フォントが見つからない」と言われない。Distroless でも Alpine でも動く。",[18,3046,3047],{},"ふたつめ。gpdf の TrueType サブセッタは CJK の cmap フォーマット (4, 6, 12) と Identity-H エンコーディングを理解している。出力 PDF には実際に使ったグリフだけが入る — NotoSansJP を 200 文字の請求書に使うと、約 30 KB のサブセットになる。フル埋め込みの 4 MB ではない。gofpdf で Japanese 1 ページの PDF が 5 MB になったことがある人は、まずこれに気づくはず。",[18,3049,3050],{},"IPAex ゴシック・源ノ角ゴシック・フォントフォールバックなど、もっと深い CJK 周りは別記事で扱う予定。",[13,3052,3054],{"id":3053},"before-after-4-全ページ共通ヘッダ-フッタにページ番号","Before / After 4: 全ページ共通ヘッダ + フッタにページ番号",[18,3056,3057,3058,227,3061,3064,3065,3068,3069,3071,3072,3075],{},"gofpdf の繰り返しクロムは ",[26,3059,3060],{},"SetHeaderFunc",[26,3062,3063],{},"SetFooterFunc"," で、それぞれカーソルに対して走る ",[26,3066,3067],{},"func()"," を渡す。ページ番号は ",[26,3070,391],{}," と ",[26,3073,3074],{},"pdf.AliasNbPages()"," を組み合わせる。",[18,3077,3078],{},[21,3079,483],{},[485,3081,3083],{"className":487,"code":3082,"language":489,"meta":490,"style":490},"pdf := gofpdf.New(\"P\", \"mm\", \"A4\", \"\")\npdf.SetHeaderFunc(func() {\n    pdf.SetFont(\"Arial\", \"B\", 12)\n    pdf.Cell(0, 10, \"ACME 株式会社\")\n    pdf.Ln(15)\n})\npdf.SetFooterFunc(func() {\n    pdf.SetY(-15)\n    pdf.SetFont(\"Arial\", \"I\", 8)\n    pdf.CellFormat(0, 10,\n        fmt.Sprintf(\"Page %d/{nb}\", pdf.PageNo()),\n        \"\", 0, \"C\", false, 0, \"\")\n})\npdf.AliasNbPages(\"\")\npdf.AddPage()\n// ... 本文 ...\n",[26,3084,3085,3127,3140,3171,3198,3214,3218,3230,3246,3277,3296,3335,3366,3370,3386,3396],{"__ignoreMap":490},[494,3086,3087,3089,3091,3093,3095,3097,3099,3101,3103,3105,3107,3109,3111,3113,3115,3117,3119,3121,3123,3125],{"class":496,"line":497},[494,3088,2408],{"class":555},[494,3090,559],{"class":500},[494,3092,562],{"class":555},[494,3094,565],{"class":500},[494,3096,568],{"class":542},[494,3098,207],{"class":500},[494,3100,573],{"class":500},[494,3102,577],{"class":576},[494,3104,573],{"class":500},[494,3106,582],{"class":500},[494,3108,522],{"class":500},[494,3110,587],{"class":576},[494,3112,573],{"class":500},[494,3114,582],{"class":500},[494,3116,522],{"class":500},[494,3118,596],{"class":576},[494,3120,573],{"class":500},[494,3122,582],{"class":500},[494,3124,603],{"class":500},[494,3126,606],{"class":500},[494,3128,3129,3131,3133,3135,3138],{"class":496,"line":508},[494,3130,1235],{"class":555},[494,3132,565],{"class":500},[494,3134,3060],{"class":542},[494,3136,3137],{"class":500},"(func()",[494,3139,549],{"class":500},[494,3141,3142,3144,3146,3148,3150,3152,3154,3156,3158,3160,3162,3164,3166,3169],{"class":496,"line":515},[494,3143,612],{"class":555},[494,3145,565],{"class":500},[494,3147,630],{"class":542},[494,3149,207],{"class":500},[494,3151,573],{"class":500},[494,3153,637],{"class":576},[494,3155,573],{"class":500},[494,3157,582],{"class":500},[494,3159,522],{"class":500},[494,3161,646],{"class":576},[494,3163,573],{"class":500},[494,3165,582],{"class":500},[494,3167,3168],{"class":653}," 12",[494,3170,606],{"class":500},[494,3172,3173,3175,3177,3179,3181,3183,3185,3187,3189,3191,3194,3196],{"class":496,"line":531},[494,3174,612],{"class":555},[494,3176,565],{"class":500},[494,3178,666],{"class":542},[494,3180,207],{"class":500},[494,3182,1760],{"class":653},[494,3184,582],{"class":500},[494,3186,676],{"class":653},[494,3188,582],{"class":500},[494,3190,522],{"class":500},[494,3192,3193],{"class":576},"ACME 株式会社",[494,3195,573],{"class":500},[494,3197,606],{"class":500},[494,3199,3200,3202,3204,3207,3209,3212],{"class":496,"line":536},[494,3201,612],{"class":555},[494,3203,565],{"class":500},[494,3205,3206],{"class":542},"Ln",[494,3208,207],{"class":500},[494,3210,3211],{"class":653},"15",[494,3213,606],{"class":500},[494,3215,3216],{"class":496,"line":552},[494,3217,2364],{"class":500},[494,3219,3220,3222,3224,3226,3228],{"class":496,"line":609},[494,3221,1235],{"class":555},[494,3223,565],{"class":500},[494,3225,3063],{"class":542},[494,3227,3137],{"class":500},[494,3229,549],{"class":500},[494,3231,3232,3234,3236,3239,3242,3244],{"class":496,"line":623},[494,3233,612],{"class":555},[494,3235,565],{"class":500},[494,3237,3238],{"class":542},"SetY",[494,3240,3241],{"class":500},"(-",[494,3243,3211],{"class":653},[494,3245,606],{"class":500},[494,3247,3248,3250,3252,3254,3256,3258,3260,3262,3264,3266,3269,3271,3273,3275],{"class":496,"line":659},[494,3249,612],{"class":555},[494,3251,565],{"class":500},[494,3253,630],{"class":542},[494,3255,207],{"class":500},[494,3257,573],{"class":500},[494,3259,637],{"class":576},[494,3261,573],{"class":500},[494,3263,582],{"class":500},[494,3265,522],{"class":500},[494,3267,3268],{"class":576},"I",[494,3270,573],{"class":500},[494,3272,582],{"class":500},[494,3274,1306],{"class":653},[494,3276,606],{"class":500},[494,3278,3279,3281,3283,3285,3287,3289,3291,3293],{"class":496,"line":690},[494,3280,612],{"class":555},[494,3282,565],{"class":500},[494,3284,1296],{"class":542},[494,3286,207],{"class":500},[494,3288,1760],{"class":653},[494,3290,582],{"class":500},[494,3292,676],{"class":653},[494,3294,3295],{"class":500},",\n",[494,3297,3298,3301,3303,3306,3308,3310,3313,3317,3320,3322,3324,3327,3329,3332],{"class":496,"line":711},[494,3299,3300],{"class":555},"        fmt",[494,3302,565],{"class":500},[494,3304,3305],{"class":542},"Sprintf",[494,3307,207],{"class":500},[494,3309,573],{"class":500},[494,3311,3312],{"class":576},"Page ",[494,3314,3316],{"class":3315},"swJcz","%d",[494,3318,3319],{"class":576},"/{nb}",[494,3321,573],{"class":500},[494,3323,582],{"class":500},[494,3325,3326],{"class":555}," pdf",[494,3328,565],{"class":500},[494,3330,3331],{"class":542},"PageNo",[494,3333,3334],{"class":500},"()),\n",[494,3336,3337,3340,3342,3344,3346,3348,3350,3352,3354,3356,3358,3360,3362,3364],{"class":496,"line":802},[494,3338,3339],{"class":500},"        \"\"",[494,3341,582],{"class":500},[494,3343,1330],{"class":653},[494,3345,582],{"class":500},[494,3347,522],{"class":500},[494,3349,1399],{"class":576},[494,3351,573],{"class":500},[494,3353,582],{"class":500},[494,3355,1786],{"class":1344},[494,3357,582],{"class":500},[494,3359,1330],{"class":653},[494,3361,582],{"class":500},[494,3363,603],{"class":500},[494,3365,606],{"class":500},[494,3367,3368],{"class":496,"line":813},[494,3369,2364],{"class":500},[494,3371,3372,3374,3376,3379,3381,3384],{"class":496,"line":832},[494,3373,1235],{"class":555},[494,3375,565],{"class":500},[494,3377,3378],{"class":542},"AliasNbPages",[494,3380,207],{"class":500},[494,3382,3383],{"class":500},"\"\"",[494,3385,606],{"class":500},[494,3387,3388,3390,3392,3394],{"class":496,"line":855},[494,3389,1235],{"class":555},[494,3391,565],{"class":500},[494,3393,617],{"class":542},[494,3395,620],{"class":500},[494,3397,3398],{"class":496,"line":891},[494,3399,3401],{"class":3400},"sHwdD","// ... 本文 ...\n",[18,3403,3404,3407],{},[26,3405,3406],{},"{nb}"," は gofpdf が出力時に総ページ数で書き換えるセンチネル。動くんだけど「知っているかどうか」の世界。",[18,3409,3410],{},[21,3411,719],{},[485,3413,3415],{"className":487,"code":3414,"language":489,"meta":490,"style":490},"doc := gpdf.NewDocument(\n    gpdf.WithPageSize(document.A4),\n    gpdf.WithMargins(document.UniformEdges(document.Mm(20))),\n)\n\ndoc.Header(func(p *template.PageBuilder) {\n    p.AutoRow(func(r *template.RowBuilder) {\n        r.Col(12, func(c *template.ColBuilder) {\n            c.Text(\"ACME 株式会社\", template.Bold(), template.FontSize(12))\n            c.Line(template.LineColor(pdf.Gray(0.7)))\n            c.Spacer(document.Mm(4))\n        })\n    })\n})\n\ndoc.Footer(func(p *template.PageBuilder) {\n    p.AutoRow(func(r *template.RowBuilder) {\n        r.Col(6, func(c *template.ColBuilder) {\n            c.Text(\"ACME 株式会社\",\n                template.FontSize(8), template.TextColor(pdf.Gray(0.5)))\n        })\n        r.Col(6, func(c *template.ColBuilder) {\n            // \"ページ X / Y\" — どちらもプレースホルダで、\n            // ページネーション完了後にレイアウトエンジンが解決する。\n            c.PageNumber(template.AlignRight(),\n                template.FontSize(8), template.TextColor(pdf.Gray(0.5)))\n        })\n    })\n})\n\nfor i := 0; i \u003C 10; i++ {\n    page := doc.AddPage()\n    page.AutoRow(func(r *template.RowBuilder) {\n        r.Col(12, func(c *template.ColBuilder) {\n            c.Text(fmt.Sprintf(\"ページ %d の本文。\", i+1))\n        })\n    })\n}\n",[26,3416,3417,3432,3451,3481,3485,3489,3516,3541,3571,3611,3646,3670,3674,3678,3682,3686,3711,3735,3766,3784,3820,3824,3854,3859,3864,3884,3918,3922,3926,3930,3934,3965,3979,4003,4033,4075,4079,4084],{"__ignoreMap":490},[494,3418,3419,3422,3424,3426,3428,3430],{"class":496,"line":497},[494,3420,3421],{"class":555},"doc ",[494,3423,559],{"class":500},[494,3425,821],{"class":555},[494,3427,565],{"class":500},[494,3429,826],{"class":542},[494,3431,829],{"class":500},[494,3433,3434,3437,3439,3441,3443,3445,3447,3449],{"class":496,"line":508},[494,3435,3436],{"class":555},"    gpdf",[494,3438,565],{"class":500},[494,3440,840],{"class":542},[494,3442,207],{"class":500},[494,3444,845],{"class":555},[494,3446,565],{"class":500},[494,3448,596],{"class":555},[494,3450,852],{"class":500},[494,3452,3453,3455,3457,3459,3461,3463,3465,3467,3469,3471,3473,3475,3477,3479],{"class":496,"line":515},[494,3454,3436],{"class":555},[494,3456,565],{"class":500},[494,3458,862],{"class":542},[494,3460,207],{"class":500},[494,3462,845],{"class":555},[494,3464,565],{"class":500},[494,3466,871],{"class":542},[494,3468,207],{"class":500},[494,3470,845],{"class":555},[494,3472,565],{"class":500},[494,3474,880],{"class":542},[494,3476,207],{"class":500},[494,3478,885],{"class":653},[494,3480,888],{"class":500},[494,3482,3483],{"class":496,"line":531},[494,3484,606],{"class":500},[494,3486,3487],{"class":496,"line":536},[494,3488,512],{"emptyLinePlaceholder":511},[494,3490,3491,3494,3496,3499,3501,3503,3505,3507,3509,3512,3514],{"class":496,"line":552},[494,3492,3493],{"class":555},"doc",[494,3495,565],{"class":500},[494,3497,3498],{"class":542},"Header",[494,3500,930],{"class":500},[494,3502,18],{"class":933},[494,3504,937],{"class":500},[494,3506,940],{"class":504},[494,3508,565],{"class":500},[494,3510,3511],{"class":504},"PageBuilder",[494,3513,351],{"class":500},[494,3515,549],{"class":500},[494,3517,3518,3521,3523,3525,3527,3529,3531,3533,3535,3537,3539],{"class":496,"line":609},[494,3519,3520],{"class":555},"    p",[494,3522,565],{"class":500},[494,3524,927],{"class":542},[494,3526,930],{"class":500},[494,3528,934],{"class":933},[494,3530,937],{"class":500},[494,3532,940],{"class":504},[494,3534,565],{"class":500},[494,3536,945],{"class":504},[494,3538,351],{"class":500},[494,3540,549],{"class":500},[494,3542,3543,3545,3547,3549,3551,3553,3555,3557,3559,3561,3563,3565,3567,3569],{"class":496,"line":623},[494,3544,955],{"class":555},[494,3546,565],{"class":500},[494,3548,960],{"class":542},[494,3550,207],{"class":500},[494,3552,965],{"class":653},[494,3554,582],{"class":500},[494,3556,970],{"class":500},[494,3558,973],{"class":933},[494,3560,937],{"class":500},[494,3562,940],{"class":504},[494,3564,565],{"class":500},[494,3566,982],{"class":504},[494,3568,351],{"class":500},[494,3570,549],{"class":500},[494,3572,3573,3575,3577,3579,3581,3583,3585,3587,3589,3591,3593,3595,3598,3600,3602,3604,3606,3608],{"class":496,"line":659},[494,3574,992],{"class":555},[494,3576,565],{"class":500},[494,3578,997],{"class":542},[494,3580,207],{"class":500},[494,3582,573],{"class":500},[494,3584,3193],{"class":576},[494,3586,573],{"class":500},[494,3588,582],{"class":500},[494,3590,1010],{"class":555},[494,3592,565],{"class":500},[494,3594,1030],{"class":542},[494,3596,3597],{"class":500},"(),",[494,3599,1010],{"class":555},[494,3601,565],{"class":500},[494,3603,1015],{"class":542},[494,3605,207],{"class":500},[494,3607,965],{"class":653},[494,3609,3610],{"class":500},"))\n",[494,3612,3613,3615,3617,3620,3622,3624,3626,3629,3631,3633,3635,3638,3640,3643],{"class":496,"line":690},[494,3614,992],{"class":555},[494,3616,565],{"class":500},[494,3618,3619],{"class":542},"Line",[494,3621,207],{"class":500},[494,3623,940],{"class":555},[494,3625,565],{"class":500},[494,3627,3628],{"class":542},"LineColor",[494,3630,207],{"class":500},[494,3632,1235],{"class":555},[494,3634,565],{"class":500},[494,3636,3637],{"class":542},"Gray",[494,3639,207],{"class":500},[494,3641,3642],{"class":653},"0.7",[494,3644,3645],{"class":500},")))\n",[494,3647,3648,3650,3652,3655,3657,3659,3661,3663,3665,3668],{"class":496,"line":711},[494,3649,992],{"class":555},[494,3651,565],{"class":500},[494,3653,3654],{"class":542},"Spacer",[494,3656,207],{"class":500},[494,3658,845],{"class":555},[494,3660,565],{"class":500},[494,3662,880],{"class":542},[494,3664,207],{"class":500},[494,3666,3667],{"class":653},"4",[494,3669,3610],{"class":500},[494,3671,3672],{"class":496,"line":802},[494,3673,1039],{"class":500},[494,3675,3676],{"class":496,"line":813},[494,3677,1045],{"class":500},[494,3679,3680],{"class":496,"line":832},[494,3681,2364],{"class":500},[494,3683,3684],{"class":496,"line":855},[494,3685,512],{"emptyLinePlaceholder":511},[494,3687,3688,3690,3692,3695,3697,3699,3701,3703,3705,3707,3709],{"class":496,"line":891},[494,3689,3493],{"class":555},[494,3691,565],{"class":500},[494,3693,3694],{"class":542},"Footer",[494,3696,930],{"class":500},[494,3698,18],{"class":933},[494,3700,937],{"class":500},[494,3702,940],{"class":504},[494,3704,565],{"class":500},[494,3706,3511],{"class":504},[494,3708,351],{"class":500},[494,3710,549],{"class":500},[494,3712,3713,3715,3717,3719,3721,3723,3725,3727,3729,3731,3733],{"class":496,"line":897},[494,3714,3520],{"class":555},[494,3716,565],{"class":500},[494,3718,927],{"class":542},[494,3720,930],{"class":500},[494,3722,934],{"class":933},[494,3724,937],{"class":500},[494,3726,940],{"class":504},[494,3728,565],{"class":500},[494,3730,945],{"class":504},[494,3732,351],{"class":500},[494,3734,549],{"class":500},[494,3736,3737,3739,3741,3743,3745,3748,3750,3752,3754,3756,3758,3760,3762,3764],{"class":496,"line":902},[494,3738,955],{"class":555},[494,3740,565],{"class":500},[494,3742,960],{"class":542},[494,3744,207],{"class":500},[494,3746,3747],{"class":653},"6",[494,3749,582],{"class":500},[494,3751,970],{"class":500},[494,3753,973],{"class":933},[494,3755,937],{"class":500},[494,3757,940],{"class":504},[494,3759,565],{"class":500},[494,3761,982],{"class":504},[494,3763,351],{"class":500},[494,3765,549],{"class":500},[494,3767,3768,3770,3772,3774,3776,3778,3780,3782],{"class":496,"line":919},[494,3769,992],{"class":555},[494,3771,565],{"class":500},[494,3773,997],{"class":542},[494,3775,207],{"class":500},[494,3777,573],{"class":500},[494,3779,3193],{"class":576},[494,3781,573],{"class":500},[494,3783,3295],{"class":500},[494,3785,3786,3788,3790,3792,3794,3797,3799,3801,3803,3805,3807,3809,3811,3813,3815,3818],{"class":496,"line":952},[494,3787,2268],{"class":555},[494,3789,565],{"class":500},[494,3791,1015],{"class":542},[494,3793,207],{"class":500},[494,3795,3796],{"class":653},"8",[494,3798,1023],{"class":500},[494,3800,1010],{"class":555},[494,3802,565],{"class":500},[494,3804,2284],{"class":542},[494,3806,207],{"class":500},[494,3808,1235],{"class":555},[494,3810,565],{"class":500},[494,3812,3637],{"class":542},[494,3814,207],{"class":500},[494,3816,3817],{"class":653},"0.5",[494,3819,3645],{"class":500},[494,3821,3822],{"class":496,"line":989},[494,3823,1039],{"class":500},[494,3825,3826,3828,3830,3832,3834,3836,3838,3840,3842,3844,3846,3848,3850,3852],{"class":496,"line":1036},[494,3827,955],{"class":555},[494,3829,565],{"class":500},[494,3831,960],{"class":542},[494,3833,207],{"class":500},[494,3835,3747],{"class":653},[494,3837,582],{"class":500},[494,3839,970],{"class":500},[494,3841,973],{"class":933},[494,3843,937],{"class":500},[494,3845,940],{"class":504},[494,3847,565],{"class":500},[494,3849,982],{"class":504},[494,3851,351],{"class":500},[494,3853,549],{"class":500},[494,3855,3856],{"class":496,"line":1042},[494,3857,3858],{"class":3400},"            // \"ページ X / Y\" — どちらもプレースホルダで、\n",[494,3860,3861],{"class":496,"line":1048},[494,3862,3863],{"class":3400},"            // ページネーション完了後にレイアウトエンジンが解決する。\n",[494,3865,3866,3868,3870,3873,3875,3877,3879,3882],{"class":496,"line":1053},[494,3867,992],{"class":555},[494,3869,565],{"class":500},[494,3871,3872],{"class":542},"PageNumber",[494,3874,207],{"class":500},[494,3876,940],{"class":555},[494,3878,565],{"class":500},[494,3880,3881],{"class":542},"AlignRight",[494,3883,2275],{"class":500},[494,3885,3886,3888,3890,3892,3894,3896,3898,3900,3902,3904,3906,3908,3910,3912,3914,3916],{"class":496,"line":1075},[494,3887,2268],{"class":555},[494,3889,565],{"class":500},[494,3891,1015],{"class":542},[494,3893,207],{"class":500},[494,3895,3796],{"class":653},[494,3897,1023],{"class":500},[494,3899,1010],{"class":555},[494,3901,565],{"class":500},[494,3903,2284],{"class":542},[494,3905,207],{"class":500},[494,3907,1235],{"class":555},[494,3909,565],{"class":500},[494,3911,3637],{"class":542},[494,3913,207],{"class":500},[494,3915,3817],{"class":653},[494,3917,3645],{"class":500},[494,3919,3920],{"class":496,"line":1091},[494,3921,1039],{"class":500},[494,3923,3924],{"class":496,"line":1109},[494,3925,1045],{"class":500},[494,3927,3928],{"class":496,"line":1115},[494,3929,2364],{"class":500},[494,3931,3932],{"class":496,"line":1161},[494,3933,512],{"emptyLinePlaceholder":511},[494,3935,3936,3938,3941,3943,3945,3948,3950,3953,3955,3957,3960,3963],{"class":496,"line":1176},[494,3937,1715],{"class":518},[494,3939,3940],{"class":555}," i ",[494,3942,559],{"class":500},[494,3944,1330],{"class":653},[494,3946,3947],{"class":500},";",[494,3949,3940],{"class":555},[494,3951,3952],{"class":500},"\u003C",[494,3954,676],{"class":653},[494,3956,3947],{"class":500},[494,3958,3959],{"class":555}," i",[494,3961,3962],{"class":500},"++",[494,3964,549],{"class":500},[494,3966,3967,3969,3971,3973,3975,3977],{"class":496,"line":1181},[494,3968,905],{"class":555},[494,3970,559],{"class":500},[494,3972,910],{"class":555},[494,3974,565],{"class":500},[494,3976,617],{"class":542},[494,3978,620],{"class":500},[494,3980,3981,3983,3985,3987,3989,3991,3993,3995,3997,3999,4001],{"class":496,"line":2976},[494,3982,922],{"class":555},[494,3984,565],{"class":500},[494,3986,927],{"class":542},[494,3988,930],{"class":500},[494,3990,934],{"class":933},[494,3992,937],{"class":500},[494,3994,940],{"class":504},[494,3996,565],{"class":500},[494,3998,945],{"class":504},[494,4000,351],{"class":500},[494,4002,549],{"class":500},[494,4004,4005,4007,4009,4011,4013,4015,4017,4019,4021,4023,4025,4027,4029,4031],{"class":496,"line":2981},[494,4006,955],{"class":555},[494,4008,565],{"class":500},[494,4010,960],{"class":542},[494,4012,207],{"class":500},[494,4014,965],{"class":653},[494,4016,582],{"class":500},[494,4018,970],{"class":500},[494,4020,973],{"class":933},[494,4022,937],{"class":500},[494,4024,940],{"class":504},[494,4026,565],{"class":500},[494,4028,982],{"class":504},[494,4030,351],{"class":500},[494,4032,549],{"class":500},[494,4034,4035,4037,4039,4041,4043,4046,4048,4050,4052,4054,4057,4059,4062,4064,4066,4068,4071,4073],{"class":496,"line":3001},[494,4036,992],{"class":555},[494,4038,565],{"class":500},[494,4040,997],{"class":542},[494,4042,207],{"class":500},[494,4044,4045],{"class":555},"fmt",[494,4047,565],{"class":500},[494,4049,3305],{"class":542},[494,4051,207],{"class":500},[494,4053,573],{"class":500},[494,4055,4056],{"class":576},"ページ ",[494,4058,3316],{"class":3315},[494,4060,4061],{"class":576}," の本文。",[494,4063,573],{"class":500},[494,4065,582],{"class":500},[494,4067,3959],{"class":555},[494,4069,4070],{"class":500},"+",[494,4072,1323],{"class":653},[494,4074,3610],{"class":500},[494,4076,4077],{"class":496,"line":3029},[494,4078,1039],{"class":500},[494,4080,4082],{"class":496,"line":4081},37,[494,4083,1045],{"class":500},[494,4085,4087],{"class":496,"line":4086},38,[494,4088,714],{"class":500},[18,4090,4091,3071,4093,4096,4097,4099,4100,4103],{},[26,4092,3872],{},[26,4094,4095],{},"TotalPages"," はプレースホルダ。レイアウトエンジンがページ数を確定したあとに展開される。",[26,4098,3406],{}," センチネルも ",[26,4101,4102],{},"SetY(-15)"," でフッタを下端に打ち付ける必要もない — フッタは単なるツリーで、毎ページ自動的に空間が確保される。",[13,4105,4107],{"id":4106},"before-after-5-http-ハンドラからバイト列を返す","Before / After 5: HTTP ハンドラからバイト列を返す",[18,4109,4110,4111,4113,4114,4117,4118,4121],{},"実運用の gofpdf コードはたいていファイルではなく ",[26,4112,1202],{}," に書く — 多くは ",[26,4115,4116],{},"application/pdf"," を返す ",[26,4119,4120],{},"http.ResponseWriter","。このペアは gpdf の API が gofpdf に一番近い場所。",[18,4123,4124],{},[21,4125,483],{},[485,4127,4129],{"className":487,"code":4128,"language":489,"meta":490,"style":490},"func handler(w http.ResponseWriter, r *http.Request) {\n    pdf := gofpdf.New(\"P\", \"mm\", \"A4\", \"\")\n    pdf.AddPage()\n    pdf.SetFont(\"Arial\", \"\", 12)\n    pdf.Cell(0, 10, \"生成日時: \"+time.Now().Format(time.RFC3339))\n\n    w.Header().Set(\"Content-Type\", \"application/pdf\")\n    if err := pdf.Output(w); err != nil {\n        http.Error(w, err.Error(), 500)\n    }\n}\n",[26,4130,4131,4170,4212,4222,4248,4300,4304,4337,4366,4396,4400],{"__ignoreMap":490},[494,4132,4133,4135,4138,4140,4143,4146,4148,4151,4153,4156,4158,4161,4163,4166,4168],{"class":496,"line":497},[494,4134,539],{"class":500},[494,4136,4137],{"class":542}," handler",[494,4139,207],{"class":500},[494,4141,4142],{"class":933},"w",[494,4144,4145],{"class":504}," http",[494,4147,565],{"class":500},[494,4149,4150],{"class":504},"ResponseWriter",[494,4152,582],{"class":500},[494,4154,4155],{"class":933}," r",[494,4157,937],{"class":500},[494,4159,4160],{"class":504},"http",[494,4162,565],{"class":500},[494,4164,4165],{"class":504},"Request",[494,4167,351],{"class":500},[494,4169,549],{"class":500},[494,4171,4172,4174,4176,4178,4180,4182,4184,4186,4188,4190,4192,4194,4196,4198,4200,4202,4204,4206,4208,4210],{"class":496,"line":508},[494,4173,556],{"class":555},[494,4175,559],{"class":500},[494,4177,562],{"class":555},[494,4179,565],{"class":500},[494,4181,568],{"class":542},[494,4183,207],{"class":500},[494,4185,573],{"class":500},[494,4187,577],{"class":576},[494,4189,573],{"class":500},[494,4191,582],{"class":500},[494,4193,522],{"class":500},[494,4195,587],{"class":576},[494,4197,573],{"class":500},[494,4199,582],{"class":500},[494,4201,522],{"class":500},[494,4203,596],{"class":576},[494,4205,573],{"class":500},[494,4207,582],{"class":500},[494,4209,603],{"class":500},[494,4211,606],{"class":500},[494,4213,4214,4216,4218,4220],{"class":496,"line":515},[494,4215,612],{"class":555},[494,4217,565],{"class":500},[494,4219,617],{"class":542},[494,4221,620],{"class":500},[494,4223,4224,4226,4228,4230,4232,4234,4236,4238,4240,4242,4244,4246],{"class":496,"line":531},[494,4225,612],{"class":555},[494,4227,565],{"class":500},[494,4229,630],{"class":542},[494,4231,207],{"class":500},[494,4233,573],{"class":500},[494,4235,637],{"class":576},[494,4237,573],{"class":500},[494,4239,582],{"class":500},[494,4241,603],{"class":500},[494,4243,582],{"class":500},[494,4245,3168],{"class":653},[494,4247,606],{"class":500},[494,4249,4250,4252,4254,4256,4258,4260,4262,4264,4266,4268,4271,4273,4275,4278,4280,4283,4286,4289,4291,4293,4295,4298],{"class":496,"line":536},[494,4251,612],{"class":555},[494,4253,565],{"class":500},[494,4255,666],{"class":542},[494,4257,207],{"class":500},[494,4259,1760],{"class":653},[494,4261,582],{"class":500},[494,4263,676],{"class":653},[494,4265,582],{"class":500},[494,4267,522],{"class":500},[494,4269,4270],{"class":576},"生成日時: ",[494,4272,573],{"class":500},[494,4274,4070],{"class":500},[494,4276,4277],{"class":555},"time",[494,4279,565],{"class":500},[494,4281,4282],{"class":542},"Now",[494,4284,4285],{"class":500},"().",[494,4287,4288],{"class":542},"Format",[494,4290,207],{"class":500},[494,4292,4277],{"class":555},[494,4294,565],{"class":500},[494,4296,4297],{"class":555},"RFC3339",[494,4299,3610],{"class":500},[494,4301,4302],{"class":496,"line":552},[494,4303,512],{"emptyLinePlaceholder":511},[494,4305,4306,4309,4311,4313,4315,4318,4320,4322,4325,4327,4329,4331,4333,4335],{"class":496,"line":609},[494,4307,4308],{"class":555},"    w",[494,4310,565],{"class":500},[494,4312,3498],{"class":542},[494,4314,4285],{"class":500},[494,4316,4317],{"class":542},"Set",[494,4319,207],{"class":500},[494,4321,573],{"class":500},[494,4323,4324],{"class":576},"Content-Type",[494,4326,573],{"class":500},[494,4328,582],{"class":500},[494,4330,522],{"class":500},[494,4332,4116],{"class":576},[494,4334,573],{"class":500},[494,4336,606],{"class":500},[494,4338,4339,4341,4343,4345,4347,4349,4352,4354,4356,4358,4360,4362,4364],{"class":496,"line":623},[494,4340,1078],{"class":518},[494,4342,1061],{"class":555},[494,4344,559],{"class":500},[494,4346,3326],{"class":555},[494,4348,565],{"class":500},[494,4350,4351],{"class":542},"Output",[494,4353,207],{"class":500},[494,4355,4142],{"class":555},[494,4357,1150],{"class":500},[494,4359,1061],{"class":555},[494,4361,1083],{"class":500},[494,4363,1086],{"class":500},[494,4365,549],{"class":500},[494,4367,4368,4371,4373,4376,4378,4380,4382,4385,4387,4389,4391,4394],{"class":496,"line":659},[494,4369,4370],{"class":555},"        http",[494,4372,565],{"class":500},[494,4374,4375],{"class":542},"Error",[494,4377,207],{"class":500},[494,4379,4142],{"class":555},[494,4381,582],{"class":500},[494,4383,4384],{"class":555}," err",[494,4386,565],{"class":500},[494,4388,4375],{"class":542},[494,4390,3597],{"class":500},[494,4392,4393],{"class":653}," 500",[494,4395,606],{"class":500},[494,4397,4398],{"class":496,"line":690},[494,4399,1112],{"class":500},[494,4401,4402],{"class":496,"line":711},[494,4403,714],{"class":500},[18,4405,4406],{},[21,4407,719],{},[485,4409,4411],{"className":487,"code":4410,"language":489,"meta":490,"style":490},"func handler(w http.ResponseWriter, r *http.Request) {\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(\"生成日時: \" + time.Now().Format(time.RFC3339))\n        })\n    })\n\n    w.Header().Set(\"Content-Type\", \"application/pdf\")\n    if err := doc.Render(w); err != nil {\n        http.Error(w, err.Error(), 500)\n    }\n}\n",[26,4412,4413,4445,4459,4477,4507,4511,4515,4529,4553,4583,4623,4627,4631,4635,4665,4694,4720,4724],{"__ignoreMap":490},[494,4414,4415,4417,4419,4421,4423,4425,4427,4429,4431,4433,4435,4437,4439,4441,4443],{"class":496,"line":497},[494,4416,539],{"class":500},[494,4418,4137],{"class":542},[494,4420,207],{"class":500},[494,4422,4142],{"class":933},[494,4424,4145],{"class":504},[494,4426,565],{"class":500},[494,4428,4150],{"class":504},[494,4430,582],{"class":500},[494,4432,4155],{"class":933},[494,4434,937],{"class":500},[494,4436,4160],{"class":504},[494,4438,565],{"class":500},[494,4440,4165],{"class":504},[494,4442,351],{"class":500},[494,4444,549],{"class":500},[494,4446,4447,4449,4451,4453,4455,4457],{"class":496,"line":508},[494,4448,816],{"class":555},[494,4450,559],{"class":500},[494,4452,821],{"class":555},[494,4454,565],{"class":500},[494,4456,826],{"class":542},[494,4458,829],{"class":500},[494,4460,4461,4463,4465,4467,4469,4471,4473,4475],{"class":496,"line":515},[494,4462,835],{"class":555},[494,4464,565],{"class":500},[494,4466,840],{"class":542},[494,4468,207],{"class":500},[494,4470,845],{"class":555},[494,4472,565],{"class":500},[494,4474,596],{"class":555},[494,4476,852],{"class":500},[494,4478,4479,4481,4483,4485,4487,4489,4491,4493,4495,4497,4499,4501,4503,4505],{"class":496,"line":531},[494,4480,835],{"class":555},[494,4482,565],{"class":500},[494,4484,862],{"class":542},[494,4486,207],{"class":500},[494,4488,845],{"class":555},[494,4490,565],{"class":500},[494,4492,871],{"class":542},[494,4494,207],{"class":500},[494,4496,845],{"class":555},[494,4498,565],{"class":500},[494,4500,880],{"class":542},[494,4502,207],{"class":500},[494,4504,885],{"class":653},[494,4506,888],{"class":500},[494,4508,4509],{"class":496,"line":536},[494,4510,894],{"class":500},[494,4512,4513],{"class":496,"line":552},[494,4514,512],{"emptyLinePlaceholder":511},[494,4516,4517,4519,4521,4523,4525,4527],{"class":496,"line":609},[494,4518,905],{"class":555},[494,4520,559],{"class":500},[494,4522,910],{"class":555},[494,4524,565],{"class":500},[494,4526,617],{"class":542},[494,4528,620],{"class":500},[494,4530,4531,4533,4535,4537,4539,4541,4543,4545,4547,4549,4551],{"class":496,"line":623},[494,4532,922],{"class":555},[494,4534,565],{"class":500},[494,4536,927],{"class":542},[494,4538,930],{"class":500},[494,4540,934],{"class":933},[494,4542,937],{"class":500},[494,4544,940],{"class":504},[494,4546,565],{"class":500},[494,4548,945],{"class":504},[494,4550,351],{"class":500},[494,4552,549],{"class":500},[494,4554,4555,4557,4559,4561,4563,4565,4567,4569,4571,4573,4575,4577,4579,4581],{"class":496,"line":659},[494,4556,955],{"class":555},[494,4558,565],{"class":500},[494,4560,960],{"class":542},[494,4562,207],{"class":500},[494,4564,965],{"class":653},[494,4566,582],{"class":500},[494,4568,970],{"class":500},[494,4570,973],{"class":933},[494,4572,937],{"class":500},[494,4574,940],{"class":504},[494,4576,565],{"class":500},[494,4578,982],{"class":504},[494,4580,351],{"class":500},[494,4582,549],{"class":500},[494,4584,4585,4587,4589,4591,4593,4595,4597,4599,4602,4605,4607,4609,4611,4613,4615,4617,4619,4621],{"class":496,"line":690},[494,4586,992],{"class":555},[494,4588,565],{"class":500},[494,4590,997],{"class":542},[494,4592,207],{"class":500},[494,4594,573],{"class":500},[494,4596,4270],{"class":576},[494,4598,573],{"class":500},[494,4600,4601],{"class":500}," +",[494,4603,4604],{"class":555}," time",[494,4606,565],{"class":500},[494,4608,4282],{"class":542},[494,4610,4285],{"class":500},[494,4612,4288],{"class":542},[494,4614,207],{"class":500},[494,4616,4277],{"class":555},[494,4618,565],{"class":500},[494,4620,4297],{"class":555},[494,4622,3610],{"class":500},[494,4624,4625],{"class":496,"line":711},[494,4626,1039],{"class":500},[494,4628,4629],{"class":496,"line":802},[494,4630,1045],{"class":500},[494,4632,4633],{"class":496,"line":813},[494,4634,512],{"emptyLinePlaceholder":511},[494,4636,4637,4639,4641,4643,4645,4647,4649,4651,4653,4655,4657,4659,4661,4663],{"class":496,"line":832},[494,4638,4308],{"class":555},[494,4640,565],{"class":500},[494,4642,3498],{"class":542},[494,4644,4285],{"class":500},[494,4646,4317],{"class":542},[494,4648,207],{"class":500},[494,4650,573],{"class":500},[494,4652,4324],{"class":576},[494,4654,573],{"class":500},[494,4656,582],{"class":500},[494,4658,522],{"class":500},[494,4660,4116],{"class":576},[494,4662,573],{"class":500},[494,4664,606],{"class":500},[494,4666,4667,4669,4671,4673,4675,4677,4680,4682,4684,4686,4688,4690,4692],{"class":496,"line":855},[494,4668,1078],{"class":518},[494,4670,1061],{"class":555},[494,4672,559],{"class":500},[494,4674,910],{"class":555},[494,4676,565],{"class":500},[494,4678,4679],{"class":542},"Render",[494,4681,207],{"class":500},[494,4683,4142],{"class":555},[494,4685,1150],{"class":500},[494,4687,1061],{"class":555},[494,4689,1083],{"class":500},[494,4691,1086],{"class":500},[494,4693,549],{"class":500},[494,4695,4696,4698,4700,4702,4704,4706,4708,4710,4712,4714,4716,4718],{"class":496,"line":891},[494,4697,4370],{"class":555},[494,4699,565],{"class":500},[494,4701,4375],{"class":542},[494,4703,207],{"class":500},[494,4705,4142],{"class":555},[494,4707,582],{"class":500},[494,4709,4384],{"class":555},[494,4711,565],{"class":500},[494,4713,4375],{"class":542},[494,4715,3597],{"class":500},[494,4717,4393],{"class":653},[494,4719,606],{"class":500},[494,4721,4722],{"class":496,"line":897},[494,4723,1112],{"class":500},[494,4725,4726],{"class":496,"line":902},[494,4727,714],{"class":500},[18,4729,4730,4731,4733,4734,4737,4738,4740,4741,4744],{},"形は同じ。",[26,4732,430],{}," がそのままレスポンスに流す。",[26,4735,4736],{},"Content-Length"," を立てたいなら、先に ",[26,4739,1198],{}," でバイト列を取って ",[26,4742,4743],{},"len()"," を入れる。",[13,4746,4748],{"id":4747},"どれだけ速ければ十分か","どれだけ速ければ「十分」か",[18,4750,4751,4752,4754,4755,4758],{},"gpdf は実用ワークロードで ",[21,4753,36],{},"。下の数値は ",[26,4756,4757],{},"_benchmark/benchmark_test.go"," を Apple M1 / Go 1.25 で回したもの。",[152,4760,4761,4778],{},[155,4762,4763],{},[158,4764,4765,4768,4770,4772,4775],{},[161,4766,4767],{},"ベンチマーク",[161,4769,23],{},[161,4771,166],{},[161,4773,4774],{},"gopdf",[161,4776,4777],{},"Maroto v2",[170,4779,4780,4799,4818,4836],{},[158,4781,4782,4785,4790,4793,4796],{},[175,4783,4784],{},"単一ページ",[175,4786,4787],{},[21,4788,4789],{},"13 µs",[175,4791,4792],{},"132 µs",[175,4794,4795],{},"423 µs",[175,4797,4798],{},"237 µs",[158,4800,4801,4804,4809,4812,4815],{},[175,4802,4803],{},"4×10 表",[175,4805,4806],{},[21,4807,4808],{},"108 µs",[175,4810,4811],{},"241 µs",[175,4813,4814],{},"835 µs",[175,4816,4817],{},"8.6 ms",[158,4819,4820,4823,4828,4831,4833],{},[175,4821,4822],{},"100 ページ",[175,4824,4825],{},[21,4826,4827],{},"683 µs",[175,4829,4830],{},"11.7 ms",[175,4832,4817],{},[175,4834,4835],{},"19.8 ms",[158,4837,4838,4841,4846,4849,4852],{},[175,4839,4840],{},"複雑な CJK 請求書",[175,4842,4843],{},[21,4844,4845],{},"133 µs",[175,4847,4848],{},"254 µs",[175,4850,4851],{},"997 µs",[175,4853,4854],{},"10.4 ms",[18,4856,4857],{},"合成ベンチではない。表ベンチは 4 列 10 行の請求書明細、100 ページベンチはヘッダとページ番号付きのレポート。本番コードが実際にやる形に揃えてある。",[18,4859,4860],{},"意味のほうも軽く。13 µs/単一ページなら 1 コアで毎秒 75,000 枚、108 µs/表ありなら毎秒 9,000 枚。「PDF 生成はキャッシュすべきか? 非同期キューに逃すべきか?」を考えなくてよくなる。多くのワークロードはリクエスト同期で生成して問題ない。",[13,4862,4863],{"id":4863},"移行で諦めるもの",[18,4865,4866],{},"ガイドが現実のギャップを隠していたら意味がない。gpdf がまだ gofpdf より弱いところを正直に挙げておく:",[4868,4869,4870,4879,4895,4901],"ul",{},[114,4871,4872,99,4875,4878],{},[21,4873,4874],{},"任意角度の線、ベジェ、複雑なパス",[26,4876,4877],{},"c.Line()"," は列を横切る水平線を引く。CAD 図面や独自グラフ描画には届いていない (チャートを画像化して埋めるのは普通に動く)。",[114,4880,4881,99,4886,4888,4889,4891,4892,4894],{},[21,4882,4883,4885],{},[26,4884,32],{}," 中心の絶対座標コード",[26,4887,350],{}," で似たことはできるが、既存コードが 2,000 行の ",[26,4890,32],{}," + ",[26,4893,666],{}," だと、移行は事実上書き直しに近い。書き直すと 1/2 になることが多いので、それが救い。",[114,4896,4897,4900],{},[21,4898,4899],{},"AcroForm (入力可能フォーム)","。gpdf はまだ生成しない。閲覧側でユーザー入力を受けるテンプレ PDF を作っているなら、当面は AcroForm 対応のライブラリに残る選択肢。",[114,4902,4903,4906],{},[21,4904,4905],{},"注釈・ブックマーク","。基本的なアウトラインは出るが、リッチな注釈は未対応。",[18,4908,4909],{},"このどれにも刺さらないなら、移行はスルッと終わる。刺さるなら GitHub Issue を立ててほしい — ロードマップは要望ベース。",[13,4911,4913],{"id":4912},"faq","FAQ",[18,4915,4916,4919],{},[21,4917,4918],{},"gpdf は gofpdf のフォーク?","\n違う。gpdf は純 Go でゼロからの再実装。PDF ワイヤフォーマット、レイアウトエンジン、TrueType サブセッタ、すべて新規。gofpdf やそのフォークと共有しているコードはない。なぜフォークではないかというと、gofpdf のアーキテクチャは「単一のミュータブルなカーソル」を前提に作られていて、宣言的グリッドを後付けすると既存の呼び出しが全部壊れるから。",[18,4921,4922,4925,4926,4929,4930,4933,4934,4937,4938,4941],{},[21,4923,4924],{},"外部依存はある?","\nコアはゼロ。",[26,4927,4928],{},"go get github.com/gpdf-dev/gpdf"," のあとに ",[26,4931,4932],{},"go mod graph | grep gpdf"," を叩くと 1 行しか返らない。",[26,4935,4936],{},"gpdf-pro"," 拡張 (HTML→PDF、AES 暗号化、署名、PDF/A) は HTML パーサのために ",[26,4939,4940],{},"golang.org/x/net"," を引くが、これはオプトインで、移行に必須ではない。",[18,4943,4944,4947,4948,4951],{},[21,4945,4946],{},"CGO は? gofpdf は CGO フリーだったけど、gpdf は?","\n同じく純 Go・CGO なし。",[26,4949,4950],{},"GOOS=linux GOARCH=arm64 go build"," でクロスコンパイルして静的バイナリで配布できる。Distroless や Alpine では CGO ツールチェーンがないだけでイメージが半分になるので、ここは大事。",[18,4953,4954,4960,4962],{},[21,4955,4956,4957,4959],{},"既存 gofpdf コードが ",[26,4958,32],{}," だらけ。書き直しなしで移行できる?",[26,4961,350],{}," をラップして似た感触は出せる。ただ、コード全体がカーソル操作中心の構造だと、レイアウトエンジン的モデルへの移行は構文ではなく頭の切り替え。多くのチームでは「書き直したほうが元より短い」になる。",[18,4964,4965,4968,4969,4971],{},[21,4966,4967],{},"電子帳簿保存法・適格請求書の対応は?","\nタイムスタンプとデジタル署名は ",[26,4970,4936],{}," で対応中。要求があるなら Issue を立てて優先度を上げてほしい。",[18,4973,4974,4977],{},[21,4975,4976],{},"go-pdf/fpdf がアーカイブ解除されたら?","\n選択肢が 1 つ増えるだけ。gpdf を作った賭けは「gofpdf が永久にアーカイブ」のほうではなく、「カーソルベース・1 バイトフォント・CJK 非対応というアーキテクチャ自体が、誰がメンテしても袋小路」のほう。2026 年の PDF 生成はプロッタを動かすより Web ページを組むのに近く、API もそれを反映すべき。",[13,4979,4981],{"id":4980},"gpdf-を使ってみる","gpdf を使ってみる",[18,4983,4984],{},"gpdf は Go の PDF 生成ライブラリ。MIT、ゼロ依存、CJK 対応。",[485,4986,4990],{"className":4987,"code":4988,"language":4989,"meta":490,"style":490},"language-bash shiki shiki-themes material-theme-lighter material-theme material-theme-palenight","go get github.com/gpdf-dev/gpdf\n","bash",[26,4991,4992],{"__ignoreMap":490},[494,4993,4994,4996,4999],{"class":496,"line":497},[494,4995,489],{"class":504},[494,4997,4998],{"class":576}," get",[494,5000,5001],{"class":576}," github.com/gpdf-dev/gpdf\n",[18,5003,5004,5011,5012],{},[5005,5006,5010],"a",{"href":5007,"rel":5008},"https://github.com/gpdf-dev/gpdf",[5009],"nofollow","⭐ Star on GitHub"," · ",[5005,5013,5016],{"href":5014,"rel":5015},"https://gpdf.dev/ja/docs/quickstart",[5009],"ドキュメント",[13,5018,5019],{"id":5019},"次に読む",[4868,5021,5022,5028,5033],{},[114,5023,5024,5025],{},"12 カラムグリッドの仕組み ",[205,5026,5027],{},"(近日公開)",[114,5029,5030,5031],{},"gpdf で日本語フォントを埋め込むには? ",[205,5032,5027],{},[114,5034,5035,5039,5040,5043],{},[5005,5036,5038],{"href":5014,"rel":5037},[5009],"Quickstart"," — 5 分セットアップ、",[26,5041,5042],{},"go.mod"," 含む",[5045,5046,5047],"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 .sfazB, html code.shiki .sfazB{--shiki-light:#91B859;--shiki-default:#C3E88D;--shiki-dark:#C3E88D}html pre.shiki code .sbssI, html code.shiki .sbssI{--shiki-light:#F76D47;--shiki-default:#F78C6C;--shiki-dark:#F78C6C}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);}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 .sfNiH, html code.shiki .sfNiH{--shiki-light:#FF5370;--shiki-default:#FF9CAC;--shiki-dark:#FF9CAC}html pre.shiki code .spNyl, html code.shiki .spNyl{--shiki-light:#9C3EDA;--shiki-default:#C792EA;--shiki-dark:#C792EA}html pre.shiki code .swJcz, html code.shiki .swJcz{--shiki-light:#E53935;--shiki-default:#F07178;--shiki-dark:#F07178}html pre.shiki code .sHwdD, html code.shiki .sHwdD{--shiki-light:#90A4AE;--shiki-light-font-style:italic;--shiki-default:#546E7A;--shiki-default-font-style:italic;--shiki-dark:#676E95;--shiki-dark-font-style:italic}",{"title":490,"searchDepth":508,"depth":508,"links":5049},[5050,5051,5052,5053,5054,5055,5056,5057,5058,5059,5060,5061,5062,5063],{"id":15,"depth":508,"text":16},{"id":75,"depth":508,"text":76},{"id":105,"depth":508,"text":106},{"id":146,"depth":508,"text":147},{"id":474,"depth":508,"text":475},{"id":1210,"depth":508,"text":1211},{"id":2387,"depth":508,"text":2388},{"id":3053,"depth":508,"text":3054},{"id":4106,"depth":508,"text":4107},{"id":4747,"depth":508,"text":4748},{"id":4863,"depth":508,"text":4863},{"id":4912,"depth":508,"text":4913},{"id":4980,"depth":508,"text":4981},{"id":5019,"depth":508,"text":5019},"2026-04-14","gofpdf は 2021 年アーカイブ、後継 go-pdf/fpdf も 2025 年停止。CJK 対応・ゼロ依存の純 Go ライブラリ gpdf への移行ガイド。",false,"md",{"name":5069,"totalTime":5070,"tools":5071,"steps":5073},"Goプロジェクトを gofpdf から gpdf に移行する","PT30M",[5072],"Go 1.22+",[5074,5077,5080,5083,5086,5089],{"name":5075,"text":5076},"import パスを置き換える","2021 年アーカイブの github.com/jung-kurt/gofpdf と 2025 年停止の github.com/go-pdf/fpdf を、github.com/gpdf-dev/gpdf、github.com/gpdf-dev/gpdf/document、github.com/gpdf-dev/gpdf/template に差し替える。",{"name":5078,"text":5079},"カーソル操作ではなくビルダーでドキュメントを構築する","gpdf.NewDocument に WithPageSize / WithMargins / WithFont を渡して生成する。SetXY でカーソルを押し回す代わりに、doc.AddPage() でページを追加し RowBuilder / ColBuilder で内容を宣言する。",{"name":5081,"text":5082},"Cell / MultiCell を宣言的な Text に書き換える","pdf.Cell や pdf.MultiCell をカラム内の c.Text(...) に置き換える。テキストはカラム境界で自動折り返しされるため MultiCell の末尾フラグは不要。フォントサイズ・太字・色は per-text のオプションとして渡す。",{"name":5084,"text":5085},"CJK フォントを WithFont で登録する","日本語・中国語・韓国語のテキストでは、pdf.AddUTF8Font の代わりにドキュメント構築時 gpdf.WithFont(name, ttfBytes) を渡す。TTF パスの管理も UTF-8 フラグも不要になり、サブセット埋め込みは自動で行われる。",{"name":5087,"text":5088},"表を行とカラムで書き直す","列幅を手動管理する Cell のネストループをやめ、AutoRow の中で row.Col(n, fn) を並べて行を作る。12 カラムグリッドが幅計算もページ分割も扱ってくれる。",{"name":5090,"text":5091},"出力呼び出しを切り替える","pdf.OutputFileAndClose(path) の代わりに doc.Generate() で []byte を取得し os.WriteFile(path, data, 0o644) で書き出す。io.Writer に直接書くなら doc.Render(w) を使う。",null,{},"/ja/blog/gofpdf-migration",{"title":5,"description":5065},"ja/blog/001.gofpdf-migration",[5098,5099,5100,5101],"migration","comparison","tutorial","cjk","owtjceeRgENHD4xA9d9ovm2x1g5r07BZi2cDAJRyP2I",1776529265252]