[{"data":1,"prerenderedAt":1427},["ShallowReactive",2],{"blog-en-table-column-widths":3},{"id":4,"title":5,"author":6,"body":10,"date":1396,"description":1397,"draft":1398,"extension":1399,"howTo":1400,"image":1418,"meta":1419,"navigation":156,"path":1420,"seo":1421,"stem":1422,"tags":1423,"updated":1418,"__hash__":1426},"blog/blog/014.table-column-widths.md","How do I set column widths in a gpdf table?",{"name":7,"url":8,"avatar":9},"Taiki Noda","https://nadai.dev/en/about","https://nadai.dev/og-default.png",{"type":11,"value":12,"toc":1384},"minimark",[13,18,36,40,51,123,130,133,137,889,899,907,918,933,939,943,946,960,963,973,1026,1033,1086,1097,1101,1108,1111,1115,1118,1288,1309,1316,1320,1342,1346,1349,1366,1380],[14,15,17],"h2",{"id":16},"the-question-in-other-words","The question, in other words",[19,20,21,22,26,27,31,32,35],"p",{},"I have a table with four columns. By default ",[23,24,25],"code",{},"c.Table(header, rows)"," makes them all the same width, but for an invoice the ",[28,29,30],"strong",{},"Description"," column should be wide and ",[28,33,34],{},"Qty"," should be narrow. How do I tell gpdf the per-column widths, and what unit am I actually setting?",[14,37,39],{"id":38},"the-quick-answer","The quick answer",[19,41,42,43,46,47,50],{},"Pass ",[23,44,45],{},"template.ColumnWidths(...)"," as a ",[23,48,49],{},"TableOption",":",[52,53,58],"pre",{"className":54,"code":55,"language":56,"meta":57,"style":57},"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","",[23,59,60],{"__ignoreMap":57},[61,62,65,69,73,77,80,83,86,89,91,94,96,99,101,105,107,110,112,115,117,120],"span",{"class":63,"line":64},"line",1,[61,66,68],{"class":67},"sTEyZ","c",[61,70,72],{"class":71},"sMK4o",".",[61,74,76],{"class":75},"s2Zo4","Table",[61,78,79],{"class":71},"(",[61,81,82],{"class":67},"header",[61,84,85],{"class":71},",",[61,87,88],{"class":67}," rows",[61,90,85],{"class":71},[61,92,93],{"class":67}," template",[61,95,72],{"class":71},[61,97,98],{"class":75},"ColumnWidths",[61,100,79],{"class":71},[61,102,104],{"class":103},"sbssI","40",[61,106,85],{"class":71},[61,108,109],{"class":103}," 15",[61,111,85],{"class":71},[61,113,114],{"class":103}," 20",[61,116,85],{"class":71},[61,118,119],{"class":103}," 25",[61,121,122],{"class":71},"))\n",[19,124,125,126,129],{},"The values are ",[28,127,128],{},"percentages of the parent column's content width",", not points. They don't have to sum to 100, but they usually should — anything missing leaves empty space on the right, anything extra overflows the cell.",[19,131,132],{},"That's it for the common case. The interesting parts are what happens when the percentages don't sum to 100, when you pass fewer values than there are columns, and what the parent width actually is.",[14,134,136],{"id":135},"working-code-a-four-column-invoice-table","Working code (a four-column invoice table)",[52,138,140],{"className":54,"code":139,"language":56,"meta":57,"style":57},"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{\"Description\", \"Qty\", \"Unit price\", \"Total\"}\n    rows := [][]string{\n        {\"Annual support contract\", \"1\", \"$1,200.00\", \"$1,200.00\"},\n        {\"On-site training (per day)\", \"3\", \"$800.00\", \"$2,400.00\"},\n        {\"Custom template development\", \"12\", \"$95.00\", \"$1,140.00\"},\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",[23,141,142,151,158,168,180,190,195,205,215,225,235,241,246,261,281,305,342,348,353,409,425,467,508,549,555,560,579,613,648,669,697,733,739,745,751,756,778,794,812,817,864,879,884],{"__ignoreMap":57},[61,143,144,147],{"class":63,"line":64},[61,145,146],{"class":71},"package",[61,148,150],{"class":149},"sBMFI"," main\n",[61,152,154],{"class":63,"line":153},2,[61,155,157],{"emptyLinePlaceholder":156},true,"\n",[61,159,161,165],{"class":63,"line":160},3,[61,162,164],{"class":163},"s7zQu","import",[61,166,167],{"class":71}," (\n",[61,169,171,174,177],{"class":63,"line":170},4,[61,172,173],{"class":71},"    \"",[61,175,176],{"class":149},"log",[61,178,179],{"class":71},"\"\n",[61,181,183,185,188],{"class":63,"line":182},5,[61,184,173],{"class":71},[61,186,187],{"class":149},"os",[61,189,179],{"class":71},[61,191,193],{"class":63,"line":192},6,[61,194,157],{"emptyLinePlaceholder":156},[61,196,198,200,203],{"class":63,"line":197},7,[61,199,173],{"class":71},[61,201,202],{"class":149},"github.com/gpdf-dev/gpdf",[61,204,179],{"class":71},[61,206,208,210,213],{"class":63,"line":207},8,[61,209,173],{"class":71},[61,211,212],{"class":149},"github.com/gpdf-dev/gpdf/document",[61,214,179],{"class":71},[61,216,218,220,223],{"class":63,"line":217},9,[61,219,173],{"class":71},[61,221,222],{"class":149},"github.com/gpdf-dev/gpdf/pdf",[61,224,179],{"class":71},[61,226,228,230,233],{"class":63,"line":227},10,[61,229,173],{"class":71},[61,231,232],{"class":149},"github.com/gpdf-dev/gpdf/template",[61,234,179],{"class":71},[61,236,238],{"class":63,"line":237},11,[61,239,240],{"class":71},")\n",[61,242,244],{"class":63,"line":243},12,[61,245,157],{"emptyLinePlaceholder":156},[61,247,249,252,255,258],{"class":63,"line":248},13,[61,250,251],{"class":71},"func",[61,253,254],{"class":75}," main",[61,256,257],{"class":71},"()",[61,259,260],{"class":71}," {\n",[61,262,264,267,270,273,275,278],{"class":63,"line":263},14,[61,265,266],{"class":67},"    doc ",[61,268,269],{"class":71},":=",[61,271,272],{"class":67}," gpdf",[61,274,72],{"class":71},[61,276,277],{"class":75},"NewDocument",[61,279,280],{"class":71},"(\n",[61,282,284,287,289,292,294,297,299,302],{"class":63,"line":283},15,[61,285,286],{"class":67},"        gpdf",[61,288,72],{"class":71},[61,290,291],{"class":75},"WithPageSize",[61,293,79],{"class":71},[61,295,296],{"class":67},"gpdf",[61,298,72],{"class":71},[61,300,301],{"class":67},"A4",[61,303,304],{"class":71},"),\n",[61,306,308,310,312,315,317,320,322,325,327,329,331,334,336,339],{"class":63,"line":307},16,[61,309,286],{"class":67},[61,311,72],{"class":71},[61,313,314],{"class":75},"WithMargins",[61,316,79],{"class":71},[61,318,319],{"class":67},"document",[61,321,72],{"class":71},[61,323,324],{"class":75},"UniformEdges",[61,326,79],{"class":71},[61,328,319],{"class":67},[61,330,72],{"class":71},[61,332,333],{"class":75},"Mm",[61,335,79],{"class":71},[61,337,338],{"class":103},"20",[61,340,341],{"class":71},"))),\n",[61,343,345],{"class":63,"line":344},17,[61,346,347],{"class":71},"    )\n",[61,349,351],{"class":63,"line":350},18,[61,352,157],{"emptyLinePlaceholder":156},[61,354,356,359,361,364,368,371,374,377,379,381,384,386,388,390,392,395,397,399,401,404,406],{"class":63,"line":355},19,[61,357,358],{"class":67},"    header ",[61,360,269],{"class":71},[61,362,363],{"class":71}," []",[61,365,367],{"class":366},"spNyl","string",[61,369,370],{"class":71},"{",[61,372,373],{"class":71},"\"",[61,375,30],{"class":376},"sfazB",[61,378,373],{"class":71},[61,380,85],{"class":71},[61,382,383],{"class":71}," \"",[61,385,34],{"class":376},[61,387,373],{"class":71},[61,389,85],{"class":71},[61,391,383],{"class":71},[61,393,394],{"class":376},"Unit price",[61,396,373],{"class":71},[61,398,85],{"class":71},[61,400,383],{"class":71},[61,402,403],{"class":376},"Total",[61,405,373],{"class":71},[61,407,408],{"class":71},"}\n",[61,410,412,415,417,420,422],{"class":63,"line":411},20,[61,413,414],{"class":67},"    rows ",[61,416,269],{"class":71},[61,418,419],{"class":71}," [][]",[61,421,367],{"class":366},[61,423,424],{"class":71},"{\n",[61,426,428,431,433,436,438,440,442,445,447,449,451,454,456,458,460,462,464],{"class":63,"line":427},21,[61,429,430],{"class":71},"        {",[61,432,373],{"class":71},[61,434,435],{"class":376},"Annual support contract",[61,437,373],{"class":71},[61,439,85],{"class":71},[61,441,383],{"class":71},[61,443,444],{"class":376},"1",[61,446,373],{"class":71},[61,448,85],{"class":71},[61,450,383],{"class":71},[61,452,453],{"class":376},"$1,200.00",[61,455,373],{"class":71},[61,457,85],{"class":71},[61,459,383],{"class":71},[61,461,453],{"class":376},[61,463,373],{"class":71},[61,465,466],{"class":71},"},\n",[61,468,470,472,474,477,479,481,483,486,488,490,492,495,497,499,501,504,506],{"class":63,"line":469},22,[61,471,430],{"class":71},[61,473,373],{"class":71},[61,475,476],{"class":376},"On-site training (per day)",[61,478,373],{"class":71},[61,480,85],{"class":71},[61,482,383],{"class":71},[61,484,485],{"class":376},"3",[61,487,373],{"class":71},[61,489,85],{"class":71},[61,491,383],{"class":71},[61,493,494],{"class":376},"$800.00",[61,496,373],{"class":71},[61,498,85],{"class":71},[61,500,383],{"class":71},[61,502,503],{"class":376},"$2,400.00",[61,505,373],{"class":71},[61,507,466],{"class":71},[61,509,511,513,515,518,520,522,524,527,529,531,533,536,538,540,542,545,547],{"class":63,"line":510},23,[61,512,430],{"class":71},[61,514,373],{"class":71},[61,516,517],{"class":376},"Custom template development",[61,519,373],{"class":71},[61,521,85],{"class":71},[61,523,383],{"class":71},[61,525,526],{"class":376},"12",[61,528,373],{"class":71},[61,530,85],{"class":71},[61,532,383],{"class":71},[61,534,535],{"class":376},"$95.00",[61,537,373],{"class":71},[61,539,85],{"class":71},[61,541,383],{"class":71},[61,543,544],{"class":376},"$1,140.00",[61,546,373],{"class":71},[61,548,466],{"class":71},[61,550,552],{"class":63,"line":551},24,[61,553,554],{"class":71},"    }\n",[61,556,558],{"class":63,"line":557},25,[61,559,157],{"emptyLinePlaceholder":156},[61,561,563,566,568,571,573,576],{"class":63,"line":562},26,[61,564,565],{"class":67},"    page ",[61,567,269],{"class":71},[61,569,570],{"class":67}," doc",[61,572,72],{"class":71},[61,574,575],{"class":75},"AddPage",[61,577,578],{"class":71},"()\n",[61,580,582,585,587,590,593,597,600,603,605,608,611],{"class":63,"line":581},27,[61,583,584],{"class":67},"    page",[61,586,72],{"class":71},[61,588,589],{"class":75},"AutoRow",[61,591,592],{"class":71},"(func(",[61,594,596],{"class":595},"sHdIc","r",[61,598,599],{"class":71}," *",[61,601,602],{"class":149},"template",[61,604,72],{"class":71},[61,606,607],{"class":149},"RowBuilder",[61,609,610],{"class":71},")",[61,612,260],{"class":71},[61,614,616,619,621,624,626,628,630,633,635,637,639,641,644,646],{"class":63,"line":615},28,[61,617,618],{"class":67},"        r",[61,620,72],{"class":71},[61,622,623],{"class":75},"Col",[61,625,79],{"class":71},[61,627,526],{"class":103},[61,629,85],{"class":71},[61,631,632],{"class":71}," func(",[61,634,68],{"class":595},[61,636,599],{"class":71},[61,638,602],{"class":149},[61,640,72],{"class":71},[61,642,643],{"class":149},"ColBuilder",[61,645,610],{"class":71},[61,647,260],{"class":71},[61,649,651,654,656,658,660,662,664,666],{"class":63,"line":650},29,[61,652,653],{"class":67},"            c",[61,655,72],{"class":71},[61,657,76],{"class":75},[61,659,79],{"class":71},[61,661,82],{"class":67},[61,663,85],{"class":71},[61,665,88],{"class":67},[61,667,668],{"class":71},",\n",[61,670,672,675,677,679,681,683,685,687,689,691,693,695],{"class":63,"line":671},30,[61,673,674],{"class":67},"                template",[61,676,72],{"class":71},[61,678,98],{"class":75},[61,680,79],{"class":71},[61,682,104],{"class":103},[61,684,85],{"class":71},[61,686,109],{"class":103},[61,688,85],{"class":71},[61,690,114],{"class":103},[61,692,85],{"class":71},[61,694,119],{"class":103},[61,696,304],{"class":71},[61,698,700,702,704,707,709,711,713,716,718,721,723,726,728,731],{"class":63,"line":699},31,[61,701,674],{"class":67},[61,703,72],{"class":71},[61,705,706],{"class":75},"TableHeaderStyle",[61,708,79],{"class":71},[61,710,602],{"class":67},[61,712,72],{"class":71},[61,714,715],{"class":75},"BgColor",[61,717,79],{"class":71},[61,719,720],{"class":67},"pdf",[61,722,72],{"class":71},[61,724,725],{"class":75},"Gray",[61,727,79],{"class":71},[61,729,730],{"class":103},"0.92",[61,732,341],{"class":71},[61,734,736],{"class":63,"line":735},32,[61,737,738],{"class":71},"            )\n",[61,740,742],{"class":63,"line":741},33,[61,743,744],{"class":71},"        })\n",[61,746,748],{"class":63,"line":747},34,[61,749,750],{"class":71},"    })\n",[61,752,754],{"class":63,"line":753},35,[61,755,157],{"emptyLinePlaceholder":156},[61,757,759,762,764,767,769,771,773,776],{"class":63,"line":758},36,[61,760,761],{"class":67},"    data",[61,763,85],{"class":71},[61,765,766],{"class":67}," err ",[61,768,269],{"class":71},[61,770,570],{"class":67},[61,772,72],{"class":71},[61,774,775],{"class":75},"Generate",[61,777,578],{"class":71},[61,779,781,784,786,789,792],{"class":63,"line":780},37,[61,782,783],{"class":163},"    if",[61,785,766],{"class":67},[61,787,788],{"class":71},"!=",[61,790,791],{"class":71}," nil",[61,793,260],{"class":71},[61,795,797,800,802,805,807,810],{"class":63,"line":796},38,[61,798,799],{"class":67},"        log",[61,801,72],{"class":71},[61,803,804],{"class":75},"Fatal",[61,806,79],{"class":71},[61,808,809],{"class":67},"err",[61,811,240],{"class":71},[61,813,815],{"class":63,"line":814},39,[61,816,554],{"class":71},[61,818,820,822,824,826,829,831,834,836,838,841,843,845,848,850,853,856,858,860,862],{"class":63,"line":819},40,[61,821,783],{"class":163},[61,823,766],{"class":67},[61,825,269],{"class":71},[61,827,828],{"class":67}," os",[61,830,72],{"class":71},[61,832,833],{"class":75},"WriteFile",[61,835,79],{"class":71},[61,837,373],{"class":71},[61,839,840],{"class":376},"invoice.pdf",[61,842,373],{"class":71},[61,844,85],{"class":71},[61,846,847],{"class":67}," data",[61,849,85],{"class":71},[61,851,852],{"class":103}," 0o644",[61,854,855],{"class":71},");",[61,857,766],{"class":67},[61,859,788],{"class":71},[61,861,791],{"class":71},[61,863,260],{"class":71},[61,865,867,869,871,873,875,877],{"class":63,"line":866},41,[61,868,799],{"class":67},[61,870,72],{"class":71},[61,872,804],{"class":75},[61,874,79],{"class":71},[61,876,809],{"class":67},[61,878,240],{"class":71},[61,880,882],{"class":63,"line":881},42,[61,883,554],{"class":71},[61,885,887],{"class":63,"line":886},43,[61,888,408],{"class":71},[19,890,891,894,895,898],{},[23,892,893],{},"r.Col(12, ...)"," claims the full row width. The table sits inside that column, so 100% of the table = 100% of the grid Col content area. With ",[23,896,897],{},"ColumnWidths(40, 15, 20, 25)"," summing to 100, every PDF point of horizontal space is used.",[14,900,902,903],{"id":901},"what-the-percentages-are-a-percentage-of","What the percentages are a percentage ",[904,905,906],"em",{},"of",[19,908,909,910,913,914,917],{},"The number you pass is forwarded to ",[23,911,912],{},"document.Pct(w)"," and resolved against the ",[28,915,916],{},"table's content width",". That's the width of the grid Col the table lives in, minus any margin, padding, and border on the table itself (in practice, just the Col width — table styling defaults to none).",[19,919,920,921,924,925,928,929,932],{},"So with ",[23,922,923],{},"r.Col(6, ...)"," (half the row) and ",[23,926,927],{},"ColumnWidths(50, 50)",", each table column is ",[28,930,931],{},"25% of the row width",", not 50%. The percentages are local to the table, not to the page.",[19,934,935,936,938],{},"This matters if you ever swap a table from a full-width row into a side-by-side layout. The ",[23,937,98],{}," call doesn't need to change — it scales.",[14,940,942],{"id":941},"what-gpdf-does-when-the-math-doesnt-work-out","What gpdf does when the math doesn't work out",[19,944,945],{},"Two cases come up constantly. Both are handled by the layout engine in a specific way that's worth knowing.",[19,947,948,951,952,955,956,959],{},[28,949,950],{},"Case 1: percentages don't sum to 100."," Each value is taken at face value. ",[23,953,954],{},"ColumnWidths(40, 30, 20)"," on a three-column table produces columns at 40%, 30%, and 20% of the parent — leaving 10% empty on the right. ",[23,957,958],{},"ColumnWidths(50, 50, 50)"," overflows; the third column extends past the parent edge and may bleed into the next page column or off the page.",[19,961,962],{},"There is no normalization step. gpdf trusts you to do the arithmetic.",[19,964,965,968,969,972],{},[28,966,967],{},"Case 2: fewer widths than there are columns."," This is the more interesting one. The trailing columns become ",[28,970,971],{},"auto-width"," and share the remainder equally:",[52,974,976],{"className":54,"code":975,"language":56,"meta":57,"style":57},"// Three-column table, only two widths given.\nc.Table(header3, rows3, template.ColumnWidths(40, 30))\n// → 40% / 30% / 30%   (the third column gets 100 - 40 - 30 = 30%)\n",[23,977,978,984,1021],{"__ignoreMap":57},[61,979,980],{"class":63,"line":64},[61,981,983],{"class":982},"sHwdD","// Three-column table, only two widths given.\n",[61,985,986,988,990,992,994,997,999,1002,1004,1006,1008,1010,1012,1014,1016,1019],{"class":63,"line":153},[61,987,68],{"class":67},[61,989,72],{"class":71},[61,991,76],{"class":75},[61,993,79],{"class":71},[61,995,996],{"class":67},"header3",[61,998,85],{"class":71},[61,1000,1001],{"class":67}," rows3",[61,1003,85],{"class":71},[61,1005,93],{"class":67},[61,1007,72],{"class":71},[61,1009,98],{"class":75},[61,1011,79],{"class":71},[61,1013,104],{"class":103},[61,1015,85],{"class":71},[61,1017,1018],{"class":103}," 30",[61,1020,122],{"class":71},[61,1022,1023],{"class":63,"line":160},[61,1024,1025],{"class":982},"// → 40% / 30% / 30%   (the third column gets 100 - 40 - 30 = 30%)\n",[19,1027,1028,1029,1032],{},"If the explicit widths already sum to 100 or more, the auto columns get ",[28,1030,1031],{},"zero width"," and effectively disappear. If they sum to less than 100, the leftover is divided equally among the auto columns:",[52,1034,1036],{"className":54,"code":1035,"language":56,"meta":57,"style":57},"// Five-column table, two widths given.\nc.Table(header5, rows5, template.ColumnWidths(50, 10))\n// → 50% / 10% / 13.33% / 13.33% / 13.33%   (40% split three ways)\n",[23,1037,1038,1043,1081],{"__ignoreMap":57},[61,1039,1040],{"class":63,"line":64},[61,1041,1042],{"class":982},"// Five-column table, two widths given.\n",[61,1044,1045,1047,1049,1051,1053,1056,1058,1061,1063,1065,1067,1069,1071,1074,1076,1079],{"class":63,"line":153},[61,1046,68],{"class":67},[61,1048,72],{"class":71},[61,1050,76],{"class":75},[61,1052,79],{"class":71},[61,1054,1055],{"class":67},"header5",[61,1057,85],{"class":71},[61,1059,1060],{"class":67}," rows5",[61,1062,85],{"class":71},[61,1064,93],{"class":67},[61,1066,72],{"class":71},[61,1068,98],{"class":75},[61,1070,79],{"class":71},[61,1072,1073],{"class":103},"50",[61,1075,85],{"class":71},[61,1077,1078],{"class":103}," 10",[61,1080,122],{"class":71},[61,1082,1083],{"class":63,"line":160},[61,1084,1085],{"class":982},"// → 50% / 10% / 13.33% / 13.33% / 13.33%   (40% split three ways)\n",[19,1087,1088,1089,1092,1093,1096],{},"There's a useful trick hiding in this rule: passing ",[23,1090,1091],{},"0"," for a column also makes it auto. So ",[23,1094,1095],{},"ColumnWidths(0, 30, 30)"," on a three-column table fixes the last two at 30% each and gives the first column the remaining 40%. This is how you say \"I care about these specific widths; let gpdf handle the rest.\"",[14,1098,1100],{"id":1099},"the-other-direction-too-many-widths","The other direction: too many widths",[19,1102,1103,1104,1107],{},"Extra values beyond the column count are silently ignored. ",[23,1105,1106],{},"ColumnWidths(40, 30, 20, 10)"," on a two-column table just uses the first two. This is forgiving but it's also a bug magnet — if you delete a column from your header but forget to drop the matching width, gpdf won't tell you. There's no warning log.",[19,1109,1110],{},"The column count itself comes from the header row's length (or the first body row, if there's no header). Add a header cell and you've added a column; gpdf will discover this and re-balance whatever ColumnWidths you passed.",[14,1112,1114],{"id":1113},"when-percentages-arent-what-you-want","When percentages aren't what you want",[19,1116,1117],{},"The builder API only exposes percentages. If you genuinely need a fixed-width column — say, a 50pt \"Qty\" column that doesn't scale with the page — you have to drop one layer down to the document tree:",[52,1119,1121],{"className":54,"code":1120,"language":56,"meta":57,"style":57},"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",[23,1122,1123,1133,1137,1155,1173,1192,1214,1235,1255,1260,1272,1284],{"__ignoreMap":57},[61,1124,1125,1127,1129,1131],{"class":63,"line":64},[61,1126,164],{"class":163},[61,1128,383],{"class":71},[61,1130,212],{"class":149},[61,1132,179],{"class":71},[61,1134,1135],{"class":63,"line":153},[61,1136,157],{"emptyLinePlaceholder":156},[61,1138,1139,1142,1144,1147,1149,1151,1153],{"class":63,"line":160},[61,1140,1141],{"class":67},"tbl ",[61,1143,269],{"class":71},[61,1145,1146],{"class":71}," &",[61,1148,319],{"class":149},[61,1150,72],{"class":71},[61,1152,76],{"class":149},[61,1154,424],{"class":71},[61,1156,1157,1160,1162,1164,1166,1168,1171],{"class":63,"line":170},[61,1158,1159],{"class":67},"    Columns",[61,1161,50],{"class":71},[61,1163,363],{"class":71},[61,1165,319],{"class":149},[61,1167,72],{"class":71},[61,1169,1170],{"class":149},"TableColumn",[61,1172,424],{"class":71},[61,1174,1175,1177,1180,1182,1185,1187,1190],{"class":63,"line":182},[61,1176,430],{"class":71},[61,1178,1179],{"class":67},"Width",[61,1181,50],{"class":71},[61,1183,1184],{"class":67}," document",[61,1186,72],{"class":71},[61,1188,1189],{"class":67},"Auto",[61,1191,466],{"class":71},[61,1193,1194,1196,1198,1200,1202,1204,1207,1209,1211],{"class":63,"line":192},[61,1195,430],{"class":71},[61,1197,1179],{"class":67},[61,1199,50],{"class":71},[61,1201,1184],{"class":67},[61,1203,72],{"class":71},[61,1205,1206],{"class":75},"Pt",[61,1208,79],{"class":71},[61,1210,1073],{"class":103},[61,1212,1213],{"class":71},")},\n",[61,1215,1216,1218,1220,1222,1224,1226,1228,1230,1233],{"class":63,"line":197},[61,1217,430],{"class":71},[61,1219,1179],{"class":67},[61,1221,50],{"class":71},[61,1223,1184],{"class":67},[61,1225,72],{"class":71},[61,1227,1206],{"class":75},[61,1229,79],{"class":71},[61,1231,1232],{"class":103},"80",[61,1234,1213],{"class":71},[61,1236,1237,1239,1241,1243,1245,1247,1249,1251,1253],{"class":63,"line":207},[61,1238,430],{"class":71},[61,1240,1179],{"class":67},[61,1242,50],{"class":71},[61,1244,1184],{"class":67},[61,1246,72],{"class":71},[61,1248,1206],{"class":75},[61,1250,79],{"class":71},[61,1252,1232],{"class":103},[61,1254,1213],{"class":71},[61,1256,1257],{"class":63,"line":217},[61,1258,1259],{"class":71},"    },\n",[61,1261,1262,1265,1267,1270],{"class":63,"line":227},[61,1263,1264],{"class":67},"    Header",[61,1266,50],{"class":71},[61,1268,1269],{"class":982}," /* ... */",[61,1271,668],{"class":71},[61,1273,1274,1277,1279,1282],{"class":63,"line":237},[61,1275,1276],{"class":67},"    Body",[61,1278,50],{"class":71},[61,1280,1281],{"class":982},"   /* ... */",[61,1283,668],{"class":71},[61,1285,1286],{"class":63,"line":243},[61,1287,408],{"class":71},[19,1289,1290,1291,1293,1294,1293,1296,1293,1298,1301,1302,1304,1305,1308],{},"Mix and match: ",[23,1292,1189],{},", ",[23,1295,1206],{},[23,1297,333],{},[23,1299,1300],{},"Pct"," all work at the document layer. The first column with ",[23,1303,1189],{}," gets whatever's left after the three fixed columns are subtracted. This is closer to the CSS ",[23,1306,1307],{},"\u003Ccol>"," element than to a percentage system.",[19,1310,1311,1312,1315],{},"You give up the convenience of ",[23,1313,1314],{},"c.Table(header, rows, ...)"," doing the cell construction for you, but for invoices that need to print on physical letterhead with stable column positions, the trade is worth it.",[14,1317,1319],{"id":1318},"related-recipes","Related recipes",[1321,1322,1323,1332],"ul",{},[1324,1325,1326,1331],"li",{},[1327,1328,1330],"a",{"href":1329},"/blog/12-column-grid","How does the 12-column grid work in gpdf?"," — how the row's 12 columns become the parent width that table percentages resolve against",[1324,1333,1334,1338,1339,1341],{},[1327,1335,1337],{"href":1336},"/blog/invoice-pdf-go-under-50-lines","Generate an invoice PDF in Go in under 50 lines"," — ",[23,1340,897],{}," in context with the rest of an invoice document",[14,1343,1345],{"id":1344},"try-gpdf","Try gpdf",[19,1347,1348],{},"gpdf is a Go library for generating PDFs. MIT licensed, zero external dependencies, native CJK support.",[52,1350,1354],{"className":1351,"code":1352,"language":1353,"meta":57,"style":57},"language-bash shiki shiki-themes material-theme-lighter material-theme material-theme-palenight","go get github.com/gpdf-dev/gpdf\n","bash",[23,1355,1356],{"__ignoreMap":57},[61,1357,1358,1360,1363],{"class":63,"line":64},[61,1359,56],{"class":149},[61,1361,1362],{"class":376}," get",[61,1364,1365],{"class":376}," github.com/gpdf-dev/gpdf\n",[19,1367,1368,1374,1375],{},[1327,1369,1373],{"href":1370,"rel":1371},"https://github.com/gpdf-dev/gpdf",[1372],"nofollow","⭐ Star on GitHub"," · ",[1327,1376,1379],{"href":1377,"rel":1378},"https://gpdf.dev/docs/quickstart",[1372],"Read the docs",[1381,1382,1383],"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":57,"searchDepth":153,"depth":153,"links":1385},[1386,1387,1388,1389,1391,1392,1393,1394,1395],{"id":16,"depth":153,"text":17},{"id":38,"depth":153,"text":39},{"id":135,"depth":153,"text":136},{"id":901,"depth":153,"text":1390},"What the percentages are a percentage of",{"id":941,"depth":153,"text":942},{"id":1099,"depth":153,"text":1100},{"id":1113,"depth":153,"text":1114},{"id":1318,"depth":153,"text":1319},{"id":1344,"depth":153,"text":1345},"2026-04-28","Pass template.ColumnWidths(...) to c.Table. Values are percentages of the parent column's width. Sum to 100; trailing missing values auto-distribute.",false,"md",{"name":1401,"totalTime":1402,"tools":1403,"steps":1405},"Set per-column widths on a table built with gpdf","PT10M",[1404],"Go 1.22+",[1406,1409,1412,1415],{"name":1407,"text":1408},"Build the table without widths first to confirm column count","Call c.Table(header, rows). With no ColumnWidths option, gpdf splits the parent column equally across the columns inferred from the header row.",{"name":1410,"text":1411},"Pass ColumnWidths as percentages summing to 100","Add template.ColumnWidths(40, 15, 20, 25) as the third argument to c.Table. Each value is a percentage of the table's parent width — the grid Col it lives in.",{"name":1413,"text":1414},"Use 0 to mark a column as auto-distributed","ColumnWidths(0, 30, 30) for a three-column table fixes the last two at 30% each and gives the remaining 40% to the first column.",{"name":1416,"text":1417},"Pass fewer widths than columns to let trailing columns share what's left","ColumnWidths(40, 30) on a three-column table assigns 40 / 30 / 30 — the third column gets the leftover 30 because it had no explicit entry.",null,{},"/blog/table-column-widths",{"title":5,"description":1397},"blog/014.table-column-widths",[1424,1425],"recipe","tutorial","KMX8jEZ0qSbUFiZDPJ7LmNlG5aBuLxxN8rJrKALvKXA",1779199010216]