[{"data":1,"prerenderedAt":2395},["ShallowReactive",2],{"doc:\u002Fautomating-reporting-workflows\u002Fexporting-excel-reports-to-pdf\u002Ffit-an-excel-sheet-to-one-page-in-pdf":3,"surround:\u002Fautomating-reporting-workflows\u002Fexporting-excel-reports-to-pdf\u002Ffit-an-excel-sheet-to-one-page-in-pdf":2363,"ancestors:\u002Fautomating-reporting-workflows\u002Fexporting-excel-reports-to-pdf\u002Ffit-an-excel-sheet-to-one-page-in-pdf":2371,"children:\u002Fautomating-reporting-workflows\u002Fexporting-excel-reports-to-pdf\u002Ffit-an-excel-sheet-to-one-page-in-pdf":2376,"related:\u002Fautomating-reporting-workflows\u002Fexporting-excel-reports-to-pdf\u002Ffit-an-excel-sheet-to-one-page-in-pdf":2377},{"id":4,"title":5,"body":6,"dateModified":2330,"datePublished":2330,"description":2331,"extension":2332,"faq":2333,"keyword":2342,"kind":2343,"meta":2344,"navigation":267,"path":2352,"seo":2353,"slug":2356,"stem":2357,"topics":2358,"type":2361,"__hash__":2362},"docs\u002Fautomating-reporting-workflows\u002Fexporting-excel-reports-to-pdf\u002Ffit-an-excel-sheet-to-one-page-in-pdf\u002Findex.md","Fit an Excel Sheet to One Page Wide When Exporting to PDF",{"type":7,"value":8,"toc":2317},"minimark",[9,19,158,163,192,200,674,678,693,764,776,779,783,786,1257,1260,1364,1368,1371,1502,1505,1509,1512,1583,1590,1594,1597,1786,1797,1939,1943,1950,2188,2193,2197,2238,2242,2252,2256,2262,2268,2274,2280,2284,2313],[10,11,12,13,18],"p",{},"A wide monthly report exported to PDF comes out as nine pages: the first three months on page one, the next months on page four, and nobody can match a number to its row. Fit-to-page fixes the split in three lines of openpyxl, and creates a new problem: the text shrinks until everything fits, possibly to a size nobody can read. This guide, part of ",[14,15,17],"a",{"href":16},"\u002Fautomating-reporting-workflows\u002Fexporting-excel-reports-to-pdf\u002F","Exporting Excel Reports to PDF",", sets the sheet to one page wide, predicts the printed text size before converting, and uses the layout changes that keep it readable. Each layout below was exported through LibreOffice and measured.",[20,21,29,30,29,34,29,38,29,46,29,56,29,63,29,68,29,73,29,76,29,80,29,85,29,90,29,93,29,97,29,102,29,107,29,110,29,114,29,117,29,121,29,124,29,128,29,133,29,138,29,141,29,145,29,148,29,152],"svg",{"viewBox":22,"role":23,"ariaLabelledBy":24,"xmlns":27,"style":28},"4 0 734 286","img",[25,26],"fp-sizes-t","fp-sizes-d","http:\u002F\u002Fwww.w3.org\u002F2000\u002Fsvg","width:100%;max-width:734px;height:auto;display:block;margin:1.5rem auto;font-family:Inter,ui-sans-serif,system-ui,sans-serif","\n  ",[31,32,33],"title",{"id":25},"Printed size of 11-point text, 18-column report on A4",[35,36,37],"desc",{"id":26},"Measured in PDF exports of an 18-column, 120-row sheet. Without scaling the text stays at 11 points but the sheet spreads over 9 pages. Fit to one page wide in portrait shrinks it to 4.4 points. Landscape gives 6.7 points, landscape with narrow margins 7.4, and hiding four helper columns 9.2. Two pages wide with the label column repeated gives 8.6 points in portrait.",[39,40],"rect",{"x":41,"y":42,"width":43,"height":44,"fill":45},"4","0","734","286","#ffffff",[39,47],{"x":48,"y":49,"width":50,"height":51,"rx":52,"fill":53,"stroke":54,"style":55},"20.0","16.0","167.9","28.0","7","#e7ebef","var(--line,#cdd5e6)","stroke-width:1px",[57,58,62],"text",{"x":59,"y":60,"style":61},"104.0","34.5","font-size:12.5px;font-weight:700;fill:var(--text,#172033);text-anchor:middle","no scaling (9 pages)",[39,64],{"x":65,"y":49,"width":66,"height":51,"rx":52,"fill":53,"stroke":54,"style":67},"197.9","489.3","stroke-width:1.5px",[57,69,72],{"x":70,"y":60,"style":71},"695.2","font-size:12px;font-weight:700;fill:var(--text,#172033);text-anchor:start","11 pt",[39,74],{"x":48,"y":75,"width":50,"height":51,"rx":52,"fill":53,"stroke":54,"style":55},"56.0",[57,77,79],{"x":59,"y":78,"style":61},"74.5","fit width, portrait",[39,81],{"x":65,"y":75,"width":82,"height":51,"rx":52,"fill":83,"stroke":84,"style":67},"195.7","#fce9e9","var(--danger,#dc2626)",[57,86,89],{"x":87,"y":78,"style":88},"401.7","font-size:12px;font-weight:700;fill:var(--accent-ink,#be185d);text-anchor:start","4.4 pt",[39,91],{"x":48,"y":92,"width":50,"height":51,"rx":52,"fill":53,"stroke":54,"style":55},"96.0",[57,94,96],{"x":59,"y":95,"style":61},"114.5","fit width, landscape",[39,98],{"x":65,"y":92,"width":99,"height":51,"rx":52,"fill":100,"stroke":101,"style":67},"298.0","#fdefd8","var(--gold,#b4740a)",[57,103,106],{"x":104,"y":95,"style":105},"504.0","font-size:12px;font-weight:700;fill:var(--gold-ink,#7a4e06);text-anchor:start","6.7 pt",[39,108],{"x":48,"y":109,"width":50,"height":51,"rx":52,"fill":53,"stroke":54,"style":55},"136.0",[57,111,113],{"x":59,"y":112,"style":61},"154.5","+ narrow margins",[39,115],{"x":65,"y":109,"width":116,"height":51,"rx":52,"fill":100,"stroke":101,"style":67},"329.2",[57,118,120],{"x":119,"y":112,"style":105},"535.1","7.4 pt",[39,122],{"x":48,"y":123,"width":50,"height":51,"rx":52,"fill":53,"stroke":54,"style":55},"176.0",[57,125,127],{"x":59,"y":126,"style":61},"194.5","+ 4 columns hidden",[39,129],{"x":65,"y":123,"width":130,"height":51,"rx":52,"fill":131,"stroke":132,"style":67},"409.2","#d9f4f1","var(--teal,#0f9488)",[57,134,137],{"x":135,"y":126,"style":136},"615.2","font-size:12px;font-weight:700;fill:var(--teal-ink,#0b6157);text-anchor:start","9.2 pt",[39,139],{"x":48,"y":140,"width":50,"height":51,"rx":52,"fill":53,"stroke":54,"style":55},"216.0",[57,142,144],{"x":59,"y":143,"style":61},"234.5","2 pages wide, portrait",[39,146],{"x":65,"y":140,"width":147,"height":51,"rx":52,"fill":131,"stroke":132,"style":67},"382.5",[57,149,151],{"x":150,"y":143,"style":136},"588.5","8.6 pt",[57,153,157],{"x":154,"y":155,"style":156},"380.0","266.0","font-size:12.5px;font-weight:400;fill:var(--muted,#5b6780);text-anchor:middle","fitting always works; whether the result is readable depends on the layout",[159,160,162],"h2",{"id":161},"prerequisites","Prerequisites",[164,165,170],"pre",{"className":166,"code":167,"language":168,"meta":169,"style":169},"language-bash shiki shiki-themes github-light github-dark-high-contrast","pip install openpyxl pypdf\n","bash","",[171,172,173],"code",{"__ignoreMap":169},[174,175,178,182,186,189],"span",{"class":176,"line":177},"line",1,[174,179,181],{"class":180},"sMTad","pip",[174,183,185],{"class":184},"srMev"," install",[174,187,188],{"class":184}," openpyxl",[174,190,191],{"class":184}," pypdf\n",[10,193,194,195,199],{},"The PDF conversion uses LibreOffice on Linux or macOS, as described in ",[14,196,198],{"href":197},"\u002Fautomating-reporting-workflows\u002Fexporting-excel-reports-to-pdf\u002Fconvert-excel-to-pdf-on-linux-with-libreoffice\u002F","Convert Excel to PDF on Linux with LibreOffice","; Excel itself honours the same settings. A wide report to work with — twelve months plus five summary columns:",[164,201,205],{"className":202,"code":203,"language":204,"meta":169,"style":169},"language-python shiki shiki-themes github-light github-dark-high-contrast","from openpyxl import Workbook\nfrom openpyxl.utils import get_column_letter\nfrom openpyxl.worksheet.page import PageMargins\nfrom openpyxl.worksheet.properties import PageSetupProperties\n\ndef make_report():\n    wb = Workbook()\n    ws = wb.active\n    ws.title = \"Sales\"\n    months = [\"Jan\", \"Feb\", \"Mar\", \"Apr\", \"May\", \"Jun\", \"Jul\", \"Aug\", \"Sep\", \"Oct\", \"Nov\", \"Dec\"]\n    ws.append([\"Region\"] + [f\"{m} 2026\" for m in months] + [\"Total\", \"Target\", \"Variance\", \"Share\", \"Notes\"])\n    for r in range(120):\n        ws.append([f\"Store {r + 1:03d}\"] + [1000 + r * 13 + c * 7 for c in range(12)] + [0, 0, 0, 0.1, \"ok\"])\n    for c in range(1, 19):\n        ws.column_dimensions[get_column_letter(c)].width = 12\n    ws.page_setup.paperSize = ws.PAPERSIZE_A4\n    return wb\n\nwb = make_report()\nws = wb.active\n","python",[171,206,207,223,236,249,262,269,282,294,305,316,389,467,491,591,614,625,639,648,653,664],{"__ignoreMap":169},[174,208,209,213,217,220],{"class":176,"line":177},[174,210,212],{"class":211},"s-kum","from",[174,214,216],{"class":215},"skGVy"," openpyxl ",[174,218,219],{"class":211},"import",[174,221,222],{"class":215}," Workbook\n",[174,224,226,228,231,233],{"class":176,"line":225},2,[174,227,212],{"class":211},[174,229,230],{"class":215}," openpyxl.utils ",[174,232,219],{"class":211},[174,234,235],{"class":215}," get_column_letter\n",[174,237,239,241,244,246],{"class":176,"line":238},3,[174,240,212],{"class":211},[174,242,243],{"class":215}," openpyxl.worksheet.page ",[174,245,219],{"class":211},[174,247,248],{"class":215}," PageMargins\n",[174,250,252,254,257,259],{"class":176,"line":251},4,[174,253,212],{"class":211},[174,255,256],{"class":215}," openpyxl.worksheet.properties ",[174,258,219],{"class":211},[174,260,261],{"class":215}," PageSetupProperties\n",[174,263,265],{"class":176,"line":264},5,[174,266,268],{"emptyLinePlaceholder":267},true,"\n",[174,270,272,275,279],{"class":176,"line":271},6,[174,273,274],{"class":211},"def",[174,276,278],{"class":277},"s_Opv"," make_report",[174,280,281],{"class":215},"():\n",[174,283,285,288,291],{"class":176,"line":284},7,[174,286,287],{"class":215},"    wb ",[174,289,290],{"class":211},"=",[174,292,293],{"class":215}," Workbook()\n",[174,295,297,300,302],{"class":176,"line":296},8,[174,298,299],{"class":215},"    ws ",[174,301,290],{"class":211},[174,303,304],{"class":215}," wb.active\n",[174,306,308,311,313],{"class":176,"line":307},9,[174,309,310],{"class":215},"    ws.title ",[174,312,290],{"class":211},[174,314,315],{"class":184}," \"Sales\"\n",[174,317,319,322,324,327,330,333,336,338,341,343,346,348,351,353,356,358,361,363,366,368,371,373,376,378,381,383,386],{"class":176,"line":318},10,[174,320,321],{"class":215},"    months ",[174,323,290],{"class":211},[174,325,326],{"class":215}," [",[174,328,329],{"class":184},"\"Jan\"",[174,331,332],{"class":215},", ",[174,334,335],{"class":184},"\"Feb\"",[174,337,332],{"class":215},[174,339,340],{"class":184},"\"Mar\"",[174,342,332],{"class":215},[174,344,345],{"class":184},"\"Apr\"",[174,347,332],{"class":215},[174,349,350],{"class":184},"\"May\"",[174,352,332],{"class":215},[174,354,355],{"class":184},"\"Jun\"",[174,357,332],{"class":215},[174,359,360],{"class":184},"\"Jul\"",[174,362,332],{"class":215},[174,364,365],{"class":184},"\"Aug\"",[174,367,332],{"class":215},[174,369,370],{"class":184},"\"Sep\"",[174,372,332],{"class":215},[174,374,375],{"class":184},"\"Oct\"",[174,377,332],{"class":215},[174,379,380],{"class":184},"\"Nov\"",[174,382,332],{"class":215},[174,384,385],{"class":184},"\"Dec\"",[174,387,388],{"class":215},"]\n",[174,390,392,395,398,401,404,406,409,412,416,419,422,425,428,431,434,437,439,441,444,446,449,451,454,456,459,461,464],{"class":176,"line":391},11,[174,393,394],{"class":215},"    ws.append([",[174,396,397],{"class":184},"\"Region\"",[174,399,400],{"class":215},"] ",[174,402,403],{"class":211},"+",[174,405,326],{"class":215},[174,407,408],{"class":211},"f",[174,410,411],{"class":184},"\"",[174,413,415],{"class":414},"sSjpA","{",[174,417,418],{"class":215},"m",[174,420,421],{"class":414},"}",[174,423,424],{"class":184}," 2026\"",[174,426,427],{"class":211}," for",[174,429,430],{"class":215}," m ",[174,432,433],{"class":211},"in",[174,435,436],{"class":215}," months] ",[174,438,403],{"class":211},[174,440,326],{"class":215},[174,442,443],{"class":184},"\"Total\"",[174,445,332],{"class":215},[174,447,448],{"class":184},"\"Target\"",[174,450,332],{"class":215},[174,452,453],{"class":184},"\"Variance\"",[174,455,332],{"class":215},[174,457,458],{"class":184},"\"Share\"",[174,460,332],{"class":215},[174,462,463],{"class":184},"\"Notes\"",[174,465,466],{"class":215},"])\n",[174,468,470,473,476,478,482,485,488],{"class":176,"line":469},12,[174,471,472],{"class":211},"    for",[174,474,475],{"class":215}," r ",[174,477,433],{"class":211},[174,479,481],{"class":480},"sP0c6"," range",[174,483,484],{"class":215},"(",[174,486,487],{"class":480},"120",[174,489,490],{"class":215},"):\n",[174,492,494,497,499,502,504,507,509,512,515,517,519,521,523,525,528,531,533,536,539,541,544,546,549,551,553,555,557,559,562,565,567,569,571,573,575,577,579,581,584,586,589],{"class":176,"line":493},13,[174,495,496],{"class":215},"        ws.append([",[174,498,408],{"class":211},[174,500,501],{"class":184},"\"Store ",[174,503,415],{"class":414},[174,505,506],{"class":215},"r ",[174,508,403],{"class":211},[174,510,511],{"class":480}," 1",[174,513,514],{"class":211},":03d",[174,516,421],{"class":414},[174,518,411],{"class":184},[174,520,400],{"class":215},[174,522,403],{"class":211},[174,524,326],{"class":215},[174,526,527],{"class":480},"1000",[174,529,530],{"class":211}," +",[174,532,475],{"class":215},[174,534,535],{"class":211},"*",[174,537,538],{"class":480}," 13",[174,540,530],{"class":211},[174,542,543],{"class":215}," c ",[174,545,535],{"class":211},[174,547,548],{"class":480}," 7",[174,550,427],{"class":211},[174,552,543],{"class":215},[174,554,433],{"class":211},[174,556,481],{"class":480},[174,558,484],{"class":215},[174,560,561],{"class":480},"12",[174,563,564],{"class":215},")] ",[174,566,403],{"class":211},[174,568,326],{"class":215},[174,570,42],{"class":480},[174,572,332],{"class":215},[174,574,42],{"class":480},[174,576,332],{"class":215},[174,578,42],{"class":480},[174,580,332],{"class":215},[174,582,583],{"class":480},"0.1",[174,585,332],{"class":215},[174,587,588],{"class":184},"\"ok\"",[174,590,466],{"class":215},[174,592,594,596,598,600,602,604,607,609,612],{"class":176,"line":593},14,[174,595,472],{"class":211},[174,597,543],{"class":215},[174,599,433],{"class":211},[174,601,481],{"class":480},[174,603,484],{"class":215},[174,605,606],{"class":480},"1",[174,608,332],{"class":215},[174,610,611],{"class":480},"19",[174,613,490],{"class":215},[174,615,617,620,622],{"class":176,"line":616},15,[174,618,619],{"class":215},"        ws.column_dimensions[get_column_letter(c)].width ",[174,621,290],{"class":211},[174,623,624],{"class":480}," 12\n",[174,626,628,631,633,636],{"class":176,"line":627},16,[174,629,630],{"class":215},"    ws.page_setup.paperSize ",[174,632,290],{"class":211},[174,634,635],{"class":215}," ws.",[174,637,638],{"class":480},"PAPERSIZE_A4\n",[174,640,642,645],{"class":176,"line":641},17,[174,643,644],{"class":211},"    return",[174,646,647],{"class":215}," wb\n",[174,649,651],{"class":176,"line":650},18,[174,652,268],{"emptyLinePlaceholder":267},[174,654,656,659,661],{"class":176,"line":655},19,[174,657,658],{"class":215},"wb ",[174,660,290],{"class":211},[174,662,663],{"class":215}," make_report()\n",[174,665,667,670,672],{"class":176,"line":666},20,[174,668,669],{"class":215},"ws ",[174,671,290],{"class":211},[174,673,304],{"class":215},[159,675,677],{"id":676},"step-1-fit-to-one-page-wide-any-number-of-pages-down","Step 1 — Fit to one page wide, any number of pages down",[10,679,680,681,684,685,688,689,692],{},"Three settings work together. ",[171,682,683],{},"fitToWidth = 1"," asks for one page across; ",[171,686,687],{},"fitToHeight = 0"," means no limit downwards, so a long report still flows onto as many pages as it needs; and ",[171,690,691],{},"fitToPage = True"," switches the sheet from percentage scaling to fit mode — without it the other two are ignored:",[164,694,696],{"className":202,"code":695,"language":204,"meta":169,"style":169},"ws.sheet_properties.pageSetUpPr = PageSetupProperties(fitToPage=True)\nws.page_setup.fitToWidth = 1\nws.page_setup.fitToHeight = 0\nws.print_title_rows = \"1:1\"                         # repeat the header on every page\nwb.save(\"sales_fit.xlsx\")\n",[171,697,698,720,730,740,754],{"__ignoreMap":169},[174,699,700,703,705,708,712,714,717],{"class":176,"line":177},[174,701,702],{"class":215},"ws.sheet_properties.pageSetUpPr ",[174,704,290],{"class":211},[174,706,707],{"class":215}," PageSetupProperties(",[174,709,711],{"class":710},"sa561","fitToPage",[174,713,290],{"class":211},[174,715,716],{"class":480},"True",[174,718,719],{"class":215},")\n",[174,721,722,725,727],{"class":176,"line":225},[174,723,724],{"class":215},"ws.page_setup.fitToWidth ",[174,726,290],{"class":211},[174,728,729],{"class":480}," 1\n",[174,731,732,735,737],{"class":176,"line":238},[174,733,734],{"class":215},"ws.page_setup.fitToHeight ",[174,736,290],{"class":211},[174,738,739],{"class":480}," 0\n",[174,741,742,745,747,750],{"class":176,"line":251},[174,743,744],{"class":215},"ws.print_title_rows ",[174,746,290],{"class":211},[174,748,749],{"class":184}," \"1:1\"",[174,751,753],{"class":752},"s-wDw","                         # repeat the header on every page\n",[174,755,756,759,762],{"class":176,"line":264},[174,757,758],{"class":215},"wb.save(",[174,760,761],{"class":184},"\"sales_fit.xlsx\"",[174,763,719],{"class":215},[10,765,766,767,770,771,775],{},"Leaving ",[171,768,769],{},"fitToHeight"," at its default of 1 squeezes the entire sheet onto a single page, which for 120 rows makes the text microscopic. Repeating row 1 keeps the month headings above the numbers on every page, since only the first page would otherwise show them. The other page-setup options — print areas, paper size, orientation — are covered in ",[14,772,774],{"href":773},"\u002Fformatting-and-charting-excel-reports-with-python\u002Fstyling-excel-cells-with-openpyxl\u002Fset-print-area-and-page-setup-with-openpyxl\u002F","Set Print Area and Page Setup with openpyxl",".",[10,777,778],{},"Exported to PDF, the unscaled sheet took 9 pages; the fitted one took 2. But the heading text measured 4.4 points: the sheet was scaled to about 40% to get 18 columns across a portrait A4 page.",[159,780,782],{"id":781},"step-2-predict-the-scale-before-converting","Step 2 — Predict the scale before converting",[10,784,785],{},"The scale is simple arithmetic: printable width divided by the total width of the printed columns. Column widths are in characters of the default font; for 11-point Calibri one character is 7 pixels plus 5 pixels of padding per column, and a pixel is 0.75 points:",[164,787,789],{"className":202,"code":788,"language":204,"meta":169,"style":169},"PAPER_WIDTH_PT = {9: (595.3, 841.9), 1: (612.0, 792.0)}   # A4, Letter (portrait w, h)\n\ndef column_points(ws, letter, default=8.43):\n    dim = ws.column_dimensions[letter] if letter in ws.column_dimensions else None\n    if dim is not None and dim.hidden:\n        return 0.0\n    width = dim.width if dim is not None and dim.width else default\n    return (int(width * 7) + 5) * 0.75\n\ndef estimated_scale(ws, pages_wide=1, repeat_cols=0):\n    paper_w, paper_h = PAPER_WIDTH_PT[ws.page_setup.paperSize or 9]\n    if ws.page_setup.orientation == \"landscape\":\n        paper_w = paper_h\n    printable = paper_w - (ws.page_margins.left + ws.page_margins.right) * 72\n    letters = [get_column_letter(c) for c in range(1, ws.max_column + 1)]\n    total = sum(column_points(ws, l) for l in letters)\n    total += (pages_wide - 1) * sum(column_points(ws, l) for l in letters[:repeat_cols])\n    return min(1.0, printable * pages_wide \u002F total)\n\nscale = estimated_scale(ws)\nprint(f\"scale {scale:.0%}, 11 pt text prints at {11 * scale:.1f} pt\")\n# scale 41%, 11 pt text prints at 4.5 pt\n",[171,790,791,837,841,858,885,908,916,945,977,981,1004,1025,1041,1051,1077,1110,1133,1164,1190,1194,1204,1251],{"__ignoreMap":169},[174,792,793,796,799,802,805,808,811,813,816,819,821,823,826,828,831,834],{"class":176,"line":177},[174,794,795],{"class":480},"PAPER_WIDTH_PT",[174,797,798],{"class":211}," =",[174,800,801],{"class":215}," {",[174,803,804],{"class":480},"9",[174,806,807],{"class":215},": (",[174,809,810],{"class":480},"595.3",[174,812,332],{"class":215},[174,814,815],{"class":480},"841.9",[174,817,818],{"class":215},"), ",[174,820,606],{"class":480},[174,822,807],{"class":215},[174,824,825],{"class":480},"612.0",[174,827,332],{"class":215},[174,829,830],{"class":480},"792.0",[174,832,833],{"class":215},")}   ",[174,835,836],{"class":752},"# A4, Letter (portrait w, h)\n",[174,838,839],{"class":176,"line":225},[174,840,268],{"emptyLinePlaceholder":267},[174,842,843,845,848,851,853,856],{"class":176,"line":238},[174,844,274],{"class":211},[174,846,847],{"class":277}," column_points",[174,849,850],{"class":215},"(ws, letter, default",[174,852,290],{"class":211},[174,854,855],{"class":480},"8.43",[174,857,490],{"class":215},[174,859,860,863,865,868,871,874,876,879,882],{"class":176,"line":251},[174,861,862],{"class":215},"    dim ",[174,864,290],{"class":211},[174,866,867],{"class":215}," ws.column_dimensions[letter] ",[174,869,870],{"class":211},"if",[174,872,873],{"class":215}," letter ",[174,875,433],{"class":211},[174,877,878],{"class":215}," ws.column_dimensions ",[174,880,881],{"class":211},"else",[174,883,884],{"class":480}," None\n",[174,886,887,890,893,896,899,902,905],{"class":176,"line":264},[174,888,889],{"class":211},"    if",[174,891,892],{"class":215}," dim ",[174,894,895],{"class":211},"is",[174,897,898],{"class":211}," not",[174,900,901],{"class":480}," None",[174,903,904],{"class":211}," and",[174,906,907],{"class":215}," dim.hidden:\n",[174,909,910,913],{"class":176,"line":271},[174,911,912],{"class":211},"        return",[174,914,915],{"class":480}," 0.0\n",[174,917,918,921,923,926,928,930,932,934,936,938,940,942],{"class":176,"line":284},[174,919,920],{"class":215},"    width ",[174,922,290],{"class":211},[174,924,925],{"class":215}," dim.width ",[174,927,870],{"class":211},[174,929,892],{"class":215},[174,931,895],{"class":211},[174,933,898],{"class":211},[174,935,901],{"class":480},[174,937,904],{"class":211},[174,939,925],{"class":215},[174,941,881],{"class":211},[174,943,944],{"class":215}," default\n",[174,946,947,949,952,955,958,960,962,965,967,970,972,974],{"class":176,"line":296},[174,948,644],{"class":211},[174,950,951],{"class":215}," (",[174,953,954],{"class":480},"int",[174,956,957],{"class":215},"(width ",[174,959,535],{"class":211},[174,961,548],{"class":480},[174,963,964],{"class":215},") ",[174,966,403],{"class":211},[174,968,969],{"class":480}," 5",[174,971,964],{"class":215},[174,973,535],{"class":211},[174,975,976],{"class":480}," 0.75\n",[174,978,979],{"class":176,"line":307},[174,980,268],{"emptyLinePlaceholder":267},[174,982,983,985,988,991,993,995,998,1000,1002],{"class":176,"line":318},[174,984,274],{"class":211},[174,986,987],{"class":277}," estimated_scale",[174,989,990],{"class":215},"(ws, pages_wide",[174,992,290],{"class":211},[174,994,606],{"class":480},[174,996,997],{"class":215},", repeat_cols",[174,999,290],{"class":211},[174,1001,42],{"class":480},[174,1003,490],{"class":215},[174,1005,1006,1009,1011,1014,1017,1020,1023],{"class":176,"line":391},[174,1007,1008],{"class":215},"    paper_w, paper_h ",[174,1010,290],{"class":211},[174,1012,1013],{"class":480}," PAPER_WIDTH_PT",[174,1015,1016],{"class":215},"[ws.page_setup.paperSize ",[174,1018,1019],{"class":211},"or",[174,1021,1022],{"class":480}," 9",[174,1024,388],{"class":215},[174,1026,1027,1029,1032,1035,1038],{"class":176,"line":469},[174,1028,889],{"class":211},[174,1030,1031],{"class":215}," ws.page_setup.orientation ",[174,1033,1034],{"class":211},"==",[174,1036,1037],{"class":184}," \"landscape\"",[174,1039,1040],{"class":215},":\n",[174,1042,1043,1046,1048],{"class":176,"line":493},[174,1044,1045],{"class":215},"        paper_w ",[174,1047,290],{"class":211},[174,1049,1050],{"class":215}," paper_h\n",[174,1052,1053,1056,1058,1061,1064,1067,1069,1072,1074],{"class":176,"line":593},[174,1054,1055],{"class":215},"    printable ",[174,1057,290],{"class":211},[174,1059,1060],{"class":215}," paper_w ",[174,1062,1063],{"class":211},"-",[174,1065,1066],{"class":215}," (ws.page_margins.left ",[174,1068,403],{"class":211},[174,1070,1071],{"class":215}," ws.page_margins.right) ",[174,1073,535],{"class":211},[174,1075,1076],{"class":480}," 72\n",[174,1078,1079,1082,1084,1087,1090,1092,1094,1096,1098,1100,1103,1105,1107],{"class":176,"line":616},[174,1080,1081],{"class":215},"    letters ",[174,1083,290],{"class":211},[174,1085,1086],{"class":215}," [get_column_letter(c) ",[174,1088,1089],{"class":211},"for",[174,1091,543],{"class":215},[174,1093,433],{"class":211},[174,1095,481],{"class":480},[174,1097,484],{"class":215},[174,1099,606],{"class":480},[174,1101,1102],{"class":215},", ws.max_column ",[174,1104,403],{"class":211},[174,1106,511],{"class":480},[174,1108,1109],{"class":215},")]\n",[174,1111,1112,1115,1117,1120,1123,1125,1128,1130],{"class":176,"line":627},[174,1113,1114],{"class":215},"    total ",[174,1116,290],{"class":211},[174,1118,1119],{"class":480}," sum",[174,1121,1122],{"class":215},"(column_points(ws, l) ",[174,1124,1089],{"class":211},[174,1126,1127],{"class":215}," l ",[174,1129,433],{"class":211},[174,1131,1132],{"class":215}," letters)\n",[174,1134,1135,1137,1140,1143,1145,1147,1149,1151,1153,1155,1157,1159,1161],{"class":176,"line":641},[174,1136,1114],{"class":215},[174,1138,1139],{"class":211},"+=",[174,1141,1142],{"class":215}," (pages_wide ",[174,1144,1063],{"class":211},[174,1146,511],{"class":480},[174,1148,964],{"class":215},[174,1150,535],{"class":211},[174,1152,1119],{"class":480},[174,1154,1122],{"class":215},[174,1156,1089],{"class":211},[174,1158,1127],{"class":215},[174,1160,433],{"class":211},[174,1162,1163],{"class":215}," letters[:repeat_cols])\n",[174,1165,1166,1168,1171,1173,1176,1179,1181,1184,1187],{"class":176,"line":650},[174,1167,644],{"class":211},[174,1169,1170],{"class":480}," min",[174,1172,484],{"class":215},[174,1174,1175],{"class":480},"1.0",[174,1177,1178],{"class":215},", printable ",[174,1180,535],{"class":211},[174,1182,1183],{"class":215}," pages_wide ",[174,1185,1186],{"class":211},"\u002F",[174,1188,1189],{"class":215}," total)\n",[174,1191,1192],{"class":176,"line":655},[174,1193,268],{"emptyLinePlaceholder":267},[174,1195,1196,1199,1201],{"class":176,"line":666},[174,1197,1198],{"class":215},"scale ",[174,1200,290],{"class":211},[174,1202,1203],{"class":215}," estimated_scale(ws)\n",[174,1205,1207,1210,1212,1214,1217,1219,1222,1225,1227,1230,1232,1235,1238,1241,1244,1246,1249],{"class":176,"line":1206},21,[174,1208,1209],{"class":480},"print",[174,1211,484],{"class":215},[174,1213,408],{"class":211},[174,1215,1216],{"class":184},"\"scale ",[174,1218,415],{"class":414},[174,1220,1221],{"class":215},"scale",[174,1223,1224],{"class":211},":.0%",[174,1226,421],{"class":414},[174,1228,1229],{"class":184},", 11 pt text prints at ",[174,1231,415],{"class":414},[174,1233,1234],{"class":480},"11",[174,1236,1237],{"class":211}," *",[174,1239,1240],{"class":215}," scale",[174,1242,1243],{"class":211},":.1f",[174,1245,421],{"class":414},[174,1247,1248],{"class":184}," pt\"",[174,1250,719],{"class":215},[174,1252,1254],{"class":176,"line":1253},22,[174,1255,1256],{"class":752},"# scale 41%, 11 pt text prints at 4.5 pt\n",[10,1258,1259],{},"The estimate of 4.5 points matched the measured 4.4 in the PDF. For every layout below it came within half a point, and always on the high side, so set the threshold with a small margin — treat an estimate of 7.5 points as the floor if 7 is the real limit. That makes it a cheap gate: run it while building the workbook and change the layout automatically instead of discovering unreadable PDFs later.",[20,1261,29,1267,29,1270,29,1273,29,1278,29,1284,29,1295,29,1300,29,1305,29,1308,29,1315,29,1320,29,1324,29,1327,29,1334,29,1339,29,1343,29,1348,29,1355,29,1360],{"viewBox":1262,"role":23,"ariaLabelledBy":1263,"xmlns":27,"style":1266},"84 0 592 434",[1264,1265],"fp-width-t","fp-width-d","width:100%;max-width:592px;height:auto;display:block;margin:1.5rem auto;font-family:Inter,ui-sans-serif,system-ui,sans-serif",[31,1268,1269],{"id":1264},"Where the printed width goes",[35,1271,1272],{"id":1265},"The paper width minus the left and right margins gives the printable width. The columns' total width is compared with it; if the columns are wider, the whole sheet is scaled down by the ratio. Reducing the columns' width or increasing the printable width both raise the scale.",[39,1274],{"x":1275,"y":42,"width":1276,"height":1277,"fill":45},"84","592","434",[39,1279],{"x":1280,"y":49,"width":1281,"height":1282,"rx":561,"fill":53,"stroke":54,"style":1283},"100.0","560.0","93.0","stroke-width:2px",[1285,1286,1288],"g",{"transform":1287},"translate(368.0,29.0) scale(1.000)",[1289,1290],"path",{"d":1291,"fill":1292,"stroke":1293,"style":1294},"M6 3h9l4 4v14H6z M15 3v4h4","none","var(--text,#172033)","stroke-width:1.80px;stroke-linecap:round;stroke-linejoin:round",[57,1296,1299],{"x":154,"y":1297,"style":1298},"75.5","font-size:13.5px;font-weight:700;fill:var(--text,#172033);text-anchor:middle","Paper width",[57,1301,1304],{"x":154,"y":1302,"style":1303},"95.0","font-size:11.5px;font-weight:400;fill:var(--text,#172033);text-anchor:middle","A4 portrait 595 pt, landscape 842 pt",[39,1306],{"x":1280,"y":1307,"width":1281,"height":1282,"rx":561,"fill":100,"stroke":101,"style":1283},"119.0",[1285,1309,1311],{"transform":1310},"translate(368.0,132.0) scale(1.000)",[1289,1312],{"d":1313,"fill":1292,"stroke":1314,"style":1294},"M12 3l9 5-9 5-9-5z M3 13l9 5 9-5 M3 17l9 5 9-5","var(--gold-ink,#7a4e06)",[57,1316,1319],{"x":154,"y":1317,"style":1318},"178.5","font-size:13.5px;font-weight:700;fill:var(--gold-ink,#7a4e06);text-anchor:middle","− left and right margins",[57,1321,1323],{"x":154,"y":1322,"style":1303},"198.0","0.75 in each by default = 108 pt",[39,1325],{"x":1280,"y":1326,"width":1281,"height":1282,"rx":561,"fill":131,"stroke":132,"style":1283},"222.0",[1285,1328,1330],{"transform":1329},"translate(368.0,235.0) scale(1.000)",[1289,1331],{"d":1332,"fill":1292,"stroke":1333,"style":1294},"M5 12.5l4.5 4.5L19 7","var(--teal-ink,#0b6157)",[57,1335,1338],{"x":154,"y":1336,"style":1337},"281.5","font-size:13.5px;font-weight:700;fill:var(--teal-ink,#0b6157);text-anchor:middle","= printable width",[57,1340,1342],{"x":154,"y":1341,"style":1303},"301.0","487 pt portrait",[39,1344],{"x":1280,"y":1345,"width":1281,"height":1282,"rx":561,"fill":1346,"stroke":1347,"style":1283},"325.0","#f0f4ff","var(--brand,#5b5cf0)",[1285,1349,1351],{"transform":1350},"translate(368.0,338.0) scale(1.000)",[1289,1352],{"d":1353,"fill":1292,"stroke":1354,"style":1294},"M3 5h18v14H3z M3 10h18 M3 15h18 M9 5v14","var(--brand-strong,#4338ca)",[57,1356,1359],{"x":154,"y":1357,"style":1358},"384.5","font-size:13.5px;font-weight:700;fill:var(--brand-strong,#4338ca);text-anchor:middle","÷ visible column width",[57,1361,1363],{"x":154,"y":1362,"style":1303},"404.0","18 × 12 chars ≈ 1,202 pt",[159,1365,1367],{"id":1366},"step-3-buy-width-landscape-then-margins","Step 3 — Buy width: landscape, then margins",[10,1369,1370],{},"Landscape is the first and biggest gain, turning 487 points of printable width into 734. Narrower margins add more; a quarter inch on each side is safe for office printers and irrelevant for PDFs read on screen:",[164,1372,1374],{"className":202,"code":1373,"language":204,"meta":169,"style":169},"ws.page_setup.orientation = \"landscape\"\nprint(f\"landscape: {11 * estimated_scale(ws):.1f} pt\")\nws.page_margins = PageMargins(left=0.25, right=0.25, top=0.5, bottom=0.5)\nprint(f\"narrow margins: {11 * estimated_scale(ws):.1f} pt\")   # 6.7, then 7.4\nwb.save(\"sales_landscape.xlsx\")\n",[171,1375,1376,1386,1414,1462,1493],{"__ignoreMap":169},[174,1377,1378,1381,1383],{"class":176,"line":177},[174,1379,1380],{"class":215},"ws.page_setup.orientation ",[174,1382,290],{"class":211},[174,1384,1385],{"class":184}," \"landscape\"\n",[174,1387,1388,1390,1392,1394,1397,1399,1401,1403,1406,1408,1410,1412],{"class":176,"line":225},[174,1389,1209],{"class":480},[174,1391,484],{"class":215},[174,1393,408],{"class":211},[174,1395,1396],{"class":184},"\"landscape: ",[174,1398,415],{"class":414},[174,1400,1234],{"class":480},[174,1402,1237],{"class":211},[174,1404,1405],{"class":215}," estimated_scale(ws)",[174,1407,1243],{"class":211},[174,1409,421],{"class":414},[174,1411,1248],{"class":184},[174,1413,719],{"class":215},[174,1415,1416,1419,1421,1424,1427,1429,1432,1434,1437,1439,1441,1443,1446,1448,1451,1453,1456,1458,1460],{"class":176,"line":238},[174,1417,1418],{"class":215},"ws.page_margins ",[174,1420,290],{"class":211},[174,1422,1423],{"class":215}," PageMargins(",[174,1425,1426],{"class":710},"left",[174,1428,290],{"class":211},[174,1430,1431],{"class":480},"0.25",[174,1433,332],{"class":215},[174,1435,1436],{"class":710},"right",[174,1438,290],{"class":211},[174,1440,1431],{"class":480},[174,1442,332],{"class":215},[174,1444,1445],{"class":710},"top",[174,1447,290],{"class":211},[174,1449,1450],{"class":480},"0.5",[174,1452,332],{"class":215},[174,1454,1455],{"class":710},"bottom",[174,1457,290],{"class":211},[174,1459,1450],{"class":480},[174,1461,719],{"class":215},[174,1463,1464,1466,1468,1470,1473,1475,1477,1479,1481,1483,1485,1487,1490],{"class":176,"line":251},[174,1465,1209],{"class":480},[174,1467,484],{"class":215},[174,1469,408],{"class":211},[174,1471,1472],{"class":184},"\"narrow margins: ",[174,1474,415],{"class":414},[174,1476,1234],{"class":480},[174,1478,1237],{"class":211},[174,1480,1405],{"class":215},[174,1482,1243],{"class":211},[174,1484,421],{"class":414},[174,1486,1248],{"class":184},[174,1488,1489],{"class":215},")   ",[174,1491,1492],{"class":752},"# 6.7, then 7.4\n",[174,1494,1495,1497,1500],{"class":176,"line":264},[174,1496,758],{"class":215},[174,1498,1499],{"class":184},"\"sales_landscape.xlsx\"",[174,1501,719],{"class":215},[10,1503,1504],{},"Measured, those were 6.7 and 7.4 points — better, still small. Past this point the paper has no more width to give; the remaining gains come from the columns.",[159,1506,1508],{"id":1507},"step-4-print-fewer-columns","Step 4 — Print fewer columns",[10,1510,1511],{},"Hidden columns are not printed. Working columns that help build the report — targets, shares, notes — can stay in the workbook for anyone who opens it and still drop out of the PDF:",[164,1513,1515],{"className":202,"code":1514,"language":204,"meta":169,"style":169},"for letter in \"OPQR\":                               # Target, Variance, Share, Notes\n    ws.column_dimensions[letter].hidden = True\nprint(f\"helpers hidden: {11 * estimated_scale(ws):.1f} pt\")   # 9.5 estimated, 9.2 measured\nwb.save(\"sales_hidden.xlsx\")\n",[171,1516,1517,1534,1544,1574],{"__ignoreMap":169},[174,1518,1519,1521,1523,1525,1528,1531],{"class":176,"line":177},[174,1520,1089],{"class":211},[174,1522,873],{"class":215},[174,1524,433],{"class":211},[174,1526,1527],{"class":184}," \"OPQR\"",[174,1529,1530],{"class":215},":                               ",[174,1532,1533],{"class":752},"# Target, Variance, Share, Notes\n",[174,1535,1536,1539,1541],{"class":176,"line":225},[174,1537,1538],{"class":215},"    ws.column_dimensions[letter].hidden ",[174,1540,290],{"class":211},[174,1542,1543],{"class":480}," True\n",[174,1545,1546,1548,1550,1552,1555,1557,1559,1561,1563,1565,1567,1569,1571],{"class":176,"line":238},[174,1547,1209],{"class":480},[174,1549,484],{"class":215},[174,1551,408],{"class":211},[174,1553,1554],{"class":184},"\"helpers hidden: ",[174,1556,415],{"class":414},[174,1558,1234],{"class":480},[174,1560,1237],{"class":211},[174,1562,1405],{"class":215},[174,1564,1243],{"class":211},[174,1566,421],{"class":414},[174,1568,1248],{"class":184},[174,1570,1489],{"class":215},[174,1572,1573],{"class":752},"# 9.5 estimated, 9.2 measured\n",[174,1575,1576,1578,1581],{"class":176,"line":251},[174,1577,758],{"class":215},[174,1579,1580],{"class":184},"\"sales_hidden.xlsx\"",[174,1582,719],{"class":215},[10,1584,1585,1586,1589],{},"With four columns hidden the measured size was 9.2 points: comfortably readable, still one page wide. When hiding is not appropriate, narrow the columns instead — numbers in a ",[171,1587,1588],{},"#,##0"," format rarely need twelve characters — or set a print area that covers only the range the PDF should show.",[159,1591,1593],{"id":1592},"step-5-when-every-column-must-stay-go-two-pages-wide","Step 5 — When every column must stay, go two pages wide",[10,1595,1596],{},"Some reports cannot lose a column. Then print them two pages wide on purpose, and repeat the label column so each page stands alone:",[164,1598,1600],{"className":202,"code":1599,"language":204,"meta":169,"style":169},"wb = make_report()\nws = wb.active\nws.sheet_properties.pageSetUpPr = PageSetupProperties(fitToPage=True)\nws.page_setup.fitToWidth = 2\nws.page_setup.fitToHeight = 0\nws.page_setup.pageOrder = \"overThenDown\"            # left half, right half, next rows\nws.print_title_rows = \"1:1\"\nws.print_title_cols = \"A:A\"                         # store names on every page\nws.page_margins = PageMargins(left=0.5, right=0.5, top=0.5, bottom=0.5)\nprint(f\"two pages wide: {11 * estimated_scale(ws, pages_wide=2, repeat_cols=1):.1f} pt\")   # 9.1 estimated, 8.6 measured\nwb.save(\"sales_two_wide.xlsx\")\n",[171,1601,1602,1610,1618,1634,1643,1651,1664,1673,1686,1726,1777],{"__ignoreMap":169},[174,1603,1604,1606,1608],{"class":176,"line":177},[174,1605,658],{"class":215},[174,1607,290],{"class":211},[174,1609,663],{"class":215},[174,1611,1612,1614,1616],{"class":176,"line":225},[174,1613,669],{"class":215},[174,1615,290],{"class":211},[174,1617,304],{"class":215},[174,1619,1620,1622,1624,1626,1628,1630,1632],{"class":176,"line":238},[174,1621,702],{"class":215},[174,1623,290],{"class":211},[174,1625,707],{"class":215},[174,1627,711],{"class":710},[174,1629,290],{"class":211},[174,1631,716],{"class":480},[174,1633,719],{"class":215},[174,1635,1636,1638,1640],{"class":176,"line":251},[174,1637,724],{"class":215},[174,1639,290],{"class":211},[174,1641,1642],{"class":480}," 2\n",[174,1644,1645,1647,1649],{"class":176,"line":264},[174,1646,734],{"class":215},[174,1648,290],{"class":211},[174,1650,739],{"class":480},[174,1652,1653,1656,1658,1661],{"class":176,"line":271},[174,1654,1655],{"class":215},"ws.page_setup.pageOrder ",[174,1657,290],{"class":211},[174,1659,1660],{"class":184}," \"overThenDown\"",[174,1662,1663],{"class":752},"            # left half, right half, next rows\n",[174,1665,1666,1668,1670],{"class":176,"line":284},[174,1667,744],{"class":215},[174,1669,290],{"class":211},[174,1671,1672],{"class":184}," \"1:1\"\n",[174,1674,1675,1678,1680,1683],{"class":176,"line":296},[174,1676,1677],{"class":215},"ws.print_title_cols ",[174,1679,290],{"class":211},[174,1681,1682],{"class":184}," \"A:A\"",[174,1684,1685],{"class":752},"                         # store names on every page\n",[174,1687,1688,1690,1692,1694,1696,1698,1700,1702,1704,1706,1708,1710,1712,1714,1716,1718,1720,1722,1724],{"class":176,"line":307},[174,1689,1418],{"class":215},[174,1691,290],{"class":211},[174,1693,1423],{"class":215},[174,1695,1426],{"class":710},[174,1697,290],{"class":211},[174,1699,1450],{"class":480},[174,1701,332],{"class":215},[174,1703,1436],{"class":710},[174,1705,290],{"class":211},[174,1707,1450],{"class":480},[174,1709,332],{"class":215},[174,1711,1445],{"class":710},[174,1713,290],{"class":211},[174,1715,1450],{"class":480},[174,1717,332],{"class":215},[174,1719,1455],{"class":710},[174,1721,290],{"class":211},[174,1723,1450],{"class":480},[174,1725,719],{"class":215},[174,1727,1728,1730,1732,1734,1737,1739,1741,1743,1746,1749,1751,1754,1756,1759,1761,1763,1766,1768,1770,1772,1774],{"class":176,"line":318},[174,1729,1209],{"class":480},[174,1731,484],{"class":215},[174,1733,408],{"class":211},[174,1735,1736],{"class":184},"\"two pages wide: ",[174,1738,415],{"class":414},[174,1740,1234],{"class":480},[174,1742,1237],{"class":211},[174,1744,1745],{"class":215}," estimated_scale(ws, ",[174,1747,1748],{"class":710},"pages_wide",[174,1750,290],{"class":211},[174,1752,1753],{"class":480},"2",[174,1755,332],{"class":215},[174,1757,1758],{"class":710},"repeat_cols",[174,1760,290],{"class":211},[174,1762,606],{"class":480},[174,1764,1765],{"class":215},")",[174,1767,1243],{"class":211},[174,1769,421],{"class":414},[174,1771,1248],{"class":184},[174,1773,1489],{"class":215},[174,1775,1776],{"class":752},"# 9.1 estimated, 8.6 measured\n",[174,1778,1779,1781,1784],{"class":176,"line":391},[174,1780,758],{"class":215},[174,1782,1783],{"class":184},"\"sales_two_wide.xlsx\"",[174,1785,719],{"class":215},[10,1787,1788,1789,1792,1793,1796],{},"The export measured 8.6 points in portrait, on 4 pages, and the right-hand pages opened with the \"Region\" heading and the store names. ",[171,1790,1791],{},"overThenDown"," puts the two halves of the same rows next to each other in the PDF; the default, ",[171,1794,1795],{},"downThenOver",", prints all the left halves first, which is awkward to read on screen.",[20,1798,29,1804,29,1807,29,1810,29,1814,29,1818,29,1823,29,1826,29,1830,29,1833,29,1836,29,1841,29,1849,29,1853,29,1858,29,1862,29,1865,29,1868,29,1871,29,1875,29,1878,29,1881,29,1885,29,1889,29,1893,29,1896,29,1899,29,1903,29,1906,29,1909,29,1912,29,1915,29,1917,29,1920,29,1924,29,1927,29,1932,29,1936],{"viewBox":1799,"role":23,"ariaLabelledBy":1800,"xmlns":27,"style":1803},"4 0 752 256",[1801,1802],"fp-choose-t","fp-choose-d","width:100%;max-width:752px;height:auto;display:block;margin:1.5rem auto;font-family:Inter,ui-sans-serif,system-ui,sans-serif",[31,1805,1806],{"id":1801},"Choosing a layout for a wide sheet",[35,1808,1809],{"id":1802},"Estimate the scale first. If it is 65% or more, fit to one page wide as is. If it is lower, switch to landscape and narrower margins. If that is still too small and some columns are helpers, hide them. If every column must stay, print two pages wide with the label column repeated.",[39,1811],{"x":41,"y":42,"width":1812,"height":1813,"fill":45},"752","256",[39,1815],{"x":1816,"y":49,"width":1817,"height":1297,"rx":561,"fill":1346,"stroke":1347,"style":1283},"231.0","298.1",[1285,1819,1820],{"transform":1287},[1289,1821],{"d":1822,"fill":1292,"stroke":1354,"style":1294},"M2 12s4-7 10-7 10 7 10 7-4 7-10 7S2 12 2 12z M12 9a3 3 0 1 0 .01 0z",[57,1824,1825],{"x":154,"y":1297,"style":1358},"Estimated scale at one page wide?",[176,1827],{"x1":154,"y1":1828,"x2":154,"y2":1829,"stroke":1347,"style":1283},"91.5","111.5",[176,1831],{"x1":59,"y1":1829,"x2":1832,"y2":1829,"stroke":1347,"style":1283},"656.0",[176,1834],{"x1":59,"y1":1829,"x2":59,"y2":1835,"stroke":1347,"style":1283},"157.5",[1837,1838],"polygon",{"points":1839,"fill":1840},"104.0,161.5 99.0,152.5 109.0,152.5","#5b5cf0",[39,1842],{"x":1843,"y":1844,"width":1845,"height":1846,"rx":1847,"fill":45,"stroke":54,"style":1848},"56.9","121.5","94.2","21.0","10","stroke-width:1.2px",[57,1850,1852],{"x":59,"y":109,"style":1851},"font-size:11.5px;font-weight:700;fill:var(--muted,#5b6780);text-anchor:middle","65% or more",[39,1854],{"x":48,"y":1855,"width":1856,"height":1857,"rx":561,"fill":131,"stroke":132,"style":1283},"163.5","168.0","76.5",[57,1859,1861],{"x":59,"y":1860,"style":1337},"197.8","fit as is",[57,1863,683],{"x":59,"y":1864,"style":1303},"217.2",[176,1866],{"x1":1867,"y1":1829,"x2":1867,"y2":1835,"stroke":1347,"style":1283},"288.0",[1837,1869],{"points":1870,"fill":1840},"288.0,161.5 283.0,152.5 293.0,152.5",[39,1872],{"x":1873,"y":1844,"width":1874,"height":1846,"rx":1847,"fill":45,"stroke":54,"style":1848},"245.9","84.2",[57,1876,1877],{"x":1867,"y":109,"style":1851},"below 65%",[39,1879],{"x":1880,"y":1855,"width":1856,"height":1857,"rx":561,"fill":100,"stroke":101,"style":1283},"204.0",[57,1882,1884],{"x":1867,"y":1883,"style":1318},"189.0","landscape and",[57,1886,1888],{"x":1867,"y":1887,"style":1318},"206.5","margins",[57,1890,1892],{"x":1867,"y":1891,"style":1303},"226.0","+50% width",[176,1894],{"x1":1895,"y1":1829,"x2":1895,"y2":1835,"stroke":1347,"style":1283},"472.0",[1837,1897],{"points":1898,"fill":1840},"472.0,161.5 467.0,152.5 477.0,152.5",[39,1900],{"x":1901,"y":1844,"width":1902,"height":1846,"rx":1847,"fill":45,"stroke":54,"style":1848},"424.4","95.3",[57,1904,1905],{"x":1895,"y":109,"style":1851},"still too small",[39,1907],{"x":1908,"y":1855,"width":1856,"height":1857,"rx":561,"fill":1346,"stroke":1347,"style":1283},"388.0",[57,1910,1911],{"x":1895,"y":1860,"style":1358},"hide helper columns",[57,1913,1914],{"x":1895,"y":1864,"style":1303},"not printed",[176,1916],{"x1":1832,"y1":1829,"x2":1832,"y2":1835,"stroke":1347,"style":1283},[1837,1918],{"points":1919,"fill":1840},"656.0,161.5 651.0,152.5 661.0,152.5",[39,1921],{"x":1922,"y":1844,"width":1923,"height":1846,"rx":1847,"fill":45,"stroke":54,"style":1848},"583.1","145.7",[57,1925,1926],{"x":1832,"y":109,"style":1851},"every column needed",[39,1928],{"x":1929,"y":1855,"width":1856,"height":1857,"rx":561,"fill":1930,"stroke":1931,"style":1283},"572.0","#fee8f2","var(--accent,#f43f8f)",[57,1933,1935],{"x":1832,"y":1860,"style":1934},"font-size:13.5px;font-weight:700;fill:var(--accent-ink,#be185d);text-anchor:middle","two pages wide",[57,1937,1938],{"x":1832,"y":1864,"style":1303},"repeat column A",[159,1940,1942],{"id":1941},"step-6-check-the-pdf-not-the-settings","Step 6 — Check the PDF, not the settings",[10,1944,1945,1946,1949],{},"Settings can be right and the export still surprising: a column width set later in the code, a print area left over from a template. Convert, then check the page count and the size of the heading text with ",[171,1947,1948],{},"pypdf",":",[164,1951,1953],{"className":202,"code":1952,"language":204,"meta":169,"style":169},"import subprocess\nfrom pypdf import PdfReader\n\nsubprocess.run([\"soffice\", \"--headless\", \"--convert-to\", \"pdf\", \"sales_hidden.xlsx\"],\n               check=True, timeout=120)\n\ndef heading_size(page, heading=\"Region\"):\n    sizes = []\n    def visit(text, cm, tm, font, size):\n        if text.strip() == heading:\n            sizes.append(size * abs(tm[0]))\n    page.extract_text(visitor_text=visit)\n    return round(sizes[0], 1) if sizes else None\n\npdf = PdfReader(\"sales_hidden.pdf\")\nprint(len(pdf.pages), \"pages, heading at\", heading_size(pdf.pages[0]), \"pt\")\n",[171,1954,1955,1962,1974,1978,2008,2028,2032,2048,2058,2069,2082,2100,2113,2141,2145,2160],{"__ignoreMap":169},[174,1956,1957,1959],{"class":176,"line":177},[174,1958,219],{"class":211},[174,1960,1961],{"class":215}," subprocess\n",[174,1963,1964,1966,1969,1971],{"class":176,"line":225},[174,1965,212],{"class":211},[174,1967,1968],{"class":215}," pypdf ",[174,1970,219],{"class":211},[174,1972,1973],{"class":215}," PdfReader\n",[174,1975,1976],{"class":176,"line":238},[174,1977,268],{"emptyLinePlaceholder":267},[174,1979,1980,1983,1986,1988,1991,1993,1996,1998,2001,2003,2005],{"class":176,"line":251},[174,1981,1982],{"class":215},"subprocess.run([",[174,1984,1985],{"class":184},"\"soffice\"",[174,1987,332],{"class":215},[174,1989,1990],{"class":184},"\"--headless\"",[174,1992,332],{"class":215},[174,1994,1995],{"class":184},"\"--convert-to\"",[174,1997,332],{"class":215},[174,1999,2000],{"class":184},"\"pdf\"",[174,2002,332],{"class":215},[174,2004,1580],{"class":184},[174,2006,2007],{"class":215},"],\n",[174,2009,2010,2013,2015,2017,2019,2022,2024,2026],{"class":176,"line":264},[174,2011,2012],{"class":710},"               check",[174,2014,290],{"class":211},[174,2016,716],{"class":480},[174,2018,332],{"class":215},[174,2020,2021],{"class":710},"timeout",[174,2023,290],{"class":211},[174,2025,487],{"class":480},[174,2027,719],{"class":215},[174,2029,2030],{"class":176,"line":271},[174,2031,268],{"emptyLinePlaceholder":267},[174,2033,2034,2036,2039,2042,2044,2046],{"class":176,"line":284},[174,2035,274],{"class":211},[174,2037,2038],{"class":277}," heading_size",[174,2040,2041],{"class":215},"(page, heading",[174,2043,290],{"class":211},[174,2045,397],{"class":184},[174,2047,490],{"class":215},[174,2049,2050,2053,2055],{"class":176,"line":296},[174,2051,2052],{"class":215},"    sizes ",[174,2054,290],{"class":211},[174,2056,2057],{"class":215}," []\n",[174,2059,2060,2063,2066],{"class":176,"line":307},[174,2061,2062],{"class":211},"    def",[174,2064,2065],{"class":277}," visit",[174,2067,2068],{"class":215},"(text, cm, tm, font, size):\n",[174,2070,2071,2074,2077,2079],{"class":176,"line":318},[174,2072,2073],{"class":211},"        if",[174,2075,2076],{"class":215}," text.strip() ",[174,2078,1034],{"class":211},[174,2080,2081],{"class":215}," heading:\n",[174,2083,2084,2087,2089,2092,2095,2097],{"class":176,"line":391},[174,2085,2086],{"class":215},"            sizes.append(size ",[174,2088,535],{"class":211},[174,2090,2091],{"class":480}," abs",[174,2093,2094],{"class":215},"(tm[",[174,2096,42],{"class":480},[174,2098,2099],{"class":215},"]))\n",[174,2101,2102,2105,2108,2110],{"class":176,"line":469},[174,2103,2104],{"class":215},"    page.extract_text(",[174,2106,2107],{"class":710},"visitor_text",[174,2109,290],{"class":211},[174,2111,2112],{"class":215},"visit)\n",[174,2114,2115,2117,2120,2123,2125,2128,2130,2132,2134,2137,2139],{"class":176,"line":493},[174,2116,644],{"class":211},[174,2118,2119],{"class":480}," round",[174,2121,2122],{"class":215},"(sizes[",[174,2124,42],{"class":480},[174,2126,2127],{"class":215},"], ",[174,2129,606],{"class":480},[174,2131,964],{"class":215},[174,2133,870],{"class":211},[174,2135,2136],{"class":215}," sizes ",[174,2138,881],{"class":211},[174,2140,884],{"class":480},[174,2142,2143],{"class":176,"line":593},[174,2144,268],{"emptyLinePlaceholder":267},[174,2146,2147,2150,2152,2155,2158],{"class":176,"line":616},[174,2148,2149],{"class":215},"pdf ",[174,2151,290],{"class":211},[174,2153,2154],{"class":215}," PdfReader(",[174,2156,2157],{"class":184},"\"sales_hidden.pdf\"",[174,2159,719],{"class":215},[174,2161,2162,2164,2166,2169,2172,2175,2178,2180,2183,2186],{"class":176,"line":627},[174,2163,1209],{"class":480},[174,2165,484],{"class":215},[174,2167,2168],{"class":480},"len",[174,2170,2171],{"class":215},"(pdf.pages), ",[174,2173,2174],{"class":184},"\"pages, heading at\"",[174,2176,2177],{"class":215},", heading_size(pdf.pages[",[174,2179,42],{"class":480},[174,2181,2182],{"class":215},"]), ",[174,2184,2185],{"class":184},"\"pt\"",[174,2187,719],{"class":215},[10,2189,2190,2192],{},[171,2191,1948],{}," reports the font size and the text matrix separately, and the matrix carries the scaling; their product is the printed size. Failing the job when the size drops below a threshold turns \"the PDF is unreadable\" from a complaint into a test.",[159,2194,2196],{"id":2195},"common-pitfalls","Common pitfalls",[2198,2199,2200,2216,2222,2232],"ul",{},[2201,2202,2203,2207,2208,2211,2212,2215],"li",{},[2204,2205,2206],"strong",{},"fitToPage missing."," ",[171,2209,2210],{},"fitToWidth"," without ",[171,2213,2214],{},"pageSetUpPr.fitToPage = True"," changes nothing. It is the most common reason the setting \"does not work\".",[2201,2217,2218,2221],{},[2204,2219,2220],{},"fitToHeight left at 1."," The default fits the whole sheet on one page. Set it to 0 for long reports.",[2201,2223,2224,2227,2228,2231],{},[2204,2225,2226],{},"Unset column widths."," Columns without an explicit width use the default of about 8.43 characters, but openpyxl reports 13 for a column it has not seen. The estimate above checks ",[171,2229,2230],{},"in ws.column_dimensions"," to avoid creating one.",[2201,2233,2234,2237],{},[2204,2235,2236],{},"Assuming the default font."," The estimate assumes 11-point Calibri. A report in a wider font, or with larger header text, prints smaller than predicted; check the PDF.",[159,2239,2241],{"id":2240},"conclusion","Conclusion",[10,2243,2244,332,2246,2248,2249,2251],{},[171,2245,683],{},[171,2247,687],{}," and ",[171,2250,691],{}," put a wide sheet on one page across. Estimate the resulting scale from the column widths before converting; when text would print below about 7 points, use landscape and narrower margins, hide helper columns, or print two pages wide with the label column repeated, and confirm the result by measuring the PDF.",[159,2253,2255],{"id":2254},"frequently-asked-questions","Frequently asked questions",[10,2257,2258,2261],{},[2204,2259,2260],{},"How do I make an Excel sheet print one page wide from Python?","\nWith openpyxl, set ws.page_setup.fitToWidth = 1, ws.page_setup.fitToHeight = 0 and ws.sheet_properties.pageSetUpPr.fitToPage = True. The zero height means as many pages down as needed. Without fitToPage the two numbers are ignored.",[10,2263,2264,2267],{},[2204,2265,2266],{},"Why is the text tiny after fitting the sheet to one page?","\nFitting scales the whole sheet down until every column fits. An 18-column report on portrait A4 printed at 40%, turning 11-point text into 4.4 points. Switch to landscape, narrow the margins or remove columns before fitting.",[10,2269,2270,2273],{},[2204,2271,2272],{},"How small can the scale go before a PDF report is hard to read?","\nBody text below about 7 points is hard to read on paper and needs zooming on screen. For 11-point cells that means a scale of roughly 65% or more; below that, change the layout instead of fitting harder.",[10,2275,2276,2279],{},[2204,2277,2278],{},"Do hidden columns appear in the PDF?","\nNo. Hidden columns are not printed, so hiding helper or working columns is a quick way to make a sheet narrower for export without deleting data from the workbook.",[159,2281,2283],{"id":2282},"related","Related",[2198,2285,2286,2292,2299,2306],{},[2201,2287,2288,2289,2291],{},"Up one level: ",[14,2290,17],{"href":16}," — turning workbooks into PDF reports.",[2201,2293,2294,2298],{},[14,2295,2297],{"href":2296},"\u002Fautomating-reporting-workflows\u002Fexporting-excel-reports-to-pdf\u002Fadd-headers-footers-and-page-numbers-to-an-excel-pdf\u002F","Add Headers, Footers and Page Numbers to an Excel PDF"," — \"page 2 of 4\" on the pages you just laid out.",[2201,2300,2301,2305],{},[14,2302,2304],{"href":2303},"\u002Fautomating-reporting-workflows\u002Fexporting-excel-reports-to-pdf\u002Fconvert-only-selected-sheets-of-a-workbook-to-pdf\u002F","Convert Only Selected Sheets of a Workbook to PDF"," — leaving data sheets out of the export.",[2201,2307,2308,2312],{},[14,2309,2311],{"href":2310},"\u002Fautomating-reporting-workflows\u002Fexporting-excel-reports-to-pdf\u002Fmerge-excel-pdf-exports-into-one-file\u002F","Merge Several Excel PDF Exports into One File"," — combining the results into one document.",[2314,2315,2316],"style",{},"html pre.shiki code .sMTad, html code.shiki .sMTad{--shiki-default:#6F42C1;--shiki-dark:#FFB757}html pre.shiki code .srMev, html code.shiki .srMev{--shiki-default:#032F62;--shiki-dark:#ADDCFF}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 .s-kum, html code.shiki .s-kum{--shiki-default:#D73A49;--shiki-dark:#FF9492}html pre.shiki code .skGVy, html code.shiki .skGVy{--shiki-default:#24292E;--shiki-dark:#F0F3F6}html pre.shiki code .s_Opv, html code.shiki .s_Opv{--shiki-default:#6F42C1;--shiki-dark:#DBB7FF}html pre.shiki code .sSjpA, html code.shiki .sSjpA{--shiki-default:#005CC5;--shiki-dark:#FF9492}html pre.shiki code .sP0c6, html code.shiki .sP0c6{--shiki-default:#005CC5;--shiki-dark:#91CBFF}html pre.shiki code .sa561, html code.shiki .sa561{--shiki-default:#E36209;--shiki-dark:#FFB757}html pre.shiki code .s-wDw, html code.shiki .s-wDw{--shiki-default:#6A737D;--shiki-dark:#BDC4CC}",{"title":169,"searchDepth":225,"depth":225,"links":2318},[2319,2320,2321,2322,2323,2324,2325,2326,2327,2328,2329],{"id":161,"depth":225,"text":162},{"id":676,"depth":225,"text":677},{"id":781,"depth":225,"text":782},{"id":1366,"depth":225,"text":1367},{"id":1507,"depth":225,"text":1508},{"id":1592,"depth":225,"text":1593},{"id":1941,"depth":225,"text":1942},{"id":2195,"depth":225,"text":2196},{"id":2240,"depth":225,"text":2241},{"id":2254,"depth":225,"text":2255},{"id":2282,"depth":225,"text":2283},"2026-09-23","Stop wide Excel reports from spilling columns onto extra PDF pages — set fit-to-width with openpyxl, predict how small the text will get before converting, and when it gets too small, use landscape, narrower margins, hidden helper columns or a two-page-wide layout with repeated labels. Every layout measured in a LibreOffice PDF export.","md",[2334,2336,2338,2340],{"q":2260,"a":2335},"With openpyxl, set ws.page_setup.fitToWidth = 1, ws.page_setup.fitToHeight = 0 and ws.sheet_properties.pageSetUpPr.fitToPage = True. The zero height means as many pages down as needed. Without fitToPage the two numbers are ignored.",{"q":2266,"a":2337},"Fitting scales the whole sheet down until every column fits. An 18-column report on portrait A4 printed at 40%, turning 11-point text into 4.4 points. Switch to landscape, narrow the margins or remove columns before fitting.",{"q":2272,"a":2339},"Body text below about 7 points is hard to read on paper and needs zooming on screen. For 11-point cells that means a scale of roughly 65% or more; below that, change the layout instead of fitting harder.",{"q":2278,"a":2341},"No. Hidden columns are not printed, so hiding helper or working columns is a quick way to make a sheet narrower for export without deleting data from the workbook.","fit an excel sheet to one page wide when exporting to pdf",null,{"breadcrumb":2345},[2346,2348,2351],{"name":2347,"item":1186},"Home",{"name":2349,"item":2350},"Automating Reporting Workflows with Python and Excel","\u002Fautomating-reporting-workflows\u002F",{"name":17,"item":16},"\u002Fautomating-reporting-workflows\u002Fexporting-excel-reports-to-pdf\u002Ffit-an-excel-sheet-to-one-page-in-pdf",{"title":2354,"description":2355},"Fit an Excel Sheet to One Page Wide in PDF with Python","Export a wide Excel sheet to PDF one page wide — fitToWidth=1 and fitToHeight=0 with fitToPage in openpyxl, estimating the printed font size from column widths, landscape and margins, hiding columns, repeating header rows and label columns, and checking page count and text size with pypdf.","fit-an-excel-sheet-to-one-page-in-pdf","automating-reporting-workflows\u002Fexporting-excel-reports-to-pdf\u002Ffit-an-excel-sheet-to-one-page-in-pdf\u002Findex",[2359,2360],"pdf-export","cell-styling","how-to","3ThSgGBwgl12oNAXmmFvQKpaBZGCH1sOhjZOJU6fKeo",[2364,2368],{"title":2365,"path":2366,"stem":2367,"children":-1},"Export an Excel Report to PDF\u002FA for Archiving","\u002Fautomating-reporting-workflows\u002Fexporting-excel-reports-to-pdf\u002Fexport-an-excel-report-to-pdf-a-for-archiving","automating-reporting-workflows\u002Fexporting-excel-reports-to-pdf\u002Fexport-an-excel-report-to-pdf-a-for-archiving\u002Findex",{"title":2311,"path":2369,"stem":2370,"children":-1},"\u002Fautomating-reporting-workflows\u002Fexporting-excel-reports-to-pdf\u002Fmerge-excel-pdf-exports-into-one-file","automating-reporting-workflows\u002Fexporting-excel-reports-to-pdf\u002Fmerge-excel-pdf-exports-into-one-file\u002Findex",[2372,2374],{"path":2373,"title":17},"\u002Fautomating-reporting-workflows\u002Fexporting-excel-reports-to-pdf",{"path":2375,"title":2349},"\u002Fautomating-reporting-workflows",[],[2378,2381,2384,2387,2389,2392],{"path":2379,"title":2380,"kind":2361},"\u002Fautomating-reporting-workflows\u002Fgenerating-excel-reports-from-templates\u002Ffill-pdf-forms-from-excel-rows-with-python","Fill PDF Forms from Excel Rows with Python",{"path":2382,"title":2383,"kind":2361},"\u002Fautomating-reporting-workflows\u002Fgenerating-excel-reports-from-templates\u002Fgenerate-one-pdf-per-excel-row","Generate One PDF per Excel Row",{"path":2385,"title":2386,"kind":2361},"\u002Fautomating-reporting-workflows\u002Fexporting-excel-reports-to-pdf\u002Fadd-bookmarks-and-a-cover-page-to-an-excel-pdf-export","Add Bookmarks and a Cover Page to an Excel PDF Export",{"path":2388,"title":2297,"kind":2361},"\u002Fautomating-reporting-workflows\u002Fexporting-excel-reports-to-pdf\u002Fadd-headers-footers-and-page-numbers-to-an-excel-pdf",{"path":2390,"title":2391,"kind":2361},"\u002Fautomating-reporting-workflows\u002Fexporting-excel-reports-to-pdf\u002Fcheck-a-pdf-export-for-cut-off-columns","Check a PDF Export for Cut-Off Columns",{"path":2393,"title":2394,"kind":2361},"\u002Fautomating-reporting-workflows\u002Fexporting-excel-reports-to-pdf\u002Fconvert-excel-file-to-pdf-with-python","Convert an Excel File to PDF with Python",1790972137098]