[{"data":1,"prerenderedAt":1423},["ShallowReactive",2],{"blog-ja-table-column-widths":3},{"id":4,"title":5,"author":6,"body":10,"date":1392,"description":1393,"draft":1394,"extension":1395,"howTo":1396,"image":1414,"meta":1415,"navigation":153,"path":1416,"seo":1417,"stem":1418,"tags":1419,"updated":1414,"__hash__":1422},"blogJa/ja/blog/014.table-column-widths.md","gpdf のテーブルで列幅を指定する方法",{"name":7,"url":8,"avatar":9},"野田大貴","https://nadai.dev/ja/about","https://nadai.dev/og-default.png",{"type":11,"value":12,"toc":1381},"minimark",[13,17,35,38,48,120,127,130,134,886,896,900,911,926,932,936,939,953,956,966,1019,1026,1079,1090,1094,1104,1110,1113,1116,1287,1308,1314,1317,1339,1343,1346,1363,1377],[14,15,16],"h2",{"id":16},"質問を言い換えると",[18,19,20,21,25,26,30,31,34],"p",{},"4 列のテーブルがある。デフォルトの ",[22,23,24],"code",{},"c.Table(header, rows)"," は全列を等幅にするが、請求書なら ",[27,28,29],"strong",{},"品目"," の列は広く、",[27,32,33],{},"数量"," の列は狭くしたい。列ごとの幅をどう指定するのか。そして、その値は何の単位なのか。",[14,36,37],{"id":37},"即答",[18,39,40,43,44,47],{},[22,41,42],{},"template.ColumnWidths(...)"," を ",[22,45,46],{},"TableOption"," として渡す:",[49,50,55],"pre",{"className":51,"code":52,"language":53,"meta":54,"style":54},"language-go shiki shiki-themes material-theme-lighter material-theme material-theme-palenight","c.Table(header, rows, template.ColumnWidths(40, 15, 20, 25))\n","go","",[22,56,57],{"__ignoreMap":54},[58,59,62,66,70,74,77,80,83,86,88,91,93,96,98,102,104,107,109,112,114,117],"span",{"class":60,"line":61},"line",1,[58,63,65],{"class":64},"sTEyZ","c",[58,67,69],{"class":68},"sMK4o",".",[58,71,73],{"class":72},"s2Zo4","Table",[58,75,76],{"class":68},"(",[58,78,79],{"class":64},"header",[58,81,82],{"class":68},",",[58,84,85],{"class":64}," rows",[58,87,82],{"class":68},[58,89,90],{"class":64}," template",[58,92,69],{"class":68},[58,94,95],{"class":72},"ColumnWidths",[58,97,76],{"class":68},[58,99,101],{"class":100},"sbssI","40",[58,103,82],{"class":68},[58,105,106],{"class":100}," 15",[58,108,82],{"class":68},[58,110,111],{"class":100}," 20",[58,113,82],{"class":68},[58,115,116],{"class":100}," 25",[58,118,119],{"class":68},"))\n",[18,121,122,123,126],{},"値は ",[27,124,125],{},"親 Col の content 幅に対するパーセンテージ","。pt ではない。合計が 100 である必要はないが、通常はそうすべき — 足りなければ右側に空白が残り、超過すればセルからはみ出す。",[18,128,129],{},"普通のケースはこれだけ。面白いのは、合計が 100 にならないとき、列数より少ない値を渡したとき、そして「親幅」が実際に何を指すのか、という 3 点。",[14,131,133],{"id":132},"動くコード-4-列の請求書テーブル","動くコード (4 列の請求書テーブル)",[49,135,137],{"className":51,"code":136,"language":53,"meta":54,"style":54},"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/pdf\"\n    \"github.com/gpdf-dev/gpdf/template\"\n)\n\nfunc main() {\n    doc := gpdf.NewDocument(\n        gpdf.WithPageSize(gpdf.A4),\n        gpdf.WithMargins(document.UniformEdges(document.Mm(20))),\n    )\n\n    header := []string{\"品目\", \"数量\", \"単価\", \"金額\"}\n    rows := [][]string{\n        {\"年間サポート契約\", \"1\", \"¥120,000\", \"¥120,000\"},\n        {\"オンサイト研修 (1 日)\", \"3\", \"¥80,000\", \"¥240,000\"},\n        {\"カスタムテンプレート開発\", \"12\", \"¥9,500\", \"¥114,000\"},\n    }\n\n    page := doc.AddPage()\n    page.AutoRow(func(r *template.RowBuilder) {\n        r.Col(12, func(c *template.ColBuilder) {\n            c.Table(header, rows,\n                template.ColumnWidths(40, 15, 20, 25),\n                template.TableHeaderStyle(template.BgColor(pdf.Gray(0.92))),\n            )\n        })\n    })\n\n    data, err := doc.Generate()\n    if err != nil {\n        log.Fatal(err)\n    }\n    if err := os.WriteFile(\"invoice.pdf\", data, 0o644); err != nil {\n        log.Fatal(err)\n    }\n}\n",[22,138,139,148,155,165,177,187,192,202,212,222,232,238,243,258,278,302,339,345,350,406,422,464,505,546,552,557,576,610,645,666,694,730,736,742,748,753,775,791,809,814,861,876,881],{"__ignoreMap":54},[58,140,141,144],{"class":60,"line":61},[58,142,143],{"class":68},"package",[58,145,147],{"class":146},"sBMFI"," main\n",[58,149,151],{"class":60,"line":150},2,[58,152,154],{"emptyLinePlaceholder":153},true,"\n",[58,156,158,162],{"class":60,"line":157},3,[58,159,161],{"class":160},"s7zQu","import",[58,163,164],{"class":68}," (\n",[58,166,168,171,174],{"class":60,"line":167},4,[58,169,170],{"class":68},"    \"",[58,172,173],{"class":146},"log",[58,175,176],{"class":68},"\"\n",[58,178,180,182,185],{"class":60,"line":179},5,[58,181,170],{"class":68},[58,183,184],{"class":146},"os",[58,186,176],{"class":68},[58,188,190],{"class":60,"line":189},6,[58,191,154],{"emptyLinePlaceholder":153},[58,193,195,197,200],{"class":60,"line":194},7,[58,196,170],{"class":68},[58,198,199],{"class":146},"github.com/gpdf-dev/gpdf",[58,201,176],{"class":68},[58,203,205,207,210],{"class":60,"line":204},8,[58,206,170],{"class":68},[58,208,209],{"class":146},"github.com/gpdf-dev/gpdf/document",[58,211,176],{"class":68},[58,213,215,217,220],{"class":60,"line":214},9,[58,216,170],{"class":68},[58,218,219],{"class":146},"github.com/gpdf-dev/gpdf/pdf",[58,221,176],{"class":68},[58,223,225,227,230],{"class":60,"line":224},10,[58,226,170],{"class":68},[58,228,229],{"class":146},"github.com/gpdf-dev/gpdf/template",[58,231,176],{"class":68},[58,233,235],{"class":60,"line":234},11,[58,236,237],{"class":68},")\n",[58,239,241],{"class":60,"line":240},12,[58,242,154],{"emptyLinePlaceholder":153},[58,244,246,249,252,255],{"class":60,"line":245},13,[58,247,248],{"class":68},"func",[58,250,251],{"class":72}," main",[58,253,254],{"class":68},"()",[58,256,257],{"class":68}," {\n",[58,259,261,264,267,270,272,275],{"class":60,"line":260},14,[58,262,263],{"class":64},"    doc ",[58,265,266],{"class":68},":=",[58,268,269],{"class":64}," gpdf",[58,271,69],{"class":68},[58,273,274],{"class":72},"NewDocument",[58,276,277],{"class":68},"(\n",[58,279,281,284,286,289,291,294,296,299],{"class":60,"line":280},15,[58,282,283],{"class":64},"        gpdf",[58,285,69],{"class":68},[58,287,288],{"class":72},"WithPageSize",[58,290,76],{"class":68},[58,292,293],{"class":64},"gpdf",[58,295,69],{"class":68},[58,297,298],{"class":64},"A4",[58,300,301],{"class":68},"),\n",[58,303,305,307,309,312,314,317,319,322,324,326,328,331,333,336],{"class":60,"line":304},16,[58,306,283],{"class":64},[58,308,69],{"class":68},[58,310,311],{"class":72},"WithMargins",[58,313,76],{"class":68},[58,315,316],{"class":64},"document",[58,318,69],{"class":68},[58,320,321],{"class":72},"UniformEdges",[58,323,76],{"class":68},[58,325,316],{"class":64},[58,327,69],{"class":68},[58,329,330],{"class":72},"Mm",[58,332,76],{"class":68},[58,334,335],{"class":100},"20",[58,337,338],{"class":68},"))),\n",[58,340,342],{"class":60,"line":341},17,[58,343,344],{"class":68},"    )\n",[58,346,348],{"class":60,"line":347},18,[58,349,154],{"emptyLinePlaceholder":153},[58,351,353,356,358,361,365,368,371,374,376,378,381,383,385,387,389,392,394,396,398,401,403],{"class":60,"line":352},19,[58,354,355],{"class":64},"    header ",[58,357,266],{"class":68},[58,359,360],{"class":68}," []",[58,362,364],{"class":363},"spNyl","string",[58,366,367],{"class":68},"{",[58,369,370],{"class":68},"\"",[58,372,29],{"class":373},"sfazB",[58,375,370],{"class":68},[58,377,82],{"class":68},[58,379,380],{"class":68}," \"",[58,382,33],{"class":373},[58,384,370],{"class":68},[58,386,82],{"class":68},[58,388,380],{"class":68},[58,390,391],{"class":373},"単価",[58,393,370],{"class":68},[58,395,82],{"class":68},[58,397,380],{"class":68},[58,399,400],{"class":373},"金額",[58,402,370],{"class":68},[58,404,405],{"class":68},"}\n",[58,407,409,412,414,417,419],{"class":60,"line":408},20,[58,410,411],{"class":64},"    rows ",[58,413,266],{"class":68},[58,415,416],{"class":68}," [][]",[58,418,364],{"class":363},[58,420,421],{"class":68},"{\n",[58,423,425,428,430,433,435,437,439,442,444,446,448,451,453,455,457,459,461],{"class":60,"line":424},21,[58,426,427],{"class":68},"        {",[58,429,370],{"class":68},[58,431,432],{"class":373},"年間サポート契約",[58,434,370],{"class":68},[58,436,82],{"class":68},[58,438,380],{"class":68},[58,440,441],{"class":373},"1",[58,443,370],{"class":68},[58,445,82],{"class":68},[58,447,380],{"class":68},[58,449,450],{"class":373},"¥120,000",[58,452,370],{"class":68},[58,454,82],{"class":68},[58,456,380],{"class":68},[58,458,450],{"class":373},[58,460,370],{"class":68},[58,462,463],{"class":68},"},\n",[58,465,467,469,471,474,476,478,480,483,485,487,489,492,494,496,498,501,503],{"class":60,"line":466},22,[58,468,427],{"class":68},[58,470,370],{"class":68},[58,472,473],{"class":373},"オンサイト研修 (1 日)",[58,475,370],{"class":68},[58,477,82],{"class":68},[58,479,380],{"class":68},[58,481,482],{"class":373},"3",[58,484,370],{"class":68},[58,486,82],{"class":68},[58,488,380],{"class":68},[58,490,491],{"class":373},"¥80,000",[58,493,370],{"class":68},[58,495,82],{"class":68},[58,497,380],{"class":68},[58,499,500],{"class":373},"¥240,000",[58,502,370],{"class":68},[58,504,463],{"class":68},[58,506,508,510,512,515,517,519,521,524,526,528,530,533,535,537,539,542,544],{"class":60,"line":507},23,[58,509,427],{"class":68},[58,511,370],{"class":68},[58,513,514],{"class":373},"カスタムテンプレート開発",[58,516,370],{"class":68},[58,518,82],{"class":68},[58,520,380],{"class":68},[58,522,523],{"class":373},"12",[58,525,370],{"class":68},[58,527,82],{"class":68},[58,529,380],{"class":68},[58,531,532],{"class":373},"¥9,500",[58,534,370],{"class":68},[58,536,82],{"class":68},[58,538,380],{"class":68},[58,540,541],{"class":373},"¥114,000",[58,543,370],{"class":68},[58,545,463],{"class":68},[58,547,549],{"class":60,"line":548},24,[58,550,551],{"class":68},"    }\n",[58,553,555],{"class":60,"line":554},25,[58,556,154],{"emptyLinePlaceholder":153},[58,558,560,563,565,568,570,573],{"class":60,"line":559},26,[58,561,562],{"class":64},"    page ",[58,564,266],{"class":68},[58,566,567],{"class":64}," doc",[58,569,69],{"class":68},[58,571,572],{"class":72},"AddPage",[58,574,575],{"class":68},"()\n",[58,577,579,582,584,587,590,594,597,600,602,605,608],{"class":60,"line":578},27,[58,580,581],{"class":64},"    page",[58,583,69],{"class":68},[58,585,586],{"class":72},"AutoRow",[58,588,589],{"class":68},"(func(",[58,591,593],{"class":592},"sHdIc","r",[58,595,596],{"class":68}," *",[58,598,599],{"class":146},"template",[58,601,69],{"class":68},[58,603,604],{"class":146},"RowBuilder",[58,606,607],{"class":68},")",[58,609,257],{"class":68},[58,611,613,616,618,621,623,625,627,630,632,634,636,638,641,643],{"class":60,"line":612},28,[58,614,615],{"class":64},"        r",[58,617,69],{"class":68},[58,619,620],{"class":72},"Col",[58,622,76],{"class":68},[58,624,523],{"class":100},[58,626,82],{"class":68},[58,628,629],{"class":68}," func(",[58,631,65],{"class":592},[58,633,596],{"class":68},[58,635,599],{"class":146},[58,637,69],{"class":68},[58,639,640],{"class":146},"ColBuilder",[58,642,607],{"class":68},[58,644,257],{"class":68},[58,646,648,651,653,655,657,659,661,663],{"class":60,"line":647},29,[58,649,650],{"class":64},"            c",[58,652,69],{"class":68},[58,654,73],{"class":72},[58,656,76],{"class":68},[58,658,79],{"class":64},[58,660,82],{"class":68},[58,662,85],{"class":64},[58,664,665],{"class":68},",\n",[58,667,669,672,674,676,678,680,682,684,686,688,690,692],{"class":60,"line":668},30,[58,670,671],{"class":64},"                template",[58,673,69],{"class":68},[58,675,95],{"class":72},[58,677,76],{"class":68},[58,679,101],{"class":100},[58,681,82],{"class":68},[58,683,106],{"class":100},[58,685,82],{"class":68},[58,687,111],{"class":100},[58,689,82],{"class":68},[58,691,116],{"class":100},[58,693,301],{"class":68},[58,695,697,699,701,704,706,708,710,713,715,718,720,723,725,728],{"class":60,"line":696},31,[58,698,671],{"class":64},[58,700,69],{"class":68},[58,702,703],{"class":72},"TableHeaderStyle",[58,705,76],{"class":68},[58,707,599],{"class":64},[58,709,69],{"class":68},[58,711,712],{"class":72},"BgColor",[58,714,76],{"class":68},[58,716,717],{"class":64},"pdf",[58,719,69],{"class":68},[58,721,722],{"class":72},"Gray",[58,724,76],{"class":68},[58,726,727],{"class":100},"0.92",[58,729,338],{"class":68},[58,731,733],{"class":60,"line":732},32,[58,734,735],{"class":68},"            )\n",[58,737,739],{"class":60,"line":738},33,[58,740,741],{"class":68},"        })\n",[58,743,745],{"class":60,"line":744},34,[58,746,747],{"class":68},"    })\n",[58,749,751],{"class":60,"line":750},35,[58,752,154],{"emptyLinePlaceholder":153},[58,754,756,759,761,764,766,768,770,773],{"class":60,"line":755},36,[58,757,758],{"class":64},"    data",[58,760,82],{"class":68},[58,762,763],{"class":64}," err ",[58,765,266],{"class":68},[58,767,567],{"class":64},[58,769,69],{"class":68},[58,771,772],{"class":72},"Generate",[58,774,575],{"class":68},[58,776,778,781,783,786,789],{"class":60,"line":777},37,[58,779,780],{"class":160},"    if",[58,782,763],{"class":64},[58,784,785],{"class":68},"!=",[58,787,788],{"class":68}," nil",[58,790,257],{"class":68},[58,792,794,797,799,802,804,807],{"class":60,"line":793},38,[58,795,796],{"class":64},"        log",[58,798,69],{"class":68},[58,800,801],{"class":72},"Fatal",[58,803,76],{"class":68},[58,805,806],{"class":64},"err",[58,808,237],{"class":68},[58,810,812],{"class":60,"line":811},39,[58,813,551],{"class":68},[58,815,817,819,821,823,826,828,831,833,835,838,840,842,845,847,850,853,855,857,859],{"class":60,"line":816},40,[58,818,780],{"class":160},[58,820,763],{"class":64},[58,822,266],{"class":68},[58,824,825],{"class":64}," os",[58,827,69],{"class":68},[58,829,830],{"class":72},"WriteFile",[58,832,76],{"class":68},[58,834,370],{"class":68},[58,836,837],{"class":373},"invoice.pdf",[58,839,370],{"class":68},[58,841,82],{"class":68},[58,843,844],{"class":64}," data",[58,846,82],{"class":68},[58,848,849],{"class":100}," 0o644",[58,851,852],{"class":68},");",[58,854,763],{"class":64},[58,856,785],{"class":68},[58,858,788],{"class":68},[58,860,257],{"class":68},[58,862,864,866,868,870,872,874],{"class":60,"line":863},41,[58,865,796],{"class":64},[58,867,69],{"class":68},[58,869,801],{"class":72},[58,871,76],{"class":68},[58,873,806],{"class":64},[58,875,237],{"class":68},[58,877,879],{"class":60,"line":878},42,[58,880,551],{"class":68},[58,882,884],{"class":60,"line":883},43,[58,885,405],{"class":68},[18,887,888,891,892,895],{},[22,889,890],{},"r.Col(12, ...)"," は行の全幅を取る。テーブルはその Col の中に配置されるので、テーブルの 100% = grid Col の content 幅の 100%。",[22,893,894],{},"ColumnWidths(40, 15, 20, 25)"," で合計 100 にすると、横の PDF ポイントは隅から隅まで使い切られる。",[14,897,899],{"id":898},"パーセンテージは何のパーセンテージか","パーセンテージは「何」のパーセンテージか",[18,901,902,903,906,907,910],{},"渡した数値は内部で ",[22,904,905],{},"document.Pct(w)"," に包まれ、",[27,908,909],{},"テーブルの content 幅"," に対して解決される。テーブルの content 幅は、配置先の grid Col の幅から、テーブル自身のマージン・パディング・ボーダーを引いたもの (実用上は Col の幅そのまま — テーブルの装飾はデフォルトでは無し)。",[18,912,913,914,917,918,921,922,925],{},"つまり ",[22,915,916],{},"r.Col(6, ...)"," (行の半分) の中で ",[22,919,920],{},"ColumnWidths(50, 50)"," と書いた場合、各テーブル列は ",[27,923,924],{},"行幅の 25%"," になる。50% ではない。パーセンテージはテーブルローカルであって、ページ基準ではない。",[18,927,928,929,931],{},"これはレイアウト変更の時に効く。テーブルを全幅から横並び 2 つに変えても、",[22,930,95],{}," の数値は変えなくていい — そのままスケールする。",[14,933,935],{"id":934},"数値が合わないときに-gpdf-は何をするか","数値が合わないときに gpdf は何をするか",[18,937,938],{},"実装で頻繁にぶつかるケースが 2 つある。レイアウトエンジンの挙動は明確に決まっていて、知っておく価値がある。",[18,940,941,944,945,948,949,952],{},[27,942,943],{},"ケース 1: パーセンテージの合計が 100 にならない。"," 各値はそのまま使われる。3 列テーブルで ",[22,946,947],{},"ColumnWidths(40, 30, 20)"," なら、列は 40% / 30% / 20% になり、右に 10% の空白が残る。",[22,950,951],{},"ColumnWidths(50, 50, 50)"," は overflow する — 3 列目が親の右端を超えて、隣の列に食い込んだりページ外に出たりする。",[18,954,955],{},"正規化は行われない。算数は書き手の責任。",[18,957,958,961,962,965],{},[27,959,960],{},"ケース 2: 列数より少ない値を渡した。"," こちらの方が興味深い。明示値のない末尾列は ",[27,963,964],{},"auto-width"," になり、余った幅を均等に分け合う:",[49,967,969],{"className":51,"code":968,"language":53,"meta":54,"style":54},"// 3 列テーブル、値は 2 つだけ。\nc.Table(header3, rows3, template.ColumnWidths(40, 30))\n// → 40% / 30% / 30%   (3 列目は 100 - 40 - 30 = 30%)\n",[22,970,971,977,1014],{"__ignoreMap":54},[58,972,973],{"class":60,"line":61},[58,974,976],{"class":975},"sHwdD","// 3 列テーブル、値は 2 つだけ。\n",[58,978,979,981,983,985,987,990,992,995,997,999,1001,1003,1005,1007,1009,1012],{"class":60,"line":150},[58,980,65],{"class":64},[58,982,69],{"class":68},[58,984,73],{"class":72},[58,986,76],{"class":68},[58,988,989],{"class":64},"header3",[58,991,82],{"class":68},[58,993,994],{"class":64}," rows3",[58,996,82],{"class":68},[58,998,90],{"class":64},[58,1000,69],{"class":68},[58,1002,95],{"class":72},[58,1004,76],{"class":68},[58,1006,101],{"class":100},[58,1008,82],{"class":68},[58,1010,1011],{"class":100}," 30",[58,1013,119],{"class":68},[58,1015,1016],{"class":60,"line":157},[58,1017,1018],{"class":975},"// → 40% / 30% / 30%   (3 列目は 100 - 40 - 30 = 30%)\n",[18,1020,1021,1022,1025],{},"明示値の合計が既に 100 以上なら、auto 列は ",[27,1023,1024],{},"0 幅"," になり、事実上消える。100 未満なら、残差を auto 列の数で均等に割る:",[49,1027,1029],{"className":51,"code":1028,"language":53,"meta":54,"style":54},"// 5 列テーブル、値は 2 つ。\nc.Table(header5, rows5, template.ColumnWidths(50, 10))\n// → 50% / 10% / 13.33% / 13.33% / 13.33%   (40% を 3 等分)\n",[22,1030,1031,1036,1074],{"__ignoreMap":54},[58,1032,1033],{"class":60,"line":61},[58,1034,1035],{"class":975},"// 5 列テーブル、値は 2 つ。\n",[58,1037,1038,1040,1042,1044,1046,1049,1051,1054,1056,1058,1060,1062,1064,1067,1069,1072],{"class":60,"line":150},[58,1039,65],{"class":64},[58,1041,69],{"class":68},[58,1043,73],{"class":72},[58,1045,76],{"class":68},[58,1047,1048],{"class":64},"header5",[58,1050,82],{"class":68},[58,1052,1053],{"class":64}," rows5",[58,1055,82],{"class":68},[58,1057,90],{"class":64},[58,1059,69],{"class":68},[58,1061,95],{"class":72},[58,1063,76],{"class":68},[58,1065,1066],{"class":100},"50",[58,1068,82],{"class":68},[58,1070,1071],{"class":100}," 10",[58,1073,119],{"class":68},[58,1075,1076],{"class":60,"line":157},[58,1077,1078],{"class":975},"// → 50% / 10% / 13.33% / 13.33% / 13.33%   (40% を 3 等分)\n",[18,1080,1081,1082,1085,1086,1089],{},"このルールには便利な裏技がある: 値に ",[22,1083,1084],{},"0"," を渡すと、その列も auto 扱いになる。3 列テーブルで ",[22,1087,1088],{},"ColumnWidths(0, 30, 30)"," と書けば、後ろ 2 列を 30% ずつに固定して、残りの 40% を先頭列に渡せる。「この列とこの列だけ正確に決めたい、あとは任せる」と書きたいときに便利。",[14,1091,1093],{"id":1092},"逆方向-値が多すぎる場合","逆方向: 値が多すぎる場合",[18,1095,1096,1097,1100,1101,1103],{},"列数を超えた値は黙って無視される。2 列テーブルで ",[22,1098,1099],{},"ColumnWidths(40, 30, 20, 10)"," を渡しても、最初の 2 つしか使われない。寛容ではあるが、バグの温床でもある — ヘッダーから列を 1 つ消したのに対応する ",[22,1102,95],{}," の値を消し忘れても、gpdf は何も警告しない。ログも出ない。",[18,1105,1106,1107,1109],{},"列数自体はヘッダー行の長さから推定される (ヘッダーがなければ最初のボディ行から)。ヘッダーセルを 1 つ足せば列が 1 つ増え、gpdf は気づいて ",[22,1108,95],{}," を新しい列数に合わせて再分配する。",[14,1111,1112],{"id":1112},"パーセンテージが嫌なとき",[18,1114,1115],{},"ビルダー API はパーセンテージしか公開していない。「数量」列を 50pt で固定してページサイズに依存させたくない、というケースでは、1 つ下のレイヤー (document ツリー) を直接組む:",[49,1117,1119],{"className":51,"code":1118,"language":53,"meta":54,"style":54},"import \"github.com/gpdf-dev/gpdf/document\"\n\ntbl := &document.Table{\n    Columns: []document.TableColumn{\n        {Width: document.Auto},\n        {Width: document.Pt(50)},\n        {Width: document.Pt(80)},\n        {Width: document.Pt(80)},\n    },\n    Header: /* ... */,\n    Body:   /* ... */,\n}\n",[22,1120,1121,1131,1135,1153,1172,1191,1213,1234,1254,1259,1271,1283],{"__ignoreMap":54},[58,1122,1123,1125,1127,1129],{"class":60,"line":61},[58,1124,161],{"class":160},[58,1126,380],{"class":68},[58,1128,209],{"class":146},[58,1130,176],{"class":68},[58,1132,1133],{"class":60,"line":150},[58,1134,154],{"emptyLinePlaceholder":153},[58,1136,1137,1140,1142,1145,1147,1149,1151],{"class":60,"line":157},[58,1138,1139],{"class":64},"tbl ",[58,1141,266],{"class":68},[58,1143,1144],{"class":68}," &",[58,1146,316],{"class":146},[58,1148,69],{"class":68},[58,1150,73],{"class":146},[58,1152,421],{"class":68},[58,1154,1155,1158,1161,1163,1165,1167,1170],{"class":60,"line":167},[58,1156,1157],{"class":64},"    Columns",[58,1159,1160],{"class":68},":",[58,1162,360],{"class":68},[58,1164,316],{"class":146},[58,1166,69],{"class":68},[58,1168,1169],{"class":146},"TableColumn",[58,1171,421],{"class":68},[58,1173,1174,1176,1179,1181,1184,1186,1189],{"class":60,"line":179},[58,1175,427],{"class":68},[58,1177,1178],{"class":64},"Width",[58,1180,1160],{"class":68},[58,1182,1183],{"class":64}," document",[58,1185,69],{"class":68},[58,1187,1188],{"class":64},"Auto",[58,1190,463],{"class":68},[58,1192,1193,1195,1197,1199,1201,1203,1206,1208,1210],{"class":60,"line":189},[58,1194,427],{"class":68},[58,1196,1178],{"class":64},[58,1198,1160],{"class":68},[58,1200,1183],{"class":64},[58,1202,69],{"class":68},[58,1204,1205],{"class":72},"Pt",[58,1207,76],{"class":68},[58,1209,1066],{"class":100},[58,1211,1212],{"class":68},")},\n",[58,1214,1215,1217,1219,1221,1223,1225,1227,1229,1232],{"class":60,"line":194},[58,1216,427],{"class":68},[58,1218,1178],{"class":64},[58,1220,1160],{"class":68},[58,1222,1183],{"class":64},[58,1224,69],{"class":68},[58,1226,1205],{"class":72},[58,1228,76],{"class":68},[58,1230,1231],{"class":100},"80",[58,1233,1212],{"class":68},[58,1235,1236,1238,1240,1242,1244,1246,1248,1250,1252],{"class":60,"line":204},[58,1237,427],{"class":68},[58,1239,1178],{"class":64},[58,1241,1160],{"class":68},[58,1243,1183],{"class":64},[58,1245,69],{"class":68},[58,1247,1205],{"class":72},[58,1249,76],{"class":68},[58,1251,1231],{"class":100},[58,1253,1212],{"class":68},[58,1255,1256],{"class":60,"line":214},[58,1257,1258],{"class":68},"    },\n",[58,1260,1261,1264,1266,1269],{"class":60,"line":224},[58,1262,1263],{"class":64},"    Header",[58,1265,1160],{"class":68},[58,1267,1268],{"class":975}," /* ... */",[58,1270,665],{"class":68},[58,1272,1273,1276,1278,1281],{"class":60,"line":234},[58,1274,1275],{"class":64},"    Body",[58,1277,1160],{"class":68},[58,1279,1280],{"class":975},"   /* ... */",[58,1282,665],{"class":68},[58,1284,1285],{"class":60,"line":240},[58,1286,405],{"class":68},[18,1288,1289,1290,1292,1293,1292,1295,1292,1297,1300,1301,1303,1304,1307],{},"document レイヤーでは ",[22,1291,1188],{}," / ",[22,1294,1205],{},[22,1296,330],{},[22,1298,1299],{},"Pct"," が混在できる。最初の ",[22,1302,1188],{}," 列は、固定 3 列を引いた残りを取る。CSS の ",[22,1305,1306],{},"\u003Ccol>"," 要素に近い。",[18,1309,1310,1313],{},[22,1311,1312],{},"c.Table(header, rows, ...)"," がやってくれていたセル構築は自分で書くことになるが、紙のレターヘッドに印刷する請求書で列位置を厳密に揃えたい用途では、十分割に合う。",[14,1315,1316],{"id":1316},"関連レシピ",[1318,1319,1320,1329],"ul",{},[1321,1322,1323,1328],"li",{},[1324,1325,1327],"a",{"href":1326},"/ja/blog/12-column-grid","gpdf の 12 カラムグリッドの仕組み"," — 行の 12 列が、テーブルのパーセンテージ計算の基準になる「親幅」をどう決めるか",[1321,1330,1331,1335,1336,1338],{},[1324,1332,1334],{"href":1333},"/ja/blog/invoice-pdf-go-under-50-lines","Go で 50 行以内の請求書 PDF を生成する"," — ",[22,1337,894],{}," を請求書全体の文脈で見る",[14,1340,1342],{"id":1341},"gpdf-を使ってみる","gpdf を使ってみる",[18,1344,1345],{},"gpdf は Go の PDF 生成ライブラリ。MIT、ゼロ依存、CJK 対応。",[49,1347,1351],{"className":1348,"code":1349,"language":1350,"meta":54,"style":54},"language-bash shiki shiki-themes material-theme-lighter material-theme material-theme-palenight","go get github.com/gpdf-dev/gpdf\n","bash",[22,1352,1353],{"__ignoreMap":54},[58,1354,1355,1357,1360],{"class":60,"line":61},[58,1356,53],{"class":146},[58,1358,1359],{"class":373}," get",[58,1361,1362],{"class":373}," github.com/gpdf-dev/gpdf\n",[18,1364,1365,1371,1372],{},[1324,1366,1370],{"href":1367,"rel":1368},"https://github.com/gpdf-dev/gpdf",[1369],"nofollow","⭐ Star on GitHub"," · ",[1324,1373,1376],{"href":1374,"rel":1375},"https://gpdf.dev/ja/docs/quickstart",[1369],"ドキュメントを読む",[1378,1379,1380],"style",{},"html pre.shiki code .sTEyZ, html code.shiki .sTEyZ{--shiki-light:#90A4AE;--shiki-default:#EEFFFF;--shiki-dark:#BABED8}html pre.shiki code .sMK4o, html code.shiki .sMK4o{--shiki-light:#39ADB5;--shiki-default:#89DDFF;--shiki-dark:#89DDFF}html pre.shiki code .s2Zo4, html code.shiki .s2Zo4{--shiki-light:#6182B8;--shiki-default:#82AAFF;--shiki-dark:#82AAFF}html pre.shiki code .sbssI, html code.shiki .sbssI{--shiki-light:#F76D47;--shiki-default:#F78C6C;--shiki-dark:#F78C6C}html .light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html.light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html.dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html pre.shiki code .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 .spNyl, html code.shiki .spNyl{--shiki-light:#9C3EDA;--shiki-default:#C792EA;--shiki-dark:#C792EA}html pre.shiki code .sfazB, html code.shiki .sfazB{--shiki-light:#91B859;--shiki-default:#C3E88D;--shiki-dark:#C3E88D}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 .sHwdD, html code.shiki .sHwdD{--shiki-light:#90A4AE;--shiki-light-font-style:italic;--shiki-default:#546E7A;--shiki-default-font-style:italic;--shiki-dark:#676E95;--shiki-dark-font-style:italic}",{"title":54,"searchDepth":150,"depth":150,"links":1382},[1383,1384,1385,1386,1387,1388,1389,1390,1391],{"id":16,"depth":150,"text":16},{"id":37,"depth":150,"text":37},{"id":132,"depth":150,"text":133},{"id":898,"depth":150,"text":899},{"id":934,"depth":150,"text":935},{"id":1092,"depth":150,"text":1093},{"id":1112,"depth":150,"text":1112},{"id":1316,"depth":150,"text":1316},{"id":1341,"depth":150,"text":1342},"2026-04-28","c.Table に template.ColumnWidths(...) を渡す。値は親 Col 幅に対するパーセンテージ。合計 100 で全幅、末尾を省くと残りが自動分配される。",false,"md",{"name":1397,"totalTime":1398,"tools":1399,"steps":1401},"gpdf で組んだテーブルに列ごとの幅を設定する","PT10M",[1400],"Go 1.22+",[1402,1405,1408,1411],{"name":1403,"text":1404},"まずは ColumnWidths なしで列数を確認する","c.Table(header, rows) を呼ぶ。ColumnWidths オプションを渡さない場合、gpdf はヘッダーから列数を推定し、親 Col の幅を均等に分割する。",{"name":1406,"text":1407},"合計 100 のパーセンテージを ColumnWidths で渡す","c.Table の第 3 引数に template.ColumnWidths(40, 15, 20, 25) を追加する。各値はテーブルの親幅 (= 配置先の grid Col の幅) に対するパーセンテージ。",{"name":1409,"text":1410},"0 を渡すとその列は自動分配になる","3 列のテーブルで ColumnWidths(0, 30, 30) と書くと、後ろ 2 列が 30% ずつ固定され、残り 40% が先頭列に割り当てられる。",{"name":1412,"text":1413},"列数より少ない値を渡せば末尾が均等分配される","3 列のテーブルで ColumnWidths(40, 30) を渡すと、3 列目は明示値がないため余りの 30% を取って 40 / 30 / 30 になる。",null,{},"/ja/blog/table-column-widths",{"title":5,"description":1393},"ja/blog/014.table-column-widths",[1420,1421],"recipe","tutorial","6oUtt2xf28aBG1EJBi-7FJwGzrZy1X0Rv1-qJpdmjzg",1779199021999]