[{"data":1,"prerenderedAt":3208},["ShallowReactive",2],{"blog-pt-page-numbers-headers-footers":3},{"id":4,"title":5,"author":6,"body":9,"date":3173,"description":3174,"draft":3175,"extension":3176,"howTo":3177,"image":3199,"meta":3200,"navigation":134,"path":3201,"seo":3202,"stem":3203,"tags":3204,"updated":3199,"__hash__":3207},"blogPt/pt/blog/027.page-numbers-headers-footers.md","Número de página, cabeçalho e rodapé em PDFs Go com gpdf",{"name":7,"url":8},"gpdf team","https://gpdf.dev",{"type":10,"value":11,"toc":3158},"minimark",[12,25,36,39,44,85,92,96,107,1468,1482,1486,1497,1500,1578,1594,1599,1605,1626,1629,1636,1640,1655,1922,1925,1932,1935,1939,1956,2283,2298,2301,2470,2484,2488,2491,2503,2512,2675,2682,2693,2702,2712,2716,2726,3000,3007,3011,3014,3017,3023,3026,3030,3040,3046,3052,3062,3087,3101,3105,3108,3115,3119,3122,3139,3154],[13,14,15,16,20,21,24],"p",{},"Um relatório financeiro de 60 páginas. Alguém abre a página 12 na fila de impressão e faz uma pergunta: que página é essa e quantas faltam? Se o rodapé só diz ",[17,18,19],"code",{},"12",", ninguém sabe. Precisa dizer ",[17,22,23],{},"12 / 60",".",[13,26,27,28,31,32,35],{},"Esse ",[17,29,30],{},"60"," é o lado onde a maioria das bibliotecas PDF falha. Ou o total não está disponível quando você escreve o rodapé, ou está atrás de um token tipo ",[17,33,34],{},"AliasNbPages"," que precisa ser chamado depois do build, ou você renderiza o documento duas vezes e descarta a primeira passagem.",[13,37,38],{},"gpdf resolve isso de maneira limpa com dois métodos do builder e um paginador interno de duas passagens. Este post é sobre como a API se parece, como funciona por dentro, e o único ponto áspero que vale a pena conhecer.",[40,41,43],"h2",{"id":42},"tldr","TL;DR",[45,46,47,58,61,71,74],"ul",{},[48,49,50,53,54,57],"li",{},[17,51,52],{},"doc.Header(fn)"," e ",[17,55,56],{},"doc.Footer(fn)"," registram uma closure executada em cada página.",[48,59,60],{},"Dentro da closure usa-se o mesmo grid de 12 colunas do corpo.",[48,62,63,66,67,70],{},[17,64,65],{},"c.PageNumber()"," imprime o número da página atual. ",[17,68,69],{},"c.TotalPages()"," imprime o total.",[48,72,73],{},"O total é resolvido em uma segunda passagem, depois que a paginação termina. Você não precisa escrever um build de duas passagens.",[48,75,76,77,80,81,84],{},"Uma aspereza: não existe um helper ",[17,78,79],{},"c.PageNumberOf(total)"," que imprima ",[17,82,83],{},"\"3 of 12\""," como uma única string inline. Compõe-se com três colunas. Detalhe abaixo.",[13,86,87,88,91],{},"Todo o código do post vem de ",[17,89,90],{},"gpdf/_examples/builder/26_page_number_test.go",", que faz parte do conjunto de testes.",[40,93,95],{"id":94},"tudo-em-um-arquivo","Tudo em um arquivo",[13,97,98,99,102,103,106],{},"Programa completo. Salve como ",[17,100,101],{},"main.go",", rode ",[17,104,105],{},"go run main.go"," e obtenha um PDF de 4 páginas com cabeçalho mostrando o total e rodapé mostrando o número atual.",[108,109,114],"pre",{"className":110,"code":111,"language":112,"meta":113,"style":113},"language-go shiki shiki-themes material-theme-lighter material-theme material-theme-palenight","package main\n\nimport (\n    \"os\"\n\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 := template.New(\n        template.WithPageSize(document.A4),\n        template.WithMargins(document.UniformEdges(document.Mm(20))),\n    )\n\n    doc.Header(func(p *template.PageBuilder) {\n        p.AutoRow(func(r *template.RowBuilder) {\n            r.Col(6, func(c *template.ColBuilder) {\n                c.Text(\"Relatório trimestral\", template.Bold(), template.FontSize(10))\n            })\n            r.Col(6, func(c *template.ColBuilder) {\n                c.TotalPages(template.AlignRight(), template.FontSize(9),\n                    template.TextColor(pdf.Gray(0.5)))\n            })\n        })\n        p.AutoRow(func(r *template.RowBuilder) {\n            r.Col(12, func(c *template.ColBuilder) {\n                c.Line(template.LineColor(pdf.RGBHex(0x1565C0)))\n                c.Spacer(document.Mm(3))\n            })\n        })\n    })\n\n    doc.Footer(func(p *template.PageBuilder) {\n        p.AutoRow(func(r *template.RowBuilder) {\n            r.Col(12, func(c *template.ColBuilder) {\n                c.Spacer(document.Mm(3))\n                c.Line(template.LineColor(pdf.Gray(0.7)))\n                c.Spacer(document.Mm(2))\n            })\n        })\n        p.AutoRow(func(r *template.RowBuilder) {\n            r.Col(6, func(c *template.ColBuilder) {\n                c.Text(\"Generated by gpdf\", template.FontSize(8),\n                    template.TextColor(pdf.Gray(0.5)))\n            })\n            r.Col(6, func(c *template.ColBuilder) {\n                c.PageNumber(template.AlignRight(), template.FontSize(8),\n                    template.TextColor(pdf.Gray(0.5)))\n            })\n        })\n    })\n\n    for _, title := range []string{\"Introdução\", \"Contexto\", \"Análise\", \"Conclusão\"} {\n        page := doc.AddPage()\n        page.AutoRow(func(r *template.RowBuilder) {\n            r.Col(12, func(c *template.ColBuilder) {\n                c.Text(title, template.FontSize(18), template.Bold())\n                c.Spacer(document.Mm(5))\n                c.Text(\"Corpo da seção \" + title + \".\")\n            })\n        })\n    }\n\n    out, err := doc.Generate()\n    if err != nil {\n        panic(err)\n    }\n    _ = os.WriteFile(\"report.pdf\", out, 0o644)\n}\n","go","",[17,115,116,129,136,146,158,163,173,183,193,199,204,220,241,266,303,309,314,347,376,414,463,469,500,534,563,568,574,599,630,665,690,695,700,706,711,737,762,793,816,848,872,877,882,907,938,971,994,999,1030,1062,1085,1090,1095,1100,1105,1174,1193,1219,1250,1289,1313,1347,1352,1357,1363,1368,1390,1406,1419,1424,1462],{"__ignoreMap":113},[117,118,121,125],"span",{"class":119,"line":120},"line",1,[117,122,124],{"class":123},"sMK4o","package",[117,126,128],{"class":127},"sBMFI"," main\n",[117,130,132],{"class":119,"line":131},2,[117,133,135],{"emptyLinePlaceholder":134},true,"\n",[117,137,139,143],{"class":119,"line":138},3,[117,140,142],{"class":141},"s7zQu","import",[117,144,145],{"class":123}," (\n",[117,147,149,152,155],{"class":119,"line":148},4,[117,150,151],{"class":123},"    \"",[117,153,154],{"class":127},"os",[117,156,157],{"class":123},"\"\n",[117,159,161],{"class":119,"line":160},5,[117,162,135],{"emptyLinePlaceholder":134},[117,164,166,168,171],{"class":119,"line":165},6,[117,167,151],{"class":123},[117,169,170],{"class":127},"github.com/gpdf-dev/gpdf/document",[117,172,157],{"class":123},[117,174,176,178,181],{"class":119,"line":175},7,[117,177,151],{"class":123},[117,179,180],{"class":127},"github.com/gpdf-dev/gpdf/pdf",[117,182,157],{"class":123},[117,184,186,188,191],{"class":119,"line":185},8,[117,187,151],{"class":123},[117,189,190],{"class":127},"github.com/gpdf-dev/gpdf/template",[117,192,157],{"class":123},[117,194,196],{"class":119,"line":195},9,[117,197,198],{"class":123},")\n",[117,200,202],{"class":119,"line":201},10,[117,203,135],{"emptyLinePlaceholder":134},[117,205,207,210,214,217],{"class":119,"line":206},11,[117,208,209],{"class":123},"func",[117,211,213],{"class":212},"s2Zo4"," main",[117,215,216],{"class":123},"()",[117,218,219],{"class":123}," {\n",[117,221,223,227,230,233,235,238],{"class":119,"line":222},12,[117,224,226],{"class":225},"sTEyZ","    doc ",[117,228,229],{"class":123},":=",[117,231,232],{"class":225}," template",[117,234,24],{"class":123},[117,236,237],{"class":212},"New",[117,239,240],{"class":123},"(\n",[117,242,244,247,249,252,255,258,260,263],{"class":119,"line":243},13,[117,245,246],{"class":225},"        template",[117,248,24],{"class":123},[117,250,251],{"class":212},"WithPageSize",[117,253,254],{"class":123},"(",[117,256,257],{"class":225},"document",[117,259,24],{"class":123},[117,261,262],{"class":225},"A4",[117,264,265],{"class":123},"),\n",[117,267,269,271,273,276,278,280,282,285,287,289,291,294,296,300],{"class":119,"line":268},14,[117,270,246],{"class":225},[117,272,24],{"class":123},[117,274,275],{"class":212},"WithMargins",[117,277,254],{"class":123},[117,279,257],{"class":225},[117,281,24],{"class":123},[117,283,284],{"class":212},"UniformEdges",[117,286,254],{"class":123},[117,288,257],{"class":225},[117,290,24],{"class":123},[117,292,293],{"class":212},"Mm",[117,295,254],{"class":123},[117,297,299],{"class":298},"sbssI","20",[117,301,302],{"class":123},"))),\n",[117,304,306],{"class":119,"line":305},15,[117,307,308],{"class":123},"    )\n",[117,310,312],{"class":119,"line":311},16,[117,313,135],{"emptyLinePlaceholder":134},[117,315,317,320,322,325,328,331,334,337,339,342,345],{"class":119,"line":316},17,[117,318,319],{"class":225},"    doc",[117,321,24],{"class":123},[117,323,324],{"class":212},"Header",[117,326,327],{"class":123},"(func(",[117,329,13],{"class":330},"sHdIc",[117,332,333],{"class":123}," *",[117,335,336],{"class":127},"template",[117,338,24],{"class":123},[117,340,341],{"class":127},"PageBuilder",[117,343,344],{"class":123},")",[117,346,219],{"class":123},[117,348,350,353,355,358,360,363,365,367,369,372,374],{"class":119,"line":349},18,[117,351,352],{"class":225},"        p",[117,354,24],{"class":123},[117,356,357],{"class":212},"AutoRow",[117,359,327],{"class":123},[117,361,362],{"class":330},"r",[117,364,333],{"class":123},[117,366,336],{"class":127},[117,368,24],{"class":123},[117,370,371],{"class":127},"RowBuilder",[117,373,344],{"class":123},[117,375,219],{"class":123},[117,377,379,382,384,387,389,392,395,398,401,403,405,407,410,412],{"class":119,"line":378},19,[117,380,381],{"class":225},"            r",[117,383,24],{"class":123},[117,385,386],{"class":212},"Col",[117,388,254],{"class":123},[117,390,391],{"class":298},"6",[117,393,394],{"class":123},",",[117,396,397],{"class":123}," func(",[117,399,400],{"class":330},"c",[117,402,333],{"class":123},[117,404,336],{"class":127},[117,406,24],{"class":123},[117,408,409],{"class":127},"ColBuilder",[117,411,344],{"class":123},[117,413,219],{"class":123},[117,415,417,420,422,425,427,430,434,436,438,440,442,445,448,450,452,455,457,460],{"class":119,"line":416},20,[117,418,419],{"class":225},"                c",[117,421,24],{"class":123},[117,423,424],{"class":212},"Text",[117,426,254],{"class":123},[117,428,429],{"class":123},"\"",[117,431,433],{"class":432},"sfazB","Relatório trimestral",[117,435,429],{"class":123},[117,437,394],{"class":123},[117,439,232],{"class":225},[117,441,24],{"class":123},[117,443,444],{"class":212},"Bold",[117,446,447],{"class":123},"(),",[117,449,232],{"class":225},[117,451,24],{"class":123},[117,453,454],{"class":212},"FontSize",[117,456,254],{"class":123},[117,458,459],{"class":298},"10",[117,461,462],{"class":123},"))\n",[117,464,466],{"class":119,"line":465},21,[117,467,468],{"class":123},"            })\n",[117,470,472,474,476,478,480,482,484,486,488,490,492,494,496,498],{"class":119,"line":471},22,[117,473,381],{"class":225},[117,475,24],{"class":123},[117,477,386],{"class":212},[117,479,254],{"class":123},[117,481,391],{"class":298},[117,483,394],{"class":123},[117,485,397],{"class":123},[117,487,400],{"class":330},[117,489,333],{"class":123},[117,491,336],{"class":127},[117,493,24],{"class":123},[117,495,409],{"class":127},[117,497,344],{"class":123},[117,499,219],{"class":123},[117,501,503,505,507,510,512,514,516,519,521,523,525,527,529,532],{"class":119,"line":502},23,[117,504,419],{"class":225},[117,506,24],{"class":123},[117,508,509],{"class":212},"TotalPages",[117,511,254],{"class":123},[117,513,336],{"class":225},[117,515,24],{"class":123},[117,517,518],{"class":212},"AlignRight",[117,520,447],{"class":123},[117,522,232],{"class":225},[117,524,24],{"class":123},[117,526,454],{"class":212},[117,528,254],{"class":123},[117,530,531],{"class":298},"9",[117,533,265],{"class":123},[117,535,537,540,542,545,547,550,552,555,557,560],{"class":119,"line":536},24,[117,538,539],{"class":225},"                    template",[117,541,24],{"class":123},[117,543,544],{"class":212},"TextColor",[117,546,254],{"class":123},[117,548,549],{"class":225},"pdf",[117,551,24],{"class":123},[117,553,554],{"class":212},"Gray",[117,556,254],{"class":123},[117,558,559],{"class":298},"0.5",[117,561,562],{"class":123},")))\n",[117,564,566],{"class":119,"line":565},25,[117,567,468],{"class":123},[117,569,571],{"class":119,"line":570},26,[117,572,573],{"class":123},"        })\n",[117,575,577,579,581,583,585,587,589,591,593,595,597],{"class":119,"line":576},27,[117,578,352],{"class":225},[117,580,24],{"class":123},[117,582,357],{"class":212},[117,584,327],{"class":123},[117,586,362],{"class":330},[117,588,333],{"class":123},[117,590,336],{"class":127},[117,592,24],{"class":123},[117,594,371],{"class":127},[117,596,344],{"class":123},[117,598,219],{"class":123},[117,600,602,604,606,608,610,612,614,616,618,620,622,624,626,628],{"class":119,"line":601},28,[117,603,381],{"class":225},[117,605,24],{"class":123},[117,607,386],{"class":212},[117,609,254],{"class":123},[117,611,19],{"class":298},[117,613,394],{"class":123},[117,615,397],{"class":123},[117,617,400],{"class":330},[117,619,333],{"class":123},[117,621,336],{"class":127},[117,623,24],{"class":123},[117,625,409],{"class":127},[117,627,344],{"class":123},[117,629,219],{"class":123},[117,631,633,635,637,640,642,644,646,649,651,653,655,658,660,663],{"class":119,"line":632},29,[117,634,419],{"class":225},[117,636,24],{"class":123},[117,638,639],{"class":212},"Line",[117,641,254],{"class":123},[117,643,336],{"class":225},[117,645,24],{"class":123},[117,647,648],{"class":212},"LineColor",[117,650,254],{"class":123},[117,652,549],{"class":225},[117,654,24],{"class":123},[117,656,657],{"class":212},"RGBHex",[117,659,254],{"class":123},[117,661,662],{"class":298},"0x1565C0",[117,664,562],{"class":123},[117,666,668,670,672,675,677,679,681,683,685,688],{"class":119,"line":667},30,[117,669,419],{"class":225},[117,671,24],{"class":123},[117,673,674],{"class":212},"Spacer",[117,676,254],{"class":123},[117,678,257],{"class":225},[117,680,24],{"class":123},[117,682,293],{"class":212},[117,684,254],{"class":123},[117,686,687],{"class":298},"3",[117,689,462],{"class":123},[117,691,693],{"class":119,"line":692},31,[117,694,468],{"class":123},[117,696,698],{"class":119,"line":697},32,[117,699,573],{"class":123},[117,701,703],{"class":119,"line":702},33,[117,704,705],{"class":123},"    })\n",[117,707,709],{"class":119,"line":708},34,[117,710,135],{"emptyLinePlaceholder":134},[117,712,714,716,718,721,723,725,727,729,731,733,735],{"class":119,"line":713},35,[117,715,319],{"class":225},[117,717,24],{"class":123},[117,719,720],{"class":212},"Footer",[117,722,327],{"class":123},[117,724,13],{"class":330},[117,726,333],{"class":123},[117,728,336],{"class":127},[117,730,24],{"class":123},[117,732,341],{"class":127},[117,734,344],{"class":123},[117,736,219],{"class":123},[117,738,740,742,744,746,748,750,752,754,756,758,760],{"class":119,"line":739},36,[117,741,352],{"class":225},[117,743,24],{"class":123},[117,745,357],{"class":212},[117,747,327],{"class":123},[117,749,362],{"class":330},[117,751,333],{"class":123},[117,753,336],{"class":127},[117,755,24],{"class":123},[117,757,371],{"class":127},[117,759,344],{"class":123},[117,761,219],{"class":123},[117,763,765,767,769,771,773,775,777,779,781,783,785,787,789,791],{"class":119,"line":764},37,[117,766,381],{"class":225},[117,768,24],{"class":123},[117,770,386],{"class":212},[117,772,254],{"class":123},[117,774,19],{"class":298},[117,776,394],{"class":123},[117,778,397],{"class":123},[117,780,400],{"class":330},[117,782,333],{"class":123},[117,784,336],{"class":127},[117,786,24],{"class":123},[117,788,409],{"class":127},[117,790,344],{"class":123},[117,792,219],{"class":123},[117,794,796,798,800,802,804,806,808,810,812,814],{"class":119,"line":795},38,[117,797,419],{"class":225},[117,799,24],{"class":123},[117,801,674],{"class":212},[117,803,254],{"class":123},[117,805,257],{"class":225},[117,807,24],{"class":123},[117,809,293],{"class":212},[117,811,254],{"class":123},[117,813,687],{"class":298},[117,815,462],{"class":123},[117,817,819,821,823,825,827,829,831,833,835,837,839,841,843,846],{"class":119,"line":818},39,[117,820,419],{"class":225},[117,822,24],{"class":123},[117,824,639],{"class":212},[117,826,254],{"class":123},[117,828,336],{"class":225},[117,830,24],{"class":123},[117,832,648],{"class":212},[117,834,254],{"class":123},[117,836,549],{"class":225},[117,838,24],{"class":123},[117,840,554],{"class":212},[117,842,254],{"class":123},[117,844,845],{"class":298},"0.7",[117,847,562],{"class":123},[117,849,851,853,855,857,859,861,863,865,867,870],{"class":119,"line":850},40,[117,852,419],{"class":225},[117,854,24],{"class":123},[117,856,674],{"class":212},[117,858,254],{"class":123},[117,860,257],{"class":225},[117,862,24],{"class":123},[117,864,293],{"class":212},[117,866,254],{"class":123},[117,868,869],{"class":298},"2",[117,871,462],{"class":123},[117,873,875],{"class":119,"line":874},41,[117,876,468],{"class":123},[117,878,880],{"class":119,"line":879},42,[117,881,573],{"class":123},[117,883,885,887,889,891,893,895,897,899,901,903,905],{"class":119,"line":884},43,[117,886,352],{"class":225},[117,888,24],{"class":123},[117,890,357],{"class":212},[117,892,327],{"class":123},[117,894,362],{"class":330},[117,896,333],{"class":123},[117,898,336],{"class":127},[117,900,24],{"class":123},[117,902,371],{"class":127},[117,904,344],{"class":123},[117,906,219],{"class":123},[117,908,910,912,914,916,918,920,922,924,926,928,930,932,934,936],{"class":119,"line":909},44,[117,911,381],{"class":225},[117,913,24],{"class":123},[117,915,386],{"class":212},[117,917,254],{"class":123},[117,919,391],{"class":298},[117,921,394],{"class":123},[117,923,397],{"class":123},[117,925,400],{"class":330},[117,927,333],{"class":123},[117,929,336],{"class":127},[117,931,24],{"class":123},[117,933,409],{"class":127},[117,935,344],{"class":123},[117,937,219],{"class":123},[117,939,941,943,945,947,949,951,954,956,958,960,962,964,966,969],{"class":119,"line":940},45,[117,942,419],{"class":225},[117,944,24],{"class":123},[117,946,424],{"class":212},[117,948,254],{"class":123},[117,950,429],{"class":123},[117,952,953],{"class":432},"Generated by gpdf",[117,955,429],{"class":123},[117,957,394],{"class":123},[117,959,232],{"class":225},[117,961,24],{"class":123},[117,963,454],{"class":212},[117,965,254],{"class":123},[117,967,968],{"class":298},"8",[117,970,265],{"class":123},[117,972,974,976,978,980,982,984,986,988,990,992],{"class":119,"line":973},46,[117,975,539],{"class":225},[117,977,24],{"class":123},[117,979,544],{"class":212},[117,981,254],{"class":123},[117,983,549],{"class":225},[117,985,24],{"class":123},[117,987,554],{"class":212},[117,989,254],{"class":123},[117,991,559],{"class":298},[117,993,562],{"class":123},[117,995,997],{"class":119,"line":996},47,[117,998,468],{"class":123},[117,1000,1002,1004,1006,1008,1010,1012,1014,1016,1018,1020,1022,1024,1026,1028],{"class":119,"line":1001},48,[117,1003,381],{"class":225},[117,1005,24],{"class":123},[117,1007,386],{"class":212},[117,1009,254],{"class":123},[117,1011,391],{"class":298},[117,1013,394],{"class":123},[117,1015,397],{"class":123},[117,1017,400],{"class":330},[117,1019,333],{"class":123},[117,1021,336],{"class":127},[117,1023,24],{"class":123},[117,1025,409],{"class":127},[117,1027,344],{"class":123},[117,1029,219],{"class":123},[117,1031,1033,1035,1037,1040,1042,1044,1046,1048,1050,1052,1054,1056,1058,1060],{"class":119,"line":1032},49,[117,1034,419],{"class":225},[117,1036,24],{"class":123},[117,1038,1039],{"class":212},"PageNumber",[117,1041,254],{"class":123},[117,1043,336],{"class":225},[117,1045,24],{"class":123},[117,1047,518],{"class":212},[117,1049,447],{"class":123},[117,1051,232],{"class":225},[117,1053,24],{"class":123},[117,1055,454],{"class":212},[117,1057,254],{"class":123},[117,1059,968],{"class":298},[117,1061,265],{"class":123},[117,1063,1065,1067,1069,1071,1073,1075,1077,1079,1081,1083],{"class":119,"line":1064},50,[117,1066,539],{"class":225},[117,1068,24],{"class":123},[117,1070,544],{"class":212},[117,1072,254],{"class":123},[117,1074,549],{"class":225},[117,1076,24],{"class":123},[117,1078,554],{"class":212},[117,1080,254],{"class":123},[117,1082,559],{"class":298},[117,1084,562],{"class":123},[117,1086,1088],{"class":119,"line":1087},51,[117,1089,468],{"class":123},[117,1091,1093],{"class":119,"line":1092},52,[117,1094,573],{"class":123},[117,1096,1098],{"class":119,"line":1097},53,[117,1099,705],{"class":123},[117,1101,1103],{"class":119,"line":1102},54,[117,1104,135],{"emptyLinePlaceholder":134},[117,1106,1108,1111,1114,1116,1119,1121,1124,1127,1131,1134,1136,1139,1141,1143,1146,1149,1151,1153,1155,1158,1160,1162,1164,1167,1169,1172],{"class":119,"line":1107},55,[117,1109,1110],{"class":141},"    for",[117,1112,1113],{"class":225}," _",[117,1115,394],{"class":123},[117,1117,1118],{"class":225}," title ",[117,1120,229],{"class":123},[117,1122,1123],{"class":141}," range",[117,1125,1126],{"class":123}," []",[117,1128,1130],{"class":1129},"spNyl","string",[117,1132,1133],{"class":123},"{",[117,1135,429],{"class":123},[117,1137,1138],{"class":432},"Introdução",[117,1140,429],{"class":123},[117,1142,394],{"class":123},[117,1144,1145],{"class":123}," \"",[117,1147,1148],{"class":432},"Contexto",[117,1150,429],{"class":123},[117,1152,394],{"class":123},[117,1154,1145],{"class":123},[117,1156,1157],{"class":432},"Análise",[117,1159,429],{"class":123},[117,1161,394],{"class":123},[117,1163,1145],{"class":123},[117,1165,1166],{"class":432},"Conclusão",[117,1168,429],{"class":123},[117,1170,1171],{"class":123},"}",[117,1173,219],{"class":123},[117,1175,1177,1180,1182,1185,1187,1190],{"class":119,"line":1176},56,[117,1178,1179],{"class":225},"        page ",[117,1181,229],{"class":123},[117,1183,1184],{"class":225}," doc",[117,1186,24],{"class":123},[117,1188,1189],{"class":212},"AddPage",[117,1191,1192],{"class":123},"()\n",[117,1194,1196,1199,1201,1203,1205,1207,1209,1211,1213,1215,1217],{"class":119,"line":1195},57,[117,1197,1198],{"class":225},"        page",[117,1200,24],{"class":123},[117,1202,357],{"class":212},[117,1204,327],{"class":123},[117,1206,362],{"class":330},[117,1208,333],{"class":123},[117,1210,336],{"class":127},[117,1212,24],{"class":123},[117,1214,371],{"class":127},[117,1216,344],{"class":123},[117,1218,219],{"class":123},[117,1220,1222,1224,1226,1228,1230,1232,1234,1236,1238,1240,1242,1244,1246,1248],{"class":119,"line":1221},58,[117,1223,381],{"class":225},[117,1225,24],{"class":123},[117,1227,386],{"class":212},[117,1229,254],{"class":123},[117,1231,19],{"class":298},[117,1233,394],{"class":123},[117,1235,397],{"class":123},[117,1237,400],{"class":330},[117,1239,333],{"class":123},[117,1241,336],{"class":127},[117,1243,24],{"class":123},[117,1245,409],{"class":127},[117,1247,344],{"class":123},[117,1249,219],{"class":123},[117,1251,1253,1255,1257,1259,1261,1264,1266,1268,1270,1272,1274,1277,1280,1282,1284,1286],{"class":119,"line":1252},59,[117,1254,419],{"class":225},[117,1256,24],{"class":123},[117,1258,424],{"class":212},[117,1260,254],{"class":123},[117,1262,1263],{"class":225},"title",[117,1265,394],{"class":123},[117,1267,232],{"class":225},[117,1269,24],{"class":123},[117,1271,454],{"class":212},[117,1273,254],{"class":123},[117,1275,1276],{"class":298},"18",[117,1278,1279],{"class":123},"),",[117,1281,232],{"class":225},[117,1283,24],{"class":123},[117,1285,444],{"class":212},[117,1287,1288],{"class":123},"())\n",[117,1290,1292,1294,1296,1298,1300,1302,1304,1306,1308,1311],{"class":119,"line":1291},60,[117,1293,419],{"class":225},[117,1295,24],{"class":123},[117,1297,674],{"class":212},[117,1299,254],{"class":123},[117,1301,257],{"class":225},[117,1303,24],{"class":123},[117,1305,293],{"class":212},[117,1307,254],{"class":123},[117,1309,1310],{"class":298},"5",[117,1312,462],{"class":123},[117,1314,1316,1318,1320,1322,1324,1326,1329,1331,1334,1336,1339,1341,1343,1345],{"class":119,"line":1315},61,[117,1317,419],{"class":225},[117,1319,24],{"class":123},[117,1321,424],{"class":212},[117,1323,254],{"class":123},[117,1325,429],{"class":123},[117,1327,1328],{"class":432},"Corpo da seção ",[117,1330,429],{"class":123},[117,1332,1333],{"class":123}," +",[117,1335,1118],{"class":225},[117,1337,1338],{"class":123},"+",[117,1340,1145],{"class":123},[117,1342,24],{"class":432},[117,1344,429],{"class":123},[117,1346,198],{"class":123},[117,1348,1350],{"class":119,"line":1349},62,[117,1351,468],{"class":123},[117,1353,1355],{"class":119,"line":1354},63,[117,1356,573],{"class":123},[117,1358,1360],{"class":119,"line":1359},64,[117,1361,1362],{"class":123},"    }\n",[117,1364,1366],{"class":119,"line":1365},65,[117,1367,135],{"emptyLinePlaceholder":134},[117,1369,1371,1374,1376,1379,1381,1383,1385,1388],{"class":119,"line":1370},66,[117,1372,1373],{"class":225},"    out",[117,1375,394],{"class":123},[117,1377,1378],{"class":225}," err ",[117,1380,229],{"class":123},[117,1382,1184],{"class":225},[117,1384,24],{"class":123},[117,1386,1387],{"class":212},"Generate",[117,1389,1192],{"class":123},[117,1391,1393,1396,1398,1401,1404],{"class":119,"line":1392},67,[117,1394,1395],{"class":141},"    if",[117,1397,1378],{"class":225},[117,1399,1400],{"class":123},"!=",[117,1402,1403],{"class":123}," nil",[117,1405,219],{"class":123},[117,1407,1409,1412,1414,1417],{"class":119,"line":1408},68,[117,1410,1411],{"class":212},"        panic",[117,1413,254],{"class":123},[117,1415,1416],{"class":225},"err",[117,1418,198],{"class":123},[117,1420,1422],{"class":119,"line":1421},69,[117,1423,1362],{"class":123},[117,1425,1427,1430,1433,1436,1438,1441,1443,1445,1448,1450,1452,1455,1457,1460],{"class":119,"line":1426},70,[117,1428,1429],{"class":225},"    _ ",[117,1431,1432],{"class":123},"=",[117,1434,1435],{"class":225}," os",[117,1437,24],{"class":123},[117,1439,1440],{"class":212},"WriteFile",[117,1442,254],{"class":123},[117,1444,429],{"class":123},[117,1446,1447],{"class":432},"report.pdf",[117,1449,429],{"class":123},[117,1451,394],{"class":123},[117,1453,1454],{"class":225}," out",[117,1456,394],{"class":123},[117,1458,1459],{"class":298}," 0o644",[117,1461,198],{"class":123},[117,1463,1465],{"class":119,"line":1464},71,[117,1466,1467],{"class":123},"}\n",[13,1469,1470,1471,1474,1475,1478,1479,1481],{},"Quatro páginas, ",[17,1472,1473],{},"4"," no canto superior direito do cabeçalho e ",[17,1476,1477],{},"1","〜",[17,1480,1473],{}," no canto inferior direito do rodapé. Em nenhum momento você disse ao gpdf que o documento tem 4 páginas — o próprio gpdf não sabe até a paginação terminar.",[40,1483,1485],{"id":1484},"por-que-page-x-of-y-é-a-parte-difícil","Por que \"Page X of Y\" é a parte difícil",[13,1487,1488,1489,1492,1493,1496],{},"O ",[17,1490,1491],{},"Y"," é chato porque o motor de layout não o conhece enquanto desenha a página 1. Num relatório de 50 páginas, a página 47 pode quebrar em duas porque uma linha de tabela não coube. O total ",[17,1494,1495],{},"50"," só fica disponível depois que o paginador termina. Mas o rodapé da página 1 foi desenhado muito antes disso.",[13,1498,1499],{},"Toda biblioteca PDF bate nesse muro. Como as principais do Go contornam:",[1501,1502,1503,1516],"table",{},[1504,1505,1506],"thead",{},[1507,1508,1509,1513],"tr",{},[1510,1511,1512],"th",{},"Biblioteca",[1510,1514,1515],{},"Estratégia para \"Page X of Y\"",[1517,1518,1519,1535,1543,1551,1565],"tbody",{},[1507,1520,1521,1525],{},[1522,1523,1524],"td",{},"gofpdf",[1522,1526,1527,1530,1531,1534],{},[17,1528,1529],{},"pdf.AliasNbPages(\"{nb}\")",". Você escreve ",[17,1532,1533],{},"{nb}"," como literal no texto, chama o método e o stream PDF é reescrito depois. Funciona, mas você tem que lembrar de chamar, e o placeholder é uma string mágica.",[1507,1536,1537,1540],{},[1522,1538,1539],{},"go-pdf/fpdf",[1522,1541,1542],{},"Fork de gofpdf. Mesmo mecanismo.",[1507,1544,1545,1548],{},[1522,1546,1547],{},"signintech/gopdf",[1522,1549,1550],{},"Sem suporte de primeira classe. Você constrói o documento, conta as páginas, reconstrói.",[1507,1552,1553,1556],{},[1522,1554,1555],{},"maroto v2",[1522,1557,1558,1559,1561,1562,1564],{},"Registro ",[17,1560,324],{},"/",[17,1563,720],{}," parecido com o do gpdf. Internamente também duas passagens. Mais lento porque por baixo é gofpdf — cerca de 10× mais lento que gpdf em cargas comuns.",[1507,1566,1567,1570],{},[1522,1568,1569],{},"gpdf",[1522,1571,1572,1574,1575,1577],{},[17,1573,65],{}," / ",[17,1576,69],{},". Chamadas de método tipadas, sem strings mágicas, resolvido pela segunda passagem interna.",[13,1579,1580,1581,1584,1585,1587,1588,1590,1591,1593],{},"gpdf é a única em que a primitiva de numeração faz parte da API tipada do builder. No gofpdf, se você digitar ",[17,1582,1583],{},"{nB}"," em vez de ",[17,1586,1533],{},", sai literalmente ",[17,1589,1583],{}," no rodapé. Com ",[17,1592,69],{},", o pior cenário é esquecer de chamar — aí não aparece número, não um errado.",[1595,1596,1598],"h3",{"id":1597},"como-a-segunda-passagem-funciona","Como a segunda passagem funciona",[13,1600,1601,1602,1604],{},"Internamente, ",[17,1603,65],{}," é renderizado como uma string placeholder — um sentinel que nenhum glifo de fonte real vai casar. Quando o paginador termina de fazer o layout de todas as páginas e sabe o total, ele percorre as instruções de texto renderizadas e substitui:",[1606,1607,1608,1620],"ol",{},[48,1609,1610,1614,1615,53,1617,1619],{},[1611,1612,1613],"strong",{},"Passagem 1 (paginar)",": renderiza cada página, incluindo cabeçalho e rodapé, tratando ",[17,1616,1039],{},[17,1618,509],{}," como tokens de largura fixa. Calcula o total.",[48,1621,1622,1625],{},[1611,1623,1624],{},"Passagem 2 (resolver)",": percorre a árvore de páginas, encontra cada sentinel e substitui pelo número real (atual ou total).",[13,1627,1628],{},"A largura do placeholder é reservada com base no máximo esperado de páginas (heurística), então o layout não se desloca depois da substituição. Números alinhados à direita continuam alinhados quando a contagem passa de 9 para 10 dígitos.",[13,1630,1631,1632,1635],{},"Você não escreve a segunda passagem. Não renderiza o documento duas vezes. Chama ",[17,1633,1634],{},"doc.Generate()"," e recebe os bytes.",[40,1637,1639],{"id":1638},"cabeçalho-e-rodapé-são-layout-normal","Cabeçalho e rodapé são layout normal",[13,1641,1642,1643,1646,1647,1650,1651,1654],{},"Quem vem do gofpdf se confunde aqui. Lá, ",[17,1644,1645],{},"SetHeaderFunc"," é chamado em uma Y fixa e você posiciona texto com ",[17,1648,1649],{},"Cell(...)"," em coordenadas absolutas. No gpdf, a closure do cabeçalho recebe um ",[17,1652,1653],{},"*template.PageBuilder"," — o mesmo tipo do corpo. Mesmo grid, mesmas linhas e colunas, mesmas opções de estilo.",[108,1656,1658],{"className":110,"code":1657,"language":112,"meta":113,"style":113},"doc.Header(func(p *template.PageBuilder) {\n    p.AutoRow(func(r *template.RowBuilder) {\n        r.Col(2, func(c *template.ColBuilder) {\n            c.Image(\"logo.png\", template.ImageHeight(document.Mm(12)))\n        })\n        r.Col(8, func(c *template.ColBuilder) {\n            c.Text(\"Annual Report 2026\", template.Bold(), template.FontSize(14))\n        })\n        r.Col(2, func(c *template.ColBuilder) {\n            c.TotalPages(template.AlignRight())\n        })\n    })\n})\n",[17,1659,1660,1685,1710,1741,1783,1787,1817,1857,1861,1891,1909,1913,1917],{"__ignoreMap":113},[117,1661,1662,1665,1667,1669,1671,1673,1675,1677,1679,1681,1683],{"class":119,"line":120},[117,1663,1664],{"class":225},"doc",[117,1666,24],{"class":123},[117,1668,324],{"class":212},[117,1670,327],{"class":123},[117,1672,13],{"class":330},[117,1674,333],{"class":123},[117,1676,336],{"class":127},[117,1678,24],{"class":123},[117,1680,341],{"class":127},[117,1682,344],{"class":123},[117,1684,219],{"class":123},[117,1686,1687,1690,1692,1694,1696,1698,1700,1702,1704,1706,1708],{"class":119,"line":131},[117,1688,1689],{"class":225},"    p",[117,1691,24],{"class":123},[117,1693,357],{"class":212},[117,1695,327],{"class":123},[117,1697,362],{"class":330},[117,1699,333],{"class":123},[117,1701,336],{"class":127},[117,1703,24],{"class":123},[117,1705,371],{"class":127},[117,1707,344],{"class":123},[117,1709,219],{"class":123},[117,1711,1712,1715,1717,1719,1721,1723,1725,1727,1729,1731,1733,1735,1737,1739],{"class":119,"line":138},[117,1713,1714],{"class":225},"        r",[117,1716,24],{"class":123},[117,1718,386],{"class":212},[117,1720,254],{"class":123},[117,1722,869],{"class":298},[117,1724,394],{"class":123},[117,1726,397],{"class":123},[117,1728,400],{"class":330},[117,1730,333],{"class":123},[117,1732,336],{"class":127},[117,1734,24],{"class":123},[117,1736,409],{"class":127},[117,1738,344],{"class":123},[117,1740,219],{"class":123},[117,1742,1743,1746,1748,1751,1753,1755,1758,1760,1762,1764,1766,1769,1771,1773,1775,1777,1779,1781],{"class":119,"line":148},[117,1744,1745],{"class":225},"            c",[117,1747,24],{"class":123},[117,1749,1750],{"class":212},"Image",[117,1752,254],{"class":123},[117,1754,429],{"class":123},[117,1756,1757],{"class":432},"logo.png",[117,1759,429],{"class":123},[117,1761,394],{"class":123},[117,1763,232],{"class":225},[117,1765,24],{"class":123},[117,1767,1768],{"class":212},"ImageHeight",[117,1770,254],{"class":123},[117,1772,257],{"class":225},[117,1774,24],{"class":123},[117,1776,293],{"class":212},[117,1778,254],{"class":123},[117,1780,19],{"class":298},[117,1782,562],{"class":123},[117,1784,1785],{"class":119,"line":160},[117,1786,573],{"class":123},[117,1788,1789,1791,1793,1795,1797,1799,1801,1803,1805,1807,1809,1811,1813,1815],{"class":119,"line":165},[117,1790,1714],{"class":225},[117,1792,24],{"class":123},[117,1794,386],{"class":212},[117,1796,254],{"class":123},[117,1798,968],{"class":298},[117,1800,394],{"class":123},[117,1802,397],{"class":123},[117,1804,400],{"class":330},[117,1806,333],{"class":123},[117,1808,336],{"class":127},[117,1810,24],{"class":123},[117,1812,409],{"class":127},[117,1814,344],{"class":123},[117,1816,219],{"class":123},[117,1818,1819,1821,1823,1825,1827,1829,1832,1834,1836,1838,1840,1842,1844,1846,1848,1850,1852,1855],{"class":119,"line":175},[117,1820,1745],{"class":225},[117,1822,24],{"class":123},[117,1824,424],{"class":212},[117,1826,254],{"class":123},[117,1828,429],{"class":123},[117,1830,1831],{"class":432},"Annual Report 2026",[117,1833,429],{"class":123},[117,1835,394],{"class":123},[117,1837,232],{"class":225},[117,1839,24],{"class":123},[117,1841,444],{"class":212},[117,1843,447],{"class":123},[117,1845,232],{"class":225},[117,1847,24],{"class":123},[117,1849,454],{"class":212},[117,1851,254],{"class":123},[117,1853,1854],{"class":298},"14",[117,1856,462],{"class":123},[117,1858,1859],{"class":119,"line":185},[117,1860,573],{"class":123},[117,1862,1863,1865,1867,1869,1871,1873,1875,1877,1879,1881,1883,1885,1887,1889],{"class":119,"line":195},[117,1864,1714],{"class":225},[117,1866,24],{"class":123},[117,1868,386],{"class":212},[117,1870,254],{"class":123},[117,1872,869],{"class":298},[117,1874,394],{"class":123},[117,1876,397],{"class":123},[117,1878,400],{"class":330},[117,1880,333],{"class":123},[117,1882,336],{"class":127},[117,1884,24],{"class":123},[117,1886,409],{"class":127},[117,1888,344],{"class":123},[117,1890,219],{"class":123},[117,1892,1893,1895,1897,1899,1901,1903,1905,1907],{"class":119,"line":201},[117,1894,1745],{"class":225},[117,1896,24],{"class":123},[117,1898,509],{"class":212},[117,1900,254],{"class":123},[117,1902,336],{"class":225},[117,1904,24],{"class":123},[117,1906,518],{"class":212},[117,1908,1288],{"class":123},[117,1910,1911],{"class":119,"line":206},[117,1912,573],{"class":123},[117,1914,1915],{"class":119,"line":222},[117,1916,705],{"class":123},[117,1918,1919],{"class":119,"line":243},[117,1920,1921],{"class":123},"})\n",[13,1923,1924],{},"Logo à esquerda, título no centro, total à direita. As colunas somam 12, mesma regra de uma linha de corpo.",[13,1926,1927,1928,1931],{},"A altura do cabeçalho é medida automaticamente. gpdf executa a closure uma vez antes do corpo, mede a altura renderizada e subtrai da altura útil do corpo em cada página. Rodapé igual. Não há ",[17,1929,1930],{},"headerHeight"," para passar. Adicione uma linha ao cabeçalho e o corpo encolhe sozinho.",[13,1933,1934],{},"Ambos se repetem em todas as páginas, incluindo as geradas por overflow. Se uma tabela longa vaza para a página 12, a página 12 também ganha cabeçalho e rodapé. Não há flag \"somente primeira página\" (ver abaixo).",[40,1936,1938],{"id":1937},"o-ponto-áspero-page-x-of-y-em-uma-linha","O ponto áspero: \"Page X of Y\" em uma linha",[13,1940,1941,1942,1945,1946,1949,1950,53,1953,1955],{},"Aqui, honestamente, a API podia ser melhor. Não existe ",[17,1943,1944],{},"c.PageOf(\"Page %d of %d\")",". Para produzir a string literal ",[17,1947,1948],{},"\"Page 3 of 12\""," é preciso compor por colunas, porque ",[17,1951,1952],{},"c.Text()",[17,1954,65],{}," são filhos independentes de uma coluna:",[108,1957,1959],{"className":110,"code":1958,"language":112,"meta":113,"style":113},"r.Col(12, func(c *template.ColBuilder) {\n    c.AutoRow(func(r *template.RowBuilder) {\n        r.Col(3, func(c *template.ColBuilder) {\n            c.Text(\"Page\", template.AlignRight())\n        })\n        r.Col(2, func(c *template.ColBuilder) {\n            c.PageNumber(template.AlignCenter())\n        })\n        r.Col(2, func(c *template.ColBuilder) {\n            c.Text(\"of\", template.AlignCenter())\n        })\n        r.Col(3, func(c *template.ColBuilder) {\n            c.TotalPages(template.AlignLeft())\n        })\n        r.Col(2, func(c *template.ColBuilder) {})\n    })\n})\n",[17,1960,1961,1991,2016,2046,2073,2077,2107,2126,2130,2160,2187,2191,2221,2240,2244,2275,2279],{"__ignoreMap":113},[117,1962,1963,1965,1967,1969,1971,1973,1975,1977,1979,1981,1983,1985,1987,1989],{"class":119,"line":120},[117,1964,362],{"class":225},[117,1966,24],{"class":123},[117,1968,386],{"class":212},[117,1970,254],{"class":123},[117,1972,19],{"class":298},[117,1974,394],{"class":123},[117,1976,397],{"class":123},[117,1978,400],{"class":330},[117,1980,333],{"class":123},[117,1982,336],{"class":127},[117,1984,24],{"class":123},[117,1986,409],{"class":127},[117,1988,344],{"class":123},[117,1990,219],{"class":123},[117,1992,1993,1996,1998,2000,2002,2004,2006,2008,2010,2012,2014],{"class":119,"line":131},[117,1994,1995],{"class":225},"    c",[117,1997,24],{"class":123},[117,1999,357],{"class":212},[117,2001,327],{"class":123},[117,2003,362],{"class":330},[117,2005,333],{"class":123},[117,2007,336],{"class":127},[117,2009,24],{"class":123},[117,2011,371],{"class":127},[117,2013,344],{"class":123},[117,2015,219],{"class":123},[117,2017,2018,2020,2022,2024,2026,2028,2030,2032,2034,2036,2038,2040,2042,2044],{"class":119,"line":138},[117,2019,1714],{"class":225},[117,2021,24],{"class":123},[117,2023,386],{"class":212},[117,2025,254],{"class":123},[117,2027,687],{"class":298},[117,2029,394],{"class":123},[117,2031,397],{"class":123},[117,2033,400],{"class":330},[117,2035,333],{"class":123},[117,2037,336],{"class":127},[117,2039,24],{"class":123},[117,2041,409],{"class":127},[117,2043,344],{"class":123},[117,2045,219],{"class":123},[117,2047,2048,2050,2052,2054,2056,2058,2061,2063,2065,2067,2069,2071],{"class":119,"line":148},[117,2049,1745],{"class":225},[117,2051,24],{"class":123},[117,2053,424],{"class":212},[117,2055,254],{"class":123},[117,2057,429],{"class":123},[117,2059,2060],{"class":432},"Page",[117,2062,429],{"class":123},[117,2064,394],{"class":123},[117,2066,232],{"class":225},[117,2068,24],{"class":123},[117,2070,518],{"class":212},[117,2072,1288],{"class":123},[117,2074,2075],{"class":119,"line":160},[117,2076,573],{"class":123},[117,2078,2079,2081,2083,2085,2087,2089,2091,2093,2095,2097,2099,2101,2103,2105],{"class":119,"line":165},[117,2080,1714],{"class":225},[117,2082,24],{"class":123},[117,2084,386],{"class":212},[117,2086,254],{"class":123},[117,2088,869],{"class":298},[117,2090,394],{"class":123},[117,2092,397],{"class":123},[117,2094,400],{"class":330},[117,2096,333],{"class":123},[117,2098,336],{"class":127},[117,2100,24],{"class":123},[117,2102,409],{"class":127},[117,2104,344],{"class":123},[117,2106,219],{"class":123},[117,2108,2109,2111,2113,2115,2117,2119,2121,2124],{"class":119,"line":175},[117,2110,1745],{"class":225},[117,2112,24],{"class":123},[117,2114,1039],{"class":212},[117,2116,254],{"class":123},[117,2118,336],{"class":225},[117,2120,24],{"class":123},[117,2122,2123],{"class":212},"AlignCenter",[117,2125,1288],{"class":123},[117,2127,2128],{"class":119,"line":185},[117,2129,573],{"class":123},[117,2131,2132,2134,2136,2138,2140,2142,2144,2146,2148,2150,2152,2154,2156,2158],{"class":119,"line":195},[117,2133,1714],{"class":225},[117,2135,24],{"class":123},[117,2137,386],{"class":212},[117,2139,254],{"class":123},[117,2141,869],{"class":298},[117,2143,394],{"class":123},[117,2145,397],{"class":123},[117,2147,400],{"class":330},[117,2149,333],{"class":123},[117,2151,336],{"class":127},[117,2153,24],{"class":123},[117,2155,409],{"class":127},[117,2157,344],{"class":123},[117,2159,219],{"class":123},[117,2161,2162,2164,2166,2168,2170,2172,2175,2177,2179,2181,2183,2185],{"class":119,"line":201},[117,2163,1745],{"class":225},[117,2165,24],{"class":123},[117,2167,424],{"class":212},[117,2169,254],{"class":123},[117,2171,429],{"class":123},[117,2173,2174],{"class":432},"of",[117,2176,429],{"class":123},[117,2178,394],{"class":123},[117,2180,232],{"class":225},[117,2182,24],{"class":123},[117,2184,2123],{"class":212},[117,2186,1288],{"class":123},[117,2188,2189],{"class":119,"line":206},[117,2190,573],{"class":123},[117,2192,2193,2195,2197,2199,2201,2203,2205,2207,2209,2211,2213,2215,2217,2219],{"class":119,"line":222},[117,2194,1714],{"class":225},[117,2196,24],{"class":123},[117,2198,386],{"class":212},[117,2200,254],{"class":123},[117,2202,687],{"class":298},[117,2204,394],{"class":123},[117,2206,397],{"class":123},[117,2208,400],{"class":330},[117,2210,333],{"class":123},[117,2212,336],{"class":127},[117,2214,24],{"class":123},[117,2216,409],{"class":127},[117,2218,344],{"class":123},[117,2220,219],{"class":123},[117,2222,2223,2225,2227,2229,2231,2233,2235,2238],{"class":119,"line":243},[117,2224,1745],{"class":225},[117,2226,24],{"class":123},[117,2228,509],{"class":212},[117,2230,254],{"class":123},[117,2232,336],{"class":225},[117,2234,24],{"class":123},[117,2236,2237],{"class":212},"AlignLeft",[117,2239,1288],{"class":123},[117,2241,2242],{"class":119,"line":268},[117,2243,573],{"class":123},[117,2245,2246,2248,2250,2252,2254,2256,2258,2260,2262,2264,2266,2268,2270,2272],{"class":119,"line":305},[117,2247,1714],{"class":225},[117,2249,24],{"class":123},[117,2251,386],{"class":212},[117,2253,254],{"class":123},[117,2255,869],{"class":298},[117,2257,394],{"class":123},[117,2259,397],{"class":123},[117,2261,400],{"class":330},[117,2263,333],{"class":123},[117,2265,336],{"class":127},[117,2267,24],{"class":123},[117,2269,409],{"class":127},[117,2271,344],{"class":123},[117,2273,2274],{"class":123}," {})\n",[117,2276,2277],{"class":119,"line":311},[117,2278,705],{"class":123},[117,2280,2281],{"class":119,"line":316},[117,2282,1921],{"class":123},[13,2284,2285,2286,2289,2290,2293,2294,2297],{},"Funciona. Fica visualmente ok. Mas é expandir para quatro colunas algo que a maioria escreveria como uma única string de formato. Uma farpa. Estamos pensando em adicionar ",[17,2287,2288],{},"c.PageOf(format string, opts ...TextOption)"," no estilo ",[17,2291,2292],{},"fmt.Sprintf"," com ",[17,2295,2296],{},"%d",". Se você tem opinião sobre a forma da API, abra uma issue no GitHub.",[13,2299,2300],{},"O atalho pragmático hoje é tirar o \"Page\" e usar barra:",[108,2302,2304],{"className":110,"code":2303,"language":112,"meta":113,"style":113},"r.Col(6, func(c *template.ColBuilder) {\n    c.PageNumber(template.AlignRight())\n})\nr.Col(1, func(c *template.ColBuilder) {\n    c.Text(\"/\", template.AlignCenter())\n})\nr.Col(5, func(c *template.ColBuilder) {\n    c.TotalPages(template.AlignLeft())\n})\n",[17,2305,2306,2336,2354,2358,2388,2414,2418,2448,2466],{"__ignoreMap":113},[117,2307,2308,2310,2312,2314,2316,2318,2320,2322,2324,2326,2328,2330,2332,2334],{"class":119,"line":120},[117,2309,362],{"class":225},[117,2311,24],{"class":123},[117,2313,386],{"class":212},[117,2315,254],{"class":123},[117,2317,391],{"class":298},[117,2319,394],{"class":123},[117,2321,397],{"class":123},[117,2323,400],{"class":330},[117,2325,333],{"class":123},[117,2327,336],{"class":127},[117,2329,24],{"class":123},[117,2331,409],{"class":127},[117,2333,344],{"class":123},[117,2335,219],{"class":123},[117,2337,2338,2340,2342,2344,2346,2348,2350,2352],{"class":119,"line":131},[117,2339,1995],{"class":225},[117,2341,24],{"class":123},[117,2343,1039],{"class":212},[117,2345,254],{"class":123},[117,2347,336],{"class":225},[117,2349,24],{"class":123},[117,2351,518],{"class":212},[117,2353,1288],{"class":123},[117,2355,2356],{"class":119,"line":138},[117,2357,1921],{"class":123},[117,2359,2360,2362,2364,2366,2368,2370,2372,2374,2376,2378,2380,2382,2384,2386],{"class":119,"line":148},[117,2361,362],{"class":225},[117,2363,24],{"class":123},[117,2365,386],{"class":212},[117,2367,254],{"class":123},[117,2369,1477],{"class":298},[117,2371,394],{"class":123},[117,2373,397],{"class":123},[117,2375,400],{"class":330},[117,2377,333],{"class":123},[117,2379,336],{"class":127},[117,2381,24],{"class":123},[117,2383,409],{"class":127},[117,2385,344],{"class":123},[117,2387,219],{"class":123},[117,2389,2390,2392,2394,2396,2398,2400,2402,2404,2406,2408,2410,2412],{"class":119,"line":160},[117,2391,1995],{"class":225},[117,2393,24],{"class":123},[117,2395,424],{"class":212},[117,2397,254],{"class":123},[117,2399,429],{"class":123},[117,2401,1561],{"class":432},[117,2403,429],{"class":123},[117,2405,394],{"class":123},[117,2407,232],{"class":225},[117,2409,24],{"class":123},[117,2411,2123],{"class":212},[117,2413,1288],{"class":123},[117,2415,2416],{"class":119,"line":165},[117,2417,1921],{"class":123},[117,2419,2420,2422,2424,2426,2428,2430,2432,2434,2436,2438,2440,2442,2444,2446],{"class":119,"line":175},[117,2421,362],{"class":225},[117,2423,24],{"class":123},[117,2425,386],{"class":212},[117,2427,254],{"class":123},[117,2429,1310],{"class":298},[117,2431,394],{"class":123},[117,2433,397],{"class":123},[117,2435,400],{"class":330},[117,2437,333],{"class":123},[117,2439,336],{"class":127},[117,2441,24],{"class":123},[117,2443,409],{"class":127},[117,2445,344],{"class":123},[117,2447,219],{"class":123},[117,2449,2450,2452,2454,2456,2458,2460,2462,2464],{"class":119,"line":185},[117,2451,1995],{"class":225},[117,2453,24],{"class":123},[117,2455,509],{"class":212},[117,2457,254],{"class":123},[117,2459,336],{"class":225},[117,2461,24],{"class":123},[117,2463,2237],{"class":212},[117,2465,1288],{"class":123},[117,2467,2468],{"class":119,"line":195},[117,2469,1921],{"class":123},[13,2471,2472,2475,2476,2479,2480,2483],{},[17,2473,2474],{},"3 / 12"," se lê tranquilamente num rodapé. Se você quiser ",[17,2477,2478],{},"Página 3 de 12",", intercale ",[17,2481,2482],{},"c.Text"," adicionais.",[40,2485,2487],{"id":2486},"padrões-que-aparecem","Padrões que aparecem",[13,2489,2490],{},"Configurações que aparecem de verdade no dia a dia.",[13,2492,2493,2496,2497,2293,2499,2502],{},[1611,2494,2495],{},"Linha sob o título."," Adicione um segundo ",[17,2498,357],{},[17,2500,2501],{},"c.Line()",". É o que o exemplo no topo faz.",[13,2504,2505,2508,2509,2511],{},[1611,2506,2507],{},"Rodapé centralizado com nota de confidencialidade."," Uma linha, uma coluna, ",[17,2510,2123],{},". O caso mais simples.",[108,2513,2515],{"className":110,"code":2514,"language":112,"meta":113,"style":113},"doc.Footer(func(p *template.PageBuilder) {\n    p.AutoRow(func(r *template.RowBuilder) {\n        r.Col(12, func(c *template.ColBuilder) {\n            c.Text(\"Confidencial — Uso interno\",\n                template.AlignCenter(),\n                template.FontSize(8),\n                template.TextColor(pdf.Gray(0.5)))\n        })\n    })\n})\n",[17,2516,2517,2541,2565,2595,2615,2627,2641,2663,2667,2671],{"__ignoreMap":113},[117,2518,2519,2521,2523,2525,2527,2529,2531,2533,2535,2537,2539],{"class":119,"line":120},[117,2520,1664],{"class":225},[117,2522,24],{"class":123},[117,2524,720],{"class":212},[117,2526,327],{"class":123},[117,2528,13],{"class":330},[117,2530,333],{"class":123},[117,2532,336],{"class":127},[117,2534,24],{"class":123},[117,2536,341],{"class":127},[117,2538,344],{"class":123},[117,2540,219],{"class":123},[117,2542,2543,2545,2547,2549,2551,2553,2555,2557,2559,2561,2563],{"class":119,"line":131},[117,2544,1689],{"class":225},[117,2546,24],{"class":123},[117,2548,357],{"class":212},[117,2550,327],{"class":123},[117,2552,362],{"class":330},[117,2554,333],{"class":123},[117,2556,336],{"class":127},[117,2558,24],{"class":123},[117,2560,371],{"class":127},[117,2562,344],{"class":123},[117,2564,219],{"class":123},[117,2566,2567,2569,2571,2573,2575,2577,2579,2581,2583,2585,2587,2589,2591,2593],{"class":119,"line":138},[117,2568,1714],{"class":225},[117,2570,24],{"class":123},[117,2572,386],{"class":212},[117,2574,254],{"class":123},[117,2576,19],{"class":298},[117,2578,394],{"class":123},[117,2580,397],{"class":123},[117,2582,400],{"class":330},[117,2584,333],{"class":123},[117,2586,336],{"class":127},[117,2588,24],{"class":123},[117,2590,409],{"class":127},[117,2592,344],{"class":123},[117,2594,219],{"class":123},[117,2596,2597,2599,2601,2603,2605,2607,2610,2612],{"class":119,"line":148},[117,2598,1745],{"class":225},[117,2600,24],{"class":123},[117,2602,424],{"class":212},[117,2604,254],{"class":123},[117,2606,429],{"class":123},[117,2608,2609],{"class":432},"Confidencial — Uso interno",[117,2611,429],{"class":123},[117,2613,2614],{"class":123},",\n",[117,2616,2617,2620,2622,2624],{"class":119,"line":160},[117,2618,2619],{"class":225},"                template",[117,2621,24],{"class":123},[117,2623,2123],{"class":212},[117,2625,2626],{"class":123},"(),\n",[117,2628,2629,2631,2633,2635,2637,2639],{"class":119,"line":165},[117,2630,2619],{"class":225},[117,2632,24],{"class":123},[117,2634,454],{"class":212},[117,2636,254],{"class":123},[117,2638,968],{"class":298},[117,2640,265],{"class":123},[117,2642,2643,2645,2647,2649,2651,2653,2655,2657,2659,2661],{"class":119,"line":175},[117,2644,2619],{"class":225},[117,2646,24],{"class":123},[117,2648,544],{"class":212},[117,2650,254],{"class":123},[117,2652,549],{"class":225},[117,2654,24],{"class":123},[117,2656,554],{"class":212},[117,2658,254],{"class":123},[117,2660,559],{"class":298},[117,2662,562],{"class":123},[117,2664,2665],{"class":119,"line":185},[117,2666,573],{"class":123},[117,2668,2669],{"class":119,"line":195},[117,2670,705],{"class":123},[117,2672,2673],{"class":119,"line":201},[117,2674,1921],{"class":123},[13,2676,2677,2678,2681],{},"No Brasil é comum adicionar \"Data de impressão: 19 de maio de 2026\" e \"Documento: DOC-2026-0517\" no rodapé. Empilhe dois ou três ",[17,2679,2680],{},"c.Text(...)",". Em PDFs anexados a NFe (DANFE auxiliar, contratos eletrônicos) esse rodapé aparece em quase todo documento.",[13,2683,2684,2687,2688,2293,2690,2692],{},[1611,2685,2686],{},"Logo à esquerda, número de página à direita."," Duas colunas 8/4 ou 6/6. Imagem à esquerda, ",[17,2689,65],{},[17,2691,518],{}," à direita.",[13,2694,2695,2698,2699,2701],{},[1611,2696,2697],{},"Rodapé \"Continua na próxima página\"."," Sem suporte atual. A closure recebe só ",[17,2700,341],{},", sem índice de página, então não dá para ramificar em \"é a última?\". Colocar isso no corpo exigiria saber o total antes — paradoxo. Está na lista.",[13,2703,2704,2707,2708,2711],{},[1611,2705,2706],{},"Cabeçalho diferente na primeira página."," Mesmo motivo, sem suporte. O workaround é deixar o cabeçalho efetivamente vazio na página 1 colocando um spacer alto no início do corpo, e deixar as demais seguirem o fluxo normal. Deselegante. Um ",[17,2709,2710],{},"doc.HeaderOn(pages, fn)"," está em design.",[40,2713,2715],{"id":2714},"cjk-funciona-direto","CJK funciona direto",[13,2717,2718,2719,2721,2722,2725],{},"Como o gpdf faz subset de TrueType sem CGO, dá para colocar japonês, chinês ou coreano em cabeçalho e rodapé como ",[17,2720,2680],{},". Sem ritual ",[17,2723,2724],{},"AddUTF8Font",", sem \"tofu\" se a fonte cobre os caracteres.",[108,2727,2729],{"className":110,"code":2728,"language":112,"meta":113,"style":113},"doc := template.New(\n    template.WithPageSize(document.A4),\n    template.WithFont(\"NotoSansJP\", notoSansJPRegular),\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(\"社外秘\", template.FontFamily(\"NotoSansJP\"), template.FontSize(8))\n        })\n        r.Col(6, func(c *template.ColBuilder) {\n            c.PageNumber(template.AlignRight(), template.FontSize(8))\n        })\n    })\n})\n",[17,2730,2731,2746,2765,2790,2794,2798,2822,2846,2876,2924,2928,2958,2988,2992,2996],{"__ignoreMap":113},[117,2732,2733,2736,2738,2740,2742,2744],{"class":119,"line":120},[117,2734,2735],{"class":225},"doc ",[117,2737,229],{"class":123},[117,2739,232],{"class":225},[117,2741,24],{"class":123},[117,2743,237],{"class":212},[117,2745,240],{"class":123},[117,2747,2748,2751,2753,2755,2757,2759,2761,2763],{"class":119,"line":131},[117,2749,2750],{"class":225},"    template",[117,2752,24],{"class":123},[117,2754,251],{"class":212},[117,2756,254],{"class":123},[117,2758,257],{"class":225},[117,2760,24],{"class":123},[117,2762,262],{"class":225},[117,2764,265],{"class":123},[117,2766,2767,2769,2771,2774,2776,2778,2781,2783,2785,2788],{"class":119,"line":138},[117,2768,2750],{"class":225},[117,2770,24],{"class":123},[117,2772,2773],{"class":212},"WithFont",[117,2775,254],{"class":123},[117,2777,429],{"class":123},[117,2779,2780],{"class":432},"NotoSansJP",[117,2782,429],{"class":123},[117,2784,394],{"class":123},[117,2786,2787],{"class":225}," notoSansJPRegular",[117,2789,265],{"class":123},[117,2791,2792],{"class":119,"line":148},[117,2793,198],{"class":123},[117,2795,2796],{"class":119,"line":160},[117,2797,135],{"emptyLinePlaceholder":134},[117,2799,2800,2802,2804,2806,2808,2810,2812,2814,2816,2818,2820],{"class":119,"line":165},[117,2801,1664],{"class":225},[117,2803,24],{"class":123},[117,2805,720],{"class":212},[117,2807,327],{"class":123},[117,2809,13],{"class":330},[117,2811,333],{"class":123},[117,2813,336],{"class":127},[117,2815,24],{"class":123},[117,2817,341],{"class":127},[117,2819,344],{"class":123},[117,2821,219],{"class":123},[117,2823,2824,2826,2828,2830,2832,2834,2836,2838,2840,2842,2844],{"class":119,"line":175},[117,2825,1689],{"class":225},[117,2827,24],{"class":123},[117,2829,357],{"class":212},[117,2831,327],{"class":123},[117,2833,362],{"class":330},[117,2835,333],{"class":123},[117,2837,336],{"class":127},[117,2839,24],{"class":123},[117,2841,371],{"class":127},[117,2843,344],{"class":123},[117,2845,219],{"class":123},[117,2847,2848,2850,2852,2854,2856,2858,2860,2862,2864,2866,2868,2870,2872,2874],{"class":119,"line":185},[117,2849,1714],{"class":225},[117,2851,24],{"class":123},[117,2853,386],{"class":212},[117,2855,254],{"class":123},[117,2857,391],{"class":298},[117,2859,394],{"class":123},[117,2861,397],{"class":123},[117,2863,400],{"class":330},[117,2865,333],{"class":123},[117,2867,336],{"class":127},[117,2869,24],{"class":123},[117,2871,409],{"class":127},[117,2873,344],{"class":123},[117,2875,219],{"class":123},[117,2877,2878,2880,2882,2884,2886,2888,2891,2893,2895,2897,2899,2902,2904,2906,2908,2910,2912,2914,2916,2918,2920,2922],{"class":119,"line":195},[117,2879,1745],{"class":225},[117,2881,24],{"class":123},[117,2883,424],{"class":212},[117,2885,254],{"class":123},[117,2887,429],{"class":123},[117,2889,2890],{"class":432},"社外秘",[117,2892,429],{"class":123},[117,2894,394],{"class":123},[117,2896,232],{"class":225},[117,2898,24],{"class":123},[117,2900,2901],{"class":212},"FontFamily",[117,2903,254],{"class":123},[117,2905,429],{"class":123},[117,2907,2780],{"class":432},[117,2909,429],{"class":123},[117,2911,1279],{"class":123},[117,2913,232],{"class":225},[117,2915,24],{"class":123},[117,2917,454],{"class":212},[117,2919,254],{"class":123},[117,2921,968],{"class":298},[117,2923,462],{"class":123},[117,2925,2926],{"class":119,"line":201},[117,2927,573],{"class":123},[117,2929,2930,2932,2934,2936,2938,2940,2942,2944,2946,2948,2950,2952,2954,2956],{"class":119,"line":206},[117,2931,1714],{"class":225},[117,2933,24],{"class":123},[117,2935,386],{"class":212},[117,2937,254],{"class":123},[117,2939,391],{"class":298},[117,2941,394],{"class":123},[117,2943,397],{"class":123},[117,2945,400],{"class":330},[117,2947,333],{"class":123},[117,2949,336],{"class":127},[117,2951,24],{"class":123},[117,2953,409],{"class":127},[117,2955,344],{"class":123},[117,2957,219],{"class":123},[117,2959,2960,2962,2964,2966,2968,2970,2972,2974,2976,2978,2980,2982,2984,2986],{"class":119,"line":222},[117,2961,1745],{"class":225},[117,2963,24],{"class":123},[117,2965,1039],{"class":212},[117,2967,254],{"class":123},[117,2969,336],{"class":225},[117,2971,24],{"class":123},[117,2973,518],{"class":212},[117,2975,447],{"class":123},[117,2977,232],{"class":225},[117,2979,24],{"class":123},[117,2981,454],{"class":212},[117,2983,254],{"class":123},[117,2985,968],{"class":298},[117,2987,462],{"class":123},[117,2989,2990],{"class":119,"line":243},[117,2991,573],{"class":123},[117,2993,2994],{"class":119,"line":268},[117,2995,705],{"class":123},[117,2997,2998],{"class":119,"line":305},[117,2999,1921],{"class":123},[13,3001,3002,3003,3006],{},"O subset embutido no PDF final contém só \"os glifos que aparecem\". Em um relatório de 60 páginas com ",[17,3004,3005],{},"\"社外秘\""," no rodapé, são três glifos da NotoSansJP, não 20.000. Para PDFs que precisam atender PDF/A com restrições de tamanho (anexos a sistemas fiscais brasileiros, por exemplo) isso pesa.",[40,3008,3010],{"id":3009},"performance","Performance",[13,3012,3013],{},"Esta parte importa se você gera PDFs em escala.",[13,3015,3016],{},"A segunda passagem não é grátis, mas é barata. Em um documento de 100 páginas em um M1, a segunda passagem fica abaixo de 50µs — menos de 1% do tempo total de geração. Benchmark de página única do gpdf: 13µs. Cem páginas: 683µs. A resolução de números de página é um fator constante independente da complexidade da página.",[13,3018,3019,3020,3022],{},"Para comparar, o ",[17,3021,34],{}," do gofpdf faz substituição de string sobre o stream inteiro depois das decisões de compressão, o que força recompressão dos streams que contêm o alias. Nos benchmarks do próprio gofpdf, isso fica em cerca de 2–4% do tempo total em um documento de 100 páginas. No gpdf, a substituição ocorre antes da codificação do stream.",[13,3024,3025],{},"Se você gera um milhão de PDFs por dia, a diferença pesa. Se gera dez, não.",[40,3027,3029],{"id":3028},"faq","FAQ",[13,3031,3032,3035,3036,3039],{},[1611,3033,3034],{},"A altura do cabeçalho/rodapé conta na margem da página?","\nSim. gpdf mede a altura renderizada de cabeçalho e rodapé e calcula a altura útil do corpo como ",[17,3037,3038],{},"pageHeight - top_margin - headerHeight - footerHeight - bottom_margin",". Margem superior 20mm + cabeçalho 15mm: o corpo começa a 35mm do topo.",[13,3041,3042,3045],{},[1611,3043,3044],{},"Dá para variar a altura do cabeçalho por página?","\nNão. A closure é avaliada uma vez para medição, e o resultado fica fixo para o documento inteiro. Se precisar de altura variável, projete uma altura máxima fixa e ajuste com espaço em branco.",[13,3047,3048,3051],{},[1611,3049,3050],{},"O que acontece com uma página sem conteúdo?","\ngpdf não gera páginas vazias. Se o corpo cabe em três páginas, o PDF tem três páginas. Cabeçalho e rodapé aparecem nessas três, e em nenhuma outra.",[13,3053,3054,3057,3058,3061],{},[1611,3055,3056],{},"Posso omitir o cabeçalho em páginas paisagem num documento misto?","\nOrientações mistas funcionam via ",[17,3059,3060],{},"WithPageSize(...)"," por página, mas a closure de cabeçalho/rodapé é a mesma para todas independentemente da orientação. O caminho prático é desenhar algo centralizado que funcione nas duas orientações.",[13,3063,3064,3067,3068,3071,3072,3075,3076,53,3079,3082,3083,3086],{},[1611,3065,3066],{},"Funciona com input JSON?","\nSim. O schema JSON tem ",[17,3069,3070],{},"header",", ",[17,3073,3074],{},"footer"," e os tipos ",[17,3077,3078],{},"{\"type\": \"pageNumber\"}",[17,3080,3081],{},"{\"type\": \"totalPages\"}",". O teste ",[17,3084,3085],{},"gpdf/_examples/json/26_page_number_test.go"," valida que o input JSON produz o mesmo PDF golden que o builder.",[13,3088,3089,3096,3097,3100],{},[1611,3090,3091,3092,3095],{},"E com ",[17,3093,3094],{},"text/template"," do Go?","\nSim. ",[17,3098,3099],{},"gpdf/_examples/gotemplate/26_page_number_test.go"," roda o mesmo cenário. Seja qual for a entrada — builder, JSON ou Go template — por baixo roda a mesma paginação de duas passagens.",[40,3102,3104],{"id":3103},"próximos-passos","Próximos passos",[13,3106,3107],{},"Cabeçalho, rodapé e número de página são a parte mais sem graça de um relatório — e também o que faz parecer pronto. Se você vinha escrevendo isso à mão sobre bibliotecas PDF de baixo nível, as poucas linhas deste post são tudo. Pegue o exemplo, troque as strings, suba.",[13,3109,3110,3111,3114],{},"Os pontos em aberto — ",[17,3112,3113],{},"c.PageOf(...)"," para formatação em string única, cabeçalho diferente na primeira página, detecção de \"última página\" — estão na lista. Se algum deles te bloqueia, registre uma issue no GitHub. Casos de uso concretos moldam a API melhor do que pedidos abstratos.",[40,3116,3118],{"id":3117},"experimentar-o-gpdf","Experimentar o gpdf",[13,3120,3121],{},"gpdf é uma biblioteca de geração de PDF para Go. MIT, zero dependências, suporte CJK.",[108,3123,3127],{"className":3124,"code":3125,"language":3126,"meta":113,"style":113},"language-bash shiki shiki-themes material-theme-lighter material-theme material-theme-palenight","go get github.com/gpdf-dev/gpdf\n","bash",[17,3128,3129],{"__ignoreMap":113},[117,3130,3131,3133,3136],{"class":119,"line":120},[117,3132,112],{"class":127},[117,3134,3135],{"class":432}," get",[117,3137,3138],{"class":432}," github.com/gpdf-dev/gpdf\n",[13,3140,3141,3148,3149],{},[3142,3143,3147],"a",{"href":3144,"rel":3145},"https://github.com/gpdf-dev/gpdf",[3146],"nofollow","⭐ Star no GitHub"," · ",[3142,3150,3153],{"href":3151,"rel":3152},"https://gpdf.dev/pt/docs/quickstart",[3146],"Ler a documentação",[3155,3156,3157],"style",{},"html pre.shiki code .sMK4o, html code.shiki .sMK4o{--shiki-light:#39ADB5;--shiki-default:#89DDFF;--shiki-dark:#89DDFF}html pre.shiki code .sBMFI, html code.shiki .sBMFI{--shiki-light:#E2931D;--shiki-default:#FFCB6B;--shiki-dark:#FFCB6B}html pre.shiki code .s7zQu, html code.shiki .s7zQu{--shiki-light:#39ADB5;--shiki-light-font-style:italic;--shiki-default:#89DDFF;--shiki-default-font-style:italic;--shiki-dark:#89DDFF;--shiki-dark-font-style:italic}html pre.shiki code .s2Zo4, html code.shiki .s2Zo4{--shiki-light:#6182B8;--shiki-default:#82AAFF;--shiki-dark:#82AAFF}html pre.shiki code .sTEyZ, html code.shiki .sTEyZ{--shiki-light:#90A4AE;--shiki-default:#EEFFFF;--shiki-dark:#BABED8}html pre.shiki code .sbssI, html code.shiki .sbssI{--shiki-light:#F76D47;--shiki-default:#F78C6C;--shiki-dark:#F78C6C}html pre.shiki code .sHdIc, html code.shiki .sHdIc{--shiki-light:#90A4AE;--shiki-light-font-style:italic;--shiki-default:#EEFFFF;--shiki-default-font-style:italic;--shiki-dark:#BABED8;--shiki-dark-font-style:italic}html pre.shiki code .sfazB, html code.shiki .sfazB{--shiki-light:#91B859;--shiki-default:#C3E88D;--shiki-dark:#C3E88D}html pre.shiki code .spNyl, html code.shiki .spNyl{--shiki-light:#9C3EDA;--shiki-default:#C792EA;--shiki-dark:#C792EA}html .light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html.light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html.dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}",{"title":113,"searchDepth":131,"depth":131,"links":3159},[3160,3161,3162,3165,3166,3167,3168,3169,3170,3171,3172],{"id":42,"depth":131,"text":43},{"id":94,"depth":131,"text":95},{"id":1484,"depth":131,"text":1485,"children":3163},[3164],{"id":1597,"depth":138,"text":1598},{"id":1638,"depth":131,"text":1639},{"id":1937,"depth":131,"text":1938},{"id":2486,"depth":131,"text":2487},{"id":2714,"depth":131,"text":2715},{"id":3009,"depth":131,"text":3010},{"id":3028,"depth":131,"text":3029},{"id":3103,"depth":131,"text":3104},{"id":3117,"depth":131,"text":3118},"2026-05-19","Como adicionar cabeçalho, rodapé e 'Page X of Y' a PDFs em Go com gpdf: dois métodos do builder e um paginador de duas passagens que resolve os totais sozinho.",false,"md",{"name":3178,"totalTime":3179,"tools":3180,"steps":3183},"Adicionar cabeçalho, rodapé e numeração Page X of Y a um PDF em Go","PT15M",[3181,3182],"Go 1.22+","github.com/gpdf-dev/gpdf",[3184,3187,3190,3193,3196],{"name":3185,"text":3186},"Criar o documento com template.New","Chame template.New com WithPageSize(document.A4) e WithMargins. Toda a configuração global de página fica nesse único ponto.",{"name":3188,"text":3189},"Registrar o cabeçalho com doc.Header","Passe uma closure que receba um *template.PageBuilder. Dentro dela, use o mesmo grid de 12 colunas (AutoRow + Col) do corpo. Para o total de páginas, use c.TotalPages().",{"name":3191,"text":3192},"Registrar o rodapé com doc.Footer","Passe outra closure. Coloque c.PageNumber() em qualquer coluna para imprimir o número da página atual. Cabeçalho e rodapé se repetem em todas as páginas, inclusive nas de overflow.",{"name":3194,"text":3195},"Adicionar conteúdo com doc.AddPage","Para cada página lógica chame doc.AddPage e preencha com linhas e colunas. A altura útil do corpo é reduzida automaticamente pela altura medida do cabeçalho e rodapé.",{"name":3197,"text":3198},"Gerar o PDF com doc.Generate","Chame doc.Generate para obter []byte ou doc.Render(w) para escrever em um io.Writer. Pouco antes do retorno, a segunda passagem substitui os placeholders de página pelos números reais.",null,{},"/pt/blog/page-numbers-headers-footers",{"title":5,"description":3174},"pt/blog/027.page-numbers-headers-footers",[3205,3206],"tutorial","internals","WOerU15wPqSEnWFricum5WaH4bfvDe3x4l7BLThhYbI",1779199037288]