[{"data":1,"prerenderedAt":3449},["ShallowReactive",2],{"blog-pt-tables-in-go-pdfs":3},{"id":4,"title":5,"author":6,"body":10,"date":3411,"description":3412,"draft":3413,"extension":3414,"howTo":3415,"image":3439,"meta":3440,"navigation":484,"path":3441,"seo":3442,"stem":3443,"tags":3444,"updated":3439,"__hash__":3448},"blogPt/pt/blog/022.tables-in-go-pdfs.md","Tabelas em PDFs com Go: larguras, listras zebra, quebra de página",{"name":7,"url":8,"avatar":9},"Taiki Noda","https://nadai.dev/en/about","https://nadai.dev/og-default.png",{"type":11,"value":12,"toc":3394},"minimark",[13,18,26,184,203,206,210,224,227,261,264,268,271,333,340,443,449,453,467,1579,1582,1598,1602,1612,1630,1636,1642,1681,1688,1719,1727,1731,1758,1768,1786,1789,1810,1822,1826,1829,1839,1865,1868,1889,1892,1899,1903,1908,2347,2384,2393,2403,2408,2412,2415,2476,2492,2498,2501,2695,2698,2702,2705,2842,2851,2864,2868,2871,3170,3173,3181,3185,3190,3213,3218,3242,3247,3250,3255,3267,3272,3278,3286,3293,3297,3304,3311,3314,3318,3321,3338,3350,3354,3390],[14,15,17],"h2",{"id":16},"resumo","Resumo",[19,20,21,25],"p",{},[22,23,24],"strong",{},"Tabelas são a parte da geração de PDF que destrói fim de semana."," Larguras de coluna que não somam, cabeçalhos que somem na página 2, listras desenhadas com um loop de linhas que tem um off-by-one. O gpdf comprime tudo isso em uma chamada:",[27,28,33],"pre",{"className":29,"code":30,"language":31,"meta":32,"style":32},"language-go shiki shiki-themes material-theme-lighter material-theme material-theme-palenight","c.Table(header, rows,\n    template.ColumnWidths(40, 15, 20, 25),\n    template.TableHeaderStyle(template.TextColor(pdf.White), template.BgColor(brand)),\n    template.TableStripe(pdf.RGBHex(0xF5F5F5)),\n)\n","go","",[34,35,36,68,103,152,178],"code",{"__ignoreMap":32},[37,38,41,45,49,53,56,59,62,65],"span",{"class":39,"line":40},"line",1,[37,42,44],{"class":43},"sTEyZ","c",[37,46,48],{"class":47},"sMK4o",".",[37,50,52],{"class":51},"s2Zo4","Table",[37,54,55],{"class":47},"(",[37,57,58],{"class":43},"header",[37,60,61],{"class":47},",",[37,63,64],{"class":43}," rows",[37,66,67],{"class":47},",\n",[37,69,71,74,76,79,81,85,87,90,92,95,97,100],{"class":39,"line":70},2,[37,72,73],{"class":43},"    template",[37,75,48],{"class":47},[37,77,78],{"class":51},"ColumnWidths",[37,80,55],{"class":47},[37,82,84],{"class":83},"sbssI","40",[37,86,61],{"class":47},[37,88,89],{"class":83}," 15",[37,91,61],{"class":47},[37,93,94],{"class":83}," 20",[37,96,61],{"class":47},[37,98,99],{"class":83}," 25",[37,101,102],{"class":47},"),\n",[37,104,106,108,110,113,115,118,120,123,125,128,130,133,136,139,141,144,146,149],{"class":39,"line":105},3,[37,107,73],{"class":43},[37,109,48],{"class":47},[37,111,112],{"class":51},"TableHeaderStyle",[37,114,55],{"class":47},[37,116,117],{"class":43},"template",[37,119,48],{"class":47},[37,121,122],{"class":51},"TextColor",[37,124,55],{"class":47},[37,126,127],{"class":43},"pdf",[37,129,48],{"class":47},[37,131,132],{"class":43},"White",[37,134,135],{"class":47},"),",[37,137,138],{"class":43}," template",[37,140,48],{"class":47},[37,142,143],{"class":51},"BgColor",[37,145,55],{"class":47},[37,147,148],{"class":43},"brand",[37,150,151],{"class":47},")),\n",[37,153,155,157,159,162,164,166,168,171,173,176],{"class":39,"line":154},4,[37,156,73],{"class":43},[37,158,48],{"class":47},[37,160,161],{"class":51},"TableStripe",[37,163,55],{"class":47},[37,165,127],{"class":43},[37,167,48],{"class":47},[37,169,170],{"class":51},"RGBHex",[37,172,55],{"class":47},[37,174,175],{"class":83},"0xF5F5F5",[37,177,151],{"class":47},[37,179,181],{"class":39,"line":180},5,[37,182,183],{"class":47},")\n",[19,185,186,187,190,191,194,195,198,199,202],{},"Isso resolve larguras, listras e ",[22,188,189],{},"repetição automática do cabeçalho a cada quebra de página",". Sem loop. Sem opção ",[34,192,193],{},"PageBreak",". O motor de layout percebe quando a tabela não cabe e reemite o slice ",[34,196,197],{},"Header"," no topo da próxima página. Para colspan, rowspan ou um rodapé que também repita, você desce uma camada para ",[34,200,201],{},"document.Table"," — mesmos blocos, mais controle.",[19,204,205],{},"Este post é sobre por que esses são os três eixos que importam, o que o gpdf faz em cada um e onde a abstração para de propósito.",[14,207,209],{"id":208},"por-que-este-artigo-existe","Por que este artigo existe",[19,211,212,219,220,223],{},[213,214,218],"a",{"href":215,"rel":216},"https://github.com/gpdf-dev/gpdf",[217],"nofollow","gpdf"," é uma biblioteca Go para gerar PDFs. MIT, dependências zero, renderiza uma página em ~13 µs. A API de tabela é pequena — oito construtores ",[34,221,222],{},"TableOption"," — mas a pressão de design sobre ela é enorme: é nas tabelas que a maioria dos projetos PDF em Go encalha.",[19,225,226],{},"Os três pontos onde uma tabela quebra no mundo Go PDF:",[228,229,230,245,251],"ol",{},[231,232,233,236,237,240,241,244],"li",{},[22,234,235],{},"Larguras de coluna."," A web tem CSS ",[34,238,239],{},"\u003Ccol>"," e ",[34,242,243],{},"colgroup",". PDF não tem nada. Ou você calcula cada largura em pontos manualmente, ou aceita o que a biblioteca dá — geralmente divisões iguais.",[231,246,247,250],{},[22,248,249],{},"Listras zebra."," Você quer cada linha alternada do corpo tingida de cinza para legibilidade. A maioria das bibliotecas de baixo nível obriga você a escrever o loop e rastrear paridade — fonte de metade dos bugs de renderização de tabela.",[231,252,253,256,257,260],{},[22,254,255],{},"Quebras de página."," Um relatório de 200 linhas não cabe em uma A4. A biblioteca precisa (a) cortar o corpo em algum lugar razoável, (b) fechar a página, (c) abrir a próxima e (d) ",[22,258,259],{},"reemitir o cabeçalho na nova página"," para que o leitor saiba qual coluna está olhando. Esqueça qualquer uma e a tabela é inutilizável.",[19,262,263],{},"Este post percorre como o gpdf resolve cada um e quais trade-offs o design assume. Se você só quer receitas para colar, os links no final apontam para receitas por opção. Esta é a versão longa para quem quer saber se pode confiar na API antes de comprometer um extrato mensal de dez mil linhas.",[14,265,267],{"id":266},"a-forma-da-api","A forma da API",[19,269,270],{},"Há um único ponto de entrada na camada builder:",[27,272,274],{"className":29,"code":273,"language":31,"meta":32,"style":32},"func (c *ColBuilder) Table(header []string, rows [][]string, opts ...TableOption)\n",[34,275,276],{"__ignoreMap":32},[37,277,278,281,284,288,291,295,298,301,303,305,308,312,314,316,319,321,323,326,329,331],{"class":39,"line":40},[37,279,280],{"class":47},"func",[37,282,283],{"class":47}," (",[37,285,287],{"class":286},"sHdIc","c ",[37,289,290],{"class":47},"*",[37,292,294],{"class":293},"sBMFI","ColBuilder",[37,296,297],{"class":47},")",[37,299,300],{"class":51}," Table",[37,302,55],{"class":47},[37,304,58],{"class":286},[37,306,307],{"class":47}," []",[37,309,311],{"class":310},"spNyl","string",[37,313,61],{"class":47},[37,315,64],{"class":286},[37,317,318],{"class":47}," [][]",[37,320,311],{"class":310},[37,322,61],{"class":47},[37,324,325],{"class":286}," opts",[37,327,328],{"class":47}," ...",[37,330,222],{"class":293},[37,332,183],{"class":47},[19,334,335,336,339],{},"Cabeçalho é um slice de strings, rows é um slice de slices de strings, e o variádico ",[34,337,338],{},"opts"," configura todo o resto. Existem oito construtores de opção:",[341,342,343,356],"table",{},[344,345,346],"thead",{},[347,348,349,353],"tr",{},[350,351,352],"th",{},"Opção",[350,354,355],{},"O que controla",[357,358,359,370,380,390,400,410,420,433],"tbody",{},[347,360,361,367],{},[362,363,364],"td",{},[34,365,366],{},"ColumnWidths(...float64)",[362,368,369],{},"Larguras por coluna como porcentagem do Col pai",[347,371,372,377],{},[362,373,374],{},[34,375,376],{},"TableHeaderStyle(...TextOption)",[362,378,379],{},"Cor de fundo e de texto do cabeçalho",[347,381,382,387],{},[362,383,384],{},[34,385,386],{},"TableStripe(pdf.Color)",[362,388,389],{},"Cor de fundo das linhas alternadas do corpo",[347,391,392,397],{},[362,393,394],{},[34,395,396],{},"TableCellVAlign(document.VerticalAlign)",[362,398,399],{},"Alinhamento vertical das células do corpo",[347,401,402,407],{},[362,403,404],{},[34,405,406],{},"WithTableBorder(BorderSpec)",[362,408,409],{},"Moldura externa de toda a tabela",[347,411,412,417],{},[362,413,414],{},[34,415,416],{},"WithTableCellBorder(BorderSpec)",[362,418,419],{},"Mesma borda em volta de cada célula — visual de grade",[347,421,422,427],{},[362,423,424],{},[34,425,426],{},"WithTableBorderCollapse(bool)",[362,428,429,430],{},"Semântica do CSS ",[34,431,432],{},"border-collapse: collapse",[347,434,435,440],{},[362,436,437],{},[34,438,439],{},"WithTableBackground(pdf.Color)",[362,441,442],{},"Preenchimento de fundo da tabela inteira",[19,444,445,446,448],{},"Essa é toda a superfície. O que dá para construir no builder se constrói com esses oito. Qualquer coisa além — colspan, rowspan, rodapé, larguras fixas em pt — vira chamada ",[34,447,201],{},". Já chegamos lá.",[14,450,452],{"id":451},"código-que-roda-livro-razão-de-seis-meses","Código que roda: livro razão de seis meses",[19,454,455,456,459,460,463,464,48],{},"Programa completo e executável. Salve como ",[34,457,458],{},"main.go",", rode ",[34,461,462],{},"go run .",", obtenha ",[34,465,466],{},"ledger.pdf",[27,468,470],{"className":29,"code":469,"language":31,"meta":32,"style":32},"package main\n\nimport (\n    \"fmt\"\n    \"log\"\n    \"os\"\n\n    \"github.com/gpdf-dev/gpdf\"\n    \"github.com/gpdf-dev/gpdf/document\"\n    \"github.com/gpdf-dev/gpdf/pdf\"\n    \"github.com/gpdf-dev/gpdf/template\"\n)\n\nfunc main() {\n    doc := gpdf.NewDocument(\n        gpdf.WithPageSize(gpdf.A4),\n        gpdf.WithMargins(document.UniformEdges(document.Mm(20))),\n    )\n\n    brand := pdf.RGBHex(0x1A237E)\n    stripe := pdf.RGBHex(0xF5F5F5)\n    hairline := template.Border(\n        template.BorderWidth(document.Pt(0.5)),\n        template.BorderColor(pdf.Gray(0.85)),\n    )\n\n    header := []string{\"Data\", \"Nº NF\", \"Cliente\", \"Valor\"}\n    rows := make([][]string, 0, 120)\n    for i := 1; i \u003C= 120; i++ {\n        rows = append(rows, []string{\n            fmt.Sprintf(\"2026-%02d-%02d\", (i%6)+1, (i%28)+1),\n            fmt.Sprintf(\"NF-%05d\", 10000+i),\n            fmt.Sprintf(\"Cliente #%d\", i),\n            fmt.Sprintf(\"R$%d,00\", 100+i*7),\n        })\n    }\n\n    page := doc.AddPage()\n    page.AutoRow(func(r *template.RowBuilder) {\n        r.Col(12, func(c *template.ColBuilder) {\n            c.Text(\"Razão S1 2026\", template.FontSize(18), template.Bold())\n            c.Spacer(document.Mm(4))\n\n            c.Table(header, rows,\n                template.ColumnWidths(20, 20, 40, 20),\n                template.TableHeaderStyle(\n                    template.TextColor(pdf.White),\n                    template.BgColor(brand),\n                ),\n                template.TableStripe(stripe),\n                template.WithTableCellBorder(hairline),\n            )\n        })\n    })\n\n    data, err := doc.Generate()\n    if err != nil {\n        log.Fatal(err)\n    }\n    if err := os.WriteFile(\"ledger.pdf\", data, 0o644); err != nil {\n        log.Fatal(err)\n    }\n}\n",[34,471,472,480,486,495,506,515,525,530,540,550,560,570,575,580,594,614,636,673,679,684,706,726,743,770,796,801,806,861,889,923,949,1014,1047,1074,1113,1119,1125,1130,1149,1180,1215,1261,1287,1292,1311,1340,1351,1371,1386,1392,1408,1425,1431,1436,1442,1447,1469,1485,1503,1508,1554,1569,1574],{"__ignoreMap":32},[37,473,474,477],{"class":39,"line":40},[37,475,476],{"class":47},"package",[37,478,479],{"class":293}," main\n",[37,481,482],{"class":39,"line":70},[37,483,485],{"emptyLinePlaceholder":484},true,"\n",[37,487,488,492],{"class":39,"line":105},[37,489,491],{"class":490},"s7zQu","import",[37,493,494],{"class":47}," (\n",[37,496,497,500,503],{"class":39,"line":154},[37,498,499],{"class":47},"    \"",[37,501,502],{"class":293},"fmt",[37,504,505],{"class":47},"\"\n",[37,507,508,510,513],{"class":39,"line":180},[37,509,499],{"class":47},[37,511,512],{"class":293},"log",[37,514,505],{"class":47},[37,516,518,520,523],{"class":39,"line":517},6,[37,519,499],{"class":47},[37,521,522],{"class":293},"os",[37,524,505],{"class":47},[37,526,528],{"class":39,"line":527},7,[37,529,485],{"emptyLinePlaceholder":484},[37,531,533,535,538],{"class":39,"line":532},8,[37,534,499],{"class":47},[37,536,537],{"class":293},"github.com/gpdf-dev/gpdf",[37,539,505],{"class":47},[37,541,543,545,548],{"class":39,"line":542},9,[37,544,499],{"class":47},[37,546,547],{"class":293},"github.com/gpdf-dev/gpdf/document",[37,549,505],{"class":47},[37,551,553,555,558],{"class":39,"line":552},10,[37,554,499],{"class":47},[37,556,557],{"class":293},"github.com/gpdf-dev/gpdf/pdf",[37,559,505],{"class":47},[37,561,563,565,568],{"class":39,"line":562},11,[37,564,499],{"class":47},[37,566,567],{"class":293},"github.com/gpdf-dev/gpdf/template",[37,569,505],{"class":47},[37,571,573],{"class":39,"line":572},12,[37,574,183],{"class":47},[37,576,578],{"class":39,"line":577},13,[37,579,485],{"emptyLinePlaceholder":484},[37,581,583,585,588,591],{"class":39,"line":582},14,[37,584,280],{"class":47},[37,586,587],{"class":51}," main",[37,589,590],{"class":47},"()",[37,592,593],{"class":47}," {\n",[37,595,597,600,603,606,608,611],{"class":39,"line":596},15,[37,598,599],{"class":43},"    doc ",[37,601,602],{"class":47},":=",[37,604,605],{"class":43}," gpdf",[37,607,48],{"class":47},[37,609,610],{"class":51},"NewDocument",[37,612,613],{"class":47},"(\n",[37,615,617,620,622,625,627,629,631,634],{"class":39,"line":616},16,[37,618,619],{"class":43},"        gpdf",[37,621,48],{"class":47},[37,623,624],{"class":51},"WithPageSize",[37,626,55],{"class":47},[37,628,218],{"class":43},[37,630,48],{"class":47},[37,632,633],{"class":43},"A4",[37,635,102],{"class":47},[37,637,639,641,643,646,648,651,653,656,658,660,662,665,667,670],{"class":39,"line":638},17,[37,640,619],{"class":43},[37,642,48],{"class":47},[37,644,645],{"class":51},"WithMargins",[37,647,55],{"class":47},[37,649,650],{"class":43},"document",[37,652,48],{"class":47},[37,654,655],{"class":51},"UniformEdges",[37,657,55],{"class":47},[37,659,650],{"class":43},[37,661,48],{"class":47},[37,663,664],{"class":51},"Mm",[37,666,55],{"class":47},[37,668,669],{"class":83},"20",[37,671,672],{"class":47},"))),\n",[37,674,676],{"class":39,"line":675},18,[37,677,678],{"class":47},"    )\n",[37,680,682],{"class":39,"line":681},19,[37,683,485],{"emptyLinePlaceholder":484},[37,685,687,690,692,695,697,699,701,704],{"class":39,"line":686},20,[37,688,689],{"class":43},"    brand ",[37,691,602],{"class":47},[37,693,694],{"class":43}," pdf",[37,696,48],{"class":47},[37,698,170],{"class":51},[37,700,55],{"class":47},[37,702,703],{"class":83},"0x1A237E",[37,705,183],{"class":47},[37,707,709,712,714,716,718,720,722,724],{"class":39,"line":708},21,[37,710,711],{"class":43},"    stripe ",[37,713,602],{"class":47},[37,715,694],{"class":43},[37,717,48],{"class":47},[37,719,170],{"class":51},[37,721,55],{"class":47},[37,723,175],{"class":83},[37,725,183],{"class":47},[37,727,729,732,734,736,738,741],{"class":39,"line":728},22,[37,730,731],{"class":43},"    hairline ",[37,733,602],{"class":47},[37,735,138],{"class":43},[37,737,48],{"class":47},[37,739,740],{"class":51},"Border",[37,742,613],{"class":47},[37,744,746,749,751,754,756,758,760,763,765,768],{"class":39,"line":745},23,[37,747,748],{"class":43},"        template",[37,750,48],{"class":47},[37,752,753],{"class":51},"BorderWidth",[37,755,55],{"class":47},[37,757,650],{"class":43},[37,759,48],{"class":47},[37,761,762],{"class":51},"Pt",[37,764,55],{"class":47},[37,766,767],{"class":83},"0.5",[37,769,151],{"class":47},[37,771,773,775,777,780,782,784,786,789,791,794],{"class":39,"line":772},24,[37,774,748],{"class":43},[37,776,48],{"class":47},[37,778,779],{"class":51},"BorderColor",[37,781,55],{"class":47},[37,783,127],{"class":43},[37,785,48],{"class":47},[37,787,788],{"class":51},"Gray",[37,790,55],{"class":47},[37,792,793],{"class":83},"0.85",[37,795,151],{"class":47},[37,797,799],{"class":39,"line":798},25,[37,800,678],{"class":47},[37,802,804],{"class":39,"line":803},26,[37,805,485],{"emptyLinePlaceholder":484},[37,807,809,812,814,816,818,821,824,828,830,832,835,838,840,842,844,847,849,851,853,856,858],{"class":39,"line":808},27,[37,810,811],{"class":43},"    header ",[37,813,602],{"class":47},[37,815,307],{"class":47},[37,817,311],{"class":310},[37,819,820],{"class":47},"{",[37,822,823],{"class":47},"\"",[37,825,827],{"class":826},"sfazB","Data",[37,829,823],{"class":47},[37,831,61],{"class":47},[37,833,834],{"class":47}," \"",[37,836,837],{"class":826},"Nº NF",[37,839,823],{"class":47},[37,841,61],{"class":47},[37,843,834],{"class":47},[37,845,846],{"class":826},"Cliente",[37,848,823],{"class":47},[37,850,61],{"class":47},[37,852,834],{"class":47},[37,854,855],{"class":826},"Valor",[37,857,823],{"class":47},[37,859,860],{"class":47},"}\n",[37,862,864,867,869,872,875,877,879,882,884,887],{"class":39,"line":863},28,[37,865,866],{"class":43},"    rows ",[37,868,602],{"class":47},[37,870,871],{"class":51}," make",[37,873,874],{"class":47},"([][]",[37,876,311],{"class":310},[37,878,61],{"class":47},[37,880,881],{"class":83}," 0",[37,883,61],{"class":47},[37,885,886],{"class":83}," 120",[37,888,183],{"class":47},[37,890,892,895,898,900,903,906,908,911,913,915,918,921],{"class":39,"line":891},29,[37,893,894],{"class":490},"    for",[37,896,897],{"class":43}," i ",[37,899,602],{"class":47},[37,901,902],{"class":83}," 1",[37,904,905],{"class":47},";",[37,907,897],{"class":43},[37,909,910],{"class":47},"\u003C=",[37,912,886],{"class":83},[37,914,905],{"class":47},[37,916,917],{"class":43}," i",[37,919,920],{"class":47},"++",[37,922,593],{"class":47},[37,924,926,929,932,935,937,940,942,944,946],{"class":39,"line":925},30,[37,927,928],{"class":43},"        rows ",[37,930,931],{"class":47},"=",[37,933,934],{"class":51}," append",[37,936,55],{"class":47},[37,938,939],{"class":43},"rows",[37,941,61],{"class":47},[37,943,307],{"class":47},[37,945,311],{"class":310},[37,947,948],{"class":47},"{\n",[37,950,952,955,957,960,962,964,967,971,974,976,978,980,982,985,988,991,994,997,999,1001,1003,1005,1008,1010,1012],{"class":39,"line":951},31,[37,953,954],{"class":43},"            fmt",[37,956,48],{"class":47},[37,958,959],{"class":51},"Sprintf",[37,961,55],{"class":47},[37,963,823],{"class":47},[37,965,966],{"class":826},"2026-",[37,968,970],{"class":969},"swJcz","%02d",[37,972,973],{"class":826},"-",[37,975,970],{"class":969},[37,977,823],{"class":47},[37,979,61],{"class":47},[37,981,283],{"class":47},[37,983,984],{"class":43},"i",[37,986,987],{"class":47},"%",[37,989,990],{"class":83},"6",[37,992,993],{"class":47},")+",[37,995,996],{"class":83},"1",[37,998,61],{"class":47},[37,1000,283],{"class":47},[37,1002,984],{"class":43},[37,1004,987],{"class":47},[37,1006,1007],{"class":83},"28",[37,1009,993],{"class":47},[37,1011,996],{"class":83},[37,1013,102],{"class":47},[37,1015,1017,1019,1021,1023,1025,1027,1030,1033,1035,1037,1040,1043,1045],{"class":39,"line":1016},32,[37,1018,954],{"class":43},[37,1020,48],{"class":47},[37,1022,959],{"class":51},[37,1024,55],{"class":47},[37,1026,823],{"class":47},[37,1028,1029],{"class":826},"NF-",[37,1031,1032],{"class":969},"%05d",[37,1034,823],{"class":47},[37,1036,61],{"class":47},[37,1038,1039],{"class":83}," 10000",[37,1041,1042],{"class":47},"+",[37,1044,984],{"class":43},[37,1046,102],{"class":47},[37,1048,1050,1052,1054,1056,1058,1060,1063,1066,1068,1070,1072],{"class":39,"line":1049},33,[37,1051,954],{"class":43},[37,1053,48],{"class":47},[37,1055,959],{"class":51},[37,1057,55],{"class":47},[37,1059,823],{"class":47},[37,1061,1062],{"class":826},"Cliente #",[37,1064,1065],{"class":969},"%d",[37,1067,823],{"class":47},[37,1069,61],{"class":47},[37,1071,917],{"class":43},[37,1073,102],{"class":47},[37,1075,1077,1079,1081,1083,1085,1087,1090,1092,1095,1097,1099,1102,1104,1106,1108,1111],{"class":39,"line":1076},34,[37,1078,954],{"class":43},[37,1080,48],{"class":47},[37,1082,959],{"class":51},[37,1084,55],{"class":47},[37,1086,823],{"class":47},[37,1088,1089],{"class":826},"R$",[37,1091,1065],{"class":969},[37,1093,1094],{"class":826},",00",[37,1096,823],{"class":47},[37,1098,61],{"class":47},[37,1100,1101],{"class":83}," 100",[37,1103,1042],{"class":47},[37,1105,984],{"class":43},[37,1107,290],{"class":47},[37,1109,1110],{"class":83},"7",[37,1112,102],{"class":47},[37,1114,1116],{"class":39,"line":1115},35,[37,1117,1118],{"class":47},"        })\n",[37,1120,1122],{"class":39,"line":1121},36,[37,1123,1124],{"class":47},"    }\n",[37,1126,1128],{"class":39,"line":1127},37,[37,1129,485],{"emptyLinePlaceholder":484},[37,1131,1133,1136,1138,1141,1143,1146],{"class":39,"line":1132},38,[37,1134,1135],{"class":43},"    page ",[37,1137,602],{"class":47},[37,1139,1140],{"class":43}," doc",[37,1142,48],{"class":47},[37,1144,1145],{"class":51},"AddPage",[37,1147,1148],{"class":47},"()\n",[37,1150,1152,1155,1157,1160,1163,1166,1169,1171,1173,1176,1178],{"class":39,"line":1151},39,[37,1153,1154],{"class":43},"    page",[37,1156,48],{"class":47},[37,1158,1159],{"class":51},"AutoRow",[37,1161,1162],{"class":47},"(func(",[37,1164,1165],{"class":286},"r",[37,1167,1168],{"class":47}," *",[37,1170,117],{"class":293},[37,1172,48],{"class":47},[37,1174,1175],{"class":293},"RowBuilder",[37,1177,297],{"class":47},[37,1179,593],{"class":47},[37,1181,1183,1186,1188,1191,1193,1196,1198,1201,1203,1205,1207,1209,1211,1213],{"class":39,"line":1182},40,[37,1184,1185],{"class":43},"        r",[37,1187,48],{"class":47},[37,1189,1190],{"class":51},"Col",[37,1192,55],{"class":47},[37,1194,1195],{"class":83},"12",[37,1197,61],{"class":47},[37,1199,1200],{"class":47}," func(",[37,1202,44],{"class":286},[37,1204,1168],{"class":47},[37,1206,117],{"class":293},[37,1208,48],{"class":47},[37,1210,294],{"class":293},[37,1212,297],{"class":47},[37,1214,593],{"class":47},[37,1216,1218,1221,1223,1226,1228,1230,1233,1235,1237,1239,1241,1244,1246,1249,1251,1253,1255,1258],{"class":39,"line":1217},41,[37,1219,1220],{"class":43},"            c",[37,1222,48],{"class":47},[37,1224,1225],{"class":51},"Text",[37,1227,55],{"class":47},[37,1229,823],{"class":47},[37,1231,1232],{"class":826},"Razão S1 2026",[37,1234,823],{"class":47},[37,1236,61],{"class":47},[37,1238,138],{"class":43},[37,1240,48],{"class":47},[37,1242,1243],{"class":51},"FontSize",[37,1245,55],{"class":47},[37,1247,1248],{"class":83},"18",[37,1250,135],{"class":47},[37,1252,138],{"class":43},[37,1254,48],{"class":47},[37,1256,1257],{"class":51},"Bold",[37,1259,1260],{"class":47},"())\n",[37,1262,1264,1266,1268,1271,1273,1275,1277,1279,1281,1284],{"class":39,"line":1263},42,[37,1265,1220],{"class":43},[37,1267,48],{"class":47},[37,1269,1270],{"class":51},"Spacer",[37,1272,55],{"class":47},[37,1274,650],{"class":43},[37,1276,48],{"class":47},[37,1278,664],{"class":51},[37,1280,55],{"class":47},[37,1282,1283],{"class":83},"4",[37,1285,1286],{"class":47},"))\n",[37,1288,1290],{"class":39,"line":1289},43,[37,1291,485],{"emptyLinePlaceholder":484},[37,1293,1295,1297,1299,1301,1303,1305,1307,1309],{"class":39,"line":1294},44,[37,1296,1220],{"class":43},[37,1298,48],{"class":47},[37,1300,52],{"class":51},[37,1302,55],{"class":47},[37,1304,58],{"class":43},[37,1306,61],{"class":47},[37,1308,64],{"class":43},[37,1310,67],{"class":47},[37,1312,1314,1317,1319,1321,1323,1325,1327,1329,1331,1334,1336,1338],{"class":39,"line":1313},45,[37,1315,1316],{"class":43},"                template",[37,1318,48],{"class":47},[37,1320,78],{"class":51},[37,1322,55],{"class":47},[37,1324,669],{"class":83},[37,1326,61],{"class":47},[37,1328,94],{"class":83},[37,1330,61],{"class":47},[37,1332,1333],{"class":83}," 40",[37,1335,61],{"class":47},[37,1337,94],{"class":83},[37,1339,102],{"class":47},[37,1341,1343,1345,1347,1349],{"class":39,"line":1342},46,[37,1344,1316],{"class":43},[37,1346,48],{"class":47},[37,1348,112],{"class":51},[37,1350,613],{"class":47},[37,1352,1354,1357,1359,1361,1363,1365,1367,1369],{"class":39,"line":1353},47,[37,1355,1356],{"class":43},"                    template",[37,1358,48],{"class":47},[37,1360,122],{"class":51},[37,1362,55],{"class":47},[37,1364,127],{"class":43},[37,1366,48],{"class":47},[37,1368,132],{"class":43},[37,1370,102],{"class":47},[37,1372,1374,1376,1378,1380,1382,1384],{"class":39,"line":1373},48,[37,1375,1356],{"class":43},[37,1377,48],{"class":47},[37,1379,143],{"class":51},[37,1381,55],{"class":47},[37,1383,148],{"class":43},[37,1385,102],{"class":47},[37,1387,1389],{"class":39,"line":1388},49,[37,1390,1391],{"class":47},"                ),\n",[37,1393,1395,1397,1399,1401,1403,1406],{"class":39,"line":1394},50,[37,1396,1316],{"class":43},[37,1398,48],{"class":47},[37,1400,161],{"class":51},[37,1402,55],{"class":47},[37,1404,1405],{"class":43},"stripe",[37,1407,102],{"class":47},[37,1409,1411,1413,1415,1418,1420,1423],{"class":39,"line":1410},51,[37,1412,1316],{"class":43},[37,1414,48],{"class":47},[37,1416,1417],{"class":51},"WithTableCellBorder",[37,1419,55],{"class":47},[37,1421,1422],{"class":43},"hairline",[37,1424,102],{"class":47},[37,1426,1428],{"class":39,"line":1427},52,[37,1429,1430],{"class":47},"            )\n",[37,1432,1434],{"class":39,"line":1433},53,[37,1435,1118],{"class":47},[37,1437,1439],{"class":39,"line":1438},54,[37,1440,1441],{"class":47},"    })\n",[37,1443,1445],{"class":39,"line":1444},55,[37,1446,485],{"emptyLinePlaceholder":484},[37,1448,1450,1453,1455,1458,1460,1462,1464,1467],{"class":39,"line":1449},56,[37,1451,1452],{"class":43},"    data",[37,1454,61],{"class":47},[37,1456,1457],{"class":43}," err ",[37,1459,602],{"class":47},[37,1461,1140],{"class":43},[37,1463,48],{"class":47},[37,1465,1466],{"class":51},"Generate",[37,1468,1148],{"class":47},[37,1470,1472,1475,1477,1480,1483],{"class":39,"line":1471},57,[37,1473,1474],{"class":490},"    if",[37,1476,1457],{"class":43},[37,1478,1479],{"class":47},"!=",[37,1481,1482],{"class":47}," nil",[37,1484,593],{"class":47},[37,1486,1488,1491,1493,1496,1498,1501],{"class":39,"line":1487},58,[37,1489,1490],{"class":43},"        log",[37,1492,48],{"class":47},[37,1494,1495],{"class":51},"Fatal",[37,1497,55],{"class":47},[37,1499,1500],{"class":43},"err",[37,1502,183],{"class":47},[37,1504,1506],{"class":39,"line":1505},59,[37,1507,1124],{"class":47},[37,1509,1511,1513,1515,1517,1520,1522,1525,1527,1529,1531,1533,1535,1538,1540,1543,1546,1548,1550,1552],{"class":39,"line":1510},60,[37,1512,1474],{"class":490},[37,1514,1457],{"class":43},[37,1516,602],{"class":47},[37,1518,1519],{"class":43}," os",[37,1521,48],{"class":47},[37,1523,1524],{"class":51},"WriteFile",[37,1526,55],{"class":47},[37,1528,823],{"class":47},[37,1530,466],{"class":826},[37,1532,823],{"class":47},[37,1534,61],{"class":47},[37,1536,1537],{"class":43}," data",[37,1539,61],{"class":47},[37,1541,1542],{"class":83}," 0o644",[37,1544,1545],{"class":47},");",[37,1547,1457],{"class":43},[37,1549,1479],{"class":47},[37,1551,1482],{"class":47},[37,1553,593],{"class":47},[37,1555,1557,1559,1561,1563,1565,1567],{"class":39,"line":1556},61,[37,1558,1490],{"class":43},[37,1560,48],{"class":47},[37,1562,1495],{"class":51},[37,1564,55],{"class":47},[37,1566,1500],{"class":43},[37,1568,183],{"class":47},[37,1570,1572],{"class":39,"line":1571},62,[37,1573,1124],{"class":47},[37,1575,1577],{"class":39,"line":1576},63,[37,1578,860],{"class":47},[19,1580,1581],{},"120 linhas em A4 ocupam cerca de cinco páginas. Em cada uma o cabeçalho azul-escuro reaparece no topo, o corpo continua de onde parou, as listras alternadas seguem coerentes através das quebras. Você não precisa tocar em nada disso.",[19,1583,1584,1585,1589,1590,1593,1594,1597],{},"O que vale notar nesse trecho é o que ",[1586,1587,1588],"em",{},"não"," tem: nenhum loop de linhas, nenhum contador de página, nenhum ",[34,1591,1592],{},"if i == lastRowOnPage"," manual, nenhum ",[34,1595,1596],{},"PageBreak()",", nenhum reemitir de cabeçalho. As quatro linhas de opções declaram como a tabela parece; o motor decide quando e onde quebrar.",[14,1599,1601],{"id":1600},"larguras-de-coluna-porcentagens-de-quê","Larguras de coluna: porcentagens de quê",[19,1603,1604,1607,1608,1611],{},[34,1605,1606],{},"ColumnWidths(40, 15, 20, 25)"," parece o CSS ",[34,1609,1610],{},"\u003Ccol width=\"40%\">",". Quase. Com três arestas afiadas.",[19,1613,1614,1617,1618,1621,1622,1625,1626,1629],{},[22,1615,1616],{},"A porcentagem é do Col pai, não da página."," Um ",[34,1619,1620],{},"r.Col(6, ...)"," ocupa metade da largura de conteúdo da linha. Uma tabela dentro com ",[34,1623,1624],{},"ColumnWidths(50, 50)"," produz duas colunas com ",[22,1627,1628],{},"25% da largura da linha",", não 50%. As porcentagens são locais ao lugar onde a tabela mora. Quando você move uma tabela de uma linha de largura inteira para um layout lado a lado, a chamada da opção não precisa mudar.",[19,1631,1632,1635],{},[22,1633,1634],{},"Sem normalização."," Se suas larguras somam 90, sobra 10% vazio à direita. Se somam 110, a coluna mais à direita transborda o pai e vaza para a página. O gpdf confia na sua aritmética. Sem aviso — e nem deveria: corrigir automaticamente o valor que você escreveu é pior que o bug.",[19,1637,1638,1641],{},[22,1639,1640],{},"Faltantes ao final auto-distribuem."," Passe menos larguras do que colunas e as restantes dividem o que sobra em partes iguais:",[27,1643,1645],{"className":29,"code":1644,"language":31,"meta":32,"style":32},"// Tabela de cinco colunas, três larguras dadas.\ntemplate.ColumnWidths(40, 10, 20)\n// → 40% / 10% / 20% / 15% / 15%   (30% dividido entre as duas finais)\n",[34,1646,1647,1653,1676],{"__ignoreMap":32},[37,1648,1649],{"class":39,"line":40},[37,1650,1652],{"class":1651},"sHwdD","// Tabela de cinco colunas, três larguras dadas.\n",[37,1654,1655,1657,1659,1661,1663,1665,1667,1670,1672,1674],{"class":39,"line":70},[37,1656,117],{"class":43},[37,1658,48],{"class":47},[37,1660,78],{"class":51},[37,1662,55],{"class":47},[37,1664,84],{"class":83},[37,1666,61],{"class":47},[37,1668,1669],{"class":83}," 10",[37,1671,61],{"class":47},[37,1673,94],{"class":83},[37,1675,183],{"class":47},[37,1677,1678],{"class":39,"line":105},[37,1679,1680],{"class":1651},"// → 40% / 10% / 20% / 15% / 15%   (30% dividido entre as duas finais)\n",[19,1682,1683,1684,1687],{},"Truque útil para \"me importam essas larguras específicas; o resto se vire\". Passar ",[34,1685,1686],{},"0"," explícito também marca a coluna como auto:",[27,1689,1691],{"className":29,"code":1690,"language":31,"meta":32,"style":32},"template.ColumnWidths(0, 30, 30) // → 40% / 30% / 30% numa tabela de 3 colunas\n",[34,1692,1693],{"__ignoreMap":32},[37,1694,1695,1697,1699,1701,1703,1705,1707,1710,1712,1714,1716],{"class":39,"line":40},[37,1696,117],{"class":43},[37,1698,48],{"class":47},[37,1700,78],{"class":51},[37,1702,55],{"class":47},[37,1704,1686],{"class":83},[37,1706,61],{"class":47},[37,1708,1709],{"class":83}," 30",[37,1711,61],{"class":47},[37,1713,1709],{"class":83},[37,1715,297],{"class":47},[37,1717,1718],{"class":1651}," // → 40% / 30% / 30% numa tabela de 3 colunas\n",[19,1720,1721,1722,1726],{},"Para os cantos finos das larguras, veja a ",[213,1723,1725],{"href":1724},"/pt/blog/table-column-widths","receita de larguras de coluna",". Resumo: porcentagens cobrem 95% dos layouts; quando não, você desce uma camada. Descrito adiante.",[14,1728,1730],{"id":1729},"listras-o-loop-de-linhas-que-você-não-escreve","Listras: o loop de linhas que você não escreve",[27,1732,1734],{"className":29,"code":1733,"language":31,"meta":32,"style":32},"template.TableStripe(pdf.RGBHex(0xF5F5F5))\n",[34,1735,1736],{"__ignoreMap":32},[37,1737,1738,1740,1742,1744,1746,1748,1750,1752,1754,1756],{"class":39,"line":40},[37,1739,117],{"class":43},[37,1741,48],{"class":47},[37,1743,161],{"class":51},[37,1745,55],{"class":47},[37,1747,127],{"class":43},[37,1749,48],{"class":47},[37,1751,170],{"class":51},[37,1753,55],{"class":47},[37,1755,175],{"class":83},[37,1757,1286],{"class":47},[19,1759,1760,1761,1763,1764,1767],{},"É só isso. O gpdf percorre as linhas do corpo com um índice ",[34,1762,984],{}," desde 0 e tinge as linhas com ",[34,1765,1766],{},"i % 2 == 1",". O cabeçalho é seu próprio slice e não conta, então a primeira linha do corpo fica limpa e a segunda sombreada — convenção Bootstrap.",[19,1769,1770,1771,240,1774,1777,1778,1781,1782,1785],{},"Por que essa opção existe: em ",[34,1772,1773],{},"gofpdf",[34,1775,1776],{},"gopdf"," você escreve o loop, chama ",[34,1779,1780],{},"SetFillColor"," por linha e invoca ",[34,1783,1784],{},"CellFormat"," com a flag de preenchimento. São oito ou dez linhas e a taxa de off-by-one é alta o suficiente para o StackOverflow ter um conjunto de respostas dedicado. Empacotar isso em uma opção faz a classe inteira de bug desaparecer.",[19,1787,1788],{},"Restrições deliberadas:",[1790,1791,1792,1798,1804],"ul",{},[231,1793,1794,1797],{},[22,1795,1796],{},"Uma cor de listra, não duas."," Sem \"alternar entre azul e cinza\". A página já é branca, então a linha sem listra é automaticamente branca. Pedir um ciclo de três cores é pedir ao leitor para pensar mais — listras zebra existem para o oposto.",[231,1799,1800,1803],{},[22,1801,1802],{},"Sem inverter a paridade."," A primeira linha do corpo é sempre limpa, a segunda sempre sombreada. Se você quer mesmo invertido, ponha uma linha em branco no início. Mas ninguém quer isso de verdade.",[231,1805,1806,1809],{},[22,1807,1808],{},"Listras atravessam quebras de página corretamente."," A linha 14 do corpo continua sendo paridade-14 quando aterrissa na página 2. O motor leva o índice através do corte.",[19,1811,1812,1813,1817,1818,1821],{},"Para escolha de cor e variantes para tema escuro, a ",[213,1814,1816],{"href":1815},"/pt/blog/zebra-striped-table-rows","receita de listras zebra"," tem a discussão de paleta. O ponto deste post: uma propriedade da ",[1586,1819,1820],{},"tabela"," (a alternância) é configurada na chamada da tabela, não por linha.",[14,1823,1825],{"id":1824},"quebras-de-página-a-parte-que-é-difícil-de-verdade","Quebras de página: a parte que é difícil de verdade",[19,1827,1828],{},"É aqui que a maioria das histórias de PDF em Go desmorona, e onde o design do gpdf rende mais.",[19,1830,1831,1832,1838],{},"Versão simples: ",[22,1833,1834,1835,1837],{},"escreva uma tabela com mais linhas do que cabem em uma página e o gpdf pagina para você. O slice ",[34,1836,197],{}," é repetido no topo de cada página de continuação."," Nenhuma opção para ligar. Nenhum método para chamar. É o comportamento padrão do motor.",[19,1840,1841,1842,1845,1846,1849,1850,1853,1854,1856,1857,1860,1861,1864],{},"Versão real, mais interessante. O motor de layout (",[34,1843,1844],{},"document/layout/block.go",") maquina a tabela com a altura disponível. Quando o corpo não cabe, o resultado inclui um campo ",[34,1847,1848],{},"Overflow"," — um novo ",[34,1851,1852],{},"*document.Table"," com o mesmo ",[34,1855,197],{},", o mesmo ",[34,1858,1859],{},"Footer"," e as linhas ",[1586,1862,1863],{},"restantes",". O sistema de páginas despeja a parte ajustada na página atual, abre a próxima e devolve a tabela overflow ao motor com a nova altura disponível. Repete até overflow estar vazio.",[19,1866,1867],{},"Duas consequências do design:",[228,1869,1870,1883],{},[231,1871,1872,1879,1880,1882],{},[22,1873,1874,1875,1878],{},"O cabeçalho mora em ",[34,1876,1877],{},"tbl.Header",", não no loop."," Como a tabela overflow reusa o mesmo slice ",[34,1881,197],{},", o cabeçalho é repetido automaticamente em cada página de continuação. Mesmo estilo, mesmas larguras, tudo igual.",[231,1884,1885,1888],{},[22,1886,1887],{},"Não há caso-limite \"o cabeçalho não cabe nessa página\"."," O motor reserva espaço para o cabeçalho antes de medir quantas linhas do corpo cabem. Se a página não aguenta cabeçalho mais ao menos uma linha do corpo, a tabela inteira vai para a próxima.",[19,1890,1891],{},"Rodapés — quando você os usa na camada documento — funcionam igual: levados em cada página de continuação automaticamente.",[19,1893,1894,1895,1898],{},"O que você não tem: uma anotação \"mantenha esse grupo de linhas junto\", supressão de quebra em uma linha específica ou \"comece esta tabela em uma página nova\". As duas primeiras são TODO. A terceira você faz na camada de página — ",[34,1896,1897],{},"doc.AddPage()"," antes da linha que contém a tabela.",[14,1900,1902],{"id":1901},"quando-você-superou-a-api-builder","Quando você superou a API builder",[19,1904,1905,1906,48],{},"O builder é bom para casos comuns. Quando você precisa de células mescladas, larguras fixas em pt, rodapé repetido ou misturar tipos de conteúdo por célula, desce para ",[34,1907,201],{},[27,1909,1911],{"className":29,"code":1910,"language":31,"meta":32,"style":32},"import (\n    \"github.com/gpdf-dev/gpdf/document\"\n)\n\nfooter := document.TableRow{\n    Cells: []document.TableCell{\n        {\n            Content: []document.DocumentNode{\n                &document.Text{Content: \"Total\", TextStyle: document.DefaultStyle()},\n            },\n            ColSpan: 3, // ← cobre as três primeiras colunas\n            RowSpan: 1,\n        },\n        {\n            Content: []document.DocumentNode{\n                &document.Text{Content: \"R$48.720,00\", TextStyle: document.DefaultStyle()},\n            },\n            ColSpan: 1,\n            RowSpan: 1,\n        },\n    },\n}\n\ntbl := &document.Table{\n    Columns: []document.TableColumn{\n        {Width: document.Pct(20)},\n        {Width: document.Pct(20)},\n        {Width: document.Auto},\n        {Width: document.Pt(80)}, // 80pt fixos independente da largura da página\n    },\n    Header: /* ... */,\n    Body:   /* ... */,\n    Footer: []document.TableRow{footer},\n}\n",[34,1912,1913,1919,1927,1931,1935,1952,1971,1976,1994,2036,2041,2056,2067,2072,2076,2092,2129,2133,2143,2153,2157,2162,2166,2170,2188,2206,2230,2250,2268,2293,2297,2309,2321,2343],{"__ignoreMap":32},[37,1914,1915,1917],{"class":39,"line":40},[37,1916,491],{"class":490},[37,1918,494],{"class":47},[37,1920,1921,1923,1925],{"class":39,"line":70},[37,1922,499],{"class":47},[37,1924,547],{"class":293},[37,1926,505],{"class":47},[37,1928,1929],{"class":39,"line":105},[37,1930,183],{"class":47},[37,1932,1933],{"class":39,"line":154},[37,1934,485],{"emptyLinePlaceholder":484},[37,1936,1937,1940,1942,1945,1947,1950],{"class":39,"line":180},[37,1938,1939],{"class":43},"footer ",[37,1941,602],{"class":47},[37,1943,1944],{"class":293}," document",[37,1946,48],{"class":47},[37,1948,1949],{"class":293},"TableRow",[37,1951,948],{"class":47},[37,1953,1954,1957,1960,1962,1964,1966,1969],{"class":39,"line":517},[37,1955,1956],{"class":43},"    Cells",[37,1958,1959],{"class":47},":",[37,1961,307],{"class":47},[37,1963,650],{"class":293},[37,1965,48],{"class":47},[37,1967,1968],{"class":293},"TableCell",[37,1970,948],{"class":47},[37,1972,1973],{"class":39,"line":527},[37,1974,1975],{"class":47},"        {\n",[37,1977,1978,1981,1983,1985,1987,1989,1992],{"class":39,"line":532},[37,1979,1980],{"class":43},"            Content",[37,1982,1959],{"class":47},[37,1984,307],{"class":47},[37,1986,650],{"class":293},[37,1988,48],{"class":47},[37,1990,1991],{"class":293},"DocumentNode",[37,1993,948],{"class":47},[37,1995,1996,1999,2001,2003,2005,2007,2010,2012,2014,2017,2019,2021,2024,2026,2028,2030,2033],{"class":39,"line":542},[37,1997,1998],{"class":47},"                &",[37,2000,650],{"class":293},[37,2002,48],{"class":47},[37,2004,1225],{"class":293},[37,2006,820],{"class":47},[37,2008,2009],{"class":43},"Content",[37,2011,1959],{"class":47},[37,2013,834],{"class":47},[37,2015,2016],{"class":826},"Total",[37,2018,823],{"class":47},[37,2020,61],{"class":47},[37,2022,2023],{"class":43}," TextStyle",[37,2025,1959],{"class":47},[37,2027,1944],{"class":43},[37,2029,48],{"class":47},[37,2031,2032],{"class":51},"DefaultStyle",[37,2034,2035],{"class":47},"()},\n",[37,2037,2038],{"class":39,"line":552},[37,2039,2040],{"class":47},"            },\n",[37,2042,2043,2046,2048,2051,2053],{"class":39,"line":562},[37,2044,2045],{"class":43},"            ColSpan",[37,2047,1959],{"class":47},[37,2049,2050],{"class":83}," 3",[37,2052,61],{"class":47},[37,2054,2055],{"class":1651}," // ← cobre as três primeiras colunas\n",[37,2057,2058,2061,2063,2065],{"class":39,"line":572},[37,2059,2060],{"class":43},"            RowSpan",[37,2062,1959],{"class":47},[37,2064,902],{"class":83},[37,2066,67],{"class":47},[37,2068,2069],{"class":39,"line":577},[37,2070,2071],{"class":47},"        },\n",[37,2073,2074],{"class":39,"line":582},[37,2075,1975],{"class":47},[37,2077,2078,2080,2082,2084,2086,2088,2090],{"class":39,"line":596},[37,2079,1980],{"class":43},[37,2081,1959],{"class":47},[37,2083,307],{"class":47},[37,2085,650],{"class":293},[37,2087,48],{"class":47},[37,2089,1991],{"class":293},[37,2091,948],{"class":47},[37,2093,2094,2096,2098,2100,2102,2104,2106,2108,2110,2113,2115,2117,2119,2121,2123,2125,2127],{"class":39,"line":616},[37,2095,1998],{"class":47},[37,2097,650],{"class":293},[37,2099,48],{"class":47},[37,2101,1225],{"class":293},[37,2103,820],{"class":47},[37,2105,2009],{"class":43},[37,2107,1959],{"class":47},[37,2109,834],{"class":47},[37,2111,2112],{"class":826},"R$48.720,00",[37,2114,823],{"class":47},[37,2116,61],{"class":47},[37,2118,2023],{"class":43},[37,2120,1959],{"class":47},[37,2122,1944],{"class":43},[37,2124,48],{"class":47},[37,2126,2032],{"class":51},[37,2128,2035],{"class":47},[37,2130,2131],{"class":39,"line":638},[37,2132,2040],{"class":47},[37,2134,2135,2137,2139,2141],{"class":39,"line":675},[37,2136,2045],{"class":43},[37,2138,1959],{"class":47},[37,2140,902],{"class":83},[37,2142,67],{"class":47},[37,2144,2145,2147,2149,2151],{"class":39,"line":681},[37,2146,2060],{"class":43},[37,2148,1959],{"class":47},[37,2150,902],{"class":83},[37,2152,67],{"class":47},[37,2154,2155],{"class":39,"line":686},[37,2156,2071],{"class":47},[37,2158,2159],{"class":39,"line":708},[37,2160,2161],{"class":47},"    },\n",[37,2163,2164],{"class":39,"line":728},[37,2165,860],{"class":47},[37,2167,2168],{"class":39,"line":745},[37,2169,485],{"emptyLinePlaceholder":484},[37,2171,2172,2175,2177,2180,2182,2184,2186],{"class":39,"line":772},[37,2173,2174],{"class":43},"tbl ",[37,2176,602],{"class":47},[37,2178,2179],{"class":47}," &",[37,2181,650],{"class":293},[37,2183,48],{"class":47},[37,2185,52],{"class":293},[37,2187,948],{"class":47},[37,2189,2190,2193,2195,2197,2199,2201,2204],{"class":39,"line":798},[37,2191,2192],{"class":43},"    Columns",[37,2194,1959],{"class":47},[37,2196,307],{"class":47},[37,2198,650],{"class":293},[37,2200,48],{"class":47},[37,2202,2203],{"class":293},"TableColumn",[37,2205,948],{"class":47},[37,2207,2208,2211,2214,2216,2218,2220,2223,2225,2227],{"class":39,"line":803},[37,2209,2210],{"class":47},"        {",[37,2212,2213],{"class":43},"Width",[37,2215,1959],{"class":47},[37,2217,1944],{"class":43},[37,2219,48],{"class":47},[37,2221,2222],{"class":51},"Pct",[37,2224,55],{"class":47},[37,2226,669],{"class":83},[37,2228,2229],{"class":47},")},\n",[37,2231,2232,2234,2236,2238,2240,2242,2244,2246,2248],{"class":39,"line":808},[37,2233,2210],{"class":47},[37,2235,2213],{"class":43},[37,2237,1959],{"class":47},[37,2239,1944],{"class":43},[37,2241,48],{"class":47},[37,2243,2222],{"class":51},[37,2245,55],{"class":47},[37,2247,669],{"class":83},[37,2249,2229],{"class":47},[37,2251,2252,2254,2256,2258,2260,2262,2265],{"class":39,"line":863},[37,2253,2210],{"class":47},[37,2255,2213],{"class":43},[37,2257,1959],{"class":47},[37,2259,1944],{"class":43},[37,2261,48],{"class":47},[37,2263,2264],{"class":43},"Auto",[37,2266,2267],{"class":47},"},\n",[37,2269,2270,2272,2274,2276,2278,2280,2282,2284,2287,2290],{"class":39,"line":891},[37,2271,2210],{"class":47},[37,2273,2213],{"class":43},[37,2275,1959],{"class":47},[37,2277,1944],{"class":43},[37,2279,48],{"class":47},[37,2281,762],{"class":51},[37,2283,55],{"class":47},[37,2285,2286],{"class":83},"80",[37,2288,2289],{"class":47},")},",[37,2291,2292],{"class":1651}," // 80pt fixos independente da largura da página\n",[37,2294,2295],{"class":39,"line":925},[37,2296,2161],{"class":47},[37,2298,2299,2302,2304,2307],{"class":39,"line":951},[37,2300,2301],{"class":43},"    Header",[37,2303,1959],{"class":47},[37,2305,2306],{"class":1651}," /* ... */",[37,2308,67],{"class":47},[37,2310,2311,2314,2316,2319],{"class":39,"line":1016},[37,2312,2313],{"class":43},"    Body",[37,2315,1959],{"class":47},[37,2317,2318],{"class":1651},"   /* ... */",[37,2320,67],{"class":47},[37,2322,2323,2326,2328,2330,2332,2334,2336,2338,2341],{"class":39,"line":1049},[37,2324,2325],{"class":43},"    Footer",[37,2327,1959],{"class":47},[37,2329,307],{"class":47},[37,2331,650],{"class":293},[37,2333,48],{"class":47},[37,2335,1949],{"class":293},[37,2337,820],{"class":47},[37,2339,2340],{"class":43},"footer",[37,2342,2267],{"class":47},[37,2344,2345],{"class":39,"line":1076},[37,2346,860],{"class":47},[19,2348,2349,2350,2353,2354,2357,2358,2360,2361,2360,2363,2360,2366,2360,2369,2360,2372,2374,2375,2377,2378,2380,2381,2383],{},"Algumas coisas para notar. ",[34,2351,2352],{},"TableColumn.Width"," é um ",[34,2355,2356],{},"document.Value"," — ",[34,2359,762],{},", ",[34,2362,664],{},[34,2364,2365],{},"Cm",[34,2367,2368],{},"In",[34,2370,2371],{},"Em",[34,2373,2222],{}," ou o especial ",[34,2376,2264],{},". Você mistura na mesma tabela. Colunas ",[34,2379,2264],{}," compartilham o que sobra após as fixas e em porcentagem. Mais perto do elemento ",[34,2382,239],{}," do CSS do que do modelo só-porcentagem do builder.",[19,2385,2386,240,2389,2392],{},[34,2387,2388],{},"TableCell.ColSpan",[34,2390,2391],{},"RowSpan"," são inteiros, padrão 1. O exemplo é o rodapé clássico de NF: três colunas do cabeçalho mescladas em \"Total\" e a quarta com a soma.",[19,2394,2395,2398,2399,2402],{},[34,2396,2397],{},"document.Table.Footer"," é ",[34,2400,2401],{},"[]TableRow"," repetido em cada página, igual ao cabeçalho. A API builder não expõe porque tabelas curtas em geral não precisam — quando você precisa, já saiu da zona \"caso comum\".",[19,2404,2405,2406,48],{},"Esse é o padrão geral do gpdf: o builder de alto nível cobre 90% com ergonomia, e a camada documento está bem ao lado para os outros 10%. Não são bibliotecas separadas. Você pode misturar linhas de builder e linhas montadas a mão no mesmo documento. O builder é só um construtor do mesmo nó ",[34,2407,201],{},[14,2409,2411],{"id":2410},"bordas-e-o-modelo-de-caixa","Bordas e o modelo de caixa",[19,2413,2414],{},"Três opções de borda, três trabalhos diferentes:",[27,2416,2418],{"className":29,"code":2417,"language":31,"meta":32,"style":32},"template.WithTableBorder(spec)         // moldura externa de toda a tabela\ntemplate.WithTableCellBorder(spec)     // mesma borda em volta de cada célula\ntemplate.WithTableBorderCollapse(true) // mescla bordas adjacentes\n",[34,2419,2420,2439,2456],{"__ignoreMap":32},[37,2421,2422,2424,2426,2429,2431,2434,2436],{"class":39,"line":40},[37,2423,117],{"class":43},[37,2425,48],{"class":47},[37,2427,2428],{"class":51},"WithTableBorder",[37,2430,55],{"class":47},[37,2432,2433],{"class":43},"spec",[37,2435,297],{"class":47},[37,2437,2438],{"class":1651},"         // moldura externa de toda a tabela\n",[37,2440,2441,2443,2445,2447,2449,2451,2453],{"class":39,"line":70},[37,2442,117],{"class":43},[37,2444,48],{"class":47},[37,2446,1417],{"class":51},[37,2448,55],{"class":47},[37,2450,2433],{"class":43},[37,2452,297],{"class":47},[37,2454,2455],{"class":1651},"     // mesma borda em volta de cada célula\n",[37,2457,2458,2460,2462,2465,2467,2471,2473],{"class":39,"line":105},[37,2459,117],{"class":43},[37,2461,48],{"class":47},[37,2463,2464],{"class":51},"WithTableBorderCollapse",[37,2466,55],{"class":47},[37,2468,2470],{"class":2469},"sfNiH","true",[37,2472,297],{"class":47},[37,2474,2475],{"class":1651}," // mescla bordas adjacentes\n",[19,2477,2478,2479,2481,2482,2484,2485,2488,2489,48],{},"Por padrão, sem bordas. Adicione ",[34,2480,2428],{}," para uma moldura. Adicione ",[34,2483,1417],{}," para o visual de grade. Os dois juntos = moldura em volta da grade. O ",[34,2486,2487],{},"BorderSpec"," é construído com ",[34,2490,2491],{},"template.Border(template.BorderWidth(...), template.BorderColor(...))",[19,2493,2494,2497],{},[34,2495,2496],{},"WithTableBorderCollapse(true)"," é o análogo CSS: bordas adjacentes mesclam em uma única linha (em vez de desenhar duas vezes, uma por borda de célula). Em grades hairline onde a borda importa visualmente, collapse fica mais limpo. Em bordas grossas onde você quer o efeito duplicado de propósito, deixe desligado. O padrão é separado.",[19,2499,2500],{},"Combinação útil: bordas hairline nas células + listras claras:",[27,2502,2504],{"className":29,"code":2503,"language":31,"meta":32,"style":32},"c.Table(header, rows,\n    template.ColumnWidths(40, 20, 15, 25),\n    template.TableHeaderStyle(template.TextColor(pdf.White), template.BgColor(brand)),\n    template.TableStripe(pdf.RGBHex(0xF5F5F5)),\n    template.WithTableCellBorder(template.Border(\n        template.BorderWidth(document.Pt(0.5)),\n        template.BorderColor(pdf.Gray(0.85)),\n    )),\n    template.WithTableBorderCollapse(true),\n)\n",[34,2505,2506,2524,2550,2588,2610,2628,2650,2672,2677,2691],{"__ignoreMap":32},[37,2507,2508,2510,2512,2514,2516,2518,2520,2522],{"class":39,"line":40},[37,2509,44],{"class":43},[37,2511,48],{"class":47},[37,2513,52],{"class":51},[37,2515,55],{"class":47},[37,2517,58],{"class":43},[37,2519,61],{"class":47},[37,2521,64],{"class":43},[37,2523,67],{"class":47},[37,2525,2526,2528,2530,2532,2534,2536,2538,2540,2542,2544,2546,2548],{"class":39,"line":70},[37,2527,73],{"class":43},[37,2529,48],{"class":47},[37,2531,78],{"class":51},[37,2533,55],{"class":47},[37,2535,84],{"class":83},[37,2537,61],{"class":47},[37,2539,94],{"class":83},[37,2541,61],{"class":47},[37,2543,89],{"class":83},[37,2545,61],{"class":47},[37,2547,99],{"class":83},[37,2549,102],{"class":47},[37,2551,2552,2554,2556,2558,2560,2562,2564,2566,2568,2570,2572,2574,2576,2578,2580,2582,2584,2586],{"class":39,"line":105},[37,2553,73],{"class":43},[37,2555,48],{"class":47},[37,2557,112],{"class":51},[37,2559,55],{"class":47},[37,2561,117],{"class":43},[37,2563,48],{"class":47},[37,2565,122],{"class":51},[37,2567,55],{"class":47},[37,2569,127],{"class":43},[37,2571,48],{"class":47},[37,2573,132],{"class":43},[37,2575,135],{"class":47},[37,2577,138],{"class":43},[37,2579,48],{"class":47},[37,2581,143],{"class":51},[37,2583,55],{"class":47},[37,2585,148],{"class":43},[37,2587,151],{"class":47},[37,2589,2590,2592,2594,2596,2598,2600,2602,2604,2606,2608],{"class":39,"line":154},[37,2591,73],{"class":43},[37,2593,48],{"class":47},[37,2595,161],{"class":51},[37,2597,55],{"class":47},[37,2599,127],{"class":43},[37,2601,48],{"class":47},[37,2603,170],{"class":51},[37,2605,55],{"class":47},[37,2607,175],{"class":83},[37,2609,151],{"class":47},[37,2611,2612,2614,2616,2618,2620,2622,2624,2626],{"class":39,"line":180},[37,2613,73],{"class":43},[37,2615,48],{"class":47},[37,2617,1417],{"class":51},[37,2619,55],{"class":47},[37,2621,117],{"class":43},[37,2623,48],{"class":47},[37,2625,740],{"class":51},[37,2627,613],{"class":47},[37,2629,2630,2632,2634,2636,2638,2640,2642,2644,2646,2648],{"class":39,"line":517},[37,2631,748],{"class":43},[37,2633,48],{"class":47},[37,2635,753],{"class":51},[37,2637,55],{"class":47},[37,2639,650],{"class":43},[37,2641,48],{"class":47},[37,2643,762],{"class":51},[37,2645,55],{"class":47},[37,2647,767],{"class":83},[37,2649,151],{"class":47},[37,2651,2652,2654,2656,2658,2660,2662,2664,2666,2668,2670],{"class":39,"line":527},[37,2653,748],{"class":43},[37,2655,48],{"class":47},[37,2657,779],{"class":51},[37,2659,55],{"class":47},[37,2661,127],{"class":43},[37,2663,48],{"class":47},[37,2665,788],{"class":51},[37,2667,55],{"class":47},[37,2669,793],{"class":83},[37,2671,151],{"class":47},[37,2673,2674],{"class":39,"line":532},[37,2675,2676],{"class":47},"    )),\n",[37,2678,2679,2681,2683,2685,2687,2689],{"class":39,"line":542},[37,2680,73],{"class":43},[37,2682,48],{"class":47},[37,2684,2464],{"class":51},[37,2686,55],{"class":47},[37,2688,2470],{"class":2469},[37,2690,102],{"class":47},[37,2692,2693],{"class":39,"line":552},[37,2694,183],{"class":47},[19,2696,2697],{},"O visual em que toda prévia de impressão de planilha de contador acaba caindo, deliberadamente. É o padrão certo para qualquer documento financeiro adjacente — NFs, extratos, livros razão, relatórios de despesa.",[14,2699,2701],{"id":2700},"como-isso-compara-com-as-alternativas","Como isso compara com as alternativas",[19,2703,2704],{},"Para contexto, o que a mesma tabela multipágina com listras custa nas bibliotecas que o gpdf costuma substituir:",[341,2706,2707,2726],{},[344,2708,2709],{},[347,2710,2711,2714,2717,2720,2723],{},[350,2712,2713],{},"Biblioteca",[350,2715,2716],{},"Linhas para a tabela",[350,2718,2719],{},"Cabeçalho repetido em quebra",[350,2721,2722],{},"Listras",[350,2724,2725],{},"Notas",[357,2727,2728,2754,2776,2791,2807,2826],{},[347,2729,2730,2734,2739,2744,2751],{},[362,2731,2732],{},[22,2733,218],{},[362,2735,2736],{},[22,2737,2738],{},"~10",[362,2740,2741],{},[22,2742,2743],{},"automático",[362,2745,2746],{},[22,2747,2748],{},[34,2749,2750],{},"TableStripe(...)",[362,2752,2753],{},"Builder e baixo nível disponíveis",[347,2755,2756,2759,2762,2768,2773],{},[362,2757,2758],{},"jung-kurt/gofpdf (arquivado em 2021)",[362,2760,2761],{},"40–60",[362,2763,2764,2765,2767],{},"manual: rastrear Y, chamar ",[34,2766,1145],{},", reemitir cabeçalho",[362,2769,2770,2771],{},"loop manual com ",[34,2772,1780],{},[362,2774,2775],{},"Fundacional, sem manutenção",[347,2777,2778,2781,2783,2786,2788],{},[362,2779,2780],{},"go-pdf/fpdf (arquivado em 2025)",[362,2782,2761],{},[362,2784,2785],{},"igual",[362,2787,2785],{},[362,2789,2790],{},"Era fork de gofpdf, mesmo modelo",[347,2792,2793,2796,2799,2802,2804],{},[362,2794,2795],{},"signintech/gopdf",[362,2797,2798],{},"50–80",[362,2800,2801],{},"manual",[362,2803,2801],{},[362,2805,2806],{},"Ainda mais baixo nível",[347,2808,2809,2812,2815,2817,2823],{},[362,2810,2811],{},"johnfercher/maroto v2",[362,2813,2814],{},"~15",[362,2816,2743],{},[362,2818,2819,2822],{},[34,2820,2821],{},"WithBackgroundColor"," por linha à mão",[362,2824,2825],{},"Sobre gofpdf; API agradável mas herda dependências",[347,2827,2828,2831,2834,2836,2839],{},[362,2829,2830],{},"unidoc/unipdf",[362,2832,2833],{},"~12",[362,2835,2743],{},[362,2837,2838],{},"helper de estilo de linha",[362,2840,2841],{},"Licença comercial obrigatória",[19,2843,2844,2845,2847,2848,2850],{},"Comparando só linhas no builder, a diferença aperta. A diferença real aparece no mês 6 de uso, quando os requisitos derivam — uma nova coluna precisa de outro alinhamento, o relatório precisa sair em japonês, o cliente quer a contagem de linhas no rodapé. Com ",[34,2846,1773],{}," ou ",[34,2849,1776],{},", cada deriva exige tocar no loop de linhas. Com gpdf, a lista de opções cresce e o corpo do código não muda.",[19,2852,2853,2854,2858,2859,2863],{},"Para benchmarks — os números µs por tabela — veja ",[213,2855,2857],{"href":2856},"/pt/blog/why-gpdf-is-faster","por que o gpdf é mais rápido",". Para o showdown mais amplo, ",[213,2860,2862],{"href":2861},"/pt/blog/go-pdf-library-showdown-2026","o showdown de 2026"," vai coluna a coluna.",[14,2865,2867],{"id":2866},"cjk-em-tabelas","CJK em tabelas",[19,2869,2870],{},"Algo invisível na tabela comparativa acima: o gpdf renderiza glifos CJK nativamente. Não há \"modo japonês\" para tabelas — você registra a fonte uma vez e a tabela usa para tudo.",[27,2872,2874],{"className":29,"code":2873,"language":31,"meta":32,"style":32},"ttf, _ := os.ReadFile(\"NotoSansJP-Regular.ttf\")\ndoc := gpdf.NewDocument(\n    gpdf.WithPageSize(gpdf.A4),\n    gpdf.WithFont(\"NotoSansJP\", ttf),\n    gpdf.WithDefaultFont(\"NotoSansJP\"),\n)\n\nc.Table(\n    []string{\"日付\", \"請求書番号\", \"顧客名\", \"金額\"},\n    [][]string{\n        {\"2026-04-01\", \"INV-10001\", \"株式会社サンプル\", \"￥120,000\"},\n        {\"2026-04-02\", \"INV-10002\", \"山田商店\", \"￥38,500\"},\n    },\n    template.ColumnWidths(20, 20, 40, 20),\n)\n",[34,2875,2876,2906,2921,2940,2965,2984,2988,2992,3002,3047,3056,3096,3136,3140,3166],{"__ignoreMap":32},[37,2877,2878,2881,2883,2886,2888,2890,2892,2895,2897,2899,2902,2904],{"class":39,"line":40},[37,2879,2880],{"class":43},"ttf",[37,2882,61],{"class":47},[37,2884,2885],{"class":43}," _ ",[37,2887,602],{"class":47},[37,2889,1519],{"class":43},[37,2891,48],{"class":47},[37,2893,2894],{"class":51},"ReadFile",[37,2896,55],{"class":47},[37,2898,823],{"class":47},[37,2900,2901],{"class":826},"NotoSansJP-Regular.ttf",[37,2903,823],{"class":47},[37,2905,183],{"class":47},[37,2907,2908,2911,2913,2915,2917,2919],{"class":39,"line":70},[37,2909,2910],{"class":43},"doc ",[37,2912,602],{"class":47},[37,2914,605],{"class":43},[37,2916,48],{"class":47},[37,2918,610],{"class":51},[37,2920,613],{"class":47},[37,2922,2923,2926,2928,2930,2932,2934,2936,2938],{"class":39,"line":105},[37,2924,2925],{"class":43},"    gpdf",[37,2927,48],{"class":47},[37,2929,624],{"class":51},[37,2931,55],{"class":47},[37,2933,218],{"class":43},[37,2935,48],{"class":47},[37,2937,633],{"class":43},[37,2939,102],{"class":47},[37,2941,2942,2944,2946,2949,2951,2953,2956,2958,2960,2963],{"class":39,"line":154},[37,2943,2925],{"class":43},[37,2945,48],{"class":47},[37,2947,2948],{"class":51},"WithFont",[37,2950,55],{"class":47},[37,2952,823],{"class":47},[37,2954,2955],{"class":826},"NotoSansJP",[37,2957,823],{"class":47},[37,2959,61],{"class":47},[37,2961,2962],{"class":43}," ttf",[37,2964,102],{"class":47},[37,2966,2967,2969,2971,2974,2976,2978,2980,2982],{"class":39,"line":180},[37,2968,2925],{"class":43},[37,2970,48],{"class":47},[37,2972,2973],{"class":51},"WithDefaultFont",[37,2975,55],{"class":47},[37,2977,823],{"class":47},[37,2979,2955],{"class":826},[37,2981,823],{"class":47},[37,2983,102],{"class":47},[37,2985,2986],{"class":39,"line":517},[37,2987,183],{"class":47},[37,2989,2990],{"class":39,"line":527},[37,2991,485],{"emptyLinePlaceholder":484},[37,2993,2994,2996,2998,3000],{"class":39,"line":532},[37,2995,44],{"class":43},[37,2997,48],{"class":47},[37,2999,52],{"class":51},[37,3001,613],{"class":47},[37,3003,3004,3007,3009,3011,3013,3016,3018,3020,3022,3025,3027,3029,3031,3034,3036,3038,3040,3043,3045],{"class":39,"line":542},[37,3005,3006],{"class":47},"    []",[37,3008,311],{"class":310},[37,3010,820],{"class":47},[37,3012,823],{"class":47},[37,3014,3015],{"class":826},"日付",[37,3017,823],{"class":47},[37,3019,61],{"class":47},[37,3021,834],{"class":47},[37,3023,3024],{"class":826},"請求書番号",[37,3026,823],{"class":47},[37,3028,61],{"class":47},[37,3030,834],{"class":47},[37,3032,3033],{"class":826},"顧客名",[37,3035,823],{"class":47},[37,3037,61],{"class":47},[37,3039,834],{"class":47},[37,3041,3042],{"class":826},"金額",[37,3044,823],{"class":47},[37,3046,2267],{"class":47},[37,3048,3049,3052,3054],{"class":39,"line":552},[37,3050,3051],{"class":47},"    [][]",[37,3053,311],{"class":310},[37,3055,948],{"class":47},[37,3057,3058,3060,3062,3065,3067,3069,3071,3074,3076,3078,3080,3083,3085,3087,3089,3092,3094],{"class":39,"line":562},[37,3059,2210],{"class":47},[37,3061,823],{"class":47},[37,3063,3064],{"class":826},"2026-04-01",[37,3066,823],{"class":47},[37,3068,61],{"class":47},[37,3070,834],{"class":47},[37,3072,3073],{"class":826},"INV-10001",[37,3075,823],{"class":47},[37,3077,61],{"class":47},[37,3079,834],{"class":47},[37,3081,3082],{"class":826},"株式会社サンプル",[37,3084,823],{"class":47},[37,3086,61],{"class":47},[37,3088,834],{"class":47},[37,3090,3091],{"class":826},"￥120,000",[37,3093,823],{"class":47},[37,3095,2267],{"class":47},[37,3097,3098,3100,3102,3105,3107,3109,3111,3114,3116,3118,3120,3123,3125,3127,3129,3132,3134],{"class":39,"line":572},[37,3099,2210],{"class":47},[37,3101,823],{"class":47},[37,3103,3104],{"class":826},"2026-04-02",[37,3106,823],{"class":47},[37,3108,61],{"class":47},[37,3110,834],{"class":47},[37,3112,3113],{"class":826},"INV-10002",[37,3115,823],{"class":47},[37,3117,61],{"class":47},[37,3119,834],{"class":47},[37,3121,3122],{"class":826},"山田商店",[37,3124,823],{"class":47},[37,3126,61],{"class":47},[37,3128,834],{"class":47},[37,3130,3131],{"class":826},"￥38,500",[37,3133,823],{"class":47},[37,3135,2267],{"class":47},[37,3137,3138],{"class":39,"line":577},[37,3139,2161],{"class":47},[37,3141,3142,3144,3146,3148,3150,3152,3154,3156,3158,3160,3162,3164],{"class":39,"line":582},[37,3143,73],{"class":43},[37,3145,48],{"class":47},[37,3147,78],{"class":51},[37,3149,55],{"class":47},[37,3151,669],{"class":83},[37,3153,61],{"class":47},[37,3155,94],{"class":83},[37,3157,61],{"class":47},[37,3159,1333],{"class":83},[37,3161,61],{"class":47},[37,3163,94],{"class":83},[37,3165,102],{"class":47},[37,3167,3168],{"class":39,"line":596},[37,3169,183],{"class":47},[19,3171,3172],{},"Cabeçalho em japonês, corpo em japonês, larguras seguem em porcentagem, repetição de cabeçalho em quebras continua funcionando. A fonte é subseteada apenas para os glifos que o documento usa, então o PDF resultante é pequeno mesmo com a Noto Sans JP completa disponível — cerca de 50 KB para uma página versus os 6 MB do arquivo completo.",[19,3174,3175,3176,3180],{},"Para a configuração da fonte, ",[213,3177,3179],{"href":3178},"/pt/blog/embed-japanese-font","embutir uma fonte TrueType japonesa"," é a receita. O ponto aqui é que nada na API de tabela muda quando os dados são CJK.",[14,3182,3184],{"id":3183},"perguntas-frequentes","Perguntas frequentes",[19,3186,3187],{},[22,3188,3189],{},"P: O gpdf suporta estilo por linha?",[19,3191,3192,3193,3196,3197,3200,3201,3203,3204,3206,3207,3210,3211,48],{},"Não na API builder. O builder recebe ",[34,3194,3195],{},"[][]string"," para o corpo, o que significa que toda célula compartilha o mesmo ",[34,3198,3199],{},"Style"," derivado da coluna. Para estilizar linhas individuais, construa a tabela na camada ",[34,3202,201],{}," onde cada ",[34,3205,1968],{}," carrega seu próprio ",[34,3208,3209],{},"CellStyle",". O padrão é direto; só custa a conveniência da forma ",[34,3212,3195],{},[19,3214,3215],{},[22,3216,3217],{},"P: Posso colocar imagens ou outras tabelas dentro de uma célula?",[19,3219,3220,3221,3223,3224,2398,3227,3230,3231,2360,3234,3237,3238,3241],{},"Sim, na camada ",[34,3222,201],{},". ",[34,3225,3226],{},"TableCell.Content",[34,3228,3229],{},"[]DocumentNode",", que aceita qualquer nó — ",[34,3232,3233],{},"*Text",[34,3235,3236],{},"*Image",", até ",[34,3239,3240],{},"*Table"," aninhado. A API builder baseada em strings não expõe porque é uma aresta mais afiada do que a maioria dos usuários quer, mas o modelo subjacente suporta.",[19,3243,3244],{},[22,3245,3246],{},"P: Como o gpdf decide onde partir o corpo entre páginas?",[19,3248,3249],{},"Linha por linha. O motor mede cada linha do corpo em ordem e adiciona à página atual até que a próxima ultrapassaria a altura disponível. Aquela linha vira a primeira linha da tabela overflow. Ainda não há anotação \"mantenha essas linhas juntas\" — toda linha é divisível. Para itens de NF onde você realmente precisa de um grupo lógico em uma página, abra a página manualmente antes do grupo ou caia para a camada documento para inserir dicas de quebra.",[19,3251,3252],{},[22,3253,3254],{},"P: Qual a maior tabela que o gpdf consegue renderizar?",[19,3256,3257,3258,3261,3262,3264,3265,48],{},"Testamos com 10.000 linhas em A4. Pagina corretamente, o cabeçalho repete em todas as páginas, o PDF resultante tem ~150 páginas e algumas centenas de KB. O gargalo não é o layout da tabela — é o shaping de texto do conteúdo da célula, que é ",[34,3259,3260],{},"O(linhas × colunas)",". Se você precisa de 100.000+ linhas, escreva em disco em chunks (várias chamadas a ",[34,3263,1466],{}," por ~10k linhas) ou alimente runs pré-shaped na camada ",[34,3266,201],{},[19,3268,3269],{},[22,3270,3271],{},"P: Posso fazer o rodapé aparecer só na última página?",[19,3273,3274,3275,3277],{},"Não nativamente. ",[34,3276,2397],{}," repete em cada página por design — é o caso comum (totais por página). Se você precisa de um resumo único no fim do documento, adicione como bloco de linhas separado depois da tabela, não dentro.",[19,3279,3280],{},[22,3281,3282,3283,3285],{},"P: ",[34,3284,1417],{}," afeta o cabeçalho também?",[19,3287,3288,3289,3292],{},"Sim. Bordas de célula aplicam uniformemente a cabeçalho e corpo. Se você quer borda diferente no cabeçalho (por exemplo, borda inferior mais grossa abaixo da linha de cabeçalho), construa o cabeçalho na camada documento e aplique ",[34,3290,3291],{},"CellStyle.Border"," por célula lá.",[14,3294,3296],{"id":3295},"a-forma-do-design","A forma do design",[19,3298,3299,3300,3303],{},"Se há uma coisa para levar: ",[22,3301,3302],{},"a API de tabelas do gpdf é pequena porque a maioria dos problemas de tabela é sempre os mesmos três problemas."," Larguras, listras, quebras de página. O resto é long tail. Pôr os casos comuns no builder e o long tail na camada documento é o trade — você ganha tabelas de cinco linhas para o que aparece todo dia, e não paga a abstração quando precisa fazer algo que o builder não expressa.",[19,3305,3306,3307,3310],{},"O custo é honesto: não há atalho ",[34,3308,3309],{},"setRowStyle(i, ...)"," e não vai ter. Se você quer estilizar a linha 4 diferente da 5, cruzou uma linha de complexidade que o builder não tenta lidar. Desça uma camada. A fronteira é clara e estável.",[19,3312,3313],{},"É o artigo todo. Vinte minutos de leitura para uma parte da API que vale a pena entender bem uma vez e depois não pensar mais.",[14,3315,3317],{"id":3316},"experimente-o-gpdf","Experimente o gpdf",[19,3319,3320],{},"gpdf é uma biblioteca Go para gerar PDFs. Licença MIT, dependências externas zero, suporte CJK nativo.",[27,3322,3326],{"className":3323,"code":3324,"language":3325,"meta":32,"style":32},"language-bash shiki shiki-themes material-theme-lighter material-theme material-theme-palenight","go get github.com/gpdf-dev/gpdf\n","bash",[34,3327,3328],{"__ignoreMap":32},[37,3329,3330,3332,3335],{"class":39,"line":40},[37,3331,31],{"class":293},[37,3333,3334],{"class":826}," get",[37,3336,3337],{"class":826}," github.com/gpdf-dev/gpdf\n",[19,3339,3340,3344,3345],{},[213,3341,3343],{"href":215,"rel":3342},[217],"⭐ Star no GitHub"," · ",[213,3346,3349],{"href":3347,"rel":3348},"https://gpdf.dev/pt/docs/quickstart",[217],"Leia a documentação",[14,3351,3353],{"id":3352},"leitura-relacionada","Leitura relacionada",[1790,3355,3356,3364,3370,3377,3384],{},[231,3357,3358,3361,3362],{},[213,3359,3360],{"href":1724},"Como defino larguras de coluna numa tabela gpdf?"," — os detalhes de ",[34,3363,78],{},[231,3365,3366,3369],{},[213,3367,3368],{"href":1815},"Como crio linhas com listras zebra?"," — escolha de cor e tema escuro",[231,3371,3372,3376],{},[213,3373,3375],{"href":3374},"/pt/blog/bootstrap-grid-thinking-for-pdf","Pensamento Bootstrap para PDF: a grade de 12 colunas do gpdf"," — qual Col pai resolve as porcentagens",[231,3378,3379,3383],{},[213,3380,3382],{"href":3381},"/pt/blog/invoice-pdf-go-under-50-lines","Gere uma NF em PDF em Go com menos de 50 linhas"," — uma tabela do mundo real dentro de um documento completo",[231,3385,3386,3389],{},[213,3387,3388],{"href":2856},"Por que o gpdf é mais rápido que gofpdf, gopdf e Maroto"," — os µs por trás da tabela comparativa",[3391,3392,3393],"style",{},"html pre.shiki code .sTEyZ, html code.shiki .sTEyZ{--shiki-light:#90A4AE;--shiki-default:#EEFFFF;--shiki-dark:#BABED8}html pre.shiki code .sMK4o, html code.shiki .sMK4o{--shiki-light:#39ADB5;--shiki-default:#89DDFF;--shiki-dark:#89DDFF}html pre.shiki code .s2Zo4, html code.shiki .s2Zo4{--shiki-light:#6182B8;--shiki-default:#82AAFF;--shiki-dark:#82AAFF}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 .sBMFI, html code.shiki .sBMFI{--shiki-light:#E2931D;--shiki-default:#FFCB6B;--shiki-dark:#FFCB6B}html pre.shiki code .spNyl, html code.shiki .spNyl{--shiki-light:#9C3EDA;--shiki-default:#C792EA;--shiki-dark:#C792EA}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 .sfazB, html code.shiki .sfazB{--shiki-light:#91B859;--shiki-default:#C3E88D;--shiki-dark:#C3E88D}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}html pre.shiki code .sfNiH, html code.shiki .sfNiH{--shiki-light:#FF5370;--shiki-default:#FF9CAC;--shiki-dark:#FF9CAC}",{"title":32,"searchDepth":70,"depth":70,"links":3395},[3396,3397,3398,3399,3400,3401,3402,3403,3404,3405,3406,3407,3408,3409,3410],{"id":16,"depth":70,"text":17},{"id":208,"depth":70,"text":209},{"id":266,"depth":70,"text":267},{"id":451,"depth":70,"text":452},{"id":1600,"depth":70,"text":1601},{"id":1729,"depth":70,"text":1730},{"id":1824,"depth":70,"text":1825},{"id":1901,"depth":70,"text":1902},{"id":2410,"depth":70,"text":2411},{"id":2700,"depth":70,"text":2701},{"id":2866,"depth":70,"text":2867},{"id":3183,"depth":70,"text":3184},{"id":3295,"depth":70,"text":3296},{"id":3316,"depth":70,"text":3317},{"id":3352,"depth":70,"text":3353},"2026-05-07","Tabelas são a parte mais difícil de um PDF em Go. gpdf reúne larguras, listras e a repetição de cabeçalho a cada página em uma única chamada Table.",false,"md",{"name":3416,"totalTime":3417,"tools":3418,"steps":3420},"Renderizar uma tabela multipágina em Go com larguras de coluna, listras e cabeçalho repetido usando gpdf","PT20M",[3419,537],"Go 1.22+",[3421,3424,3427,3430,3433,3436],{"name":3422,"text":3423},"Instalar o gpdf","Rode go get github.com/gpdf-dev/gpdf em um módulo Go 1.22+. A biblioteca core não tem dependências externas, então essa linha basta.",{"name":3425,"text":3426},"Construir uma única chamada Table dentro de um Col","Dentro de page.AutoRow → r.Col(12, ...), chame c.Table(header, rows). header é []string, rows é [][]string. Sem opções, as colunas se dividem igualmente.",{"name":3428,"text":3429},"Definir larguras por coluna em porcentagens","Passe template.ColumnWidths(40, 15, 20, 25). Cada valor é a porcentagem da largura do Col pai. Valores faltantes ao final são auto-distribuídos.",{"name":3431,"text":3432},"Estilizar o cabeçalho e adicionar listras","Adicione template.TableHeaderStyle(template.TextColor(pdf.White), template.BgColor(brand)) e template.TableStripe(pdf.RGBHex(0xF5F5F5)). Listras só atingem o corpo, o cabeçalho fica de fora.",{"name":3434,"text":3435},"Deixe o gpdf paginar. O cabeçalho repete sozinho","Forneça linhas suficientes para extrapolar uma página. O gpdf parte o corpo entre páginas e reemite o slice Header no topo de cada página de continuação. Sem opção PageBreak nem contagem manual.",{"name":3437,"text":3438},"Desça para document.Table quando precisar de ColSpan, RowSpan, larguras fixas ou rodapé","Construa &document.Table{Columns, Header, Body, Footer} diretamente quando precisar de células mescladas, colunas em pt fixas ou um rodapé que repita em todas as páginas. A API builder não expõe isso de propósito.",null,{},"/pt/blog/tables-in-go-pdfs",{"title":5,"description":3412},"pt/blog/022.tables-in-go-pdfs",[3445,3446,3447],"tutorial","templates","comparison","3ogIhp45DpFn1y0MLNkRlsdVpYuKX8Fp-MDVNVROFFU",1779199037310]