[{"data":1,"prerenderedAt":5708},["ShallowReactive",2],{"blog-pt-unidoc-migration":3},{"id":4,"title":5,"author":6,"body":10,"date":5667,"description":5668,"draft":5669,"extension":5670,"howTo":5671,"image":5698,"meta":5699,"navigation":304,"path":5700,"seo":5701,"stem":5702,"tags":5703,"updated":5698,"__hash__":5707},"blogPt/pt/blog/016.unidoc-migration.md","unipdf é AGPL ou pago. Como migrar para o gpdf.",{"name":7,"url":8,"avatar":9},"Taiki Noda","https://nadai.dev/en/about","https://nadai.dev/og-default.png",{"type":11,"value":12,"toc":5650},"minimark",[13,18,43,59,74,77,81,84,87,109,112,116,119,249,256,260,263,410,531,549,556,560,571,878,909,913,916,921,1295,1300,1730,1739,1743,1760,1764,2380,2383,2387,2781,2794,2805,2812,2816,2819,2823,3086,3092,3096,3550,3565,3568,3572,3587,3591,3881,3884,3888,4550,4558,4562,4568,4572,5037,5041,5329,5340,5344,5351,5447,5450,5453,5457,5460,5501,5507,5511,5517,5529,5549,5555,5574,5580,5584,5587,5604,5617,5621,5647],[14,15,17],"h2",{"id":16},"tldr","TL;DR",[19,20,21,25,26,29,30,33,34,38,39,42],"p",{},[22,23,24],"strong",{},"gpdf"," é uma biblioteca PDF em Go puro sob ",[22,27,28],{},"licença MIT",", com ",[22,31,32],{},"zero dependências externas"," e sem etapa de registro de chave de licença. Se você está em ",[35,36,37],"code",{},"unidoc/unipdf"," porque nada mais resolveu CJK ou aplainamento de AcroForm, mas a cláusula AGPL travou o jurídico para distribuição e o tier comercial é difícil de justificar, este guia mapeia a API ",[35,40,41],{},"creator"," do unipdf para o gpdf, peça por peça.",[19,44,45,46,49,50,53,54,58],{},"No último trimestre, um amigo numa fintech levou ",[35,47,48],{},"github.com/unidoc/unipdf/v3"," pelo fluxo de aprovação OSS. O ticket de compliance voltou no dia seguinte com um X vermelho ao lado de ",[22,51,52],{},"AGPL-3.0"," e uma nota do jurídico: ",[55,56,57],"em",{},"\"Não pode ser linkado em produtos fechados distribuíveis. Adquirir licença comercial ou remover.\""," O orçamento comercial chegou com uma anuidade por desenvolvedor que, para um time de doze, fez todo mundo reabrir os resultados de busca.",[19,60,61,62,65,66,69,70,73],{},"Esta é a parte da história do unipdf que não aparece no README. unipdf é tecnicamente excelente — maduro, completo, bem mantido. Também é ",[22,63,64],{},"dual-licensed",": ",[22,67,68],{},"AGPL v3"," para uso aberto, ",[22,71,72],{},"comercial pago"," para o resto. AGPL v3 é o copyleft mais forte de uso comum. Se você linka unipdf num serviço acessado por usuários via rede, o §13 obriga publicar todo o código-fonte correspondente. A maioria dos jurídicos diz não.",[19,75,76],{},"Se você tem código unipdf em produção e a licença pegou na auditoria ou está chegando na renovação, este é o mapa de migração. Se você está começando e pegou unipdf no reflexo porque a documentação era a mais polida, esta é a alternativa que não vem com relação de cobrança.",[14,78,80],{"id":79},"o-que-agpl-ou-pago-significa-na-prática","O que \"AGPL ou pago\" significa na prática",[19,82,83],{},"Muitas bibliotecas Go ganham um rótulo \"AGPL\" sem o time pensar de fato no que significa. unipdf não é assim. O arquivo de licença do repositório é AGPL v3 puro, o README é explícito que uso comercial requer chave, e o próprio binário força isso — chame qualquer API do unipdf sem registrar uma licença na inicialização e você recebe um erro ou uma marca d'água em cada página de saída.",[19,85,86],{},"Você acaba em um destes três modos:",[88,89,90,97,103],"ol",{},[91,92,93,96],"li",{},[22,94,95],{},"Modo AGPL."," Você publica o seu código sob AGPL v3. Cada byte do seu serviço que toca unipdf, mais tudo que linka a ele, precisa ficar disponível para qualquer um que interaja com o serviço pela rede. Para a maioria das ferramentas internas e produtos SaaS, isso é inviável.",[91,98,99,102],{},[22,100,101],{},"Modo comercial."," Você paga à UniDoc por desenvolvedor por ano. Os preços variam — orçamentos públicos recentes giraram em torno de quatro dígitos por assento por ano — e incluem uma chamada de registro (medida ou por chave) que cada binário precisa fazer no startup. A chave é tratada como segredo, então mora no seu secret manager e é injetada em cada container.",[91,104,105,108],{},[22,106,107],{},"Modo trial / avaliação."," Grátis por tempo limitado. Saídas com marca d'água. Inviável em produção.",[19,110,111],{},"Nenhum desses modos é intrinsecamente errado. UniDoc é uma empresa real com engenheiros reais, e o preço reflete o que custa construir e manter uma biblioteca PDF abrangente. O ponto é que a decisão de licenciamento se infiltra em cada camada: revisão jurídica, rotação de segredos, renovação financeira e a superfície de deploy (cada container precisa da chave). gpdf elimina essa coluna inteira da sua planilha por ser MIT.",[14,113,115],{"id":114},"o-que-você-perde-e-o-que-você-mantém","O que você perde e o que você mantém",[19,117,118],{},"Vale ser honesto antes de entrar na API. unipdf faz coisas que gpdf não faz:",[120,121,122,137],"table",{},[123,124,125],"thead",{},[126,127,128,132,135],"tr",{},[129,130,131],"th",{},"Capacidade",[129,133,134],{},"unipdf",[129,136,24],{},[138,139,140,151,161,171,181,190,200,210,220,229,238],"tbody",{},[126,141,142,146,149],{},[143,144,145],"td",{},"Geração de PDF",[143,147,148],{},"✅",[143,150,148],{},[126,152,153,156,158],{},[143,154,155],{},"TrueType / fontes CJK",[143,157,148],{},[143,159,160],{},"✅ (sem CGO, subset automático)",[126,162,163,166,168],{},[143,164,165],{},"Cifragem AES-128/256",[143,167,148],{},[143,169,170],{},"✅ (ISO 32000-2 Rev 6, Go puro)",[126,172,173,176,178],{},[143,174,175],{},"Assinatura PKCS#7 / PAdES",[143,177,148],{},[143,179,180],{},"✅ (suporte RFC 3161 TSA)",[126,182,183,186,188],{},[143,184,185],{},"PDF/A-1b/2b",[143,187,148],{},[143,189,148],{},[126,191,192,195,197],{},[143,193,194],{},"AcroForm — preencher existente",[143,196,148],{},[143,198,199],{},"✅ (apenas flatten, sem criar campo novo)",[126,201,202,205,207],{},[143,203,204],{},"AcroForm — criar campos novos",[143,206,148],{},[143,208,209],{},"❌",[126,211,212,215,217],{},[143,213,214],{},"Parsing / extração de texto",[143,216,148],{},[143,218,219],{},"❌ (gpdf foca em geração)",[126,221,222,225,227],{},[143,223,224],{},"OCR",[143,226,148],{},[143,228,209],{},[126,230,231,234,236],{},[143,232,233],{},"Redaction (tarjamento)",[143,235,148],{},[143,237,209],{},[126,239,240,243,246],{},[143,241,242],{},"Renderização HTML",[143,244,245],{},"parcial",[143,247,248],{},"❌ (use renderer separado e faça merge)",[19,250,251,252,255],{},"Se você precisa de parsing de PDF, OCR ou redaction, esta migração não te leva até o fim. Ou mantém unipdf só nesses caminhos de código (vai continuar devendo a licença comercial para esses binários) ou escolhe uma biblioteca focada em parsing para o lado de leitura. Para o caminho de ",[22,253,254],{},"geração, cifragem, assinatura, fontes e CJK"," — para o que a maior parte das faturas de unipdf de fato vai — gpdf é uma troca completa.",[14,257,259],{"id":258},"removendo-o-código-de-registro-de-licença","Removendo o código de registro de licença",[19,261,262],{},"É o menor diff de toda a migração e o que faz o resto parecer real. Binários unipdf precisam registrar uma chave no startup. Há algumas variantes:",[264,265,270],"pre",{"className":266,"code":267,"language":268,"meta":269,"style":269},"language-go shiki shiki-themes material-theme-lighter material-theme material-theme-palenight","// API key (medida)\nimport \"github.com/unidoc/unipdf/v3/common/license\"\n\nfunc init() {\n    if err := license.SetMeteredKey(os.Getenv(\"UNIDOC_API_KEY\")); err != nil {\n        log.Fatal(err)\n    }\n}\n","go","",[35,271,272,281,299,306,322,379,398,404],{"__ignoreMap":269},[273,274,277],"span",{"class":275,"line":276},"line",1,[273,278,280],{"class":279},"sHwdD","// API key (medida)\n",[273,282,284,288,292,296],{"class":275,"line":283},2,[273,285,287],{"class":286},"s7zQu","import",[273,289,291],{"class":290},"sMK4o"," \"",[273,293,295],{"class":294},"sBMFI","github.com/unidoc/unipdf/v3/common/license",[273,297,298],{"class":290},"\"\n",[273,300,302],{"class":275,"line":301},3,[273,303,305],{"emptyLinePlaceholder":304},true,"\n",[273,307,309,312,316,319],{"class":275,"line":308},4,[273,310,311],{"class":290},"func",[273,313,315],{"class":314},"s2Zo4"," init",[273,317,318],{"class":290},"()",[273,320,321],{"class":290}," {\n",[273,323,325,328,332,335,338,341,344,347,350,352,355,357,360,364,366,369,371,374,377],{"class":275,"line":324},5,[273,326,327],{"class":286},"    if",[273,329,331],{"class":330},"sTEyZ"," err ",[273,333,334],{"class":290},":=",[273,336,337],{"class":330}," license",[273,339,340],{"class":290},".",[273,342,343],{"class":314},"SetMeteredKey",[273,345,346],{"class":290},"(",[273,348,349],{"class":330},"os",[273,351,340],{"class":290},[273,353,354],{"class":314},"Getenv",[273,356,346],{"class":290},[273,358,359],{"class":290},"\"",[273,361,363],{"class":362},"sfazB","UNIDOC_API_KEY",[273,365,359],{"class":290},[273,367,368],{"class":290},"));",[273,370,331],{"class":330},[273,372,373],{"class":290},"!=",[273,375,376],{"class":290}," nil",[273,378,321],{"class":290},[273,380,382,385,387,390,392,395],{"class":275,"line":381},6,[273,383,384],{"class":330},"        log",[273,386,340],{"class":290},[273,388,389],{"class":314},"Fatal",[273,391,346],{"class":290},[273,393,394],{"class":330},"err",[273,396,397],{"class":290},")\n",[273,399,401],{"class":275,"line":400},7,[273,402,403],{"class":290},"    }\n",[273,405,407],{"class":275,"line":406},8,[273,408,409],{"class":290},"}\n",[264,411,413],{"className":266,"code":412,"language":268,"meta":269,"style":269},"// Arquivo de licença offline\nfunc init() {\n    licenseKey, _ := os.ReadFile(\"/etc/unidoc/license.txt\")\n    if err := license.SetLicenseKey(string(licenseKey), \"Acme Corp\"); err != nil {\n        log.Fatal(err)\n    }\n}\n",[35,414,415,420,430,462,509,523,527],{"__ignoreMap":269},[273,416,417],{"class":275,"line":276},[273,418,419],{"class":279},"// Arquivo de licença offline\n",[273,421,422,424,426,428],{"class":275,"line":283},[273,423,311],{"class":290},[273,425,315],{"class":314},[273,427,318],{"class":290},[273,429,321],{"class":290},[273,431,432,435,438,441,443,446,448,451,453,455,458,460],{"class":275,"line":301},[273,433,434],{"class":330},"    licenseKey",[273,436,437],{"class":290},",",[273,439,440],{"class":330}," _ ",[273,442,334],{"class":290},[273,444,445],{"class":330}," os",[273,447,340],{"class":290},[273,449,450],{"class":314},"ReadFile",[273,452,346],{"class":290},[273,454,359],{"class":290},[273,456,457],{"class":362},"/etc/unidoc/license.txt",[273,459,359],{"class":290},[273,461,397],{"class":290},[273,463,464,466,468,470,472,474,477,479,483,485,488,491,493,496,498,501,503,505,507],{"class":275,"line":308},[273,465,327],{"class":286},[273,467,331],{"class":330},[273,469,334],{"class":290},[273,471,337],{"class":330},[273,473,340],{"class":290},[273,475,476],{"class":314},"SetLicenseKey",[273,478,346],{"class":290},[273,480,482],{"class":481},"spNyl","string",[273,484,346],{"class":290},[273,486,487],{"class":330},"licenseKey",[273,489,490],{"class":290},"),",[273,492,291],{"class":290},[273,494,495],{"class":362},"Acme Corp",[273,497,359],{"class":290},[273,499,500],{"class":290},");",[273,502,331],{"class":330},[273,504,373],{"class":290},[273,506,376],{"class":290},[273,508,321],{"class":290},[273,510,511,513,515,517,519,521],{"class":275,"line":324},[273,512,384],{"class":330},[273,514,340],{"class":290},[273,516,389],{"class":314},[273,518,346],{"class":290},[273,520,394],{"class":330},[273,522,397],{"class":290},[273,524,525],{"class":275,"line":381},[273,526,403],{"class":290},[273,528,529],{"class":275,"line":400},[273,530,409],{"class":290},[19,532,533,534,537,538,540,541,544,545,548],{},"No gpdf não existe equivalente. Apague o bloco ",[35,535,536],{},"init()"," inteiro. Tire ",[35,539,363],{}," do seu secret manager, das variáveis de CI e dos manifests de container. Remova o arquivo de licença da imagem. A única coisa que você importa é ",[35,542,543],{},"github.com/gpdf-dev/gpdf",", e a única exigência é chamar ",[35,546,547],{},"gpdf.NewDocument"," em algum lugar.",[19,550,551,552,555],{},"Só isso. Também é o teste de que sua migração de fato aterrissou: ",[35,553,554],{},"grep -r unidoc ."," deve retornar zero ocorrências quando terminar.",[14,557,559],{"id":558},"tabela-de-mapeamento-da-api","Tabela de mapeamento da API",[19,561,562,563,566,567,570],{},"A tabela é a cola. As seções depois andam por cinco pares concretos. unipdf chama o builder de alto nível de ",[35,564,565],{},"Creator","; gpdf chama de ",[35,568,569],{},"Document",". As formas são parecidas o suficiente para a maioria do código se traduzir por inspeção visual.",[120,572,573,588],{},[123,574,575],{},[126,576,577,580,586],{},[129,578,579],{},"O que você quer fazer",[129,581,582,583,585],{},"unipdf (",[35,584,41],{},")",[129,587,24],{},[138,589,590,605,620,635,654,672,690,706,721,736,751,773,795,815,830,848,863],{},[126,591,592,595,600],{},[143,593,594],{},"Criar um builder",[143,596,597],{},[35,598,599],{},"c := creator.New(); c.SetPageSize(creator.PageSizeA4)",[143,601,602],{},[35,603,604],{},"doc := gpdf.NewDocument(gpdf.WithPageSize(document.A4))",[126,606,607,610,615],{},[143,608,609],{},"Definir margens",[143,611,612],{},[35,613,614],{},"c.SetPageMargins(L, R, T, B)",[143,616,617],{},[35,618,619],{},"gpdf.WithMargins(document.UniformEdges(document.Mm(20)))",[126,621,622,625,630],{},[143,623,624],{},"Nova página",[143,626,627],{},[35,628,629],{},"c.NewPage()",[143,631,632],{},[35,633,634],{},"page := doc.AddPage()",[126,636,637,640,645],{},[143,638,639],{},"Linha única de texto",[143,641,642],{},[35,643,644],{},"p := c.NewParagraph(\"hi\"); c.Draw(p)",[143,646,647,650,651],{},[35,648,649],{},"c.Text(\"hi\")"," ",[55,652,653],{},"(dentro de uma coluna)",[126,655,656,659,664],{},[143,657,658],{},"Texto com quebra",[143,660,661],{},[35,662,663],{},"p := c.NewStyledParagraph(); p.SetText(...); c.Draw(p)",[143,665,666,650,669],{},[35,667,668],{},"c.Text(body)",[55,670,671],{},"(quebra automática)",[126,673,674,677,682],{},[143,675,676],{},"Registro de fonte",[143,678,679],{},[35,680,681],{},"model.NewCompositePdfFontFromTTFFile(path)",[143,683,684,650,687],{},[35,685,686],{},"gpdf.WithFont(\"Name\", ttfBytes)",[55,688,689],{},"(no construtor)",[126,691,692,695,700],{},[143,693,694],{},"Aplicar fonte ao texto",[143,696,697],{},[35,698,699],{},"style.Font = font; style.FontSize = 12",[143,701,702,705],{},[35,703,704],{},"template.FontFamily(\"Name\"), template.FontSize(12)"," por-texto",[126,707,708,711,716],{},[143,709,710],{},"Cor",[143,712,713],{},[35,714,715],{},"style.Color = creator.ColorRGBFromHex(\"#1A237E\")",[143,717,718],{},[35,719,720],{},"template.TextColor(pdf.RGBHex(0x1A237E))",[126,722,723,726,731],{},[143,724,725],{},"Tabela",[143,727,728],{},[35,729,730],{},"t := c.NewTable(4); t.SetColumnWidths(...); c.Draw(t)",[143,732,733],{},[35,734,735],{},"c.Table(headers, rows, template.ColumnWidths(...))",[126,737,738,741,746],{},[143,739,740],{},"Imagem",[143,742,743],{},[35,744,745],{},"img, _ := c.NewImageFromFile(path); img.ScaleToWidth(w); c.Draw(img)",[143,747,748],{},[35,749,750],{},"c.Image(imgBytes, template.FitWidth(document.Mm(50)))",[126,752,753,756,765],{},[143,754,755],{},"Cabeçalho / rodapé",[143,757,758,761,762],{},[35,759,760],{},"c.DrawHeader(fn)"," / ",[35,763,764],{},"c.DrawFooter(fn)",[143,766,767,761,770],{},[35,768,769],{},"doc.Header(fn)",[35,771,772],{},"doc.Footer(fn)",[126,774,775,778,784],{},[143,776,777],{},"Número de página",[143,779,780,781],{},"manual via args de ",[35,782,783],{},"DrawFooter",[143,785,786,761,789,650,792],{},[35,787,788],{},"c.PageNumber()",[35,790,791],{},"c.TotalPages()",[55,793,794],{},"(placeholders)",[126,796,797,800,810],{},[143,798,799],{},"Cifragem",[143,801,802,805,806,809],{},[35,803,804],{},"model.PdfWriter"," + ",[35,807,808],{},"Encrypt"," re-encoding",[143,811,812],{},[35,813,814],{},"gpdf.WithEncryption(gpdf.AES256, \"user\", \"owner\", perms)",[126,816,817,820,825],{},[143,818,819],{},"Assinatura",[143,821,822],{},[35,823,824],{},"model.NewPdfAppender(...).Sign(...)",[143,826,827],{},[35,828,829],{},"gpdf.SignDocument(pdfBytes, signer, opts)",[126,831,832,835,843],{},[143,833,834],{},"Registro de licença",[143,836,837,840,841],{},[35,838,839],{},"license.SetMeteredKey(...)"," em ",[35,842,536],{},[143,844,845],{},[55,846,847],{},"(nenhum — apague)",[126,849,850,853,858],{},[143,851,852],{},"Saída para arquivo",[143,854,855],{},[35,856,857],{},"c.WriteToFile(\"out.pdf\")",[143,859,860],{},[35,861,862],{},"data, _ := doc.Generate(); os.WriteFile(\"out.pdf\", data, 0o644)",[126,864,865,868,873],{},[143,866,867],{},"Saída para writer",[143,869,870],{},[35,871,872],{},"c.Write(w)",[143,874,875],{},[35,876,877],{},"doc.Render(w)",[19,879,880,881,884,885,888,889,892,893,896,897,900,901,904,905,908],{},"Duas mudanças estruturais para guardar. O creator do unipdf é ",[22,882,883],{},"com estado",": você constrói um ",[35,886,887],{},"Paragraph"," ou uma ",[35,890,891],{},"Table"," e chama ",[35,894,895],{},"c.Draw(thing)"," para confirmar. gpdf é ",[22,898,899],{},"declarativo",": você descreve uma árvore de linhas e colunas e deixa o motor de layout posicionar. A segunda mudança é que gpdf tem uma ",[22,902,903],{},"grade de 12 colunas"," como o Bootstrap. Toda linha tem implicitamente 12 unidades de largura; você gasta com ",[35,906,907],{},"r.Col(n, fn)",". A maioria dos layouts colapsa em duas ou três linhas assim que você para de medir larguras em milímetros.",[14,910,912],{"id":911},"antes-depois-1-o-pdf-mais-simples-possível","Antes / Depois 1: o PDF mais simples possível",[19,914,915],{},"O par \"hello world\". A versão unipdf não é longa; só tem mais cerimônia por causa da chamada de licença.",[19,917,918],{},[22,919,920],{},"Antes — unipdf:",[264,922,924],{"className":266,"code":923,"language":268,"meta":269,"style":269},"package main\n\nimport (\n    \"log\"\n    \"os\"\n\n    \"github.com/unidoc/unipdf/v3/common/license\"\n    \"github.com/unidoc/unipdf/v3/creator\"\n)\n\nfunc init() {\n    if err := license.SetMeteredKey(os.Getenv(\"UNIDOC_API_KEY\")); err != nil {\n        log.Fatal(err)\n    }\n}\n\nfunc main() {\n    c := creator.New()\n    c.SetPageSize(creator.PageSizeA4)\n\n    p := c.NewParagraph(\"Hello, World!\")\n    p.SetFontSize(24)\n    if err := c.Draw(p); err != nil {\n        log.Fatal(err)\n    }\n\n    if err := c.WriteToFile(\"hello.pdf\"); err != nil {\n        log.Fatal(err)\n    }\n}\n",[35,925,926,934,938,945,955,963,967,975,984,989,994,1005,1046,1061,1066,1071,1076,1088,1107,1129,1134,1161,1180,1210,1225,1230,1235,1270,1285,1290],{"__ignoreMap":269},[273,927,928,931],{"class":275,"line":276},[273,929,930],{"class":290},"package",[273,932,933],{"class":294}," main\n",[273,935,936],{"class":275,"line":283},[273,937,305],{"emptyLinePlaceholder":304},[273,939,940,942],{"class":275,"line":301},[273,941,287],{"class":286},[273,943,944],{"class":290}," (\n",[273,946,947,950,953],{"class":275,"line":308},[273,948,949],{"class":290},"    \"",[273,951,952],{"class":294},"log",[273,954,298],{"class":290},[273,956,957,959,961],{"class":275,"line":324},[273,958,949],{"class":290},[273,960,349],{"class":294},[273,962,298],{"class":290},[273,964,965],{"class":275,"line":381},[273,966,305],{"emptyLinePlaceholder":304},[273,968,969,971,973],{"class":275,"line":400},[273,970,949],{"class":290},[273,972,295],{"class":294},[273,974,298],{"class":290},[273,976,977,979,982],{"class":275,"line":406},[273,978,949],{"class":290},[273,980,981],{"class":294},"github.com/unidoc/unipdf/v3/creator",[273,983,298],{"class":290},[273,985,987],{"class":275,"line":986},9,[273,988,397],{"class":290},[273,990,992],{"class":275,"line":991},10,[273,993,305],{"emptyLinePlaceholder":304},[273,995,997,999,1001,1003],{"class":275,"line":996},11,[273,998,311],{"class":290},[273,1000,315],{"class":314},[273,1002,318],{"class":290},[273,1004,321],{"class":290},[273,1006,1008,1010,1012,1014,1016,1018,1020,1022,1024,1026,1028,1030,1032,1034,1036,1038,1040,1042,1044],{"class":275,"line":1007},12,[273,1009,327],{"class":286},[273,1011,331],{"class":330},[273,1013,334],{"class":290},[273,1015,337],{"class":330},[273,1017,340],{"class":290},[273,1019,343],{"class":314},[273,1021,346],{"class":290},[273,1023,349],{"class":330},[273,1025,340],{"class":290},[273,1027,354],{"class":314},[273,1029,346],{"class":290},[273,1031,359],{"class":290},[273,1033,363],{"class":362},[273,1035,359],{"class":290},[273,1037,368],{"class":290},[273,1039,331],{"class":330},[273,1041,373],{"class":290},[273,1043,376],{"class":290},[273,1045,321],{"class":290},[273,1047,1049,1051,1053,1055,1057,1059],{"class":275,"line":1048},13,[273,1050,384],{"class":330},[273,1052,340],{"class":290},[273,1054,389],{"class":314},[273,1056,346],{"class":290},[273,1058,394],{"class":330},[273,1060,397],{"class":290},[273,1062,1064],{"class":275,"line":1063},14,[273,1065,403],{"class":290},[273,1067,1069],{"class":275,"line":1068},15,[273,1070,409],{"class":290},[273,1072,1074],{"class":275,"line":1073},16,[273,1075,305],{"emptyLinePlaceholder":304},[273,1077,1079,1081,1084,1086],{"class":275,"line":1078},17,[273,1080,311],{"class":290},[273,1082,1083],{"class":314}," main",[273,1085,318],{"class":290},[273,1087,321],{"class":290},[273,1089,1091,1094,1096,1099,1101,1104],{"class":275,"line":1090},18,[273,1092,1093],{"class":330},"    c ",[273,1095,334],{"class":290},[273,1097,1098],{"class":330}," creator",[273,1100,340],{"class":290},[273,1102,1103],{"class":314},"New",[273,1105,1106],{"class":290},"()\n",[273,1108,1110,1113,1115,1118,1120,1122,1124,1127],{"class":275,"line":1109},19,[273,1111,1112],{"class":330},"    c",[273,1114,340],{"class":290},[273,1116,1117],{"class":314},"SetPageSize",[273,1119,346],{"class":290},[273,1121,41],{"class":330},[273,1123,340],{"class":290},[273,1125,1126],{"class":330},"PageSizeA4",[273,1128,397],{"class":290},[273,1130,1132],{"class":275,"line":1131},20,[273,1133,305],{"emptyLinePlaceholder":304},[273,1135,1137,1140,1142,1145,1147,1150,1152,1154,1157,1159],{"class":275,"line":1136},21,[273,1138,1139],{"class":330},"    p ",[273,1141,334],{"class":290},[273,1143,1144],{"class":330}," c",[273,1146,340],{"class":290},[273,1148,1149],{"class":314},"NewParagraph",[273,1151,346],{"class":290},[273,1153,359],{"class":290},[273,1155,1156],{"class":362},"Hello, World!",[273,1158,359],{"class":290},[273,1160,397],{"class":290},[273,1162,1164,1167,1169,1172,1174,1178],{"class":275,"line":1163},22,[273,1165,1166],{"class":330},"    p",[273,1168,340],{"class":290},[273,1170,1171],{"class":314},"SetFontSize",[273,1173,346],{"class":290},[273,1175,1177],{"class":1176},"sbssI","24",[273,1179,397],{"class":290},[273,1181,1183,1185,1187,1189,1191,1193,1196,1198,1200,1202,1204,1206,1208],{"class":275,"line":1182},23,[273,1184,327],{"class":286},[273,1186,331],{"class":330},[273,1188,334],{"class":290},[273,1190,1144],{"class":330},[273,1192,340],{"class":290},[273,1194,1195],{"class":314},"Draw",[273,1197,346],{"class":290},[273,1199,19],{"class":330},[273,1201,500],{"class":290},[273,1203,331],{"class":330},[273,1205,373],{"class":290},[273,1207,376],{"class":290},[273,1209,321],{"class":290},[273,1211,1213,1215,1217,1219,1221,1223],{"class":275,"line":1212},24,[273,1214,384],{"class":330},[273,1216,340],{"class":290},[273,1218,389],{"class":314},[273,1220,346],{"class":290},[273,1222,394],{"class":330},[273,1224,397],{"class":290},[273,1226,1228],{"class":275,"line":1227},25,[273,1229,403],{"class":290},[273,1231,1233],{"class":275,"line":1232},26,[273,1234,305],{"emptyLinePlaceholder":304},[273,1236,1238,1240,1242,1244,1246,1248,1251,1253,1255,1258,1260,1262,1264,1266,1268],{"class":275,"line":1237},27,[273,1239,327],{"class":286},[273,1241,331],{"class":330},[273,1243,334],{"class":290},[273,1245,1144],{"class":330},[273,1247,340],{"class":290},[273,1249,1250],{"class":314},"WriteToFile",[273,1252,346],{"class":290},[273,1254,359],{"class":290},[273,1256,1257],{"class":362},"hello.pdf",[273,1259,359],{"class":290},[273,1261,500],{"class":290},[273,1263,331],{"class":330},[273,1265,373],{"class":290},[273,1267,376],{"class":290},[273,1269,321],{"class":290},[273,1271,1273,1275,1277,1279,1281,1283],{"class":275,"line":1272},28,[273,1274,384],{"class":330},[273,1276,340],{"class":290},[273,1278,389],{"class":314},[273,1280,346],{"class":290},[273,1282,394],{"class":330},[273,1284,397],{"class":290},[273,1286,1288],{"class":275,"line":1287},29,[273,1289,403],{"class":290},[273,1291,1293],{"class":275,"line":1292},30,[273,1294,409],{"class":290},[19,1296,1297],{},[22,1298,1299],{},"Depois — gpdf:",[264,1301,1303],{"className":266,"code":1302,"language":268,"meta":269,"style":269},"package main\n\nimport (\n    \"log\"\n    \"os\"\n\n    \"github.com/gpdf-dev/gpdf\"\n    \"github.com/gpdf-dev/gpdf/document\"\n    \"github.com/gpdf-dev/gpdf/template\"\n)\n\nfunc main() {\n    doc := gpdf.NewDocument(\n        gpdf.WithPageSize(document.A4),\n        gpdf.WithMargins(document.UniformEdges(document.Mm(20))),\n    )\n\n    page := doc.AddPage()\n    page.AutoRow(func(r *template.RowBuilder) {\n        r.Col(12, func(c *template.ColBuilder) {\n            c.Text(\"Hello, World!\", template.FontSize(24), template.Bold())\n        })\n    })\n\n    data, err := doc.Generate()\n    if err != nil {\n        log.Fatal(err)\n    }\n    if err := os.WriteFile(\"hello.pdf\", data, 0o644); err != nil {\n        log.Fatal(err)\n    }\n}\n",[35,1304,1305,1311,1315,1321,1329,1337,1341,1349,1358,1367,1371,1375,1385,1403,1426,1461,1466,1470,1487,1519,1555,1599,1604,1609,1613,1633,1645,1659,1663,1706,1720,1725],{"__ignoreMap":269},[273,1306,1307,1309],{"class":275,"line":276},[273,1308,930],{"class":290},[273,1310,933],{"class":294},[273,1312,1313],{"class":275,"line":283},[273,1314,305],{"emptyLinePlaceholder":304},[273,1316,1317,1319],{"class":275,"line":301},[273,1318,287],{"class":286},[273,1320,944],{"class":290},[273,1322,1323,1325,1327],{"class":275,"line":308},[273,1324,949],{"class":290},[273,1326,952],{"class":294},[273,1328,298],{"class":290},[273,1330,1331,1333,1335],{"class":275,"line":324},[273,1332,949],{"class":290},[273,1334,349],{"class":294},[273,1336,298],{"class":290},[273,1338,1339],{"class":275,"line":381},[273,1340,305],{"emptyLinePlaceholder":304},[273,1342,1343,1345,1347],{"class":275,"line":400},[273,1344,949],{"class":290},[273,1346,543],{"class":294},[273,1348,298],{"class":290},[273,1350,1351,1353,1356],{"class":275,"line":406},[273,1352,949],{"class":290},[273,1354,1355],{"class":294},"github.com/gpdf-dev/gpdf/document",[273,1357,298],{"class":290},[273,1359,1360,1362,1365],{"class":275,"line":986},[273,1361,949],{"class":290},[273,1363,1364],{"class":294},"github.com/gpdf-dev/gpdf/template",[273,1366,298],{"class":290},[273,1368,1369],{"class":275,"line":991},[273,1370,397],{"class":290},[273,1372,1373],{"class":275,"line":996},[273,1374,305],{"emptyLinePlaceholder":304},[273,1376,1377,1379,1381,1383],{"class":275,"line":1007},[273,1378,311],{"class":290},[273,1380,1083],{"class":314},[273,1382,318],{"class":290},[273,1384,321],{"class":290},[273,1386,1387,1390,1392,1395,1397,1400],{"class":275,"line":1048},[273,1388,1389],{"class":330},"    doc ",[273,1391,334],{"class":290},[273,1393,1394],{"class":330}," gpdf",[273,1396,340],{"class":290},[273,1398,1399],{"class":314},"NewDocument",[273,1401,1402],{"class":290},"(\n",[273,1404,1405,1408,1410,1413,1415,1418,1420,1423],{"class":275,"line":1063},[273,1406,1407],{"class":330},"        gpdf",[273,1409,340],{"class":290},[273,1411,1412],{"class":314},"WithPageSize",[273,1414,346],{"class":290},[273,1416,1417],{"class":330},"document",[273,1419,340],{"class":290},[273,1421,1422],{"class":330},"A4",[273,1424,1425],{"class":290},"),\n",[273,1427,1428,1430,1432,1435,1437,1439,1441,1444,1446,1448,1450,1453,1455,1458],{"class":275,"line":1068},[273,1429,1407],{"class":330},[273,1431,340],{"class":290},[273,1433,1434],{"class":314},"WithMargins",[273,1436,346],{"class":290},[273,1438,1417],{"class":330},[273,1440,340],{"class":290},[273,1442,1443],{"class":314},"UniformEdges",[273,1445,346],{"class":290},[273,1447,1417],{"class":330},[273,1449,340],{"class":290},[273,1451,1452],{"class":314},"Mm",[273,1454,346],{"class":290},[273,1456,1457],{"class":1176},"20",[273,1459,1460],{"class":290},"))),\n",[273,1462,1463],{"class":275,"line":1073},[273,1464,1465],{"class":290},"    )\n",[273,1467,1468],{"class":275,"line":1078},[273,1469,305],{"emptyLinePlaceholder":304},[273,1471,1472,1475,1477,1480,1482,1485],{"class":275,"line":1090},[273,1473,1474],{"class":330},"    page ",[273,1476,334],{"class":290},[273,1478,1479],{"class":330}," doc",[273,1481,340],{"class":290},[273,1483,1484],{"class":314},"AddPage",[273,1486,1106],{"class":290},[273,1488,1489,1492,1494,1497,1500,1504,1507,1510,1512,1515,1517],{"class":275,"line":1109},[273,1490,1491],{"class":330},"    page",[273,1493,340],{"class":290},[273,1495,1496],{"class":314},"AutoRow",[273,1498,1499],{"class":290},"(func(",[273,1501,1503],{"class":1502},"sHdIc","r",[273,1505,1506],{"class":290}," *",[273,1508,1509],{"class":294},"template",[273,1511,340],{"class":290},[273,1513,1514],{"class":294},"RowBuilder",[273,1516,585],{"class":290},[273,1518,321],{"class":290},[273,1520,1521,1524,1526,1529,1531,1534,1536,1539,1542,1544,1546,1548,1551,1553],{"class":275,"line":1131},[273,1522,1523],{"class":330},"        r",[273,1525,340],{"class":290},[273,1527,1528],{"class":314},"Col",[273,1530,346],{"class":290},[273,1532,1533],{"class":1176},"12",[273,1535,437],{"class":290},[273,1537,1538],{"class":290}," func(",[273,1540,1541],{"class":1502},"c",[273,1543,1506],{"class":290},[273,1545,1509],{"class":294},[273,1547,340],{"class":290},[273,1549,1550],{"class":294},"ColBuilder",[273,1552,585],{"class":290},[273,1554,321],{"class":290},[273,1556,1557,1560,1562,1565,1567,1569,1571,1573,1575,1578,1580,1583,1585,1587,1589,1591,1593,1596],{"class":275,"line":1136},[273,1558,1559],{"class":330},"            c",[273,1561,340],{"class":290},[273,1563,1564],{"class":314},"Text",[273,1566,346],{"class":290},[273,1568,359],{"class":290},[273,1570,1156],{"class":362},[273,1572,359],{"class":290},[273,1574,437],{"class":290},[273,1576,1577],{"class":330}," template",[273,1579,340],{"class":290},[273,1581,1582],{"class":314},"FontSize",[273,1584,346],{"class":290},[273,1586,1177],{"class":1176},[273,1588,490],{"class":290},[273,1590,1577],{"class":330},[273,1592,340],{"class":290},[273,1594,1595],{"class":314},"Bold",[273,1597,1598],{"class":290},"())\n",[273,1600,1601],{"class":275,"line":1163},[273,1602,1603],{"class":290},"        })\n",[273,1605,1606],{"class":275,"line":1182},[273,1607,1608],{"class":290},"    })\n",[273,1610,1611],{"class":275,"line":1212},[273,1612,305],{"emptyLinePlaceholder":304},[273,1614,1615,1618,1620,1622,1624,1626,1628,1631],{"class":275,"line":1227},[273,1616,1617],{"class":330},"    data",[273,1619,437],{"class":290},[273,1621,331],{"class":330},[273,1623,334],{"class":290},[273,1625,1479],{"class":330},[273,1627,340],{"class":290},[273,1629,1630],{"class":314},"Generate",[273,1632,1106],{"class":290},[273,1634,1635,1637,1639,1641,1643],{"class":275,"line":1232},[273,1636,327],{"class":286},[273,1638,331],{"class":330},[273,1640,373],{"class":290},[273,1642,376],{"class":290},[273,1644,321],{"class":290},[273,1646,1647,1649,1651,1653,1655,1657],{"class":275,"line":1237},[273,1648,384],{"class":330},[273,1650,340],{"class":290},[273,1652,389],{"class":314},[273,1654,346],{"class":290},[273,1656,394],{"class":330},[273,1658,397],{"class":290},[273,1660,1661],{"class":275,"line":1272},[273,1662,403],{"class":290},[273,1664,1665,1667,1669,1671,1673,1675,1678,1680,1682,1684,1686,1688,1691,1693,1696,1698,1700,1702,1704],{"class":275,"line":1287},[273,1666,327],{"class":286},[273,1668,331],{"class":330},[273,1670,334],{"class":290},[273,1672,445],{"class":330},[273,1674,340],{"class":290},[273,1676,1677],{"class":314},"WriteFile",[273,1679,346],{"class":290},[273,1681,359],{"class":290},[273,1683,1257],{"class":362},[273,1685,359],{"class":290},[273,1687,437],{"class":290},[273,1689,1690],{"class":330}," data",[273,1692,437],{"class":290},[273,1694,1695],{"class":1176}," 0o644",[273,1697,500],{"class":290},[273,1699,331],{"class":330},[273,1701,373],{"class":290},[273,1703,376],{"class":290},[273,1705,321],{"class":290},[273,1707,1708,1710,1712,1714,1716,1718],{"class":275,"line":1292},[273,1709,384],{"class":330},[273,1711,340],{"class":290},[273,1713,389],{"class":314},[273,1715,346],{"class":290},[273,1717,394],{"class":330},[273,1719,397],{"class":290},[273,1721,1723],{"class":275,"line":1722},31,[273,1724,403],{"class":290},[273,1726,1728],{"class":275,"line":1727},32,[273,1729,409],{"class":290},[19,1731,1732,1733,1735,1736,1738],{},"Três coisas para notar. O bloco ",[35,1734,536],{}," sumiu — sem chave, sem variável de ambiente. A construção usa opções em vez de mutar o builder. O texto vive dentro de uma linha e coluna em vez de ser um ",[35,1737,887],{}," solto que você desenha depois. A grade está fazendo o posicionamento; você não escolhe coordenadas.",[14,1740,1742],{"id":1741},"antes-depois-2-tabela-de-itens-de-uma-fatura","Antes / Depois 2: tabela de itens de uma fatura",[19,1744,1745,1746,1748,1749,1752,1753,761,1756,1759],{},"Tabelas são onde a API creator do unipdf alonga. Você constrói uma ",[35,1747,891],{},", chama ",[35,1750,1751],{},"SetColumnWidths"," com frações absolutas, monta células uma a uma com ",[35,1754,1755],{},"NewCell",[35,1757,1758],{},"SetContent"," e configura bordas e alinhamento de cada célula à mão.",[19,1761,1762],{},[22,1763,920],{},[264,1765,1767],{"className":266,"code":1766,"language":268,"meta":269,"style":269},"table := c.NewTable(4)\ntable.SetColumnWidths(0.5, 0.15, 0.15, 0.2)\n\nheaderStyle := c.NewTextStyle()\nheaderStyle.Font, _ = model.NewStandard14Font(\"Helvetica-Bold\")\nheaderStyle.FontSize = 11\nheaderStyle.Color = creator.ColorWhite\n\ndrawHeaderCell := func(text string) {\n    cell := table.NewCell()\n    cell.SetBackgroundColor(creator.ColorRGBFromHex(\"#1A237E\"))\n    cell.SetBorder(creator.CellBorderSideAll, creator.CellBorderStyleSingle, 0.5)\n\n    p := c.NewStyledParagraph()\n    chunk := p.Append(text)\n    chunk.Style = headerStyle\n    cell.SetContent(p)\n}\n\nfor _, h := range []string{\"Descrição\", \"Qtd.\", \"Unit.\", \"Total\"} {\n    drawHeaderCell(h)\n}\n\nfor _, row := range items {\n    for _, cellText := range row {\n        cell := table.NewCell()\n        cell.SetBorder(creator.CellBorderSideAll, creator.CellBorderStyleSingle, 0.3)\n\n        p := c.NewParagraph(cellText)\n        p.SetFontSize(11)\n        cell.SetContent(p)\n    }\n}\n\nif err := c.Draw(table); err != nil {\n    log.Fatal(err)\n}\n",[35,1768,1769,1790,1819,1823,1839,1875,1889,1907,1911,1930,1946,1977,2011,2015,2030,2051,2066,2080,2084,2088,2153,2165,2169,2173,2194,2214,2229,2261,2265,2285,2301,2315,2319,2324,2329,2359,2375],{"__ignoreMap":269},[273,1770,1771,1774,1776,1778,1780,1783,1785,1788],{"class":275,"line":276},[273,1772,1773],{"class":330},"table ",[273,1775,334],{"class":290},[273,1777,1144],{"class":330},[273,1779,340],{"class":290},[273,1781,1782],{"class":314},"NewTable",[273,1784,346],{"class":290},[273,1786,1787],{"class":1176},"4",[273,1789,397],{"class":290},[273,1791,1792,1794,1796,1798,1800,1803,1805,1808,1810,1812,1814,1817],{"class":275,"line":283},[273,1793,120],{"class":330},[273,1795,340],{"class":290},[273,1797,1751],{"class":314},[273,1799,346],{"class":290},[273,1801,1802],{"class":1176},"0.5",[273,1804,437],{"class":290},[273,1806,1807],{"class":1176}," 0.15",[273,1809,437],{"class":290},[273,1811,1807],{"class":1176},[273,1813,437],{"class":290},[273,1815,1816],{"class":1176}," 0.2",[273,1818,397],{"class":290},[273,1820,1821],{"class":275,"line":301},[273,1822,305],{"emptyLinePlaceholder":304},[273,1824,1825,1828,1830,1832,1834,1837],{"class":275,"line":308},[273,1826,1827],{"class":330},"headerStyle ",[273,1829,334],{"class":290},[273,1831,1144],{"class":330},[273,1833,340],{"class":290},[273,1835,1836],{"class":314},"NewTextStyle",[273,1838,1106],{"class":290},[273,1840,1841,1844,1846,1849,1851,1853,1856,1859,1861,1864,1866,1868,1871,1873],{"class":275,"line":324},[273,1842,1843],{"class":330},"headerStyle",[273,1845,340],{"class":290},[273,1847,1848],{"class":330},"Font",[273,1850,437],{"class":290},[273,1852,440],{"class":330},[273,1854,1855],{"class":290},"=",[273,1857,1858],{"class":330}," model",[273,1860,340],{"class":290},[273,1862,1863],{"class":314},"NewStandard14Font",[273,1865,346],{"class":290},[273,1867,359],{"class":290},[273,1869,1870],{"class":362},"Helvetica-Bold",[273,1872,359],{"class":290},[273,1874,397],{"class":290},[273,1876,1877,1879,1881,1884,1886],{"class":275,"line":381},[273,1878,1843],{"class":330},[273,1880,340],{"class":290},[273,1882,1883],{"class":330},"FontSize ",[273,1885,1855],{"class":290},[273,1887,1888],{"class":1176}," 11\n",[273,1890,1891,1893,1895,1898,1900,1902,1904],{"class":275,"line":400},[273,1892,1843],{"class":330},[273,1894,340],{"class":290},[273,1896,1897],{"class":330},"Color ",[273,1899,1855],{"class":290},[273,1901,1098],{"class":330},[273,1903,340],{"class":290},[273,1905,1906],{"class":330},"ColorWhite\n",[273,1908,1909],{"class":275,"line":406},[273,1910,305],{"emptyLinePlaceholder":304},[273,1912,1913,1916,1918,1920,1923,1926,1928],{"class":275,"line":986},[273,1914,1915],{"class":330},"drawHeaderCell ",[273,1917,334],{"class":290},[273,1919,1538],{"class":290},[273,1921,1922],{"class":1502},"text",[273,1924,1925],{"class":481}," string",[273,1927,585],{"class":290},[273,1929,321],{"class":290},[273,1931,1932,1935,1937,1940,1942,1944],{"class":275,"line":991},[273,1933,1934],{"class":330},"    cell ",[273,1936,334],{"class":290},[273,1938,1939],{"class":330}," table",[273,1941,340],{"class":290},[273,1943,1755],{"class":314},[273,1945,1106],{"class":290},[273,1947,1948,1951,1953,1956,1958,1960,1962,1965,1967,1969,1972,1974],{"class":275,"line":996},[273,1949,1950],{"class":330},"    cell",[273,1952,340],{"class":290},[273,1954,1955],{"class":314},"SetBackgroundColor",[273,1957,346],{"class":290},[273,1959,41],{"class":330},[273,1961,340],{"class":290},[273,1963,1964],{"class":314},"ColorRGBFromHex",[273,1966,346],{"class":290},[273,1968,359],{"class":290},[273,1970,1971],{"class":362},"#1A237E",[273,1973,359],{"class":290},[273,1975,1976],{"class":290},"))\n",[273,1978,1979,1981,1983,1986,1988,1990,1992,1995,1997,1999,2001,2004,2006,2009],{"class":275,"line":1007},[273,1980,1950],{"class":330},[273,1982,340],{"class":290},[273,1984,1985],{"class":314},"SetBorder",[273,1987,346],{"class":290},[273,1989,41],{"class":330},[273,1991,340],{"class":290},[273,1993,1994],{"class":330},"CellBorderSideAll",[273,1996,437],{"class":290},[273,1998,1098],{"class":330},[273,2000,340],{"class":290},[273,2002,2003],{"class":330},"CellBorderStyleSingle",[273,2005,437],{"class":290},[273,2007,2008],{"class":1176}," 0.5",[273,2010,397],{"class":290},[273,2012,2013],{"class":275,"line":1048},[273,2014,305],{"emptyLinePlaceholder":304},[273,2016,2017,2019,2021,2023,2025,2028],{"class":275,"line":1063},[273,2018,1139],{"class":330},[273,2020,334],{"class":290},[273,2022,1144],{"class":330},[273,2024,340],{"class":290},[273,2026,2027],{"class":314},"NewStyledParagraph",[273,2029,1106],{"class":290},[273,2031,2032,2035,2037,2040,2042,2045,2047,2049],{"class":275,"line":1068},[273,2033,2034],{"class":330},"    chunk ",[273,2036,334],{"class":290},[273,2038,2039],{"class":330}," p",[273,2041,340],{"class":290},[273,2043,2044],{"class":314},"Append",[273,2046,346],{"class":290},[273,2048,1922],{"class":330},[273,2050,397],{"class":290},[273,2052,2053,2056,2058,2061,2063],{"class":275,"line":1073},[273,2054,2055],{"class":330},"    chunk",[273,2057,340],{"class":290},[273,2059,2060],{"class":330},"Style ",[273,2062,1855],{"class":290},[273,2064,2065],{"class":330}," headerStyle\n",[273,2067,2068,2070,2072,2074,2076,2078],{"class":275,"line":1078},[273,2069,1950],{"class":330},[273,2071,340],{"class":290},[273,2073,1758],{"class":314},[273,2075,346],{"class":290},[273,2077,19],{"class":330},[273,2079,397],{"class":290},[273,2081,2082],{"class":275,"line":1090},[273,2083,409],{"class":290},[273,2085,2086],{"class":275,"line":1109},[273,2087,305],{"emptyLinePlaceholder":304},[273,2089,2090,2093,2096,2098,2101,2103,2106,2109,2111,2114,2116,2119,2121,2123,2125,2128,2130,2132,2134,2137,2139,2141,2143,2146,2148,2151],{"class":275,"line":1131},[273,2091,2092],{"class":286},"for",[273,2094,2095],{"class":330}," _",[273,2097,437],{"class":290},[273,2099,2100],{"class":330}," h ",[273,2102,334],{"class":290},[273,2104,2105],{"class":286}," range",[273,2107,2108],{"class":290}," []",[273,2110,482],{"class":481},[273,2112,2113],{"class":290},"{",[273,2115,359],{"class":290},[273,2117,2118],{"class":362},"Descrição",[273,2120,359],{"class":290},[273,2122,437],{"class":290},[273,2124,291],{"class":290},[273,2126,2127],{"class":362},"Qtd.",[273,2129,359],{"class":290},[273,2131,437],{"class":290},[273,2133,291],{"class":290},[273,2135,2136],{"class":362},"Unit.",[273,2138,359],{"class":290},[273,2140,437],{"class":290},[273,2142,291],{"class":290},[273,2144,2145],{"class":362},"Total",[273,2147,359],{"class":290},[273,2149,2150],{"class":290},"}",[273,2152,321],{"class":290},[273,2154,2155,2158,2160,2163],{"class":275,"line":1136},[273,2156,2157],{"class":314},"    drawHeaderCell",[273,2159,346],{"class":290},[273,2161,2162],{"class":330},"h",[273,2164,397],{"class":290},[273,2166,2167],{"class":275,"line":1163},[273,2168,409],{"class":290},[273,2170,2171],{"class":275,"line":1182},[273,2172,305],{"emptyLinePlaceholder":304},[273,2174,2175,2177,2179,2181,2184,2186,2188,2191],{"class":275,"line":1212},[273,2176,2092],{"class":286},[273,2178,2095],{"class":330},[273,2180,437],{"class":290},[273,2182,2183],{"class":330}," row ",[273,2185,334],{"class":290},[273,2187,2105],{"class":286},[273,2189,2190],{"class":330}," items ",[273,2192,2193],{"class":290},"{\n",[273,2195,2196,2199,2201,2203,2206,2208,2210,2212],{"class":275,"line":1227},[273,2197,2198],{"class":286},"    for",[273,2200,2095],{"class":330},[273,2202,437],{"class":290},[273,2204,2205],{"class":330}," cellText ",[273,2207,334],{"class":290},[273,2209,2105],{"class":286},[273,2211,2183],{"class":330},[273,2213,2193],{"class":290},[273,2215,2216,2219,2221,2223,2225,2227],{"class":275,"line":1232},[273,2217,2218],{"class":330},"        cell ",[273,2220,334],{"class":290},[273,2222,1939],{"class":330},[273,2224,340],{"class":290},[273,2226,1755],{"class":314},[273,2228,1106],{"class":290},[273,2230,2231,2234,2236,2238,2240,2242,2244,2246,2248,2250,2252,2254,2256,2259],{"class":275,"line":1237},[273,2232,2233],{"class":330},"        cell",[273,2235,340],{"class":290},[273,2237,1985],{"class":314},[273,2239,346],{"class":290},[273,2241,41],{"class":330},[273,2243,340],{"class":290},[273,2245,1994],{"class":330},[273,2247,437],{"class":290},[273,2249,1098],{"class":330},[273,2251,340],{"class":290},[273,2253,2003],{"class":330},[273,2255,437],{"class":290},[273,2257,2258],{"class":1176}," 0.3",[273,2260,397],{"class":290},[273,2262,2263],{"class":275,"line":1272},[273,2264,305],{"emptyLinePlaceholder":304},[273,2266,2267,2270,2272,2274,2276,2278,2280,2283],{"class":275,"line":1287},[273,2268,2269],{"class":330},"        p ",[273,2271,334],{"class":290},[273,2273,1144],{"class":330},[273,2275,340],{"class":290},[273,2277,1149],{"class":314},[273,2279,346],{"class":290},[273,2281,2282],{"class":330},"cellText",[273,2284,397],{"class":290},[273,2286,2287,2290,2292,2294,2296,2299],{"class":275,"line":1292},[273,2288,2289],{"class":330},"        p",[273,2291,340],{"class":290},[273,2293,1171],{"class":314},[273,2295,346],{"class":290},[273,2297,2298],{"class":1176},"11",[273,2300,397],{"class":290},[273,2302,2303,2305,2307,2309,2311,2313],{"class":275,"line":1722},[273,2304,2233],{"class":330},[273,2306,340],{"class":290},[273,2308,1758],{"class":314},[273,2310,346],{"class":290},[273,2312,19],{"class":330},[273,2314,397],{"class":290},[273,2316,2317],{"class":275,"line":1727},[273,2318,403],{"class":290},[273,2320,2322],{"class":275,"line":2321},33,[273,2323,409],{"class":290},[273,2325,2327],{"class":275,"line":2326},34,[273,2328,305],{"emptyLinePlaceholder":304},[273,2330,2332,2335,2337,2339,2341,2343,2345,2347,2349,2351,2353,2355,2357],{"class":275,"line":2331},35,[273,2333,2334],{"class":286},"if",[273,2336,331],{"class":330},[273,2338,334],{"class":290},[273,2340,1144],{"class":330},[273,2342,340],{"class":290},[273,2344,1195],{"class":314},[273,2346,346],{"class":290},[273,2348,120],{"class":330},[273,2350,500],{"class":290},[273,2352,331],{"class":330},[273,2354,373],{"class":290},[273,2356,376],{"class":290},[273,2358,321],{"class":290},[273,2360,2362,2365,2367,2369,2371,2373],{"class":275,"line":2361},36,[273,2363,2364],{"class":330},"    log",[273,2366,340],{"class":290},[273,2368,389],{"class":314},[273,2370,346],{"class":290},[273,2372,394],{"class":330},[273,2374,397],{"class":290},[273,2376,2378],{"class":275,"line":2377},37,[273,2379,409],{"class":290},[19,2381,2382],{},"Bordas, conteúdo por célula, loop que desenha o cabeçalho — tudo mecânico.",[19,2384,2385],{},[22,2386,1299],{},[264,2388,2390],{"className":266,"code":2389,"language":268,"meta":269,"style":269},"page.AutoRow(func(r *template.RowBuilder) {\n    r.Col(12, func(c *template.ColBuilder) {\n        c.Table(\n            []string{\"Descrição\", \"Qtd.\", \"Unit.\", \"Total\"},\n            [][]string{\n                {\"Desenvolvimento frontend\", \"40 h\", \"R$ 750,00\", \"R$ 30.000,00\"},\n                {\"Desenvolvimento backend\",  \"60 h\", \"R$ 750,00\", \"R$ 45.000,00\"},\n                {\"Design de UI\",             \"20 h\", \"R$ 600,00\", \"R$ 12.000,00\"},\n            },\n            template.ColumnWidths(50, 15, 15, 20),\n            template.TableHeaderStyle(\n                template.Bold(),\n                template.TextColor(pdf.White),\n                template.BgColor(pdf.RGBHex(0x1A237E)),\n            ),\n            template.TableStripe(pdf.RGBHex(0xF5F5F5)),\n        )\n    })\n})\n",[35,2391,2392,2417,2448,2459,2501,2510,2551,2591,2632,2637,2668,2679,2691,2712,2738,2743,2767,2772,2776],{"__ignoreMap":269},[273,2393,2394,2397,2399,2401,2403,2405,2407,2409,2411,2413,2415],{"class":275,"line":276},[273,2395,2396],{"class":330},"page",[273,2398,340],{"class":290},[273,2400,1496],{"class":314},[273,2402,1499],{"class":290},[273,2404,1503],{"class":1502},[273,2406,1506],{"class":290},[273,2408,1509],{"class":294},[273,2410,340],{"class":290},[273,2412,1514],{"class":294},[273,2414,585],{"class":290},[273,2416,321],{"class":290},[273,2418,2419,2422,2424,2426,2428,2430,2432,2434,2436,2438,2440,2442,2444,2446],{"class":275,"line":283},[273,2420,2421],{"class":330},"    r",[273,2423,340],{"class":290},[273,2425,1528],{"class":314},[273,2427,346],{"class":290},[273,2429,1533],{"class":1176},[273,2431,437],{"class":290},[273,2433,1538],{"class":290},[273,2435,1541],{"class":1502},[273,2437,1506],{"class":290},[273,2439,1509],{"class":294},[273,2441,340],{"class":290},[273,2443,1550],{"class":294},[273,2445,585],{"class":290},[273,2447,321],{"class":290},[273,2449,2450,2453,2455,2457],{"class":275,"line":301},[273,2451,2452],{"class":330},"        c",[273,2454,340],{"class":290},[273,2456,891],{"class":314},[273,2458,1402],{"class":290},[273,2460,2461,2464,2466,2468,2470,2472,2474,2476,2478,2480,2482,2484,2486,2488,2490,2492,2494,2496,2498],{"class":275,"line":308},[273,2462,2463],{"class":290},"            []",[273,2465,482],{"class":481},[273,2467,2113],{"class":290},[273,2469,359],{"class":290},[273,2471,2118],{"class":362},[273,2473,359],{"class":290},[273,2475,437],{"class":290},[273,2477,291],{"class":290},[273,2479,2127],{"class":362},[273,2481,359],{"class":290},[273,2483,437],{"class":290},[273,2485,291],{"class":290},[273,2487,2136],{"class":362},[273,2489,359],{"class":290},[273,2491,437],{"class":290},[273,2493,291],{"class":290},[273,2495,2145],{"class":362},[273,2497,359],{"class":290},[273,2499,2500],{"class":290},"},\n",[273,2502,2503,2506,2508],{"class":275,"line":324},[273,2504,2505],{"class":290},"            [][]",[273,2507,482],{"class":481},[273,2509,2193],{"class":290},[273,2511,2512,2515,2517,2520,2522,2524,2526,2529,2531,2533,2535,2538,2540,2542,2544,2547,2549],{"class":275,"line":381},[273,2513,2514],{"class":290},"                {",[273,2516,359],{"class":290},[273,2518,2519],{"class":362},"Desenvolvimento frontend",[273,2521,359],{"class":290},[273,2523,437],{"class":290},[273,2525,291],{"class":290},[273,2527,2528],{"class":362},"40 h",[273,2530,359],{"class":290},[273,2532,437],{"class":290},[273,2534,291],{"class":290},[273,2536,2537],{"class":362},"R$ 750,00",[273,2539,359],{"class":290},[273,2541,437],{"class":290},[273,2543,291],{"class":290},[273,2545,2546],{"class":362},"R$ 30.000,00",[273,2548,359],{"class":290},[273,2550,2500],{"class":290},[273,2552,2553,2555,2557,2560,2562,2564,2567,2570,2572,2574,2576,2578,2580,2582,2584,2587,2589],{"class":275,"line":400},[273,2554,2514],{"class":290},[273,2556,359],{"class":290},[273,2558,2559],{"class":362},"Desenvolvimento backend",[273,2561,359],{"class":290},[273,2563,437],{"class":290},[273,2565,2566],{"class":290},"  \"",[273,2568,2569],{"class":362},"60 h",[273,2571,359],{"class":290},[273,2573,437],{"class":290},[273,2575,291],{"class":290},[273,2577,2537],{"class":362},[273,2579,359],{"class":290},[273,2581,437],{"class":290},[273,2583,291],{"class":290},[273,2585,2586],{"class":362},"R$ 45.000,00",[273,2588,359],{"class":290},[273,2590,2500],{"class":290},[273,2592,2593,2595,2597,2600,2602,2604,2607,2610,2612,2614,2616,2619,2621,2623,2625,2628,2630],{"class":275,"line":406},[273,2594,2514],{"class":290},[273,2596,359],{"class":290},[273,2598,2599],{"class":362},"Design de UI",[273,2601,359],{"class":290},[273,2603,437],{"class":290},[273,2605,2606],{"class":290},"             \"",[273,2608,2609],{"class":362},"20 h",[273,2611,359],{"class":290},[273,2613,437],{"class":290},[273,2615,291],{"class":290},[273,2617,2618],{"class":362},"R$ 600,00",[273,2620,359],{"class":290},[273,2622,437],{"class":290},[273,2624,291],{"class":290},[273,2626,2627],{"class":362},"R$ 12.000,00",[273,2629,359],{"class":290},[273,2631,2500],{"class":290},[273,2633,2634],{"class":275,"line":986},[273,2635,2636],{"class":290},"            },\n",[273,2638,2639,2642,2644,2647,2649,2652,2654,2657,2659,2661,2663,2666],{"class":275,"line":991},[273,2640,2641],{"class":330},"            template",[273,2643,340],{"class":290},[273,2645,2646],{"class":314},"ColumnWidths",[273,2648,346],{"class":290},[273,2650,2651],{"class":1176},"50",[273,2653,437],{"class":290},[273,2655,2656],{"class":1176}," 15",[273,2658,437],{"class":290},[273,2660,2656],{"class":1176},[273,2662,437],{"class":290},[273,2664,2665],{"class":1176}," 20",[273,2667,1425],{"class":290},[273,2669,2670,2672,2674,2677],{"class":275,"line":996},[273,2671,2641],{"class":330},[273,2673,340],{"class":290},[273,2675,2676],{"class":314},"TableHeaderStyle",[273,2678,1402],{"class":290},[273,2680,2681,2684,2686,2688],{"class":275,"line":1007},[273,2682,2683],{"class":330},"                template",[273,2685,340],{"class":290},[273,2687,1595],{"class":314},[273,2689,2690],{"class":290},"(),\n",[273,2692,2693,2695,2697,2700,2702,2705,2707,2710],{"class":275,"line":1048},[273,2694,2683],{"class":330},[273,2696,340],{"class":290},[273,2698,2699],{"class":314},"TextColor",[273,2701,346],{"class":290},[273,2703,2704],{"class":330},"pdf",[273,2706,340],{"class":290},[273,2708,2709],{"class":330},"White",[273,2711,1425],{"class":290},[273,2713,2714,2716,2718,2721,2723,2725,2727,2730,2732,2735],{"class":275,"line":1063},[273,2715,2683],{"class":330},[273,2717,340],{"class":290},[273,2719,2720],{"class":314},"BgColor",[273,2722,346],{"class":290},[273,2724,2704],{"class":330},[273,2726,340],{"class":290},[273,2728,2729],{"class":314},"RGBHex",[273,2731,346],{"class":290},[273,2733,2734],{"class":1176},"0x1A237E",[273,2736,2737],{"class":290},")),\n",[273,2739,2740],{"class":275,"line":1068},[273,2741,2742],{"class":290},"            ),\n",[273,2744,2745,2747,2749,2752,2754,2756,2758,2760,2762,2765],{"class":275,"line":1073},[273,2746,2641],{"class":330},[273,2748,340],{"class":290},[273,2750,2751],{"class":314},"TableStripe",[273,2753,346],{"class":290},[273,2755,2704],{"class":330},[273,2757,340],{"class":290},[273,2759,2729],{"class":314},[273,2761,346],{"class":290},[273,2763,2764],{"class":1176},"0xF5F5F5",[273,2766,2737],{"class":290},[273,2768,2769],{"class":275,"line":1078},[273,2770,2771],{"class":290},"        )\n",[273,2773,2774],{"class":275,"line":1090},[273,2775,1608],{"class":290},[273,2777,2778],{"class":275,"line":1109},[273,2779,2780],{"class":290},"})\n",[19,2782,2783,2785,2786,2789,2790,2793],{},[35,2784,2646],{}," são ",[22,2787,2788],{},"porcentagens da coluna em que a tabela vive",", não frações absolutas da página. Coloque a mesma tabela dentro de ",[35,2791,2792],{},"r.Col(6, ...)"," e os percentuais continuam valendo: a tabela ocupa metade da linha e as colunas se redistribuem na proporção. A quebra de página é automática; se o corpo passar a margem inferior, o cabeçalho repete na próxima página sem você fiar nada.",[19,2795,2796,2797,2800,2801,2804],{},"Um detalhe específico. A Table do unipdf numa rodada de fatura de 100 linhas marca cerca de ",[22,2798,2799],{},"8,6 ms"," por render na nossa suite. A do gpdf faz o mesmo trabalho em ",[22,2802,2803],{},"108 µs"," — cerca de 80× mais rápido — porque o motor de layout mede cada linha uma vez e escreve páginas em uma única passada, em vez de materializar um DOM célula por célula. Numa fatura solta isso é invisível. Num batch em cron, muda se você precisa ou não de uma fila.",[19,2806,2807,2808,2811],{},"Para NF-e / DANFE / PDF/A-3 (Brasil), o lado de layout funciona com gpdf direto. Se precisar de timestamping para conformidade, vai pelo lado de ",[35,2809,2810],{},"gpdf.SignDocument"," com a opção RFC 3161 TSA.",[14,2813,2815],{"id":2814},"antes-depois-3-texto-com-acentos-sem-a-dança-da-composite-font","Antes / Depois 3: texto com acentos sem a dança da composite font",[19,2817,2818],{},"unipdf suporta texto estendido (incluindo CJK), mas o caminho é verboso. Você constrói uma composite font a partir de um TTF em disco, define como font do style e passa por cada paragraph. Se quiser fallbacks, fia você mesmo.",[19,2820,2821],{},[22,2822,920],{},[264,2824,2826],{"className":266,"code":2825,"language":268,"meta":269,"style":269},"font, err := model.NewCompositePdfFontFromTTFFile(\"NotoSans-Regular.ttf\")\nif err != nil {\n    log.Fatal(err)\n}\n\nc := creator.New()\nc.SetPageSize(creator.PageSizeA4)\n\nstyle := c.NewTextStyle()\nstyle.Font = font\nstyle.FontSize = 14\n\np := c.NewStyledParagraph()\np.Append(\"Olá, mundo. Atenção: ção, ã, é, ô.\").Style = style\nif err := c.Draw(p); err != nil {\n    log.Fatal(err)\n}\n\nc.WriteToFile(\"pt.pdf\")\n",[35,2827,2828,2857,2869,2883,2887,2891,2906,2924,2928,2943,2958,2971,2975,2990,3017,3045,3059,3063,3067],{"__ignoreMap":269},[273,2829,2830,2833,2835,2837,2839,2841,2843,2846,2848,2850,2853,2855],{"class":275,"line":276},[273,2831,2832],{"class":330},"font",[273,2834,437],{"class":290},[273,2836,331],{"class":330},[273,2838,334],{"class":290},[273,2840,1858],{"class":330},[273,2842,340],{"class":290},[273,2844,2845],{"class":314},"NewCompositePdfFontFromTTFFile",[273,2847,346],{"class":290},[273,2849,359],{"class":290},[273,2851,2852],{"class":362},"NotoSans-Regular.ttf",[273,2854,359],{"class":290},[273,2856,397],{"class":290},[273,2858,2859,2861,2863,2865,2867],{"class":275,"line":283},[273,2860,2334],{"class":286},[273,2862,331],{"class":330},[273,2864,373],{"class":290},[273,2866,376],{"class":290},[273,2868,321],{"class":290},[273,2870,2871,2873,2875,2877,2879,2881],{"class":275,"line":301},[273,2872,2364],{"class":330},[273,2874,340],{"class":290},[273,2876,389],{"class":314},[273,2878,346],{"class":290},[273,2880,394],{"class":330},[273,2882,397],{"class":290},[273,2884,2885],{"class":275,"line":308},[273,2886,409],{"class":290},[273,2888,2889],{"class":275,"line":324},[273,2890,305],{"emptyLinePlaceholder":304},[273,2892,2893,2896,2898,2900,2902,2904],{"class":275,"line":381},[273,2894,2895],{"class":330},"c ",[273,2897,334],{"class":290},[273,2899,1098],{"class":330},[273,2901,340],{"class":290},[273,2903,1103],{"class":314},[273,2905,1106],{"class":290},[273,2907,2908,2910,2912,2914,2916,2918,2920,2922],{"class":275,"line":400},[273,2909,1541],{"class":330},[273,2911,340],{"class":290},[273,2913,1117],{"class":314},[273,2915,346],{"class":290},[273,2917,41],{"class":330},[273,2919,340],{"class":290},[273,2921,1126],{"class":330},[273,2923,397],{"class":290},[273,2925,2926],{"class":275,"line":406},[273,2927,305],{"emptyLinePlaceholder":304},[273,2929,2930,2933,2935,2937,2939,2941],{"class":275,"line":986},[273,2931,2932],{"class":330},"style ",[273,2934,334],{"class":290},[273,2936,1144],{"class":330},[273,2938,340],{"class":290},[273,2940,1836],{"class":314},[273,2942,1106],{"class":290},[273,2944,2945,2948,2950,2953,2955],{"class":275,"line":991},[273,2946,2947],{"class":330},"style",[273,2949,340],{"class":290},[273,2951,2952],{"class":330},"Font ",[273,2954,1855],{"class":290},[273,2956,2957],{"class":330}," font\n",[273,2959,2960,2962,2964,2966,2968],{"class":275,"line":996},[273,2961,2947],{"class":330},[273,2963,340],{"class":290},[273,2965,1883],{"class":330},[273,2967,1855],{"class":290},[273,2969,2970],{"class":1176}," 14\n",[273,2972,2973],{"class":275,"line":1007},[273,2974,305],{"emptyLinePlaceholder":304},[273,2976,2977,2980,2982,2984,2986,2988],{"class":275,"line":1048},[273,2978,2979],{"class":330},"p ",[273,2981,334],{"class":290},[273,2983,1144],{"class":330},[273,2985,340],{"class":290},[273,2987,2027],{"class":314},[273,2989,1106],{"class":290},[273,2991,2992,2994,2996,2998,3000,3002,3005,3007,3010,3012,3014],{"class":275,"line":1063},[273,2993,19],{"class":330},[273,2995,340],{"class":290},[273,2997,2044],{"class":314},[273,2999,346],{"class":290},[273,3001,359],{"class":290},[273,3003,3004],{"class":362},"Olá, mundo. Atenção: ção, ã, é, ô.",[273,3006,359],{"class":290},[273,3008,3009],{"class":290},").",[273,3011,2060],{"class":330},[273,3013,1855],{"class":290},[273,3015,3016],{"class":330}," style\n",[273,3018,3019,3021,3023,3025,3027,3029,3031,3033,3035,3037,3039,3041,3043],{"class":275,"line":1068},[273,3020,2334],{"class":286},[273,3022,331],{"class":330},[273,3024,334],{"class":290},[273,3026,1144],{"class":330},[273,3028,340],{"class":290},[273,3030,1195],{"class":314},[273,3032,346],{"class":290},[273,3034,19],{"class":330},[273,3036,500],{"class":290},[273,3038,331],{"class":330},[273,3040,373],{"class":290},[273,3042,376],{"class":290},[273,3044,321],{"class":290},[273,3046,3047,3049,3051,3053,3055,3057],{"class":275,"line":1073},[273,3048,2364],{"class":330},[273,3050,340],{"class":290},[273,3052,389],{"class":314},[273,3054,346],{"class":290},[273,3056,394],{"class":330},[273,3058,397],{"class":290},[273,3060,3061],{"class":275,"line":1078},[273,3062,409],{"class":290},[273,3064,3065],{"class":275,"line":1090},[273,3066,305],{"emptyLinePlaceholder":304},[273,3068,3069,3071,3073,3075,3077,3079,3082,3084],{"class":275,"line":1109},[273,3070,1541],{"class":330},[273,3072,340],{"class":290},[273,3074,1250],{"class":314},[273,3076,346],{"class":290},[273,3078,359],{"class":290},[273,3080,3081],{"class":362},"pt.pdf",[273,3083,359],{"class":290},[273,3085,397],{"class":290},[19,3087,3088,3089,3091],{},"O TTF precisa existir no caminho indicado, em runtime, no host que roda o binário. As imagens de container têm que carregar a fonte. ",[35,3090,2845],{}," precisa acontecer antes de qualquer chamada de desenho que use a fonte, então mora em algum lugar global ou é passada como dependência.",[19,3093,3094],{},[22,3095,1299],{},[264,3097,3099],{"className":266,"code":3098,"language":268,"meta":269,"style":269},"package main\n\nimport (\n    _ \"embed\"\n    \"log\"\n    \"os\"\n\n    \"github.com/gpdf-dev/gpdf\"\n    \"github.com/gpdf-dev/gpdf/document\"\n    \"github.com/gpdf-dev/gpdf/template\"\n)\n\n//go:embed NotoSans-Regular.ttf\nvar noto []byte\n\nfunc main() {\n    doc := gpdf.NewDocument(\n        gpdf.WithPageSize(document.A4),\n        gpdf.WithMargins(document.UniformEdges(document.Mm(20))),\n        gpdf.WithFont(\"Noto\", noto),\n        gpdf.WithDefaultFont(\"Noto\", 14),\n    )\n\n    page := doc.AddPage()\n    page.AutoRow(func(r *template.RowBuilder) {\n        r.Col(12, func(c *template.ColBuilder) {\n            c.Text(\"Olá, mundo.\")\n            c.Text(\"Atenção: ção, ã, é, ô — sem escapes.\")\n            c.Text(\"Av. Paulista, 1578, São Paulo\")\n        })\n    })\n\n    data, _ := doc.Generate()\n    if err := os.WriteFile(\"pt.pdf\", data, 0o644); err != nil {\n        log.Fatal(err)\n    }\n}\n",[35,3100,3101,3107,3111,3117,3129,3137,3145,3149,3157,3165,3173,3177,3181,3186,3200,3204,3214,3228,3246,3276,3301,3325,3329,3333,3347,3371,3401,3420,3439,3458,3462,3466,3470,3488,3528,3542,3546],{"__ignoreMap":269},[273,3102,3103,3105],{"class":275,"line":276},[273,3104,930],{"class":290},[273,3106,933],{"class":294},[273,3108,3109],{"class":275,"line":283},[273,3110,305],{"emptyLinePlaceholder":304},[273,3112,3113,3115],{"class":275,"line":301},[273,3114,287],{"class":286},[273,3116,944],{"class":290},[273,3118,3119,3122,3124,3127],{"class":275,"line":308},[273,3120,3121],{"class":330},"    _ ",[273,3123,359],{"class":290},[273,3125,3126],{"class":294},"embed",[273,3128,298],{"class":290},[273,3130,3131,3133,3135],{"class":275,"line":324},[273,3132,949],{"class":290},[273,3134,952],{"class":294},[273,3136,298],{"class":290},[273,3138,3139,3141,3143],{"class":275,"line":381},[273,3140,949],{"class":290},[273,3142,349],{"class":294},[273,3144,298],{"class":290},[273,3146,3147],{"class":275,"line":400},[273,3148,305],{"emptyLinePlaceholder":304},[273,3150,3151,3153,3155],{"class":275,"line":406},[273,3152,949],{"class":290},[273,3154,543],{"class":294},[273,3156,298],{"class":290},[273,3158,3159,3161,3163],{"class":275,"line":986},[273,3160,949],{"class":290},[273,3162,1355],{"class":294},[273,3164,298],{"class":290},[273,3166,3167,3169,3171],{"class":275,"line":991},[273,3168,949],{"class":290},[273,3170,1364],{"class":294},[273,3172,298],{"class":290},[273,3174,3175],{"class":275,"line":996},[273,3176,397],{"class":290},[273,3178,3179],{"class":275,"line":1007},[273,3180,305],{"emptyLinePlaceholder":304},[273,3182,3183],{"class":275,"line":1048},[273,3184,3185],{"class":279},"//go:embed NotoSans-Regular.ttf\n",[273,3187,3188,3191,3194,3197],{"class":275,"line":1063},[273,3189,3190],{"class":290},"var",[273,3192,3193],{"class":330}," noto ",[273,3195,3196],{"class":290},"[]",[273,3198,3199],{"class":481},"byte\n",[273,3201,3202],{"class":275,"line":1068},[273,3203,305],{"emptyLinePlaceholder":304},[273,3205,3206,3208,3210,3212],{"class":275,"line":1073},[273,3207,311],{"class":290},[273,3209,1083],{"class":314},[273,3211,318],{"class":290},[273,3213,321],{"class":290},[273,3215,3216,3218,3220,3222,3224,3226],{"class":275,"line":1078},[273,3217,1389],{"class":330},[273,3219,334],{"class":290},[273,3221,1394],{"class":330},[273,3223,340],{"class":290},[273,3225,1399],{"class":314},[273,3227,1402],{"class":290},[273,3229,3230,3232,3234,3236,3238,3240,3242,3244],{"class":275,"line":1090},[273,3231,1407],{"class":330},[273,3233,340],{"class":290},[273,3235,1412],{"class":314},[273,3237,346],{"class":290},[273,3239,1417],{"class":330},[273,3241,340],{"class":290},[273,3243,1422],{"class":330},[273,3245,1425],{"class":290},[273,3247,3248,3250,3252,3254,3256,3258,3260,3262,3264,3266,3268,3270,3272,3274],{"class":275,"line":1109},[273,3249,1407],{"class":330},[273,3251,340],{"class":290},[273,3253,1434],{"class":314},[273,3255,346],{"class":290},[273,3257,1417],{"class":330},[273,3259,340],{"class":290},[273,3261,1443],{"class":314},[273,3263,346],{"class":290},[273,3265,1417],{"class":330},[273,3267,340],{"class":290},[273,3269,1452],{"class":314},[273,3271,346],{"class":290},[273,3273,1457],{"class":1176},[273,3275,1460],{"class":290},[273,3277,3278,3280,3282,3285,3287,3289,3292,3294,3296,3299],{"class":275,"line":1131},[273,3279,1407],{"class":330},[273,3281,340],{"class":290},[273,3283,3284],{"class":314},"WithFont",[273,3286,346],{"class":290},[273,3288,359],{"class":290},[273,3290,3291],{"class":362},"Noto",[273,3293,359],{"class":290},[273,3295,437],{"class":290},[273,3297,3298],{"class":330}," noto",[273,3300,1425],{"class":290},[273,3302,3303,3305,3307,3310,3312,3314,3316,3318,3320,3323],{"class":275,"line":1136},[273,3304,1407],{"class":330},[273,3306,340],{"class":290},[273,3308,3309],{"class":314},"WithDefaultFont",[273,3311,346],{"class":290},[273,3313,359],{"class":290},[273,3315,3291],{"class":362},[273,3317,359],{"class":290},[273,3319,437],{"class":290},[273,3321,3322],{"class":1176}," 14",[273,3324,1425],{"class":290},[273,3326,3327],{"class":275,"line":1163},[273,3328,1465],{"class":290},[273,3330,3331],{"class":275,"line":1182},[273,3332,305],{"emptyLinePlaceholder":304},[273,3334,3335,3337,3339,3341,3343,3345],{"class":275,"line":1212},[273,3336,1474],{"class":330},[273,3338,334],{"class":290},[273,3340,1479],{"class":330},[273,3342,340],{"class":290},[273,3344,1484],{"class":314},[273,3346,1106],{"class":290},[273,3348,3349,3351,3353,3355,3357,3359,3361,3363,3365,3367,3369],{"class":275,"line":1227},[273,3350,1491],{"class":330},[273,3352,340],{"class":290},[273,3354,1496],{"class":314},[273,3356,1499],{"class":290},[273,3358,1503],{"class":1502},[273,3360,1506],{"class":290},[273,3362,1509],{"class":294},[273,3364,340],{"class":290},[273,3366,1514],{"class":294},[273,3368,585],{"class":290},[273,3370,321],{"class":290},[273,3372,3373,3375,3377,3379,3381,3383,3385,3387,3389,3391,3393,3395,3397,3399],{"class":275,"line":1232},[273,3374,1523],{"class":330},[273,3376,340],{"class":290},[273,3378,1528],{"class":314},[273,3380,346],{"class":290},[273,3382,1533],{"class":1176},[273,3384,437],{"class":290},[273,3386,1538],{"class":290},[273,3388,1541],{"class":1502},[273,3390,1506],{"class":290},[273,3392,1509],{"class":294},[273,3394,340],{"class":290},[273,3396,1550],{"class":294},[273,3398,585],{"class":290},[273,3400,321],{"class":290},[273,3402,3403,3405,3407,3409,3411,3413,3416,3418],{"class":275,"line":1237},[273,3404,1559],{"class":330},[273,3406,340],{"class":290},[273,3408,1564],{"class":314},[273,3410,346],{"class":290},[273,3412,359],{"class":290},[273,3414,3415],{"class":362},"Olá, mundo.",[273,3417,359],{"class":290},[273,3419,397],{"class":290},[273,3421,3422,3424,3426,3428,3430,3432,3435,3437],{"class":275,"line":1272},[273,3423,1559],{"class":330},[273,3425,340],{"class":290},[273,3427,1564],{"class":314},[273,3429,346],{"class":290},[273,3431,359],{"class":290},[273,3433,3434],{"class":362},"Atenção: ção, ã, é, ô — sem escapes.",[273,3436,359],{"class":290},[273,3438,397],{"class":290},[273,3440,3441,3443,3445,3447,3449,3451,3454,3456],{"class":275,"line":1287},[273,3442,1559],{"class":330},[273,3444,340],{"class":290},[273,3446,1564],{"class":314},[273,3448,346],{"class":290},[273,3450,359],{"class":290},[273,3452,3453],{"class":362},"Av. Paulista, 1578, São Paulo",[273,3455,359],{"class":290},[273,3457,397],{"class":290},[273,3459,3460],{"class":275,"line":1292},[273,3461,1603],{"class":290},[273,3463,3464],{"class":275,"line":1722},[273,3465,1608],{"class":290},[273,3467,3468],{"class":275,"line":1727},[273,3469,305],{"emptyLinePlaceholder":304},[273,3471,3472,3474,3476,3478,3480,3482,3484,3486],{"class":275,"line":2321},[273,3473,1617],{"class":330},[273,3475,437],{"class":290},[273,3477,440],{"class":330},[273,3479,334],{"class":290},[273,3481,1479],{"class":330},[273,3483,340],{"class":290},[273,3485,1630],{"class":314},[273,3487,1106],{"class":290},[273,3489,3490,3492,3494,3496,3498,3500,3502,3504,3506,3508,3510,3512,3514,3516,3518,3520,3522,3524,3526],{"class":275,"line":2326},[273,3491,327],{"class":286},[273,3493,331],{"class":330},[273,3495,334],{"class":290},[273,3497,445],{"class":330},[273,3499,340],{"class":290},[273,3501,1677],{"class":314},[273,3503,346],{"class":290},[273,3505,359],{"class":290},[273,3507,3081],{"class":362},[273,3509,359],{"class":290},[273,3511,437],{"class":290},[273,3513,1690],{"class":330},[273,3515,437],{"class":290},[273,3517,1695],{"class":1176},[273,3519,500],{"class":290},[273,3521,331],{"class":330},[273,3523,373],{"class":290},[273,3525,376],{"class":290},[273,3527,321],{"class":290},[273,3529,3530,3532,3534,3536,3538,3540],{"class":275,"line":2331},[273,3531,384],{"class":330},[273,3533,340],{"class":290},[273,3535,389],{"class":314},[273,3537,346],{"class":290},[273,3539,394],{"class":330},[273,3541,397],{"class":290},[273,3543,3544],{"class":275,"line":2361},[273,3545,403],{"class":290},[273,3547,3548],{"class":275,"line":2377},[273,3549,409],{"class":290},[19,3551,3552,3553,3556,3557,3560,3561,3564],{},"Três diferenças a observar. A fonte é ",[22,3554,3555],{},"bytes",", não caminho — ",[35,3558,3559],{},"//go:embed"," compila ela no binário, então a imagem de runtime deixa de precisar de um diretório de fontes. A fonte é registrada ",[22,3562,3563],{},"uma vez no construtor","; sem encadeamento de style por paragraph. E o subseteador TrueType do gpdf entende formatos cmap CJK (4, 6, 12) e codificação Identity-H, então o PDF de saída só carrega os glifos que você de fato usou. Uma fatura de 200 caracteres produz um subset de fonte de ~30 KB em vez de um embed completo de 4 MB.",[19,3566,3567],{},"Para CJK específico (Source Han Sans, IPAex Gothic, cadeias de fallback), há um post complementar sobre fontes japonesas.",[14,3569,3571],{"id":3570},"antes-depois-4-cabeçalho-em-todas-as-páginas-número-de-página-no-rodapé","Antes / Depois 4: cabeçalho em todas as páginas, número de página no rodapé",[19,3573,3574,3575,761,3577,3579,3580,761,3583,3586],{},"O padrão do unipdf é ",[35,3576,760],{},[35,3578,764],{},", ambos recebem um contexto com o block atual e o número da página. Os números vêm dos campos ",[35,3581,3582],{},"PageNum",[35,3584,3585],{},"TotalPages"," do contexto.",[19,3588,3589],{},[22,3590,920],{},[264,3592,3594],{"className":266,"code":3593,"language":268,"meta":269,"style":269},"c.DrawHeader(func(block *creator.Block, args creator.HeaderFunctionArgs) {\n    p := c.NewParagraph(\"ACME Ltda.\")\n    p.SetFontSize(12)\n    p.SetPos(40, 30)\n    block.Draw(p)\n})\n\nc.DrawFooter(func(block *creator.Block, args creator.FooterFunctionArgs) {\n    p := c.NewParagraph(fmt.Sprintf(\"Página %d de %d\", args.PageNum, args.TotalPages))\n    p.SetFontSize(8)\n    p.SetPos(0, 20)\n    p.SetTextAlignment(creator.TextAlignmentCenter)\n    block.Draw(p)\n})\n",[35,3595,3596,3635,3658,3672,3693,3708,3712,3716,3751,3809,3824,3843,3863,3877],{"__ignoreMap":269},[273,3597,3598,3600,3602,3605,3607,3610,3612,3614,3616,3619,3621,3624,3626,3628,3631,3633],{"class":275,"line":276},[273,3599,1541],{"class":330},[273,3601,340],{"class":290},[273,3603,3604],{"class":314},"DrawHeader",[273,3606,1499],{"class":290},[273,3608,3609],{"class":1502},"block",[273,3611,1506],{"class":290},[273,3613,41],{"class":294},[273,3615,340],{"class":290},[273,3617,3618],{"class":294},"Block",[273,3620,437],{"class":290},[273,3622,3623],{"class":1502}," args",[273,3625,1098],{"class":294},[273,3627,340],{"class":290},[273,3629,3630],{"class":294},"HeaderFunctionArgs",[273,3632,585],{"class":290},[273,3634,321],{"class":290},[273,3636,3637,3639,3641,3643,3645,3647,3649,3651,3654,3656],{"class":275,"line":283},[273,3638,1139],{"class":330},[273,3640,334],{"class":290},[273,3642,1144],{"class":330},[273,3644,340],{"class":290},[273,3646,1149],{"class":314},[273,3648,346],{"class":290},[273,3650,359],{"class":290},[273,3652,3653],{"class":362},"ACME Ltda.",[273,3655,359],{"class":290},[273,3657,397],{"class":290},[273,3659,3660,3662,3664,3666,3668,3670],{"class":275,"line":301},[273,3661,1166],{"class":330},[273,3663,340],{"class":290},[273,3665,1171],{"class":314},[273,3667,346],{"class":290},[273,3669,1533],{"class":1176},[273,3671,397],{"class":290},[273,3673,3674,3676,3678,3681,3683,3686,3688,3691],{"class":275,"line":308},[273,3675,1166],{"class":330},[273,3677,340],{"class":290},[273,3679,3680],{"class":314},"SetPos",[273,3682,346],{"class":290},[273,3684,3685],{"class":1176},"40",[273,3687,437],{"class":290},[273,3689,3690],{"class":1176}," 30",[273,3692,397],{"class":290},[273,3694,3695,3698,3700,3702,3704,3706],{"class":275,"line":324},[273,3696,3697],{"class":330},"    block",[273,3699,340],{"class":290},[273,3701,1195],{"class":314},[273,3703,346],{"class":290},[273,3705,19],{"class":330},[273,3707,397],{"class":290},[273,3709,3710],{"class":275,"line":381},[273,3711,2780],{"class":290},[273,3713,3714],{"class":275,"line":400},[273,3715,305],{"emptyLinePlaceholder":304},[273,3717,3718,3720,3722,3724,3726,3728,3730,3732,3734,3736,3738,3740,3742,3744,3747,3749],{"class":275,"line":406},[273,3719,1541],{"class":330},[273,3721,340],{"class":290},[273,3723,783],{"class":314},[273,3725,1499],{"class":290},[273,3727,3609],{"class":1502},[273,3729,1506],{"class":290},[273,3731,41],{"class":294},[273,3733,340],{"class":290},[273,3735,3618],{"class":294},[273,3737,437],{"class":290},[273,3739,3623],{"class":1502},[273,3741,1098],{"class":294},[273,3743,340],{"class":290},[273,3745,3746],{"class":294},"FooterFunctionArgs",[273,3748,585],{"class":290},[273,3750,321],{"class":290},[273,3752,3753,3755,3757,3759,3761,3763,3765,3768,3770,3773,3775,3777,3780,3784,3787,3789,3791,3793,3795,3797,3799,3801,3803,3805,3807],{"class":275,"line":986},[273,3754,1139],{"class":330},[273,3756,334],{"class":290},[273,3758,1144],{"class":330},[273,3760,340],{"class":290},[273,3762,1149],{"class":314},[273,3764,346],{"class":290},[273,3766,3767],{"class":330},"fmt",[273,3769,340],{"class":290},[273,3771,3772],{"class":314},"Sprintf",[273,3774,346],{"class":290},[273,3776,359],{"class":290},[273,3778,3779],{"class":362},"Página ",[273,3781,3783],{"class":3782},"swJcz","%d",[273,3785,3786],{"class":362}," de ",[273,3788,3783],{"class":3782},[273,3790,359],{"class":290},[273,3792,437],{"class":290},[273,3794,3623],{"class":330},[273,3796,340],{"class":290},[273,3798,3582],{"class":330},[273,3800,437],{"class":290},[273,3802,3623],{"class":330},[273,3804,340],{"class":290},[273,3806,3585],{"class":330},[273,3808,1976],{"class":290},[273,3810,3811,3813,3815,3817,3819,3822],{"class":275,"line":991},[273,3812,1166],{"class":330},[273,3814,340],{"class":290},[273,3816,1171],{"class":314},[273,3818,346],{"class":290},[273,3820,3821],{"class":1176},"8",[273,3823,397],{"class":290},[273,3825,3826,3828,3830,3832,3834,3837,3839,3841],{"class":275,"line":996},[273,3827,1166],{"class":330},[273,3829,340],{"class":290},[273,3831,3680],{"class":314},[273,3833,346],{"class":290},[273,3835,3836],{"class":1176},"0",[273,3838,437],{"class":290},[273,3840,2665],{"class":1176},[273,3842,397],{"class":290},[273,3844,3845,3847,3849,3852,3854,3856,3858,3861],{"class":275,"line":1007},[273,3846,1166],{"class":330},[273,3848,340],{"class":290},[273,3850,3851],{"class":314},"SetTextAlignment",[273,3853,346],{"class":290},[273,3855,41],{"class":330},[273,3857,340],{"class":290},[273,3859,3860],{"class":330},"TextAlignmentCenter",[273,3862,397],{"class":290},[273,3864,3865,3867,3869,3871,3873,3875],{"class":275,"line":1048},[273,3866,3697],{"class":330},[273,3868,340],{"class":290},[273,3870,1195],{"class":314},[273,3872,346],{"class":290},[273,3874,19],{"class":330},[273,3876,397],{"class":290},[273,3878,3879],{"class":275,"line":1063},[273,3880,2780],{"class":290},[19,3882,3883],{},"Cabeçalho / rodapé são blocks que você desenha em posições absolutas. Coordenada Y errada, margem errada — trabalho de pixel toda vez que muda o tamanho da página.",[19,3885,3886],{},[22,3887,1299],{},[264,3889,3891],{"className":266,"code":3890,"language":268,"meta":269,"style":269},"doc := gpdf.NewDocument(\n    gpdf.WithPageSize(document.A4),\n    gpdf.WithMargins(document.UniformEdges(document.Mm(20))),\n)\n\ndoc.Header(func(p *template.PageBuilder) {\n    p.AutoRow(func(r *template.RowBuilder) {\n        r.Col(12, func(c *template.ColBuilder) {\n            c.Text(\"ACME Ltda.\", template.Bold(), template.FontSize(12))\n            c.Line(template.LineColor(pdf.Gray(0.7)))\n            c.Spacer(document.Mm(4))\n        })\n    })\n})\n\ndoc.Footer(func(p *template.PageBuilder) {\n    p.AutoRow(func(r *template.RowBuilder) {\n        r.Col(6, func(c *template.ColBuilder) {\n            c.Text(\"ACME Ltda.\",\n                template.FontSize(8), template.TextColor(pdf.Gray(0.5)))\n        })\n        r.Col(6, func(c *template.ColBuilder) {\n            c.PageNumber(template.AlignRight(),\n                template.FontSize(8), template.TextColor(pdf.Gray(0.5)))\n        })\n    })\n})\n\nfor i := 0; i \u003C 10; i++ {\n    page := doc.AddPage()\n    page.AutoRow(func(r *template.RowBuilder) {\n        r.Col(12, func(c *template.ColBuilder) {\n            c.Text(fmt.Sprintf(\"Conteúdo da página %d.\", i+1))\n        })\n    })\n}\n",[35,3892,3893,3908,3927,3957,3961,3965,3992,4016,4046,4085,4120,4143,4147,4151,4155,4159,4184,4208,4239,4258,4292,4296,4326,4346,4380,4384,4388,4392,4396,4429,4443,4467,4497,4538,4542,4546],{"__ignoreMap":269},[273,3894,3895,3898,3900,3902,3904,3906],{"class":275,"line":276},[273,3896,3897],{"class":330},"doc ",[273,3899,334],{"class":290},[273,3901,1394],{"class":330},[273,3903,340],{"class":290},[273,3905,1399],{"class":314},[273,3907,1402],{"class":290},[273,3909,3910,3913,3915,3917,3919,3921,3923,3925],{"class":275,"line":283},[273,3911,3912],{"class":330},"    gpdf",[273,3914,340],{"class":290},[273,3916,1412],{"class":314},[273,3918,346],{"class":290},[273,3920,1417],{"class":330},[273,3922,340],{"class":290},[273,3924,1422],{"class":330},[273,3926,1425],{"class":290},[273,3928,3929,3931,3933,3935,3937,3939,3941,3943,3945,3947,3949,3951,3953,3955],{"class":275,"line":301},[273,3930,3912],{"class":330},[273,3932,340],{"class":290},[273,3934,1434],{"class":314},[273,3936,346],{"class":290},[273,3938,1417],{"class":330},[273,3940,340],{"class":290},[273,3942,1443],{"class":314},[273,3944,346],{"class":290},[273,3946,1417],{"class":330},[273,3948,340],{"class":290},[273,3950,1452],{"class":314},[273,3952,346],{"class":290},[273,3954,1457],{"class":1176},[273,3956,1460],{"class":290},[273,3958,3959],{"class":275,"line":308},[273,3960,397],{"class":290},[273,3962,3963],{"class":275,"line":324},[273,3964,305],{"emptyLinePlaceholder":304},[273,3966,3967,3970,3972,3975,3977,3979,3981,3983,3985,3988,3990],{"class":275,"line":381},[273,3968,3969],{"class":330},"doc",[273,3971,340],{"class":290},[273,3973,3974],{"class":314},"Header",[273,3976,1499],{"class":290},[273,3978,19],{"class":1502},[273,3980,1506],{"class":290},[273,3982,1509],{"class":294},[273,3984,340],{"class":290},[273,3986,3987],{"class":294},"PageBuilder",[273,3989,585],{"class":290},[273,3991,321],{"class":290},[273,3993,3994,3996,3998,4000,4002,4004,4006,4008,4010,4012,4014],{"class":275,"line":400},[273,3995,1166],{"class":330},[273,3997,340],{"class":290},[273,3999,1496],{"class":314},[273,4001,1499],{"class":290},[273,4003,1503],{"class":1502},[273,4005,1506],{"class":290},[273,4007,1509],{"class":294},[273,4009,340],{"class":290},[273,4011,1514],{"class":294},[273,4013,585],{"class":290},[273,4015,321],{"class":290},[273,4017,4018,4020,4022,4024,4026,4028,4030,4032,4034,4036,4038,4040,4042,4044],{"class":275,"line":406},[273,4019,1523],{"class":330},[273,4021,340],{"class":290},[273,4023,1528],{"class":314},[273,4025,346],{"class":290},[273,4027,1533],{"class":1176},[273,4029,437],{"class":290},[273,4031,1538],{"class":290},[273,4033,1541],{"class":1502},[273,4035,1506],{"class":290},[273,4037,1509],{"class":294},[273,4039,340],{"class":290},[273,4041,1550],{"class":294},[273,4043,585],{"class":290},[273,4045,321],{"class":290},[273,4047,4048,4050,4052,4054,4056,4058,4060,4062,4064,4066,4068,4070,4073,4075,4077,4079,4081,4083],{"class":275,"line":986},[273,4049,1559],{"class":330},[273,4051,340],{"class":290},[273,4053,1564],{"class":314},[273,4055,346],{"class":290},[273,4057,359],{"class":290},[273,4059,3653],{"class":362},[273,4061,359],{"class":290},[273,4063,437],{"class":290},[273,4065,1577],{"class":330},[273,4067,340],{"class":290},[273,4069,1595],{"class":314},[273,4071,4072],{"class":290},"(),",[273,4074,1577],{"class":330},[273,4076,340],{"class":290},[273,4078,1582],{"class":314},[273,4080,346],{"class":290},[273,4082,1533],{"class":1176},[273,4084,1976],{"class":290},[273,4086,4087,4089,4091,4094,4096,4098,4100,4103,4105,4107,4109,4112,4114,4117],{"class":275,"line":991},[273,4088,1559],{"class":330},[273,4090,340],{"class":290},[273,4092,4093],{"class":314},"Line",[273,4095,346],{"class":290},[273,4097,1509],{"class":330},[273,4099,340],{"class":290},[273,4101,4102],{"class":314},"LineColor",[273,4104,346],{"class":290},[273,4106,2704],{"class":330},[273,4108,340],{"class":290},[273,4110,4111],{"class":314},"Gray",[273,4113,346],{"class":290},[273,4115,4116],{"class":1176},"0.7",[273,4118,4119],{"class":290},")))\n",[273,4121,4122,4124,4126,4129,4131,4133,4135,4137,4139,4141],{"class":275,"line":996},[273,4123,1559],{"class":330},[273,4125,340],{"class":290},[273,4127,4128],{"class":314},"Spacer",[273,4130,346],{"class":290},[273,4132,1417],{"class":330},[273,4134,340],{"class":290},[273,4136,1452],{"class":314},[273,4138,346],{"class":290},[273,4140,1787],{"class":1176},[273,4142,1976],{"class":290},[273,4144,4145],{"class":275,"line":1007},[273,4146,1603],{"class":290},[273,4148,4149],{"class":275,"line":1048},[273,4150,1608],{"class":290},[273,4152,4153],{"class":275,"line":1063},[273,4154,2780],{"class":290},[273,4156,4157],{"class":275,"line":1068},[273,4158,305],{"emptyLinePlaceholder":304},[273,4160,4161,4163,4165,4168,4170,4172,4174,4176,4178,4180,4182],{"class":275,"line":1073},[273,4162,3969],{"class":330},[273,4164,340],{"class":290},[273,4166,4167],{"class":314},"Footer",[273,4169,1499],{"class":290},[273,4171,19],{"class":1502},[273,4173,1506],{"class":290},[273,4175,1509],{"class":294},[273,4177,340],{"class":290},[273,4179,3987],{"class":294},[273,4181,585],{"class":290},[273,4183,321],{"class":290},[273,4185,4186,4188,4190,4192,4194,4196,4198,4200,4202,4204,4206],{"class":275,"line":1078},[273,4187,1166],{"class":330},[273,4189,340],{"class":290},[273,4191,1496],{"class":314},[273,4193,1499],{"class":290},[273,4195,1503],{"class":1502},[273,4197,1506],{"class":290},[273,4199,1509],{"class":294},[273,4201,340],{"class":290},[273,4203,1514],{"class":294},[273,4205,585],{"class":290},[273,4207,321],{"class":290},[273,4209,4210,4212,4214,4216,4218,4221,4223,4225,4227,4229,4231,4233,4235,4237],{"class":275,"line":1090},[273,4211,1523],{"class":330},[273,4213,340],{"class":290},[273,4215,1528],{"class":314},[273,4217,346],{"class":290},[273,4219,4220],{"class":1176},"6",[273,4222,437],{"class":290},[273,4224,1538],{"class":290},[273,4226,1541],{"class":1502},[273,4228,1506],{"class":290},[273,4230,1509],{"class":294},[273,4232,340],{"class":290},[273,4234,1550],{"class":294},[273,4236,585],{"class":290},[273,4238,321],{"class":290},[273,4240,4241,4243,4245,4247,4249,4251,4253,4255],{"class":275,"line":1109},[273,4242,1559],{"class":330},[273,4244,340],{"class":290},[273,4246,1564],{"class":314},[273,4248,346],{"class":290},[273,4250,359],{"class":290},[273,4252,3653],{"class":362},[273,4254,359],{"class":290},[273,4256,4257],{"class":290},",\n",[273,4259,4260,4262,4264,4266,4268,4270,4272,4274,4276,4278,4280,4282,4284,4286,4288,4290],{"class":275,"line":1131},[273,4261,2683],{"class":330},[273,4263,340],{"class":290},[273,4265,1582],{"class":314},[273,4267,346],{"class":290},[273,4269,3821],{"class":1176},[273,4271,490],{"class":290},[273,4273,1577],{"class":330},[273,4275,340],{"class":290},[273,4277,2699],{"class":314},[273,4279,346],{"class":290},[273,4281,2704],{"class":330},[273,4283,340],{"class":290},[273,4285,4111],{"class":314},[273,4287,346],{"class":290},[273,4289,1802],{"class":1176},[273,4291,4119],{"class":290},[273,4293,4294],{"class":275,"line":1136},[273,4295,1603],{"class":290},[273,4297,4298,4300,4302,4304,4306,4308,4310,4312,4314,4316,4318,4320,4322,4324],{"class":275,"line":1163},[273,4299,1523],{"class":330},[273,4301,340],{"class":290},[273,4303,1528],{"class":314},[273,4305,346],{"class":290},[273,4307,4220],{"class":1176},[273,4309,437],{"class":290},[273,4311,1538],{"class":290},[273,4313,1541],{"class":1502},[273,4315,1506],{"class":290},[273,4317,1509],{"class":294},[273,4319,340],{"class":290},[273,4321,1550],{"class":294},[273,4323,585],{"class":290},[273,4325,321],{"class":290},[273,4327,4328,4330,4332,4335,4337,4339,4341,4344],{"class":275,"line":1182},[273,4329,1559],{"class":330},[273,4331,340],{"class":290},[273,4333,4334],{"class":314},"PageNumber",[273,4336,346],{"class":290},[273,4338,1509],{"class":330},[273,4340,340],{"class":290},[273,4342,4343],{"class":314},"AlignRight",[273,4345,2690],{"class":290},[273,4347,4348,4350,4352,4354,4356,4358,4360,4362,4364,4366,4368,4370,4372,4374,4376,4378],{"class":275,"line":1212},[273,4349,2683],{"class":330},[273,4351,340],{"class":290},[273,4353,1582],{"class":314},[273,4355,346],{"class":290},[273,4357,3821],{"class":1176},[273,4359,490],{"class":290},[273,4361,1577],{"class":330},[273,4363,340],{"class":290},[273,4365,2699],{"class":314},[273,4367,346],{"class":290},[273,4369,2704],{"class":330},[273,4371,340],{"class":290},[273,4373,4111],{"class":314},[273,4375,346],{"class":290},[273,4377,1802],{"class":1176},[273,4379,4119],{"class":290},[273,4381,4382],{"class":275,"line":1227},[273,4383,1603],{"class":290},[273,4385,4386],{"class":275,"line":1232},[273,4387,1608],{"class":290},[273,4389,4390],{"class":275,"line":1237},[273,4391,2780],{"class":290},[273,4393,4394],{"class":275,"line":1272},[273,4395,305],{"emptyLinePlaceholder":304},[273,4397,4398,4400,4403,4405,4408,4411,4413,4416,4419,4421,4424,4427],{"class":275,"line":1287},[273,4399,2092],{"class":286},[273,4401,4402],{"class":330}," i ",[273,4404,334],{"class":290},[273,4406,4407],{"class":1176}," 0",[273,4409,4410],{"class":290},";",[273,4412,4402],{"class":330},[273,4414,4415],{"class":290},"\u003C",[273,4417,4418],{"class":1176}," 10",[273,4420,4410],{"class":290},[273,4422,4423],{"class":330}," i",[273,4425,4426],{"class":290},"++",[273,4428,321],{"class":290},[273,4430,4431,4433,4435,4437,4439,4441],{"class":275,"line":1292},[273,4432,1474],{"class":330},[273,4434,334],{"class":290},[273,4436,1479],{"class":330},[273,4438,340],{"class":290},[273,4440,1484],{"class":314},[273,4442,1106],{"class":290},[273,4444,4445,4447,4449,4451,4453,4455,4457,4459,4461,4463,4465],{"class":275,"line":1722},[273,4446,1491],{"class":330},[273,4448,340],{"class":290},[273,4450,1496],{"class":314},[273,4452,1499],{"class":290},[273,4454,1503],{"class":1502},[273,4456,1506],{"class":290},[273,4458,1509],{"class":294},[273,4460,340],{"class":290},[273,4462,1514],{"class":294},[273,4464,585],{"class":290},[273,4466,321],{"class":290},[273,4468,4469,4471,4473,4475,4477,4479,4481,4483,4485,4487,4489,4491,4493,4495],{"class":275,"line":1727},[273,4470,1523],{"class":330},[273,4472,340],{"class":290},[273,4474,1528],{"class":314},[273,4476,346],{"class":290},[273,4478,1533],{"class":1176},[273,4480,437],{"class":290},[273,4482,1538],{"class":290},[273,4484,1541],{"class":1502},[273,4486,1506],{"class":290},[273,4488,1509],{"class":294},[273,4490,340],{"class":290},[273,4492,1550],{"class":294},[273,4494,585],{"class":290},[273,4496,321],{"class":290},[273,4498,4499,4501,4503,4505,4507,4509,4511,4513,4515,4517,4520,4522,4524,4526,4528,4530,4533,4536],{"class":275,"line":2321},[273,4500,1559],{"class":330},[273,4502,340],{"class":290},[273,4504,1564],{"class":314},[273,4506,346],{"class":290},[273,4508,3767],{"class":330},[273,4510,340],{"class":290},[273,4512,3772],{"class":314},[273,4514,346],{"class":290},[273,4516,359],{"class":290},[273,4518,4519],{"class":362},"Conteúdo da página ",[273,4521,3783],{"class":3782},[273,4523,340],{"class":362},[273,4525,359],{"class":290},[273,4527,437],{"class":290},[273,4529,4423],{"class":330},[273,4531,4532],{"class":290},"+",[273,4534,4535],{"class":1176},"1",[273,4537,1976],{"class":290},[273,4539,4540],{"class":275,"line":2326},[273,4541,1603],{"class":290},[273,4543,4544],{"class":275,"line":2331},[273,4545,1608],{"class":290},[273,4547,4548],{"class":275,"line":2361},[273,4549,409],{"class":290},[19,4551,4552,4554,4555,4557],{},[35,4553,4334],{}," e ",[35,4556,3585],{}," são placeholders que o motor de layout resolve depois da paginação. Cabeçalho e rodapé são árvores em si, não blocks que você posiciona à mão. O motor reserva espaço para eles em cada página automaticamente; se mudar o tamanho da página de A4 para Letter, nada mais precisa ser movido.",[14,4559,4561],{"id":4560},"antes-depois-5-cifragem-com-aes-256","Antes / Depois 5: cifragem com AES-256",[19,4563,4564,4565,4567],{},"O par em que a foto de licenciamento aparece mais nítida. A cifragem do unipdf vai por ",[35,4566,804],{},", que conta como uso comercial e dispara o caminho de registro de licença. A do gpdf mora atrás de uma única opção funcional, e a implementação AES-256 (ISO 32000-2 Rev 6) está no core MIT de código aberto.",[19,4569,4570],{},[22,4571,920],{},[264,4573,4575],{"className":266,"code":4574,"language":268,"meta":269,"style":269},"// Renderiza o conteúdo via creator e re-codifica com model.PdfWriter\n// para anexar cifragem. O check de licença dispara aqui.\nc := creator.New()\n// ... desenhar conteúdo ...\n\nvar buf bytes.Buffer\nif err := c.Write(&buf); err != nil {\n    log.Fatal(err)\n}\n\nreader, err := model.NewPdfReader(bytes.NewReader(buf.Bytes()))\nif err != nil {\n    log.Fatal(err)\n}\n\nwriter := model.NewPdfWriter()\nencryptOpts := &model.EncryptOptions{Algorithm: model.RC4_128bit, Permissions: model.PermPrinting}\nif err := writer.Encrypt([]byte(\"user-pwd\"), []byte(\"owner-pwd\"), encryptOpts); err != nil {\n    log.Fatal(err)\n}\n\nfor i := 1; i \u003C= reader.NumPage; i++ {\n    page, _ := reader.GetPage(i)\n    writer.AddPage(page)\n}\n\nf, _ := os.Create(\"encrypted.pdf\")\ndefer f.Close()\nwriter.Write(f)\n",[35,4576,4577,4582,4587,4601,4606,4610,4624,4655,4669,4673,4677,4716,4728,4742,4746,4750,4766,4815,4875,4889,4893,4897,4931,4955,4970,4974,4978,5007,5022],{"__ignoreMap":269},[273,4578,4579],{"class":275,"line":276},[273,4580,4581],{"class":279},"// Renderiza o conteúdo via creator e re-codifica com model.PdfWriter\n",[273,4583,4584],{"class":275,"line":283},[273,4585,4586],{"class":279},"// para anexar cifragem. O check de licença dispara aqui.\n",[273,4588,4589,4591,4593,4595,4597,4599],{"class":275,"line":301},[273,4590,2895],{"class":330},[273,4592,334],{"class":290},[273,4594,1098],{"class":330},[273,4596,340],{"class":290},[273,4598,1103],{"class":314},[273,4600,1106],{"class":290},[273,4602,4603],{"class":275,"line":308},[273,4604,4605],{"class":279},"// ... desenhar conteúdo ...\n",[273,4607,4608],{"class":275,"line":324},[273,4609,305],{"emptyLinePlaceholder":304},[273,4611,4612,4614,4617,4619,4621],{"class":275,"line":381},[273,4613,3190],{"class":290},[273,4615,4616],{"class":330}," buf ",[273,4618,3555],{"class":294},[273,4620,340],{"class":290},[273,4622,4623],{"class":294},"Buffer\n",[273,4625,4626,4628,4630,4632,4634,4636,4639,4642,4645,4647,4649,4651,4653],{"class":275,"line":400},[273,4627,2334],{"class":286},[273,4629,331],{"class":330},[273,4631,334],{"class":290},[273,4633,1144],{"class":330},[273,4635,340],{"class":290},[273,4637,4638],{"class":314},"Write",[273,4640,4641],{"class":290},"(&",[273,4643,4644],{"class":330},"buf",[273,4646,500],{"class":290},[273,4648,331],{"class":330},[273,4650,373],{"class":290},[273,4652,376],{"class":290},[273,4654,321],{"class":290},[273,4656,4657,4659,4661,4663,4665,4667],{"class":275,"line":406},[273,4658,2364],{"class":330},[273,4660,340],{"class":290},[273,4662,389],{"class":314},[273,4664,346],{"class":290},[273,4666,394],{"class":330},[273,4668,397],{"class":290},[273,4670,4671],{"class":275,"line":986},[273,4672,409],{"class":290},[273,4674,4675],{"class":275,"line":991},[273,4676,305],{"emptyLinePlaceholder":304},[273,4678,4679,4682,4684,4686,4688,4690,4692,4695,4697,4699,4701,4704,4706,4708,4710,4713],{"class":275,"line":996},[273,4680,4681],{"class":330},"reader",[273,4683,437],{"class":290},[273,4685,331],{"class":330},[273,4687,334],{"class":290},[273,4689,1858],{"class":330},[273,4691,340],{"class":290},[273,4693,4694],{"class":314},"NewPdfReader",[273,4696,346],{"class":290},[273,4698,3555],{"class":330},[273,4700,340],{"class":290},[273,4702,4703],{"class":314},"NewReader",[273,4705,346],{"class":290},[273,4707,4644],{"class":330},[273,4709,340],{"class":290},[273,4711,4712],{"class":314},"Bytes",[273,4714,4715],{"class":290},"()))\n",[273,4717,4718,4720,4722,4724,4726],{"class":275,"line":1007},[273,4719,2334],{"class":286},[273,4721,331],{"class":330},[273,4723,373],{"class":290},[273,4725,376],{"class":290},[273,4727,321],{"class":290},[273,4729,4730,4732,4734,4736,4738,4740],{"class":275,"line":1048},[273,4731,2364],{"class":330},[273,4733,340],{"class":290},[273,4735,389],{"class":314},[273,4737,346],{"class":290},[273,4739,394],{"class":330},[273,4741,397],{"class":290},[273,4743,4744],{"class":275,"line":1063},[273,4745,409],{"class":290},[273,4747,4748],{"class":275,"line":1068},[273,4749,305],{"emptyLinePlaceholder":304},[273,4751,4752,4755,4757,4759,4761,4764],{"class":275,"line":1073},[273,4753,4754],{"class":330},"writer ",[273,4756,334],{"class":290},[273,4758,1858],{"class":330},[273,4760,340],{"class":290},[273,4762,4763],{"class":314},"NewPdfWriter",[273,4765,1106],{"class":290},[273,4767,4768,4771,4773,4776,4779,4781,4784,4786,4789,4792,4794,4796,4799,4801,4804,4806,4808,4810,4813],{"class":275,"line":1078},[273,4769,4770],{"class":330},"encryptOpts ",[273,4772,334],{"class":290},[273,4774,4775],{"class":290}," &",[273,4777,4778],{"class":294},"model",[273,4780,340],{"class":290},[273,4782,4783],{"class":294},"EncryptOptions",[273,4785,2113],{"class":290},[273,4787,4788],{"class":330},"Algorithm",[273,4790,4791],{"class":290},":",[273,4793,1858],{"class":330},[273,4795,340],{"class":290},[273,4797,4798],{"class":330},"RC4_128bit",[273,4800,437],{"class":290},[273,4802,4803],{"class":330}," Permissions",[273,4805,4791],{"class":290},[273,4807,1858],{"class":330},[273,4809,340],{"class":290},[273,4811,4812],{"class":330},"PermPrinting",[273,4814,409],{"class":290},[273,4816,4817,4819,4821,4823,4826,4828,4830,4833,4836,4838,4840,4843,4845,4847,4849,4851,4853,4855,4858,4860,4862,4865,4867,4869,4871,4873],{"class":275,"line":1090},[273,4818,2334],{"class":286},[273,4820,331],{"class":330},[273,4822,334],{"class":290},[273,4824,4825],{"class":330}," writer",[273,4827,340],{"class":290},[273,4829,808],{"class":314},[273,4831,4832],{"class":290},"([]",[273,4834,4835],{"class":481},"byte",[273,4837,346],{"class":290},[273,4839,359],{"class":290},[273,4841,4842],{"class":362},"user-pwd",[273,4844,359],{"class":290},[273,4846,490],{"class":290},[273,4848,2108],{"class":290},[273,4850,4835],{"class":481},[273,4852,346],{"class":290},[273,4854,359],{"class":290},[273,4856,4857],{"class":362},"owner-pwd",[273,4859,359],{"class":290},[273,4861,490],{"class":290},[273,4863,4864],{"class":330}," encryptOpts",[273,4866,500],{"class":290},[273,4868,331],{"class":330},[273,4870,373],{"class":290},[273,4872,376],{"class":290},[273,4874,321],{"class":290},[273,4876,4877,4879,4881,4883,4885,4887],{"class":275,"line":1109},[273,4878,2364],{"class":330},[273,4880,340],{"class":290},[273,4882,389],{"class":314},[273,4884,346],{"class":290},[273,4886,394],{"class":330},[273,4888,397],{"class":290},[273,4890,4891],{"class":275,"line":1131},[273,4892,409],{"class":290},[273,4894,4895],{"class":275,"line":1136},[273,4896,305],{"emptyLinePlaceholder":304},[273,4898,4899,4901,4903,4905,4908,4910,4912,4915,4918,4920,4923,4925,4927,4929],{"class":275,"line":1163},[273,4900,2092],{"class":286},[273,4902,4402],{"class":330},[273,4904,334],{"class":290},[273,4906,4907],{"class":1176}," 1",[273,4909,4410],{"class":290},[273,4911,4402],{"class":330},[273,4913,4914],{"class":290},"\u003C=",[273,4916,4917],{"class":330}," reader",[273,4919,340],{"class":290},[273,4921,4922],{"class":330},"NumPage",[273,4924,4410],{"class":290},[273,4926,4423],{"class":330},[273,4928,4426],{"class":290},[273,4930,321],{"class":290},[273,4932,4933,4935,4937,4939,4941,4943,4945,4948,4950,4953],{"class":275,"line":1182},[273,4934,1491],{"class":330},[273,4936,437],{"class":290},[273,4938,440],{"class":330},[273,4940,334],{"class":290},[273,4942,4917],{"class":330},[273,4944,340],{"class":290},[273,4946,4947],{"class":314},"GetPage",[273,4949,346],{"class":290},[273,4951,4952],{"class":330},"i",[273,4954,397],{"class":290},[273,4956,4957,4960,4962,4964,4966,4968],{"class":275,"line":1212},[273,4958,4959],{"class":330},"    writer",[273,4961,340],{"class":290},[273,4963,1484],{"class":314},[273,4965,346],{"class":290},[273,4967,2396],{"class":330},[273,4969,397],{"class":290},[273,4971,4972],{"class":275,"line":1227},[273,4973,409],{"class":290},[273,4975,4976],{"class":275,"line":1232},[273,4977,305],{"emptyLinePlaceholder":304},[273,4979,4980,4983,4985,4987,4989,4991,4993,4996,4998,5000,5003,5005],{"class":275,"line":1237},[273,4981,4982],{"class":330},"f",[273,4984,437],{"class":290},[273,4986,440],{"class":330},[273,4988,334],{"class":290},[273,4990,445],{"class":330},[273,4992,340],{"class":290},[273,4994,4995],{"class":314},"Create",[273,4997,346],{"class":290},[273,4999,359],{"class":290},[273,5001,5002],{"class":362},"encrypted.pdf",[273,5004,359],{"class":290},[273,5006,397],{"class":290},[273,5008,5009,5012,5015,5017,5020],{"class":275,"line":1272},[273,5010,5011],{"class":286},"defer",[273,5013,5014],{"class":330}," f",[273,5016,340],{"class":290},[273,5018,5019],{"class":314},"Close",[273,5021,1106],{"class":290},[273,5023,5024,5027,5029,5031,5033,5035],{"class":275,"line":1287},[273,5025,5026],{"class":330},"writer",[273,5028,340],{"class":290},[273,5030,4638],{"class":314},[273,5032,346],{"class":290},[273,5034,4982],{"class":330},[273,5036,397],{"class":290},[19,5038,5039],{},[22,5040,1299],{},[264,5042,5044],{"className":266,"code":5043,"language":268,"meta":269,"style":269},"doc := gpdf.NewDocument(\n    gpdf.WithPageSize(document.A4),\n    gpdf.WithMargins(document.UniformEdges(document.Mm(20))),\n    gpdf.WithEncryption(\n        gpdf.AES256,\n        \"user-pwd\",\n        \"owner-pwd\",\n        gpdf.PermPrinting|gpdf.PermCopyContent,\n    ),\n)\n\npage := doc.AddPage()\npage.AutoRow(func(r *template.RowBuilder) {\n    r.Col(12, func(c *template.ColBuilder) {\n        c.Text(\"Confidencial.\")\n    })\n})\n\ndata, _ := doc.Generate()\nos.WriteFile(\"encrypted.pdf\", data, 0o644)\n",[35,5045,5046,5060,5078,5108,5119,5130,5141,5151,5171,5176,5180,5184,5199,5223,5253,5272,5276,5280,5284,5303],{"__ignoreMap":269},[273,5047,5048,5050,5052,5054,5056,5058],{"class":275,"line":276},[273,5049,3897],{"class":330},[273,5051,334],{"class":290},[273,5053,1394],{"class":330},[273,5055,340],{"class":290},[273,5057,1399],{"class":314},[273,5059,1402],{"class":290},[273,5061,5062,5064,5066,5068,5070,5072,5074,5076],{"class":275,"line":283},[273,5063,3912],{"class":330},[273,5065,340],{"class":290},[273,5067,1412],{"class":314},[273,5069,346],{"class":290},[273,5071,1417],{"class":330},[273,5073,340],{"class":290},[273,5075,1422],{"class":330},[273,5077,1425],{"class":290},[273,5079,5080,5082,5084,5086,5088,5090,5092,5094,5096,5098,5100,5102,5104,5106],{"class":275,"line":301},[273,5081,3912],{"class":330},[273,5083,340],{"class":290},[273,5085,1434],{"class":314},[273,5087,346],{"class":290},[273,5089,1417],{"class":330},[273,5091,340],{"class":290},[273,5093,1443],{"class":314},[273,5095,346],{"class":290},[273,5097,1417],{"class":330},[273,5099,340],{"class":290},[273,5101,1452],{"class":314},[273,5103,346],{"class":290},[273,5105,1457],{"class":1176},[273,5107,1460],{"class":290},[273,5109,5110,5112,5114,5117],{"class":275,"line":308},[273,5111,3912],{"class":330},[273,5113,340],{"class":290},[273,5115,5116],{"class":314},"WithEncryption",[273,5118,1402],{"class":290},[273,5120,5121,5123,5125,5128],{"class":275,"line":324},[273,5122,1407],{"class":330},[273,5124,340],{"class":290},[273,5126,5127],{"class":330},"AES256",[273,5129,4257],{"class":290},[273,5131,5132,5135,5137,5139],{"class":275,"line":381},[273,5133,5134],{"class":290},"        \"",[273,5136,4842],{"class":362},[273,5138,359],{"class":290},[273,5140,4257],{"class":290},[273,5142,5143,5145,5147,5149],{"class":275,"line":400},[273,5144,5134],{"class":290},[273,5146,4857],{"class":362},[273,5148,359],{"class":290},[273,5150,4257],{"class":290},[273,5152,5153,5155,5157,5159,5162,5164,5166,5169],{"class":275,"line":406},[273,5154,1407],{"class":330},[273,5156,340],{"class":290},[273,5158,4812],{"class":330},[273,5160,5161],{"class":290},"|",[273,5163,24],{"class":330},[273,5165,340],{"class":290},[273,5167,5168],{"class":330},"PermCopyContent",[273,5170,4257],{"class":290},[273,5172,5173],{"class":275,"line":986},[273,5174,5175],{"class":290},"    ),\n",[273,5177,5178],{"class":275,"line":991},[273,5179,397],{"class":290},[273,5181,5182],{"class":275,"line":996},[273,5183,305],{"emptyLinePlaceholder":304},[273,5185,5186,5189,5191,5193,5195,5197],{"class":275,"line":1007},[273,5187,5188],{"class":330},"page ",[273,5190,334],{"class":290},[273,5192,1479],{"class":330},[273,5194,340],{"class":290},[273,5196,1484],{"class":314},[273,5198,1106],{"class":290},[273,5200,5201,5203,5205,5207,5209,5211,5213,5215,5217,5219,5221],{"class":275,"line":1048},[273,5202,2396],{"class":330},[273,5204,340],{"class":290},[273,5206,1496],{"class":314},[273,5208,1499],{"class":290},[273,5210,1503],{"class":1502},[273,5212,1506],{"class":290},[273,5214,1509],{"class":294},[273,5216,340],{"class":290},[273,5218,1514],{"class":294},[273,5220,585],{"class":290},[273,5222,321],{"class":290},[273,5224,5225,5227,5229,5231,5233,5235,5237,5239,5241,5243,5245,5247,5249,5251],{"class":275,"line":1063},[273,5226,2421],{"class":330},[273,5228,340],{"class":290},[273,5230,1528],{"class":314},[273,5232,346],{"class":290},[273,5234,1533],{"class":1176},[273,5236,437],{"class":290},[273,5238,1538],{"class":290},[273,5240,1541],{"class":1502},[273,5242,1506],{"class":290},[273,5244,1509],{"class":294},[273,5246,340],{"class":290},[273,5248,1550],{"class":294},[273,5250,585],{"class":290},[273,5252,321],{"class":290},[273,5254,5255,5257,5259,5261,5263,5265,5268,5270],{"class":275,"line":1068},[273,5256,2452],{"class":330},[273,5258,340],{"class":290},[273,5260,1564],{"class":314},[273,5262,346],{"class":290},[273,5264,359],{"class":290},[273,5266,5267],{"class":362},"Confidencial.",[273,5269,359],{"class":290},[273,5271,397],{"class":290},[273,5273,5274],{"class":275,"line":1073},[273,5275,1608],{"class":290},[273,5277,5278],{"class":275,"line":1078},[273,5279,2780],{"class":290},[273,5281,5282],{"class":275,"line":1090},[273,5283,305],{"emptyLinePlaceholder":304},[273,5285,5286,5289,5291,5293,5295,5297,5299,5301],{"class":275,"line":1109},[273,5287,5288],{"class":330},"data",[273,5290,437],{"class":290},[273,5292,440],{"class":330},[273,5294,334],{"class":290},[273,5296,1479],{"class":330},[273,5298,340],{"class":290},[273,5300,1630],{"class":314},[273,5302,1106],{"class":290},[273,5304,5305,5307,5309,5311,5313,5315,5317,5319,5321,5323,5325,5327],{"class":275,"line":1131},[273,5306,349],{"class":330},[273,5308,340],{"class":290},[273,5310,1677],{"class":314},[273,5312,346],{"class":290},[273,5314,359],{"class":290},[273,5316,5002],{"class":362},[273,5318,359],{"class":290},[273,5320,437],{"class":290},[273,5322,1690],{"class":330},[273,5324,437],{"class":290},[273,5326,1695],{"class":1176},[273,5328,397],{"class":290},[19,5330,5331,5332,5335,5336,5339],{},"Uma opção, AES-256 por padrão, sem passada de writer separada. O caminho de cifragem inteiro mora dentro do core MIT — mesmo módulo, mesmo ",[35,5333,5334],{},"go get",". Mesma história para assinatura digital: ",[35,5337,5338],{},"gpdf.SignDocument(pdfBytes, signer, gpdf.WithTSA(\"http://timestamp.digicert.com\"))"," pós-processa os bytes com timestamp PKCS#7 + RFC 3161, sem pacote extra e sem registro de chave.",[14,5341,5343],{"id":5342},"quão-rápido-fica","Quão rápido fica?",[19,5345,5346,5347,5350],{},"Benchmarks de ",[35,5348,5349],{},"_benchmark/benchmark_test.go"," em um Apple M1 com Go 1.25. unipdf não está direto na nossa suite porque os termos de licença tornavam estranho distribuir o código de comparação; os números abaixo são o que coletamos no mesmo hardware contra as mesmas cargas.",[120,5352,5353,5371],{},[123,5354,5355],{},[126,5356,5357,5360,5362,5365,5368],{},[129,5358,5359],{},"Benchmark",[129,5361,24],{},[129,5363,5364],{},"unipdf*",[129,5366,5367],{},"gofpdf",[129,5369,5370],{},"Maroto v2",[138,5372,5373,5392,5409,5428],{},[126,5374,5375,5378,5383,5386,5389],{},[143,5376,5377],{},"Página única",[143,5379,5380],{},[22,5381,5382],{},"13 µs",[143,5384,5385],{},"~180 µs",[143,5387,5388],{},"132 µs",[143,5390,5391],{},"237 µs",[126,5393,5394,5397,5401,5404,5407],{},[143,5395,5396],{},"Tabela 4×10 fatura",[143,5398,5399],{},[22,5400,2803],{},[143,5402,5403],{},"~8,6 ms",[143,5405,5406],{},"241 µs",[143,5408,2799],{},[126,5410,5411,5414,5419,5422,5425],{},[143,5412,5413],{},"Relatório 100 páginas",[143,5415,5416],{},[22,5417,5418],{},"683 µs",[143,5420,5421],{},"~95 ms",[143,5423,5424],{},"11,7 ms",[143,5426,5427],{},"19,8 ms",[126,5429,5430,5433,5438,5441,5444],{},[143,5431,5432],{},"Fatura CJK complexa",[143,5434,5435],{},[22,5436,5437],{},"133 µs",[143,5439,5440],{},"~12 ms",[143,5442,5443],{},"254 µs",[143,5445,5446],{},"10,4 ms",[19,5448,5449],{},"* Os números do unipdf vêm de uma rodada separada no mesmo Apple M1 / Go 1.25, capturados por nós contra o último unipdf v3 no momento da escrita. Trate como aproximados; não fazem parte da nossa suite versionada.",[19,5451,5452],{},"A forma é a mesma da comparação com gofpdf: gpdf é cerca de 10–80× mais rápido nas cargas que as pessoas rodam de verdade. A 108 µs por página com tabela, um único core produz ~9.000 faturas por segundo. O ponto não é vangloriar — é que você pode parar de pensar se vai cachear ou enfileirar a geração de PDF. Gerar no caminho de request basta para quase tudo.",[14,5454,5456],{"id":5455},"e-as-partes-que-gpdf-não-tem","E as partes que gpdf não tem?",[19,5458,5459],{},"Se sua fatura de unipdf paga OCR, redaction ou parsing de PDF, esta migração não te leva até o fim. As opções honestas:",[5461,5462,5463,5477,5489,5495],"ul",{},[91,5464,5465,5468,5469,5476],{},[22,5466,5467],{},"OCR."," gpdf não faz OCR e dificilmente fará. Use ",[5470,5471,5475],"a",{"href":5472,"rel":5473},"https://github.com/tesseract-ocr/tesseract",[5474],"nofollow","Tesseract"," via gosseract, ou uma API de OCR hospedada. A geração fica no gpdf, o parsing fica no que você escolher.",[91,5478,5479,5482,5483,5488],{},[22,5480,5481],{},"Parsing / extração de texto."," gpdf é só geração por design. Para cargas de leitura, ",[5470,5484,5487],{"href":5485,"rel":5486},"https://github.com/pdfcpu/pdfcpu",[5474],"pdfcpu"," cobre muitos casos comuns (Apache 2.0). Mantenha unipdf só para parsing e talvez consiga reduzir o número de assentos.",[91,5490,5491,5494],{},[22,5492,5493],{},"Criação de campos AcroForm."," gpdf consegue achatar campos AcroForm existentes; ainda não consegue criar novos. Se você produz formulários para usuários preencherem em um visualizador, este é o gap que vai sentir. Está no roadmap.",[91,5496,5497,5500],{},[22,5498,5499],{},"Redaction."," Não está no roadmap do gpdf. Redaction precisa de um renderer de verdade para saber o que apagar, que é uma arquitetura diferente da geração.",[19,5502,5503,5504,5506],{},"Para o caminho de ",[22,5505,254],{}," — o destino real da maior parte das faturas de unipdf — a troca é completa.",[14,5508,5510],{"id":5509},"faq","FAQ",[19,5512,5513,5516],{},[22,5514,5515],{},"gpdf é um fork do unipdf?","\nNão. gpdf é uma reimplementação limpa em Go puro. Wire format do PDF, motor de layout, subseteador TrueType, AES, PKCS#7 — tudo escrito do zero. Sem código compartilhado, sem linhagem compartilhada e sem risco de uma discussão de licenciamento dar errado porque nada foi copiado.",[19,5518,5519,5522,5523,5528],{},[22,5520,5521],{},"gpdf é mesmo MIT? Sem \"AGPL sob certa condição\"?","\nSim. A ",[5470,5524,5527],{"href":5525,"rel":5526},"https://github.com/gpdf-dev/gpdf/blob/main/LICENSE",[5474],"LICENSE"," do repositório é a licença MIT literal, sem anexos, sem cláusulas de campo de uso, sem recortes de tier comercial. Use em produtos fechados distribuíveis, embuta em SaaS comercial, mande dentro de appliances on-prem. A única obrigação é a nota de licença e copyright na sua distribuição.",[19,5530,5531,5534,5535,5538,5539,5542,5543,5546,5547,340],{},[22,5532,5533],{},"E as dependências transitivas — tem copyleft escondido por baixo?","\nO bloco ",[35,5536,5537],{},"require"," do ",[35,5540,5541],{},"go.mod"," do core do gpdf está vazio. Sem AGPL transitiva, sem GPL transitiva, sem nada transitivo. Verifique com ",[35,5544,5545],{},"go mod graph | grep gpdf"," depois do ",[35,5548,5334],{},[19,5550,5551,5554],{},[22,5552,5553],{},"Tirar a chave de licença importa tanto assim?","\nPara alguns times é tudo. A chave precisa morar no secret manager, ser rotacionada, ser auditada, ser incluída em cada imagem de container e não vazar em logs. Para um SaaS multi-tenant com centenas de pods, isso é uma superfície operacional de verdade. Eliminar a exigência apaga uma classe de incidentes.",[19,5556,5557,5564,5565,5568,5569,5573],{},[22,5558,5559,5560,5563],{},"Meu código atual de unipdf usa ",[35,5561,5562],{},"creator.Block.SetPos"," para posicionamento absoluto em todo lugar. gpdf tem equivalente?","\nTem — ",[35,5566,5567],{},"page.Absolute(x, y, fn)"," deixa você colocar uma sub-árvore numa coordenada explícita. Mas se seu código está estruturado em torno de manipulação de cursor, o modelo de motor de layout é uma mudança mental, não sintática. Leia o ",[5470,5570,5572],{"href":5571},"/pt/blog/12-column-grid","post sobre a grade de 12 colunas"," antes de estimar; código reescrito costuma ser mais curto que o original.",[19,5575,5576,5579],{},[22,5577,5578],{},"E se a UniDoc relicenciar o unipdf para MIT um dia?","\nVocê ganha mais uma opção. A aposta por trás do gpdf não é que unipdf vai ficar AGPL para sempre; é que uma licença que exige uma chamada de registro no startup e renovação por desenvolvedor no nível financeiro é um imposto que não precisa existir para a maioria das cargas. Mesmo se relicenciassem amanhã, a superfície operacional da chave continuaria lá até eles tirarem.",[14,5581,5583],{"id":5582},"experimentar-gpdf","Experimentar gpdf",[19,5585,5586],{},"gpdf é uma biblioteca Go para gerar PDFs. Licença MIT, zero dependências externas, sem chave de licença, suporte CJK nativo.",[264,5588,5592],{"className":5589,"code":5590,"language":5591,"meta":269,"style":269},"language-bash shiki shiki-themes material-theme-lighter material-theme material-theme-palenight","go get github.com/gpdf-dev/gpdf\n","bash",[35,5593,5594],{"__ignoreMap":269},[273,5595,5596,5598,5601],{"class":275,"line":276},[273,5597,268],{"class":294},[273,5599,5600],{"class":362}," get",[273,5602,5603],{"class":362}," github.com/gpdf-dev/gpdf\n",[19,5605,5606,5611,5612],{},[5470,5607,5610],{"href":5608,"rel":5609},"https://github.com/gpdf-dev/gpdf",[5474],"⭐ Star no GitHub"," · ",[5470,5613,5616],{"href":5614,"rel":5615},"https://gpdf.dev/pt/docs/quickstart",[5474],"Leia os docs",[14,5618,5620],{"id":5619},"próximas-leituras","Próximas leituras",[5461,5622,5623,5629,5634,5640],{},[91,5624,5625],{},[5470,5626,5628],{"href":5627},"/pt/blog/embed-japanese-font","Como embutir uma fonte japonesa no gpdf",[91,5630,5631],{},[5470,5632,5633],{"href":5571},"A grade de 12 colunas: pensamento Bootstrap aplicado ao PDF",[91,5635,5636],{},[5470,5637,5639],{"href":5638},"/pt/blog/gofpdf-migration","gofpdf foi arquivado. Como migrar para o gpdf",[91,5641,5642,5646],{},[5470,5643,5645],{"href":5614,"rel":5644},[5474],"Quickstart"," — setup em cinco minutos",[2947,5648,5649],{},"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 .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 .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 .s2Zo4, html code.shiki .s2Zo4{--shiki-light:#6182B8;--shiki-default:#82AAFF;--shiki-dark:#82AAFF}html pre.shiki code .sTEyZ, html code.shiki .sTEyZ{--shiki-light:#90A4AE;--shiki-default:#EEFFFF;--shiki-dark:#BABED8}html pre.shiki code .sfazB, html code.shiki .sfazB{--shiki-light:#91B859;--shiki-default:#C3E88D;--shiki-dark:#C3E88D}html .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 .spNyl, html code.shiki .spNyl{--shiki-light:#9C3EDA;--shiki-default:#C792EA;--shiki-dark:#C792EA}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 .swJcz, html code.shiki .swJcz{--shiki-light:#E53935;--shiki-default:#F07178;--shiki-dark:#F07178}",{"title":269,"searchDepth":283,"depth":283,"links":5651},[5652,5653,5654,5655,5656,5657,5658,5659,5660,5661,5662,5663,5664,5665,5666],{"id":16,"depth":283,"text":17},{"id":79,"depth":283,"text":80},{"id":114,"depth":283,"text":115},{"id":258,"depth":283,"text":259},{"id":558,"depth":283,"text":559},{"id":911,"depth":283,"text":912},{"id":1741,"depth":283,"text":1742},{"id":2814,"depth":283,"text":2815},{"id":3570,"depth":283,"text":3571},{"id":4560,"depth":283,"text":4561},{"id":5342,"depth":283,"text":5343},{"id":5455,"depth":283,"text":5456},{"id":5509,"depth":283,"text":5510},{"id":5582,"depth":283,"text":5583},{"id":5619,"depth":283,"text":5620},"2026-04-29","O unipdf da UniDoc obriga AGPL v3 ou licença comercial por desenvolvedor. Este guia mapeia a API creator do unipdf para gpdf — MIT, zero deps, sem chave.",false,"md",{"name":5672,"totalTime":5673,"tools":5674,"steps":5676},"Migrar um projeto Go de unidoc/unipdf para gpdf","PT45M",[5675],"Go 1.22+",[5677,5680,5683,5686,5689,5692,5695],{"name":5678,"text":5679},"Apagar o código de registro de licença","Remova as chamadas license.SetMeteredKey ou license.SetLicenseKey do unipdf em main e em qualquer init(). gpdf não tem chave de licença, nem API de medição, nem registro na inicialização.",{"name":5681,"text":5682},"Trocar os caminhos de import","Substitua github.com/unidoc/unipdf/v3/creator e github.com/unidoc/unipdf/v3/model por github.com/gpdf-dev/gpdf, github.com/gpdf-dev/gpdf/document e github.com/gpdf-dev/gpdf/template.",{"name":5684,"text":5685},"Substituir creator.New por gpdf.NewDocument","Construa o documento com gpdf.NewDocument(WithPageSize(document.A4), WithMargins(...)). Páginas vêm de doc.AddPage() e retornam um PageBuilder, sem cursor livre.",{"name":5687,"text":5688},"Converter Paragraph e StyledParagraph em c.Text","Dentro de uma coluna, chame c.Text(string, options...) em vez de construir um Paragraph e passá-lo para c.Draw. Fonte, tamanho e cor saem de campos de struct para opções por texto.",{"name":5690,"text":5691},"Reescrever tabelas com a grade de 12 colunas","Troque creator.NewTable(cols).SetColumnWidths e SetCellSpan por row.Col(span, fn) dentro de um AutoRow. A grade de 12 colunas trata larguras como porcentagens e quebra tabelas entre páginas automaticamente.",{"name":5693,"text":5694},"Registrar fontes como bytes, não como caminhos","Substitua model.NewCompositePdfFontFromTTFFile por gpdf.WithFont(name, ttfBytes) no construtor. Embuta o TTF com //go:embed para o binário deixar de precisar de caminho de fonte em runtime.",{"name":5696,"text":5697},"Trocar a chamada de saída","Substitua c.WriteToFile(path) por doc.Generate() seguido de os.WriteFile(path, data, 0o644), ou use doc.Render(w) para escrever direto em um io.Writer.",null,{},"/pt/blog/unidoc-migration",{"title":5,"description":5668},"pt/blog/016.unidoc-migration",[5704,5705,5706],"migration","comparison","tutorial","G7QLcsh8xlxJbO2pqTc1O_hoVeffrt5VAK9RHHeoGZI",1779199037358]