[{"data":1,"prerenderedAt":1763},["ShallowReactive",2],{"blog-zh-multi-page-table":3},{"id":4,"title":5,"author":6,"body":10,"date":1728,"description":1729,"draft":1730,"extension":1731,"howTo":1732,"image":1753,"meta":1754,"navigation":140,"path":1755,"seo":1756,"stem":1757,"tags":1758,"updated":1753,"__hash__":1762},"blogZh/zh/blog/024.multi-page-table.md","如何让表格跨多页输出?",{"name":7,"url":8,"avatar":9},"Taiki Noda","https://nadai.dev/en/about","https://nadai.dev/og-default.png",{"type":11,"value":12,"toc":1716},"minimark",[13,17,29,32,40,84,103,106,121,1134,1140,1143,1168,1171,1195,1198,1205,1403,1417,1420,1423,1545,1556,1559,1593,1596,1637,1640,1676,1680,1683,1700,1712],[14,15,16],"h2",{"id":16},"换个说法",[18,19,20,21,28],"p",{},"我有一份报表 —— 发票明细、交易日志、300 行的导出 —— 显然装不进一张 A4。在 Go 的 PDF 库里,要让表格流到第 2 页、第 3 页,并且每页顶部重新出现表头,我得做什么? 在 ",[22,23,27],"a",{"href":24,"rel":25},"https://github.com/gpdf-dev/gpdf",[26],"nofollow","gpdf"," 里,答案很短。",[14,30,31],{"id":31},"结论",[18,33,34,35,39],{},"什么都不用做。写一次 ",[36,37,38],"code",{},"Table"," 调用,把所有行都给它,gpdf 就会分页:",[41,42,47],"pre",{"className":43,"code":44,"language":45,"meta":46,"style":46},"language-go shiki shiki-themes material-theme-lighter material-theme material-theme-palenight","c.Table(header, rows) // rows 有 300 条 —— gpdf 会把它分到多页\n","go","",[36,48,49],{"__ignoreMap":46},[50,51,54,58,62,65,68,71,74,77,80],"span",{"class":52,"line":53},"line",1,[50,55,57],{"class":56},"sTEyZ","c",[50,59,61],{"class":60},"sMK4o",".",[50,63,38],{"class":64},"s2Zo4",[50,66,67],{"class":60},"(",[50,69,70],{"class":56},"header",[50,72,73],{"class":60},",",[50,75,76],{"class":56}," rows",[50,78,79],{"class":60},")",[50,81,83],{"class":82},"sHwdD"," // rows 有 300 条 —— gpdf 会把它分到多页\n",[18,85,86,87,89,90,94,95,98,99,102],{},"表体会逐行分到所需的页数上。",[36,88,70],{}," 切片会",[91,92,93],"strong",{},"自动在每个续页顶部重新渲染"," —— 列宽、样式都一样。没有 ",[36,96,97],{},"PageBreak()"," 方法,没有 ",[36,100,101],{},"MaxRowsPerPage"," 选项,没有数行的循环。处理溢出是布局引擎的活,不是你的活。",[14,104,105],{"id":105},"可运行代码",[18,107,108,109,112,113,116,117,120],{},"一个输出跨页表格的完整程序。存为 ",[36,110,111],{},"main.go",",运行 ",[36,114,115],{},"go run .",",得到 ",[36,118,119],{},"report.pdf","。",[41,122,124],{"className":43,"code":123,"language":45,"meta":46,"style":46},"package main\n\nimport (\n    \"fmt\"\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    brand := pdf.RGBHex(0x1A237E)\n\n    header := []string{\"Date\", \"Invoice #\", \"Customer\", \"Amount\"}\n    rows := make([][]string, 0, 200)\n    for i := 1; i \u003C= 200; i++ {\n        rows = append(rows, []string{\n            fmt.Sprintf(\"2026-%02d-%02d\", (i%6)+1, (i%28)+1),\n            fmt.Sprintf(\"INV-%05d\", 10000+i),\n            fmt.Sprintf(\"Customer #%d\", i),\n            fmt.Sprintf(\"$%d.00\", 100+i*7),\n        })\n    }\n\n    page := doc.AddPage()\n    page.AutoRow(func(r *template.RowBuilder) {\n        r.Col(12, func(c *template.ColBuilder) {\n            c.Text(\"2026 Invoice Ledger\", template.FontSize(18), template.Bold())\n            c.Spacer(document.Mm(4))\n\n            c.Table(header, rows,\n                template.ColumnWidths(20, 20, 40, 20),\n                template.TableHeaderStyle(\n                    template.TextColor(pdf.White),\n                    template.BgColor(brand),\n                ),\n            )\n        })\n    })\n\n    data, err := doc.Generate()\n    if err != nil {\n        log.Fatal(err)\n    }\n    if err := os.WriteFile(\"report.pdf\", data, 0o644); err != nil {\n        log.Fatal(err)\n    }\n}\n",[36,125,126,135,142,152,164,174,184,189,199,209,219,229,235,240,255,275,298,336,342,347,370,375,433,461,495,521,587,620,647,687,693,699,704,723,756,792,840,866,871,891,922,934,957,974,980,986,991,997,1002,1024,1040,1058,1063,1109,1124,1129],{"__ignoreMap":46},[50,127,128,131],{"class":52,"line":53},[50,129,130],{"class":60},"package",[50,132,134],{"class":133},"sBMFI"," main\n",[50,136,138],{"class":52,"line":137},2,[50,139,141],{"emptyLinePlaceholder":140},true,"\n",[50,143,145,149],{"class":52,"line":144},3,[50,146,148],{"class":147},"s7zQu","import",[50,150,151],{"class":60}," (\n",[50,153,155,158,161],{"class":52,"line":154},4,[50,156,157],{"class":60},"    \"",[50,159,160],{"class":133},"fmt",[50,162,163],{"class":60},"\"\n",[50,165,167,169,172],{"class":52,"line":166},5,[50,168,157],{"class":60},[50,170,171],{"class":133},"log",[50,173,163],{"class":60},[50,175,177,179,182],{"class":52,"line":176},6,[50,178,157],{"class":60},[50,180,181],{"class":133},"os",[50,183,163],{"class":60},[50,185,187],{"class":52,"line":186},7,[50,188,141],{"emptyLinePlaceholder":140},[50,190,192,194,197],{"class":52,"line":191},8,[50,193,157],{"class":60},[50,195,196],{"class":133},"github.com/gpdf-dev/gpdf",[50,198,163],{"class":60},[50,200,202,204,207],{"class":52,"line":201},9,[50,203,157],{"class":60},[50,205,206],{"class":133},"github.com/gpdf-dev/gpdf/document",[50,208,163],{"class":60},[50,210,212,214,217],{"class":52,"line":211},10,[50,213,157],{"class":60},[50,215,216],{"class":133},"github.com/gpdf-dev/gpdf/pdf",[50,218,163],{"class":60},[50,220,222,224,227],{"class":52,"line":221},11,[50,223,157],{"class":60},[50,225,226],{"class":133},"github.com/gpdf-dev/gpdf/template",[50,228,163],{"class":60},[50,230,232],{"class":52,"line":231},12,[50,233,234],{"class":60},")\n",[50,236,238],{"class":52,"line":237},13,[50,239,141],{"emptyLinePlaceholder":140},[50,241,243,246,249,252],{"class":52,"line":242},14,[50,244,245],{"class":60},"func",[50,247,248],{"class":64}," main",[50,250,251],{"class":60},"()",[50,253,254],{"class":60}," {\n",[50,256,258,261,264,267,269,272],{"class":52,"line":257},15,[50,259,260],{"class":56},"    doc ",[50,262,263],{"class":60},":=",[50,265,266],{"class":56}," gpdf",[50,268,61],{"class":60},[50,270,271],{"class":64},"NewDocument",[50,273,274],{"class":60},"(\n",[50,276,278,281,283,286,288,290,292,295],{"class":52,"line":277},16,[50,279,280],{"class":56},"        gpdf",[50,282,61],{"class":60},[50,284,285],{"class":64},"WithPageSize",[50,287,67],{"class":60},[50,289,27],{"class":56},[50,291,61],{"class":60},[50,293,294],{"class":56},"A4",[50,296,297],{"class":60},"),\n",[50,299,301,303,305,308,310,313,315,318,320,322,324,327,329,333],{"class":52,"line":300},17,[50,302,280],{"class":56},[50,304,61],{"class":60},[50,306,307],{"class":64},"WithMargins",[50,309,67],{"class":60},[50,311,312],{"class":56},"document",[50,314,61],{"class":60},[50,316,317],{"class":64},"UniformEdges",[50,319,67],{"class":60},[50,321,312],{"class":56},[50,323,61],{"class":60},[50,325,326],{"class":64},"Mm",[50,328,67],{"class":60},[50,330,332],{"class":331},"sbssI","20",[50,334,335],{"class":60},"))),\n",[50,337,339],{"class":52,"line":338},18,[50,340,341],{"class":60},"    )\n",[50,343,345],{"class":52,"line":344},19,[50,346,141],{"emptyLinePlaceholder":140},[50,348,350,353,355,358,360,363,365,368],{"class":52,"line":349},20,[50,351,352],{"class":56},"    brand ",[50,354,263],{"class":60},[50,356,357],{"class":56}," pdf",[50,359,61],{"class":60},[50,361,362],{"class":64},"RGBHex",[50,364,67],{"class":60},[50,366,367],{"class":331},"0x1A237E",[50,369,234],{"class":60},[50,371,373],{"class":52,"line":372},21,[50,374,141],{"emptyLinePlaceholder":140},[50,376,378,381,383,386,390,393,396,400,402,404,407,410,412,414,416,419,421,423,425,428,430],{"class":52,"line":377},22,[50,379,380],{"class":56},"    header ",[50,382,263],{"class":60},[50,384,385],{"class":60}," []",[50,387,389],{"class":388},"spNyl","string",[50,391,392],{"class":60},"{",[50,394,395],{"class":60},"\"",[50,397,399],{"class":398},"sfazB","Date",[50,401,395],{"class":60},[50,403,73],{"class":60},[50,405,406],{"class":60}," \"",[50,408,409],{"class":398},"Invoice #",[50,411,395],{"class":60},[50,413,73],{"class":60},[50,415,406],{"class":60},[50,417,418],{"class":398},"Customer",[50,420,395],{"class":60},[50,422,73],{"class":60},[50,424,406],{"class":60},[50,426,427],{"class":398},"Amount",[50,429,395],{"class":60},[50,431,432],{"class":60},"}\n",[50,434,436,439,441,444,447,449,451,454,456,459],{"class":52,"line":435},23,[50,437,438],{"class":56},"    rows ",[50,440,263],{"class":60},[50,442,443],{"class":64}," make",[50,445,446],{"class":60},"([][]",[50,448,389],{"class":388},[50,450,73],{"class":60},[50,452,453],{"class":331}," 0",[50,455,73],{"class":60},[50,457,458],{"class":331}," 200",[50,460,234],{"class":60},[50,462,464,467,470,472,475,478,480,483,485,487,490,493],{"class":52,"line":463},24,[50,465,466],{"class":147},"    for",[50,468,469],{"class":56}," i ",[50,471,263],{"class":60},[50,473,474],{"class":331}," 1",[50,476,477],{"class":60},";",[50,479,469],{"class":56},[50,481,482],{"class":60},"\u003C=",[50,484,458],{"class":331},[50,486,477],{"class":60},[50,488,489],{"class":56}," i",[50,491,492],{"class":60},"++",[50,494,254],{"class":60},[50,496,498,501,504,507,509,512,514,516,518],{"class":52,"line":497},25,[50,499,500],{"class":56},"        rows ",[50,502,503],{"class":60},"=",[50,505,506],{"class":64}," append",[50,508,67],{"class":60},[50,510,511],{"class":56},"rows",[50,513,73],{"class":60},[50,515,385],{"class":60},[50,517,389],{"class":388},[50,519,520],{"class":60},"{\n",[50,522,524,527,529,532,534,536,539,543,546,548,550,552,555,558,561,564,567,570,572,574,576,578,581,583,585],{"class":52,"line":523},26,[50,525,526],{"class":56},"            fmt",[50,528,61],{"class":60},[50,530,531],{"class":64},"Sprintf",[50,533,67],{"class":60},[50,535,395],{"class":60},[50,537,538],{"class":398},"2026-",[50,540,542],{"class":541},"swJcz","%02d",[50,544,545],{"class":398},"-",[50,547,542],{"class":541},[50,549,395],{"class":60},[50,551,73],{"class":60},[50,553,554],{"class":60}," (",[50,556,557],{"class":56},"i",[50,559,560],{"class":60},"%",[50,562,563],{"class":331},"6",[50,565,566],{"class":60},")+",[50,568,569],{"class":331},"1",[50,571,73],{"class":60},[50,573,554],{"class":60},[50,575,557],{"class":56},[50,577,560],{"class":60},[50,579,580],{"class":331},"28",[50,582,566],{"class":60},[50,584,569],{"class":331},[50,586,297],{"class":60},[50,588,590,592,594,596,598,600,603,606,608,610,613,616,618],{"class":52,"line":589},27,[50,591,526],{"class":56},[50,593,61],{"class":60},[50,595,531],{"class":64},[50,597,67],{"class":60},[50,599,395],{"class":60},[50,601,602],{"class":398},"INV-",[50,604,605],{"class":541},"%05d",[50,607,395],{"class":60},[50,609,73],{"class":60},[50,611,612],{"class":331}," 10000",[50,614,615],{"class":60},"+",[50,617,557],{"class":56},[50,619,297],{"class":60},[50,621,623,625,627,629,631,633,636,639,641,643,645],{"class":52,"line":622},28,[50,624,526],{"class":56},[50,626,61],{"class":60},[50,628,531],{"class":64},[50,630,67],{"class":60},[50,632,395],{"class":60},[50,634,635],{"class":398},"Customer #",[50,637,638],{"class":541},"%d",[50,640,395],{"class":60},[50,642,73],{"class":60},[50,644,489],{"class":56},[50,646,297],{"class":60},[50,648,650,652,654,656,658,660,663,665,668,670,672,675,677,679,682,685],{"class":52,"line":649},29,[50,651,526],{"class":56},[50,653,61],{"class":60},[50,655,531],{"class":64},[50,657,67],{"class":60},[50,659,395],{"class":60},[50,661,662],{"class":398},"$",[50,664,638],{"class":541},[50,666,667],{"class":398},".00",[50,669,395],{"class":60},[50,671,73],{"class":60},[50,673,674],{"class":331}," 100",[50,676,615],{"class":60},[50,678,557],{"class":56},[50,680,681],{"class":60},"*",[50,683,684],{"class":331},"7",[50,686,297],{"class":60},[50,688,690],{"class":52,"line":689},30,[50,691,692],{"class":60},"        })\n",[50,694,696],{"class":52,"line":695},31,[50,697,698],{"class":60},"    }\n",[50,700,702],{"class":52,"line":701},32,[50,703,141],{"emptyLinePlaceholder":140},[50,705,707,710,712,715,717,720],{"class":52,"line":706},33,[50,708,709],{"class":56},"    page ",[50,711,263],{"class":60},[50,713,714],{"class":56}," doc",[50,716,61],{"class":60},[50,718,719],{"class":64},"AddPage",[50,721,722],{"class":60},"()\n",[50,724,726,729,731,734,737,741,744,747,749,752,754],{"class":52,"line":725},34,[50,727,728],{"class":56},"    page",[50,730,61],{"class":60},[50,732,733],{"class":64},"AutoRow",[50,735,736],{"class":60},"(func(",[50,738,740],{"class":739},"sHdIc","r",[50,742,743],{"class":60}," *",[50,745,746],{"class":133},"template",[50,748,61],{"class":60},[50,750,751],{"class":133},"RowBuilder",[50,753,79],{"class":60},[50,755,254],{"class":60},[50,757,759,762,764,767,769,772,774,777,779,781,783,785,788,790],{"class":52,"line":758},35,[50,760,761],{"class":56},"        r",[50,763,61],{"class":60},[50,765,766],{"class":64},"Col",[50,768,67],{"class":60},[50,770,771],{"class":331},"12",[50,773,73],{"class":60},[50,775,776],{"class":60}," func(",[50,778,57],{"class":739},[50,780,743],{"class":60},[50,782,746],{"class":133},[50,784,61],{"class":60},[50,786,787],{"class":133},"ColBuilder",[50,789,79],{"class":60},[50,791,254],{"class":60},[50,793,795,798,800,803,805,807,810,812,814,817,819,822,824,827,830,832,834,837],{"class":52,"line":794},36,[50,796,797],{"class":56},"            c",[50,799,61],{"class":60},[50,801,802],{"class":64},"Text",[50,804,67],{"class":60},[50,806,395],{"class":60},[50,808,809],{"class":398},"2026 Invoice Ledger",[50,811,395],{"class":60},[50,813,73],{"class":60},[50,815,816],{"class":56}," template",[50,818,61],{"class":60},[50,820,821],{"class":64},"FontSize",[50,823,67],{"class":60},[50,825,826],{"class":331},"18",[50,828,829],{"class":60},"),",[50,831,816],{"class":56},[50,833,61],{"class":60},[50,835,836],{"class":64},"Bold",[50,838,839],{"class":60},"())\n",[50,841,843,845,847,850,852,854,856,858,860,863],{"class":52,"line":842},37,[50,844,797],{"class":56},[50,846,61],{"class":60},[50,848,849],{"class":64},"Spacer",[50,851,67],{"class":60},[50,853,312],{"class":56},[50,855,61],{"class":60},[50,857,326],{"class":64},[50,859,67],{"class":60},[50,861,862],{"class":331},"4",[50,864,865],{"class":60},"))\n",[50,867,869],{"class":52,"line":868},38,[50,870,141],{"emptyLinePlaceholder":140},[50,872,874,876,878,880,882,884,886,888],{"class":52,"line":873},39,[50,875,797],{"class":56},[50,877,61],{"class":60},[50,879,38],{"class":64},[50,881,67],{"class":60},[50,883,70],{"class":56},[50,885,73],{"class":60},[50,887,76],{"class":56},[50,889,890],{"class":60},",\n",[50,892,894,897,899,902,904,906,908,911,913,916,918,920],{"class":52,"line":893},40,[50,895,896],{"class":56},"                template",[50,898,61],{"class":60},[50,900,901],{"class":64},"ColumnWidths",[50,903,67],{"class":60},[50,905,332],{"class":331},[50,907,73],{"class":60},[50,909,910],{"class":331}," 20",[50,912,73],{"class":60},[50,914,915],{"class":331}," 40",[50,917,73],{"class":60},[50,919,910],{"class":331},[50,921,297],{"class":60},[50,923,925,927,929,932],{"class":52,"line":924},41,[50,926,896],{"class":56},[50,928,61],{"class":60},[50,930,931],{"class":64},"TableHeaderStyle",[50,933,274],{"class":60},[50,935,937,940,942,945,947,950,952,955],{"class":52,"line":936},42,[50,938,939],{"class":56},"                    template",[50,941,61],{"class":60},[50,943,944],{"class":64},"TextColor",[50,946,67],{"class":60},[50,948,949],{"class":56},"pdf",[50,951,61],{"class":60},[50,953,954],{"class":56},"White",[50,956,297],{"class":60},[50,958,960,962,964,967,969,972],{"class":52,"line":959},43,[50,961,939],{"class":56},[50,963,61],{"class":60},[50,965,966],{"class":64},"BgColor",[50,968,67],{"class":60},[50,970,971],{"class":56},"brand",[50,973,297],{"class":60},[50,975,977],{"class":52,"line":976},44,[50,978,979],{"class":60},"                ),\n",[50,981,983],{"class":52,"line":982},45,[50,984,985],{"class":60},"            )\n",[50,987,989],{"class":52,"line":988},46,[50,990,692],{"class":60},[50,992,994],{"class":52,"line":993},47,[50,995,996],{"class":60},"    })\n",[50,998,1000],{"class":52,"line":999},48,[50,1001,141],{"emptyLinePlaceholder":140},[50,1003,1005,1008,1010,1013,1015,1017,1019,1022],{"class":52,"line":1004},49,[50,1006,1007],{"class":56},"    data",[50,1009,73],{"class":60},[50,1011,1012],{"class":56}," err ",[50,1014,263],{"class":60},[50,1016,714],{"class":56},[50,1018,61],{"class":60},[50,1020,1021],{"class":64},"Generate",[50,1023,722],{"class":60},[50,1025,1027,1030,1032,1035,1038],{"class":52,"line":1026},50,[50,1028,1029],{"class":147},"    if",[50,1031,1012],{"class":56},[50,1033,1034],{"class":60},"!=",[50,1036,1037],{"class":60}," nil",[50,1039,254],{"class":60},[50,1041,1043,1046,1048,1051,1053,1056],{"class":52,"line":1042},51,[50,1044,1045],{"class":56},"        log",[50,1047,61],{"class":60},[50,1049,1050],{"class":64},"Fatal",[50,1052,67],{"class":60},[50,1054,1055],{"class":56},"err",[50,1057,234],{"class":60},[50,1059,1061],{"class":52,"line":1060},52,[50,1062,698],{"class":60},[50,1064,1066,1068,1070,1072,1075,1077,1080,1082,1084,1086,1088,1090,1093,1095,1098,1101,1103,1105,1107],{"class":52,"line":1065},53,[50,1067,1029],{"class":147},[50,1069,1012],{"class":56},[50,1071,263],{"class":60},[50,1073,1074],{"class":56}," os",[50,1076,61],{"class":60},[50,1078,1079],{"class":64},"WriteFile",[50,1081,67],{"class":60},[50,1083,395],{"class":60},[50,1085,119],{"class":398},[50,1087,395],{"class":60},[50,1089,73],{"class":60},[50,1091,1092],{"class":56}," data",[50,1094,73],{"class":60},[50,1096,1097],{"class":331}," 0o644",[50,1099,1100],{"class":60},");",[50,1102,1012],{"class":56},[50,1104,1034],{"class":60},[50,1106,1037],{"class":60},[50,1108,254],{"class":60},[50,1110,1112,1114,1116,1118,1120,1122],{"class":52,"line":1111},54,[50,1113,1045],{"class":56},[50,1115,61],{"class":60},[50,1117,1050],{"class":64},[50,1119,67],{"class":60},[50,1121,1055],{"class":56},[50,1123,234],{"class":60},[50,1125,1127],{"class":52,"line":1126},55,[50,1128,698],{"class":60},[50,1130,1132],{"class":52,"line":1131},56,[50,1133,432],{"class":60},[18,1135,1136,1137,120],{},"200 行铺到 A4 上大约是 8 页。每一页顶部都坐着深蓝色的表头;表体从上一页停下的地方接着来。这段代码里唯一暗示「跨页」的,只有循环上界的 ",[36,1138,1139],{},"200",[14,1141,1142],{"id":1142},"它是怎么工作的",[18,1144,1145,1146,1150,1151,1157,1158,1163,1164,1167],{},"值得了解一下,这样你才会信任它。布局引擎布局表格时,按顺序测量表体行,一直往当前页里加,直到下一行会超出可用高度。没装下的行变成一个",[1147,1148,1149],"em",{},"溢出表格"," —— 一个携带",[91,1152,1153,1154],{},"相同 ",[36,1155,1156],{},"Header","、",[91,1159,1153,1160],{},[36,1161,1162],{},"Footer"," 和剩余表体行的新 ",[36,1165,1166],{},"*document.Table","。gpdf 把已布局的部分刷到页面上,开下一页,再用新页的高度把溢出表格喂回布局引擎。重复,直到没有剩余。",[18,1169,1170],{},"由此得出两件事:",[1172,1173,1174,1185],"ul",{},[1175,1176,1177,1184],"li",{},[91,1178,1179,1180,1183],{},"表头会重复,是因为它在 ",[36,1181,1182],{},"tbl.Header"," 里,不在你的循环里。"," 溢出表格复用同一个切片,所以它在每页上渲染得一模一样。这是白送的。",[1175,1186,1187,1190,1191,1194],{},[91,1188,1189],{},"不存在「表头装不下」这种边界情况。"," 引擎在测量能装几行表体",[1147,1192,1193],{},"之前","就为表头预留了高度。如果一页装不下表头加至少一行表体,整个表格会被推到下一页,而不是被尴尬地切开。",[14,1196,1197],{"id":1197},"页脚也会重复",[18,1199,1200,1201,1204],{},"如果想要一个合计行(或「本页小计」)也出现在每页底部,那就是 ",[36,1202,1203],{},"document.Table.Footer"," —— 在 document 层而不是通过 builder 构建表格时可用:",[41,1206,1208],{"className":43,"code":1207,"language":45,"meta":46,"style":46},"import \"github.com/gpdf-dev/gpdf/document\"\n\ntbl := &document.Table{\n    Columns: []document.TableColumn{\n        {Width: document.Pct(20)}, {Width: document.Pct(20)},\n        {Width: document.Auto},    {Width: document.Pct(20)},\n    },\n    Header: headerRows, // []document.TableRow\n    Body:   bodyRows,\n    Footer: []document.TableRow{footerRow},\n}\n",[36,1209,1210,1220,1224,1242,1261,1306,1343,1348,1363,1375,1399],{"__ignoreMap":46},[50,1211,1212,1214,1216,1218],{"class":52,"line":53},[50,1213,148],{"class":147},[50,1215,406],{"class":60},[50,1217,206],{"class":133},[50,1219,163],{"class":60},[50,1221,1222],{"class":52,"line":137},[50,1223,141],{"emptyLinePlaceholder":140},[50,1225,1226,1229,1231,1234,1236,1238,1240],{"class":52,"line":144},[50,1227,1228],{"class":56},"tbl ",[50,1230,263],{"class":60},[50,1232,1233],{"class":60}," &",[50,1235,312],{"class":133},[50,1237,61],{"class":60},[50,1239,38],{"class":133},[50,1241,520],{"class":60},[50,1243,1244,1247,1250,1252,1254,1256,1259],{"class":52,"line":154},[50,1245,1246],{"class":56},"    Columns",[50,1248,1249],{"class":60},":",[50,1251,385],{"class":60},[50,1253,312],{"class":133},[50,1255,61],{"class":60},[50,1257,1258],{"class":133},"TableColumn",[50,1260,520],{"class":60},[50,1262,1263,1266,1269,1271,1274,1276,1279,1281,1283,1286,1289,1291,1293,1295,1297,1299,1301,1303],{"class":52,"line":166},[50,1264,1265],{"class":60},"        {",[50,1267,1268],{"class":56},"Width",[50,1270,1249],{"class":60},[50,1272,1273],{"class":56}," document",[50,1275,61],{"class":60},[50,1277,1278],{"class":64},"Pct",[50,1280,67],{"class":60},[50,1282,332],{"class":331},[50,1284,1285],{"class":60},")},",[50,1287,1288],{"class":60}," {",[50,1290,1268],{"class":56},[50,1292,1249],{"class":60},[50,1294,1273],{"class":56},[50,1296,61],{"class":60},[50,1298,1278],{"class":64},[50,1300,67],{"class":60},[50,1302,332],{"class":331},[50,1304,1305],{"class":60},")},\n",[50,1307,1308,1310,1312,1314,1316,1318,1321,1324,1327,1329,1331,1333,1335,1337,1339,1341],{"class":52,"line":176},[50,1309,1265],{"class":60},[50,1311,1268],{"class":56},[50,1313,1249],{"class":60},[50,1315,1273],{"class":56},[50,1317,61],{"class":60},[50,1319,1320],{"class":56},"Auto",[50,1322,1323],{"class":60},"},",[50,1325,1326],{"class":60},"    {",[50,1328,1268],{"class":56},[50,1330,1249],{"class":60},[50,1332,1273],{"class":56},[50,1334,61],{"class":60},[50,1336,1278],{"class":64},[50,1338,67],{"class":60},[50,1340,332],{"class":331},[50,1342,1305],{"class":60},[50,1344,1345],{"class":52,"line":186},[50,1346,1347],{"class":60},"    },\n",[50,1349,1350,1353,1355,1358,1360],{"class":52,"line":191},[50,1351,1352],{"class":56},"    Header",[50,1354,1249],{"class":60},[50,1356,1357],{"class":56}," headerRows",[50,1359,73],{"class":60},[50,1361,1362],{"class":82}," // []document.TableRow\n",[50,1364,1365,1368,1370,1373],{"class":52,"line":201},[50,1366,1367],{"class":56},"    Body",[50,1369,1249],{"class":60},[50,1371,1372],{"class":56},"   bodyRows",[50,1374,890],{"class":60},[50,1376,1377,1380,1382,1384,1386,1388,1391,1393,1396],{"class":52,"line":211},[50,1378,1379],{"class":56},"    Footer",[50,1381,1249],{"class":60},[50,1383,385],{"class":60},[50,1385,312],{"class":133},[50,1387,61],{"class":60},[50,1389,1390],{"class":133},"TableRow",[50,1392,392],{"class":60},[50,1394,1395],{"class":56},"footerRow",[50,1397,1398],{"class":60},"},\n",[50,1400,1401],{"class":52,"line":221},[50,1402,432],{"class":60},[18,1404,1405,1407,1408,1411,1412,1416],{},[36,1406,1162],{}," 切片在每个续页上重复,机制和表头一样。builder 的 ",[36,1409,1410],{},"c.Table(...)"," 没暴露页脚,是因为大多数短表格不需要 —— 一旦需要,你就已经离开了「常见情况」区。",[22,1413,1415],{"href":1414},"/zh/blog/tables-in-go-pdfs","表格深入讲解","会走一遍 document 层。",[14,1418,1419],{"id":1419},"强制表格从新页开始",[18,1421,1422],{},"没有针对单个表格的「从新页开始」选项。在页级别做 —— 在持有表格的那一行之前加一页:",[41,1424,1426],{"className":43,"code":1425,"language":45,"meta":46,"style":46},"doc.AddPage() // 下面的表格从这一页顶部开始\npage2 := doc.AddPage()\npage2.AutoRow(func(r *template.RowBuilder) {\n    r.Col(12, func(c *template.ColBuilder) {\n        c.Table(header, rows /* , opts... */)\n    })\n})\n",[36,1427,1428,1442,1457,1482,1513,1536,1540],{"__ignoreMap":46},[50,1429,1430,1433,1435,1437,1439],{"class":52,"line":53},[50,1431,1432],{"class":56},"doc",[50,1434,61],{"class":60},[50,1436,719],{"class":64},[50,1438,251],{"class":60},[50,1440,1441],{"class":82}," // 下面的表格从这一页顶部开始\n",[50,1443,1444,1447,1449,1451,1453,1455],{"class":52,"line":137},[50,1445,1446],{"class":56},"page2 ",[50,1448,263],{"class":60},[50,1450,714],{"class":56},[50,1452,61],{"class":60},[50,1454,719],{"class":64},[50,1456,722],{"class":60},[50,1458,1459,1462,1464,1466,1468,1470,1472,1474,1476,1478,1480],{"class":52,"line":144},[50,1460,1461],{"class":56},"page2",[50,1463,61],{"class":60},[50,1465,733],{"class":64},[50,1467,736],{"class":60},[50,1469,740],{"class":739},[50,1471,743],{"class":60},[50,1473,746],{"class":133},[50,1475,61],{"class":60},[50,1477,751],{"class":133},[50,1479,79],{"class":60},[50,1481,254],{"class":60},[50,1483,1484,1487,1489,1491,1493,1495,1497,1499,1501,1503,1505,1507,1509,1511],{"class":52,"line":154},[50,1485,1486],{"class":56},"    r",[50,1488,61],{"class":60},[50,1490,766],{"class":64},[50,1492,67],{"class":60},[50,1494,771],{"class":331},[50,1496,73],{"class":60},[50,1498,776],{"class":60},[50,1500,57],{"class":739},[50,1502,743],{"class":60},[50,1504,746],{"class":133},[50,1506,61],{"class":60},[50,1508,787],{"class":133},[50,1510,79],{"class":60},[50,1512,254],{"class":60},[50,1514,1515,1518,1520,1522,1524,1526,1528,1531,1534],{"class":52,"line":166},[50,1516,1517],{"class":56},"        c",[50,1519,61],{"class":60},[50,1521,38],{"class":64},[50,1523,67],{"class":60},[50,1525,70],{"class":56},[50,1527,73],{"class":60},[50,1529,1530],{"class":56}," rows ",[50,1532,1533],{"class":82},"/* , opts... */",[50,1535,234],{"class":60},[50,1537,1538],{"class":52,"line":176},[50,1539,996],{"class":60},[50,1541,1542],{"class":52,"line":186},[50,1543,1544],{"class":60},"})\n",[18,1546,1547,1548,1551,1552,1555],{},"表格需要的「分页」控制就这一个,因为表格",[1147,1549,1550],{},"内部","的分页已经替你处理好了,",[1147,1553,1554],{},"外部","的分页只不过是「这个块从哪开始」。",[14,1557,1558],{"id":1558},"做不到的事",[1172,1560,1561,1567,1584],{},[1175,1562,1563,1566],{},[91,1564,1565],{},"「这几行保持在一起」。"," 每一行表体都可被切分。没有「第 4–7 行这组必须在同一页」这样的注解。这是已知的缺口。如果一条发票明细加它的子行绝对不能被跨页撕开,变通办法是在那组之前开新页,或在 document 层构建表格并插入自己的分页提示。",[1175,1568,1569,1572,1573,1575,1576,1579,1580,1583],{},[91,1570,1571],{},"只在最后一页的页脚。"," ",[36,1574,1203],{}," 按设计在",[1147,1577,1578],{},"每一","页重复(每页列合计是常见情况)。文档末尾要一次性的总计,就在表格",[1147,1581,1582],{},"之后","作为单独的块加进去,而不是放在里面。",[1175,1585,1586,1589,1590,120],{},[91,1587,1588],{},"表格里的页码。"," 「第 3 页/共 8 页」属于文档页脚,不属于表格。它放在哪见",[22,1591,1592],{"href":1414},"页码、页眉和页脚",[14,1594,1595],{"id":1595},"浪费十分钟的错误",[1172,1597,1598,1608,1622,1631],{},[1175,1599,1600,1607],{},[91,1601,1602,1603,1606],{},"去找 ",[36,1604,1605],{},"PageBreak"," 选项。"," 没有,你也不想要 —— 你在手动调它的时候就已经输了。把所有行都传进去就行。",[1175,1609,1610,1613,1614,1617,1618,1621],{},[91,1611,1612],{},"自己把数据切成每页一块。"," 有人在第 1 页 ",[36,1615,1616],{},"rows[0:40]","、第 2 页 ",[36,1619,1620],{},"rows[40:80]","…… 别。你会在某处算错行,最后一页会变短,表头样式会漂移。把整个切片交给 gpdf。",[1175,1623,1624,1627,1628,1630],{},[91,1625,1626],{},"以为表头只在第 1 页。"," 有些库是那样。gpdf 在",[1147,1629,1578],{},"页重复,这正是给打印出来翻阅的报表所需要的。",[1175,1632,1633,1636],{},[91,1634,1635],{},"150 页的表格配 6 MB 的 CJK 字体。"," 字体会被子集化到实际用到的字形,所以没问题 —— 输出仍然很小。但如果你出于某种原因关掉了子集化,长表格就是它咬人的地方。把子集化保持开启(默认)。",[14,1638,1639],{"id":1639},"相关菜谱",[1172,1641,1642,1652,1662,1669],{},[1175,1643,1644,1647,1648,1651],{},[22,1645,1646],{"href":1414},"Go PDF 里的表格:列宽、斑马纹、分页"," —— 含 ",[36,1649,1650],{},"document.Table"," 和页脚的长文。",[1175,1653,1654,1658,1659,1661],{},[22,1655,1657],{"href":1656},"/zh/blog/table-column-widths","如何为表格设置自定义列宽?"," —— ",[36,1660,901],{}," 的边界情况。",[1175,1663,1664,1668],{},[22,1665,1667],{"href":1666},"/zh/blog/zebra-striped-table-rows","如何给表格加斑马纹行?"," —— 以及斑马纹为何跨页仍然对齐。",[1175,1670,1671,1675],{},[22,1672,1674],{"href":1673},"/zh/blog/invoice-pdf-go-under-50-lines","用 Go 在 50 行以内生成发票 PDF"," —— 一份含分页表格的真实文档。",[14,1677,1679],{"id":1678},"试试-gpdf","试试 gpdf",[18,1681,1682],{},"gpdf 是一个 Go 的 PDF 生成库。MIT 许可、零外部依赖、原生支持 CJK。",[41,1684,1688],{"className":1685,"code":1686,"language":1687,"meta":46,"style":46},"language-bash shiki shiki-themes material-theme-lighter material-theme material-theme-palenight","go get github.com/gpdf-dev/gpdf\n","bash",[36,1689,1690],{"__ignoreMap":46},[50,1691,1692,1694,1697],{"class":52,"line":53},[50,1693,45],{"class":133},[50,1695,1696],{"class":398}," get",[50,1698,1699],{"class":398}," github.com/gpdf-dev/gpdf\n",[18,1701,1702,1706,1707],{},[22,1703,1705],{"href":24,"rel":1704},[26],"⭐ Star on GitHub"," · ",[22,1708,1711],{"href":1709,"rel":1710},"https://gpdf.dev/docs/quickstart",[26],"Read the docs",[1713,1714,1715],"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 .sHwdD, html code.shiki .sHwdD{--shiki-light:#90A4AE;--shiki-light-font-style:italic;--shiki-default:#546E7A;--shiki-default-font-style:italic;--shiki-dark:#676E95;--shiki-dark-font-style:italic}html .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 .sbssI, html code.shiki .sbssI{--shiki-light:#F76D47;--shiki-default:#F78C6C;--shiki-dark:#F78C6C}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 .swJcz, html code.shiki .swJcz{--shiki-light:#E53935;--shiki-default:#F07178;--shiki-dark:#F07178}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}",{"title":46,"searchDepth":137,"depth":137,"links":1717},[1718,1719,1720,1721,1722,1723,1724,1725,1726,1727],{"id":16,"depth":137,"text":16},{"id":31,"depth":137,"text":31},{"id":105,"depth":137,"text":105},{"id":1142,"depth":137,"text":1142},{"id":1197,"depth":137,"text":1197},{"id":1419,"depth":137,"text":1419},{"id":1558,"depth":137,"text":1558},{"id":1595,"depth":137,"text":1595},{"id":1639,"depth":137,"text":1639},{"id":1678,"depth":137,"text":1679},"2026-05-12","什么都不用做。给 gpdf 传一个行数超过一页的表格,它会自动把表体分页,并在每一页顶部重复表头。",false,"md",{"name":1733,"totalTime":1734,"tools":1735,"steps":1737},"在 gpdf 中输出表头自动重复的跨页表格","PT10M",[1736,196],"Go 1.22+",[1738,1741,1744,1747,1750],{"name":1739,"text":1740},"在 Col 里调用一次 Table","在 page.AutoRow → r.Col(12, ...) 中调用 c.Table(header, rows)。header 是 []string,rows 是 [][]string。不写循环、不数行数、不调任何分页方法。",{"name":1742,"text":1743},"传入超过一页容量的行数","把数据的全部行直接 append 进去。当表体溢出当前页时,gpdf 的布局引擎会生成一个携带剩余行的溢出表格,并在下一页继续。",{"name":1745,"text":1746},"让 gpdf 重复表头","Header 切片会自动在每个续页顶部重新渲染 —— 样式相同、列宽相同。没有开关来启用它,这就是默认行为。",{"name":1748,"text":1749},"需要每页小计时使用 document.Table.Footer","想要在每页底部也重复的页脚行(列合计、页码标记)时,在 document 层用 &document.Table{Header, Body, Footer} 构建。",{"name":1751,"text":1752},"想从新页开始就先调 doc.AddPage()","如果希望表格从新页顶部开始而不是接着上一段内容,先加一页。没有针对单个表格的「从新页开始」选项。",null,{},"/zh/blog/multi-page-table",{"title":5,"description":1729},"zh/blog/024.multi-page-table",[1759,1760,1761],"recipe","tutorial","templates","80IwLEfqo-GfLIyswSLSre3rfWzJUUB_8MYDrvGydVI",1779199016619]