[{"data":1,"prerenderedAt":2597},["ShallowReactive",2],{"doc:\u002Fgetting-started-with-python-excel-automation\u002Ftroubleshooting-common-python-excel-errors\u002Ffix-openpyxl-value-must-be-one-of-errors":3,"surround:\u002Fgetting-started-with-python-excel-automation\u002Ftroubleshooting-common-python-excel-errors\u002Ffix-openpyxl-value-must-be-one-of-errors":2562,"ancestors:\u002Fgetting-started-with-python-excel-automation\u002Ftroubleshooting-common-python-excel-errors\u002Ffix-openpyxl-value-must-be-one-of-errors":2570,"children:\u002Fgetting-started-with-python-excel-automation\u002Ftroubleshooting-common-python-excel-errors\u002Ffix-openpyxl-value-must-be-one-of-errors":2575,"related:\u002Fgetting-started-with-python-excel-automation\u002Ftroubleshooting-common-python-excel-errors\u002Ffix-openpyxl-value-must-be-one-of-errors":2576},{"id":4,"title":5,"body":6,"dateModified":2527,"datePublished":2527,"description":2528,"extension":2529,"faq":2530,"keyword":2539,"kind":2540,"meta":2541,"navigation":105,"path":2550,"seo":2551,"slug":2554,"stem":2555,"topics":2556,"type":2560,"__hash__":2561},"docs\u002Fgetting-started-with-python-excel-automation\u002Ftroubleshooting-common-python-excel-errors\u002Ffix-openpyxl-value-must-be-one-of-errors\u002Findex.md","Fix openpyxl \"Value must be one of\" and \"Max value is\" Errors",{"type":7,"value":8,"toc":2514},"minimark",[9,40,45,70,73,77,377,422,584,588,591,902,936,940,943,1038,1049,1053,1056,1254,1290,1436,1440,1447,1599,1630,1753,1757,1760,2312,2332,2336,2412,2416,2450,2454,2460,2466,2472,2478,2482,2511],[10,11,12,13,17,18,21,22,25,26,29,30,33,34,39],"p",{},"Styling code written from memory of Excel's menus fails on its first line: ",[14,15,16],"code",{},"Side(style=\"bold\")"," raises ",[14,19,20],{},"ValueError: Value must be one of {'hair', 'dashDotDot', 'thin', …}",". Excel's interface says \"bold border\", \"middle align\" and \"Landscape\"; the file format — and openpyxl, which mirrors it — uses ",[14,23,24],{},"medium",", ",[14,27,28],{},"center"," and ",[14,31,32],{},"landscape",". openpyxl checks every such attribute against the exact set of names the format allows, case included, and prints that set in the error. Most of these errors are therefore fixed by reading the message carefully. A few are subtler: some values are not checked until the workbook is saved, which leaves a half-written, unreadable file behind. This page belongs to ",[35,36,38],"a",{"href":37},"\u002Fgetting-started-with-python-excel-automation\u002Ftroubleshooting-common-python-excel-errors\u002F","Troubleshooting Common Python Excel Errors",".",[41,42,44],"h2",{"id":43},"prerequisites","Prerequisites",[46,47,52],"pre",{"className":48,"code":49,"language":50,"meta":51,"style":51},"language-bash shiki shiki-themes github-light github-dark-high-contrast","pip install openpyxl\n","bash","",[14,53,54],{"__ignoreMap":51},[55,56,59,63,67],"span",{"class":57,"line":58},"line",1,[55,60,62],{"class":61},"sMTad","pip",[55,64,66],{"class":65},"srMev"," install",[55,68,69],{"class":65}," openpyxl\n",[10,71,72],{},"Messages below are from openpyxl 3.1; the set inside the braces is printed in a different order on each run, because it is a Python set.",[41,74,76],{"id":75},"step-1-read-the-message-as-a-list-of-valid-names","Step 1 — Read the message as a list of valid names",[46,78,82],{"className":79,"code":80,"language":81,"meta":51,"style":51},"language-python shiki shiki-themes github-light github-dark-high-contrast","from openpyxl.styles import Side, Alignment, PatternFill, Font\n\nattempts = {\n    'Side(style=\"bold\")': lambda: Side(style=\"bold\"),\n    'Alignment(horizontal=\"middle\")': lambda: Alignment(horizontal=\"middle\"),\n    'PatternFill(fill_type=\"Solid\")': lambda: PatternFill(fill_type=\"Solid\", fgColor=\"FFFF00\"),\n    'Font(u=\"double underline\")': lambda: Font(u=\"double underline\"),\n}\nfor code, attempt in attempts.items():\n    try:\n        attempt()\n    except ValueError as exc:\n        names = sorted(str(exc).split(\"{\", 1)[1].rstrip(\"}\").replace(\"'\", \"\").split(\", \"))\n        print(f\"{code:32} -> {names}\")\n","python",[14,83,84,100,107,119,146,169,202,225,231,246,255,261,277,336],{"__ignoreMap":51},[55,85,86,90,94,97],{"class":57,"line":58},[55,87,89],{"class":88},"s-kum","from",[55,91,93],{"class":92},"skGVy"," openpyxl.styles ",[55,95,96],{"class":88},"import",[55,98,99],{"class":92}," Side, Alignment, PatternFill, Font\n",[55,101,103],{"class":57,"line":102},2,[55,104,106],{"emptyLinePlaceholder":105},true,"\n",[55,108,110,113,116],{"class":57,"line":109},3,[55,111,112],{"class":92},"attempts ",[55,114,115],{"class":88},"=",[55,117,118],{"class":92}," {\n",[55,120,122,125,128,131,134,138,140,143],{"class":57,"line":121},4,[55,123,124],{"class":65},"    'Side(style=\"bold\")'",[55,126,127],{"class":92},": ",[55,129,130],{"class":88},"lambda",[55,132,133],{"class":92},": Side(",[55,135,137],{"class":136},"sa561","style",[55,139,115],{"class":88},[55,141,142],{"class":65},"\"bold\"",[55,144,145],{"class":92},"),\n",[55,147,149,152,154,156,159,162,164,167],{"class":57,"line":148},5,[55,150,151],{"class":65},"    'Alignment(horizontal=\"middle\")'",[55,153,127],{"class":92},[55,155,130],{"class":88},[55,157,158],{"class":92},": Alignment(",[55,160,161],{"class":136},"horizontal",[55,163,115],{"class":88},[55,165,166],{"class":65},"\"middle\"",[55,168,145],{"class":92},[55,170,172,175,177,179,182,185,187,190,192,195,197,200],{"class":57,"line":171},6,[55,173,174],{"class":65},"    'PatternFill(fill_type=\"Solid\")'",[55,176,127],{"class":92},[55,178,130],{"class":88},[55,180,181],{"class":92},": PatternFill(",[55,183,184],{"class":136},"fill_type",[55,186,115],{"class":88},[55,188,189],{"class":65},"\"Solid\"",[55,191,25],{"class":92},[55,193,194],{"class":136},"fgColor",[55,196,115],{"class":88},[55,198,199],{"class":65},"\"FFFF00\"",[55,201,145],{"class":92},[55,203,205,208,210,212,215,218,220,223],{"class":57,"line":204},7,[55,206,207],{"class":65},"    'Font(u=\"double underline\")'",[55,209,127],{"class":92},[55,211,130],{"class":88},[55,213,214],{"class":92},": Font(",[55,216,217],{"class":136},"u",[55,219,115],{"class":88},[55,221,222],{"class":65},"\"double underline\"",[55,224,145],{"class":92},[55,226,228],{"class":57,"line":227},8,[55,229,230],{"class":92},"}\n",[55,232,234,237,240,243],{"class":57,"line":233},9,[55,235,236],{"class":88},"for",[55,238,239],{"class":92}," code, attempt ",[55,241,242],{"class":88},"in",[55,244,245],{"class":92}," attempts.items():\n",[55,247,249,252],{"class":57,"line":248},10,[55,250,251],{"class":88},"    try",[55,253,254],{"class":92},":\n",[55,256,258],{"class":57,"line":257},11,[55,259,260],{"class":92},"        attempt()\n",[55,262,264,267,271,274],{"class":57,"line":263},12,[55,265,266],{"class":88},"    except",[55,268,270],{"class":269},"sP0c6"," ValueError",[55,272,273],{"class":88}," as",[55,275,276],{"class":92}," exc:\n",[55,278,280,283,285,288,291,294,297,300,302,305,308,310,313,316,319,322,324,327,330,333],{"class":57,"line":279},13,[55,281,282],{"class":92},"        names ",[55,284,115],{"class":88},[55,286,287],{"class":269}," sorted",[55,289,290],{"class":92},"(",[55,292,293],{"class":269},"str",[55,295,296],{"class":92},"(exc).split(",[55,298,299],{"class":65},"\"{\"",[55,301,25],{"class":92},[55,303,304],{"class":269},"1",[55,306,307],{"class":92},")[",[55,309,304],{"class":269},[55,311,312],{"class":92},"].rstrip(",[55,314,315],{"class":65},"\"}\"",[55,317,318],{"class":92},").replace(",[55,320,321],{"class":65},"\"'\"",[55,323,25],{"class":92},[55,325,326],{"class":65},"\"\"",[55,328,329],{"class":92},").split(",[55,331,332],{"class":65},"\", \"",[55,334,335],{"class":92},"))\n",[55,337,339,342,344,347,350,354,356,359,362,365,367,370,372,374],{"class":57,"line":338},14,[55,340,341],{"class":269},"        print",[55,343,290],{"class":92},[55,345,346],{"class":88},"f",[55,348,349],{"class":65},"\"",[55,351,353],{"class":352},"sSjpA","{",[55,355,14],{"class":92},[55,357,358],{"class":88},":32",[55,360,361],{"class":352},"}",[55,363,364],{"class":65}," -> ",[55,366,353],{"class":352},[55,368,369],{"class":92},"names",[55,371,361],{"class":352},[55,373,349],{"class":65},[55,375,376],{"class":92},")\n",[10,378,379,380,25,383,25,385,25,388,25,391,394,395,398,399,401,402,405,406,409,410,25,413,25,415,29,418,421],{},"Each error message ends with the complete set of accepted values, so the fix is usually visible in it: borders are ",[14,381,382],{},"thin",[14,384,24],{},[14,386,387],{},"thick",[14,389,390],{},"double",[14,392,393],{},"dashed"," and friends — there is no ",[14,396,397],{},"bold","; horizontal alignment is ",[14,400,28],{},", not ",[14,403,404],{},"middle","; fill types are lower-case ",[14,407,408],{},"solid","; underline styles are ",[14,411,412],{},"single",[14,414,390],{},[14,416,417],{},"singleAccounting",[14,419,420],{},"doubleAccounting",". The names are the ones written into the XML, which is why they look like identifiers rather than menu labels.",[423,424,432,433,432,437,432,441,432,449,432,457,432,464,432,470,432,474,432,477,432,481,432,484,432,488,432,491,432,495,432,498,432,502,432,505,432,509,432,514,432,518,432,522,432,526,432,528,432,531,432,533,432,536,432,538,432,541,432,543,432,546,432,548,432,551,432,556,432,559,432,565,432,570,432,578],"svg",{"viewBox":425,"role":426,"ariaLabelledBy":427,"xmlns":430,"style":431},"137 0 491 252","img",[428,429],"vm-translate-t","vm-translate-d","http:\u002F\u002Fwww.w3.org\u002F2000\u002Fsvg","width:100%;max-width:491px;height:auto;display:block;margin:1.5rem auto;font-family:Inter,ui-sans-serif,system-ui,sans-serif","\n  ",[434,435,436],"title",{"id":428},"Menu names versus the names openpyxl accepts",[438,439,440],"desc",{"id":429},"On the left the words people use from Excel's interface, such as bold border, middle, Solid, Landscape, number validation and hide. On the right the values openpyxl accepts — medium or thick, center, solid, landscape, decimal or whole, hidden.",[442,443],"rect",{"x":444,"y":445,"width":446,"height":447,"fill":448},"137","0","491","252","#ffffff",[442,450],{"x":451,"y":452,"width":453,"height":454,"rx":445,"fill":448,"stroke":455,"style":456},"153.6","40.0","168.0","28.0","var(--line,#cdd5e6)","stroke-width:1px",[458,459,463],"text",{"x":460,"y":461,"style":462},"237.6","59.0","font-size:11px;font-weight:700;fill:var(--text,#172033);text-anchor:middle","Value tried",[442,465],{"x":451,"y":466,"width":453,"height":454,"rx":445,"fill":467,"stroke":468,"style":469},"68.0","#fce9e9","var(--danger,#dc2626)","stroke-width:1.5px",[458,471,16],{"x":460,"y":472,"style":473},"87.0","font-size:11px;font-weight:700;fill:var(--accent-ink,#be185d);text-anchor:middle",[442,475],{"x":451,"y":476,"width":453,"height":454,"rx":445,"fill":467,"stroke":468,"style":469},"96.0",[458,478,480],{"x":460,"y":479,"style":473},"115.0","horizontal=\"middle\"",[442,482],{"x":451,"y":483,"width":453,"height":454,"rx":445,"fill":467,"stroke":468,"style":469},"124.0",[458,485,487],{"x":460,"y":486,"style":473},"143.0","fill_type=\"Solid\"",[442,489],{"x":451,"y":490,"width":453,"height":454,"rx":445,"fill":467,"stroke":468,"style":469},"152.0",[458,492,494],{"x":460,"y":493,"style":473},"171.0","orientation=\"Landscape\"",[442,496],{"x":451,"y":497,"width":453,"height":454,"rx":445,"fill":467,"stroke":468,"style":469},"180.0",[458,499,501],{"x":460,"y":500,"style":473},"199.0","type=\"number\"",[442,503],{"x":451,"y":504,"width":453,"height":454,"rx":445,"fill":467,"stroke":468,"style":469},"208.0",[458,506,508],{"x":460,"y":507,"style":473},"227.0","sheet_state=\"hide\"",[442,510],{"x":511,"y":452,"width":512,"height":454,"rx":445,"fill":513,"stroke":455,"style":469},"468.4","138.0","#e7ebef",[458,515,517],{"x":516,"y":461,"style":462},"537.4","Accepted",[442,519],{"x":511,"y":466,"width":512,"height":454,"rx":445,"fill":520,"stroke":521,"style":469},"#d9f4f1","var(--teal,#0f9488)",[458,523,525],{"x":516,"y":472,"style":524},"font-size:11px;font-weight:700;fill:var(--teal-ink,#0b6157);text-anchor:middle","\"medium\" \u002F \"thick\"",[442,527],{"x":511,"y":476,"width":512,"height":454,"rx":445,"fill":520,"stroke":521,"style":469},[458,529,530],{"x":516,"y":479,"style":524},"\"center\"",[442,532],{"x":511,"y":483,"width":512,"height":454,"rx":445,"fill":520,"stroke":521,"style":469},[458,534,535],{"x":516,"y":486,"style":524},"\"solid\"",[442,537],{"x":511,"y":490,"width":512,"height":454,"rx":445,"fill":520,"stroke":521,"style":469},[458,539,540],{"x":516,"y":493,"style":524},"\"landscape\"",[442,542],{"x":511,"y":497,"width":512,"height":454,"rx":445,"fill":520,"stroke":521,"style":469},[458,544,545],{"x":516,"y":500,"style":524},"\"decimal\" \u002F \"whole\"",[442,547],{"x":511,"y":504,"width":512,"height":454,"rx":445,"fill":520,"stroke":521,"style":469},[458,549,550],{"x":516,"y":507,"style":524},"\"hidden\"",[458,552,555],{"x":460,"y":553,"style":554},"29.0","font-size:12.5px;font-weight:700;fill:var(--muted,#5b6780);text-anchor:middle","what people type",[458,557,558],{"x":516,"y":553,"style":554},"what openpyxl accepts",[57,560],{"x1":561,"y1":512,"x2":562,"y2":512,"stroke":563,"style":564},"331.6","454.4","var(--brand,#5b5cf0)","stroke-width:2px",[566,567],"polygon",{"points":568,"fill":569},"458.4,138.0 449.4,143.0 449.4,133.0","#5b5cf0",[442,571],{"x":572,"y":573,"width":574,"height":575,"rx":576,"fill":448,"stroke":455,"style":577},"352.3","105.0","85.4","22.0","11","stroke-width:1.2px",[458,579,583],{"x":580,"y":581,"style":582},"395.0","120.0","font-size:11.5px;font-weight:400;fill:var(--brand-strong,#4338ca);text-anchor:middle;font-family:ui-monospace,SFMono-Regular,Menlo,Consolas,monospace","translate",[41,585,587],{"id":586},"step-2-the-usual-translations","Step 2 — The usual translations",[10,589,590],{},"The same handful of mistakes account for most of these errors. Corrected, the code from Step 1 and its relatives look like this:",[46,592,594],{"className":79,"code":593,"language":81,"meta":51,"style":51},"from openpyxl import Workbook\nfrom openpyxl.styles import Border\nfrom openpyxl.worksheet.datavalidation import DataValidation\n\nwb = Workbook()\nws = wb.active\nws[\"B2\"] = \"Total\"\nws[\"B2\"].border = Border(bottom=Side(style=\"medium\"))          # \"bold\" border\nws[\"B2\"].alignment = Alignment(horizontal=\"center\", vertical=\"center\")  # \"middle\"\nws[\"B2\"].fill = PatternFill(fill_type=\"solid\", fgColor=\"FFFF00\")         # \"Solid\"\nws[\"B2\"].font = Font(u=\"double\")                                # \"double underline\"\nws.page_setup.orientation = \"landscape\"                         # \"Landscape\"\ndv = DataValidation(type=\"decimal\", operator=\"greaterThan\", formula1=\"0\")  # \"number\"\nws.add_data_validation(dv)\ndv.add(\"C2:C20\")\nws.sheet_view.view = \"pageLayout\"                               # \"pageLayoutView\"\nprint(\"all accepted\")\n",[14,595,596,608,619,631,635,645,655,671,707,742,776,803,816,859,864,875,889],{"__ignoreMap":51},[55,597,598,600,603,605],{"class":57,"line":58},[55,599,89],{"class":88},[55,601,602],{"class":92}," openpyxl ",[55,604,96],{"class":88},[55,606,607],{"class":92}," Workbook\n",[55,609,610,612,614,616],{"class":57,"line":102},[55,611,89],{"class":88},[55,613,93],{"class":92},[55,615,96],{"class":88},[55,617,618],{"class":92}," Border\n",[55,620,621,623,626,628],{"class":57,"line":109},[55,622,89],{"class":88},[55,624,625],{"class":92}," openpyxl.worksheet.datavalidation ",[55,627,96],{"class":88},[55,629,630],{"class":92}," DataValidation\n",[55,632,633],{"class":57,"line":121},[55,634,106],{"emptyLinePlaceholder":105},[55,636,637,640,642],{"class":57,"line":148},[55,638,639],{"class":92},"wb ",[55,641,115],{"class":88},[55,643,644],{"class":92}," Workbook()\n",[55,646,647,650,652],{"class":57,"line":171},[55,648,649],{"class":92},"ws ",[55,651,115],{"class":88},[55,653,654],{"class":92}," wb.active\n",[55,656,657,660,663,666,668],{"class":57,"line":204},[55,658,659],{"class":92},"ws[",[55,661,662],{"class":65},"\"B2\"",[55,664,665],{"class":92},"] ",[55,667,115],{"class":88},[55,669,670],{"class":65}," \"Total\"\n",[55,672,673,675,677,680,682,685,688,690,693,695,697,700,703],{"class":57,"line":227},[55,674,659],{"class":92},[55,676,662],{"class":65},[55,678,679],{"class":92},"].border ",[55,681,115],{"class":88},[55,683,684],{"class":92}," Border(",[55,686,687],{"class":136},"bottom",[55,689,115],{"class":88},[55,691,692],{"class":92},"Side(",[55,694,137],{"class":136},[55,696,115],{"class":88},[55,698,699],{"class":65},"\"medium\"",[55,701,702],{"class":92},"))          ",[55,704,706],{"class":705},"s-wDw","# \"bold\" border\n",[55,708,709,711,713,716,718,721,723,725,727,729,732,734,736,739],{"class":57,"line":233},[55,710,659],{"class":92},[55,712,662],{"class":65},[55,714,715],{"class":92},"].alignment ",[55,717,115],{"class":88},[55,719,720],{"class":92}," Alignment(",[55,722,161],{"class":136},[55,724,115],{"class":88},[55,726,530],{"class":65},[55,728,25],{"class":92},[55,730,731],{"class":136},"vertical",[55,733,115],{"class":88},[55,735,530],{"class":65},[55,737,738],{"class":92},")  ",[55,740,741],{"class":705},"# \"middle\"\n",[55,743,744,746,748,751,753,756,758,760,762,764,766,768,770,773],{"class":57,"line":248},[55,745,659],{"class":92},[55,747,662],{"class":65},[55,749,750],{"class":92},"].fill ",[55,752,115],{"class":88},[55,754,755],{"class":92}," PatternFill(",[55,757,184],{"class":136},[55,759,115],{"class":88},[55,761,535],{"class":65},[55,763,25],{"class":92},[55,765,194],{"class":136},[55,767,115],{"class":88},[55,769,199],{"class":65},[55,771,772],{"class":92},")         ",[55,774,775],{"class":705},"# \"Solid\"\n",[55,777,778,780,782,785,787,790,792,794,797,800],{"class":57,"line":257},[55,779,659],{"class":92},[55,781,662],{"class":65},[55,783,784],{"class":92},"].font ",[55,786,115],{"class":88},[55,788,789],{"class":92}," Font(",[55,791,217],{"class":136},[55,793,115],{"class":88},[55,795,796],{"class":65},"\"double\"",[55,798,799],{"class":92},")                                ",[55,801,802],{"class":705},"# \"double underline\"\n",[55,804,805,808,810,813],{"class":57,"line":263},[55,806,807],{"class":92},"ws.page_setup.orientation ",[55,809,115],{"class":88},[55,811,812],{"class":65}," \"landscape\"",[55,814,815],{"class":705},"                         # \"Landscape\"\n",[55,817,818,821,823,826,829,831,834,836,839,841,844,846,849,851,854,856],{"class":57,"line":279},[55,819,820],{"class":92},"dv ",[55,822,115],{"class":88},[55,824,825],{"class":92}," DataValidation(",[55,827,828],{"class":136},"type",[55,830,115],{"class":88},[55,832,833],{"class":65},"\"decimal\"",[55,835,25],{"class":92},[55,837,838],{"class":136},"operator",[55,840,115],{"class":88},[55,842,843],{"class":65},"\"greaterThan\"",[55,845,25],{"class":92},[55,847,848],{"class":136},"formula1",[55,850,115],{"class":88},[55,852,853],{"class":65},"\"0\"",[55,855,738],{"class":92},[55,857,858],{"class":705},"# \"number\"\n",[55,860,861],{"class":57,"line":338},[55,862,863],{"class":92},"ws.add_data_validation(dv)\n",[55,865,867,870,873],{"class":57,"line":866},15,[55,868,869],{"class":92},"dv.add(",[55,871,872],{"class":65},"\"C2:C20\"",[55,874,376],{"class":92},[55,876,878,881,883,886],{"class":57,"line":877},16,[55,879,880],{"class":92},"ws.sheet_view.view ",[55,882,115],{"class":88},[55,884,885],{"class":65}," \"pageLayout\"",[55,887,888],{"class":705},"                               # \"pageLayoutView\"\n",[55,890,892,895,897,900],{"class":57,"line":891},17,[55,893,894],{"class":269},"print",[55,896,290],{"class":92},[55,898,899],{"class":65},"\"all accepted\"",[55,901,376],{"class":92},[10,903,904,906,907,909,910,913,914,917,918,920,921,29,924,926,927,25,930,29,933,39],{},[14,905,24],{}," is the heavier line most reports use under headings and totals; ",[14,908,387],{}," is heavier still. Data validation has ",[14,911,912],{},"whole"," for integers and ",[14,915,916],{},"decimal"," for any number. Vertical alignment's middle is also ",[14,919,28],{},", while its other values are ",[14,922,923],{},"top",[14,925,687],{},". Sheet views are ",[14,928,929],{},"normal",[14,931,932],{},"pageLayout",[14,934,935],{},"pageBreakPreview",[41,937,939],{"id":938},"step-3-use-openpyxls-constants-instead-of-strings","Step 3 — Use openpyxl's constants instead of strings",[10,941,942],{},"openpyxl defines module-level constants for most of these sets. They make typos impossible and show the valid options in an editor's autocomplete:",[46,944,946],{"className":79,"code":945,"language":81,"meta":51,"style":51},"from openpyxl.styles.borders import BORDER_MEDIUM, BORDER_THIN\nfrom openpyxl.styles.fills import FILL_SOLID\nfrom openpyxl.styles.alignment import horizontal_alignments, vertical_aligments\n\nprint(BORDER_MEDIUM, BORDER_THIN, FILL_SOLID)\nprint(\"horizontal:\", horizontal_alignments)\nprint(\"vertical:  \", vertical_aligments)\n",[14,947,948,965,977,989,993,1014,1026],{"__ignoreMap":51},[55,949,950,952,955,957,960,962],{"class":57,"line":58},[55,951,89],{"class":88},[55,953,954],{"class":92}," openpyxl.styles.borders ",[55,956,96],{"class":88},[55,958,959],{"class":269}," BORDER_MEDIUM",[55,961,25],{"class":92},[55,963,964],{"class":269},"BORDER_THIN\n",[55,966,967,969,972,974],{"class":57,"line":102},[55,968,89],{"class":88},[55,970,971],{"class":92}," openpyxl.styles.fills ",[55,973,96],{"class":88},[55,975,976],{"class":269}," FILL_SOLID\n",[55,978,979,981,984,986],{"class":57,"line":109},[55,980,89],{"class":88},[55,982,983],{"class":92}," openpyxl.styles.alignment ",[55,985,96],{"class":88},[55,987,988],{"class":92}," horizontal_alignments, vertical_aligments\n",[55,990,991],{"class":57,"line":121},[55,992,106],{"emptyLinePlaceholder":105},[55,994,995,997,999,1002,1004,1007,1009,1012],{"class":57,"line":148},[55,996,894],{"class":269},[55,998,290],{"class":92},[55,1000,1001],{"class":269},"BORDER_MEDIUM",[55,1003,25],{"class":92},[55,1005,1006],{"class":269},"BORDER_THIN",[55,1008,25],{"class":92},[55,1010,1011],{"class":269},"FILL_SOLID",[55,1013,376],{"class":92},[55,1015,1016,1018,1020,1023],{"class":57,"line":171},[55,1017,894],{"class":269},[55,1019,290],{"class":92},[55,1021,1022],{"class":65},"\"horizontal:\"",[55,1024,1025],{"class":92},", horizontal_alignments)\n",[55,1027,1028,1030,1032,1035],{"class":57,"line":204},[55,1029,894],{"class":269},[55,1031,290],{"class":92},[55,1033,1034],{"class":65},"\"vertical:  \"",[55,1036,1037],{"class":92},", vertical_aligments)\n",[10,1039,1040,1041,1044,1045,39],{},"The alignment tuples double as documentation: print them once and the valid values are in front of you. (The second name really is spelled ",[14,1042,1043],{},"vertical_aligments"," in openpyxl — copy it as is.) For a reusable set of styles built from these constants, see ",[35,1046,1048],{"href":1047},"\u002Fformatting-and-charting-excel-reports-with-python\u002Fstyling-excel-cells-with-openpyxl\u002Fapply-a-reusable-style-theme-across-an-excel-report\u002F","Apply a Reusable Style Theme Across an Excel Report",[41,1050,1052],{"id":1051},"step-4-max-value-is-and-colour-errors","Step 4 — \"Max value is\" and colour errors",[10,1054,1055],{},"Numeric attributes have ranges, and colours have a format:",[46,1057,1059],{"className":79,"code":1058,"language":81,"meta":51,"style":51},"for code, attempt in {\n    \"Alignment(indent=300)\": lambda: Alignment(indent=300),\n    \"Alignment(text_rotation=200)\": lambda: Alignment(text_rotation=200),\n    'Font(color=\"#FF0000\")': lambda: Font(color=\"#FF0000\"),\n    'PatternFill(\"solid\", fgColor=\"red\")': lambda: PatternFill(\"solid\", fgColor=\"red\"),\n}.items():\n    try:\n        attempt()\n    except ValueError as exc:\n        print(f\"{code:36} -> {str(exc)[:70]}\")\n\nprint(Font(color=\"FF0000\").color.rgb, Alignment(text_rotation=135).text_rotation)\n",[14,1060,1061,1071,1092,1113,1134,1158,1163,1169,1173,1183,1223,1227],{"__ignoreMap":51},[55,1062,1063,1065,1067,1069],{"class":57,"line":58},[55,1064,236],{"class":88},[55,1066,239],{"class":92},[55,1068,242],{"class":88},[55,1070,118],{"class":92},[55,1072,1073,1076,1078,1080,1082,1085,1087,1090],{"class":57,"line":102},[55,1074,1075],{"class":65},"    \"Alignment(indent=300)\"",[55,1077,127],{"class":92},[55,1079,130],{"class":88},[55,1081,158],{"class":92},[55,1083,1084],{"class":136},"indent",[55,1086,115],{"class":88},[55,1088,1089],{"class":269},"300",[55,1091,145],{"class":92},[55,1093,1094,1097,1099,1101,1103,1106,1108,1111],{"class":57,"line":109},[55,1095,1096],{"class":65},"    \"Alignment(text_rotation=200)\"",[55,1098,127],{"class":92},[55,1100,130],{"class":88},[55,1102,158],{"class":92},[55,1104,1105],{"class":136},"text_rotation",[55,1107,115],{"class":88},[55,1109,1110],{"class":269},"200",[55,1112,145],{"class":92},[55,1114,1115,1118,1120,1122,1124,1127,1129,1132],{"class":57,"line":121},[55,1116,1117],{"class":65},"    'Font(color=\"#FF0000\")'",[55,1119,127],{"class":92},[55,1121,130],{"class":88},[55,1123,214],{"class":92},[55,1125,1126],{"class":136},"color",[55,1128,115],{"class":88},[55,1130,1131],{"class":65},"\"#FF0000\"",[55,1133,145],{"class":92},[55,1135,1136,1139,1141,1143,1145,1147,1149,1151,1153,1156],{"class":57,"line":148},[55,1137,1138],{"class":65},"    'PatternFill(\"solid\", fgColor=\"red\")'",[55,1140,127],{"class":92},[55,1142,130],{"class":88},[55,1144,181],{"class":92},[55,1146,535],{"class":65},[55,1148,25],{"class":92},[55,1150,194],{"class":136},[55,1152,115],{"class":88},[55,1154,1155],{"class":65},"\"red\"",[55,1157,145],{"class":92},[55,1159,1160],{"class":57,"line":171},[55,1161,1162],{"class":92},"}.items():\n",[55,1164,1165,1167],{"class":57,"line":204},[55,1166,251],{"class":88},[55,1168,254],{"class":92},[55,1170,1171],{"class":57,"line":227},[55,1172,260],{"class":92},[55,1174,1175,1177,1179,1181],{"class":57,"line":233},[55,1176,266],{"class":88},[55,1178,270],{"class":269},[55,1180,273],{"class":88},[55,1182,276],{"class":92},[55,1184,1185,1187,1189,1191,1193,1195,1197,1200,1202,1204,1206,1208,1211,1214,1217,1219,1221],{"class":57,"line":248},[55,1186,341],{"class":269},[55,1188,290],{"class":92},[55,1190,346],{"class":88},[55,1192,349],{"class":65},[55,1194,353],{"class":352},[55,1196,14],{"class":92},[55,1198,1199],{"class":88},":36",[55,1201,361],{"class":352},[55,1203,364],{"class":65},[55,1205,353],{"class":352},[55,1207,293],{"class":269},[55,1209,1210],{"class":92},"(exc)[:",[55,1212,1213],{"class":269},"70",[55,1215,1216],{"class":92},"]",[55,1218,361],{"class":352},[55,1220,349],{"class":65},[55,1222,376],{"class":92},[55,1224,1225],{"class":57,"line":257},[55,1226,106],{"emptyLinePlaceholder":105},[55,1228,1229,1231,1234,1236,1238,1241,1244,1246,1248,1251],{"class":57,"line":263},[55,1230,894],{"class":269},[55,1232,1233],{"class":92},"(Font(",[55,1235,1126],{"class":136},[55,1237,115],{"class":88},[55,1239,1240],{"class":65},"\"FF0000\"",[55,1242,1243],{"class":92},").color.rgb, Alignment(",[55,1245,1105],{"class":136},[55,1247,115],{"class":88},[55,1249,1250],{"class":269},"135",[55,1252,1253],{"class":92},").text_rotation)\n",[10,1255,1256,1258,1259,1262,1263,1265,1266,127,1269,1271,1272,1275,1276,1278,1279,1281,1282,1285,1286,39],{},[14,1257,1084],{}," is capped at 255 (",[14,1260,1261],{},"Max value is 255","). ",[14,1264,1105],{}," accepts 0–180, where 0–90 rotate counter-clockwise and 91–180 rotate clockwise (an angle of −45° is written as 135); 255 means vertical stacked text — which is why the error for 200 lists every number from 0 to 180 (the printed set leaves out 255, which openpyxl nevertheless accepts). Colours must be hex without ",[14,1267,1268],{},"#",[14,1270,1240],{}," or the eight-digit ",[14,1273,1274],{},"\"FFFF0000\""," with alpha, never ",[14,1277,1131],{}," or ",[14,1280,1155],{}," (",[14,1283,1284],{},"Colors must be aRGB hex values","). Rotation is covered in ",[35,1287,1289],{"href":1288},"\u002Fformatting-and-charting-excel-reports-with-python\u002Fstyling-excel-cells-with-openpyxl\u002Frotate-text-in-excel-cells-with-openpyxl\u002F","Rotate Text in Excel Cells with openpyxl",[423,1291,432,1297,432,1300,432,1303,432,1308,432,1313,432,1318,432,1324,432,1327,432,1331,432,1335,432,1341,432,1343,432,1348,432,1350,432,1352,432,1355,432,1359,432,1361,432,1364,432,1366,432,1368,432,1370,432,1374,432,1376,432,1380,432,1382,432,1384,432,1387,432,1390,432,1392,432,1396,432,1398,432,1401,432,1404,432,1408,432,1410,432,1414,432,1416,432,1419,432,1422,432,1426,432,1428,432,1432,432,1434],{"viewBox":1292,"role":426,"ariaLabelledBy":1293,"xmlns":430,"style":1296},"4 0 752 276",[1294,1295],"vm-ranges-t","vm-ranges-d","width:100%;max-width:752px;height:auto;display:block;margin:1.5rem auto;font-family:Inter,ui-sans-serif,system-ui,sans-serif",[434,1298,1299],{"id":1294},"Value rules openpyxl enforces on common attributes",[438,1301,1302],{"id":1295},"Border style, horizontal and vertical alignment, fill type and underline must come from fixed name sets. Indent has a maximum of 255. Text rotation must be 0 to 180 or 255. Colours must be six or eight hex digits without a hash.",[442,1304],{"x":1305,"y":445,"width":1306,"height":1307,"fill":448},"4","752","276",[442,1309],{"x":1310,"y":1311,"width":1312,"height":452,"rx":445,"fill":448,"stroke":455,"style":456},"20.0","16.0","228.5",[442,1314],{"x":1315,"y":1311,"width":1316,"height":452,"rx":445,"fill":1317,"stroke":563,"style":577},"248.5","245.7","#f0f4ff",[458,1319,1323],{"x":1320,"y":1321,"style":1322},"371.4","41.0","font-size:13px;font-weight:700;fill:var(--brand-strong,#4338ca);text-anchor:middle","rule",[442,1325],{"x":1326,"y":1311,"width":1316,"height":452,"rx":445,"fill":1317,"stroke":563,"style":577},"494.3",[458,1328,1330],{"x":1329,"y":1321,"style":1322},"617.1","example that passes",[442,1332],{"x":1310,"y":1333,"width":1312,"height":1334,"rx":445,"fill":513,"stroke":455,"style":456},"56.0","34.0",[458,1336,1340],{"x":1337,"y":1338,"style":1339},"32.0","78.0","font-size:12.5px;font-weight:700;fill:var(--text,#172033);text-anchor:start","Side(style=…)",[442,1342],{"x":1315,"y":1333,"width":1316,"height":1334,"rx":445,"fill":448,"stroke":455,"style":456},[458,1344,1347],{"x":1320,"y":1345,"style":1346},"77.0","font-size:11.5px;font-weight:400;fill:var(--text,#172033);text-anchor:middle","fixed names",[442,1349],{"x":1326,"y":1333,"width":1316,"height":1334,"rx":445,"fill":448,"stroke":455,"style":456},[458,1351,699],{"x":1329,"y":1345,"style":1346},[442,1353],{"x":1310,"y":1354,"width":1312,"height":1334,"rx":445,"fill":513,"stroke":455,"style":456},"90.0",[458,1356,1358],{"x":1337,"y":1357,"style":1339},"112.0","Alignment(horizontal \u002F vertical)",[442,1360],{"x":1315,"y":1354,"width":1316,"height":1334,"rx":445,"fill":448,"stroke":455,"style":456},[458,1362,1347],{"x":1320,"y":1363,"style":1346},"111.0",[442,1365],{"x":1326,"y":1354,"width":1316,"height":1334,"rx":445,"fill":448,"stroke":455,"style":456},[458,1367,530],{"x":1329,"y":1363,"style":1346},[442,1369],{"x":1310,"y":483,"width":1312,"height":1334,"rx":445,"fill":513,"stroke":455,"style":456},[458,1371,1373],{"x":1337,"y":1372,"style":1339},"146.0","PatternFill(fill_type=…)",[442,1375],{"x":1315,"y":483,"width":1316,"height":1334,"rx":445,"fill":448,"stroke":455,"style":456},[458,1377,1379],{"x":1320,"y":1378,"style":1346},"145.0","fixed names, lower case",[442,1381],{"x":1326,"y":483,"width":1316,"height":1334,"rx":445,"fill":448,"stroke":455,"style":456},[458,1383,535],{"x":1329,"y":1378,"style":1346},[442,1385],{"x":1310,"y":1386,"width":1312,"height":1334,"rx":445,"fill":513,"stroke":455,"style":456},"158.0",[458,1388,1389],{"x":1337,"y":497,"style":1339},"Alignment(indent=…)",[442,1391],{"x":1315,"y":1386,"width":1316,"height":1334,"rx":445,"fill":448,"stroke":455,"style":456},[458,1393,1395],{"x":1320,"y":1394,"style":1346},"179.0","0 – 255",[442,1397],{"x":1326,"y":1386,"width":1316,"height":1334,"rx":445,"fill":448,"stroke":455,"style":456},[458,1399,1400],{"x":1329,"y":1394,"style":1346},"2",[442,1402],{"x":1310,"y":1403,"width":1312,"height":1334,"rx":445,"fill":513,"stroke":455,"style":456},"192.0",[458,1405,1407],{"x":1337,"y":1406,"style":1339},"214.0","Alignment(text_rotation=…)",[442,1409],{"x":1315,"y":1403,"width":1316,"height":1334,"rx":445,"fill":448,"stroke":455,"style":456},[458,1411,1413],{"x":1320,"y":1412,"style":1346},"213.0","0 – 180, or 255",[442,1415],{"x":1326,"y":1403,"width":1316,"height":1334,"rx":445,"fill":448,"stroke":455,"style":456},[458,1417,1418],{"x":1329,"y":1412,"style":1346},"135 (= −45°)",[442,1420],{"x":1310,"y":1421,"width":1312,"height":1334,"rx":445,"fill":513,"stroke":455,"style":456},"226.0",[458,1423,1425],{"x":1337,"y":1424,"style":1339},"248.0","Font(color=…), fgColor",[442,1427],{"x":1315,"y":1421,"width":1316,"height":1334,"rx":445,"fill":448,"stroke":455,"style":456},[458,1429,1431],{"x":1320,"y":1430,"style":1346},"247.0","aRGB hex, no #",[442,1433],{"x":1326,"y":1421,"width":1316,"height":1334,"rx":445,"fill":448,"stroke":455,"style":456},[458,1435,1240],{"x":1329,"y":1430,"style":1346},[41,1437,1439],{"id":1438},"step-5-values-that-are-only-checked-when-you-save","Step 5 — Values that are only checked when you save",[10,1441,1442,1443,1446],{},"Not every attribute is validated when you set it. Some are accepted silently and rejected by ",[14,1444,1445],{},"save()",", after part of the file has been written:",[46,1448,1450],{"className":79,"code":1449,"language":81,"meta":51,"style":51},"from pathlib import Path\nimport zipfile\n\nwb = Workbook()\nwb.create_sheet(\"Data\")\nwb.active.sheet_state = \"hide\"           # should be \"hidden\" — no error here\ntry:\n    wb.save(\"broken.xlsx\")\nexcept ValueError as exc:\n    print(\"save failed:\", exc)\nprint(\"file left behind:\", Path(\"broken.xlsx\").exists(), \"| valid zip:\", zipfile.is_zipfile(\"broken.xlsx\"))\nprint(\"has workbook.xml:\", \"xl\u002Fworkbook.xml\" in zipfile.ZipFile(\"broken.xlsx\").namelist())\n",[14,1451,1452,1464,1471,1475,1483,1493,1506,1513,1523,1534,1547,1574],{"__ignoreMap":51},[55,1453,1454,1456,1459,1461],{"class":57,"line":58},[55,1455,89],{"class":88},[55,1457,1458],{"class":92}," pathlib ",[55,1460,96],{"class":88},[55,1462,1463],{"class":92}," Path\n",[55,1465,1466,1468],{"class":57,"line":102},[55,1467,96],{"class":88},[55,1469,1470],{"class":92}," zipfile\n",[55,1472,1473],{"class":57,"line":109},[55,1474,106],{"emptyLinePlaceholder":105},[55,1476,1477,1479,1481],{"class":57,"line":121},[55,1478,639],{"class":92},[55,1480,115],{"class":88},[55,1482,644],{"class":92},[55,1484,1485,1488,1491],{"class":57,"line":148},[55,1486,1487],{"class":92},"wb.create_sheet(",[55,1489,1490],{"class":65},"\"Data\"",[55,1492,376],{"class":92},[55,1494,1495,1498,1500,1503],{"class":57,"line":171},[55,1496,1497],{"class":92},"wb.active.sheet_state ",[55,1499,115],{"class":88},[55,1501,1502],{"class":65}," \"hide\"",[55,1504,1505],{"class":705},"           # should be \"hidden\" — no error here\n",[55,1507,1508,1511],{"class":57,"line":204},[55,1509,1510],{"class":88},"try",[55,1512,254],{"class":92},[55,1514,1515,1518,1521],{"class":57,"line":227},[55,1516,1517],{"class":92},"    wb.save(",[55,1519,1520],{"class":65},"\"broken.xlsx\"",[55,1522,376],{"class":92},[55,1524,1525,1528,1530,1532],{"class":57,"line":233},[55,1526,1527],{"class":88},"except",[55,1529,270],{"class":269},[55,1531,273],{"class":88},[55,1533,276],{"class":92},[55,1535,1536,1539,1541,1544],{"class":57,"line":248},[55,1537,1538],{"class":269},"    print",[55,1540,290],{"class":92},[55,1542,1543],{"class":65},"\"save failed:\"",[55,1545,1546],{"class":92},", exc)\n",[55,1548,1549,1551,1553,1556,1559,1561,1564,1567,1570,1572],{"class":57,"line":257},[55,1550,894],{"class":269},[55,1552,290],{"class":92},[55,1554,1555],{"class":65},"\"file left behind:\"",[55,1557,1558],{"class":92},", Path(",[55,1560,1520],{"class":65},[55,1562,1563],{"class":92},").exists(), ",[55,1565,1566],{"class":65},"\"| valid zip:\"",[55,1568,1569],{"class":92},", zipfile.is_zipfile(",[55,1571,1520],{"class":65},[55,1573,335],{"class":92},[55,1575,1576,1578,1580,1583,1585,1588,1591,1594,1596],{"class":57,"line":263},[55,1577,894],{"class":269},[55,1579,290],{"class":92},[55,1581,1582],{"class":65},"\"has workbook.xml:\"",[55,1584,25],{"class":92},[55,1586,1587],{"class":65},"\"xl\u002Fworkbook.xml\"",[55,1589,1590],{"class":88}," in",[55,1592,1593],{"class":92}," zipfile.ZipFile(",[55,1595,1520],{"class":65},[55,1597,1598],{"class":92},").namelist())\n",[10,1600,1601,1602,1605,1606,1608,1609,1612,1613,1616,1617,1620,1621,1624,1625,1629],{},"Setting ",[14,1603,1604],{},"sheet_state = \"hide\""," raises nothing; ",[14,1607,1445],{}," then fails with ",[14,1610,1611],{},"Value must be one of {'visible', 'hidden', 'veryHidden'}"," — and leaves ",[14,1614,1615],{},"broken.xlsx"," on disk as a ZIP without its workbook part, which Excel cannot open and which overwrites whatever good file had that name before. Assigning a plain string as a cell's fill (",[14,1618,1619],{},"cell.fill = \"FFFF00\"",") behaves the same way, failing at save with a ",[14,1622,1623],{},"TypeError",". Two defences: save to a temporary name and rename only on success, as in ",[35,1626,1628],{"href":1627},"\u002Fautomating-reporting-workflows\u002Ferror-handling-and-logging-in-excel-automation\u002Fwrite-excel-files-atomically-in-python\u002F","Write Excel Files Atomically in Python",", and keep a test that saves the workbook so these errors appear in development rather than in the nightly run.",[423,1631,432,1636,432,1639,432,1642,432,1645,432,1652,432,1663,432,1669,432,1673,432,1677,432,1682,432,1685,432,1688,432,1695,432,1701,432,1705,432,1709,432,1712,432,1715,432,1722,432,1727,432,1730,432,1734,432,1737,432,1740,432,1746,432,1750],{"viewBox":1632,"role":426,"ariaLabelledBy":1633,"xmlns":430,"style":1296},"4 0 752 142",[1634,1635],"vm-save-t","vm-save-d",[434,1637,1638],{"id":1634},"How a bad value can survive until save",[438,1640,1641],{"id":1635},"Assigning sheet_state \"hide\" raises no error. The report is built. At save time openpyxl validates the value, raises ValueError, and leaves a partial file on disk without its workbook part.",[442,1643],{"x":1305,"y":445,"width":1306,"height":1644,"fill":448},"142",[442,1646],{"x":1310,"y":1311,"width":1647,"height":1648,"rx":1649,"fill":1650,"stroke":1651,"style":564},"153.0","110.5","12","#fdefd8","var(--gold,#b4740a)",[1653,1654,1656],"g",{"transform":1655},"translate(84.5,29.0) scale(1.000)",[1657,1658],"path",{"d":1659,"fill":1660,"stroke":1661,"style":1662},"M12 3.5l9.5 17h-19z M12 10v5 M12 17.8v.4","none","var(--gold-ink,#7a4e06)","stroke-width:1.80px;stroke-linecap:round;stroke-linejoin:round",[458,1664,1668],{"x":1665,"y":1666,"style":1667},"96.5","75.5","font-size:13.5px;font-weight:700;fill:var(--gold-ink,#7a4e06);text-anchor:middle","sheet_state =",[458,1670,1672],{"x":1665,"y":1671,"style":1667},"93.0","\"hide\"",[458,1674,1676],{"x":1665,"y":1675,"style":1346},"112.5","accepted silently",[57,1678],{"x1":1679,"y1":1680,"x2":1681,"y2":1680,"stroke":563,"style":564},"178.0","71.2","200.0",[566,1683],{"points":1684,"fill":569},"204.0,71.2 195.0,76.2 195.0,66.2",[442,1686],{"x":1687,"y":1311,"width":1647,"height":1648,"rx":1649,"fill":513,"stroke":455,"style":564},"209.0",[1653,1689,1691],{"transform":1690},"translate(273.5,37.8) scale(1.000)",[1657,1692],{"d":1693,"fill":1660,"stroke":1694,"style":1662},"M12 9a3 3 0 1 0 .01 0z M12 2.5v3 M12 18.5v3 M2.5 12h3 M18.5 12h3 M5.3 5.3l2.1 2.1 M16.6 16.6l2.1 2.1 M5.3 18.7l2.1-2.1 M16.6 7.4l2.1-2.1","var(--text,#172033)",[458,1696,1700],{"x":1697,"y":1698,"style":1699},"285.5","84.2","font-size:13.5px;font-weight:700;fill:var(--text,#172033);text-anchor:middle","Build the report",[458,1702,1704],{"x":1697,"y":1703,"style":1346},"103.8","minutes of work",[57,1706],{"x1":1707,"y1":1680,"x2":1708,"y2":1680,"stroke":563,"style":564},"367.0","389.0",[566,1710],{"points":1711,"fill":569},"393.0,71.2 384.0,76.2 384.0,66.2",[442,1713],{"x":1714,"y":1311,"width":1647,"height":1648,"rx":1649,"fill":467,"stroke":468,"style":564},"398.0",[1653,1716,1718],{"transform":1717},"translate(462.5,37.8) scale(1.000)",[1657,1719],{"d":1720,"fill":1660,"stroke":1721,"style":1662},"M6 6l12 12 M18 6L6 18","var(--accent-ink,#be185d)",[458,1723,1726],{"x":1724,"y":1698,"style":1725},"474.5","font-size:13.5px;font-weight:700;fill:var(--accent-ink,#be185d);text-anchor:middle","wb.save(path)",[458,1728,1729],{"x":1724,"y":1703,"style":1346},"ValueError raised",[57,1731],{"x1":1732,"y1":1680,"x2":1733,"y2":1680,"stroke":563,"style":564},"556.0","578.0",[566,1735],{"points":1736,"fill":569},"582.0,71.2 573.0,76.2 573.0,66.2",[442,1738],{"x":1739,"y":1311,"width":1647,"height":1648,"rx":1649,"fill":467,"stroke":468,"style":564},"587.0",[1653,1741,1743],{"transform":1742},"translate(651.5,37.8) scale(1.000)",[1657,1744],{"d":1745,"fill":1660,"stroke":1721,"style":1662},"M6 3h9l4 4v14H6z M15 3v4h4",[458,1747,1749],{"x":1748,"y":1698,"style":1725},"663.5","Partial file left",[458,1751,1752],{"x":1748,"y":1703,"style":1346},"no xl\u002Fworkbook.xml",[41,1754,1756],{"id":1755},"step-6-check-style-settings-from-a-config-file-up-front","Step 6 — Check style settings from a config file up front",[10,1758,1759],{},"Report styles often live in a configuration file so that people can change colours and borders without touching code. That moves these errors to whoever edits the file, at run time. Check the whole configuration before building anything and report every problem at once:",[46,1761,1763],{"className":79,"code":1762,"language":81,"meta":51,"style":51},"import re\n\nSTYLE_RULES = {\n    \"border\": set(Side.style.values) - {None},\n    \"align\": set(horizontal_alignments),\n    \"valign\": set(vertical_aligments),\n    \"fill\": set(PatternFill.patternType.values) - {None},\n}\nHEX = re.compile(r\"^[0-9A-Fa-f]{6}([0-9A-Fa-f]{2})?$\")\n\ndef check_styles(config):\n    problems = []\n    for name, spec in config.items():\n        for key, value in spec.items():\n            if key in STYLE_RULES and value not in STYLE_RULES[key]:\n                close = [v for v in STYLE_RULES[key] if v.lower() == str(value).lower()]\n                hint = f\" (did you mean {close[0]!r}?)\" if close else \"\"\n                problems.append(f\"{name}.{key}={value!r} is not one of {sorted(STYLE_RULES[key])}{hint}\")\n            if key.endswith(\"color\") and not HEX.match(str(value)):\n                problems.append(f\"{name}.{key}={value!r} must be hex like 'FF0000'\")\n    return problems\n\nconfig = {\"header\": {\"fill\": \"Solid\", \"fill_color\": \"#4338CA\", \"align\": \"center\"},\n          \"total\": {\"border\": \"bold\", \"valign\": \"middle\"}}\nfor p in check_styles(config):\n    print(\"-\", p)\n",[14,1764,1765,1772,1776,1786,1811,1823,1835,1855,1859,1908,1912,1924,1934,1947,1960,1989,2026,2068,2132,2163,2201,2210,2215,2259,2286,2299],{"__ignoreMap":51},[55,1766,1767,1769],{"class":57,"line":58},[55,1768,96],{"class":88},[55,1770,1771],{"class":92}," re\n",[55,1773,1774],{"class":57,"line":102},[55,1775,106],{"emptyLinePlaceholder":105},[55,1777,1778,1781,1784],{"class":57,"line":109},[55,1779,1780],{"class":269},"STYLE_RULES",[55,1782,1783],{"class":88}," =",[55,1785,118],{"class":92},[55,1787,1788,1791,1793,1796,1799,1802,1805,1808],{"class":57,"line":121},[55,1789,1790],{"class":65},"    \"border\"",[55,1792,127],{"class":92},[55,1794,1795],{"class":269},"set",[55,1797,1798],{"class":92},"(Side.style.values) ",[55,1800,1801],{"class":88},"-",[55,1803,1804],{"class":92}," {",[55,1806,1807],{"class":269},"None",[55,1809,1810],{"class":92},"},\n",[55,1812,1813,1816,1818,1820],{"class":57,"line":148},[55,1814,1815],{"class":65},"    \"align\"",[55,1817,127],{"class":92},[55,1819,1795],{"class":269},[55,1821,1822],{"class":92},"(horizontal_alignments),\n",[55,1824,1825,1828,1830,1832],{"class":57,"line":171},[55,1826,1827],{"class":65},"    \"valign\"",[55,1829,127],{"class":92},[55,1831,1795],{"class":269},[55,1833,1834],{"class":92},"(vertical_aligments),\n",[55,1836,1837,1840,1842,1844,1847,1849,1851,1853],{"class":57,"line":204},[55,1838,1839],{"class":65},"    \"fill\"",[55,1841,127],{"class":92},[55,1843,1795],{"class":269},[55,1845,1846],{"class":92},"(PatternFill.patternType.values) ",[55,1848,1801],{"class":88},[55,1850,1804],{"class":92},[55,1852,1807],{"class":269},[55,1854,1810],{"class":92},[55,1856,1857],{"class":57,"line":227},[55,1858,230],{"class":92},[55,1860,1861,1864,1866,1869,1872,1874,1877,1880,1882,1885,1888,1890,1892,1895,1898,1901,1904,1906],{"class":57,"line":233},[55,1862,1863],{"class":269},"HEX",[55,1865,1783],{"class":88},[55,1867,1868],{"class":92}," re.compile(",[55,1870,1871],{"class":88},"r",[55,1873,349],{"class":65},[55,1875,1876],{"class":269},"^[",[55,1878,1879],{"class":352},"0-9A-Fa-f",[55,1881,1216],{"class":269},[55,1883,1884],{"class":88},"{6}",[55,1886,1887],{"class":269},"([",[55,1889,1879],{"class":352},[55,1891,1216],{"class":269},[55,1893,1894],{"class":88},"{2}",[55,1896,1897],{"class":269},")",[55,1899,1900],{"class":88},"?",[55,1902,1903],{"class":269},"$",[55,1905,349],{"class":65},[55,1907,376],{"class":92},[55,1909,1910],{"class":57,"line":248},[55,1911,106],{"emptyLinePlaceholder":105},[55,1913,1914,1917,1921],{"class":57,"line":257},[55,1915,1916],{"class":88},"def",[55,1918,1920],{"class":1919},"s_Opv"," check_styles",[55,1922,1923],{"class":92},"(config):\n",[55,1925,1926,1929,1931],{"class":57,"line":263},[55,1927,1928],{"class":92},"    problems ",[55,1930,115],{"class":88},[55,1932,1933],{"class":92}," []\n",[55,1935,1936,1939,1942,1944],{"class":57,"line":279},[55,1937,1938],{"class":88},"    for",[55,1940,1941],{"class":92}," name, spec ",[55,1943,242],{"class":88},[55,1945,1946],{"class":92}," config.items():\n",[55,1948,1949,1952,1955,1957],{"class":57,"line":338},[55,1950,1951],{"class":88},"        for",[55,1953,1954],{"class":92}," key, value ",[55,1956,242],{"class":88},[55,1958,1959],{"class":92}," spec.items():\n",[55,1961,1962,1965,1968,1970,1973,1976,1979,1982,1984,1986],{"class":57,"line":866},[55,1963,1964],{"class":88},"            if",[55,1966,1967],{"class":92}," key ",[55,1969,242],{"class":88},[55,1971,1972],{"class":269}," STYLE_RULES",[55,1974,1975],{"class":88}," and",[55,1977,1978],{"class":92}," value ",[55,1980,1981],{"class":88},"not",[55,1983,1590],{"class":88},[55,1985,1972],{"class":269},[55,1987,1988],{"class":92},"[key]:\n",[55,1990,1991,1994,1996,1999,2001,2004,2006,2008,2011,2014,2017,2020,2023],{"class":57,"line":877},[55,1992,1993],{"class":92},"                close ",[55,1995,115],{"class":88},[55,1997,1998],{"class":92}," [v ",[55,2000,236],{"class":88},[55,2002,2003],{"class":92}," v ",[55,2005,242],{"class":88},[55,2007,1972],{"class":269},[55,2009,2010],{"class":92},"[key] ",[55,2012,2013],{"class":88},"if",[55,2015,2016],{"class":92}," v.lower() ",[55,2018,2019],{"class":88},"==",[55,2021,2022],{"class":269}," str",[55,2024,2025],{"class":92},"(value).lower()]\n",[55,2027,2028,2031,2033,2036,2039,2041,2044,2046,2048,2051,2053,2056,2059,2062,2065],{"class":57,"line":891},[55,2029,2030],{"class":92},"                hint ",[55,2032,115],{"class":88},[55,2034,2035],{"class":88}," f",[55,2037,2038],{"class":65},"\" (did you mean ",[55,2040,353],{"class":352},[55,2042,2043],{"class":92},"close[",[55,2045,445],{"class":269},[55,2047,1216],{"class":92},[55,2049,2050],{"class":88},"!r",[55,2052,361],{"class":352},[55,2054,2055],{"class":65},"?)\"",[55,2057,2058],{"class":88}," if",[55,2060,2061],{"class":92}," close ",[55,2063,2064],{"class":88},"else",[55,2066,2067],{"class":65}," \"\"\n",[55,2069,2071,2074,2076,2078,2080,2083,2085,2087,2089,2092,2094,2096,2098,2101,2103,2105,2108,2110,2113,2115,2117,2120,2123,2126,2128,2130],{"class":57,"line":2070},18,[55,2072,2073],{"class":92},"                problems.append(",[55,2075,346],{"class":88},[55,2077,349],{"class":65},[55,2079,353],{"class":352},[55,2081,2082],{"class":92},"name",[55,2084,361],{"class":352},[55,2086,39],{"class":65},[55,2088,353],{"class":352},[55,2090,2091],{"class":92},"key",[55,2093,361],{"class":352},[55,2095,115],{"class":65},[55,2097,353],{"class":352},[55,2099,2100],{"class":92},"value",[55,2102,2050],{"class":88},[55,2104,361],{"class":352},[55,2106,2107],{"class":65}," is not one of ",[55,2109,353],{"class":352},[55,2111,2112],{"class":269},"sorted",[55,2114,290],{"class":92},[55,2116,1780],{"class":269},[55,2118,2119],{"class":92},"[key])",[55,2121,2122],{"class":352},"}{",[55,2124,2125],{"class":92},"hint",[55,2127,361],{"class":352},[55,2129,349],{"class":65},[55,2131,376],{"class":92},[55,2133,2135,2137,2140,2143,2146,2149,2152,2155,2158,2160],{"class":57,"line":2134},19,[55,2136,1964],{"class":88},[55,2138,2139],{"class":92}," key.endswith(",[55,2141,2142],{"class":65},"\"color\"",[55,2144,2145],{"class":92},") ",[55,2147,2148],{"class":88},"and",[55,2150,2151],{"class":88}," not",[55,2153,2154],{"class":269}," HEX",[55,2156,2157],{"class":92},".match(",[55,2159,293],{"class":269},[55,2161,2162],{"class":92},"(value)):\n",[55,2164,2166,2168,2170,2172,2174,2176,2178,2180,2182,2184,2186,2188,2190,2192,2194,2196,2199],{"class":57,"line":2165},20,[55,2167,2073],{"class":92},[55,2169,346],{"class":88},[55,2171,349],{"class":65},[55,2173,353],{"class":352},[55,2175,2082],{"class":92},[55,2177,361],{"class":352},[55,2179,39],{"class":65},[55,2181,353],{"class":352},[55,2183,2091],{"class":92},[55,2185,361],{"class":352},[55,2187,115],{"class":65},[55,2189,353],{"class":352},[55,2191,2100],{"class":92},[55,2193,2050],{"class":88},[55,2195,361],{"class":352},[55,2197,2198],{"class":65}," must be hex like 'FF0000'\"",[55,2200,376],{"class":92},[55,2202,2204,2207],{"class":57,"line":2203},21,[55,2205,2206],{"class":88},"    return",[55,2208,2209],{"class":92}," problems\n",[55,2211,2213],{"class":57,"line":2212},22,[55,2214,106],{"emptyLinePlaceholder":105},[55,2216,2218,2221,2223,2225,2228,2231,2234,2236,2238,2240,2243,2245,2248,2250,2253,2255,2257],{"class":57,"line":2217},23,[55,2219,2220],{"class":92},"config ",[55,2222,115],{"class":88},[55,2224,1804],{"class":92},[55,2226,2227],{"class":65},"\"header\"",[55,2229,2230],{"class":92},": {",[55,2232,2233],{"class":65},"\"fill\"",[55,2235,127],{"class":92},[55,2237,189],{"class":65},[55,2239,25],{"class":92},[55,2241,2242],{"class":65},"\"fill_color\"",[55,2244,127],{"class":92},[55,2246,2247],{"class":65},"\"#4338CA\"",[55,2249,25],{"class":92},[55,2251,2252],{"class":65},"\"align\"",[55,2254,127],{"class":92},[55,2256,530],{"class":65},[55,2258,1810],{"class":92},[55,2260,2262,2265,2267,2270,2272,2274,2276,2279,2281,2283],{"class":57,"line":2261},24,[55,2263,2264],{"class":65},"          \"total\"",[55,2266,2230],{"class":92},[55,2268,2269],{"class":65},"\"border\"",[55,2271,127],{"class":92},[55,2273,142],{"class":65},[55,2275,25],{"class":92},[55,2277,2278],{"class":65},"\"valign\"",[55,2280,127],{"class":92},[55,2282,166],{"class":65},[55,2284,2285],{"class":92},"}}\n",[55,2287,2289,2291,2294,2296],{"class":57,"line":2288},25,[55,2290,236],{"class":88},[55,2292,2293],{"class":92}," p ",[55,2295,242],{"class":88},[55,2297,2298],{"class":92}," check_styles(config):\n",[55,2300,2302,2304,2306,2309],{"class":57,"line":2301},26,[55,2303,1538],{"class":269},[55,2305,290],{"class":92},[55,2307,2308],{"class":65},"\"-\"",[55,2310,2311],{"class":92},", p)\n",[10,2313,2314,2315,25,2318,1281,2321,2323,2324,2327,2328,39],{},"The descriptor objects on openpyxl's classes — ",[14,2316,2317],{},"Side.style.values",[14,2319,2320],{},"PatternFill.patternType.values",[14,2322,184],{}," is an alias for it) — hold the same sets the error messages print, so the check never drifts from what openpyxl enforces. A case-insensitive comparison turns ",[14,2325,2326],{},"Solid"," into a helpful \"did you mean 'solid'?\", and a single list of problems beats fixing them one exception at a time. Where report settings live and how to load them is covered in ",[35,2329,2331],{"href":2330},"\u002Fautomating-reporting-workflows\u002Ftesting-and-packaging-excel-automation-scripts\u002Fkeep-excel-report-settings-in-a-config-file\u002F","Keep Excel Report Settings in a Config File",[41,2333,2335],{"id":2334},"common-pitfalls","Common pitfalls",[2337,2338,2339,2361,2372,2384,2390,2406],"ul",{},[2340,2341,2342,2346,2347,25,2349,25,2351,25,2354,29,2357,2360],"li",{},[2343,2344,2345],"strong",{},"Menu names instead of file-format names."," ",[14,2348,397],{},[14,2350,404],{},[14,2352,2353],{},"Landscape",[14,2355,2356],{},"number",[14,2358,2359],{},"hide"," are not valid; read the set in the error.",[2340,2362,2363,2346,2366,29,2368,2371],{},[2343,2364,2365],{},"Capitalisation.",[14,2367,2326],{},[14,2369,2370],{},"Center"," fail; every name is case-sensitive.",[2340,2373,2374,2380,2381,2383],{},[2343,2375,2376,2377,2379],{},"Colours with ",[14,2378,1268],{}," or names."," Use ",[14,2382,1240],{},"; convert CSS colours first.",[2340,2385,2386,2389],{},[2343,2387,2388],{},"Assuming validation happens on assignment."," Some values fail only at save; test the save.",[2340,2391,2392,2395,2396,2398,2399,2402,2403,39],{},[2343,2393,2394],{},"Sets that include None."," Several attributes also accept ",[14,2397,1807],{}," (no border, no fill); the descriptor's ",[14,2400,2401],{},"values"," set contains it, which is why the checker above subtracts ",[14,2404,2405],{},"{None}",[2340,2407,2408,2411],{},[2343,2409,2410],{},"Overwriting the last good file."," A failed save leaves a broken file at the target path; write to a temporary path first.",[41,2413,2415],{"id":2414},"conclusion","Conclusion",[10,2417,2418,2421,2422,1278,2424,2426,2427,2429,2430,2432,2433,25,2435,1278,2437,2439,2440,2443,2444,2446,2447,2449],{},[14,2419,2420],{},"Value must be one of {...}"," is openpyxl telling you the exact names the file format accepts — use ",[14,2423,24],{},[14,2425,387],{}," for bold borders, ",[14,2428,28],{}," for middle alignment, lower-case ",[14,2431,408],{}," fills, ",[14,2434,32],{},[14,2436,916],{},[14,2438,912],{}," validations and ",[14,2441,2442],{},"hidden"," sheets, or the constants openpyxl provides. Keep numbers in range (",[14,2445,1084],{}," ≤ 255, rotation 0–180 or 255), write colours as hex without ",[14,2448,1268],{},", and save to a temporary file, because a few values are only checked at save time and leave a broken workbook behind.",[41,2451,2453],{"id":2452},"frequently-asked-questions","Frequently asked questions",[10,2455,2456,2459],{},[2343,2457,2458],{},"Why does openpyxl say \"Value must be one of\" for my border style?","\nopenpyxl only accepts the border names the Excel file format uses: thin, medium, thick, double, dashed, dotted, hair and the dash-dot variants. There is no bold; use medium or thick.",[10,2461,2462,2465],{},[2343,2463,2464],{},"How do I centre text vertically in openpyxl?","\nUse Alignment(vertical=\"center\"). The accepted vertical values are top, center, bottom, justify and distributed; middle is not one of them.",[10,2467,2468,2471],{},[2343,2469,2470],{},"What does \"Colors must be aRGB hex values\" mean?","\nThe colour was given as \"#FF0000\", a name like \"red\", or another format. openpyxl needs six or eight hexadecimal digits without a hash, such as \"FF0000\" or \"FFFF0000\".",[10,2473,2474,2477],{},[2343,2475,2476],{},"Why did openpyxl fail only when saving the workbook?","\nSome attributes, such as sheet_state, are validated when the file is written rather than when they are set. The save raises the ValueError and leaves a partial file behind, so save to a temporary path and rename it after success.",[41,2479,2481],{"id":2480},"related","Related",[2337,2483,2484,2490,2497,2504],{},[2340,2485,2486,2487,2489],{},"Up one level: ",[35,2488,38],{"href":37}," — fixes for common failures.",[2340,2491,2492,2496],{},[35,2493,2495],{"href":2494},"\u002Fgetting-started-with-python-excel-automation\u002Ftroubleshooting-common-python-excel-errors\u002Ffix-openpyxl-typeerror-expected-class\u002F","Fix openpyxl \"TypeError: expected \u003Cclass ...>\""," — the error for passing the wrong kind of object.",[2340,2498,2499,2503],{},[35,2500,2502],{"href":2501},"\u002Fformatting-and-charting-excel-reports-with-python\u002Fstyling-excel-cells-with-openpyxl\u002Fadd-borders-to-a-range-with-openpyxl\u002F","Add Borders to a Range with openpyxl"," — borders with valid styles.",[2340,2505,2506,2510],{},[35,2507,2509],{"href":2508},"\u002Fformatting-and-charting-excel-reports-with-python\u002Fstyling-excel-cells-with-openpyxl\u002Fwrap-text-and-align-cells-with-openpyxl\u002F","Wrap Text and Align Cells with openpyxl"," — alignment options in practice.",[137,2512,2513],{},"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 .sa561, html code.shiki .sa561{--shiki-default:#E36209;--shiki-dark:#FFB757}html pre.shiki code .sP0c6, html code.shiki .sP0c6{--shiki-default:#005CC5;--shiki-dark:#91CBFF}html pre.shiki code .sSjpA, html code.shiki .sSjpA{--shiki-default:#005CC5;--shiki-dark:#FF9492}html pre.shiki code .s-wDw, html code.shiki .s-wDw{--shiki-default:#6A737D;--shiki-dark:#BDC4CC}html pre.shiki code .s_Opv, html code.shiki .s_Opv{--shiki-default:#6F42C1;--shiki-dark:#DBB7FF}",{"title":51,"searchDepth":102,"depth":102,"links":2515},[2516,2517,2518,2519,2520,2521,2522,2523,2524,2525,2526],{"id":43,"depth":102,"text":44},{"id":75,"depth":102,"text":76},{"id":586,"depth":102,"text":587},{"id":938,"depth":102,"text":939},{"id":1051,"depth":102,"text":1052},{"id":1438,"depth":102,"text":1439},{"id":1755,"depth":102,"text":1756},{"id":2334,"depth":102,"text":2335},{"id":2414,"depth":102,"text":2415},{"id":2452,"depth":102,"text":2453},{"id":2480,"depth":102,"text":2481},"2026-10-02","openpyxl validates style and settings values against the names Excel uses internally, so Side(style=\"bold\"), Alignment(horizontal=\"middle\"), PatternFill(\"Solid\") and orientation=\"Landscape\" all fail with ValueError: Value must be one of {...}. Translate the familiar names to the accepted ones, use openpyxl's constants, handle \"Max value is\" and colour errors, and watch for values that are only checked at save time — after half a file has been written.","md",[2531,2533,2535,2537],{"q":2458,"a":2532},"openpyxl only accepts the border names the Excel file format uses: thin, medium, thick, double, dashed, dotted, hair and the dash-dot variants. There is no bold; use medium or thick.",{"q":2464,"a":2534},"Use Alignment(vertical=\"center\"). The accepted vertical values are top, center, bottom, justify and distributed; middle is not one of them.",{"q":2470,"a":2536},"The colour was given as \"#FF0000\", a name like \"red\", or another format. openpyxl needs six or eight hexadecimal digits without a hash, such as \"FF0000\" or \"FFFF0000\".",{"q":2476,"a":2538},"Some attributes, such as sheet_state, are validated when the file is written rather than when they are set. The save raises the ValueError and leaves a partial file behind, so save to a temporary path and rename it after success.","fix openpyxl value must be one of errors",null,{"breadcrumb":2542},[2543,2546,2549],{"name":2544,"item":2545},"Home","\u002F",{"name":2547,"item":2548},"Getting Started with Python Excel Automation","\u002Fgetting-started-with-python-excel-automation\u002F",{"name":38,"item":37},"\u002Fgetting-started-with-python-excel-automation\u002Ftroubleshooting-common-python-excel-errors\u002Ffix-openpyxl-value-must-be-one-of-errors",{"title":2552,"description":2553},"Fix openpyxl ValueError \"Value must be one of\" and \"Max value is\"","Why openpyxl rejects Side(style=\"bold\"), Alignment(horizontal=\"middle\"), PatternFill(\"Solid\"), DataValidation(type=\"number\") and orientation=\"Landscape\": the accepted Excel names, constants, Max value limits, aRGB colour errors and save-time validation that leaves broken files.","fix-openpyxl-value-must-be-one-of-errors","getting-started-with-python-excel-automation\u002Ftroubleshooting-common-python-excel-errors\u002Ffix-openpyxl-value-must-be-one-of-errors\u002Findex",[2557,2558,2559],"troubleshooting","openpyxl","cell-styling","how-to","Rgc4SrX_grVsqWRsgybQ0N3nkNHXpRkX6sicV4Kt6rU",[2563,2566],{"title":2495,"path":2564,"stem":2565,"children":-1},"\u002Fgetting-started-with-python-excel-automation\u002Ftroubleshooting-common-python-excel-errors\u002Ffix-openpyxl-typeerror-expected-class","getting-started-with-python-excel-automation\u002Ftroubleshooting-common-python-excel-errors\u002Ffix-openpyxl-typeerror-expected-class\u002Findex",{"title":2567,"path":2568,"stem":2569,"children":-1},"Fix \"OverflowError: date value out of range\" When Reading Excel","\u002Fgetting-started-with-python-excel-automation\u002Ftroubleshooting-common-python-excel-errors\u002Ffix-overflowerror-date-value-out-of-range-when-reading-excel","getting-started-with-python-excel-automation\u002Ftroubleshooting-common-python-excel-errors\u002Ffix-overflowerror-date-value-out-of-range-when-reading-excel\u002Findex",[2571,2573],{"path":2572,"title":2547},"\u002Fgetting-started-with-python-excel-automation",{"path":2574,"title":38},"\u002Fgetting-started-with-python-excel-automation\u002Ftroubleshooting-common-python-excel-errors",[],[2577,2581,2584,2587,2590,2593],{"path":2578,"title":2579,"kind":2580},"\u002Fautomating-reporting-workflows\u002Ferror-handling-and-logging-in-excel-automation\u002Fhandle-permission-denied-when-writing-excel-in-python","Handle Permission Denied When Writing Excel in Python","fix",{"path":2582,"title":2583,"kind":2560},"\u002Fgetting-started-with-python-excel-automation\u002Fusing-openpyxl-for-excel-file-manipulation\u002Fwhat-openpyxl-loses-when-saving-an-existing-workbook","What openpyxl Loses When You Save an Existing Workbook",{"path":2585,"title":2586,"kind":2580},"\u002Fadvanced-data-transformation-and-cleaning\u002Fworking-with-dates-and-times-in-excel-data\u002Ffix-excel-serial-numbers-showing-instead-of-dates","Fix Excel Serial Numbers Showing Instead of Dates",{"path":2588,"title":2589,"kind":2560},"\u002Fadvanced-data-transformation-and-cleaning\u002Fworking-with-dates-and-times-in-excel-data\u002Fhandle-daylight-saving-time-in-excel-timestamps","Handle Daylight Saving Time in Excel Timestamps",{"path":2591,"title":2592,"kind":2560},"\u002Fautomating-reporting-workflows\u002Fautomating-excel-online-with-microsoft-graph\u002Fhandle-microsoft-graph-throttling-for-excel","Handle Microsoft Graph Throttling in Excel Automation",{"path":2594,"title":2595,"kind":2596},"\u002Fautomating-reporting-workflows\u002Ferror-handling-and-logging-in-excel-automation","Error Handling and Logging in Excel Automation","guide",1790972067323]