[{"data":1,"prerenderedAt":1910},["ShallowReactive",2],{"blog-pt-japanese-pdf-in-go":3},{"id":4,"title":5,"author":6,"body":9,"date":1871,"description":1872,"draft":1873,"extension":1874,"howTo":1875,"image":1900,"meta":1901,"navigation":334,"path":1902,"seo":1903,"stem":1904,"tags":1905,"updated":1900,"__hash__":1909},"blogPt/pt/blog/007.japanese-pdf-in-go.md","PDFs em japonês com Go: o guia definitivo de 2026",{"name":7,"url":8},"gpdf team","https://gpdf.dev",{"type":10,"value":11,"toc":1857},"minimark",[12,17,43,47,50,57,64,67,71,82,125,136,142,146,149,278,281,287,293,297,307,1281,1284,1340,1349,1353,1359,1362,1365,1414,1427,1430,1455,1471,1475,1478,1486,1489,1503,1509,1591,1602,1606,1609,1618,1628,1652,1666,1669,1673,1680,1687,1693,1707,1710,1714,1739,1745,1751,1765,1775,1784,1788,1791,1806,1820,1824,1853],[13,14,16],"h2",{"id":15},"tldr","TL;DR",[18,19,20,21,25,26,29,30,33,34,38,39,42],"p",{},"Se seu PDF em Go renderiza ",[22,23,24],"code",{},"こんにちは"," como cinco caixas de tofu, a correção são duas linhas de configuração, não uma reescrita. Carregue um TTF japonês, passe ",[22,27,28],{},"gpdf.WithFont"," para ",[22,31,32],{},"NewDocument",", escreva em japonês. ",[35,36,37],"strong",{},"O gpdf faz o subconjunto da tabela de glifos automaticamente",", então a saída carrega apenas os caracteres que você usou — cerca de 30 KB, não os 5 MB da fonte completa. Este guia é o mapa: por que gerar PDFs em japonês com Go tem sido estranhamente difícil, as quatro opções reais em 2026, um exemplo completo e funcional, os detalhes internos do subconjunto de fontes, casos limite de escritas mistas, e ",[35,40,41],{},"o que ainda não funciona",".",[13,44,46],{"id":45},"por-que-este-guia-existe","Por que este guia existe",[18,48,49],{},"Tirar um PDF com texto japonês do Go deveria ser trabalho de cinco minutos. Para muitos times é um dia e meio.",[18,51,52,53,56],{},"A história usual: alguém troca para ",[22,54,55],{},"AddUTF8Font",", o PDF mostra retângulos em branco — o infame 豆腐 — e um dev sênior passa a tarde descobrindo se o problema é o caminho da fonte, a flag de subconjunto, o CMap, a flag UTF-8 ou o leitor de PDF. Ao cair da noite há uma thread no Slack chamada \"POR QUE 漢字 AINDA ESTÁ QUEBRADO\" e um PR que adiciona três funções auxiliares das quais todos já se arrependem.",[18,58,59,60,63],{},"A causa raiz não é nenhuma delas. ",[35,61,62],{},"A biblioteca de PDF mais longeva do Go foi desenhada em 2002 para PHP e Latin-1",", e quase todos os tutoriais japoneses escritos desde então estão brigando com esse legado. Este guia é a versão 2026: o que realmente funciona quando você começa do zero, e o que ainda é genuinamente difícil.",[18,65,66],{},"Todo o código deste post roda com gpdf v1.x em 2026-04. Os números de benchmark são de um Apple M1 com Go 1.25.",[13,68,70],{"id":69},"o-problema-do-tofu-em-90-segundos","O problema do tofu em 90 segundos",[18,72,73,74,77,78,81],{},"PDF não se importa com Unicode. Ele se importa com ",[35,75,76],{},"IDs de glifo"," — índices inteiros para a tabela de glifos embutida da fonte. Quando você escreve ",[22,79,80],{},"\"こんにちは\""," num PDF, alguém tem que:",[83,84,85,96,102,108],"ol",{},[86,87,88,91,92,95],"li",{},[35,89,90],{},"Parsear o TTF"," e achar o ID de glifo para cada code point (via a subtabela ",[22,93,94],{},"cmap"," da fonte).",[86,97,98,101],{},[35,99,100],{},"Escrever um ToUnicode CMap"," para que o leitor de PDF consiga mapear glifos de volta ao texto quando o usuário copiar ou buscar.",[86,103,104,107],{},[35,105,106],{},"Fazer o subconjunto"," da fonte para que o PDF não carregue todos os 20.000 glifos da Noto Sans JP.",[86,109,110,113,114,117,118,117,121,124],{},[35,111,112],{},"Embutir o resultado"," com as tabelas ",[22,115,116],{},"name",", ",[22,119,120],{},"OS/2",[22,122,123],{},"head"," e as referências de codificação corretamente costuradas.",[18,126,127,128,131,132,135],{},"Se algum passo falta ou está errado, o leitor não acha glifo para o code point e pinta uma caixa de tofu. Os linhagens arquivadas ",[22,129,130],{},"jung-kurt/gofpdf"," e ",[22,133,134],{},"go-pdf/fpdf"," encaixaram tudo isso num modelo interno de fonte de byte único — o FPDF original de 2002 só conhecia Latin-1. É por isso que a configuração é frágil, a saída frequentemente embute a fonte completa em vez do subconjunto, e os modos de falha variam por SO e leitor de PDF.",[18,137,138,139,141],{},"gpdf trata CJK como caso de primeira classe. O subsetter TTF está no pacote core. O ToUnicode CMap é escrito automaticamente. Não há dança de ",[22,140,55],{}," porque não há legado de fonte de byte único para contornar.",[13,143,145],{"id":144},"as-quatro-opções-reais-em-2026","As quatro opções reais em 2026",[18,147,148],{},"Antes de escrever código: o campo honesto. \"Capaz de japonês\" significa \"renderiza qualquer texto japonês sem crashes ou tofu, dado um TTF correto\".",[150,151,152,177],"table",{},[153,154,155],"thead",{},[156,157,158,162,165,168,171,174],"tr",{},[159,160,161],"th",{},"Opção",[159,163,164],{},"Licença",[159,166,167],{},"Deps",[159,169,170],{},"Caminho CJK",[159,172,173],{},"Tamanho para 300 caracteres",[159,175,176],{},"Notas",[178,179,180,205,228,253],"tbody",{},[156,181,182,188,191,194,199,202],{},[183,184,185,187],"td",{},[22,186,134],{}," (arquivada 2025)",[183,189,190],{},"MIT",[183,192,193],{},"stdlib",[183,195,196,197],{},"Encaixe ",[22,198,55],{},[183,200,201],{},"~5 MB (fonte cheia)",[183,203,204],{},"Encaixe em core Latin-1. Subconjunto é opt-in e imperfeito.",[156,206,207,212,214,216,222,225],{},[183,208,209],{},[22,210,211],{},"signintech/gopdf",[183,213,190],{},[183,215,193],{},[183,217,218,221],{},[22,219,220],{},"AddTTFFont"," + manual",[183,223,224],{},"~3 MB típico",[183,226,227],{},"Baixo nível. Você escreve coordenadas. Subconjunto existe mas você conduz.",[156,229,230,236,239,244,247,250],{},[183,231,232,235],{},[22,233,234],{},"chromedp"," + Chromium",[183,237,238],{},"MIT + Chrome",[183,240,241],{},[35,242,243],{},"binário Chromium",[183,245,246],{},"Nativo via navegador",[183,248,249],{},"variável",[183,251,252],{},"HTML/CSS. Precisa de fontes instaladas no container. Imagem 500 MB+.",[156,254,255,260,262,267,270,275],{},[183,256,257],{},[22,258,259],{},"gpdf",[183,261,190],{},[183,263,264],{},[35,265,266],{},"só stdlib",[183,268,269],{},"Nativo, subconjunto automático",[183,271,272],{},[35,273,274],{},"~30 KB",[183,276,277],{},"Go puro. API builder. ToUnicode CMap escrito por você.",[18,279,280],{},"Duas coisas que vale sublinhar:",[18,282,283,286],{},[35,284,285],{},"A diferença de 160× entre \"fonte cheia embutida\" e \"subconjunto automático\" não é arredondamento."," Uma fatura de e-commerce para o mercado japonês com dez linhas precisa de talvez 120 glifos japoneses únicos. Embutir a Noto Sans JP completa (5,1 MB) em cada fatura significa que sua conta de storage carrega os mesmos 5 MB de dados de glifos 10 milhões de vezes ao fim do ano. O subconjunto carrega só o que você usou.",[18,288,289,292],{},[35,290,291],{},"\"chromedp funciona\" é verdade e também é a resposta mais cara."," Se seu time já roda uma frota de Chrome headless para screenshots, pegar carona dela para PDFs está bem. Se não, subir uma só para imprimir 日本語 é muita infraestrutura para um problema de 40 linhas de Go.",[13,294,296],{"id":295},"o-caminho-mais-curto-que-funciona","O caminho mais curto que funciona",[18,298,299,300,303,304,42],{},"Comece com isto. É completo — copie, salve como ",[22,301,302],{},"main.go",", ponha dois TTFs ao lado, ",[22,305,306],{},"go run main.go",[308,309,314],"pre",{"className":310,"code":311,"language":312,"meta":313,"style":313},"language-go shiki shiki-themes material-theme-lighter material-theme material-theme-palenight","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    regular, err := os.ReadFile(\"NotoSansJP-Regular.ttf\")\n    if err != nil {\n        log.Fatal(err)\n    }\n    bold, err := os.ReadFile(\"NotoSansJP-Bold.ttf\")\n    if err != nil {\n        log.Fatal(err)\n    }\n\n    doc := gpdf.NewDocument(\n        gpdf.WithPageSize(document.A4),\n        gpdf.WithMargins(document.UniformEdges(document.Mm(20))),\n        gpdf.WithFont(\"NotoSansJP\", regular),\n        gpdf.WithFont(\"NotoSansJP-Bold\", bold),\n        gpdf.WithDefaultFont(\"NotoSansJP\", 11),\n    )\n\n    page := doc.AddPage()\n    page.AutoRow(func(r *template.RowBuilder) {\n        r.Col(12, func(c *template.ColBuilder) {\n            c.Text(\"請求書\", template.FontFamily(\"NotoSansJP-Bold\"), template.FontSize(22))\n            c.Text(\"2026 年 4 月 16 日\")\n        })\n    })\n    page.AutoRow(func(r *template.RowBuilder) {\n        r.Col(7, func(c *template.ColBuilder) {\n            c.Text(\"株式会社 ABC 御中\", template.FontSize(13))\n            c.Text(\"〒 100-0001 東京都千代田区千代田 1-1\")\n        })\n        r.Col(5, func(c *template.ColBuilder) {\n            c.Text(\"合計 ¥ 128,000\", template.FontFamily(\"NotoSansJP-Bold\"), template.AlignRight())\n            c.Text(\"支払期限: 2026-05-31\", template.AlignRight())\n        })\n    })\n\n    data, err := doc.Generate()\n    if err != nil {\n        log.Fatal(err)\n    }\n    if err := os.WriteFile(\"invoice-ja.pdf\", data, 0o644); err != nil {\n        log.Fatal(err)\n    }\n}\n","go","",[22,315,316,329,336,346,358,368,373,383,393,403,409,414,430,468,484,502,508,537,550,565,570,575,593,617,654,680,705,730,736,741,760,794,831,887,907,913,919,944,976,1009,1029,1034,1066,1112,1140,1145,1150,1155,1176,1189,1204,1209,1255,1270,1275],{"__ignoreMap":313},[317,318,321,325],"span",{"class":319,"line":320},"line",1,[317,322,324],{"class":323},"sMK4o","package",[317,326,328],{"class":327},"sBMFI"," main\n",[317,330,332],{"class":319,"line":331},2,[317,333,335],{"emptyLinePlaceholder":334},true,"\n",[317,337,339,343],{"class":319,"line":338},3,[317,340,342],{"class":341},"s7zQu","import",[317,344,345],{"class":323}," (\n",[317,347,349,352,355],{"class":319,"line":348},4,[317,350,351],{"class":323},"    \"",[317,353,354],{"class":327},"log",[317,356,357],{"class":323},"\"\n",[317,359,361,363,366],{"class":319,"line":360},5,[317,362,351],{"class":323},[317,364,365],{"class":327},"os",[317,367,357],{"class":323},[317,369,371],{"class":319,"line":370},6,[317,372,335],{"emptyLinePlaceholder":334},[317,374,376,378,381],{"class":319,"line":375},7,[317,377,351],{"class":323},[317,379,380],{"class":327},"github.com/gpdf-dev/gpdf",[317,382,357],{"class":323},[317,384,386,388,391],{"class":319,"line":385},8,[317,387,351],{"class":323},[317,389,390],{"class":327},"github.com/gpdf-dev/gpdf/document",[317,392,357],{"class":323},[317,394,396,398,401],{"class":319,"line":395},9,[317,397,351],{"class":323},[317,399,400],{"class":327},"github.com/gpdf-dev/gpdf/template",[317,402,357],{"class":323},[317,404,406],{"class":319,"line":405},10,[317,407,408],{"class":323},")\n",[317,410,412],{"class":319,"line":411},11,[317,413,335],{"emptyLinePlaceholder":334},[317,415,417,420,424,427],{"class":319,"line":416},12,[317,418,419],{"class":323},"func",[317,421,423],{"class":422},"s2Zo4"," main",[317,425,426],{"class":323},"()",[317,428,429],{"class":323}," {\n",[317,431,433,437,440,443,446,449,451,454,457,460,464,466],{"class":319,"line":432},13,[317,434,436],{"class":435},"sTEyZ","    regular",[317,438,439],{"class":323},",",[317,441,442],{"class":435}," err ",[317,444,445],{"class":323},":=",[317,447,448],{"class":435}," os",[317,450,42],{"class":323},[317,452,453],{"class":422},"ReadFile",[317,455,456],{"class":323},"(",[317,458,459],{"class":323},"\"",[317,461,463],{"class":462},"sfazB","NotoSansJP-Regular.ttf",[317,465,459],{"class":323},[317,467,408],{"class":323},[317,469,471,474,476,479,482],{"class":319,"line":470},14,[317,472,473],{"class":341},"    if",[317,475,442],{"class":435},[317,477,478],{"class":323},"!=",[317,480,481],{"class":323}," nil",[317,483,429],{"class":323},[317,485,487,490,492,495,497,500],{"class":319,"line":486},15,[317,488,489],{"class":435},"        log",[317,491,42],{"class":323},[317,493,494],{"class":422},"Fatal",[317,496,456],{"class":323},[317,498,499],{"class":435},"err",[317,501,408],{"class":323},[317,503,505],{"class":319,"line":504},16,[317,506,507],{"class":323},"    }\n",[317,509,511,514,516,518,520,522,524,526,528,530,533,535],{"class":319,"line":510},17,[317,512,513],{"class":435},"    bold",[317,515,439],{"class":323},[317,517,442],{"class":435},[317,519,445],{"class":323},[317,521,448],{"class":435},[317,523,42],{"class":323},[317,525,453],{"class":422},[317,527,456],{"class":323},[317,529,459],{"class":323},[317,531,532],{"class":462},"NotoSansJP-Bold.ttf",[317,534,459],{"class":323},[317,536,408],{"class":323},[317,538,540,542,544,546,548],{"class":319,"line":539},18,[317,541,473],{"class":341},[317,543,442],{"class":435},[317,545,478],{"class":323},[317,547,481],{"class":323},[317,549,429],{"class":323},[317,551,553,555,557,559,561,563],{"class":319,"line":552},19,[317,554,489],{"class":435},[317,556,42],{"class":323},[317,558,494],{"class":422},[317,560,456],{"class":323},[317,562,499],{"class":435},[317,564,408],{"class":323},[317,566,568],{"class":319,"line":567},20,[317,569,507],{"class":323},[317,571,573],{"class":319,"line":572},21,[317,574,335],{"emptyLinePlaceholder":334},[317,576,578,581,583,586,588,590],{"class":319,"line":577},22,[317,579,580],{"class":435},"    doc ",[317,582,445],{"class":323},[317,584,585],{"class":435}," gpdf",[317,587,42],{"class":323},[317,589,32],{"class":422},[317,591,592],{"class":323},"(\n",[317,594,596,599,601,604,606,609,611,614],{"class":319,"line":595},23,[317,597,598],{"class":435},"        gpdf",[317,600,42],{"class":323},[317,602,603],{"class":422},"WithPageSize",[317,605,456],{"class":323},[317,607,608],{"class":435},"document",[317,610,42],{"class":323},[317,612,613],{"class":435},"A4",[317,615,616],{"class":323},"),\n",[317,618,620,622,624,627,629,631,633,636,638,640,642,645,647,651],{"class":319,"line":619},24,[317,621,598],{"class":435},[317,623,42],{"class":323},[317,625,626],{"class":422},"WithMargins",[317,628,456],{"class":323},[317,630,608],{"class":435},[317,632,42],{"class":323},[317,634,635],{"class":422},"UniformEdges",[317,637,456],{"class":323},[317,639,608],{"class":435},[317,641,42],{"class":323},[317,643,644],{"class":422},"Mm",[317,646,456],{"class":323},[317,648,650],{"class":649},"sbssI","20",[317,652,653],{"class":323},"))),\n",[317,655,657,659,661,664,666,668,671,673,675,678],{"class":319,"line":656},25,[317,658,598],{"class":435},[317,660,42],{"class":323},[317,662,663],{"class":422},"WithFont",[317,665,456],{"class":323},[317,667,459],{"class":323},[317,669,670],{"class":462},"NotoSansJP",[317,672,459],{"class":323},[317,674,439],{"class":323},[317,676,677],{"class":435}," regular",[317,679,616],{"class":323},[317,681,683,685,687,689,691,693,696,698,700,703],{"class":319,"line":682},26,[317,684,598],{"class":435},[317,686,42],{"class":323},[317,688,663],{"class":422},[317,690,456],{"class":323},[317,692,459],{"class":323},[317,694,695],{"class":462},"NotoSansJP-Bold",[317,697,459],{"class":323},[317,699,439],{"class":323},[317,701,702],{"class":435}," bold",[317,704,616],{"class":323},[317,706,708,710,712,715,717,719,721,723,725,728],{"class":319,"line":707},27,[317,709,598],{"class":435},[317,711,42],{"class":323},[317,713,714],{"class":422},"WithDefaultFont",[317,716,456],{"class":323},[317,718,459],{"class":323},[317,720,670],{"class":462},[317,722,459],{"class":323},[317,724,439],{"class":323},[317,726,727],{"class":649}," 11",[317,729,616],{"class":323},[317,731,733],{"class":319,"line":732},28,[317,734,735],{"class":323},"    )\n",[317,737,739],{"class":319,"line":738},29,[317,740,335],{"emptyLinePlaceholder":334},[317,742,744,747,749,752,754,757],{"class":319,"line":743},30,[317,745,746],{"class":435},"    page ",[317,748,445],{"class":323},[317,750,751],{"class":435}," doc",[317,753,42],{"class":323},[317,755,756],{"class":422},"AddPage",[317,758,759],{"class":323},"()\n",[317,761,763,766,768,771,774,778,781,784,786,789,792],{"class":319,"line":762},31,[317,764,765],{"class":435},"    page",[317,767,42],{"class":323},[317,769,770],{"class":422},"AutoRow",[317,772,773],{"class":323},"(func(",[317,775,777],{"class":776},"sHdIc","r",[317,779,780],{"class":323}," *",[317,782,783],{"class":327},"template",[317,785,42],{"class":323},[317,787,788],{"class":327},"RowBuilder",[317,790,791],{"class":323},")",[317,793,429],{"class":323},[317,795,797,800,802,805,807,810,812,815,818,820,822,824,827,829],{"class":319,"line":796},32,[317,798,799],{"class":435},"        r",[317,801,42],{"class":323},[317,803,804],{"class":422},"Col",[317,806,456],{"class":323},[317,808,809],{"class":649},"12",[317,811,439],{"class":323},[317,813,814],{"class":323}," func(",[317,816,817],{"class":776},"c",[317,819,780],{"class":323},[317,821,783],{"class":327},[317,823,42],{"class":323},[317,825,826],{"class":327},"ColBuilder",[317,828,791],{"class":323},[317,830,429],{"class":323},[317,832,834,837,839,842,844,846,849,851,853,856,858,861,863,865,867,869,872,874,876,879,881,884],{"class":319,"line":833},33,[317,835,836],{"class":435},"            c",[317,838,42],{"class":323},[317,840,841],{"class":422},"Text",[317,843,456],{"class":323},[317,845,459],{"class":323},[317,847,848],{"class":462},"請求書",[317,850,459],{"class":323},[317,852,439],{"class":323},[317,854,855],{"class":435}," template",[317,857,42],{"class":323},[317,859,860],{"class":422},"FontFamily",[317,862,456],{"class":323},[317,864,459],{"class":323},[317,866,695],{"class":462},[317,868,459],{"class":323},[317,870,871],{"class":323},"),",[317,873,855],{"class":435},[317,875,42],{"class":323},[317,877,878],{"class":422},"FontSize",[317,880,456],{"class":323},[317,882,883],{"class":649},"22",[317,885,886],{"class":323},"))\n",[317,888,890,892,894,896,898,900,903,905],{"class":319,"line":889},34,[317,891,836],{"class":435},[317,893,42],{"class":323},[317,895,841],{"class":422},[317,897,456],{"class":323},[317,899,459],{"class":323},[317,901,902],{"class":462},"2026 年 4 月 16 日",[317,904,459],{"class":323},[317,906,408],{"class":323},[317,908,910],{"class":319,"line":909},35,[317,911,912],{"class":323},"        })\n",[317,914,916],{"class":319,"line":915},36,[317,917,918],{"class":323},"    })\n",[317,920,922,924,926,928,930,932,934,936,938,940,942],{"class":319,"line":921},37,[317,923,765],{"class":435},[317,925,42],{"class":323},[317,927,770],{"class":422},[317,929,773],{"class":323},[317,931,777],{"class":776},[317,933,780],{"class":323},[317,935,783],{"class":327},[317,937,42],{"class":323},[317,939,788],{"class":327},[317,941,791],{"class":323},[317,943,429],{"class":323},[317,945,947,949,951,953,955,958,960,962,964,966,968,970,972,974],{"class":319,"line":946},38,[317,948,799],{"class":435},[317,950,42],{"class":323},[317,952,804],{"class":422},[317,954,456],{"class":323},[317,956,957],{"class":649},"7",[317,959,439],{"class":323},[317,961,814],{"class":323},[317,963,817],{"class":776},[317,965,780],{"class":323},[317,967,783],{"class":327},[317,969,42],{"class":323},[317,971,826],{"class":327},[317,973,791],{"class":323},[317,975,429],{"class":323},[317,977,979,981,983,985,987,989,992,994,996,998,1000,1002,1004,1007],{"class":319,"line":978},39,[317,980,836],{"class":435},[317,982,42],{"class":323},[317,984,841],{"class":422},[317,986,456],{"class":323},[317,988,459],{"class":323},[317,990,991],{"class":462},"株式会社 ABC 御中",[317,993,459],{"class":323},[317,995,439],{"class":323},[317,997,855],{"class":435},[317,999,42],{"class":323},[317,1001,878],{"class":422},[317,1003,456],{"class":323},[317,1005,1006],{"class":649},"13",[317,1008,886],{"class":323},[317,1010,1012,1014,1016,1018,1020,1022,1025,1027],{"class":319,"line":1011},40,[317,1013,836],{"class":435},[317,1015,42],{"class":323},[317,1017,841],{"class":422},[317,1019,456],{"class":323},[317,1021,459],{"class":323},[317,1023,1024],{"class":462},"〒 100-0001 東京都千代田区千代田 1-1",[317,1026,459],{"class":323},[317,1028,408],{"class":323},[317,1030,1032],{"class":319,"line":1031},41,[317,1033,912],{"class":323},[317,1035,1037,1039,1041,1043,1045,1048,1050,1052,1054,1056,1058,1060,1062,1064],{"class":319,"line":1036},42,[317,1038,799],{"class":435},[317,1040,42],{"class":323},[317,1042,804],{"class":422},[317,1044,456],{"class":323},[317,1046,1047],{"class":649},"5",[317,1049,439],{"class":323},[317,1051,814],{"class":323},[317,1053,817],{"class":776},[317,1055,780],{"class":323},[317,1057,783],{"class":327},[317,1059,42],{"class":323},[317,1061,826],{"class":327},[317,1063,791],{"class":323},[317,1065,429],{"class":323},[317,1067,1069,1071,1073,1075,1077,1079,1082,1084,1086,1088,1090,1092,1094,1096,1098,1100,1102,1104,1106,1109],{"class":319,"line":1068},43,[317,1070,836],{"class":435},[317,1072,42],{"class":323},[317,1074,841],{"class":422},[317,1076,456],{"class":323},[317,1078,459],{"class":323},[317,1080,1081],{"class":462},"合計 ¥ 128,000",[317,1083,459],{"class":323},[317,1085,439],{"class":323},[317,1087,855],{"class":435},[317,1089,42],{"class":323},[317,1091,860],{"class":422},[317,1093,456],{"class":323},[317,1095,459],{"class":323},[317,1097,695],{"class":462},[317,1099,459],{"class":323},[317,1101,871],{"class":323},[317,1103,855],{"class":435},[317,1105,42],{"class":323},[317,1107,1108],{"class":422},"AlignRight",[317,1110,1111],{"class":323},"())\n",[317,1113,1115,1117,1119,1121,1123,1125,1128,1130,1132,1134,1136,1138],{"class":319,"line":1114},44,[317,1116,836],{"class":435},[317,1118,42],{"class":323},[317,1120,841],{"class":422},[317,1122,456],{"class":323},[317,1124,459],{"class":323},[317,1126,1127],{"class":462},"支払期限: 2026-05-31",[317,1129,459],{"class":323},[317,1131,439],{"class":323},[317,1133,855],{"class":435},[317,1135,42],{"class":323},[317,1137,1108],{"class":422},[317,1139,1111],{"class":323},[317,1141,1143],{"class":319,"line":1142},45,[317,1144,912],{"class":323},[317,1146,1148],{"class":319,"line":1147},46,[317,1149,918],{"class":323},[317,1151,1153],{"class":319,"line":1152},47,[317,1154,335],{"emptyLinePlaceholder":334},[317,1156,1158,1161,1163,1165,1167,1169,1171,1174],{"class":319,"line":1157},48,[317,1159,1160],{"class":435},"    data",[317,1162,439],{"class":323},[317,1164,442],{"class":435},[317,1166,445],{"class":323},[317,1168,751],{"class":435},[317,1170,42],{"class":323},[317,1172,1173],{"class":422},"Generate",[317,1175,759],{"class":323},[317,1177,1179,1181,1183,1185,1187],{"class":319,"line":1178},49,[317,1180,473],{"class":341},[317,1182,442],{"class":435},[317,1184,478],{"class":323},[317,1186,481],{"class":323},[317,1188,429],{"class":323},[317,1190,1192,1194,1196,1198,1200,1202],{"class":319,"line":1191},50,[317,1193,489],{"class":435},[317,1195,42],{"class":323},[317,1197,494],{"class":422},[317,1199,456],{"class":323},[317,1201,499],{"class":435},[317,1203,408],{"class":323},[317,1205,1207],{"class":319,"line":1206},51,[317,1208,507],{"class":323},[317,1210,1212,1214,1216,1218,1220,1222,1225,1227,1229,1232,1234,1236,1239,1241,1244,1247,1249,1251,1253],{"class":319,"line":1211},52,[317,1213,473],{"class":341},[317,1215,442],{"class":435},[317,1217,445],{"class":323},[317,1219,448],{"class":435},[317,1221,42],{"class":323},[317,1223,1224],{"class":422},"WriteFile",[317,1226,456],{"class":323},[317,1228,459],{"class":323},[317,1230,1231],{"class":462},"invoice-ja.pdf",[317,1233,459],{"class":323},[317,1235,439],{"class":323},[317,1237,1238],{"class":435}," data",[317,1240,439],{"class":323},[317,1242,1243],{"class":649}," 0o644",[317,1245,1246],{"class":323},");",[317,1248,442],{"class":435},[317,1250,478],{"class":323},[317,1252,481],{"class":323},[317,1254,429],{"class":323},[317,1256,1258,1260,1262,1264,1266,1268],{"class":319,"line":1257},53,[317,1259,489],{"class":435},[317,1261,42],{"class":323},[317,1263,494],{"class":422},[317,1265,456],{"class":323},[317,1267,499],{"class":435},[317,1269,408],{"class":323},[317,1271,1273],{"class":319,"line":1272},54,[317,1274,507],{"class":323},[317,1276,1278],{"class":319,"line":1277},55,[317,1279,1280],{"class":323},"}\n",[18,1282,1283],{},"Coisas que vale notar sem narrar cada uma:",[1285,1286,1287,1305,1314,1331],"ul",{},[86,1288,1289,1297,1298,1300,1301,1304],{},[35,1290,1291,1292,1294,1295,42],{},"Sem ",[22,1293,55],{},", sem flag UTF-8, sem argumento de caminho de fonte para ",[22,1296,841],{}," ",[22,1299,28],{}," registra uma família; ",[22,1302,1303],{},"c.Text"," só escreve Unicode. O encanamento fica interno.",[86,1306,1307,1310,1311,1313],{},[35,1308,1309],{},"Negrito é uma família à parte, não uma flag."," Isso combina com a forma como os TTFs são distribuídos (Noto Sans JP Regular e Noto Sans JP Bold são arquivos distintos com tabelas ",[22,1312,116],{}," diferentes). As variantes Gothic/Mincho, ou Source Han Sans JP Normal/Heavy, seguem o mesmo padrão.",[86,1315,1316,1297,1319,131,1322,1325,1326,42],{},[35,1317,1318],{},"Layout é grid, não cursor.",[22,1320,1321],{},"r.Col(7, ...)",[22,1323,1324],{},"r.Col(5, ...)"," somam 12. As larguras são declarativas; você não calcula coordenadas x. Mais em ",[1327,1328,1330],"a",{"href":1329},"/pt/blog/12-column-grid","Como funciona a grid de 12 colunas no gpdf",[86,1332,1333,1339],{},[35,1334,1335,1338],{},[22,1336,1337],{},"AlignRight()"," é agnóstico de locale."," O japonês \"¥ 128,000\" alinha à direita do mesmo jeito que \"R$ 1.280,00\" alinharia. O conteúdo do texto não muda o código de layout.",[18,1341,1342,1343,1345,1346,1348],{},"Abra o ",[22,1344,1231],{}," resultante em qualquer leitor. Selecione \"株式会社 ABC 御中\". Cole num editor de texto. Você obtém ",[22,1347,991],{},", não uma bagunça. Isso é o ToUnicode CMap trabalhando; gpdf escreve um por padrão.",[13,1350,1352],{"id":1351},"subconjunto-de-fontes-a-bomba-de-tamanho-escondida","Subconjunto de fontes: a bomba de tamanho escondida",[18,1354,1355,1356,42],{},"Aqui vai a propriedade mais importante de CJK-em-PDF que os tutoriais pulam: ",[35,1357,1358],{},"embutir por subconjunto",[18,1360,1361],{},"Uma fonte TTF é uma coleção de contornos de glifo mais tabelas de metadados. Noto Sans JP Regular traz cerca de 17.500 glifos e pesa 5,1 MB. Uma fatura típica usa entre 60 e 200 caracteres japoneses únicos. Embutir a fonte completa em cada documento é desperdício de uma ordem de magnitude.",[18,1363,1364],{},"Embutir por subconjunto mantém só os glifos que você usou. gpdf faz isso automaticamente. Você pode ver isso rodando o exemplo acima:",[308,1366,1370],{"className":1367,"code":1368,"language":1369,"meta":313,"style":313},"language-bash shiki shiki-themes material-theme-lighter material-theme material-theme-palenight","$ ls -l invoice-ja.pdf\n-rw-r--r--  1 dev  staff  34892 Apr 16 10:12 invoice-ja.pdf\n","bash",[22,1371,1372,1386],{"__ignoreMap":313},[317,1373,1374,1377,1380,1383],{"class":319,"line":320},[317,1375,1376],{"class":327},"$",[317,1378,1379],{"class":462}," ls",[317,1381,1382],{"class":462}," -l",[317,1384,1385],{"class":462}," invoice-ja.pdf\n",[317,1387,1388,1391,1394,1397,1400,1403,1406,1409,1412],{"class":319,"line":331},[317,1389,1390],{"class":327},"-rw-r--r--",[317,1392,1393],{"class":649},"  1",[317,1395,1396],{"class":462}," dev",[317,1398,1399],{"class":462},"  staff",[317,1401,1402],{"class":649},"  34892",[317,1404,1405],{"class":462}," Apr",[317,1407,1408],{"class":649}," 16",[317,1410,1411],{"class":462}," 10:12",[317,1413,1385],{"class":462},[18,1415,1416,1417,131,1419,1422,1423,1426],{},"34 KB. Para comparar, o mesmo documento gerado com ",[22,1418,134],{},[22,1420,1421],{},"AddUTF8Font(\"NotoSansJP\", \"NotoSansJP-Regular.ttf\", true)"," — onde o terceiro argumento é a flag UTF-8 — dá ",[35,1424,1425],{},"4,9 MB",". Mesma entrada, mesmo texto de saída, arquivo 143× maior. O motivo é que o caminho de código do fpdf embute a tabela inteira da fonte em vez de fazer subconjunto no momento do emit.",[18,1428,1429],{},"Algumas consequências que vale nomear:",[1285,1431,1432,1443,1449],{},[86,1433,1434,1435,1438,1439,1442],{},"A ",[35,1436,1437],{},"10 faturas por segundo"," (escala SaaS normal), a diferença de subconjunto é a diferença entre ",[35,1440,1441],{},"0,3 MB/s e 43 MB/s"," de bytes PDF de saída. Seu load balancer tem opinião sobre isso.",[86,1444,1445,1448],{},[35,1446,1447],{},"Contas de cold storage"," escalam linearmente com o tamanho do PDF. Cinco milhões de faturas arquivadas a 5 MB cada dão 25 TB. A 30 KB cada, 150 GB. Preço de object storage faz disso uma linha mensal de quatro dígitos contra dois.",[86,1450,1451,1454],{},[35,1452,1453],{},"Entrega por email"," tem limites de anexo de 10–25 MB dependendo do provedor. Uma fatura japonesa de 5 MB mais qualquer outro anexo mais a codificação MIME começa a bater nesse teto.",[18,1456,1457,1458,117,1461,117,1464,131,1467,1470],{},"gpdf faz o subconjunto em tempo de render. Não há flag para ligar. Você pode ver quais glifos foram parar na saída rodando a ferramenta de verificação do gpdf localmente, mas a versão curta é: se você usou ",[22,1459,1460],{},"株",[22,1462,1463],{},"式",[22,1465,1466],{},"会",[22,1468,1469],{},"社",", esses quatro glifos estão na saída e os outros 17.496 não.",[13,1472,1474],{"id":1473},"escritas-mistas-kanji-kana-ascii-na-mesma-linha","Escritas mistas: kanji + kana + ASCII na mesma linha",[18,1476,1477],{},"Texto japonês raramente é só japonês. Uma linha real num documento japonês parece com isto:",[308,1479,1484],{"className":1480,"code":1482,"language":1483},[1481],"language-text","API の P95 レイテンシは 50 ms 未満です。\n","text",[22,1485,1482],{"__ignoreMap":313},[18,1487,1488],{},"São cinco escritas: romaji (ASCII Latin), katakana, hiragana, kanji (Han) e numerais. Uma implementação ingênua escolhe a fonte errada para as partes ASCII e você fica com um \"API\" monoespaçado ao lado de japonês proporcional, o que fica horrível.",[18,1490,1491,1492,1495,1496,131,1499,1502],{},"O comportamento padrão do gpdf é ",[35,1493,1494],{},"renderizar cada code point com a família registrada",". Se Noto Sans JP é seu padrão, ",[22,1497,1498],{},"API",[22,1500,1501],{},"50 ms"," são desenhados com os glifos Latin da Noto Sans JP, que a Noto fornece (a maioria das superfamílias japonesas fornece). O resultado parece uma única tipografia, porque é.",[18,1504,1505,1506,1508],{},"Se você quer misturar famílias deliberadamente — por exemplo, uma sans condensada para ASCII e Noto Sans JP para japonês — registre as duas e sobrescreva por chamada de ",[22,1507,1303],{},":",[308,1510,1512],{"className":310,"code":1511,"language":312,"meta":313,"style":313},"c.Text(\"API の P95 レイテンシは 50 ms 未満です。\",\n    template.FontFamily(\"NotoSansJP\"))\nc.Text(\"API latency (P95) is under 50 ms.\",\n    template.FontFamily(\"InterVariable\"))\n",[22,1513,1514,1534,1553,1572],{"__ignoreMap":313},[317,1515,1516,1518,1520,1522,1524,1526,1529,1531],{"class":319,"line":320},[317,1517,817],{"class":435},[317,1519,42],{"class":323},[317,1521,841],{"class":422},[317,1523,456],{"class":323},[317,1525,459],{"class":323},[317,1527,1528],{"class":462},"API の P95 レイテンシは 50 ms 未満です。",[317,1530,459],{"class":323},[317,1532,1533],{"class":323},",\n",[317,1535,1536,1539,1541,1543,1545,1547,1549,1551],{"class":319,"line":331},[317,1537,1538],{"class":435},"    template",[317,1540,42],{"class":323},[317,1542,860],{"class":422},[317,1544,456],{"class":323},[317,1546,459],{"class":323},[317,1548,670],{"class":462},[317,1550,459],{"class":323},[317,1552,886],{"class":323},[317,1554,1555,1557,1559,1561,1563,1565,1568,1570],{"class":319,"line":338},[317,1556,817],{"class":435},[317,1558,42],{"class":323},[317,1560,841],{"class":422},[317,1562,456],{"class":323},[317,1564,459],{"class":323},[317,1566,1567],{"class":462},"API latency (P95) is under 50 ms.",[317,1569,459],{"class":323},[317,1571,1533],{"class":323},[317,1573,1574,1576,1578,1580,1582,1584,1587,1589],{"class":319,"line":348},[317,1575,1538],{"class":435},[317,1577,42],{"class":323},[317,1579,860],{"class":422},[317,1581,456],{"class":323},[317,1583,459],{"class":323},[317,1585,1586],{"class":462},"InterVariable",[317,1588,459],{"class":323},[317,1590,886],{"class":323},[18,1592,1593,1594,1596,1597,1601],{},"Duas ",[22,1595,1303],{},", duas famílias, zero lógica de detecção de escrita no seu código. Se precisar de mistura intra-linha (Inter para ASCII + Noto para japonês na ",[1598,1599,1600],"em",{},"mesma"," frase), vem no gpdf v1.2; hoje o workaround é quebrar nas fronteiras de escrita manualmente e dispor numa linha horizontal de colunas.",[13,1603,1605],{"id":1604},"o-que-ainda-dói","O que ainda dói",[18,1607,1608],{},"A história do PDF japonês em Go está 95% resolvida. Aqui estão os 5%.",[18,1610,1611,1614,1615,42],{},[35,1612,1613],{},"Texto vertical (縦書き) ainda não está lá."," gpdf renderiza só texto horizontal em v1.x. A diagramação japonesa tradicional — colunas da direita para a esquerda, caracteres de cima para baixo, com a rotação apropriada de glifos e reposicionamento de pontuação — é uma mudança profunda do motor de layout, não um ajuste de renderização. A issue aberta tem uma proposta de design; vai aterrissar quando aterrissar. Por enquanto, se você precisa de 縦書き para livros ou correspondência formal, gere com uma ferramenta que suporta (Word, InDesign ou um pipeline pandoc + LuaLaTeX) e embuta o PDF resultante com ",[22,1616,1617],{},"gpdf.Merge",[18,1619,1620,1623,1624,1627],{},[35,1621,1622],{},"Anotações ruby (振り仮名) são só workaround."," Não há primitiva ",[22,1625,1626],{},"c.Ruby(\"漢字\", \"かんじ\")",". Se você precisa de ruby para conteúdo infantil ou livros de língua, o workaround é uma coluna de duas linhas: texto kana pequeno em cima, kanji normal embaixo, alinhados. Funciona, mas é manual, e o kerning fino nas fronteiras de furigana exige cuidado.",[18,1629,1630,1633,1634,117,1637,117,1640,1643,1644,1646,1647,1651],{},[35,1631,1632],{},"Fallbacks complexos entre múltiplas fontes CJK."," Se um usuário submete texto que mistura kanji japonês com caracteres só chineses (as formas diferem — ",[22,1635,1636],{},"直",[22,1638,1639],{},"骨",[22,1641,1642],{},"角"," renderizam sutilmente diferentes em CN vs JP), você precisa partir manualmente e usar duas famílias. O gpdf não faz auto-fallback entre famílias dentro de uma única chamada de ",[22,1645,1303],{},". Na prática muito poucos documentos precisam disso; se o seu precisa, veja ",[1327,1648,1650],{"href":1649},"/pt/blog/","PDFs multilíngues: misturando JP/CN/KR/EN"," (B-070 pendente).",[18,1653,1654,1657,1658,1661,1662,1665],{},[35,1655,1656],{},"Conformidade PDF/A-2b estrita com japonês."," gpdf produz saída PDF/A via ",[22,1659,1660],{},"gpdf.WithPDFA",", mas os requisitos estritos sobre metadados de glifos embutidos, o span ",[22,1663,1664],{},"ActualText"," em cada run CJK, e árvores de estrutura etiquetadas ainda estão sendo afinados para o caso CJK. Se você está exportando para arquivamento de longo prazo para atender à NFe, ao DANFE ou ao PDF/A-3b brasileiro (ou à 電子帳簿保存法 japonesa), valide com uma ferramenta de terceiros (veraPDF é grátis) antes de committar.",[18,1667,1668],{},"Nenhum desses é bloqueio para os casos comuns: faturas, relatórios, extratos, recibos, certificados. Vale nomear porque alguém lendo isto está prestes a encontrar um em produção, e \"está no roadmap\" é menos útil que \"aqui está o workaround\".",[13,1670,1672],{"id":1671},"uma-palavra-sobre-conformidade","Uma palavra sobre conformidade",[18,1674,1675,1676,1679],{},"Um pedaço de contexto de ecossistema que costuma ficar não dito: ",[35,1677,1678],{},"gerar PDFs japoneses em 2026 não é só problema tipográfico."," Duas mudanças regulatórias o empurram para a conversa de conformidade.",[18,1681,1682,1683,1686],{},"O regime ",[35,1684,1685],{},"適格請求書 (nota fiscal qualificada)"," sob a reforma do imposto de consumo exige que as notas incluam campos específicos (número de negócio registrado, alíquota aplicável, detalhamento) e que sejam retidas de forma à prova de adulteração. PDFs são o formato padrão para isso, e \"à prova de adulteração\" mapeia para assinaturas digitais PDF — PAdES-B-LT no caso estrito.",[18,1688,1434,1689,1692],{},[35,1690,1691],{},"電子帳簿保存法 (lei de armazenamento eletrônico de livros)",", revisada em 2024, estendeu mandatos de retenção para incluir notas armazenadas em forma eletrônica. PDFs arquivados precisam atender a certos requisitos de integridade. PDF/A-2b ou PDF/A-3b são o formato-alvo de fato. No Brasil, a NFe requer assinatura digital ICP-Brasil e PDF/A-3 para a DANFE arquivada — a mesma classe de requisito.",[18,1694,1695,1696,1699,1700,1703,1704,1706],{},"Ambos os requisitos se apoiam em ",[35,1697,1698],{},"recursos nativos do PDF"," — assinaturas, validação de longo prazo, metadados PDF/A embutidos. HTML-para-PDF via navegador headless não atende a nenhum limpamente: a saída PDF do Chromium não é compatível com PDF/A e não consegue embutir assinaturas digitais num único passo. Um stack Go nativo (gpdf + ",[22,1701,1702],{},"gpdf/signature"," para PAdES + ",[22,1705,1660],{},") faz a cadeia toda num pipeline sem sair do processo.",[18,1708,1709],{},"Isto é um sinal para posts futuros em vez de um mergulho profundo — assinatura e PDF/A merecem cada um seu próprio artigo hero (são B-067 e B-068 no backlog). Mas se você está escolhendo um stack de PDF japonês hoje e conformidade está no seu radar, escolha um stack que possa fazer assinaturas e PDF/A nativamente. O imposto de migração de \"funciona hoje\" para \"passa na auditoria\" é real.",[13,1711,1713],{"id":1712},"faq","FAQ",[18,1715,1716,1719,1720,1723,1724,1727,1728,1731,1732,1735,1736,42],{},[35,1717,1718],{},"Preciso instalar fontes no servidor ou no container?","\nNão. gpdf lê bytes TTF; não passa pelo cache de fontes do sistema. ",[22,1721,1722],{},"os.ReadFile(\"NotoSansJP-Regular.ttf\")"," ou ",[22,1725,1726],{},"//go:embed NotoSansJP-Regular.ttf"," funciona igual em macOS, Linux e Windows, dentro de um container distroless, e em AWS Lambda. Sem ",[22,1729,1730],{},"fontconfig",", sem ",[22,1733,1734],{},"fc-cache -fv",". Essa é uma das razões do gpdf funcionar em imagens ",[22,1737,1738],{},"FROM scratch",[18,1740,1741,1744],{},[35,1742,1743],{},"Noto Sans JP vs Source Han Sans JP — faz diferença?","\nSão a mesma família de fonte sob dois nomes. A Adobe publica Source Han Sans JP; o Google reempacota como Noto Sans JP. Cobertura de glifos idêntica. Escolha a distribuição de licença que passar na sua revisão jurídica; ambas são SIL Open Font License. Para documentação neutra de marca usamos Noto Sans JP por padrão porque os nomes de arquivo são mais fáceis de lembrar.",[18,1746,1747,1750],{},[35,1748,1749],{},"E 游ゴシック (Yu Gothic) ou Hiragino?","\nFontes proprietárias que vêm com o SO. Você pode usá-las se seu alvo de deploy tem licença (Windows Server traz Yu Gothic; macOS traz Hiragino), mas vai precisar pegar o arquivo TTF e confirmar os termos de redistribuição para seu build de container. Para deploys abertos, fique com Noto Sans JP ou IPAex Gothic (ambas de redistribuição livre).",[18,1752,1753,1760,1761,1764],{},[35,1754,1755,1756,1759],{},"O PDF renderiza mas ",[22,1757,1758],{},"Ctrl+F"," não acha nada. Por quê?","\nQuase sempre é problema de ToUnicode CMap. gpdf escreve um automaticamente, então se você vê isso com gpdf, abra uma issue com o nome do leitor. Se vê com gofpdf, o conserto é ligar a flag UTF-8 ",[1598,1762,1763],{},"e"," garantir que o leitor suporta fontes CID — versões antigas do Preview.app no macOS têm issues conhecidos. Teste com Adobe Reader ou Chrome como controle.",[18,1766,1767,1770,1771,1774],{},[35,1768,1769],{},"Como adiciono um caractere JIS X 0213 que não está na fonte?","\nNão tem como — não há glifo para desenhar. A resposta prática é \"use uma fonte que cubra JIS X 0213\". Noto Sans JP cobre o BMP completo mais JIS X 0213 Nível 1. Para variantes históricas raras, Hanazono Mincho (花園明朝) é o fallback final. Se um code point não está em nenhuma fonte, gpdf emite o caractere de substituição Unicode (U+FFFD) em vez de um tofu silencioso — então você vê ",[22,1772,1773],{},"�"," na saída e sabe que precisa investigar.",[18,1776,1777,1780,1781,1783],{},[35,1778,1779],{},"Tem custo de performance entre CJK e ASCII?","\nPequeno. O benchmark do gpdf para \"fatura CJK complexa\" é 133 µs por documento num Apple M1, vs 108 µs para uma tabela ASCII 4×10. São ~23% de overhead, quase todo do trabalho maior de lookup de glifo e subconjunto. Para referência, ",[22,1782,134],{}," no mesmo benchmark CJK é 254 µs, e Maroto v2 é 10,4 ms. Renderização japonesa não é o gargalo no seu serviço.",[13,1785,1787],{"id":1786},"experimente-o-gpdf","Experimente o gpdf",[18,1789,1790],{},"gpdf é uma biblioteca Go para gerar PDFs. MIT, zero dependências externas, CJK nativo.",[308,1792,1794],{"className":1367,"code":1793,"language":1369,"meta":313,"style":313},"go get github.com/gpdf-dev/gpdf\n",[22,1795,1796],{"__ignoreMap":313},[317,1797,1798,1800,1803],{"class":319,"line":320},[317,1799,312],{"class":327},[317,1801,1802],{"class":462}," get",[317,1804,1805],{"class":462}," github.com/gpdf-dev/gpdf\n",[18,1807,1808,1814,1815],{},[1327,1809,1813],{"href":1810,"rel":1811},"https://github.com/gpdf-dev/gpdf",[1812],"nofollow","⭐ Star no GitHub"," · ",[1327,1816,1819],{"href":1817,"rel":1818},"https://gpdf.dev/pt/docs/quickstart",[1812],"Leia a documentação",[13,1821,1823],{"id":1822},"próximas-leituras","Próximas leituras",[1285,1825,1826,1833,1840,1846],{},[86,1827,1828,1832],{},[1327,1829,1831],{"href":1830},"/pt/blog/embed-japanese-font","Como embuto uma fonte japonesa no gpdf?"," — a receita de três linhas sem o contexto",[86,1834,1835,1839],{},[1327,1836,1838],{"href":1837},"/pt/blog/noto-sans-jp-with-gpdf","Como uso Noto Sans JP com gpdf?"," — configuração de pesos Regular / Bold / Medium",[86,1841,1842,1845],{},[1327,1843,1844],{"href":1329},"Como funciona a grid de 12 colunas no gpdf?"," — o idioma de layout que substitui empurrar o cursor",[86,1847,1848,1852],{},[1327,1849,1851],{"href":1850},"/pt/blog/go-pdf-fpdf-archived","go-pdf/fpdf também foi arquivada. O stack Go PDF moderno."," — o panorama mais amplo de 2026",[1854,1855,1856],"style",{},"html pre.shiki code .sMK4o, html code.shiki .sMK4o{--shiki-light:#39ADB5;--shiki-default:#89DDFF;--shiki-dark:#89DDFF}html pre.shiki code .sBMFI, html code.shiki .sBMFI{--shiki-light:#E2931D;--shiki-default:#FFCB6B;--shiki-dark:#FFCB6B}html pre.shiki code .s7zQu, html code.shiki .s7zQu{--shiki-light:#39ADB5;--shiki-light-font-style:italic;--shiki-default:#89DDFF;--shiki-default-font-style:italic;--shiki-dark:#89DDFF;--shiki-dark-font-style:italic}html pre.shiki code .s2Zo4, html code.shiki .s2Zo4{--shiki-light:#6182B8;--shiki-default:#82AAFF;--shiki-dark:#82AAFF}html pre.shiki code .sTEyZ, html code.shiki .sTEyZ{--shiki-light:#90A4AE;--shiki-default:#EEFFFF;--shiki-dark:#BABED8}html pre.shiki code .sfazB, html code.shiki .sfazB{--shiki-light:#91B859;--shiki-default:#C3E88D;--shiki-dark:#C3E88D}html pre.shiki code .sbssI, html code.shiki .sbssI{--shiki-light:#F76D47;--shiki-default:#F78C6C;--shiki-dark:#F78C6C}html 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 .light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html.light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html.dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}",{"title":313,"searchDepth":331,"depth":331,"links":1858},[1859,1860,1861,1862,1863,1864,1865,1866,1867,1868,1869,1870],{"id":15,"depth":331,"text":16},{"id":45,"depth":331,"text":46},{"id":69,"depth":331,"text":70},{"id":144,"depth":331,"text":145},{"id":295,"depth":331,"text":296},{"id":1351,"depth":331,"text":1352},{"id":1473,"depth":331,"text":1474},{"id":1604,"depth":331,"text":1605},{"id":1671,"depth":331,"text":1672},{"id":1712,"depth":331,"text":1713},{"id":1786,"depth":331,"text":1787},{"id":1822,"depth":331,"text":1823},"2026-04-16","Como gerar PDFs em japonês com Go em 2026 — fontes, subconjuntos TrueType, kanji/kana/ASCII misturados, e por que não precisa de CGO nem Chromium.",false,"md",{"name":1876,"totalTime":1877,"tools":1878,"steps":1881},"Gerar um PDF em japonês com Go usando subconjunto TrueType nativo","PT20M",[1879,1880],"Go 1.22+","NotoSansJP-Regular.ttf e NotoSansJP-Bold.ttf (ou qualquer par TTF capaz de CJK)",[1882,1885,1888,1891,1894,1897],{"name":1883,"text":1884},"Instalar gpdf e baixar as fontes","Execute go get github.com/gpdf-dev/gpdf. Baixe Noto Sans JP Regular e Bold do Google Fonts e coloque os TTFs ao lado de main.go. Sem CGO, sem configuração de fontes do sistema.",{"name":1886,"text":1887},"Carregar os bytes TTF na inicialização","Leia os dois arquivos TTF com os.ReadFile para buffers []byte. //go:embed funciona se você quiser compilar as fontes dentro do binário.",{"name":1889,"text":1890},"Registrar as fontes na construção do documento","Passe gpdf.WithFont(\"NotoSansJP\", regular) e gpdf.WithFont(\"NotoSansJP-Bold\", bold) para gpdf.NewDocument. O nome da família é um identificador arbitrário — é o handle que você referenciará depois.",{"name":1892,"text":1893},"Definir a fonte japonesa como padrão","Adicione gpdf.WithDefaultFont(\"NotoSansJP\", 11). Cada c.Text usará a fonte japonesa sem uma opção FontFamily explícita.",{"name":1895,"text":1896},"Construir a árvore do documento com c.Text","Dentro de um bloco page.AutoRow, chame r.Col(span, fn) e c.Text(\"こんにちは、世界。\"). Negrito e tamanho são opções de template, não métodos separados.",{"name":1898,"text":1899},"Gerar e inspecionar a saída","Chame doc.Generate() para obter []byte, escreva em disco com os.WriteFile. Abra o PDF, selecione o texto, cole num editor — o ToUnicode CMap garante que copiar e colar funcione.",null,{},"/pt/blog/japanese-pdf-in-go",{"title":5,"description":1872},"pt/blog/007.japanese-pdf-in-go",[1906,1907,1908],"tutorial","cjk","troubleshooting","r4clWad079eCB2emSAwP1ORJir7WBOcVJncNL8Jyz_c",1776529275935]