[{"data":1,"prerenderedAt":5107},["ShallowReactive",2],{"blog-pt-gofpdf-migration":3},{"id":4,"title":5,"author":6,"body":9,"date":5069,"description":5070,"draft":5071,"extension":5072,"howTo":5073,"image":5097,"meta":5098,"navigation":519,"path":5099,"seo":5100,"stem":5101,"tags":5102,"updated":5097,"__hash__":5106},"blogPt/pt/blog/001.gofpdf-migration.md","gofpdf foi arquivado. Guia de migração para gpdf.",{"name":7,"url":8},"gpdf team","https://gpdf.dev",{"type":10,"value":11,"toc":5053},"minimark",[12,17,38,49,52,66,69,73,79,86,93,100,103,107,116,144,150,154,157,437,450,480,484,487,492,723,728,1192,1202,1216,1220,1230,1234,1986,1989,1993,2374,2391,2394,2398,2404,2408,2571,2580,2584,3037,3040,3051,3054,3057,3061,3080,3084,3406,3412,3416,4092,4107,4111,4125,4129,4407,4411,4731,4747,4751,4761,4857,4860,4863,4867,4870,4911,4914,4918,4924,4946,4956,4968,4977,4983,4987,4990,5007,5022,5026,5049],[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"," é uma biblioteca Go pura, sem dependências externas, com suporte CJK nativo (sem a dança do ",[26,27,28],"code",{},"AddUTF8Font","), que usa uma grade de 12 colunas em vez de empurrar pixels com ",[26,31,32],{},"SetXY"," e roda aproximadamente ",[21,35,36],{},"10× mais rápido que o gofpdf"," nas mesmas cargas. A migração consiste basicamente em substituir chamadas imperativas ao cursor por builders declarativos. Este guia percorre o mapeamento com cinco pares antes/depois.",[18,39,40,41,44,45,48],{},"Semana passada um colega abriu um projeto Go novo, rodou ",[26,42,43],{},"go get github.com/jung-kurt/gofpdf"," e dez minutos depois me mandou o screenshot do banner do GitHub: ",[21,46,47],{},"\"This repository has been archived by the owner. It is now read-only.\""," Seguido por: \"Espera, o fork também está arquivado?\"",[18,50,51],{},"Sim. Os dois.",[18,53,54,57,58,61,62,65],{},[26,55,56],{},"jung-kurt/gofpdf"," foi arquivado em ",[21,59,60],{},"8 de setembro de 2021",". O fork comunitário ",[26,63,64],{},"go-pdf/fpdf"," publicou seu último release em 2023 e foi arquivado em 2025. A biblioteca Go que dois terços das respostas no Stack Overflow ainda recomendam está há mais de quatro anos em modo somente-leitura, e o fork que deveria substituí-la também já se foi.",[18,67,68],{},"Se você tem uma base gofpdf em produção, este post é um mapa de migração. Se está começando um projeto novo e foi puxar gofpdf por reflexo, porque era o que os resultados de busca mostravam, esta é a alternativa.",[13,70,72],{"id":71},"por-que-o-gofpdf-realmente-não-volta","Por que o gofpdf realmente não volta",[18,74,75,76,78],{},"Bibliotecas open source nem sempre morrem. Às vezes o mantenedor se afasta e alguém assume. Era o que todo mundo assumiu que ia acontecer com o gofpdf — e por um tempo aconteceu. O fork ",[26,77,64],{}," reorganizou o código, resolveu alguns bugs antigos, aceitou PRs, parecia uma continuação legítima.",[18,80,81,82],{},"Aí, no início de 2025, o fork também foi arquivado. O README agora diz, em parte: ",[83,84,85],"em",{},"\"Este projeto não é mais mantido ativamente. Considere usar outra biblioteca.\"",[18,87,88,89,92],{},"A razão importa menos que a consequência: ",[21,90,91],{},"todo projeto Go que depende do gofpdf agora está em cima de duas camadas de código sem manutenção",". Questões de segurança não vão ser corrigidas. A spec PDF 2.0 saiu em 2020 e o gofpdf não cobre a maior parte do que mudou. A semântica de variáveis de loop do Go 1.25 ainda funciona com gofpdf hoje, mas o que quebrar amanhã é você que conserta em um fork privado.",[18,94,95,96,99],{},"Não é um problema de \"a biblioteca tem bugs\". É um problema de ",[21,97,98],{},"cadeia de suprimentos",".",[18,101,102],{},"Para times no Brasil há um agravante: exigências fiscais (NFe, DANFE, PDF/A para arquivamento) já são difíceis de justificar com uma biblioteca abandonada em auditoria.",[13,104,106],{"id":105},"para-que-o-pessoal-realmente-usa-gofpdf","Para que o pessoal realmente usa gofpdf",[18,108,109,110,112,113,115],{},"Antes de entrar no mapeamento, vale ser específico sobre as cargas que migram. Olhando os trackers de issues e as perguntas de Stack Overflow e dev.to sobre ",[26,111,56],{}," e ",[26,114,64],{},", os usos dominantes são:",[117,118,119,126,132,138],"ol",{},[120,121,122,125],"li",{},[21,123,124],{},"Notas fiscais, recibos, DANFEs"," — cabeçalho, bloco do cliente, tabela de itens, totais, rodapé.",[120,127,128,131],{},[21,129,130],{},"Relatórios"," — documentos multipágina com cabeçalhos repetidos, números de página, gráficos inseridos como imagens.",[120,133,134,137],{},[21,135,136],{},"Formulários e certificados"," — texto em posições fixas sobre um template.",[120,139,140,143],{},[21,141,142],{},"Documentos CJK"," — notas e etiquetas de envio em japonês, chinês, coreano.",[18,145,146,147,149],{},"Os três primeiros a API de builder do gpdf cobre tranquilamente. O quarto — CJK — é onde o gpdf abre a maior distância em relação ao gofpdf. O gofpdf obrigava você a chamar ",[26,148,28],{},", gerenciar um caminho para um TTF, e torcer para o texto não sair do plano básico. O gpdf trata CJK como cidadão de primeira classe: registra uma fonte TrueType, escreve em japonês, sai um PDF.",[13,151,153],{"id":152},"a-tabela-de-mapeamento-da-api","A tabela de mapeamento da API",[18,155,156],{},"A tabela a seguir é a colinha. As seções seguintes percorrem cinco pares antes/depois concretos.",[158,159,160,175],"table",{},[161,162,163],"thead",{},[164,165,166,170,173],"tr",{},[167,168,169],"th",{},"O que você quer fazer",[167,171,172],{},"gofpdf",[167,174,23],{},[176,177,178,194,217,240,258,273,291,309,324,339,357,372,387,407,422],"tbody",{},[164,179,180,184,189],{},[181,182,183],"td",{},"Criar um documento",[181,185,186],{},[26,187,188],{},"gofpdf.New(\"P\", \"mm\", \"A4\", \"\")",[181,190,191],{},[26,192,193],{},"gpdf.NewDocument(gpdf.WithPageSize(document.A4))",[164,195,196,199,204],{},[181,197,198],{},"Adicionar uma página",[181,200,201],{},[26,202,203],{},"pdf.AddPage()",[181,205,206,209,210],{},[26,207,208],{},"doc.AddPage()"," ",[83,211,212,213,216],{},"(retorna um ",[26,214,215],{},"*PageBuilder",")",[164,218,219,222,227],{},[181,220,221],{},"Definir uma fonte",[181,223,224],{},[26,225,226],{},"pdf.SetFont(\"Arial\", \"B\", 16)",[181,228,229,232,233,232,236,239],{},[26,230,231],{},"template.FontFamily(...)",", ",[26,234,235],{},"template.Bold()",[26,237,238],{},"template.FontSize(16)"," como opções de texto",[164,241,242,245,250],{},[181,243,244],{},"Registrar um TTF (CJK)",[181,246,247],{},[26,248,249],{},"pdf.AddUTF8Font(\"noto\", \"\", \"NotoSansJP-Regular.ttf\")",[181,251,252,209,255],{},[26,253,254],{},"gpdf.WithFont(\"NotoSansJP\", ttfBytes)",[83,256,257],{},"(na construção)",[164,259,260,263,268],{},[181,261,262],{},"Escrever uma linha",[181,264,265],{},[26,266,267],{},"pdf.Cell(40, 10, \"hi\")",[181,269,270],{},[26,271,272],{},"c.Text(\"hi\")",[164,274,275,278,283],{},[181,276,277],{},"Escrever texto com quebra",[181,279,280],{},[26,281,282],{},"pdf.MultiCell(0, 10, body, \"\", \"L\", false)",[181,284,285,209,288],{},[26,286,287],{},"c.Text(body)",[83,289,290],{},"(quebra automaticamente)",[164,292,293,296,301],{},[181,294,295],{},"Cor do texto",[181,297,298],{},[26,299,300],{},"pdf.SetTextColor(255, 0, 0)",[181,302,303,209,306],{},[26,304,305],{},"template.TextColor(pdf.Red)",[83,307,308],{},"(opção por texto)",[164,310,311,314,319],{},[181,312,313],{},"Desenhar uma linha horizontal",[181,315,316],{},[26,317,318],{},"pdf.Line(x1, y1, x2, y2)",[181,320,321],{},[26,322,323],{},"c.Line(template.LineThickness(document.Pt(1)))",[164,325,326,329,334],{},[181,327,328],{},"Inserir uma imagem",[181,330,331],{},[26,332,333],{},"pdf.ImageOptions(\"logo.png\", x, y, w, h, ...)",[181,335,336],{},[26,337,338],{},"c.Image(imgBytes, template.FitWidth(document.Mm(50)))",[164,340,341,344,349],{},[181,342,343],{},"Definir cursor XY",[181,345,346],{},[26,347,348],{},"pdf.SetXY(x, y)",[181,350,351],{},[83,352,353,354,216],{},"(sem equivalente — use linhas/colunas ou ",[26,355,356],{},"page.Absolute(x, y, fn)",[164,358,359,362,367],{},[181,360,361],{},"Cabeçalho repetido",[181,363,364],{},[26,365,366],{},"pdf.SetHeaderFunc(fn)",[181,368,369],{},[26,370,371],{},"doc.Header(fn)",[164,373,374,377,382],{},[181,375,376],{},"Rodapé repetido",[181,378,379],{},[26,380,381],{},"pdf.SetFooterFunc(fn)",[181,383,384],{},[26,385,386],{},"doc.Footer(fn)",[164,388,389,392,398],{},[181,390,391],{},"Número de página",[181,393,394,395],{},"manual: ",[26,396,397],{},"pdf.PageNo()",[181,399,400,403,404],{},[26,401,402],{},"c.PageNumber()"," / ",[26,405,406],{},"c.TotalPages()",[164,408,409,412,417],{},[181,410,411],{},"Saída para arquivo",[181,413,414],{},[26,415,416],{},"pdf.OutputFileAndClose(\"out.pdf\")",[181,418,419],{},[26,420,421],{},"data, _ := doc.Generate(); os.WriteFile(\"out.pdf\", data, 0o644)",[164,423,424,427,432],{},[181,425,426],{},"Saída para writer",[181,428,429],{},[26,430,431],{},"pdf.Output(w)",[181,433,434],{},[26,435,436],{},"doc.Render(w)",[18,438,439,440,443,444,447,448,99],{},"A mudança de forma é o que pesa mais: gofpdf é ",[21,441,442],{},"imperativo",", gpdf é ",[21,445,446],{},"declarativo",". No gofpdf você empurra um cursor pela página e escreve onde ele cai. No gpdf você descreve uma árvore de linhas e colunas e deixa o motor de layout posicionar as coisas. Os primeiros trechos parecem mais longos em gpdf. No terceiro você para de sentir falta do ",[26,449,32],{},[18,451,452,453,232,456,232,459,462,463,232,466,232,469,232,472,475,476,479],{},"Uma nota sobre unidades. O gofpdf te faz escolher uma unidade base na construção (",[26,454,455],{},"\"mm\"",[26,457,458],{},"\"pt\"",[26,460,461],{},"\"in\"","). O gpdf usa pontos internamente e oferece helpers — ",[26,464,465],{},"document.Mm(20)",[26,467,468],{},"document.Pt(12)",[26,470,471],{},"document.Cm(1)",[26,473,474],{},"document.In(0.5)"," — para a unidade que você preferir no ponto de chamada. É mais próximo de CSS do que do gofpdf, e depois que você coloca um cabeçalho em cada página com margens em ",[26,477,478],{},"document.Mm(15)",", para de pensar em unidade.",[13,481,483],{"id":482},"antes-depois-1-o-pdf-mais-simples-possível","Antes / Depois 1: o PDF mais simples possível",[18,485,486],{},"O par \"hello world\". A brevidade do gofpdf foi o que o deixou tão citável. A versão gpdf tem algumas linhas a mais porque está construindo uma árvore, não dirigindo um cursor.",[18,488,489],{},[21,490,491],{},"Antes — gofpdf:",[493,494,499],"pre",{"className":495,"code":496,"language":497,"meta":498,"style":498},"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,500,501,514,521,537,542,558,615,629,665,696,717],{"__ignoreMap":498},[502,503,506,510],"span",{"class":504,"line":505},"line",1,[502,507,509],{"class":508},"sMK4o","package",[502,511,513],{"class":512},"sBMFI"," main\n",[502,515,517],{"class":504,"line":516},2,[502,518,520],{"emptyLinePlaceholder":519},true,"\n",[502,522,524,528,531,534],{"class":504,"line":523},3,[502,525,527],{"class":526},"s7zQu","import",[502,529,530],{"class":508}," \"",[502,532,533],{"class":512},"github.com/jung-kurt/gofpdf",[502,535,536],{"class":508},"\"\n",[502,538,540],{"class":504,"line":539},4,[502,541,520],{"emptyLinePlaceholder":519},[502,543,545,548,552,555],{"class":504,"line":544},5,[502,546,547],{"class":508},"func",[502,549,551],{"class":550},"s2Zo4"," main",[502,553,554],{"class":508},"()",[502,556,557],{"class":508}," {\n",[502,559,561,565,568,571,573,576,579,582,586,588,591,593,596,598,600,602,605,607,609,612],{"class":504,"line":560},6,[502,562,564],{"class":563},"sTEyZ","    pdf ",[502,566,567],{"class":508},":=",[502,569,570],{"class":563}," gofpdf",[502,572,99],{"class":508},[502,574,575],{"class":550},"New",[502,577,578],{"class":508},"(",[502,580,581],{"class":508},"\"",[502,583,585],{"class":584},"sfazB","P",[502,587,581],{"class":508},[502,589,590],{"class":508},",",[502,592,530],{"class":508},[502,594,595],{"class":584},"mm",[502,597,581],{"class":508},[502,599,590],{"class":508},[502,601,530],{"class":508},[502,603,604],{"class":584},"A4",[502,606,581],{"class":508},[502,608,590],{"class":508},[502,610,611],{"class":508}," \"\"",[502,613,614],{"class":508},")\n",[502,616,618,621,623,626],{"class":504,"line":617},7,[502,619,620],{"class":563},"    pdf",[502,622,99],{"class":508},[502,624,625],{"class":550},"AddPage",[502,627,628],{"class":508},"()\n",[502,630,632,634,636,639,641,643,646,648,650,652,655,657,659,663],{"class":504,"line":631},8,[502,633,620],{"class":563},[502,635,99],{"class":508},[502,637,638],{"class":550},"SetFont",[502,640,578],{"class":508},[502,642,581],{"class":508},[502,644,645],{"class":584},"Arial",[502,647,581],{"class":508},[502,649,590],{"class":508},[502,651,530],{"class":508},[502,653,654],{"class":584},"B",[502,656,581],{"class":508},[502,658,590],{"class":508},[502,660,662],{"class":661},"sbssI"," 24",[502,664,614],{"class":508},[502,666,668,670,672,675,677,680,682,685,687,689,692,694],{"class":504,"line":667},9,[502,669,620],{"class":563},[502,671,99],{"class":508},[502,673,674],{"class":550},"Cell",[502,676,578],{"class":508},[502,678,679],{"class":661},"40",[502,681,590],{"class":508},[502,683,684],{"class":661}," 10",[502,686,590],{"class":508},[502,688,530],{"class":508},[502,690,691],{"class":584},"Hello, World!",[502,693,581],{"class":508},[502,695,614],{"class":508},[502,697,699,701,703,706,708,710,713,715],{"class":504,"line":698},10,[502,700,620],{"class":563},[502,702,99],{"class":508},[502,704,705],{"class":550},"OutputFileAndClose",[502,707,578],{"class":508},[502,709,581],{"class":508},[502,711,712],{"class":584},"hello.pdf",[502,714,581],{"class":508},[502,716,614],{"class":508},[502,718,720],{"class":504,"line":719},11,[502,721,722],{"class":508},"}\n",[18,724,725],{},[21,726,727],{},"Depois — gpdf:",[493,729,731],{"className":495,"code":730,"language":497,"meta":498,"style":498},"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,732,733,739,743,750,760,769,773,782,791,800,804,808,819,838,861,897,903,908,925,958,995,1042,1048,1054,1059,1081,1097,1115,1121,1167,1182,1187],{"__ignoreMap":498},[502,734,735,737],{"class":504,"line":505},[502,736,509],{"class":508},[502,738,513],{"class":512},[502,740,741],{"class":504,"line":516},[502,742,520],{"emptyLinePlaceholder":519},[502,744,745,747],{"class":504,"line":523},[502,746,527],{"class":526},[502,748,749],{"class":508}," (\n",[502,751,752,755,758],{"class":504,"line":539},[502,753,754],{"class":508},"    \"",[502,756,757],{"class":512},"log",[502,759,536],{"class":508},[502,761,762,764,767],{"class":504,"line":544},[502,763,754],{"class":508},[502,765,766],{"class":512},"os",[502,768,536],{"class":508},[502,770,771],{"class":504,"line":560},[502,772,520],{"emptyLinePlaceholder":519},[502,774,775,777,780],{"class":504,"line":617},[502,776,754],{"class":508},[502,778,779],{"class":512},"github.com/gpdf-dev/gpdf",[502,781,536],{"class":508},[502,783,784,786,789],{"class":504,"line":631},[502,785,754],{"class":508},[502,787,788],{"class":512},"github.com/gpdf-dev/gpdf/document",[502,790,536],{"class":508},[502,792,793,795,798],{"class":504,"line":667},[502,794,754],{"class":508},[502,796,797],{"class":512},"github.com/gpdf-dev/gpdf/template",[502,799,536],{"class":508},[502,801,802],{"class":504,"line":698},[502,803,614],{"class":508},[502,805,806],{"class":504,"line":719},[502,807,520],{"emptyLinePlaceholder":519},[502,809,811,813,815,817],{"class":504,"line":810},12,[502,812,547],{"class":508},[502,814,551],{"class":550},[502,816,554],{"class":508},[502,818,557],{"class":508},[502,820,822,825,827,830,832,835],{"class":504,"line":821},13,[502,823,824],{"class":563},"    doc ",[502,826,567],{"class":508},[502,828,829],{"class":563}," gpdf",[502,831,99],{"class":508},[502,833,834],{"class":550},"NewDocument",[502,836,837],{"class":508},"(\n",[502,839,841,844,846,849,851,854,856,858],{"class":504,"line":840},14,[502,842,843],{"class":563},"        gpdf",[502,845,99],{"class":508},[502,847,848],{"class":550},"WithPageSize",[502,850,578],{"class":508},[502,852,853],{"class":563},"document",[502,855,99],{"class":508},[502,857,604],{"class":563},[502,859,860],{"class":508},"),\n",[502,862,864,866,868,871,873,875,877,880,882,884,886,889,891,894],{"class":504,"line":863},15,[502,865,843],{"class":563},[502,867,99],{"class":508},[502,869,870],{"class":550},"WithMargins",[502,872,578],{"class":508},[502,874,853],{"class":563},[502,876,99],{"class":508},[502,878,879],{"class":550},"UniformEdges",[502,881,578],{"class":508},[502,883,853],{"class":563},[502,885,99],{"class":508},[502,887,888],{"class":550},"Mm",[502,890,578],{"class":508},[502,892,893],{"class":661},"20",[502,895,896],{"class":508},"))),\n",[502,898,900],{"class":504,"line":899},16,[502,901,902],{"class":508},"    )\n",[502,904,906],{"class":504,"line":905},17,[502,907,520],{"emptyLinePlaceholder":519},[502,909,911,914,916,919,921,923],{"class":504,"line":910},18,[502,912,913],{"class":563},"    page ",[502,915,567],{"class":508},[502,917,918],{"class":563}," doc",[502,920,99],{"class":508},[502,922,625],{"class":550},[502,924,628],{"class":508},[502,926,928,931,933,936,939,943,946,949,951,954,956],{"class":504,"line":927},19,[502,929,930],{"class":563},"    page",[502,932,99],{"class":508},[502,934,935],{"class":550},"AutoRow",[502,937,938],{"class":508},"(func(",[502,940,942],{"class":941},"sHdIc","r",[502,944,945],{"class":508}," *",[502,947,948],{"class":512},"template",[502,950,99],{"class":508},[502,952,953],{"class":512},"RowBuilder",[502,955,216],{"class":508},[502,957,557],{"class":508},[502,959,961,964,966,969,971,974,976,979,982,984,986,988,991,993],{"class":504,"line":960},20,[502,962,963],{"class":563},"        r",[502,965,99],{"class":508},[502,967,968],{"class":550},"Col",[502,970,578],{"class":508},[502,972,973],{"class":661},"12",[502,975,590],{"class":508},[502,977,978],{"class":508}," func(",[502,980,981],{"class":941},"c",[502,983,945],{"class":508},[502,985,948],{"class":512},[502,987,99],{"class":508},[502,989,990],{"class":512},"ColBuilder",[502,992,216],{"class":508},[502,994,557],{"class":508},[502,996,998,1001,1003,1006,1008,1010,1012,1014,1016,1019,1021,1024,1026,1029,1032,1034,1036,1039],{"class":504,"line":997},21,[502,999,1000],{"class":563},"            c",[502,1002,99],{"class":508},[502,1004,1005],{"class":550},"Text",[502,1007,578],{"class":508},[502,1009,581],{"class":508},[502,1011,691],{"class":584},[502,1013,581],{"class":508},[502,1015,590],{"class":508},[502,1017,1018],{"class":563}," template",[502,1020,99],{"class":508},[502,1022,1023],{"class":550},"FontSize",[502,1025,578],{"class":508},[502,1027,1028],{"class":661},"24",[502,1030,1031],{"class":508},"),",[502,1033,1018],{"class":563},[502,1035,99],{"class":508},[502,1037,1038],{"class":550},"Bold",[502,1040,1041],{"class":508},"())\n",[502,1043,1045],{"class":504,"line":1044},22,[502,1046,1047],{"class":508},"        })\n",[502,1049,1051],{"class":504,"line":1050},23,[502,1052,1053],{"class":508},"    })\n",[502,1055,1057],{"class":504,"line":1056},24,[502,1058,520],{"emptyLinePlaceholder":519},[502,1060,1062,1065,1067,1070,1072,1074,1076,1079],{"class":504,"line":1061},25,[502,1063,1064],{"class":563},"    data",[502,1066,590],{"class":508},[502,1068,1069],{"class":563}," err ",[502,1071,567],{"class":508},[502,1073,918],{"class":563},[502,1075,99],{"class":508},[502,1077,1078],{"class":550},"Generate",[502,1080,628],{"class":508},[502,1082,1084,1087,1089,1092,1095],{"class":504,"line":1083},26,[502,1085,1086],{"class":526},"    if",[502,1088,1069],{"class":563},[502,1090,1091],{"class":508},"!=",[502,1093,1094],{"class":508}," nil",[502,1096,557],{"class":508},[502,1098,1100,1103,1105,1108,1110,1113],{"class":504,"line":1099},27,[502,1101,1102],{"class":563},"        log",[502,1104,99],{"class":508},[502,1106,1107],{"class":550},"Fatal",[502,1109,578],{"class":508},[502,1111,1112],{"class":563},"err",[502,1114,614],{"class":508},[502,1116,1118],{"class":504,"line":1117},28,[502,1119,1120],{"class":508},"    }\n",[502,1122,1124,1126,1128,1130,1133,1135,1138,1140,1142,1144,1146,1148,1151,1153,1156,1159,1161,1163,1165],{"class":504,"line":1123},29,[502,1125,1086],{"class":526},[502,1127,1069],{"class":563},[502,1129,567],{"class":508},[502,1131,1132],{"class":563}," os",[502,1134,99],{"class":508},[502,1136,1137],{"class":550},"WriteFile",[502,1139,578],{"class":508},[502,1141,581],{"class":508},[502,1143,712],{"class":584},[502,1145,581],{"class":508},[502,1147,590],{"class":508},[502,1149,1150],{"class":563}," data",[502,1152,590],{"class":508},[502,1154,1155],{"class":661}," 0o644",[502,1157,1158],{"class":508},");",[502,1160,1069],{"class":563},[502,1162,1091],{"class":508},[502,1164,1094],{"class":508},[502,1166,557],{"class":508},[502,1168,1170,1172,1174,1176,1178,1180],{"class":504,"line":1169},30,[502,1171,1102],{"class":563},[502,1173,99],{"class":508},[502,1175,1107],{"class":550},[502,1177,578],{"class":508},[502,1179,1112],{"class":563},[502,1181,614],{"class":508},[502,1183,1185],{"class":504,"line":1184},31,[502,1186,1120],{"class":508},[502,1188,1190],{"class":504,"line":1189},32,[502,1191,722],{"class":508},[18,1193,1194,1195,1197,1198,1201],{},"A grade faz o trabalho. ",[26,1196,935],{}," adiciona uma linha cuja altura vem do conteúdo; ",[26,1199,1200],{},"r.Col(12, ...)"," diz \"esta coluna ocupa as 12 colunas da grade\". Mesma ideia do Bootstrap aplicada a uma página PDF.",[18,1203,1204,1207,1208,1211,1212,1215],{},[26,1205,1206],{},"Generate()"," devolve os bytes; ",[26,1209,1210],{},"Render(w)"," transmite para um ",[26,1213,1214],{},"io.Writer"," se você preferir não alocar. Não existe o passo de \"fechar o arquivo\" porque o gpdf não segura file handle nenhum.",[13,1217,1219],{"id":1218},"antes-depois-2-uma-tabela-de-itens-de-nota","Antes / Depois 2: uma tabela de itens de nota",[18,1221,1222,1223,1225,1226,1229],{},"Tabelas é onde o gofpdf fica verboso. Não tem tabela embutida; você chama ",[26,1224,674],{}," em loops aninhados, gerencia largura de colunas na mão e usa ",[26,1227,1228],{},"Ln(-1)"," para pular linha. Metade dos tutoriais de nota fiscal com gofpdf na internet é, literalmente, boilerplate de tabela.",[18,1231,1232],{},[21,1233,491],{},[493,1235,1237],{"className":495,"code":1236,"language":497,"meta":498,"style":498},"pdf.SetFont(\"Arial\", \"B\", 11)\npdf.SetFillColor(220, 220, 220)\npdf.CellFormat(80, 8, \"Descrição\",    \"1\", 0, \"L\", true, 0, \"\")\npdf.CellFormat(20, 8, \"Qtd.\",         \"1\", 0, \"C\", true, 0, \"\")\npdf.CellFormat(30, 8, \"Preço Unit.\",  \"1\", 0, \"R\", true, 0, \"\")\npdf.CellFormat(30, 8, \"Total\",        \"1\", 1, \"R\", true, 0, \"\")\n\npdf.SetFont(\"Arial\", \"\", 11)\nitems := [][]string{\n    {\"Desenvolvimento frontend\", \"40 h\", \"R$ 150,00\", \"R$ 6.000,00\"},\n    {\"Desenvolvimento backend\",  \"60 h\", \"R$ 150,00\", \"R$ 9.000,00\"},\n    {\"Design de UI\",             \"20 h\", \"R$ 120,00\", \"R$ 2.400,00\"},\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,1238,1239,1271,1296,1363,1424,1486,1547,1551,1577,1594,1636,1675,1716,1720,1743,1806,1864,1923,1982],{"__ignoreMap":498},[502,1240,1241,1244,1246,1248,1250,1252,1254,1256,1258,1260,1262,1264,1266,1269],{"class":504,"line":505},[502,1242,1243],{"class":563},"pdf",[502,1245,99],{"class":508},[502,1247,638],{"class":550},[502,1249,578],{"class":508},[502,1251,581],{"class":508},[502,1253,645],{"class":584},[502,1255,581],{"class":508},[502,1257,590],{"class":508},[502,1259,530],{"class":508},[502,1261,654],{"class":584},[502,1263,581],{"class":508},[502,1265,590],{"class":508},[502,1267,1268],{"class":661}," 11",[502,1270,614],{"class":508},[502,1272,1273,1275,1277,1280,1282,1285,1287,1290,1292,1294],{"class":504,"line":516},[502,1274,1243],{"class":563},[502,1276,99],{"class":508},[502,1278,1279],{"class":550},"SetFillColor",[502,1281,578],{"class":508},[502,1283,1284],{"class":661},"220",[502,1286,590],{"class":508},[502,1288,1289],{"class":661}," 220",[502,1291,590],{"class":508},[502,1293,1289],{"class":661},[502,1295,614],{"class":508},[502,1297,1298,1300,1302,1305,1307,1310,1312,1315,1317,1319,1322,1324,1326,1328,1331,1333,1335,1338,1340,1342,1345,1347,1349,1353,1355,1357,1359,1361],{"class":504,"line":523},[502,1299,1243],{"class":563},[502,1301,99],{"class":508},[502,1303,1304],{"class":550},"CellFormat",[502,1306,578],{"class":508},[502,1308,1309],{"class":661},"80",[502,1311,590],{"class":508},[502,1313,1314],{"class":661}," 8",[502,1316,590],{"class":508},[502,1318,530],{"class":508},[502,1320,1321],{"class":584},"Descrição",[502,1323,581],{"class":508},[502,1325,590],{"class":508},[502,1327,754],{"class":508},[502,1329,1330],{"class":584},"1",[502,1332,581],{"class":508},[502,1334,590],{"class":508},[502,1336,1337],{"class":661}," 0",[502,1339,590],{"class":508},[502,1341,530],{"class":508},[502,1343,1344],{"class":584},"L",[502,1346,581],{"class":508},[502,1348,590],{"class":508},[502,1350,1352],{"class":1351},"sfNiH"," true",[502,1354,590],{"class":508},[502,1356,1337],{"class":661},[502,1358,590],{"class":508},[502,1360,611],{"class":508},[502,1362,614],{"class":508},[502,1364,1365,1367,1369,1371,1373,1375,1377,1379,1381,1383,1386,1388,1390,1393,1395,1397,1399,1401,1403,1405,1408,1410,1412,1414,1416,1418,1420,1422],{"class":504,"line":539},[502,1366,1243],{"class":563},[502,1368,99],{"class":508},[502,1370,1304],{"class":550},[502,1372,578],{"class":508},[502,1374,893],{"class":661},[502,1376,590],{"class":508},[502,1378,1314],{"class":661},[502,1380,590],{"class":508},[502,1382,530],{"class":508},[502,1384,1385],{"class":584},"Qtd.",[502,1387,581],{"class":508},[502,1389,590],{"class":508},[502,1391,1392],{"class":508},"         \"",[502,1394,1330],{"class":584},[502,1396,581],{"class":508},[502,1398,590],{"class":508},[502,1400,1337],{"class":661},[502,1402,590],{"class":508},[502,1404,530],{"class":508},[502,1406,1407],{"class":584},"C",[502,1409,581],{"class":508},[502,1411,590],{"class":508},[502,1413,1352],{"class":1351},[502,1415,590],{"class":508},[502,1417,1337],{"class":661},[502,1419,590],{"class":508},[502,1421,611],{"class":508},[502,1423,614],{"class":508},[502,1425,1426,1428,1430,1432,1434,1437,1439,1441,1443,1445,1448,1450,1452,1455,1457,1459,1461,1463,1465,1467,1470,1472,1474,1476,1478,1480,1482,1484],{"class":504,"line":544},[502,1427,1243],{"class":563},[502,1429,99],{"class":508},[502,1431,1304],{"class":550},[502,1433,578],{"class":508},[502,1435,1436],{"class":661},"30",[502,1438,590],{"class":508},[502,1440,1314],{"class":661},[502,1442,590],{"class":508},[502,1444,530],{"class":508},[502,1446,1447],{"class":584},"Preço Unit.",[502,1449,581],{"class":508},[502,1451,590],{"class":508},[502,1453,1454],{"class":508},"  \"",[502,1456,1330],{"class":584},[502,1458,581],{"class":508},[502,1460,590],{"class":508},[502,1462,1337],{"class":661},[502,1464,590],{"class":508},[502,1466,530],{"class":508},[502,1468,1469],{"class":584},"R",[502,1471,581],{"class":508},[502,1473,590],{"class":508},[502,1475,1352],{"class":1351},[502,1477,590],{"class":508},[502,1479,1337],{"class":661},[502,1481,590],{"class":508},[502,1483,611],{"class":508},[502,1485,614],{"class":508},[502,1487,1488,1490,1492,1494,1496,1498,1500,1502,1504,1506,1509,1511,1513,1516,1518,1520,1522,1525,1527,1529,1531,1533,1535,1537,1539,1541,1543,1545],{"class":504,"line":560},[502,1489,1243],{"class":563},[502,1491,99],{"class":508},[502,1493,1304],{"class":550},[502,1495,578],{"class":508},[502,1497,1436],{"class":661},[502,1499,590],{"class":508},[502,1501,1314],{"class":661},[502,1503,590],{"class":508},[502,1505,530],{"class":508},[502,1507,1508],{"class":584},"Total",[502,1510,581],{"class":508},[502,1512,590],{"class":508},[502,1514,1515],{"class":508},"        \"",[502,1517,1330],{"class":584},[502,1519,581],{"class":508},[502,1521,590],{"class":508},[502,1523,1524],{"class":661}," 1",[502,1526,590],{"class":508},[502,1528,530],{"class":508},[502,1530,1469],{"class":584},[502,1532,581],{"class":508},[502,1534,590],{"class":508},[502,1536,1352],{"class":1351},[502,1538,590],{"class":508},[502,1540,1337],{"class":661},[502,1542,590],{"class":508},[502,1544,611],{"class":508},[502,1546,614],{"class":508},[502,1548,1549],{"class":504,"line":617},[502,1550,520],{"emptyLinePlaceholder":519},[502,1552,1553,1555,1557,1559,1561,1563,1565,1567,1569,1571,1573,1575],{"class":504,"line":631},[502,1554,1243],{"class":563},[502,1556,99],{"class":508},[502,1558,638],{"class":550},[502,1560,578],{"class":508},[502,1562,581],{"class":508},[502,1564,645],{"class":584},[502,1566,581],{"class":508},[502,1568,590],{"class":508},[502,1570,611],{"class":508},[502,1572,590],{"class":508},[502,1574,1268],{"class":661},[502,1576,614],{"class":508},[502,1578,1579,1582,1584,1587,1591],{"class":504,"line":667},[502,1580,1581],{"class":563},"items ",[502,1583,567],{"class":508},[502,1585,1586],{"class":508}," [][]",[502,1588,1590],{"class":1589},"spNyl","string",[502,1592,1593],{"class":508},"{\n",[502,1595,1596,1599,1601,1604,1606,1608,1610,1613,1615,1617,1619,1622,1624,1626,1628,1631,1633],{"class":504,"line":698},[502,1597,1598],{"class":508},"    {",[502,1600,581],{"class":508},[502,1602,1603],{"class":584},"Desenvolvimento frontend",[502,1605,581],{"class":508},[502,1607,590],{"class":508},[502,1609,530],{"class":508},[502,1611,1612],{"class":584},"40 h",[502,1614,581],{"class":508},[502,1616,590],{"class":508},[502,1618,530],{"class":508},[502,1620,1621],{"class":584},"R$ 150,00",[502,1623,581],{"class":508},[502,1625,590],{"class":508},[502,1627,530],{"class":508},[502,1629,1630],{"class":584},"R$ 6.000,00",[502,1632,581],{"class":508},[502,1634,1635],{"class":508},"},\n",[502,1637,1638,1640,1642,1645,1647,1649,1651,1654,1656,1658,1660,1662,1664,1666,1668,1671,1673],{"class":504,"line":719},[502,1639,1598],{"class":508},[502,1641,581],{"class":508},[502,1643,1644],{"class":584},"Desenvolvimento backend",[502,1646,581],{"class":508},[502,1648,590],{"class":508},[502,1650,1454],{"class":508},[502,1652,1653],{"class":584},"60 h",[502,1655,581],{"class":508},[502,1657,590],{"class":508},[502,1659,530],{"class":508},[502,1661,1621],{"class":584},[502,1663,581],{"class":508},[502,1665,590],{"class":508},[502,1667,530],{"class":508},[502,1669,1670],{"class":584},"R$ 9.000,00",[502,1672,581],{"class":508},[502,1674,1635],{"class":508},[502,1676,1677,1679,1681,1684,1686,1688,1691,1694,1696,1698,1700,1703,1705,1707,1709,1712,1714],{"class":504,"line":810},[502,1678,1598],{"class":508},[502,1680,581],{"class":508},[502,1682,1683],{"class":584},"Design de UI",[502,1685,581],{"class":508},[502,1687,590],{"class":508},[502,1689,1690],{"class":508},"             \"",[502,1692,1693],{"class":584},"20 h",[502,1695,581],{"class":508},[502,1697,590],{"class":508},[502,1699,530],{"class":508},[502,1701,1702],{"class":584},"R$ 120,00",[502,1704,581],{"class":508},[502,1706,590],{"class":508},[502,1708,530],{"class":508},[502,1710,1711],{"class":584},"R$ 2.400,00",[502,1713,581],{"class":508},[502,1715,1635],{"class":508},[502,1717,1718],{"class":504,"line":821},[502,1719,722],{"class":508},[502,1721,1722,1725,1728,1730,1733,1735,1738,1741],{"class":504,"line":840},[502,1723,1724],{"class":526},"for",[502,1726,1727],{"class":563}," _",[502,1729,590],{"class":508},[502,1731,1732],{"class":563}," row ",[502,1734,567],{"class":508},[502,1736,1737],{"class":526}," range",[502,1739,1740],{"class":563}," items ",[502,1742,1593],{"class":508},[502,1744,1745,1747,1749,1751,1753,1755,1757,1759,1761,1764,1767,1770,1773,1775,1777,1779,1781,1783,1785,1787,1789,1791,1793,1796,1798,1800,1802,1804],{"class":504,"line":863},[502,1746,620],{"class":563},[502,1748,99],{"class":508},[502,1750,1304],{"class":550},[502,1752,578],{"class":508},[502,1754,1309],{"class":661},[502,1756,590],{"class":508},[502,1758,1314],{"class":661},[502,1760,590],{"class":508},[502,1762,1763],{"class":563}," row",[502,1765,1766],{"class":508},"[",[502,1768,1769],{"class":661},"0",[502,1771,1772],{"class":508},"],",[502,1774,530],{"class":508},[502,1776,1330],{"class":584},[502,1778,581],{"class":508},[502,1780,590],{"class":508},[502,1782,1337],{"class":661},[502,1784,590],{"class":508},[502,1786,530],{"class":508},[502,1788,1344],{"class":584},[502,1790,581],{"class":508},[502,1792,590],{"class":508},[502,1794,1795],{"class":1351}," false",[502,1797,590],{"class":508},[502,1799,1337],{"class":661},[502,1801,590],{"class":508},[502,1803,611],{"class":508},[502,1805,614],{"class":508},[502,1807,1808,1810,1812,1814,1816,1818,1820,1822,1824,1826,1828,1830,1832,1834,1836,1838,1840,1842,1844,1846,1848,1850,1852,1854,1856,1858,1860,1862],{"class":504,"line":899},[502,1809,620],{"class":563},[502,1811,99],{"class":508},[502,1813,1304],{"class":550},[502,1815,578],{"class":508},[502,1817,893],{"class":661},[502,1819,590],{"class":508},[502,1821,1314],{"class":661},[502,1823,590],{"class":508},[502,1825,1763],{"class":563},[502,1827,1766],{"class":508},[502,1829,1330],{"class":661},[502,1831,1772],{"class":508},[502,1833,530],{"class":508},[502,1835,1330],{"class":584},[502,1837,581],{"class":508},[502,1839,590],{"class":508},[502,1841,1337],{"class":661},[502,1843,590],{"class":508},[502,1845,530],{"class":508},[502,1847,1407],{"class":584},[502,1849,581],{"class":508},[502,1851,590],{"class":508},[502,1853,1795],{"class":1351},[502,1855,590],{"class":508},[502,1857,1337],{"class":661},[502,1859,590],{"class":508},[502,1861,611],{"class":508},[502,1863,614],{"class":508},[502,1865,1866,1868,1870,1872,1874,1876,1878,1880,1882,1884,1886,1889,1891,1893,1895,1897,1899,1901,1903,1905,1907,1909,1911,1913,1915,1917,1919,1921],{"class":504,"line":905},[502,1867,620],{"class":563},[502,1869,99],{"class":508},[502,1871,1304],{"class":550},[502,1873,578],{"class":508},[502,1875,1436],{"class":661},[502,1877,590],{"class":508},[502,1879,1314],{"class":661},[502,1881,590],{"class":508},[502,1883,1763],{"class":563},[502,1885,1766],{"class":508},[502,1887,1888],{"class":661},"2",[502,1890,1772],{"class":508},[502,1892,530],{"class":508},[502,1894,1330],{"class":584},[502,1896,581],{"class":508},[502,1898,590],{"class":508},[502,1900,1337],{"class":661},[502,1902,590],{"class":508},[502,1904,530],{"class":508},[502,1906,1469],{"class":584},[502,1908,581],{"class":508},[502,1910,590],{"class":508},[502,1912,1795],{"class":1351},[502,1914,590],{"class":508},[502,1916,1337],{"class":661},[502,1918,590],{"class":508},[502,1920,611],{"class":508},[502,1922,614],{"class":508},[502,1924,1925,1927,1929,1931,1933,1935,1937,1939,1941,1943,1945,1948,1950,1952,1954,1956,1958,1960,1962,1964,1966,1968,1970,1972,1974,1976,1978,1980],{"class":504,"line":910},[502,1926,620],{"class":563},[502,1928,99],{"class":508},[502,1930,1304],{"class":550},[502,1932,578],{"class":508},[502,1934,1436],{"class":661},[502,1936,590],{"class":508},[502,1938,1314],{"class":661},[502,1940,590],{"class":508},[502,1942,1763],{"class":563},[502,1944,1766],{"class":508},[502,1946,1947],{"class":661},"3",[502,1949,1772],{"class":508},[502,1951,530],{"class":508},[502,1953,1330],{"class":584},[502,1955,581],{"class":508},[502,1957,590],{"class":508},[502,1959,1524],{"class":661},[502,1961,590],{"class":508},[502,1963,530],{"class":508},[502,1965,1469],{"class":584},[502,1967,581],{"class":508},[502,1969,590],{"class":508},[502,1971,1795],{"class":1351},[502,1973,590],{"class":508},[502,1975,1337],{"class":661},[502,1977,590],{"class":508},[502,1979,611],{"class":508},[502,1981,614],{"class":508},[502,1983,1984],{"class":504,"line":927},[502,1985,722],{"class":508},[18,1987,1988],{},"Você calcula as larguras de cabeça, e boa sorte se alguma descrição quebrar.",[18,1990,1991],{},[21,1992,727],{},[493,1994,1996],{"className":495,"code":1995,"language":497,"meta":498,"style":498},"page.AutoRow(func(r *template.RowBuilder) {\n    r.Col(12, func(c *template.ColBuilder) {\n        c.Table(\n            []string{\"Descrição\", \"Qtd.\", \"Preço Unit.\", \"Total\"},\n            [][]string{\n                {\"Desenvolvimento frontend\", \"40 h\", \"R$ 150,00\", \"R$ 6.000,00\"},\n                {\"Desenvolvimento backend\",  \"60 h\", \"R$ 150,00\", \"R$ 9.000,00\"},\n                {\"Design de UI\",             \"20 h\", \"R$ 120,00\", \"R$ 2.400,00\"},\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,1997,1998,2023,2054,2066,2108,2117,2154,2190,2226,2231,2262,2273,2285,2305,2331,2336,2360,2365,2369],{"__ignoreMap":498},[502,1999,2000,2003,2005,2007,2009,2011,2013,2015,2017,2019,2021],{"class":504,"line":505},[502,2001,2002],{"class":563},"page",[502,2004,99],{"class":508},[502,2006,935],{"class":550},[502,2008,938],{"class":508},[502,2010,942],{"class":941},[502,2012,945],{"class":508},[502,2014,948],{"class":512},[502,2016,99],{"class":508},[502,2018,953],{"class":512},[502,2020,216],{"class":508},[502,2022,557],{"class":508},[502,2024,2025,2028,2030,2032,2034,2036,2038,2040,2042,2044,2046,2048,2050,2052],{"class":504,"line":516},[502,2026,2027],{"class":563},"    r",[502,2029,99],{"class":508},[502,2031,968],{"class":550},[502,2033,578],{"class":508},[502,2035,973],{"class":661},[502,2037,590],{"class":508},[502,2039,978],{"class":508},[502,2041,981],{"class":941},[502,2043,945],{"class":508},[502,2045,948],{"class":512},[502,2047,99],{"class":508},[502,2049,990],{"class":512},[502,2051,216],{"class":508},[502,2053,557],{"class":508},[502,2055,2056,2059,2061,2064],{"class":504,"line":523},[502,2057,2058],{"class":563},"        c",[502,2060,99],{"class":508},[502,2062,2063],{"class":550},"Table",[502,2065,837],{"class":508},[502,2067,2068,2071,2073,2076,2078,2080,2082,2084,2086,2088,2090,2092,2094,2096,2098,2100,2102,2104,2106],{"class":504,"line":539},[502,2069,2070],{"class":508},"            []",[502,2072,1590],{"class":1589},[502,2074,2075],{"class":508},"{",[502,2077,581],{"class":508},[502,2079,1321],{"class":584},[502,2081,581],{"class":508},[502,2083,590],{"class":508},[502,2085,530],{"class":508},[502,2087,1385],{"class":584},[502,2089,581],{"class":508},[502,2091,590],{"class":508},[502,2093,530],{"class":508},[502,2095,1447],{"class":584},[502,2097,581],{"class":508},[502,2099,590],{"class":508},[502,2101,530],{"class":508},[502,2103,1508],{"class":584},[502,2105,581],{"class":508},[502,2107,1635],{"class":508},[502,2109,2110,2113,2115],{"class":504,"line":544},[502,2111,2112],{"class":508},"            [][]",[502,2114,1590],{"class":1589},[502,2116,1593],{"class":508},[502,2118,2119,2122,2124,2126,2128,2130,2132,2134,2136,2138,2140,2142,2144,2146,2148,2150,2152],{"class":504,"line":560},[502,2120,2121],{"class":508},"                {",[502,2123,581],{"class":508},[502,2125,1603],{"class":584},[502,2127,581],{"class":508},[502,2129,590],{"class":508},[502,2131,530],{"class":508},[502,2133,1612],{"class":584},[502,2135,581],{"class":508},[502,2137,590],{"class":508},[502,2139,530],{"class":508},[502,2141,1621],{"class":584},[502,2143,581],{"class":508},[502,2145,590],{"class":508},[502,2147,530],{"class":508},[502,2149,1630],{"class":584},[502,2151,581],{"class":508},[502,2153,1635],{"class":508},[502,2155,2156,2158,2160,2162,2164,2166,2168,2170,2172,2174,2176,2178,2180,2182,2184,2186,2188],{"class":504,"line":617},[502,2157,2121],{"class":508},[502,2159,581],{"class":508},[502,2161,1644],{"class":584},[502,2163,581],{"class":508},[502,2165,590],{"class":508},[502,2167,1454],{"class":508},[502,2169,1653],{"class":584},[502,2171,581],{"class":508},[502,2173,590],{"class":508},[502,2175,530],{"class":508},[502,2177,1621],{"class":584},[502,2179,581],{"class":508},[502,2181,590],{"class":508},[502,2183,530],{"class":508},[502,2185,1670],{"class":584},[502,2187,581],{"class":508},[502,2189,1635],{"class":508},[502,2191,2192,2194,2196,2198,2200,2202,2204,2206,2208,2210,2212,2214,2216,2218,2220,2222,2224],{"class":504,"line":631},[502,2193,2121],{"class":508},[502,2195,581],{"class":508},[502,2197,1683],{"class":584},[502,2199,581],{"class":508},[502,2201,590],{"class":508},[502,2203,1690],{"class":508},[502,2205,1693],{"class":584},[502,2207,581],{"class":508},[502,2209,590],{"class":508},[502,2211,530],{"class":508},[502,2213,1702],{"class":584},[502,2215,581],{"class":508},[502,2217,590],{"class":508},[502,2219,530],{"class":508},[502,2221,1711],{"class":584},[502,2223,581],{"class":508},[502,2225,1635],{"class":508},[502,2227,2228],{"class":504,"line":667},[502,2229,2230],{"class":508},"            },\n",[502,2232,2233,2236,2238,2241,2243,2246,2248,2251,2253,2255,2257,2260],{"class":504,"line":698},[502,2234,2235],{"class":563},"            template",[502,2237,99],{"class":508},[502,2239,2240],{"class":550},"ColumnWidths",[502,2242,578],{"class":508},[502,2244,2245],{"class":661},"50",[502,2247,590],{"class":508},[502,2249,2250],{"class":661}," 15",[502,2252,590],{"class":508},[502,2254,2250],{"class":661},[502,2256,590],{"class":508},[502,2258,2259],{"class":661}," 20",[502,2261,860],{"class":508},[502,2263,2264,2266,2268,2271],{"class":504,"line":719},[502,2265,2235],{"class":563},[502,2267,99],{"class":508},[502,2269,2270],{"class":550},"TableHeaderStyle",[502,2272,837],{"class":508},[502,2274,2275,2278,2280,2282],{"class":504,"line":810},[502,2276,2277],{"class":563},"                template",[502,2279,99],{"class":508},[502,2281,1038],{"class":550},[502,2283,2284],{"class":508},"(),\n",[502,2286,2287,2289,2291,2294,2296,2298,2300,2303],{"class":504,"line":821},[502,2288,2277],{"class":563},[502,2290,99],{"class":508},[502,2292,2293],{"class":550},"TextColor",[502,2295,578],{"class":508},[502,2297,1243],{"class":563},[502,2299,99],{"class":508},[502,2301,2302],{"class":563},"White",[502,2304,860],{"class":508},[502,2306,2307,2309,2311,2314,2316,2318,2320,2323,2325,2328],{"class":504,"line":840},[502,2308,2277],{"class":563},[502,2310,99],{"class":508},[502,2312,2313],{"class":550},"BgColor",[502,2315,578],{"class":508},[502,2317,1243],{"class":563},[502,2319,99],{"class":508},[502,2321,2322],{"class":550},"RGBHex",[502,2324,578],{"class":508},[502,2326,2327],{"class":661},"0x1A237E",[502,2329,2330],{"class":508},")),\n",[502,2332,2333],{"class":504,"line":863},[502,2334,2335],{"class":508},"            ),\n",[502,2337,2338,2340,2342,2345,2347,2349,2351,2353,2355,2358],{"class":504,"line":899},[502,2339,2235],{"class":563},[502,2341,99],{"class":508},[502,2343,2344],{"class":550},"TableStripe",[502,2346,578],{"class":508},[502,2348,1243],{"class":563},[502,2350,99],{"class":508},[502,2352,2322],{"class":550},[502,2354,578],{"class":508},[502,2356,2357],{"class":661},"0xF5F5F5",[502,2359,2330],{"class":508},[502,2361,2362],{"class":504,"line":905},[502,2363,2364],{"class":508},"        )\n",[502,2366,2367],{"class":504,"line":910},[502,2368,1053],{"class":508},[502,2370,2371],{"class":504,"line":927},[502,2372,2373],{"class":508},"})\n",[18,2375,2376,2379,2380,2383,2384,2387,2388,2390],{},[26,2377,2378],{},"ColumnWidths(50, 15, 15, 20)"," são ",[21,2381,2382],{},"porcentagens da coluna em que a tabela vive",", não milímetros absolutos. Jogue a mesma tabela dentro de um ",[26,2385,2386],{},"r.Col(6, ...)"," e as mesmas porcentagens continuam funcionando. Esse é o tipo de coisa que não sai do ",[26,2389,1304],{}," sem um wrapper.",[18,2392,2393],{},"Quebra de linha automática. Quebra de página automática — se a tabela passar da margem inferior, o cabeçalho se repete na página seguinte.",[13,2395,2397],{"id":2396},"antes-depois-3-texto-cjk-sem-a-dança-ritual","Antes / Depois 3: texto CJK sem a dança ritual",[18,2399,2400,2401,2403],{},"Esse é o que me fez largar o gofpdf. Para renderizar japonês em gofpdf você chama ",[26,2402,28],{},", aponta para um TTF no disco, define a fonte e reza. O subsetting funciona na maior parte do tempo. Alguns TTFs disparam colisão de glyph-id e produzem caracteres corrompidos. As mensagens de erro não ajudam.",[18,2405,2406],{},[21,2407,491],{},[493,2409,2411],{"className":495,"code":2410,"language":497,"meta":498,"style":498},"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,2412,2413,2456,2488,2498,2525,2552],{"__ignoreMap":498},[502,2414,2415,2418,2420,2422,2424,2426,2428,2430,2432,2434,2436,2438,2440,2442,2444,2446,2448,2450,2452,2454],{"class":504,"line":505},[502,2416,2417],{"class":563},"pdf ",[502,2419,567],{"class":508},[502,2421,570],{"class":563},[502,2423,99],{"class":508},[502,2425,575],{"class":550},[502,2427,578],{"class":508},[502,2429,581],{"class":508},[502,2431,585],{"class":584},[502,2433,581],{"class":508},[502,2435,590],{"class":508},[502,2437,530],{"class":508},[502,2439,595],{"class":584},[502,2441,581],{"class":508},[502,2443,590],{"class":508},[502,2445,530],{"class":508},[502,2447,604],{"class":584},[502,2449,581],{"class":508},[502,2451,590],{"class":508},[502,2453,611],{"class":508},[502,2455,614],{"class":508},[502,2457,2458,2460,2462,2464,2466,2468,2471,2473,2475,2477,2479,2481,2484,2486],{"class":504,"line":516},[502,2459,1243],{"class":563},[502,2461,99],{"class":508},[502,2463,28],{"class":550},[502,2465,578],{"class":508},[502,2467,581],{"class":508},[502,2469,2470],{"class":584},"notosansjp",[502,2472,581],{"class":508},[502,2474,590],{"class":508},[502,2476,611],{"class":508},[502,2478,590],{"class":508},[502,2480,530],{"class":508},[502,2482,2483],{"class":584},"NotoSansJP-Regular.ttf",[502,2485,581],{"class":508},[502,2487,614],{"class":508},[502,2489,2490,2492,2494,2496],{"class":504,"line":523},[502,2491,1243],{"class":563},[502,2493,99],{"class":508},[502,2495,625],{"class":550},[502,2497,628],{"class":508},[502,2499,2500,2502,2504,2506,2508,2510,2512,2514,2516,2518,2520,2523],{"class":504,"line":539},[502,2501,1243],{"class":563},[502,2503,99],{"class":508},[502,2505,638],{"class":550},[502,2507,578],{"class":508},[502,2509,581],{"class":508},[502,2511,2470],{"class":584},[502,2513,581],{"class":508},[502,2515,590],{"class":508},[502,2517,611],{"class":508},[502,2519,590],{"class":508},[502,2521,2522],{"class":661}," 14",[502,2524,614],{"class":508},[502,2526,2527,2529,2531,2533,2535,2537,2539,2541,2543,2545,2548,2550],{"class":504,"line":544},[502,2528,1243],{"class":563},[502,2530,99],{"class":508},[502,2532,674],{"class":550},[502,2534,578],{"class":508},[502,2536,1769],{"class":661},[502,2538,590],{"class":508},[502,2540,684],{"class":661},[502,2542,590],{"class":508},[502,2544,530],{"class":508},[502,2546,2547],{"class":584},"こんにちは、世界。",[502,2549,581],{"class":508},[502,2551,614],{"class":508},[502,2553,2554,2556,2558,2560,2562,2564,2567,2569],{"class":504,"line":560},[502,2555,1243],{"class":563},[502,2557,99],{"class":508},[502,2559,705],{"class":550},[502,2561,578],{"class":508},[502,2563,581],{"class":508},[502,2565,2566],{"class":584},"ja.pdf",[502,2568,581],{"class":508},[502,2570,614],{"class":508},[18,2572,2573,2574,2576,2577,2579],{},"Duas minas. O TTF precisa existir no caminho dado em tempo de execução (então sua imagem Docker tem que carregar a fonte). E ",[26,2575,674],{}," com largura ",[26,2578,1769],{}," significa \"até a margem direita\", o que em CJK frequentemente corta porque o estimador de largura não conta corretamente os glifos de largura total.",[18,2581,2582],{},[21,2583,727],{},[493,2585,2587],{"className":495,"code":2586,"language":497,"meta":498,"style":498},"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,2588,2589,2595,2599,2605,2613,2621,2625,2633,2641,2649,2653,2657,2667,2695,2707,2721,2725,2729,2743,2761,2791,2816,2839,2843,2847,2861,2885,2915,2933,2952,2971,2975,2979,2984,3004,3032],{"__ignoreMap":498},[502,2590,2591,2593],{"class":504,"line":505},[502,2592,509],{"class":508},[502,2594,513],{"class":512},[502,2596,2597],{"class":504,"line":516},[502,2598,520],{"emptyLinePlaceholder":519},[502,2600,2601,2603],{"class":504,"line":523},[502,2602,527],{"class":526},[502,2604,749],{"class":508},[502,2606,2607,2609,2611],{"class":504,"line":539},[502,2608,754],{"class":508},[502,2610,757],{"class":512},[502,2612,536],{"class":508},[502,2614,2615,2617,2619],{"class":504,"line":544},[502,2616,754],{"class":508},[502,2618,766],{"class":512},[502,2620,536],{"class":508},[502,2622,2623],{"class":504,"line":560},[502,2624,520],{"emptyLinePlaceholder":519},[502,2626,2627,2629,2631],{"class":504,"line":617},[502,2628,754],{"class":508},[502,2630,779],{"class":512},[502,2632,536],{"class":508},[502,2634,2635,2637,2639],{"class":504,"line":631},[502,2636,754],{"class":508},[502,2638,788],{"class":512},[502,2640,536],{"class":508},[502,2642,2643,2645,2647],{"class":504,"line":667},[502,2644,754],{"class":508},[502,2646,797],{"class":512},[502,2648,536],{"class":508},[502,2650,2651],{"class":504,"line":698},[502,2652,614],{"class":508},[502,2654,2655],{"class":504,"line":719},[502,2656,520],{"emptyLinePlaceholder":519},[502,2658,2659,2661,2663,2665],{"class":504,"line":810},[502,2660,547],{"class":508},[502,2662,551],{"class":550},[502,2664,554],{"class":508},[502,2666,557],{"class":508},[502,2668,2669,2672,2674,2676,2678,2680,2682,2685,2687,2689,2691,2693],{"class":504,"line":821},[502,2670,2671],{"class":563},"    fontData",[502,2673,590],{"class":508},[502,2675,1069],{"class":563},[502,2677,567],{"class":508},[502,2679,1132],{"class":563},[502,2681,99],{"class":508},[502,2683,2684],{"class":550},"ReadFile",[502,2686,578],{"class":508},[502,2688,581],{"class":508},[502,2690,2483],{"class":584},[502,2692,581],{"class":508},[502,2694,614],{"class":508},[502,2696,2697,2699,2701,2703,2705],{"class":504,"line":840},[502,2698,1086],{"class":526},[502,2700,1069],{"class":563},[502,2702,1091],{"class":508},[502,2704,1094],{"class":508},[502,2706,557],{"class":508},[502,2708,2709,2711,2713,2715,2717,2719],{"class":504,"line":863},[502,2710,1102],{"class":563},[502,2712,99],{"class":508},[502,2714,1107],{"class":550},[502,2716,578],{"class":508},[502,2718,1112],{"class":563},[502,2720,614],{"class":508},[502,2722,2723],{"class":504,"line":899},[502,2724,1120],{"class":508},[502,2726,2727],{"class":504,"line":905},[502,2728,520],{"emptyLinePlaceholder":519},[502,2730,2731,2733,2735,2737,2739,2741],{"class":504,"line":910},[502,2732,824],{"class":563},[502,2734,567],{"class":508},[502,2736,829],{"class":563},[502,2738,99],{"class":508},[502,2740,834],{"class":550},[502,2742,837],{"class":508},[502,2744,2745,2747,2749,2751,2753,2755,2757,2759],{"class":504,"line":927},[502,2746,843],{"class":563},[502,2748,99],{"class":508},[502,2750,848],{"class":550},[502,2752,578],{"class":508},[502,2754,853],{"class":563},[502,2756,99],{"class":508},[502,2758,604],{"class":563},[502,2760,860],{"class":508},[502,2762,2763,2765,2767,2769,2771,2773,2775,2777,2779,2781,2783,2785,2787,2789],{"class":504,"line":960},[502,2764,843],{"class":563},[502,2766,99],{"class":508},[502,2768,870],{"class":550},[502,2770,578],{"class":508},[502,2772,853],{"class":563},[502,2774,99],{"class":508},[502,2776,879],{"class":550},[502,2778,578],{"class":508},[502,2780,853],{"class":563},[502,2782,99],{"class":508},[502,2784,888],{"class":550},[502,2786,578],{"class":508},[502,2788,893],{"class":661},[502,2790,896],{"class":508},[502,2792,2793,2795,2797,2800,2802,2804,2807,2809,2811,2814],{"class":504,"line":997},[502,2794,843],{"class":563},[502,2796,99],{"class":508},[502,2798,2799],{"class":550},"WithFont",[502,2801,578],{"class":508},[502,2803,581],{"class":508},[502,2805,2806],{"class":584},"NotoSansJP",[502,2808,581],{"class":508},[502,2810,590],{"class":508},[502,2812,2813],{"class":563}," fontData",[502,2815,860],{"class":508},[502,2817,2818,2820,2822,2825,2827,2829,2831,2833,2835,2837],{"class":504,"line":1044},[502,2819,843],{"class":563},[502,2821,99],{"class":508},[502,2823,2824],{"class":550},"WithDefaultFont",[502,2826,578],{"class":508},[502,2828,581],{"class":508},[502,2830,2806],{"class":584},[502,2832,581],{"class":508},[502,2834,590],{"class":508},[502,2836,2522],{"class":661},[502,2838,860],{"class":508},[502,2840,2841],{"class":504,"line":1050},[502,2842,902],{"class":508},[502,2844,2845],{"class":504,"line":1056},[502,2846,520],{"emptyLinePlaceholder":519},[502,2848,2849,2851,2853,2855,2857,2859],{"class":504,"line":1061},[502,2850,913],{"class":563},[502,2852,567],{"class":508},[502,2854,918],{"class":563},[502,2856,99],{"class":508},[502,2858,625],{"class":550},[502,2860,628],{"class":508},[502,2862,2863,2865,2867,2869,2871,2873,2875,2877,2879,2881,2883],{"class":504,"line":1083},[502,2864,930],{"class":563},[502,2866,99],{"class":508},[502,2868,935],{"class":550},[502,2870,938],{"class":508},[502,2872,942],{"class":941},[502,2874,945],{"class":508},[502,2876,948],{"class":512},[502,2878,99],{"class":508},[502,2880,953],{"class":512},[502,2882,216],{"class":508},[502,2884,557],{"class":508},[502,2886,2887,2889,2891,2893,2895,2897,2899,2901,2903,2905,2907,2909,2911,2913],{"class":504,"line":1099},[502,2888,963],{"class":563},[502,2890,99],{"class":508},[502,2892,968],{"class":550},[502,2894,578],{"class":508},[502,2896,973],{"class":661},[502,2898,590],{"class":508},[502,2900,978],{"class":508},[502,2902,981],{"class":941},[502,2904,945],{"class":508},[502,2906,948],{"class":512},[502,2908,99],{"class":508},[502,2910,990],{"class":512},[502,2912,216],{"class":508},[502,2914,557],{"class":508},[502,2916,2917,2919,2921,2923,2925,2927,2929,2931],{"class":504,"line":1117},[502,2918,1000],{"class":563},[502,2920,99],{"class":508},[502,2922,1005],{"class":550},[502,2924,578],{"class":508},[502,2926,581],{"class":508},[502,2928,2547],{"class":584},[502,2930,581],{"class":508},[502,2932,614],{"class":508},[502,2934,2935,2937,2939,2941,2943,2945,2948,2950],{"class":504,"line":1123},[502,2936,1000],{"class":563},[502,2938,99],{"class":508},[502,2940,1005],{"class":550},[502,2942,578],{"class":508},[502,2944,581],{"class":508},[502,2946,2947],{"class":584},"吾輩は猫である。名前はまだ無い。",[502,2949,581],{"class":508},[502,2951,614],{"class":508},[502,2953,2954,2956,2958,2960,2962,2964,2967,2969],{"class":504,"line":1169},[502,2955,1000],{"class":563},[502,2957,99],{"class":508},[502,2959,1005],{"class":550},[502,2961,578],{"class":508},[502,2963,581],{"class":508},[502,2965,2966],{"class":584},"東京都渋谷区神宮前1-2-3",[502,2968,581],{"class":508},[502,2970,614],{"class":508},[502,2972,2973],{"class":504,"line":1184},[502,2974,1047],{"class":508},[502,2976,2977],{"class":504,"line":1189},[502,2978,1053],{"class":508},[502,2980,2982],{"class":504,"line":2981},33,[502,2983,520],{"emptyLinePlaceholder":519},[502,2985,2987,2989,2991,2994,2996,2998,3000,3002],{"class":504,"line":2986},34,[502,2988,1064],{"class":563},[502,2990,590],{"class":508},[502,2992,2993],{"class":563}," _ ",[502,2995,567],{"class":508},[502,2997,918],{"class":563},[502,2999,99],{"class":508},[502,3001,1078],{"class":550},[502,3003,628],{"class":508},[502,3005,3007,3010,3012,3014,3016,3018,3020,3022,3024,3026,3028,3030],{"class":504,"line":3006},35,[502,3008,3009],{"class":563},"    os",[502,3011,99],{"class":508},[502,3013,1137],{"class":550},[502,3015,578],{"class":508},[502,3017,581],{"class":508},[502,3019,2566],{"class":584},[502,3021,581],{"class":508},[502,3023,590],{"class":508},[502,3025,1150],{"class":563},[502,3027,590],{"class":508},[502,3029,1155],{"class":661},[502,3031,614],{"class":508},[502,3033,3035],{"class":504,"line":3034},36,[502,3036,722],{"class":508},[18,3038,3039],{},"Duas diferenças.",[18,3041,3042,3043,3046,3047,3050],{},"Primeira: você passa ",[21,3044,3045],{},"bytes",", não um caminho. Embute o TTF com ",[26,3048,3049],{},"//go:embed"," e seu binário fica autocontido. Nada de \"font not found\" em produção porque alguém esqueceu de montar um volume.",[18,3052,3053],{},"Segunda: o subsetter TrueType do gpdf entende os formatos cmap de CJK (4, 6, 12) e a codificação Identity-H. O PDF de saída carrega apenas os glifos que você realmente usou — embutir NotoSansJP para uma nota de 200 caracteres dá um subset de ~30 KB, não um embed cheio de 4 MB. Se você já viu o gofpdf produzir um PDF de 5 MB para uma página em japonês, essa é a primeira coisa que você nota.",[18,3055,3056],{},"Para um tour mais profundo de opções específicas de CJK — IPAex Gothic, Source Han Sans, cadeias de fallback — veja o post complementar que vem.",[13,3058,3060],{"id":3059},"antes-depois-4-cabeçalho-em-cada-página-número-no-rodapé","Antes / Depois 4: cabeçalho em cada página, número no rodapé",[18,3062,3063,3064,112,3067,3070,3071,3074,3075,112,3077,99],{},"O padrão do gofpdf para cromo repetido é ",[26,3065,3066],{},"SetHeaderFunc",[26,3068,3069],{},"SetFooterFunc"," — ambos recebem um ",[26,3072,3073],{},"func()"," que roda contra o cursor atual. Números de página vêm de ",[26,3076,397],{},[26,3078,3079],{},"pdf.AliasNbPages()",[18,3081,3082],{},[21,3083,491],{},[493,3085,3087],{"className":495,"code":3086,"language":497,"meta":498,"style":498},"pdf := gofpdf.New(\"P\", \"mm\", \"A4\", \"\")\npdf.SetHeaderFunc(func() {\n    pdf.SetFont(\"Arial\", \"B\", 12)\n    pdf.Cell(0, 10, \"ACME Ltda.\")\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(\"Página %d/{nb}\", pdf.PageNo()),\n        \"\", 0, \"C\", false, 0, \"\")\n})\npdf.AliasNbPages(\"\")\npdf.AddPage()\n// ... corpo ...\n",[26,3088,3089,3131,3144,3175,3202,3218,3222,3234,3250,3281,3300,3339,3370,3374,3390,3400],{"__ignoreMap":498},[502,3090,3091,3093,3095,3097,3099,3101,3103,3105,3107,3109,3111,3113,3115,3117,3119,3121,3123,3125,3127,3129],{"class":504,"line":505},[502,3092,2417],{"class":563},[502,3094,567],{"class":508},[502,3096,570],{"class":563},[502,3098,99],{"class":508},[502,3100,575],{"class":550},[502,3102,578],{"class":508},[502,3104,581],{"class":508},[502,3106,585],{"class":584},[502,3108,581],{"class":508},[502,3110,590],{"class":508},[502,3112,530],{"class":508},[502,3114,595],{"class":584},[502,3116,581],{"class":508},[502,3118,590],{"class":508},[502,3120,530],{"class":508},[502,3122,604],{"class":584},[502,3124,581],{"class":508},[502,3126,590],{"class":508},[502,3128,611],{"class":508},[502,3130,614],{"class":508},[502,3132,3133,3135,3137,3139,3142],{"class":504,"line":516},[502,3134,1243],{"class":563},[502,3136,99],{"class":508},[502,3138,3066],{"class":550},[502,3140,3141],{"class":508},"(func()",[502,3143,557],{"class":508},[502,3145,3146,3148,3150,3152,3154,3156,3158,3160,3162,3164,3166,3168,3170,3173],{"class":504,"line":523},[502,3147,620],{"class":563},[502,3149,99],{"class":508},[502,3151,638],{"class":550},[502,3153,578],{"class":508},[502,3155,581],{"class":508},[502,3157,645],{"class":584},[502,3159,581],{"class":508},[502,3161,590],{"class":508},[502,3163,530],{"class":508},[502,3165,654],{"class":584},[502,3167,581],{"class":508},[502,3169,590],{"class":508},[502,3171,3172],{"class":661}," 12",[502,3174,614],{"class":508},[502,3176,3177,3179,3181,3183,3185,3187,3189,3191,3193,3195,3198,3200],{"class":504,"line":539},[502,3178,620],{"class":563},[502,3180,99],{"class":508},[502,3182,674],{"class":550},[502,3184,578],{"class":508},[502,3186,1769],{"class":661},[502,3188,590],{"class":508},[502,3190,684],{"class":661},[502,3192,590],{"class":508},[502,3194,530],{"class":508},[502,3196,3197],{"class":584},"ACME Ltda.",[502,3199,581],{"class":508},[502,3201,614],{"class":508},[502,3203,3204,3206,3208,3211,3213,3216],{"class":504,"line":544},[502,3205,620],{"class":563},[502,3207,99],{"class":508},[502,3209,3210],{"class":550},"Ln",[502,3212,578],{"class":508},[502,3214,3215],{"class":661},"15",[502,3217,614],{"class":508},[502,3219,3220],{"class":504,"line":560},[502,3221,2373],{"class":508},[502,3223,3224,3226,3228,3230,3232],{"class":504,"line":617},[502,3225,1243],{"class":563},[502,3227,99],{"class":508},[502,3229,3069],{"class":550},[502,3231,3141],{"class":508},[502,3233,557],{"class":508},[502,3235,3236,3238,3240,3243,3246,3248],{"class":504,"line":631},[502,3237,620],{"class":563},[502,3239,99],{"class":508},[502,3241,3242],{"class":550},"SetY",[502,3244,3245],{"class":508},"(-",[502,3247,3215],{"class":661},[502,3249,614],{"class":508},[502,3251,3252,3254,3256,3258,3260,3262,3264,3266,3268,3270,3273,3275,3277,3279],{"class":504,"line":667},[502,3253,620],{"class":563},[502,3255,99],{"class":508},[502,3257,638],{"class":550},[502,3259,578],{"class":508},[502,3261,581],{"class":508},[502,3263,645],{"class":584},[502,3265,581],{"class":508},[502,3267,590],{"class":508},[502,3269,530],{"class":508},[502,3271,3272],{"class":584},"I",[502,3274,581],{"class":508},[502,3276,590],{"class":508},[502,3278,1314],{"class":661},[502,3280,614],{"class":508},[502,3282,3283,3285,3287,3289,3291,3293,3295,3297],{"class":504,"line":698},[502,3284,620],{"class":563},[502,3286,99],{"class":508},[502,3288,1304],{"class":550},[502,3290,578],{"class":508},[502,3292,1769],{"class":661},[502,3294,590],{"class":508},[502,3296,684],{"class":661},[502,3298,3299],{"class":508},",\n",[502,3301,3302,3305,3307,3310,3312,3314,3317,3321,3324,3326,3328,3331,3333,3336],{"class":504,"line":719},[502,3303,3304],{"class":563},"        fmt",[502,3306,99],{"class":508},[502,3308,3309],{"class":550},"Sprintf",[502,3311,578],{"class":508},[502,3313,581],{"class":508},[502,3315,3316],{"class":584},"Página ",[502,3318,3320],{"class":3319},"swJcz","%d",[502,3322,3323],{"class":584},"/{nb}",[502,3325,581],{"class":508},[502,3327,590],{"class":508},[502,3329,3330],{"class":563}," pdf",[502,3332,99],{"class":508},[502,3334,3335],{"class":550},"PageNo",[502,3337,3338],{"class":508},"()),\n",[502,3340,3341,3344,3346,3348,3350,3352,3354,3356,3358,3360,3362,3364,3366,3368],{"class":504,"line":810},[502,3342,3343],{"class":508},"        \"\"",[502,3345,590],{"class":508},[502,3347,1337],{"class":661},[502,3349,590],{"class":508},[502,3351,530],{"class":508},[502,3353,1407],{"class":584},[502,3355,581],{"class":508},[502,3357,590],{"class":508},[502,3359,1795],{"class":1351},[502,3361,590],{"class":508},[502,3363,1337],{"class":661},[502,3365,590],{"class":508},[502,3367,611],{"class":508},[502,3369,614],{"class":508},[502,3371,3372],{"class":504,"line":821},[502,3373,2373],{"class":508},[502,3375,3376,3378,3380,3383,3385,3388],{"class":504,"line":840},[502,3377,1243],{"class":563},[502,3379,99],{"class":508},[502,3381,3382],{"class":550},"AliasNbPages",[502,3384,578],{"class":508},[502,3386,3387],{"class":508},"\"\"",[502,3389,614],{"class":508},[502,3391,3392,3394,3396,3398],{"class":504,"line":863},[502,3393,1243],{"class":563},[502,3395,99],{"class":508},[502,3397,625],{"class":550},[502,3399,628],{"class":508},[502,3401,3402],{"class":504,"line":899},[502,3403,3405],{"class":3404},"sHwdD","// ... corpo ...\n",[18,3407,3408,3411],{},[26,3409,3410],{},"{nb}"," é uma sentinela que o gofpdf reescreve na saída com o número total de páginas. Funciona, só faz parte daquelas coisas que você precisa saber.",[18,3413,3414],{},[21,3415,727],{},[493,3417,3419],{"className":495,"code":3418,"language":497,"meta":498,"style":498},"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 Ltda.\", 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 Ltda.\",\n                template.FontSize(8), template.TextColor(pdf.Gray(0.5)))\n        })\n        r.Col(6, func(c *template.ColBuilder) {\n            // \"Página X / Y\" — ambas partes são placeholders\n            // resolvidos pelo motor de layout após a paginação.\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(\"Conteúdo da página %d.\", i+1))\n        })\n    })\n}\n",[26,3420,3421,3436,3455,3485,3489,3493,3520,3545,3575,3615,3650,3674,3678,3682,3686,3690,3715,3739,3770,3788,3824,3828,3858,3863,3868,3888,3922,3926,3930,3934,3938,3969,3983,4007,4037,4078,4082,4087],{"__ignoreMap":498},[502,3422,3423,3426,3428,3430,3432,3434],{"class":504,"line":505},[502,3424,3425],{"class":563},"doc ",[502,3427,567],{"class":508},[502,3429,829],{"class":563},[502,3431,99],{"class":508},[502,3433,834],{"class":550},[502,3435,837],{"class":508},[502,3437,3438,3441,3443,3445,3447,3449,3451,3453],{"class":504,"line":516},[502,3439,3440],{"class":563},"    gpdf",[502,3442,99],{"class":508},[502,3444,848],{"class":550},[502,3446,578],{"class":508},[502,3448,853],{"class":563},[502,3450,99],{"class":508},[502,3452,604],{"class":563},[502,3454,860],{"class":508},[502,3456,3457,3459,3461,3463,3465,3467,3469,3471,3473,3475,3477,3479,3481,3483],{"class":504,"line":523},[502,3458,3440],{"class":563},[502,3460,99],{"class":508},[502,3462,870],{"class":550},[502,3464,578],{"class":508},[502,3466,853],{"class":563},[502,3468,99],{"class":508},[502,3470,879],{"class":550},[502,3472,578],{"class":508},[502,3474,853],{"class":563},[502,3476,99],{"class":508},[502,3478,888],{"class":550},[502,3480,578],{"class":508},[502,3482,893],{"class":661},[502,3484,896],{"class":508},[502,3486,3487],{"class":504,"line":539},[502,3488,614],{"class":508},[502,3490,3491],{"class":504,"line":544},[502,3492,520],{"emptyLinePlaceholder":519},[502,3494,3495,3498,3500,3503,3505,3507,3509,3511,3513,3516,3518],{"class":504,"line":560},[502,3496,3497],{"class":563},"doc",[502,3499,99],{"class":508},[502,3501,3502],{"class":550},"Header",[502,3504,938],{"class":508},[502,3506,18],{"class":941},[502,3508,945],{"class":508},[502,3510,948],{"class":512},[502,3512,99],{"class":508},[502,3514,3515],{"class":512},"PageBuilder",[502,3517,216],{"class":508},[502,3519,557],{"class":508},[502,3521,3522,3525,3527,3529,3531,3533,3535,3537,3539,3541,3543],{"class":504,"line":617},[502,3523,3524],{"class":563},"    p",[502,3526,99],{"class":508},[502,3528,935],{"class":550},[502,3530,938],{"class":508},[502,3532,942],{"class":941},[502,3534,945],{"class":508},[502,3536,948],{"class":512},[502,3538,99],{"class":508},[502,3540,953],{"class":512},[502,3542,216],{"class":508},[502,3544,557],{"class":508},[502,3546,3547,3549,3551,3553,3555,3557,3559,3561,3563,3565,3567,3569,3571,3573],{"class":504,"line":631},[502,3548,963],{"class":563},[502,3550,99],{"class":508},[502,3552,968],{"class":550},[502,3554,578],{"class":508},[502,3556,973],{"class":661},[502,3558,590],{"class":508},[502,3560,978],{"class":508},[502,3562,981],{"class":941},[502,3564,945],{"class":508},[502,3566,948],{"class":512},[502,3568,99],{"class":508},[502,3570,990],{"class":512},[502,3572,216],{"class":508},[502,3574,557],{"class":508},[502,3576,3577,3579,3581,3583,3585,3587,3589,3591,3593,3595,3597,3599,3602,3604,3606,3608,3610,3612],{"class":504,"line":667},[502,3578,1000],{"class":563},[502,3580,99],{"class":508},[502,3582,1005],{"class":550},[502,3584,578],{"class":508},[502,3586,581],{"class":508},[502,3588,3197],{"class":584},[502,3590,581],{"class":508},[502,3592,590],{"class":508},[502,3594,1018],{"class":563},[502,3596,99],{"class":508},[502,3598,1038],{"class":550},[502,3600,3601],{"class":508},"(),",[502,3603,1018],{"class":563},[502,3605,99],{"class":508},[502,3607,1023],{"class":550},[502,3609,578],{"class":508},[502,3611,973],{"class":661},[502,3613,3614],{"class":508},"))\n",[502,3616,3617,3619,3621,3624,3626,3628,3630,3633,3635,3637,3639,3642,3644,3647],{"class":504,"line":698},[502,3618,1000],{"class":563},[502,3620,99],{"class":508},[502,3622,3623],{"class":550},"Line",[502,3625,578],{"class":508},[502,3627,948],{"class":563},[502,3629,99],{"class":508},[502,3631,3632],{"class":550},"LineColor",[502,3634,578],{"class":508},[502,3636,1243],{"class":563},[502,3638,99],{"class":508},[502,3640,3641],{"class":550},"Gray",[502,3643,578],{"class":508},[502,3645,3646],{"class":661},"0.7",[502,3648,3649],{"class":508},")))\n",[502,3651,3652,3654,3656,3659,3661,3663,3665,3667,3669,3672],{"class":504,"line":719},[502,3653,1000],{"class":563},[502,3655,99],{"class":508},[502,3657,3658],{"class":550},"Spacer",[502,3660,578],{"class":508},[502,3662,853],{"class":563},[502,3664,99],{"class":508},[502,3666,888],{"class":550},[502,3668,578],{"class":508},[502,3670,3671],{"class":661},"4",[502,3673,3614],{"class":508},[502,3675,3676],{"class":504,"line":810},[502,3677,1047],{"class":508},[502,3679,3680],{"class":504,"line":821},[502,3681,1053],{"class":508},[502,3683,3684],{"class":504,"line":840},[502,3685,2373],{"class":508},[502,3687,3688],{"class":504,"line":863},[502,3689,520],{"emptyLinePlaceholder":519},[502,3691,3692,3694,3696,3699,3701,3703,3705,3707,3709,3711,3713],{"class":504,"line":899},[502,3693,3497],{"class":563},[502,3695,99],{"class":508},[502,3697,3698],{"class":550},"Footer",[502,3700,938],{"class":508},[502,3702,18],{"class":941},[502,3704,945],{"class":508},[502,3706,948],{"class":512},[502,3708,99],{"class":508},[502,3710,3515],{"class":512},[502,3712,216],{"class":508},[502,3714,557],{"class":508},[502,3716,3717,3719,3721,3723,3725,3727,3729,3731,3733,3735,3737],{"class":504,"line":905},[502,3718,3524],{"class":563},[502,3720,99],{"class":508},[502,3722,935],{"class":550},[502,3724,938],{"class":508},[502,3726,942],{"class":941},[502,3728,945],{"class":508},[502,3730,948],{"class":512},[502,3732,99],{"class":508},[502,3734,953],{"class":512},[502,3736,216],{"class":508},[502,3738,557],{"class":508},[502,3740,3741,3743,3745,3747,3749,3752,3754,3756,3758,3760,3762,3764,3766,3768],{"class":504,"line":910},[502,3742,963],{"class":563},[502,3744,99],{"class":508},[502,3746,968],{"class":550},[502,3748,578],{"class":508},[502,3750,3751],{"class":661},"6",[502,3753,590],{"class":508},[502,3755,978],{"class":508},[502,3757,981],{"class":941},[502,3759,945],{"class":508},[502,3761,948],{"class":512},[502,3763,99],{"class":508},[502,3765,990],{"class":512},[502,3767,216],{"class":508},[502,3769,557],{"class":508},[502,3771,3772,3774,3776,3778,3780,3782,3784,3786],{"class":504,"line":927},[502,3773,1000],{"class":563},[502,3775,99],{"class":508},[502,3777,1005],{"class":550},[502,3779,578],{"class":508},[502,3781,581],{"class":508},[502,3783,3197],{"class":584},[502,3785,581],{"class":508},[502,3787,3299],{"class":508},[502,3789,3790,3792,3794,3796,3798,3801,3803,3805,3807,3809,3811,3813,3815,3817,3819,3822],{"class":504,"line":960},[502,3791,2277],{"class":563},[502,3793,99],{"class":508},[502,3795,1023],{"class":550},[502,3797,578],{"class":508},[502,3799,3800],{"class":661},"8",[502,3802,1031],{"class":508},[502,3804,1018],{"class":563},[502,3806,99],{"class":508},[502,3808,2293],{"class":550},[502,3810,578],{"class":508},[502,3812,1243],{"class":563},[502,3814,99],{"class":508},[502,3816,3641],{"class":550},[502,3818,578],{"class":508},[502,3820,3821],{"class":661},"0.5",[502,3823,3649],{"class":508},[502,3825,3826],{"class":504,"line":997},[502,3827,1047],{"class":508},[502,3829,3830,3832,3834,3836,3838,3840,3842,3844,3846,3848,3850,3852,3854,3856],{"class":504,"line":1044},[502,3831,963],{"class":563},[502,3833,99],{"class":508},[502,3835,968],{"class":550},[502,3837,578],{"class":508},[502,3839,3751],{"class":661},[502,3841,590],{"class":508},[502,3843,978],{"class":508},[502,3845,981],{"class":941},[502,3847,945],{"class":508},[502,3849,948],{"class":512},[502,3851,99],{"class":508},[502,3853,990],{"class":512},[502,3855,216],{"class":508},[502,3857,557],{"class":508},[502,3859,3860],{"class":504,"line":1050},[502,3861,3862],{"class":3404},"            // \"Página X / Y\" — ambas partes são placeholders\n",[502,3864,3865],{"class":504,"line":1056},[502,3866,3867],{"class":3404},"            // resolvidos pelo motor de layout após a paginação.\n",[502,3869,3870,3872,3874,3877,3879,3881,3883,3886],{"class":504,"line":1061},[502,3871,1000],{"class":563},[502,3873,99],{"class":508},[502,3875,3876],{"class":550},"PageNumber",[502,3878,578],{"class":508},[502,3880,948],{"class":563},[502,3882,99],{"class":508},[502,3884,3885],{"class":550},"AlignRight",[502,3887,2284],{"class":508},[502,3889,3890,3892,3894,3896,3898,3900,3902,3904,3906,3908,3910,3912,3914,3916,3918,3920],{"class":504,"line":1083},[502,3891,2277],{"class":563},[502,3893,99],{"class":508},[502,3895,1023],{"class":550},[502,3897,578],{"class":508},[502,3899,3800],{"class":661},[502,3901,1031],{"class":508},[502,3903,1018],{"class":563},[502,3905,99],{"class":508},[502,3907,2293],{"class":550},[502,3909,578],{"class":508},[502,3911,1243],{"class":563},[502,3913,99],{"class":508},[502,3915,3641],{"class":550},[502,3917,578],{"class":508},[502,3919,3821],{"class":661},[502,3921,3649],{"class":508},[502,3923,3924],{"class":504,"line":1099},[502,3925,1047],{"class":508},[502,3927,3928],{"class":504,"line":1117},[502,3929,1053],{"class":508},[502,3931,3932],{"class":504,"line":1123},[502,3933,2373],{"class":508},[502,3935,3936],{"class":504,"line":1169},[502,3937,520],{"emptyLinePlaceholder":519},[502,3939,3940,3942,3945,3947,3949,3952,3954,3957,3959,3961,3964,3967],{"class":504,"line":1184},[502,3941,1724],{"class":526},[502,3943,3944],{"class":563}," i ",[502,3946,567],{"class":508},[502,3948,1337],{"class":661},[502,3950,3951],{"class":508},";",[502,3953,3944],{"class":563},[502,3955,3956],{"class":508},"\u003C",[502,3958,684],{"class":661},[502,3960,3951],{"class":508},[502,3962,3963],{"class":563}," i",[502,3965,3966],{"class":508},"++",[502,3968,557],{"class":508},[502,3970,3971,3973,3975,3977,3979,3981],{"class":504,"line":1189},[502,3972,913],{"class":563},[502,3974,567],{"class":508},[502,3976,918],{"class":563},[502,3978,99],{"class":508},[502,3980,625],{"class":550},[502,3982,628],{"class":508},[502,3984,3985,3987,3989,3991,3993,3995,3997,3999,4001,4003,4005],{"class":504,"line":2981},[502,3986,930],{"class":563},[502,3988,99],{"class":508},[502,3990,935],{"class":550},[502,3992,938],{"class":508},[502,3994,942],{"class":941},[502,3996,945],{"class":508},[502,3998,948],{"class":512},[502,4000,99],{"class":508},[502,4002,953],{"class":512},[502,4004,216],{"class":508},[502,4006,557],{"class":508},[502,4008,4009,4011,4013,4015,4017,4019,4021,4023,4025,4027,4029,4031,4033,4035],{"class":504,"line":2986},[502,4010,963],{"class":563},[502,4012,99],{"class":508},[502,4014,968],{"class":550},[502,4016,578],{"class":508},[502,4018,973],{"class":661},[502,4020,590],{"class":508},[502,4022,978],{"class":508},[502,4024,981],{"class":941},[502,4026,945],{"class":508},[502,4028,948],{"class":512},[502,4030,99],{"class":508},[502,4032,990],{"class":512},[502,4034,216],{"class":508},[502,4036,557],{"class":508},[502,4038,4039,4041,4043,4045,4047,4050,4052,4054,4056,4058,4061,4063,4065,4067,4069,4071,4074,4076],{"class":504,"line":3006},[502,4040,1000],{"class":563},[502,4042,99],{"class":508},[502,4044,1005],{"class":550},[502,4046,578],{"class":508},[502,4048,4049],{"class":563},"fmt",[502,4051,99],{"class":508},[502,4053,3309],{"class":550},[502,4055,578],{"class":508},[502,4057,581],{"class":508},[502,4059,4060],{"class":584},"Conteúdo da página ",[502,4062,3320],{"class":3319},[502,4064,99],{"class":584},[502,4066,581],{"class":508},[502,4068,590],{"class":508},[502,4070,3963],{"class":563},[502,4072,4073],{"class":508},"+",[502,4075,1330],{"class":661},[502,4077,3614],{"class":508},[502,4079,4080],{"class":504,"line":3034},[502,4081,1047],{"class":508},[502,4083,4085],{"class":504,"line":4084},37,[502,4086,1053],{"class":508},[502,4088,4090],{"class":504,"line":4089},38,[502,4091,722],{"class":508},[18,4093,4094,112,4096,4099,4100,4102,4103,4106],{},[26,4095,3876],{},[26,4097,4098],{},"TotalPages"," são placeholders. Eles se expandem após a paginação, quando o motor de layout já sabe quantas páginas existem. Sem sentinela ",[26,4101,3410],{},", sem ",[26,4104,4105],{},"SetY(-15)"," para cravar o rodapé embaixo — o rodapé é só uma árvore, e o motor reserva espaço para ele em cada página automaticamente.",[13,4108,4110],{"id":4109},"antes-depois-5-produzir-bytes-para-um-handler-http","Antes / Depois 5: produzir bytes para um handler HTTP",[18,4112,4113,4114,4116,4117,4120,4121,4124],{},"A maior parte do código gofpdf em produção não escreve em arquivo. Escreve num ",[26,4115,1214],{}," — geralmente um ",[26,4118,4119],{},"http.ResponseWriter"," retornando ",[26,4122,4123],{},"application/pdf"," para o navegador. Este é o par onde a API do gpdf mais se parece com a do gofpdf.",[18,4126,4127],{},[21,4128,491],{},[493,4130,4132],{"className":495,"code":4131,"language":497,"meta":498,"style":498},"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, \"Gerado em \"+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,4133,4134,4173,4215,4225,4251,4303,4307,4340,4369,4399,4403],{"__ignoreMap":498},[502,4135,4136,4138,4141,4143,4146,4149,4151,4154,4156,4159,4161,4164,4166,4169,4171],{"class":504,"line":505},[502,4137,547],{"class":508},[502,4139,4140],{"class":550}," handler",[502,4142,578],{"class":508},[502,4144,4145],{"class":941},"w",[502,4147,4148],{"class":512}," http",[502,4150,99],{"class":508},[502,4152,4153],{"class":512},"ResponseWriter",[502,4155,590],{"class":508},[502,4157,4158],{"class":941}," r",[502,4160,945],{"class":508},[502,4162,4163],{"class":512},"http",[502,4165,99],{"class":508},[502,4167,4168],{"class":512},"Request",[502,4170,216],{"class":508},[502,4172,557],{"class":508},[502,4174,4175,4177,4179,4181,4183,4185,4187,4189,4191,4193,4195,4197,4199,4201,4203,4205,4207,4209,4211,4213],{"class":504,"line":516},[502,4176,564],{"class":563},[502,4178,567],{"class":508},[502,4180,570],{"class":563},[502,4182,99],{"class":508},[502,4184,575],{"class":550},[502,4186,578],{"class":508},[502,4188,581],{"class":508},[502,4190,585],{"class":584},[502,4192,581],{"class":508},[502,4194,590],{"class":508},[502,4196,530],{"class":508},[502,4198,595],{"class":584},[502,4200,581],{"class":508},[502,4202,590],{"class":508},[502,4204,530],{"class":508},[502,4206,604],{"class":584},[502,4208,581],{"class":508},[502,4210,590],{"class":508},[502,4212,611],{"class":508},[502,4214,614],{"class":508},[502,4216,4217,4219,4221,4223],{"class":504,"line":523},[502,4218,620],{"class":563},[502,4220,99],{"class":508},[502,4222,625],{"class":550},[502,4224,628],{"class":508},[502,4226,4227,4229,4231,4233,4235,4237,4239,4241,4243,4245,4247,4249],{"class":504,"line":539},[502,4228,620],{"class":563},[502,4230,99],{"class":508},[502,4232,638],{"class":550},[502,4234,578],{"class":508},[502,4236,581],{"class":508},[502,4238,645],{"class":584},[502,4240,581],{"class":508},[502,4242,590],{"class":508},[502,4244,611],{"class":508},[502,4246,590],{"class":508},[502,4248,3172],{"class":661},[502,4250,614],{"class":508},[502,4252,4253,4255,4257,4259,4261,4263,4265,4267,4269,4271,4274,4276,4278,4281,4283,4286,4289,4292,4294,4296,4298,4301],{"class":504,"line":544},[502,4254,620],{"class":563},[502,4256,99],{"class":508},[502,4258,674],{"class":550},[502,4260,578],{"class":508},[502,4262,1769],{"class":661},[502,4264,590],{"class":508},[502,4266,684],{"class":661},[502,4268,590],{"class":508},[502,4270,530],{"class":508},[502,4272,4273],{"class":584},"Gerado em ",[502,4275,581],{"class":508},[502,4277,4073],{"class":508},[502,4279,4280],{"class":563},"time",[502,4282,99],{"class":508},[502,4284,4285],{"class":550},"Now",[502,4287,4288],{"class":508},"().",[502,4290,4291],{"class":550},"Format",[502,4293,578],{"class":508},[502,4295,4280],{"class":563},[502,4297,99],{"class":508},[502,4299,4300],{"class":563},"RFC3339",[502,4302,3614],{"class":508},[502,4304,4305],{"class":504,"line":560},[502,4306,520],{"emptyLinePlaceholder":519},[502,4308,4309,4312,4314,4316,4318,4321,4323,4325,4328,4330,4332,4334,4336,4338],{"class":504,"line":617},[502,4310,4311],{"class":563},"    w",[502,4313,99],{"class":508},[502,4315,3502],{"class":550},[502,4317,4288],{"class":508},[502,4319,4320],{"class":550},"Set",[502,4322,578],{"class":508},[502,4324,581],{"class":508},[502,4326,4327],{"class":584},"Content-Type",[502,4329,581],{"class":508},[502,4331,590],{"class":508},[502,4333,530],{"class":508},[502,4335,4123],{"class":584},[502,4337,581],{"class":508},[502,4339,614],{"class":508},[502,4341,4342,4344,4346,4348,4350,4352,4355,4357,4359,4361,4363,4365,4367],{"class":504,"line":631},[502,4343,1086],{"class":526},[502,4345,1069],{"class":563},[502,4347,567],{"class":508},[502,4349,3330],{"class":563},[502,4351,99],{"class":508},[502,4353,4354],{"class":550},"Output",[502,4356,578],{"class":508},[502,4358,4145],{"class":563},[502,4360,1158],{"class":508},[502,4362,1069],{"class":563},[502,4364,1091],{"class":508},[502,4366,1094],{"class":508},[502,4368,557],{"class":508},[502,4370,4371,4374,4376,4379,4381,4383,4385,4388,4390,4392,4394,4397],{"class":504,"line":667},[502,4372,4373],{"class":563},"        http",[502,4375,99],{"class":508},[502,4377,4378],{"class":550},"Error",[502,4380,578],{"class":508},[502,4382,4145],{"class":563},[502,4384,590],{"class":508},[502,4386,4387],{"class":563}," err",[502,4389,99],{"class":508},[502,4391,4378],{"class":550},[502,4393,3601],{"class":508},[502,4395,4396],{"class":661}," 500",[502,4398,614],{"class":508},[502,4400,4401],{"class":504,"line":698},[502,4402,1120],{"class":508},[502,4404,4405],{"class":504,"line":719},[502,4406,722],{"class":508},[18,4408,4409],{},[21,4410,727],{},[493,4412,4414],{"className":495,"code":4413,"language":497,"meta":498,"style":498},"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(\"Gerado em \" + 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,4415,4416,4448,4462,4480,4510,4514,4518,4532,4556,4586,4626,4630,4634,4638,4668,4697,4723,4727],{"__ignoreMap":498},[502,4417,4418,4420,4422,4424,4426,4428,4430,4432,4434,4436,4438,4440,4442,4444,4446],{"class":504,"line":505},[502,4419,547],{"class":508},[502,4421,4140],{"class":550},[502,4423,578],{"class":508},[502,4425,4145],{"class":941},[502,4427,4148],{"class":512},[502,4429,99],{"class":508},[502,4431,4153],{"class":512},[502,4433,590],{"class":508},[502,4435,4158],{"class":941},[502,4437,945],{"class":508},[502,4439,4163],{"class":512},[502,4441,99],{"class":508},[502,4443,4168],{"class":512},[502,4445,216],{"class":508},[502,4447,557],{"class":508},[502,4449,4450,4452,4454,4456,4458,4460],{"class":504,"line":516},[502,4451,824],{"class":563},[502,4453,567],{"class":508},[502,4455,829],{"class":563},[502,4457,99],{"class":508},[502,4459,834],{"class":550},[502,4461,837],{"class":508},[502,4463,4464,4466,4468,4470,4472,4474,4476,4478],{"class":504,"line":523},[502,4465,843],{"class":563},[502,4467,99],{"class":508},[502,4469,848],{"class":550},[502,4471,578],{"class":508},[502,4473,853],{"class":563},[502,4475,99],{"class":508},[502,4477,604],{"class":563},[502,4479,860],{"class":508},[502,4481,4482,4484,4486,4488,4490,4492,4494,4496,4498,4500,4502,4504,4506,4508],{"class":504,"line":539},[502,4483,843],{"class":563},[502,4485,99],{"class":508},[502,4487,870],{"class":550},[502,4489,578],{"class":508},[502,4491,853],{"class":563},[502,4493,99],{"class":508},[502,4495,879],{"class":550},[502,4497,578],{"class":508},[502,4499,853],{"class":563},[502,4501,99],{"class":508},[502,4503,888],{"class":550},[502,4505,578],{"class":508},[502,4507,893],{"class":661},[502,4509,896],{"class":508},[502,4511,4512],{"class":504,"line":544},[502,4513,902],{"class":508},[502,4515,4516],{"class":504,"line":560},[502,4517,520],{"emptyLinePlaceholder":519},[502,4519,4520,4522,4524,4526,4528,4530],{"class":504,"line":617},[502,4521,913],{"class":563},[502,4523,567],{"class":508},[502,4525,918],{"class":563},[502,4527,99],{"class":508},[502,4529,625],{"class":550},[502,4531,628],{"class":508},[502,4533,4534,4536,4538,4540,4542,4544,4546,4548,4550,4552,4554],{"class":504,"line":631},[502,4535,930],{"class":563},[502,4537,99],{"class":508},[502,4539,935],{"class":550},[502,4541,938],{"class":508},[502,4543,942],{"class":941},[502,4545,945],{"class":508},[502,4547,948],{"class":512},[502,4549,99],{"class":508},[502,4551,953],{"class":512},[502,4553,216],{"class":508},[502,4555,557],{"class":508},[502,4557,4558,4560,4562,4564,4566,4568,4570,4572,4574,4576,4578,4580,4582,4584],{"class":504,"line":667},[502,4559,963],{"class":563},[502,4561,99],{"class":508},[502,4563,968],{"class":550},[502,4565,578],{"class":508},[502,4567,973],{"class":661},[502,4569,590],{"class":508},[502,4571,978],{"class":508},[502,4573,981],{"class":941},[502,4575,945],{"class":508},[502,4577,948],{"class":512},[502,4579,99],{"class":508},[502,4581,990],{"class":512},[502,4583,216],{"class":508},[502,4585,557],{"class":508},[502,4587,4588,4590,4592,4594,4596,4598,4600,4602,4605,4608,4610,4612,4614,4616,4618,4620,4622,4624],{"class":504,"line":698},[502,4589,1000],{"class":563},[502,4591,99],{"class":508},[502,4593,1005],{"class":550},[502,4595,578],{"class":508},[502,4597,581],{"class":508},[502,4599,4273],{"class":584},[502,4601,581],{"class":508},[502,4603,4604],{"class":508}," +",[502,4606,4607],{"class":563}," time",[502,4609,99],{"class":508},[502,4611,4285],{"class":550},[502,4613,4288],{"class":508},[502,4615,4291],{"class":550},[502,4617,578],{"class":508},[502,4619,4280],{"class":563},[502,4621,99],{"class":508},[502,4623,4300],{"class":563},[502,4625,3614],{"class":508},[502,4627,4628],{"class":504,"line":719},[502,4629,1047],{"class":508},[502,4631,4632],{"class":504,"line":810},[502,4633,1053],{"class":508},[502,4635,4636],{"class":504,"line":821},[502,4637,520],{"emptyLinePlaceholder":519},[502,4639,4640,4642,4644,4646,4648,4650,4652,4654,4656,4658,4660,4662,4664,4666],{"class":504,"line":840},[502,4641,4311],{"class":563},[502,4643,99],{"class":508},[502,4645,3502],{"class":550},[502,4647,4288],{"class":508},[502,4649,4320],{"class":550},[502,4651,578],{"class":508},[502,4653,581],{"class":508},[502,4655,4327],{"class":584},[502,4657,581],{"class":508},[502,4659,590],{"class":508},[502,4661,530],{"class":508},[502,4663,4123],{"class":584},[502,4665,581],{"class":508},[502,4667,614],{"class":508},[502,4669,4670,4672,4674,4676,4678,4680,4683,4685,4687,4689,4691,4693,4695],{"class":504,"line":863},[502,4671,1086],{"class":526},[502,4673,1069],{"class":563},[502,4675,567],{"class":508},[502,4677,918],{"class":563},[502,4679,99],{"class":508},[502,4681,4682],{"class":550},"Render",[502,4684,578],{"class":508},[502,4686,4145],{"class":563},[502,4688,1158],{"class":508},[502,4690,1069],{"class":563},[502,4692,1091],{"class":508},[502,4694,1094],{"class":508},[502,4696,557],{"class":508},[502,4698,4699,4701,4703,4705,4707,4709,4711,4713,4715,4717,4719,4721],{"class":504,"line":899},[502,4700,4373],{"class":563},[502,4702,99],{"class":508},[502,4704,4378],{"class":550},[502,4706,578],{"class":508},[502,4708,4145],{"class":563},[502,4710,590],{"class":508},[502,4712,4387],{"class":563},[502,4714,99],{"class":508},[502,4716,4378],{"class":550},[502,4718,3601],{"class":508},[502,4720,4396],{"class":661},[502,4722,614],{"class":508},[502,4724,4725],{"class":504,"line":905},[502,4726,1120],{"class":508},[502,4728,4729],{"class":504,"line":910},[502,4730,722],{"class":508},[18,4732,4733,4734,4736,4737,4740,4741,4743,4744,99],{},"Mesma forma. ",[26,4735,436],{}," transmite o PDF direto na resposta. Se quiser setar ",[26,4738,4739],{},"Content-Length",", chame ",[26,4742,1206],{}," primeiro para pegar o slice de bytes e tire ",[26,4745,4746],{},"len()",[13,4748,4750],{"id":4749},"quão-rápido-é-rápido-o-suficiente","Quão rápido é \"rápido o suficiente\"?",[18,4752,4753,4754,4756,4757,4760],{},"O gpdf é aproximadamente ",[21,4755,36],{}," nas cargas que a galera realmente roda. Os números abaixo vêm de ",[26,4758,4759],{},"_benchmark/benchmark_test.go"," rodando num Apple M1 com Go 1.25.",[158,4762,4763,4780],{},[161,4764,4765],{},[164,4766,4767,4770,4772,4774,4777],{},[167,4768,4769],{},"Benchmark",[167,4771,23],{},[167,4773,172],{},[167,4775,4776],{},"gopdf",[167,4778,4779],{},"Maroto v2",[176,4781,4782,4801,4820,4838],{},[164,4783,4784,4787,4792,4795,4798],{},[181,4785,4786],{},"Página única",[181,4788,4789],{},[21,4790,4791],{},"13 µs",[181,4793,4794],{},"132 µs",[181,4796,4797],{},"423 µs",[181,4799,4800],{},"237 µs",[164,4802,4803,4806,4811,4814,4817],{},[181,4804,4805],{},"Tabela 4×10",[181,4807,4808],{},[21,4809,4810],{},"108 µs",[181,4812,4813],{},"241 µs",[181,4815,4816],{},"835 µs",[181,4818,4819],{},"8,6 ms",[164,4821,4822,4825,4830,4833,4835],{},[181,4823,4824],{},"Documento de 100 págs.",[181,4826,4827],{},[21,4828,4829],{},"683 µs",[181,4831,4832],{},"11,7 ms",[181,4834,4819],{},[181,4836,4837],{},"19,8 ms",[164,4839,4840,4843,4848,4851,4854],{},[181,4841,4842],{},"Nota fiscal CJK complexa",[181,4844,4845],{},[21,4846,4847],{},"133 µs",[181,4849,4850],{},"254 µs",[181,4852,4853],{},"997 µs",[181,4855,4856],{},"10,4 ms",[18,4858,4859],{},"Não são sintéticos — o benchmark de tabela é uma de itens de nota com 4 colunas e 10 linhas; o de 100 páginas é um relatório paginado com cabeçalho repetido e números de página. A forma combina com o que o código de produção faz de verdade.",[18,4861,4862],{},"Sobre o que esses números significam. A 13 µs por página única, um único core produz ~75.000 PDFs \"hello world\" por segundo. A 108 µs por página com tabela, ~9.000 notas por segundo. O ponto não é ostentar — é que você pode parar de se perguntar se precisa cachear ou empurrar geração de PDF para uma fila assíncrona. Para a maioria das cargas, gerar no caminho da requisição basta.",[13,4864,4866],{"id":4865},"o-que-você-perde-na-migração","O que você perde na migração",[18,4868,4869],{},"Nada neste guia tem valor se esconder lacunas reais. Aqui está o que o gpdf ainda não faz e o gofpdf fazia:",[4871,4872,4873,4882,4899,4905],"ul",{},[120,4874,4875,209,4878,4881],{},[21,4876,4877],{},"Linhas em ângulos arbitrários, curvas Bézier e caminhos complexos.",[26,4879,4880],{},"c.Line()"," desenha uma régua horizontal cruzando uma coluna. Se você produz desenhos técnicos ou gráficos com geometria própria, o gpdf ainda não chegou lá. (Gráficos como imagens pré-renderizadas: funciona sem problema.)",[120,4883,4884,4889,4890,4892,4893,4895,4896,4898],{},[21,4885,4886,4888],{},[26,4887,32],{}," e trabalho com cursor absoluto."," Dá pra posicionar absoluto com ",[26,4891,356],{},", mas se seu código existente são 2.000 linhas de ",[26,4894,32],{}," seguidas de ",[26,4897,674],{},", a migração é mais uma reescrita. A boa notícia é que o código reescrito costuma ser metade do tamanho do original.",[120,4900,4901,4904],{},[21,4902,4903],{},"Campos de formulário (AcroForm)."," O gpdf ainda não gera campos preenchíveis. Se seus PDFs são templates que o usuário preenche num visualizador, fique com uma biblioteca que suporte AcroForm — por enquanto.",[120,4906,4907,4910],{},[21,4908,4909],{},"Anotações e marcadores."," Suporte básico de outline existe; anotações ricas não.",[18,4912,4913],{},"Se nada disso morde você, a migração é direta. Se morde, abra uma issue — o roadmap é movido pelo que as pessoas pedem.",[13,4915,4917],{"id":4916},"faq","FAQ",[18,4919,4920,4923],{},[21,4921,4922],{},"O gpdf é um fork do gofpdf?","\nNão. O gpdf é uma reimplementação limpa. O trabalho de formato de cabo PDF, o motor de layout, o subsetter TrueType — tudo escrito do zero em Go puro. Não há linhagem compartilhada com gofpdf ou seus forks. Tem que ser reescrita porque a arquitetura do gofpdf é construída em torno de um único cursor mutável; não dá para extrair uma grade declarativa daquilo sem quebrar todos os sites de chamada existentes.",[18,4925,4926,4929,4930,4933,4934,4937,4938,4941,4942,4945],{},[21,4927,4928],{},"O gpdf tem dependências externas?","\nA biblioteca core tem zero. Rode ",[26,4931,4932],{},"go mod graph | grep gpdf"," depois de ",[26,4935,4936],{},"go get github.com/gpdf-dev/gpdf"," e verá uma única linha. O add-on ",[26,4939,4940],{},"gpdf-pro"," (HTML→PDF, criptografia AES, assinaturas, PDF/A) puxa ",[26,4943,4944],{},"golang.org/x/net"," para parsing HTML, mas é opt-in e não é necessário para migrar.",[18,4947,4948,4951,4952,4955],{},[21,4949,4950],{},"E CGO? O gofpdf era CGO-free, e o gpdf?","\nIgual. Go puro, sem CGO. Faça ",[26,4953,4954],{},"GOOS=linux GOARCH=arm64 go build"," e entregue um binário estático. Isso importa em imagens distroless e Alpine, onde arrastar uma toolchain CGO dobra o tamanho do container.",[18,4957,4958,4964,4965,4967],{},[21,4959,4960,4961,4963],{},"Meu código gofpdf existente usa ",[26,4962,32],{}," para posicionamento absoluto em todo lugar. Dá para migrar sem reescrever?","\nVocê consegue envolver ",[26,4966,356],{}," e ter algo com sensação parecida. Mas se seu código está estruturado em torno de manipulação de cursor, o modelo do motor de layout é uma mudança mental, não sintática. A maior parte dos times descobre que a reescrita sai mais curta do que o original.",[18,4969,4970,4973,4974,4976],{},[21,4971,4972],{},"NFe, DANFE e PDF/A para arquivamento fiscal?","\nCarimbo de tempo e assinatura digital estão sendo implementados em ",[26,4975,4940],{},". Se você tem um requisito concreto, abra uma issue para subir a prioridade.",[18,4978,4979,4982],{},[21,4980,4981],{},"E se o go-pdf/fpdf for desarquivado?","\nAí você tem mais uma opção. A aposta por trás do gpdf não é que o gofpdf fique arquivado para sempre — é que a arquitetura (baseada em cursor, fontes de um byte, sem CJK nativo) é beco sem saída independente de quem mantém. Gerar PDF em 2026 se parece mais com montar uma página web do que com dirigir um plotter, e a API deveria refletir isso.",[13,4984,4986],{"id":4985},"experimente-o-gpdf","Experimente o gpdf",[18,4988,4989],{},"gpdf é uma biblioteca Go para gerar PDFs. Licença MIT, zero dependências externas, suporte CJK nativo.",[493,4991,4995],{"className":4992,"code":4993,"language":4994,"meta":498,"style":498},"language-bash shiki shiki-themes material-theme-lighter material-theme material-theme-palenight","go get github.com/gpdf-dev/gpdf\n","bash",[26,4996,4997],{"__ignoreMap":498},[502,4998,4999,5001,5004],{"class":504,"line":505},[502,5000,497],{"class":512},[502,5002,5003],{"class":584}," get",[502,5005,5006],{"class":584}," github.com/gpdf-dev/gpdf\n",[18,5008,5009,5016,5017],{},[5010,5011,5015],"a",{"href":5012,"rel":5013},"https://github.com/gpdf-dev/gpdf",[5014],"nofollow","⭐ Star no GitHub"," · ",[5010,5018,5021],{"href":5019,"rel":5020},"https://gpdf.dev/pt/docs/quickstart",[5014],"Leia a documentação",[13,5023,5025],{"id":5024},"próximas-leituras","Próximas leituras",[4871,5027,5028,5034,5039],{},[120,5029,5030,5031],{},"Como funciona a grade de 12 colunas no gpdf? ",[83,5032,5033],{},"(em breve)",[120,5035,5036,5037],{},"Como embutir uma fonte japonesa no gpdf? ",[83,5038,5033],{},[120,5040,5041,5045,5046],{},[5010,5042,5044],{"href":5019,"rel":5043},[5014],"Quickstart"," — setup em cinco minutos, incluindo ",[26,5047,5048],{},"go.mod",[5050,5051,5052],"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":498,"searchDepth":516,"depth":516,"links":5054},[5055,5056,5057,5058,5059,5060,5061,5062,5063,5064,5065,5066,5067,5068],{"id":15,"depth":516,"text":16},{"id":71,"depth":516,"text":72},{"id":105,"depth":516,"text":106},{"id":152,"depth":516,"text":153},{"id":482,"depth":516,"text":483},{"id":1218,"depth":516,"text":1219},{"id":2396,"depth":516,"text":2397},{"id":3059,"depth":516,"text":3060},{"id":4109,"depth":516,"text":4110},{"id":4749,"depth":516,"text":4750},{"id":4865,"depth":516,"text":4866},{"id":4916,"depth":516,"text":4917},{"id":4985,"depth":516,"text":4986},{"id":5024,"depth":516,"text":5025},"2026-04-14","jung-kurt/gofpdf foi arquivado em 2021 e go-pdf/fpdf em 2025. Este guia mapeia toda a API do gofpdf para o gpdf — Go puro, zero dependências, CJK nativo.",false,"md",{"name":5074,"totalTime":5075,"tools":5076,"steps":5078},"Migrar um projeto Go de gofpdf para gpdf","PT30M",[5077],"Go 1.22+",[5079,5082,5085,5088,5091,5094],{"name":5080,"text":5081},"Substituir o caminho do import","Troque github.com/jung-kurt/gofpdf (arquivado em 2021) e github.com/go-pdf/fpdf (arquivado em 2025) por github.com/gpdf-dev/gpdf, github.com/gpdf-dev/gpdf/document e github.com/gpdf-dev/gpdf/template.",{"name":5083,"text":5084},"Construir o documento com builders em vez de cursores","Chame gpdf.NewDocument com WithPageSize, WithMargins e WithFont. Em vez de movimentar um cursor com SetXY, adicione páginas via doc.AddPage() e descreva o conteúdo com RowBuilder e ColBuilder.",{"name":5086,"text":5087},"Converter Cell e MultiCell em Text declarativo","Substitua pdf.Cell e pdf.MultiCell por c.Text(...) dentro de uma coluna. O texto quebra automaticamente no limite da coluna, então a flag final do MultiCell desaparece. Tamanho de fonte, peso e cor viram opções per-text.",{"name":5089,"text":5090},"Registrar fontes CJK via WithFont","Para textos em chinês, japonês ou coreano, substitua pdf.AddUTF8Font por gpdf.WithFont(name, ttfBytes) na construção do documento. Não há mais necessidade de gerenciar caminhos TTF ou a flag UTF-8 — o subset embedding acontece automaticamente.",{"name":5092,"text":5093},"Reescrever tabelas com linhas e colunas","Descarte os loops aninhados de Cell com larguras manuais. Dentro de um AutoRow, use row.Col(n, fn) para construir linhas de tabela; a grade de 12 colunas calcula as larguras e cuida das quebras de página.",{"name":5095,"text":5096},"Trocar a chamada de saída","Substitua pdf.OutputFileAndClose(path) por doc.Generate() seguido de os.WriteFile(path, data, 0o644), ou use doc.Render(w) para escrever direto em um io.Writer.",null,{},"/pt/blog/gofpdf-migration",{"title":5,"description":5070},"pt/blog/001.gofpdf-migration",[5103,5104,5105],"migration","comparison","tutorial","FkitdjLnTPGcq3xjJuzDfDe_o2FraVgXUCIC5BV00Eo",1776529276230]