[{"data":1,"prerenderedAt":2205},["ShallowReactive",2],{"doc:\u002Fformatting-and-charting-excel-reports-with-python\u002Fcreating-excel-tables-and-autofilters-with-python\u002Frename-and-restyle-existing-excel-tables":3,"surround:\u002Fformatting-and-charting-excel-reports-with-python\u002Fcreating-excel-tables-and-autofilters-with-python\u002Frename-and-restyle-existing-excel-tables":2172,"ancestors:\u002Fformatting-and-charting-excel-reports-with-python\u002Fcreating-excel-tables-and-autofilters-with-python\u002Frename-and-restyle-existing-excel-tables":2180,"children:\u002Fformatting-and-charting-excel-reports-with-python\u002Fcreating-excel-tables-and-autofilters-with-python\u002Frename-and-restyle-existing-excel-tables":2185,"related:\u002Fformatting-and-charting-excel-reports-with-python\u002Fcreating-excel-tables-and-autofilters-with-python\u002Frename-and-restyle-existing-excel-tables":2186},{"id":4,"title":5,"body":6,"dateModified":2138,"datePublished":2138,"description":2139,"extension":2140,"faq":2141,"keyword":2150,"kind":2151,"meta":2152,"navigation":133,"path":2161,"seo":2162,"slug":2165,"stem":2166,"topics":2167,"type":2170,"__hash__":2171},"docs\u002Fformatting-and-charting-excel-reports-with-python\u002Fcreating-excel-tables-and-autofilters-with-python\u002Frename-and-restyle-existing-excel-tables\u002Findex.md","Rename and Restyle Existing Excel Tables",{"type":7,"value":8,"toc":2126},"minimark",[9,44,49,74,93,97,579,607,768,772,1444,1462,1469,1573,1577,1719,1752,1756,1876,1892,1956,1960,1968,1972,2021,2025,2042,2046,2062,2068,2074,2089,2093,2122],[10,11,12,13,17,18,17,21,24,25,29,30,33,34,37,38,43],"p",{},"Tables created by hand in Excel are named ",[14,15,16],"em",{},"Table1",", ",[14,19,20],{},"Table2",[14,22,23],{},"Table13"," in the order they were made, and formulas that use them read ",[26,27,28],"code",{},"=SUM(Table7[Amount])"," — correct, but meaningless to anyone maintaining the workbook. Renaming them in Excel's Table Design tab updates every formula automatically. Renaming them from Python does not: openpyxl stores formulas as plain text, so changing the table's name leaves every ",[26,31,32],{},"Table7[...]"," pointing at a table that no longer exists, and Excel shows ",[26,35,36],{},"#REF!"," the next time it calculates. This page renames tables safely — the table object, its key in the sheet and every structured reference in formulas, defined names, data validation and conditional formatting — then applies a consistent style to every table in the workbook, and proves the formulas still calculate the same results. It belongs to ",[39,40,42],"a",{"href":41},"\u002Fformatting-and-charting-excel-reports-with-python\u002Fcreating-excel-tables-and-autofilters-with-python\u002F","Creating Excel Tables and Autofilters with Python",".",[45,46,48],"h2",{"id":47},"prerequisites","Prerequisites",[50,51,56],"pre",{"className":52,"code":53,"language":54,"meta":55,"style":55},"language-bash shiki shiki-themes github-light github-dark-high-contrast","pip install openpyxl\n","bash","",[26,57,58],{"__ignoreMap":55},[59,60,63,67,71],"span",{"class":61,"line":62},"line",1,[59,64,66],{"class":65},"sMTad","pip",[59,68,70],{"class":69},"srMev"," install",[59,72,73],{"class":69}," openpyxl\n",[10,75,76,77,80,81,83,84,80,87,83,89,92],{},"The example workbook has an ",[14,78,79],{},"Orders"," table called ",[14,82,16],{},", a ",[14,85,86],{},"Regions",[14,88,20],{},[14,90,91],{},"Summary"," sheet whose formulas use both, a defined name, a dropdown whose list comes from a table column, and a conditional formatting rule that refers to a table. LibreOffice is used to recalculate the formulas as a check; it understands structured references.",[45,94,96],{"id":95},"step-1-find-every-place-a-table-name-is-used","Step 1 — Find every place a table name is used",[50,98,102],{"className":99,"code":100,"language":101,"meta":55,"style":55},"language-python shiki shiki-themes github-light github-dark-high-contrast","import re\nfrom openpyxl import load_workbook\n\ndef table_refs(wb, name):\n    \"\"\"Yield (where, text) for every formula-like string that refers to the table.\"\"\"\n    rx = re.compile(rf\"(?\u003C![\\w.]){re.escape(name)}\\[\", re.IGNORECASE)\n    for ws in wb.worksheets:\n        for row in ws.iter_rows():\n            for c in row:\n                if isinstance(c.value, str) and c.value.startswith(\"=\") and rx.search(c.value):\n                    yield f\"{ws.title}!{c.coordinate}\", c.value\n        for dv in ws.data_validations.dataValidation:\n            if dv.formula1 and rx.search(dv.formula1):\n                yield f\"{ws.title} validation {dv.sqref}\", dv.formula1\n        for cf in ws.conditional_formatting:\n            for rule in cf.rules:\n                for f in rule.formula or []:\n                    if rx.search(f):\n                        yield f\"{ws.title} format {cf.sqref}\", f\n    for dn_name, dn in wb.defined_names.items():\n        if rx.search(dn.attr_text or \"\"):\n            yield f\"name {dn_name}\", dn.attr_text\n\nwb = load_workbook(\"orders.xlsx\")\nfor where, text in table_refs(wb, \"Table1\"):\n    print(f\"{where:28} {text}\")\n","python",[26,103,104,114,128,135,148,154,195,210,224,238,272,306,319,333,364,377,390,410,419,450,463,480,503,508,524,543],{"__ignoreMap":55},[59,105,106,110],{"class":61,"line":62},[59,107,109],{"class":108},"s-kum","import",[59,111,113],{"class":112},"skGVy"," re\n",[59,115,117,120,123,125],{"class":61,"line":116},2,[59,118,119],{"class":108},"from",[59,121,122],{"class":112}," openpyxl ",[59,124,109],{"class":108},[59,126,127],{"class":112}," load_workbook\n",[59,129,131],{"class":61,"line":130},3,[59,132,134],{"emptyLinePlaceholder":133},true,"\n",[59,136,138,141,145],{"class":61,"line":137},4,[59,139,140],{"class":108},"def",[59,142,144],{"class":143},"s_Opv"," table_refs",[59,146,147],{"class":112},"(wb, name):\n",[59,149,151],{"class":61,"line":150},5,[59,152,153],{"class":69},"    \"\"\"Yield (where, text) for every formula-like string that refers to the table.\"\"\"\n",[59,155,157,160,163,166,169,172,176,179,182,185,188,192],{"class":61,"line":156},6,[59,158,159],{"class":112},"    rx ",[59,161,162],{"class":108},"=",[59,164,165],{"class":112}," re.compile(",[59,167,168],{"class":108},"rf",[59,170,171],{"class":69},"\"(?\u003C![\\w.])",[59,173,175],{"class":174},"sSjpA","{",[59,177,178],{"class":112},"re.escape(name)",[59,180,181],{"class":174},"}",[59,183,184],{"class":69},"\\[\"",[59,186,187],{"class":112},", re.",[59,189,191],{"class":190},"sP0c6","IGNORECASE",[59,193,194],{"class":112},")\n",[59,196,198,201,204,207],{"class":61,"line":197},7,[59,199,200],{"class":108},"    for",[59,202,203],{"class":112}," ws ",[59,205,206],{"class":108},"in",[59,208,209],{"class":112}," wb.worksheets:\n",[59,211,213,216,219,221],{"class":61,"line":212},8,[59,214,215],{"class":108},"        for",[59,217,218],{"class":112}," row ",[59,220,206],{"class":108},[59,222,223],{"class":112}," ws.iter_rows():\n",[59,225,227,230,233,235],{"class":61,"line":226},9,[59,228,229],{"class":108},"            for",[59,231,232],{"class":112}," c ",[59,234,206],{"class":108},[59,236,237],{"class":112}," row:\n",[59,239,241,244,247,250,253,256,259,262,265,267,269],{"class":61,"line":240},10,[59,242,243],{"class":108},"                if",[59,245,246],{"class":190}," isinstance",[59,248,249],{"class":112},"(c.value, ",[59,251,252],{"class":190},"str",[59,254,255],{"class":112},") ",[59,257,258],{"class":108},"and",[59,260,261],{"class":112}," c.value.startswith(",[59,263,264],{"class":69},"\"=\"",[59,266,255],{"class":112},[59,268,258],{"class":108},[59,270,271],{"class":112}," rx.search(c.value):\n",[59,273,275,278,281,284,286,289,291,294,296,299,301,303],{"class":61,"line":274},11,[59,276,277],{"class":108},"                    yield",[59,279,280],{"class":108}," f",[59,282,283],{"class":69},"\"",[59,285,175],{"class":174},[59,287,288],{"class":112},"ws.title",[59,290,181],{"class":174},[59,292,293],{"class":69},"!",[59,295,175],{"class":174},[59,297,298],{"class":112},"c.coordinate",[59,300,181],{"class":174},[59,302,283],{"class":69},[59,304,305],{"class":112},", c.value\n",[59,307,309,311,314,316],{"class":61,"line":308},12,[59,310,215],{"class":108},[59,312,313],{"class":112}," dv ",[59,315,206],{"class":108},[59,317,318],{"class":112}," ws.data_validations.dataValidation:\n",[59,320,322,325,328,330],{"class":61,"line":321},13,[59,323,324],{"class":108},"            if",[59,326,327],{"class":112}," dv.formula1 ",[59,329,258],{"class":108},[59,331,332],{"class":112}," rx.search(dv.formula1):\n",[59,334,336,339,341,343,345,347,349,352,354,357,359,361],{"class":61,"line":335},14,[59,337,338],{"class":108},"                yield",[59,340,280],{"class":108},[59,342,283],{"class":69},[59,344,175],{"class":174},[59,346,288],{"class":112},[59,348,181],{"class":174},[59,350,351],{"class":69}," validation ",[59,353,175],{"class":174},[59,355,356],{"class":112},"dv.sqref",[59,358,181],{"class":174},[59,360,283],{"class":69},[59,362,363],{"class":112},", dv.formula1\n",[59,365,367,369,372,374],{"class":61,"line":366},15,[59,368,215],{"class":108},[59,370,371],{"class":112}," cf ",[59,373,206],{"class":108},[59,375,376],{"class":112}," ws.conditional_formatting:\n",[59,378,380,382,385,387],{"class":61,"line":379},16,[59,381,229],{"class":108},[59,383,384],{"class":112}," rule ",[59,386,206],{"class":108},[59,388,389],{"class":112}," cf.rules:\n",[59,391,393,396,399,401,404,407],{"class":61,"line":392},17,[59,394,395],{"class":108},"                for",[59,397,398],{"class":112}," f ",[59,400,206],{"class":108},[59,402,403],{"class":112}," rule.formula ",[59,405,406],{"class":108},"or",[59,408,409],{"class":112}," []:\n",[59,411,413,416],{"class":61,"line":412},18,[59,414,415],{"class":108},"                    if",[59,417,418],{"class":112}," rx.search(f):\n",[59,420,422,425,427,429,431,433,435,438,440,443,445,447],{"class":61,"line":421},19,[59,423,424],{"class":108},"                        yield",[59,426,280],{"class":108},[59,428,283],{"class":69},[59,430,175],{"class":174},[59,432,288],{"class":112},[59,434,181],{"class":174},[59,436,437],{"class":69}," format ",[59,439,175],{"class":174},[59,441,442],{"class":112},"cf.sqref",[59,444,181],{"class":174},[59,446,283],{"class":69},[59,448,449],{"class":112},", f\n",[59,451,453,455,458,460],{"class":61,"line":452},20,[59,454,200],{"class":108},[59,456,457],{"class":112}," dn_name, dn ",[59,459,206],{"class":108},[59,461,462],{"class":112}," wb.defined_names.items():\n",[59,464,466,469,472,474,477],{"class":61,"line":465},21,[59,467,468],{"class":108},"        if",[59,470,471],{"class":112}," rx.search(dn.attr_text ",[59,473,406],{"class":108},[59,475,476],{"class":69}," \"\"",[59,478,479],{"class":112},"):\n",[59,481,483,486,488,491,493,496,498,500],{"class":61,"line":482},22,[59,484,485],{"class":108},"            yield",[59,487,280],{"class":108},[59,489,490],{"class":69},"\"name ",[59,492,175],{"class":174},[59,494,495],{"class":112},"dn_name",[59,497,181],{"class":174},[59,499,283],{"class":69},[59,501,502],{"class":112},", dn.attr_text\n",[59,504,506],{"class":61,"line":505},23,[59,507,134],{"emptyLinePlaceholder":133},[59,509,511,514,516,519,522],{"class":61,"line":510},24,[59,512,513],{"class":112},"wb ",[59,515,162],{"class":108},[59,517,518],{"class":112}," load_workbook(",[59,520,521],{"class":69},"\"orders.xlsx\"",[59,523,194],{"class":112},[59,525,527,530,533,535,538,541],{"class":61,"line":526},25,[59,528,529],{"class":108},"for",[59,531,532],{"class":112}," where, text ",[59,534,206],{"class":108},[59,536,537],{"class":112}," table_refs(wb, ",[59,539,540],{"class":69},"\"Table1\"",[59,542,479],{"class":112},[59,544,546,549,552,555,557,559,562,565,567,570,573,575,577],{"class":61,"line":545},26,[59,547,548],{"class":190},"    print",[59,550,551],{"class":112},"(",[59,553,554],{"class":108},"f",[59,556,283],{"class":69},[59,558,175],{"class":174},[59,560,561],{"class":112},"where",[59,563,564],{"class":108},":28",[59,566,181],{"class":174},[59,568,569],{"class":174}," {",[59,571,572],{"class":112},"text",[59,574,181],{"class":174},[59,576,283],{"class":69},[59,578,194],{"class":112},[10,580,581,582,585,586,17,589,17,592,595,596,598,599,602,603,606],{},"A structured reference is the table name followed directly by ",[26,583,584],{},"[",": ",[26,587,588],{},"Table1[Amount]",[26,590,591],{},"Table1[[#Data],[Amount]]",[26,593,594],{},"Table1[#All]",". The pattern matches the name only when it is followed by a bracket and not preceded by a letter, digit or full stop, so renaming ",[14,597,16],{}," never touches ",[14,600,601],{},"Table10"," or ",[14,604,605],{},"MyTable1",". Table names are not case-sensitive in Excel, so neither is the search. Formulas live in more places than cells: data validation lists, conditional formatting rules and defined names can all refer to a table, and each needs updating. Listing them before changing anything shows the scope of a rename, which is worth a look on a workbook you did not build.",[608,609,617,618,617,622,617,626,617,634,617,643,617,647,617,653,617,657,617,661,617,665,617,669,617,674,617,678,617,680,617,683,617,686,617,690,617,692,617,696,617,698,617,701,617,704,617,708,617,710,617,713,617,715,617,718,617,721,617,725,617,727,617,730,617,732,617,735,617,738,617,742,617,744,617,747,617,749,617,752,617,755,617,759,617,761,617,764,617,766],"svg",{"viewBox":610,"role":611,"ariaLabelledBy":612,"xmlns":615,"style":616},"120 0 519 224","img",[613,614],"rn-refs-t","rn-refs-d","http:\u002F\u002Fwww.w3.org\u002F2000\u002Fsvg","width:100%;max-width:519px;height:auto;display:block;margin:1.5rem auto;font-family:Inter,ui-sans-serif,system-ui,sans-serif","\n  ",[619,620,621],"title",{"id":613},"Where Table1 is referred to",[623,624,625],"desc",{"id":614},"Three Summary cells use Table1 in SUM, SUMIFS and MAX formulas. A conditional formatting rule on the Orders sheet compares amounts with the table average, and the defined name OrderAmounts points at the Amount column.",[627,628],"rect",{"x":629,"y":630,"width":631,"height":632,"fill":633},"120","0","519","224","#ffffff",[627,635],{"x":636,"y":637,"width":638,"height":639,"rx":630,"fill":640,"stroke":641,"style":642},"136.6","16.0","32.0","24.0","#e7ebef","var(--line,#cdd5e6)","stroke-width:1px",[627,644],{"x":645,"y":637,"width":646,"height":639,"rx":630,"fill":640,"stroke":641,"style":642},"168.6","152.6",[572,648,652],{"x":649,"y":650,"style":651},"244.9","33.0","font-size:11px;font-weight:600;fill:var(--muted,#5b6780);text-anchor:middle","A",[627,654],{"x":655,"y":637,"width":656,"height":639,"rx":630,"fill":640,"stroke":641,"style":642},"321.2","302.2",[572,658,660],{"x":659,"y":650,"style":651},"472.3","B",[627,662],{"x":636,"y":663,"width":638,"height":664,"rx":630,"fill":640,"stroke":641,"style":642},"40.0","28.0",[572,666,668],{"x":646,"y":667,"style":651},"59.0","1",[627,670],{"x":645,"y":663,"width":646,"height":664,"rx":630,"fill":671,"stroke":672,"style":673},"#f0f4ff","var(--brand,#5b5cf0)","stroke-width:1.5px",[572,675,677],{"x":649,"y":667,"style":676},"font-size:12px;font-weight:700;fill:var(--brand-strong,#4338ca);text-anchor:middle","Where",[627,679],{"x":655,"y":663,"width":656,"height":664,"rx":630,"fill":671,"stroke":672,"style":673},[572,681,682],{"x":659,"y":667,"style":676},"Formula",[627,684],{"x":636,"y":685,"width":638,"height":664,"rx":630,"fill":640,"stroke":641,"style":642},"68.0",[572,687,689],{"x":646,"y":688,"style":651},"87.0","2",[627,691],{"x":645,"y":685,"width":646,"height":664,"rx":630,"fill":633,"stroke":641,"style":642},[572,693,695],{"x":649,"y":688,"style":694},"font-size:12px;font-weight:400;fill:var(--text,#172033);text-anchor:middle","Summary!B1",[627,697],{"x":655,"y":685,"width":656,"height":664,"rx":630,"fill":633,"stroke":641,"style":642},[572,699,700],{"x":659,"y":688,"style":694},"=SUM(Table1[Amount])",[627,702],{"x":636,"y":703,"width":638,"height":664,"rx":630,"fill":640,"stroke":641,"style":642},"96.0",[572,705,707],{"x":646,"y":706,"style":651},"115.0","3",[627,709],{"x":645,"y":703,"width":646,"height":664,"rx":630,"fill":633,"stroke":641,"style":642},[572,711,712],{"x":649,"y":706,"style":694},"Summary!B2",[627,714],{"x":655,"y":703,"width":656,"height":664,"rx":630,"fill":633,"stroke":641,"style":642},[572,716,717],{"x":659,"y":706,"style":694},"=SUMIFS(Table1[Amount],Table1[Region],…)",[627,719],{"x":636,"y":720,"width":638,"height":664,"rx":630,"fill":640,"stroke":641,"style":642},"124.0",[572,722,724],{"x":646,"y":723,"style":651},"143.0","4",[627,726],{"x":645,"y":720,"width":646,"height":664,"rx":630,"fill":633,"stroke":641,"style":642},[572,728,729],{"x":649,"y":723,"style":694},"Summary!B4",[627,731],{"x":655,"y":720,"width":656,"height":664,"rx":630,"fill":633,"stroke":641,"style":642},[572,733,734],{"x":659,"y":723,"style":694},"=MAX(Table1[[#Data],[Amount]])",[627,736],{"x":636,"y":737,"width":638,"height":664,"rx":630,"fill":640,"stroke":641,"style":642},"152.0",[572,739,741],{"x":646,"y":740,"style":651},"171.0","5",[627,743],{"x":645,"y":737,"width":646,"height":664,"rx":630,"fill":633,"stroke":641,"style":642},[572,745,746],{"x":649,"y":740,"style":694},"Orders format C2:C5",[627,748],{"x":655,"y":737,"width":656,"height":664,"rx":630,"fill":633,"stroke":641,"style":642},[572,750,751],{"x":659,"y":740,"style":694},"C2>AVERAGE(Table1[Amount])",[627,753],{"x":636,"y":754,"width":638,"height":664,"rx":630,"fill":640,"stroke":641,"style":642},"180.0",[572,756,758],{"x":646,"y":757,"style":651},"199.0","6",[627,760],{"x":645,"y":754,"width":646,"height":664,"rx":630,"fill":633,"stroke":641,"style":642},[572,762,763],{"x":649,"y":757,"style":694},"name OrderAmounts",[627,765],{"x":655,"y":754,"width":656,"height":664,"rx":630,"fill":633,"stroke":641,"style":642},[572,767,588],{"x":659,"y":757,"style":694},[45,769,771],{"id":770},"step-2-rename-the-table-and-rewrite-the-references","Step 2 — Rename the table and rewrite the references",[50,773,775],{"className":99,"code":774,"language":101,"meta":55,"style":55},"NAME_RX = re.compile(r\"[A-Za-z_\\\\][\\w.]{0,254}\")\n\ndef rename_table(wb, old, new):\n    if not NAME_RX.fullmatch(new) or re.fullmatch(r\"[A-Za-z]{1,3}\\d+\", new):\n        raise ValueError(f\"{new!r} is not a valid table name\")\n    taken = {t.lower() for ws in wb.worksheets for t in ws.tables} | {n.lower() for n in wb.defined_names}\n    if new.lower() in taken - {old.lower()}:\n        raise ValueError(f\"{new!r} is already used by a table or defined name\")\n    ws = next(ws for ws in wb.worksheets if old in ws.tables)\n    table = ws.tables[old]\n    table.name = table.displayName = new\n    del ws.tables[old]\n    ws.tables[new] = table\n\n    rx = re.compile(rf\"(?\u003C![\\w.]){re.escape(old)}(?=\\[)\", re.IGNORECASE)\n    count = 0\n    def sub(text):\n        nonlocal count\n        text, n = rx.subn(new, text)\n        count += n\n        return text\n    for sheet in wb.worksheets:\n        for row in sheet.iter_rows():\n            for c in row:\n                if isinstance(c.value, str) and c.value.startswith(\"=\"):\n                    c.value = sub(c.value)\n        for dv in sheet.data_validations.dataValidation:\n            if dv.formula1:\n                dv.formula1 = sub(dv.formula1)\n        for cf in sheet.conditional_formatting:\n            for rule in cf.rules:\n                rule.formula = [sub(f) for f in rule.formula or []]\n    for dn in wb.defined_names.values():\n        dn.attr_text = sub(dn.attr_text or \"\")\n    return count\n\nprint(\"Table1 -> Orders:\", rename_table(wb, \"Table1\", \"Orders\"), \"references updated\")\nprint(\"Table2 -> Regions:\", rename_table(wb, \"Table2\", \"Regions\"), \"references updated\")\ntry:\n    rename_table(wb, \"Orders\", \"OrderAmounts\")\nexcept ValueError as e:\n    print(\"refused:\", e)\n",[26,776,777,816,820,830,874,903,948,966,991,1023,1033,1048,1055,1065,1069,1097,1107,1118,1126,1136,1147,1155,1166,1177,1187,1207,1217,1229,1237,1248,1260,1271,1295,1308,1325,1333,1338,1367,1393,1402,1417,1431],{"__ignoreMap":55},[59,778,779,782,785,787,790,792,794,797,801,804,806,809,812,814],{"class":61,"line":62},[59,780,781],{"class":190},"NAME_RX",[59,783,784],{"class":108}," =",[59,786,165],{"class":112},[59,788,789],{"class":108},"r",[59,791,283],{"class":69},[59,793,584],{"class":190},[59,795,796],{"class":174},"A-Za-z_",[59,798,800],{"class":799},"s_b0D","\\\\",[59,802,803],{"class":190},"][\\w",[59,805,43],{"class":174},[59,807,808],{"class":190},"]",[59,810,811],{"class":108},"{0,254}",[59,813,283],{"class":69},[59,815,194],{"class":112},[59,817,818],{"class":61,"line":116},[59,819,134],{"emptyLinePlaceholder":133},[59,821,822,824,827],{"class":61,"line":130},[59,823,140],{"class":108},[59,825,826],{"class":143}," rename_table",[59,828,829],{"class":112},"(wb, old, new):\n",[59,831,832,835,838,841,844,846,849,851,853,855,858,860,863,866,869,871],{"class":61,"line":137},[59,833,834],{"class":108},"    if",[59,836,837],{"class":108}," not",[59,839,840],{"class":190}," NAME_RX",[59,842,843],{"class":112},".fullmatch(new) ",[59,845,406],{"class":108},[59,847,848],{"class":112}," re.fullmatch(",[59,850,789],{"class":108},[59,852,283],{"class":69},[59,854,584],{"class":190},[59,856,857],{"class":174},"A-Za-z",[59,859,808],{"class":190},[59,861,862],{"class":108},"{1,3}",[59,864,865],{"class":190},"\\d",[59,867,868],{"class":108},"+",[59,870,283],{"class":69},[59,872,873],{"class":112},", new):\n",[59,875,876,879,882,884,886,888,890,893,896,898,901],{"class":61,"line":150},[59,877,878],{"class":108},"        raise",[59,880,881],{"class":190}," ValueError",[59,883,551],{"class":112},[59,885,554],{"class":108},[59,887,283],{"class":69},[59,889,175],{"class":174},[59,891,892],{"class":112},"new",[59,894,895],{"class":108},"!r",[59,897,181],{"class":174},[59,899,900],{"class":69}," is not a valid table name\"",[59,902,194],{"class":112},[59,904,905,908,910,913,915,917,919,922,924,927,929,932,935,938,940,943,945],{"class":61,"line":156},[59,906,907],{"class":112},"    taken ",[59,909,162],{"class":108},[59,911,912],{"class":112}," {t.lower() ",[59,914,529],{"class":108},[59,916,203],{"class":112},[59,918,206],{"class":108},[59,920,921],{"class":112}," wb.worksheets ",[59,923,529],{"class":108},[59,925,926],{"class":112}," t ",[59,928,206],{"class":108},[59,930,931],{"class":112}," ws.tables} ",[59,933,934],{"class":108},"|",[59,936,937],{"class":112}," {n.lower() ",[59,939,529],{"class":108},[59,941,942],{"class":112}," n ",[59,944,206],{"class":108},[59,946,947],{"class":112}," wb.defined_names}\n",[59,949,950,952,955,957,960,963],{"class":61,"line":197},[59,951,834],{"class":108},[59,953,954],{"class":112}," new.lower() ",[59,956,206],{"class":108},[59,958,959],{"class":112}," taken ",[59,961,962],{"class":108},"-",[59,964,965],{"class":112}," {old.lower()}:\n",[59,967,968,970,972,974,976,978,980,982,984,986,989],{"class":61,"line":212},[59,969,878],{"class":108},[59,971,881],{"class":190},[59,973,551],{"class":112},[59,975,554],{"class":108},[59,977,283],{"class":69},[59,979,175],{"class":174},[59,981,892],{"class":112},[59,983,895],{"class":108},[59,985,181],{"class":174},[59,987,988],{"class":69}," is already used by a table or defined name\"",[59,990,194],{"class":112},[59,992,993,996,998,1001,1004,1006,1008,1010,1012,1015,1018,1020],{"class":61,"line":226},[59,994,995],{"class":112},"    ws ",[59,997,162],{"class":108},[59,999,1000],{"class":190}," next",[59,1002,1003],{"class":112},"(ws ",[59,1005,529],{"class":108},[59,1007,203],{"class":112},[59,1009,206],{"class":108},[59,1011,921],{"class":112},[59,1013,1014],{"class":108},"if",[59,1016,1017],{"class":112}," old ",[59,1019,206],{"class":108},[59,1021,1022],{"class":112}," ws.tables)\n",[59,1024,1025,1028,1030],{"class":61,"line":240},[59,1026,1027],{"class":112},"    table ",[59,1029,162],{"class":108},[59,1031,1032],{"class":112}," ws.tables[old]\n",[59,1034,1035,1038,1040,1043,1045],{"class":61,"line":274},[59,1036,1037],{"class":112},"    table.name ",[59,1039,162],{"class":108},[59,1041,1042],{"class":112}," table.displayName ",[59,1044,162],{"class":108},[59,1046,1047],{"class":112}," new\n",[59,1049,1050,1053],{"class":61,"line":308},[59,1051,1052],{"class":108},"    del",[59,1054,1032],{"class":112},[59,1056,1057,1060,1062],{"class":61,"line":321},[59,1058,1059],{"class":112},"    ws.tables[new] ",[59,1061,162],{"class":108},[59,1063,1064],{"class":112}," table\n",[59,1066,1067],{"class":61,"line":335},[59,1068,134],{"emptyLinePlaceholder":133},[59,1070,1071,1073,1075,1077,1079,1081,1083,1086,1088,1091,1093,1095],{"class":61,"line":366},[59,1072,159],{"class":112},[59,1074,162],{"class":108},[59,1076,165],{"class":112},[59,1078,168],{"class":108},[59,1080,171],{"class":69},[59,1082,175],{"class":174},[59,1084,1085],{"class":112},"re.escape(old)",[59,1087,181],{"class":174},[59,1089,1090],{"class":69},"(?=\\[)\"",[59,1092,187],{"class":112},[59,1094,191],{"class":190},[59,1096,194],{"class":112},[59,1098,1099,1102,1104],{"class":61,"line":379},[59,1100,1101],{"class":112},"    count ",[59,1103,162],{"class":108},[59,1105,1106],{"class":190}," 0\n",[59,1108,1109,1112,1115],{"class":61,"line":392},[59,1110,1111],{"class":108},"    def",[59,1113,1114],{"class":143}," sub",[59,1116,1117],{"class":112},"(text):\n",[59,1119,1120,1123],{"class":61,"line":412},[59,1121,1122],{"class":108},"        nonlocal",[59,1124,1125],{"class":112}," count\n",[59,1127,1128,1131,1133],{"class":61,"line":421},[59,1129,1130],{"class":112},"        text, n ",[59,1132,162],{"class":108},[59,1134,1135],{"class":112}," rx.subn(new, text)\n",[59,1137,1138,1141,1144],{"class":61,"line":452},[59,1139,1140],{"class":112},"        count ",[59,1142,1143],{"class":108},"+=",[59,1145,1146],{"class":112}," n\n",[59,1148,1149,1152],{"class":61,"line":465},[59,1150,1151],{"class":108},"        return",[59,1153,1154],{"class":112}," text\n",[59,1156,1157,1159,1162,1164],{"class":61,"line":482},[59,1158,200],{"class":108},[59,1160,1161],{"class":112}," sheet ",[59,1163,206],{"class":108},[59,1165,209],{"class":112},[59,1167,1168,1170,1172,1174],{"class":61,"line":505},[59,1169,215],{"class":108},[59,1171,218],{"class":112},[59,1173,206],{"class":108},[59,1175,1176],{"class":112}," sheet.iter_rows():\n",[59,1178,1179,1181,1183,1185],{"class":61,"line":510},[59,1180,229],{"class":108},[59,1182,232],{"class":112},[59,1184,206],{"class":108},[59,1186,237],{"class":112},[59,1188,1189,1191,1193,1195,1197,1199,1201,1203,1205],{"class":61,"line":526},[59,1190,243],{"class":108},[59,1192,246],{"class":190},[59,1194,249],{"class":112},[59,1196,252],{"class":190},[59,1198,255],{"class":112},[59,1200,258],{"class":108},[59,1202,261],{"class":112},[59,1204,264],{"class":69},[59,1206,479],{"class":112},[59,1208,1209,1212,1214],{"class":61,"line":545},[59,1210,1211],{"class":112},"                    c.value ",[59,1213,162],{"class":108},[59,1215,1216],{"class":112}," sub(c.value)\n",[59,1218,1220,1222,1224,1226],{"class":61,"line":1219},27,[59,1221,215],{"class":108},[59,1223,313],{"class":112},[59,1225,206],{"class":108},[59,1227,1228],{"class":112}," sheet.data_validations.dataValidation:\n",[59,1230,1232,1234],{"class":61,"line":1231},28,[59,1233,324],{"class":108},[59,1235,1236],{"class":112}," dv.formula1:\n",[59,1238,1240,1243,1245],{"class":61,"line":1239},29,[59,1241,1242],{"class":112},"                dv.formula1 ",[59,1244,162],{"class":108},[59,1246,1247],{"class":112}," sub(dv.formula1)\n",[59,1249,1251,1253,1255,1257],{"class":61,"line":1250},30,[59,1252,215],{"class":108},[59,1254,371],{"class":112},[59,1256,206],{"class":108},[59,1258,1259],{"class":112}," sheet.conditional_formatting:\n",[59,1261,1263,1265,1267,1269],{"class":61,"line":1262},31,[59,1264,229],{"class":108},[59,1266,384],{"class":112},[59,1268,206],{"class":108},[59,1270,389],{"class":112},[59,1272,1274,1277,1279,1282,1284,1286,1288,1290,1292],{"class":61,"line":1273},32,[59,1275,1276],{"class":112},"                rule.formula ",[59,1278,162],{"class":108},[59,1280,1281],{"class":112}," [sub(f) ",[59,1283,529],{"class":108},[59,1285,398],{"class":112},[59,1287,206],{"class":108},[59,1289,403],{"class":112},[59,1291,406],{"class":108},[59,1293,1294],{"class":112}," []]\n",[59,1296,1298,1300,1303,1305],{"class":61,"line":1297},33,[59,1299,200],{"class":108},[59,1301,1302],{"class":112}," dn ",[59,1304,206],{"class":108},[59,1306,1307],{"class":112}," wb.defined_names.values():\n",[59,1309,1311,1314,1316,1319,1321,1323],{"class":61,"line":1310},34,[59,1312,1313],{"class":112},"        dn.attr_text ",[59,1315,162],{"class":108},[59,1317,1318],{"class":112}," sub(dn.attr_text ",[59,1320,406],{"class":108},[59,1322,476],{"class":69},[59,1324,194],{"class":112},[59,1326,1328,1331],{"class":61,"line":1327},35,[59,1329,1330],{"class":108},"    return",[59,1332,1125],{"class":112},[59,1334,1336],{"class":61,"line":1335},36,[59,1337,134],{"emptyLinePlaceholder":133},[59,1339,1341,1344,1346,1349,1352,1354,1356,1359,1362,1365],{"class":61,"line":1340},37,[59,1342,1343],{"class":190},"print",[59,1345,551],{"class":112},[59,1347,1348],{"class":69},"\"Table1 -> Orders:\"",[59,1350,1351],{"class":112},", rename_table(wb, ",[59,1353,540],{"class":69},[59,1355,17],{"class":112},[59,1357,1358],{"class":69},"\"Orders\"",[59,1360,1361],{"class":112},"), ",[59,1363,1364],{"class":69},"\"references updated\"",[59,1366,194],{"class":112},[59,1368,1370,1372,1374,1377,1379,1382,1384,1387,1389,1391],{"class":61,"line":1369},38,[59,1371,1343],{"class":190},[59,1373,551],{"class":112},[59,1375,1376],{"class":69},"\"Table2 -> Regions:\"",[59,1378,1351],{"class":112},[59,1380,1381],{"class":69},"\"Table2\"",[59,1383,17],{"class":112},[59,1385,1386],{"class":69},"\"Regions\"",[59,1388,1361],{"class":112},[59,1390,1364],{"class":69},[59,1392,194],{"class":112},[59,1394,1396,1399],{"class":61,"line":1395},39,[59,1397,1398],{"class":108},"try",[59,1400,1401],{"class":112},":\n",[59,1403,1405,1408,1410,1412,1415],{"class":61,"line":1404},40,[59,1406,1407],{"class":112},"    rename_table(wb, ",[59,1409,1358],{"class":69},[59,1411,17],{"class":112},[59,1413,1414],{"class":69},"\"OrderAmounts\"",[59,1416,194],{"class":112},[59,1418,1420,1423,1425,1428],{"class":61,"line":1419},41,[59,1421,1422],{"class":108},"except",[59,1424,881],{"class":190},[59,1426,1427],{"class":108}," as",[59,1429,1430],{"class":112}," e:\n",[59,1432,1434,1436,1438,1441],{"class":61,"line":1433},42,[59,1435,548],{"class":190},[59,1437,551],{"class":112},[59,1439,1440],{"class":69},"\"refused:\"",[59,1442,1443],{"class":112},", e)\n",[10,1445,1446,1447,1450,1451,1454,1455,1457,1458,1461],{},"The rename has three parts. The table object's ",[26,1448,1449],{},"name"," and ",[26,1452,1453],{},"displayName"," are both set — Excel uses the display name in formulas, and openpyxl writes both. The sheet's table list is keyed by name, so the entry is removed under the old key and added under the new one; otherwise openpyxl saves a table whose key and name disagree. Then the same pattern as before rewrites every reference, using a lookahead for the bracket so only the name itself is replaced. Before any of that, the new name is checked: it must be a valid name, must not look like a cell address, and must not already belong to another table ",[14,1456,406],{}," a defined name, because tables and defined names share one namespace in Excel. The last call shows the check working: ",[14,1459,1460],{},"OrderAmounts"," is already a defined name, so the rename is refused rather than producing a broken file.",[10,1463,1464,1465,1468],{},"One kind of reference is deliberately not touched: a table name inside a text string, such as the ",[26,1466,1467],{},"INDIRECT(\"Table2[Region]\")"," in the dropdown. Excel does not update those either when a table is renamed in its own interface, because to Excel they are text, not references. The pattern above does rewrite it, since the validation formula is searched as plain text — which here is what we want, but it is worth knowing that the rename goes one step further than Excel would.",[608,1470,617,1476,617,1479,617,1482,617,1486,617,1495,617,1501,617,1503,617,1508,617,1513,617,1518,617,1521,617,1526,617,1528,617,1531,617,1535,617,1538,617,1541,617,1546,617,1550,617,1554,617,1557,617,1562,617,1567,617,1570],{"viewBox":1471,"role":611,"ariaLabelledBy":1472,"xmlns":615,"style":1475},"4 0 752 108",[1473,1474],"rn-steps-t","rn-steps-d","width:100%;max-width:752px;height:auto;display:block;margin:1.5rem auto;font-family:Inter,ui-sans-serif,system-ui,sans-serif",[619,1477,1478],{"id":1473},"What rename_table does",[623,1480,1481],{"id":1474},"The new name is checked for validity and clashes with tables and defined names. The table's name and display name are set and it is re-keyed in the sheet's table list. Then every structured reference in cells, validation, conditional formats and defined names is rewritten.",[627,1483],{"x":724,"y":630,"width":1484,"height":1485,"fill":633},"752","108",[627,1487],{"x":1488,"y":637,"width":1489,"height":1490,"rx":1491,"fill":1492,"stroke":1493,"style":1494},"20.0","153.0","76.5","12","#fdefd8","var(--gold,#b4740a)","stroke-width:2px",[572,1496,1500],{"x":1497,"y":1498,"style":1499},"96.5","41.5","font-size:13.5px;font-weight:700;fill:var(--gold-ink,#7a4e06);text-anchor:middle","Check the new",[572,1502,1449],{"x":1497,"y":667,"style":1499},[572,1504,1507],{"x":1497,"y":1505,"style":1506},"78.5","font-size:11.5px;font-weight:400;fill:var(--text,#172033);text-anchor:middle","valid, no clash",[61,1509],{"x1":1510,"y1":1511,"x2":1512,"y2":1511,"stroke":672,"style":1494},"178.0","54.2","200.0",[1514,1515],"polygon",{"points":1516,"fill":1517},"204.0,54.2 195.0,59.2 195.0,49.2","#5b5cf0",[627,1519],{"x":1520,"y":637,"width":1489,"height":1490,"rx":1491,"fill":671,"stroke":672,"style":1494},"209.0",[572,1522,1525],{"x":1523,"y":1498,"style":1524},"285.5","font-size:13.5px;font-weight:700;fill:var(--brand-strong,#4338ca);text-anchor:middle","Set name and",[572,1527,1453],{"x":1523,"y":667,"style":1524},[572,1529,1530],{"x":1523,"y":1505,"style":1506},"on the table",[61,1532],{"x1":1533,"y1":1511,"x2":1534,"y2":1511,"stroke":672,"style":1494},"367.0","389.0",[1514,1536],{"points":1537,"fill":1517},"393.0,54.2 384.0,59.2 384.0,49.2",[627,1539],{"x":1540,"y":637,"width":1489,"height":1490,"rx":1491,"fill":671,"stroke":672,"style":1494},"398.0",[572,1542,1545],{"x":1543,"y":1544,"style":1524},"474.5","50.2","Re-key ws.tables",[572,1547,1549],{"x":1543,"y":1548,"style":1506},"69.8","old key out, new in",[61,1551],{"x1":1552,"y1":1511,"x2":1553,"y2":1511,"stroke":672,"style":1494},"556.0","578.0",[1514,1555],{"points":1556,"fill":1517},"582.0,54.2 573.0,59.2 573.0,49.2",[627,1558],{"x":1559,"y":637,"width":1489,"height":1490,"rx":1491,"fill":1560,"stroke":1561,"style":1494},"587.0","#d9f4f1","var(--teal,#0f9488)",[572,1563,1566],{"x":1564,"y":1498,"style":1565},"663.5","font-size:13.5px;font-weight:700;fill:var(--teal-ink,#0b6157);text-anchor:middle","Rewrite",[572,1568,1569],{"x":1564,"y":667,"style":1565},"references",[572,1571,1572],{"x":1564,"y":1505,"style":1506},"cells, rules, names",[45,1574,1576],{"id":1575},"step-3-one-style-for-every-table","Step 3 — One style for every table",[50,1578,1580],{"className":99,"code":1579,"language":101,"meta":55,"style":55},"from openpyxl.worksheet.table import TableStyleInfo\n\nfor ws in wb.worksheets:\n    for table in ws.tables.values():\n        table.tableStyleInfo = TableStyleInfo(name=\"TableStyleMedium2\", showRowStripes=True,\n                                              showFirstColumn=False, showLastColumn=False, showColumnStripes=False)\nwb.save(\"orders_renamed.xlsx\")\nprint({ws.title: {n: ws.tables[n].tableStyleInfo.name for n in ws.tables} for ws in wb.worksheets if ws.tables})\n",[26,1581,1582,1594,1598,1608,1620,1651,1681,1691],{"__ignoreMap":55},[59,1583,1584,1586,1589,1591],{"class":61,"line":62},[59,1585,119],{"class":108},[59,1587,1588],{"class":112}," openpyxl.worksheet.table ",[59,1590,109],{"class":108},[59,1592,1593],{"class":112}," TableStyleInfo\n",[59,1595,1596],{"class":61,"line":116},[59,1597,134],{"emptyLinePlaceholder":133},[59,1599,1600,1602,1604,1606],{"class":61,"line":130},[59,1601,529],{"class":108},[59,1603,203],{"class":112},[59,1605,206],{"class":108},[59,1607,209],{"class":112},[59,1609,1610,1612,1615,1617],{"class":61,"line":137},[59,1611,200],{"class":108},[59,1613,1614],{"class":112}," table ",[59,1616,206],{"class":108},[59,1618,1619],{"class":112}," ws.tables.values():\n",[59,1621,1622,1625,1627,1630,1633,1635,1638,1640,1643,1645,1648],{"class":61,"line":150},[59,1623,1624],{"class":112},"        table.tableStyleInfo ",[59,1626,162],{"class":108},[59,1628,1629],{"class":112}," TableStyleInfo(",[59,1631,1449],{"class":1632},"sa561",[59,1634,162],{"class":108},[59,1636,1637],{"class":69},"\"TableStyleMedium2\"",[59,1639,17],{"class":112},[59,1641,1642],{"class":1632},"showRowStripes",[59,1644,162],{"class":108},[59,1646,1647],{"class":190},"True",[59,1649,1650],{"class":112},",\n",[59,1652,1653,1656,1658,1661,1663,1666,1668,1670,1672,1675,1677,1679],{"class":61,"line":156},[59,1654,1655],{"class":1632},"                                              showFirstColumn",[59,1657,162],{"class":108},[59,1659,1660],{"class":190},"False",[59,1662,17],{"class":112},[59,1664,1665],{"class":1632},"showLastColumn",[59,1667,162],{"class":108},[59,1669,1660],{"class":190},[59,1671,17],{"class":112},[59,1673,1674],{"class":1632},"showColumnStripes",[59,1676,162],{"class":108},[59,1678,1660],{"class":190},[59,1680,194],{"class":112},[59,1682,1683,1686,1689],{"class":61,"line":197},[59,1684,1685],{"class":112},"wb.save(",[59,1687,1688],{"class":69},"\"orders_renamed.xlsx\"",[59,1690,194],{"class":112},[59,1692,1693,1695,1698,1700,1702,1704,1706,1708,1710,1712,1714,1716],{"class":61,"line":212},[59,1694,1343],{"class":190},[59,1696,1697],{"class":112},"({ws.title: {n: ws.tables[n].tableStyleInfo.name ",[59,1699,529],{"class":108},[59,1701,942],{"class":112},[59,1703,206],{"class":108},[59,1705,931],{"class":112},[59,1707,529],{"class":108},[59,1709,203],{"class":112},[59,1711,206],{"class":108},[59,1713,921],{"class":112},[59,1715,1014],{"class":108},[59,1717,1718],{"class":112}," ws.tables})\n",[10,1720,1721,1722,1725,1726,1729,1730,1733,1734,1737,1738,17,1741,17,1744,1747,1748,43],{},"The loop uses ",[26,1723,1724],{},"ws.tables.values()"," to get the table objects; note that openpyxl's ",[26,1727,1728],{},"ws.tables.items()"," is unusual and returns each table's ",[14,1731,1732],{},"range"," rather than the object, so it is the wrong tool here. Workbooks built by hand usually end up with a different table style on every sheet — whatever was the default when each table was made. Setting the same ",[26,1735,1736],{},"TableStyleInfo"," on every table gives the workbook one look. The style names are Excel's built-in ones (",[14,1739,1740],{},"TableStyleLight1–21",[14,1742,1743],{},"Medium1–28",[14,1745,1746],{},"Dark1–11","); choosing and customising them is covered in ",[39,1749,1751],{"href":1750},"\u002Fformatting-and-charting-excel-reports-with-python\u002Fcreating-excel-tables-and-autofilters-with-python\u002Fchoose-and-customise-excel-table-styles-with-python\u002F","Choose and Customise Excel Table Styles with Python",[45,1753,1755],{"id":1754},"step-4-prove-the-formulas-still-work","Step 4 — Prove the formulas still work",[50,1757,1759],{"className":52,"code":1758,"language":54,"meta":55,"style":55},"for f in orders orders_renamed; do\n  soffice --headless --convert-to 'csv:Text - txt - csv (StarCalc):44,34,76,1,,0,false,true,true,false,false,3' \"$f.xlsx\" > \u002Fdev\u002Fnull 2>&1\n  echo \"$f: $(head -4 \"$f-Summary.csv\" | tr '\\n' ' ')\"\ndone\npython -c \"\nfrom openpyxl import load_workbook\nwb = load_workbook('orders_renamed.xlsx'); s = wb['Summary']\nprint([s[c].value for c in ('B1', 'B2', 'B3', 'B4')]); print(wb.defined_names['OrderAmounts'].attr_text)\"\n",[26,1760,1761,1781,1813,1846,1851,1861,1866,1871],{"__ignoreMap":55},[59,1762,1763,1765,1767,1769,1772,1775,1778],{"class":61,"line":62},[59,1764,529],{"class":108},[59,1766,398],{"class":112},[59,1768,206],{"class":108},[59,1770,1771],{"class":69}," orders",[59,1773,1774],{"class":69}," orders_renamed",[59,1776,1777],{"class":112},"; ",[59,1779,1780],{"class":108},"do\n",[59,1782,1783,1786,1789,1792,1795,1798,1801,1804,1807,1810],{"class":61,"line":116},[59,1784,1785],{"class":65},"  soffice",[59,1787,1788],{"class":190}," --headless",[59,1790,1791],{"class":190}," --convert-to",[59,1793,1794],{"class":69}," 'csv:Text - txt - csv (StarCalc):44,34,76,1,,0,false,true,true,false,false,3'",[59,1796,1797],{"class":69}," \"",[59,1799,1800],{"class":112},"$f",[59,1802,1803],{"class":69},".xlsx\"",[59,1805,1806],{"class":108}," >",[59,1808,1809],{"class":69}," \u002Fdev\u002Fnull",[59,1811,1812],{"class":108}," 2>&1\n",[59,1814,1815,1818,1820,1822,1825,1828,1831,1833,1835,1838,1840,1843],{"class":61,"line":130},[59,1816,1817],{"class":190},"  echo",[59,1819,1797],{"class":69},[59,1821,1800],{"class":112},[59,1823,1824],{"class":69},": $(",[59,1826,1827],{"class":65},"head",[59,1829,1830],{"class":190}," -4",[59,1832,1797],{"class":69},[59,1834,1800],{"class":112},[59,1836,1837],{"class":69},"-Summary.csv\" ",[59,1839,934],{"class":108},[59,1841,1842],{"class":65}," tr",[59,1844,1845],{"class":69}," '\\n' ' ')\"\n",[59,1847,1848],{"class":61,"line":137},[59,1849,1850],{"class":108},"done\n",[59,1852,1853,1855,1858],{"class":61,"line":150},[59,1854,101],{"class":65},[59,1856,1857],{"class":190}," -c",[59,1859,1860],{"class":69}," \"\n",[59,1862,1863],{"class":61,"line":156},[59,1864,1865],{"class":69},"from openpyxl import load_workbook\n",[59,1867,1868],{"class":61,"line":197},[59,1869,1870],{"class":69},"wb = load_workbook('orders_renamed.xlsx'); s = wb['Summary']\n",[59,1872,1873],{"class":61,"line":212},[59,1874,1875],{"class":69},"print([s[c].value for c in ('B1', 'B2', 'B3', 'B4')]); print(wb.defined_names['OrderAmounts'].attr_text)\"\n",[10,1877,1878,1879,1881,1882,1450,1885,1888,1889,43],{},"The check recalculates the ",[14,1880,91],{}," sheet of the original and the renamed workbook in LibreOffice and prints both. The totals are identical — 3,480 in total, 1,630 for North, three regions and a largest order of 1,200 — which shows that every formula still finds its table under the new name. The formulas themselves now read ",[26,1883,1884],{},"=SUM(Orders[Amount])",[26,1886,1887],{},"=ROWS(Regions[Region])",", and the defined name points at ",[26,1890,1891],{},"Orders[Amount]",[608,1893,617,1898,617,1901,617,1904,617,1907,617,1912,617,1918,617,1923,617,1926,617,1930,617,1934,617,1936,617,1941,617,1945,617,1947,617,1949,617,1952],{"viewBox":1894,"role":611,"ariaLabelledBy":1895,"xmlns":615,"style":1475},"4 0 752 199",[1896,1897],"rn-before-after-t","rn-before-after-d",[619,1899,1900],{"id":1896},"Before and after the rename",[623,1902,1903],{"id":1897},"Before, formulas refer to Table1 and Table2 and the tables use two different styles. After, the same formulas refer to Orders and Regions, every table uses one style, and the calculated results are unchanged.",[627,1905],{"x":724,"y":630,"width":1484,"height":1906,"fill":633},"199",[627,1908],{"x":1488,"y":637,"width":1909,"height":1910,"rx":1911,"fill":640,"stroke":641,"style":1494},"351.0","167.0","14",[572,1913,1917],{"x":1914,"y":1915,"style":1916},"195.5","44.0","font-size:14px;font-weight:700;fill:var(--text,#172033);text-anchor:middle","Before",[61,1919],{"x1":1920,"y1":1921,"x2":1922,"y2":1921,"stroke":641,"style":642},"36.0","57.0","355.0",[572,1924,700],{"x":1914,"y":1925,"style":694},"77.0",[572,1927,1929],{"x":1914,"y":1928,"style":694},"103.0","=ROWS(Table2[Region])",[572,1931,1933],{"x":1914,"y":1932,"style":694},"129.0","two different table styles",[627,1935],{"x":1534,"y":637,"width":1909,"height":1910,"rx":1911,"fill":1560,"stroke":1561,"style":1494},[572,1937,1940],{"x":1938,"y":1915,"style":1939},"564.5","font-size:14px;font-weight:700;fill:var(--teal-ink,#0b6157);text-anchor:middle","After",[61,1942],{"x1":1943,"y1":1921,"x2":1944,"y2":1921,"stroke":1561,"style":642},"405.0","724.0",[572,1946,1884],{"x":1938,"y":1925,"style":694},[572,1948,1887],{"x":1938,"y":1928,"style":694},[572,1950,1951],{"x":1938,"y":1932,"style":694},"one style everywhere",[572,1953,1955],{"x":1938,"y":1954,"style":694},"155.0","same results: 3,480 and 3",[45,1957,1959],{"id":1958},"what-this-does-not-update","What this does not update",[10,1961,1962,1963,1967],{},"The rename covers everything stored as a formula inside the workbook. It cannot reach references held elsewhere: Power Query queries and pivot table caches in the same file that read a table by name, other workbooks that link to this one, VBA code, and pandas or Power BI scripts that load the table by name. openpyxl keeps pivot tables and queries only partially in any case, as described in ",[39,1964,1966],{"href":1965},"\u002Fgetting-started-with-python-excel-automation\u002Fusing-openpyxl-for-excel-file-manipulation\u002Fwhat-openpyxl-loses-when-saving-an-existing-workbook\u002F","What openpyxl Loses When You Save an Existing Workbook",", so a workbook with pivots or queries is better renamed in Excel itself. For plain data workbooks, renaming in code and checking by recalculation is safe and quick.",[45,1969,1971],{"id":1970},"common-pitfalls","Common pitfalls",[1973,1974,1975,1989,2003,2009,2015],"ul",{},[1976,1977,1978,1984,1985,1988],"li",{},[1979,1980,1981,1982,43],"strong",{},"Changing only ",[26,1983,1453],{}," Also re-key ",[26,1986,1987],{},"ws.tables",", or the sheet's entry keeps the old name.",[1976,1990,1991,1994,1995,1997,1998,2000,2001,43],{},[1979,1992,1993],{},"Plain find-and-replace."," Match the name followed by ",[26,1996,584],{},", or ",[26,1999,16],{}," will also hit ",[26,2002,601],{},[1976,2004,2005,2008],{},[1979,2006,2007],{},"Forgetting validation, formats and names."," Formulas live in all of them.",[1976,2010,2011,2014],{},[1979,2012,2013],{},"Names that clash with defined names."," Tables and names share one namespace.",[1976,2016,2017,2020],{},[1979,2018,2019],{},"No check afterwards."," Recalculate and compare results before and after.",[45,2022,2024],{"id":2023},"conclusion","Conclusion",[10,2026,2027,2028,1450,2030,2032,2033,2035,2036,2038,2039,2041],{},"To rename a table with openpyxl, validate the new name against both tables and defined names, set the table's ",[26,2029,1449],{},[26,2031,1453],{},", re-key it in ",[26,2034,1987],{},", and rewrite every structured reference — in cells, data validation, conditional formatting and defined names — with a pattern that matches the old name only when it is followed by ",[26,2037,584],{},". Apply one ",[26,2040,1736],{}," to every table for a consistent look, and recalculate the workbook before and after to prove nothing broke.",[45,2043,2045],{"id":2044},"frequently-asked-questions","Frequently asked questions",[10,2047,2048,2051,2052,1450,2055,2058,2059,2061],{},[1979,2049,2050],{},"How do I rename an Excel table with openpyxl?","\nSet ",[26,2053,2054],{},"table.name",[26,2056,2057],{},"table.displayName",", move it to the new key in ",[26,2060,1987],{},", and update all formulas that use the old name.",[10,2063,2064,2067],{},[1979,2065,2066],{},"Does openpyxl update formulas when a table is renamed?","\nNo; formulas are stored as text, so structured references must be rewritten with a search and replace.",[10,2069,2070,2073],{},[1979,2071,2072],{},"Can a table have the same name as a defined name?","\nNo; tables and defined names share one namespace, so the names must differ.",[10,2075,2076,2079,2080,2082,2083,2086,2087,43],{},[1979,2077,2078],{},"How do I apply the same style to every table in a workbook?","\nLoop over ",[26,2081,1724],{}," on every sheet and set ",[26,2084,2085],{},"tableStyleInfo"," to the same ",[26,2088,1736],{},[45,2090,2092],{"id":2091},"related","Related",[1973,2094,2095,2101,2108,2115],{},[1976,2096,2097,2098,2100],{},"Up one level: ",[39,2099,42],{"href":41}," — tables and filters.",[1976,2102,2103,2107],{},[39,2104,2106],{"href":2105},"\u002Fformatting-and-charting-excel-reports-with-python\u002Fcreating-excel-tables-and-autofilters-with-python\u002Fconvert-several-ranges-into-excel-tables-at-once\u002F","Convert Several Ranges into Excel Tables at Once"," — creating tables in bulk.",[1976,2109,2110,2114],{},[39,2111,2113],{"href":2112},"\u002Fformatting-and-charting-excel-reports-with-python\u002Fcreating-excel-tables-and-autofilters-with-python\u002Fadd-calculated-columns-to-an-excel-table-with-python\u002F","Add Calculated Columns to an Excel Table with Python"," — structured references in columns.",[1976,2116,2117,2121],{},[39,2118,2120],{"href":2119},"\u002Fformatting-and-charting-excel-reports-with-python\u002Fcreating-excel-tables-and-autofilters-with-python\u002Fread-an-excel-table-by-name-into-pandas\u002F","Read an Excel Table by Name into pandas"," — scripts that depend on table names.",[2123,2124,2125],"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 .s_b0D, html code.shiki .s_b0D{--shiki-default:#22863A;--shiki-default-font-weight:bold;--shiki-dark:#72F088;--shiki-dark-font-weight:bold}html pre.shiki code .sa561, html code.shiki .sa561{--shiki-default:#E36209;--shiki-dark:#FFB757}",{"title":55,"searchDepth":116,"depth":116,"links":2127},[2128,2129,2130,2131,2132,2133,2134,2135,2136,2137],{"id":47,"depth":116,"text":48},{"id":95,"depth":116,"text":96},{"id":770,"depth":116,"text":771},{"id":1575,"depth":116,"text":1576},{"id":1754,"depth":116,"text":1755},{"id":1958,"depth":116,"text":1959},{"id":1970,"depth":116,"text":1971},{"id":2023,"depth":116,"text":2024},{"id":2044,"depth":116,"text":2045},{"id":2091,"depth":116,"text":2092},"2026-10-02","Give the Table1, Table2 and Table3 in an existing workbook meaningful names with openpyxl without breaking anything: rename the table object and its key, rewrite every structured reference to it in cell formulas, defined names, data validation and conditional formatting, refuse names that clash, then apply one table style across the workbook — checked by recalculating the formulas in LibreOffice before and after.","md",[2142,2144,2146,2148],{"q":2050,"a":2143},"Set table.name and table.displayName, move it to the new key in ws.tables, and update all formulas that use the old name.",{"q":2066,"a":2145},"No; formulas are stored as text, so structured references must be rewritten with a search and replace.",{"q":2072,"a":2147},"No; tables and defined names share one namespace, so the names must differ.",{"q":2078,"a":2149},"Loop over ws.tables.values() on every sheet and set tableStyleInfo to the same TableStyleInfo.","rename excel table openpyxl",null,{"breadcrumb":2153},[2154,2157,2160],{"name":2155,"item":2156},"Home","\u002F",{"name":2158,"item":2159},"Formatting and Charting Excel Reports with Python","\u002Fformatting-and-charting-excel-reports-with-python\u002F",{"name":42,"item":41},"\u002Fformatting-and-charting-excel-reports-with-python\u002Fcreating-excel-tables-and-autofilters-with-python\u002Frename-and-restyle-existing-excel-tables",{"title":2163,"description":2164},"Rename and Restyle Existing Excel Tables with Python","Rename Excel tables with openpyxl and update structured references in formulas, defined names, validation and conditional formatting; check for clashes, restyle all tables and verify by recalculation.","rename-and-restyle-existing-excel-tables","formatting-and-charting-excel-reports-with-python\u002Fcreating-excel-tables-and-autofilters-with-python\u002Frename-and-restyle-existing-excel-tables\u002Findex",[2168,2169],"tables-and-filters","openpyxl","how-to","OWCYcVMeixSQYZfgONXE7uv3M_N-MNaJJherf3jCX5g",[2173,2176],{"title":2120,"path":2174,"stem":2175,"children":-1},"\u002Fformatting-and-charting-excel-reports-with-python\u002Fcreating-excel-tables-and-autofilters-with-python\u002Fread-an-excel-table-by-name-into-pandas","formatting-and-charting-excel-reports-with-python\u002Fcreating-excel-tables-and-autofilters-with-python\u002Fread-an-excel-table-by-name-into-pandas\u002Findex",{"title":2177,"path":2178,"stem":2179,"children":-1},"Sort Excel Rows with Python Before Writing","\u002Fformatting-and-charting-excel-reports-with-python\u002Fcreating-excel-tables-and-autofilters-with-python\u002Fsort-excel-rows-with-python-before-writing","formatting-and-charting-excel-reports-with-python\u002Fcreating-excel-tables-and-autofilters-with-python\u002Fsort-excel-rows-with-python-before-writing\u002Findex",[2181,2183],{"path":2182,"title":42},"\u002Fformatting-and-charting-excel-reports-with-python\u002Fcreating-excel-tables-and-autofilters-with-python",{"path":2184,"title":2158},"\u002Fformatting-and-charting-excel-reports-with-python",[],[2187,2190,2193,2196,2199,2202],{"path":2188,"title":2189,"kind":2170},"\u002Fadvanced-data-transformation-and-cleaning\u002Fapplying-conditional-formatting-with-openpyxl\u002Fapply-conditional-formatting-to-an-excel-table-that-grows","Apply Conditional Formatting to an Excel Table That Grows",{"path":2191,"title":2192,"kind":2170},"\u002Fautomating-reporting-workflows\u002Fautomating-excel-online-with-microsoft-graph\u002Fsort-and-filter-an-excel-online-table-with-microsoft-graph","Sort and Filter an Excel Online Table with Microsoft Graph",{"path":2194,"title":2195,"kind":2170},"\u002Fformatting-and-charting-excel-reports-with-python\u002Fbuilding-excel-reports-with-xlsxwriter\u002Fwrite-an-excel-table-with-formula-columns-using-xlsxwriter","Write an Excel Table with Formula Columns Using XlsxWriter",{"path":2197,"title":2198,"kind":2170},"\u002Fformatting-and-charting-excel-reports-with-python\u002Fcreating-charts-in-excel-with-openpyxl\u002Fmake-an-excel-chart-grow-with-its-data","Make an Excel Chart Grow with Its Data",{"path":2200,"title":2201,"kind":2170},"\u002Fformatting-and-charting-excel-reports-with-python\u002Fcreating-excel-tables-and-autofilters-with-python\u002Fadd-a-total-row-to-an-excel-table","Add a Total Row to an Excel Table with Python",{"path":2203,"title":2204,"kind":2170},"\u002Fformatting-and-charting-excel-reports-with-python\u002Fcreating-excel-tables-and-autofilters-with-python\u002Fadd-an-autofilter-to-an-excel-sheet-with-openpyxl","Add an Autofilter to an Excel Sheet with openpyxl",1790972116537]