[{"data":1,"prerenderedAt":2238},["ShallowReactive",2],{"doc:\u002Fgetting-started-with-python-excel-automation\u002Fusing-openpyxl-for-excel-file-manipulation\u002Fclear-cell-contents-and-formatting-with-openpyxl":3,"surround:\u002Fgetting-started-with-python-excel-automation\u002Fusing-openpyxl-for-excel-file-manipulation\u002Fclear-cell-contents-and-formatting-with-openpyxl":2205,"ancestors:\u002Fgetting-started-with-python-excel-automation\u002Fusing-openpyxl-for-excel-file-manipulation\u002Fclear-cell-contents-and-formatting-with-openpyxl":2213,"children:\u002Fgetting-started-with-python-excel-automation\u002Fusing-openpyxl-for-excel-file-manipulation\u002Fclear-cell-contents-and-formatting-with-openpyxl":2217,"related:\u002Fgetting-started-with-python-excel-automation\u002Fusing-openpyxl-for-excel-file-manipulation\u002Fclear-cell-contents-and-formatting-with-openpyxl":2218},{"id":4,"title":5,"body":6,"dateModified":2171,"datePublished":2171,"description":2172,"extension":2173,"faq":2174,"keyword":2183,"kind":2184,"meta":2185,"navigation":335,"path":2194,"seo":2195,"slug":2198,"stem":2199,"topics":2200,"type":2203,"__hash__":2204},"docs\u002Fgetting-started-with-python-excel-automation\u002Fusing-openpyxl-for-excel-file-manipulation\u002Fclear-cell-contents-and-formatting-with-openpyxl\u002Findex.md","Clear Cell Contents and Formatting with openpyxl",{"type":7,"value":8,"toc":2156},"minimark",[9,24,253,258,283,294,422,426,433,506,512,516,519,560,577,581,584,631,642,646,656,765,768,952,964,1159,1163,1166,1383,1402,1405,1695,1698,1702,1709,1820,1832,1998,2002,2010,2014,2060,2064,2067,2071,2092,2096,2102,2108,2114,2120,2124,2153],[10,11,12,13,17,18,23],"p",{},"Excel's Home → Clear menu offers five choices — Clear All, Clear Formats, Clear Contents, Clear Comments and Notes, Clear Hyperlinks — because \"clear this range\" means different things in different situations. A script that refills a weekly template wants to wipe last week's numbers but keep the yellow input cells and the formulas; a script tidying an export wants the opposite. openpyxl has no single ",[14,15,16],"code",{},"clear()"," method, but each of Excel's options maps onto one or two attribute assignments. This page, part of ",[19,20,22],"a",{"href":21},"\u002Fgetting-started-with-python-excel-automation\u002Fusing-openpyxl-for-excel-file-manipulation\u002F","Using openpyxl for Excel File Manipulation",", shows each one, then builds a helper for the template case and explains the merged-cell trap.",[25,26,34,35,34,39,34,43,34,51,34,59,34,66,34,73,34,76,34,80,34,83,34,87,34,90,34,94,34,97,34,101,34,106,34,112,34,114,34,119,34,121,34,124,34,126,34,129,34,131,34,133,34,135,34,137,34,140,34,144,34,146,34,150,34,152,34,154,34,156,34,158,34,160,34,162,34,164,34,166,34,169,34,173,34,175,34,179,34,181,34,183,34,185,34,187,34,189,34,191,34,193,34,195,34,198,34,202,34,204,34,208,34,210,34,212,34,214,34,216,34,218,34,220,34,222,34,224,34,227,34,231,34,233,34,237,34,239,34,241,34,243,34,245,34,247,34,249,34,251],"svg",{"viewBox":27,"role":28,"ariaLabelledBy":29,"xmlns":32,"style":33},"4 0 752 242","img",[30,31],"clr-menu-t","clr-menu-d","http:\u002F\u002Fwww.w3.org\u002F2000\u002Fsvg","width:100%;max-width:752px;height:auto;display:block;margin:1.5rem auto;font-family:Inter,ui-sans-serif,system-ui,sans-serif","\n  ",[36,37,38],"title",{"id":30},"Excel's Clear options and their openpyxl equivalents",[40,41,42],"desc",{"id":31},"A table mapping each Clear option to openpyxl. Clear Contents is cell.value = None and keeps formats, comments and links. Clear Formats is cell.style = \"Normal\" and keeps values, comments and links. Clear Comments is cell.comment = None. Clear Hyperlinks is cell.hyperlink = None. Clear All combines all four.",[44,45],"rect",{"x":46,"y":47,"width":48,"height":49,"fill":50},"4","0","752","242","#ffffff",[44,52],{"x":53,"y":54,"width":55,"height":56,"rx":47,"fill":50,"stroke":57,"style":58},"20.0","16.0","135.0","40.0","var(--line,#cdd5e6)","stroke-width:1px",[44,60],{"x":61,"y":54,"width":62,"height":56,"rx":47,"fill":63,"stroke":64,"style":65},"155.0","117.0","#f0f4ff","var(--brand,#5b5cf0)","stroke-width:1.2px",[67,68,72],"text",{"x":69,"y":70,"style":71},"213.5","41.0","font-size:13px;font-weight:700;fill:var(--brand-strong,#4338ca);text-anchor:middle","openpyxl",[44,74],{"x":75,"y":54,"width":62,"height":56,"rx":47,"fill":63,"stroke":64,"style":65},"272.0",[67,77,79],{"x":78,"y":70,"style":71},"330.5","Value",[44,81],{"x":82,"y":54,"width":62,"height":56,"rx":47,"fill":63,"stroke":64,"style":65},"389.0",[67,84,86],{"x":85,"y":70,"style":71},"447.5","Formatting",[44,88],{"x":89,"y":54,"width":62,"height":56,"rx":47,"fill":63,"stroke":64,"style":65},"506.0",[67,91,93],{"x":92,"y":70,"style":71},"564.5","Comment",[44,95],{"x":96,"y":54,"width":62,"height":56,"rx":47,"fill":63,"stroke":64,"style":65},"623.0",[67,98,100],{"x":99,"y":70,"style":71},"681.5","Link",[44,102],{"x":53,"y":103,"width":55,"height":104,"rx":47,"fill":105,"stroke":57,"style":58},"56.0","34.0","#e7ebef",[67,107,111],{"x":108,"y":109,"style":110},"32.0","78.0","font-size:12.5px;font-weight:700;fill:var(--text,#172033);text-anchor:start","Clear Contents",[44,113],{"x":61,"y":103,"width":62,"height":104,"rx":47,"fill":50,"stroke":57,"style":58},[67,115,118],{"x":69,"y":116,"style":117},"77.0","font-size:11.5px;font-weight:400;fill:var(--text,#172033);text-anchor:middle","value = None",[44,120],{"x":75,"y":103,"width":62,"height":104,"rx":47,"fill":50,"stroke":57,"style":58},[67,122,123],{"x":78,"y":116,"style":117},"cleared",[44,125],{"x":82,"y":103,"width":62,"height":104,"rx":47,"fill":50,"stroke":57,"style":58},[67,127,128],{"x":85,"y":116,"style":117},"kept",[44,130],{"x":89,"y":103,"width":62,"height":104,"rx":47,"fill":50,"stroke":57,"style":58},[67,132,128],{"x":92,"y":116,"style":117},[44,134],{"x":96,"y":103,"width":62,"height":104,"rx":47,"fill":50,"stroke":57,"style":58},[67,136,128],{"x":99,"y":116,"style":117},[44,138],{"x":53,"y":139,"width":55,"height":104,"rx":47,"fill":105,"stroke":57,"style":58},"90.0",[67,141,143],{"x":108,"y":142,"style":110},"112.0","Clear Formats",[44,145],{"x":61,"y":139,"width":62,"height":104,"rx":47,"fill":50,"stroke":57,"style":58},[67,147,149],{"x":69,"y":148,"style":117},"111.0","style = \"Normal\"",[44,151],{"x":75,"y":139,"width":62,"height":104,"rx":47,"fill":50,"stroke":57,"style":58},[67,153,128],{"x":78,"y":148,"style":117},[44,155],{"x":82,"y":139,"width":62,"height":104,"rx":47,"fill":50,"stroke":57,"style":58},[67,157,123],{"x":85,"y":148,"style":117},[44,159],{"x":89,"y":139,"width":62,"height":104,"rx":47,"fill":50,"stroke":57,"style":58},[67,161,128],{"x":92,"y":148,"style":117},[44,163],{"x":96,"y":139,"width":62,"height":104,"rx":47,"fill":50,"stroke":57,"style":58},[67,165,128],{"x":99,"y":148,"style":117},[44,167],{"x":53,"y":168,"width":55,"height":104,"rx":47,"fill":105,"stroke":57,"style":58},"124.0",[67,170,172],{"x":108,"y":171,"style":110},"146.0","Clear Comments",[44,174],{"x":61,"y":168,"width":62,"height":104,"rx":47,"fill":50,"stroke":57,"style":58},[67,176,178],{"x":69,"y":177,"style":117},"145.0","comment = None",[44,180],{"x":75,"y":168,"width":62,"height":104,"rx":47,"fill":50,"stroke":57,"style":58},[67,182,128],{"x":78,"y":177,"style":117},[44,184],{"x":82,"y":168,"width":62,"height":104,"rx":47,"fill":50,"stroke":57,"style":58},[67,186,128],{"x":85,"y":177,"style":117},[44,188],{"x":89,"y":168,"width":62,"height":104,"rx":47,"fill":50,"stroke":57,"style":58},[67,190,123],{"x":92,"y":177,"style":117},[44,192],{"x":96,"y":168,"width":62,"height":104,"rx":47,"fill":50,"stroke":57,"style":58},[67,194,128],{"x":99,"y":177,"style":117},[44,196],{"x":53,"y":197,"width":55,"height":104,"rx":47,"fill":105,"stroke":57,"style":58},"158.0",[67,199,201],{"x":108,"y":200,"style":110},"180.0","Clear Hyperlinks",[44,203],{"x":61,"y":197,"width":62,"height":104,"rx":47,"fill":50,"stroke":57,"style":58},[67,205,207],{"x":69,"y":206,"style":117},"179.0","hyperlink = None",[44,209],{"x":75,"y":197,"width":62,"height":104,"rx":47,"fill":50,"stroke":57,"style":58},[67,211,128],{"x":78,"y":206,"style":117},[44,213],{"x":82,"y":197,"width":62,"height":104,"rx":47,"fill":50,"stroke":57,"style":58},[67,215,128],{"x":85,"y":206,"style":117},[44,217],{"x":89,"y":197,"width":62,"height":104,"rx":47,"fill":50,"stroke":57,"style":58},[67,219,128],{"x":92,"y":206,"style":117},[44,221],{"x":96,"y":197,"width":62,"height":104,"rx":47,"fill":50,"stroke":57,"style":58},[67,223,123],{"x":99,"y":206,"style":117},[44,225],{"x":53,"y":226,"width":55,"height":104,"rx":47,"fill":105,"stroke":57,"style":58},"192.0",[67,228,230],{"x":108,"y":229,"style":110},"214.0","Clear All",[44,232],{"x":61,"y":226,"width":62,"height":104,"rx":47,"fill":50,"stroke":57,"style":58},[67,234,236],{"x":69,"y":235,"style":117},"213.0","all four",[44,238],{"x":75,"y":226,"width":62,"height":104,"rx":47,"fill":50,"stroke":57,"style":58},[67,240,123],{"x":78,"y":235,"style":117},[44,242],{"x":82,"y":226,"width":62,"height":104,"rx":47,"fill":50,"stroke":57,"style":58},[67,244,123],{"x":85,"y":235,"style":117},[44,246],{"x":89,"y":226,"width":62,"height":104,"rx":47,"fill":50,"stroke":57,"style":58},[67,248,123],{"x":92,"y":235,"style":117},[44,250],{"x":96,"y":226,"width":62,"height":104,"rx":47,"fill":50,"stroke":57,"style":58},[67,252,123],{"x":99,"y":235,"style":117},[254,255,257],"h2",{"id":256},"prerequisites","Prerequisites",[259,260,265],"pre",{"className":261,"code":262,"language":263,"meta":264,"style":264},"language-bash shiki shiki-themes github-light github-dark-high-contrast","pip install openpyxl\n","bash","",[14,266,267],{"__ignoreMap":264},[268,269,272,276,280],"span",{"class":270,"line":271},"line",1,[268,273,275],{"class":274},"sMTad","pip",[268,277,279],{"class":278},"srMev"," install",[268,281,282],{"class":278}," openpyxl\n",[10,284,285,286,289,290,293],{},"The examples use ",[14,287,288],{},"template.xlsx",": a merged title in A1:D1, a header row, three item rows with yellow input cells in B and C, ",[14,291,292],{},"=B*C"," formulas in column D, a comment on B3 and a hyperlink on A4.",[259,295,299],{"className":296,"code":297,"language":298,"meta":264,"style":264},"language-python shiki shiki-themes github-light github-dark-high-contrast","from openpyxl import load_workbook\nfrom openpyxl.cell.cell import MergedCell\n\ndef state(cell):\n    return {\"value\": cell.value, \"fill\": cell.fill.fgColor.rgb if cell.fill.fill_type else None,\n            \"comment\": cell.comment is not None, \"link\": cell.hyperlink is not None}\n","python",[14,300,301,317,330,337,350,387],{"__ignoreMap":264},[268,302,303,307,311,314],{"class":270,"line":271},[268,304,306],{"class":305},"s-kum","from",[268,308,310],{"class":309},"skGVy"," openpyxl ",[268,312,313],{"class":305},"import",[268,315,316],{"class":309}," load_workbook\n",[268,318,320,322,325,327],{"class":270,"line":319},2,[268,321,306],{"class":305},[268,323,324],{"class":309}," openpyxl.cell.cell ",[268,326,313],{"class":305},[268,328,329],{"class":309}," MergedCell\n",[268,331,333],{"class":270,"line":332},3,[268,334,336],{"emptyLinePlaceholder":335},true,"\n",[268,338,340,343,347],{"class":270,"line":339},4,[268,341,342],{"class":305},"def",[268,344,346],{"class":345},"s_Opv"," state",[268,348,349],{"class":309},"(cell):\n",[268,351,353,356,359,362,365,368,371,374,377,380,384],{"class":270,"line":352},5,[268,354,355],{"class":305},"    return",[268,357,358],{"class":309}," {",[268,360,361],{"class":278},"\"value\"",[268,363,364],{"class":309},": cell.value, ",[268,366,367],{"class":278},"\"fill\"",[268,369,370],{"class":309},": cell.fill.fgColor.rgb ",[268,372,373],{"class":305},"if",[268,375,376],{"class":309}," cell.fill.fill_type ",[268,378,379],{"class":305},"else",[268,381,383],{"class":382},"sP0c6"," None",[268,385,386],{"class":309},",\n",[268,388,390,393,396,399,402,404,407,410,413,415,417,419],{"class":270,"line":389},6,[268,391,392],{"class":278},"            \"comment\"",[268,394,395],{"class":309},": cell.comment ",[268,397,398],{"class":305},"is",[268,400,401],{"class":305}," not",[268,403,383],{"class":382},[268,405,406],{"class":309},", ",[268,408,409],{"class":278},"\"link\"",[268,411,412],{"class":309},": cell.hyperlink ",[268,414,398],{"class":305},[268,416,401],{"class":305},[268,418,383],{"class":382},[268,420,421],{"class":309},"}\n",[254,423,425],{"id":424},"step-1-clear-contents-keep-formatting","Step 1 — Clear contents, keep formatting",[10,427,428,429,432],{},"Setting the value to ",[14,430,431],{},"None"," is Excel's Clear Contents. Everything else about the cell stays:",[259,434,436],{"className":296,"code":435,"language":298,"meta":264,"style":264},"wb = load_workbook(\"template.xlsx\")\nws = wb[\"Input\"]\nws[\"B3\"].value = None\nprint(state(ws[\"B3\"]))\n# {'value': None, 'fill': '00FFF2CC', 'comment': True, 'link': False}\n",[14,437,438,455,471,487,500],{"__ignoreMap":264},[268,439,440,443,446,449,452],{"class":270,"line":271},[268,441,442],{"class":309},"wb ",[268,444,445],{"class":305},"=",[268,447,448],{"class":309}," load_workbook(",[268,450,451],{"class":278},"\"template.xlsx\"",[268,453,454],{"class":309},")\n",[268,456,457,460,462,465,468],{"class":270,"line":319},[268,458,459],{"class":309},"ws ",[268,461,445],{"class":305},[268,463,464],{"class":309}," wb[",[268,466,467],{"class":278},"\"Input\"",[268,469,470],{"class":309},"]\n",[268,472,473,476,479,482,484],{"class":270,"line":332},[268,474,475],{"class":309},"ws[",[268,477,478],{"class":278},"\"B3\"",[268,480,481],{"class":309},"].value ",[268,483,445],{"class":305},[268,485,486],{"class":382}," None\n",[268,488,489,492,495,497],{"class":270,"line":339},[268,490,491],{"class":382},"print",[268,493,494],{"class":309},"(state(ws[",[268,496,478],{"class":278},[268,498,499],{"class":309},"]))\n",[268,501,502],{"class":270,"line":352},[268,503,505],{"class":504},"s-wDw","# {'value': None, 'fill': '00FFF2CC', 'comment': True, 'link': False}\n",[10,507,508,509,511],{},"The yellow fill and the comment survive. That is exactly the behaviour a template needs, and it is why ",[14,510,118],{}," is the right default for \"clear this range\".",[254,513,515],{"id":514},"step-2-clear-formatting-keep-values","Step 2 — Clear formatting, keep values",[10,517,518],{},"Assigning the built-in \"Normal\" named style resets every formatting attribute at once — font, fill, border, alignment, protection and number format — to the workbook's default:",[259,520,522],{"className":296,"code":521,"language":298,"meta":264,"style":264},"ws[\"C3\"].style = \"Normal\"\nprint(state(ws[\"C3\"]), ws[\"C3\"].has_style)\n# {'value': 3.5, 'fill': None, 'comment': False, 'link': False} False\n",[14,523,524,539,555],{"__ignoreMap":264},[268,525,526,528,531,534,536],{"class":270,"line":271},[268,527,475],{"class":309},[268,529,530],{"class":278},"\"C3\"",[268,532,533],{"class":309},"].style ",[268,535,445],{"class":305},[268,537,538],{"class":278}," \"Normal\"\n",[268,540,541,543,545,547,550,552],{"class":270,"line":319},[268,542,491],{"class":382},[268,544,494],{"class":309},[268,546,530],{"class":278},[268,548,549],{"class":309},"]), ws[",[268,551,530],{"class":278},[268,553,554],{"class":309},"].has_style)\n",[268,556,557],{"class":270,"line":332},[268,558,559],{"class":504},"# {'value': 3.5, 'fill': None, 'comment': False, 'link': False} False\n",[10,561,562,565,566,569,570,406,573,576],{},[14,563,564],{},"has_style"," becoming ",[14,567,568],{},"False"," means the cell now carries no formatting of its own. Resetting attributes one by one (",[14,571,572],{},"cell.font = Font()",[14,574,575],{},"cell.fill = PatternFill()",", and so on) also works but is easy to leave incomplete — a forgotten border or number format survives. The named style is one assignment and cannot miss anything.",[254,578,580],{"id":579},"step-3-remove-comments-and-hyperlinks","Step 3 — Remove comments and hyperlinks",[10,582,583],{},"Comments and hyperlinks are not formatting, so neither of the steps above touches them. Clear them explicitly:",[259,585,587],{"className":296,"code":586,"language":298,"meta":264,"style":264},"ws[\"B3\"].comment = None\nws[\"A4\"].hyperlink = None\nprint(state(ws[\"B3\"]), state(ws[\"A4\"]))\n",[14,588,589,602,616],{"__ignoreMap":264},[268,590,591,593,595,598,600],{"class":270,"line":271},[268,592,475],{"class":309},[268,594,478],{"class":278},[268,596,597],{"class":309},"].comment ",[268,599,445],{"class":305},[268,601,486],{"class":382},[268,603,604,606,609,612,614],{"class":270,"line":319},[268,605,475],{"class":309},[268,607,608],{"class":278},"\"A4\"",[268,610,611],{"class":309},"].hyperlink ",[268,613,445],{"class":305},[268,615,486],{"class":382},[268,617,618,620,622,624,627,629],{"class":270,"line":332},[268,619,491],{"class":382},[268,621,494],{"class":309},[268,623,478],{"class":278},[268,625,626],{"class":309},"]), state(ws[",[268,628,608],{"class":278},[268,630,499],{"class":309},[10,632,633,634,638,639,641],{},"When a hyperlink is removed this way, the cell keeps the hyperlink ",[635,636,637],"em",{},"style"," (blue, underlined) if one was applied. Follow it with ",[14,640,149],{}," when the cell should look like plain text again.",[254,643,645],{"id":644},"step-4-clear-a-range-skipping-merged-cells","Step 4 — Clear a range, skipping merged cells",[10,647,648,649,652,653,655],{},"Clearing a whole range means looping over it. The obvious loop fails as soon as the range includes a merged block, because covered cells are ",[14,650,651],{},"MergedCell"," objects that refuse any assignment, even ",[14,654,431],{},":",[259,657,659],{"className":296,"code":658,"language":298,"meta":264,"style":264},"wb = load_workbook(\"template.xlsx\")\nws = wb[\"Input\"]\ntry:\n    for row in ws[\"A1:D1\"]:\n        for cell in row:\n            cell.value = None\nexcept AttributeError as exc:\n    print(exc)\n# 'MergedCell' object attribute 'value' is read-only\n",[14,660,661,673,685,693,713,726,735,750,759],{"__ignoreMap":264},[268,662,663,665,667,669,671],{"class":270,"line":271},[268,664,442],{"class":309},[268,666,445],{"class":305},[268,668,448],{"class":309},[268,670,451],{"class":278},[268,672,454],{"class":309},[268,674,675,677,679,681,683],{"class":270,"line":319},[268,676,459],{"class":309},[268,678,445],{"class":305},[268,680,464],{"class":309},[268,682,467],{"class":278},[268,684,470],{"class":309},[268,686,687,690],{"class":270,"line":332},[268,688,689],{"class":305},"try",[268,691,692],{"class":309},":\n",[268,694,695,698,701,704,707,710],{"class":270,"line":339},[268,696,697],{"class":305},"    for",[268,699,700],{"class":309}," row ",[268,702,703],{"class":305},"in",[268,705,706],{"class":309}," ws[",[268,708,709],{"class":278},"\"A1:D1\"",[268,711,712],{"class":309},"]:\n",[268,714,715,718,721,723],{"class":270,"line":352},[268,716,717],{"class":305},"        for",[268,719,720],{"class":309}," cell ",[268,722,703],{"class":305},[268,724,725],{"class":309}," row:\n",[268,727,728,731,733],{"class":270,"line":389},[268,729,730],{"class":309},"            cell.value ",[268,732,445],{"class":305},[268,734,486],{"class":382},[268,736,738,741,744,747],{"class":270,"line":737},7,[268,739,740],{"class":305},"except",[268,742,743],{"class":382}," AttributeError",[268,745,746],{"class":305}," as",[268,748,749],{"class":309}," exc:\n",[268,751,753,756],{"class":270,"line":752},8,[268,754,755],{"class":382},"    print",[268,757,758],{"class":309},"(exc)\n",[268,760,762],{"class":270,"line":761},9,[268,763,764],{"class":504},"# 'MergedCell' object attribute 'value' is read-only\n",[10,766,767],{},"Skip placeholders; the merge's top-left cell holds the only value there is:",[259,769,771],{"className":296,"code":770,"language":298,"meta":264,"style":264},"def clear_range(ws, cell_range, contents=True, formats=False, comments=False, links=False):\n    for row in ws[cell_range]:\n        for cell in row:\n            if isinstance(cell, MergedCell):\n                continue\n            if contents:\n                cell.value = None\n            if comments:\n                cell.comment = None\n            if links:\n                cell.hyperlink = None\n            if formats:\n                cell.style = \"Normal\"\n\nclear_range(ws, \"A1:D1\")\nprint(ws[\"A1\"].value, ws.merged_cells.ranges)\n# None {\u003CMergedCellRange A1:D1>}\n",[14,772,773,812,823,833,844,849,856,865,872,881,889,899,907,917,922,932,946],{"__ignoreMap":264},[268,774,775,777,780,783,785,788,791,793,795,798,800,802,805,807,809],{"class":270,"line":271},[268,776,342],{"class":305},[268,778,779],{"class":345}," clear_range",[268,781,782],{"class":309},"(ws, cell_range, contents",[268,784,445],{"class":305},[268,786,787],{"class":382},"True",[268,789,790],{"class":309},", formats",[268,792,445],{"class":305},[268,794,568],{"class":382},[268,796,797],{"class":309},", comments",[268,799,445],{"class":305},[268,801,568],{"class":382},[268,803,804],{"class":309},", links",[268,806,445],{"class":305},[268,808,568],{"class":382},[268,810,811],{"class":309},"):\n",[268,813,814,816,818,820],{"class":270,"line":319},[268,815,697],{"class":305},[268,817,700],{"class":309},[268,819,703],{"class":305},[268,821,822],{"class":309}," ws[cell_range]:\n",[268,824,825,827,829,831],{"class":270,"line":332},[268,826,717],{"class":305},[268,828,720],{"class":309},[268,830,703],{"class":305},[268,832,725],{"class":309},[268,834,835,838,841],{"class":270,"line":339},[268,836,837],{"class":305},"            if",[268,839,840],{"class":382}," isinstance",[268,842,843],{"class":309},"(cell, MergedCell):\n",[268,845,846],{"class":270,"line":352},[268,847,848],{"class":305},"                continue\n",[268,850,851,853],{"class":270,"line":389},[268,852,837],{"class":305},[268,854,855],{"class":309}," contents:\n",[268,857,858,861,863],{"class":270,"line":737},[268,859,860],{"class":309},"                cell.value ",[268,862,445],{"class":305},[268,864,486],{"class":382},[268,866,867,869],{"class":270,"line":752},[268,868,837],{"class":305},[268,870,871],{"class":309}," comments:\n",[268,873,874,877,879],{"class":270,"line":761},[268,875,876],{"class":309},"                cell.comment ",[268,878,445],{"class":305},[268,880,486],{"class":382},[268,882,884,886],{"class":270,"line":883},10,[268,885,837],{"class":305},[268,887,888],{"class":309}," links:\n",[268,890,892,895,897],{"class":270,"line":891},11,[268,893,894],{"class":309},"                cell.hyperlink ",[268,896,445],{"class":305},[268,898,486],{"class":382},[268,900,902,904],{"class":270,"line":901},12,[268,903,837],{"class":305},[268,905,906],{"class":309}," formats:\n",[268,908,910,913,915],{"class":270,"line":909},13,[268,911,912],{"class":309},"                cell.style ",[268,914,445],{"class":305},[268,916,538],{"class":278},[268,918,920],{"class":270,"line":919},14,[268,921,336],{"emptyLinePlaceholder":335},[268,923,925,928,930],{"class":270,"line":924},15,[268,926,927],{"class":309},"clear_range(ws, ",[268,929,709],{"class":278},[268,931,454],{"class":309},[268,933,935,937,940,943],{"class":270,"line":934},16,[268,936,491],{"class":382},[268,938,939],{"class":309},"(ws[",[268,941,942],{"class":278},"\"A1\"",[268,944,945],{"class":309},"].value, ws.merged_cells.ranges)\n",[268,947,949],{"class":270,"line":948},17,[268,950,951],{"class":504},"# None {\u003CMergedCellRange A1:D1>}\n",[10,953,954,955,958,959,963],{},"The merge itself stays, which is usually right for a template. If the merged block should go too, call ",[14,956,957],{},"ws.unmerge_cells(\"A1:D1\")"," before clearing. ",[19,960,962],{"href":961},"\u002Fgetting-started-with-python-excel-automation\u002Ftroubleshooting-common-python-excel-errors\u002Ffix-mergedcell-value-is-read-only-in-openpyxl\u002F","Fix \"MergedCell object attribute value is read-only\" in openpyxl"," explains the placeholders in detail.",[25,965,34,971,34,974,34,977,34,982,34,988,34,993,34,997,34,1003,34,1007,34,1011,34,1015,34,1019,34,1023,34,1027,34,1031,34,1036,34,1038,34,1042,34,1044,34,1047,34,1049,34,1052,34,1054,34,1057,34,1060,34,1064,34,1066,34,1071,34,1073,34,1077,34,1081,34,1084,34,1087,34,1089,34,1091,34,1093,34,1095,34,1098,34,1101,34,1105,34,1107,34,1109,34,1111,34,1113,34,1116,34,1122,34,1127,34,1134,34,1145,34,1151,34,1155],{"viewBox":966,"role":28,"ariaLabelledBy":967,"xmlns":32,"style":970},"125 0 509 200",[968,969],"clr-template-t","clr-template-d","width:100%;max-width:509px;height:auto;display:block;margin:1.5rem auto;font-family:Inter,ui-sans-serif,system-ui,sans-serif",[36,972,973],{"id":968},"Clearing a template's inputs but keeping its formulas",[40,975,976],{"id":969},"The input sheet after clearing constants in A3:D5. The yellow input cells in columns B and C are empty but keep their fill, the item names in column A are cleared, and the total formulas in column D such as =B3*C3 are kept so the sheet is ready for next week's numbers.",[44,978],{"x":979,"y":47,"width":980,"height":981,"fill":50},"125","509","200",[67,983,987],{"x":984,"y":985,"style":986},"380.0","31.0","font-size:14px;font-weight:700;fill:var(--brand-strong,#4338ca);text-anchor:middle","After clear_inputs(ws, \"A3:D5\") — formulas survive",[44,989],{"x":990,"y":991,"width":108,"height":992,"rx":47,"fill":105,"stroke":57,"style":58},"141.6","48.0","24.0",[44,994],{"x":995,"y":991,"width":996,"height":992,"rx":47,"fill":105,"stroke":57,"style":58},"173.6","51.0",[67,998,1002],{"x":999,"y":1000,"style":1001},"199.1","65.0","font-size:11px;font-weight:600;fill:var(--muted,#5b6780);text-anchor:middle","A",[44,1004],{"x":1005,"y":991,"width":1006,"height":992,"rx":47,"fill":105,"stroke":57,"style":58},"224.6","44.1",[67,1008,1010],{"x":1009,"y":1000,"style":1001},"246.7","B",[44,1012],{"x":1013,"y":991,"width":1014,"height":992,"rx":47,"fill":105,"stroke":57,"style":58},"268.7","55.4",[67,1016,1018],{"x":1017,"y":1000,"style":1001},"296.4","C",[44,1020],{"x":1021,"y":991,"width":1022,"height":992,"rx":47,"fill":105,"stroke":57,"style":58},"324.1","74.3",[67,1024,1026],{"x":1025,"y":1000,"style":1001},"361.3","D",[44,1028],{"x":990,"y":1029,"width":108,"height":1030,"rx":47,"fill":105,"stroke":57,"style":58},"72.0","28.0",[67,1032,1035],{"x":1033,"y":1034,"style":1001},"157.6","91.0","2",[44,1037],{"x":995,"y":1029,"width":996,"height":1030,"rx":47,"fill":50,"stroke":57,"style":58},[67,1039,1041],{"x":999,"y":1034,"style":1040},"font-size:12px;font-weight:700;fill:var(--text,#172033);text-anchor:middle","item",[44,1043],{"x":1005,"y":1029,"width":1006,"height":1030,"rx":47,"fill":50,"stroke":57,"style":58},[67,1045,1046],{"x":1009,"y":1034,"style":1040},"qty",[44,1048],{"x":1013,"y":1029,"width":1014,"height":1030,"rx":47,"fill":50,"stroke":57,"style":58},[67,1050,1051],{"x":1017,"y":1034,"style":1040},"price",[44,1053],{"x":1021,"y":1029,"width":1022,"height":1030,"rx":47,"fill":50,"stroke":57,"style":58},[67,1055,1056],{"x":1025,"y":1034,"style":1040},"total",[44,1058],{"x":990,"y":1059,"width":108,"height":1030,"rx":47,"fill":105,"stroke":57,"style":58},"100.0",[67,1061,1063],{"x":1033,"y":1062,"style":1001},"119.0","3",[44,1065],{"x":995,"y":1059,"width":996,"height":1030,"rx":47,"fill":50,"stroke":57,"style":58},[44,1067],{"x":1005,"y":1059,"width":1006,"height":1030,"rx":47,"fill":1068,"stroke":1069,"style":1070},"#fdefd8","var(--gold,#b4740a)","stroke-width:1.5px",[44,1072],{"x":1013,"y":1059,"width":1014,"height":1030,"rx":47,"fill":1068,"stroke":1069,"style":1070},[44,1074],{"x":1021,"y":1059,"width":1022,"height":1030,"rx":47,"fill":1075,"stroke":1076,"style":1070},"#d9f4f1","var(--teal,#0f9488)",[67,1078,1080],{"x":1025,"y":1062,"style":1079},"font-size:12px;font-weight:700;fill:var(--teal-ink,#0b6157);text-anchor:middle","=B3*C3",[44,1082],{"x":990,"y":1083,"width":108,"height":1030,"rx":47,"fill":105,"stroke":57,"style":58},"128.0",[67,1085,46],{"x":1033,"y":1086,"style":1001},"147.0",[44,1088],{"x":995,"y":1083,"width":996,"height":1030,"rx":47,"fill":50,"stroke":57,"style":58},[44,1090],{"x":1005,"y":1083,"width":1006,"height":1030,"rx":47,"fill":1068,"stroke":1069,"style":1070},[44,1092],{"x":1013,"y":1083,"width":1014,"height":1030,"rx":47,"fill":1068,"stroke":1069,"style":1070},[44,1094],{"x":1021,"y":1083,"width":1022,"height":1030,"rx":47,"fill":1075,"stroke":1076,"style":1070},[67,1096,1097],{"x":1025,"y":1086,"style":1079},"=B4*C4",[44,1099],{"x":990,"y":1100,"width":108,"height":1030,"rx":47,"fill":105,"stroke":57,"style":58},"156.0",[67,1102,1104],{"x":1033,"y":1103,"style":1001},"175.0","5",[44,1106],{"x":995,"y":1100,"width":996,"height":1030,"rx":47,"fill":50,"stroke":57,"style":58},[44,1108],{"x":1005,"y":1100,"width":1006,"height":1030,"rx":47,"fill":1068,"stroke":1069,"style":1070},[44,1110],{"x":1013,"y":1100,"width":1014,"height":1030,"rx":47,"fill":1068,"stroke":1069,"style":1070},[44,1112],{"x":1021,"y":1100,"width":1022,"height":1030,"rx":47,"fill":1075,"stroke":1076,"style":1070},[67,1114,1115],{"x":1025,"y":1103,"style":1079},"=B5*C5",[270,1117],{"x1":1118,"y1":1119,"x2":1120,"y2":1119,"stroke":64,"style":1121},"406.4","116.0","438.4","stroke-width:2px",[1123,1124],"polygon",{"points":1125,"fill":1126},"442.4,116.0 433.4,121.0 433.4,111.0","#5b5cf0",[44,1128],{"x":1129,"y":1130,"width":1131,"height":1132,"rx":1133,"fill":1075,"stroke":1076,"style":1121},"448.4","60.8","170.0","110.5","12",[1135,1136,1138],"g",{"transform":1137},"translate(521.4,73.8) scale(1.000)",[1139,1140],"path",{"d":1141,"fill":1142,"stroke":1143,"style":1144},"M5 12.5l4.5 4.5L19 7","none","var(--teal-ink,#0b6157)","stroke-width:1.80px;stroke-linecap:round;stroke-linejoin:round",[67,1146,1150],{"x":1147,"y":1148,"style":1149},"533.4","120.2","font-size:13.5px;font-weight:700;fill:var(--teal-ink,#0b6157);text-anchor:middle","Constants cleared",[67,1152,1154],{"x":1147,"y":1153,"style":117},"139.8","fills kept on inputs",[67,1156,1158],{"x":1147,"y":1157,"style":117},"157.2","formulas left in place",[254,1160,1162],{"id":1161},"step-5-clear-a-templates-inputs-but-keep-its-formulas","Step 5 — Clear a template's inputs but keep its formulas",[10,1164,1165],{},"The most common real task is resetting a template for the next run: every typed number goes, every formula stays. Excel users do this with Go To Special → Constants; in openpyxl, check whether each value is a formula before clearing it:",[259,1167,1169],{"className":296,"code":1168,"language":298,"meta":264,"style":264},"def clear_inputs(ws, cell_range):\n    cleared = 0\n    for row in ws[cell_range]:\n        for cell in row:\n            if isinstance(cell, MergedCell) or cell.value is None:\n                continue\n            if isinstance(cell.value, str) and cell.value.startswith(\"=\"):\n                continue                     # keep formulas\n            cell.value = None\n            cleared += 1\n    return cleared\n\nwb = load_workbook(\"template.xlsx\")\nws = wb[\"Input\"]\nprint(clear_inputs(ws, \"A3:D5\"), \"cells cleared\")\nprint([[c.value for c in row] for row in ws[\"A3:D5\"]])\nwb.save(\"template_reset.xlsx\")\n",[14,1170,1171,1181,1191,1201,1211,1232,1236,1262,1270,1278,1289,1296,1300,1312,1324,1342,1373],{"__ignoreMap":264},[268,1172,1173,1175,1178],{"class":270,"line":271},[268,1174,342],{"class":305},[268,1176,1177],{"class":345}," clear_inputs",[268,1179,1180],{"class":309},"(ws, cell_range):\n",[268,1182,1183,1186,1188],{"class":270,"line":319},[268,1184,1185],{"class":309},"    cleared ",[268,1187,445],{"class":305},[268,1189,1190],{"class":382}," 0\n",[268,1192,1193,1195,1197,1199],{"class":270,"line":332},[268,1194,697],{"class":305},[268,1196,700],{"class":309},[268,1198,703],{"class":305},[268,1200,822],{"class":309},[268,1202,1203,1205,1207,1209],{"class":270,"line":339},[268,1204,717],{"class":305},[268,1206,720],{"class":309},[268,1208,703],{"class":305},[268,1210,725],{"class":309},[268,1212,1213,1215,1217,1220,1223,1226,1228,1230],{"class":270,"line":352},[268,1214,837],{"class":305},[268,1216,840],{"class":382},[268,1218,1219],{"class":309},"(cell, MergedCell) ",[268,1221,1222],{"class":305},"or",[268,1224,1225],{"class":309}," cell.value ",[268,1227,398],{"class":305},[268,1229,383],{"class":382},[268,1231,692],{"class":309},[268,1233,1234],{"class":270,"line":389},[268,1235,848],{"class":305},[268,1237,1238,1240,1242,1245,1248,1251,1254,1257,1260],{"class":270,"line":737},[268,1239,837],{"class":305},[268,1241,840],{"class":382},[268,1243,1244],{"class":309},"(cell.value, ",[268,1246,1247],{"class":382},"str",[268,1249,1250],{"class":309},") ",[268,1252,1253],{"class":305},"and",[268,1255,1256],{"class":309}," cell.value.startswith(",[268,1258,1259],{"class":278},"\"=\"",[268,1261,811],{"class":309},[268,1263,1264,1267],{"class":270,"line":752},[268,1265,1266],{"class":305},"                continue",[268,1268,1269],{"class":504},"                     # keep formulas\n",[268,1271,1272,1274,1276],{"class":270,"line":761},[268,1273,730],{"class":309},[268,1275,445],{"class":305},[268,1277,486],{"class":382},[268,1279,1280,1283,1286],{"class":270,"line":883},[268,1281,1282],{"class":309},"            cleared ",[268,1284,1285],{"class":305},"+=",[268,1287,1288],{"class":382}," 1\n",[268,1290,1291,1293],{"class":270,"line":891},[268,1292,355],{"class":305},[268,1294,1295],{"class":309}," cleared\n",[268,1297,1298],{"class":270,"line":901},[268,1299,336],{"emptyLinePlaceholder":335},[268,1301,1302,1304,1306,1308,1310],{"class":270,"line":909},[268,1303,442],{"class":309},[268,1305,445],{"class":305},[268,1307,448],{"class":309},[268,1309,451],{"class":278},[268,1311,454],{"class":309},[268,1313,1314,1316,1318,1320,1322],{"class":270,"line":919},[268,1315,459],{"class":309},[268,1317,445],{"class":305},[268,1319,464],{"class":309},[268,1321,467],{"class":278},[268,1323,470],{"class":309},[268,1325,1326,1328,1331,1334,1337,1340],{"class":270,"line":924},[268,1327,491],{"class":382},[268,1329,1330],{"class":309},"(clear_inputs(ws, ",[268,1332,1333],{"class":278},"\"A3:D5\"",[268,1335,1336],{"class":309},"), ",[268,1338,1339],{"class":278},"\"cells cleared\"",[268,1341,454],{"class":309},[268,1343,1344,1346,1349,1352,1355,1357,1360,1362,1364,1366,1368,1370],{"class":270,"line":934},[268,1345,491],{"class":382},[268,1347,1348],{"class":309},"([[c.value ",[268,1350,1351],{"class":305},"for",[268,1353,1354],{"class":309}," c ",[268,1356,703],{"class":305},[268,1358,1359],{"class":309}," row] ",[268,1361,1351],{"class":305},[268,1363,700],{"class":309},[268,1365,703],{"class":305},[268,1367,706],{"class":309},[268,1369,1333],{"class":278},[268,1371,1372],{"class":309},"]])\n",[268,1374,1375,1378,1381],{"class":270,"line":948},[268,1376,1377],{"class":309},"wb.save(",[268,1379,1380],{"class":278},"\"template_reset.xlsx\"",[268,1382,454],{"class":309},[10,1384,1385,1386,1388,1389,1392,1393,1396,1397,1401],{},"Nine constants go; the three ",[14,1387,292],{}," formulas remain, and the yellow fills stay on the input cells so the next person knows where to type. Load the workbook ",[635,1390,1391],{},"without"," ",[14,1394,1395],{},"data_only=True"," for this — with it, formulas are replaced by their cached results, the check cannot see them, and saving would destroy them. ",[19,1398,1400],{"href":1399},"\u002Fautomating-reporting-workflows\u002Fgenerating-excel-reports-from-templates\u002Ffill-excel-template-with-python-openpyxl\u002F","Fill an Excel Template with Python and openpyxl"," covers the filling half of the cycle.",[10,1403,1404],{},"Before overwriting last week's file, it is worth keeping a record of what was cleared. A template reset that runs on the wrong workbook — last month's final numbers instead of this week's scratch copy — is otherwise unrecoverable. Collect the old values as you clear them and write them somewhere safe:",[259,1406,1408],{"className":296,"code":1407,"language":298,"meta":264,"style":264},"import csv\n\ndef clear_inputs_logged(ws, cell_range, log_path):\n    rows = []\n    for row in ws[cell_range]:\n        for cell in row:\n            if isinstance(cell, MergedCell) or cell.value is None:\n                continue\n            if isinstance(cell.value, str) and cell.value.startswith(\"=\"):\n                continue\n            rows.append({\"sheet\": ws.title, \"cell\": cell.coordinate, \"old_value\": cell.value})\n            cell.value = None\n    with open(log_path, \"w\", newline=\"\", encoding=\"utf-8\") as fh:\n        writer = csv.DictWriter(fh, fieldnames=[\"sheet\", \"cell\", \"old_value\"])\n        writer.writeheader()\n        writer.writerows(rows)\n    return len(rows)\n\nwb = load_workbook(\"template.xlsx\")\nprint(clear_inputs_logged(wb[\"Input\"], \"A3:D5\", \"cleared_values.csv\"))\nprint(open(\"cleared_values.csv\").read().splitlines()[:3])\n",[14,1409,1410,1417,1421,1431,1441,1451,1461,1479,1483,1503,1507,1530,1538,1581,1612,1617,1622,1632,1637,1650,1673],{"__ignoreMap":264},[268,1411,1412,1414],{"class":270,"line":271},[268,1413,313],{"class":305},[268,1415,1416],{"class":309}," csv\n",[268,1418,1419],{"class":270,"line":319},[268,1420,336],{"emptyLinePlaceholder":335},[268,1422,1423,1425,1428],{"class":270,"line":332},[268,1424,342],{"class":305},[268,1426,1427],{"class":345}," clear_inputs_logged",[268,1429,1430],{"class":309},"(ws, cell_range, log_path):\n",[268,1432,1433,1436,1438],{"class":270,"line":339},[268,1434,1435],{"class":309},"    rows ",[268,1437,445],{"class":305},[268,1439,1440],{"class":309}," []\n",[268,1442,1443,1445,1447,1449],{"class":270,"line":352},[268,1444,697],{"class":305},[268,1446,700],{"class":309},[268,1448,703],{"class":305},[268,1450,822],{"class":309},[268,1452,1453,1455,1457,1459],{"class":270,"line":389},[268,1454,717],{"class":305},[268,1456,720],{"class":309},[268,1458,703],{"class":305},[268,1460,725],{"class":309},[268,1462,1463,1465,1467,1469,1471,1473,1475,1477],{"class":270,"line":737},[268,1464,837],{"class":305},[268,1466,840],{"class":382},[268,1468,1219],{"class":309},[268,1470,1222],{"class":305},[268,1472,1225],{"class":309},[268,1474,398],{"class":305},[268,1476,383],{"class":382},[268,1478,692],{"class":309},[268,1480,1481],{"class":270,"line":752},[268,1482,848],{"class":305},[268,1484,1485,1487,1489,1491,1493,1495,1497,1499,1501],{"class":270,"line":761},[268,1486,837],{"class":305},[268,1488,840],{"class":382},[268,1490,1244],{"class":309},[268,1492,1247],{"class":382},[268,1494,1250],{"class":309},[268,1496,1253],{"class":305},[268,1498,1256],{"class":309},[268,1500,1259],{"class":278},[268,1502,811],{"class":309},[268,1504,1505],{"class":270,"line":883},[268,1506,848],{"class":305},[268,1508,1509,1512,1515,1518,1521,1524,1527],{"class":270,"line":891},[268,1510,1511],{"class":309},"            rows.append({",[268,1513,1514],{"class":278},"\"sheet\"",[268,1516,1517],{"class":309},": ws.title, ",[268,1519,1520],{"class":278},"\"cell\"",[268,1522,1523],{"class":309},": cell.coordinate, ",[268,1525,1526],{"class":278},"\"old_value\"",[268,1528,1529],{"class":309},": cell.value})\n",[268,1531,1532,1534,1536],{"class":270,"line":901},[268,1533,730],{"class":309},[268,1535,445],{"class":305},[268,1537,486],{"class":382},[268,1539,1540,1543,1546,1549,1552,1554,1558,1560,1563,1565,1568,1570,1573,1575,1578],{"class":270,"line":909},[268,1541,1542],{"class":305},"    with",[268,1544,1545],{"class":382}," open",[268,1547,1548],{"class":309},"(log_path, ",[268,1550,1551],{"class":278},"\"w\"",[268,1553,406],{"class":309},[268,1555,1557],{"class":1556},"sa561","newline",[268,1559,445],{"class":305},[268,1561,1562],{"class":278},"\"\"",[268,1564,406],{"class":309},[268,1566,1567],{"class":1556},"encoding",[268,1569,445],{"class":305},[268,1571,1572],{"class":278},"\"utf-8\"",[268,1574,1250],{"class":309},[268,1576,1577],{"class":305},"as",[268,1579,1580],{"class":309}," fh:\n",[268,1582,1583,1586,1588,1591,1594,1596,1599,1601,1603,1605,1607,1609],{"class":270,"line":919},[268,1584,1585],{"class":309},"        writer ",[268,1587,445],{"class":305},[268,1589,1590],{"class":309}," csv.DictWriter(fh, ",[268,1592,1593],{"class":1556},"fieldnames",[268,1595,445],{"class":305},[268,1597,1598],{"class":309},"[",[268,1600,1514],{"class":278},[268,1602,406],{"class":309},[268,1604,1520],{"class":278},[268,1606,406],{"class":309},[268,1608,1526],{"class":278},[268,1610,1611],{"class":309},"])\n",[268,1613,1614],{"class":270,"line":924},[268,1615,1616],{"class":309},"        writer.writeheader()\n",[268,1618,1619],{"class":270,"line":934},[268,1620,1621],{"class":309},"        writer.writerows(rows)\n",[268,1623,1624,1626,1629],{"class":270,"line":948},[268,1625,355],{"class":305},[268,1627,1628],{"class":382}," len",[268,1630,1631],{"class":309},"(rows)\n",[268,1633,1635],{"class":270,"line":1634},18,[268,1636,336],{"emptyLinePlaceholder":335},[268,1638,1640,1642,1644,1646,1648],{"class":270,"line":1639},19,[268,1641,442],{"class":309},[268,1643,445],{"class":305},[268,1645,448],{"class":309},[268,1647,451],{"class":278},[268,1649,454],{"class":309},[268,1651,1653,1655,1658,1660,1663,1665,1667,1670],{"class":270,"line":1652},20,[268,1654,491],{"class":382},[268,1656,1657],{"class":309},"(clear_inputs_logged(wb[",[268,1659,467],{"class":278},[268,1661,1662],{"class":309},"], ",[268,1664,1333],{"class":278},[268,1666,406],{"class":309},[268,1668,1669],{"class":278},"\"cleared_values.csv\"",[268,1671,1672],{"class":309},"))\n",[268,1674,1676,1678,1681,1684,1686,1688,1691,1693],{"class":270,"line":1675},21,[268,1677,491],{"class":382},[268,1679,1680],{"class":309},"(",[268,1682,1683],{"class":382},"open",[268,1685,1680],{"class":309},[268,1687,1669],{"class":278},[268,1689,1690],{"class":309},").read().splitlines()[:",[268,1692,1063],{"class":382},[268,1694,1611],{"class":309},[10,1696,1697],{},"The CSV is enough to put any cell back by hand, and the count is a useful sanity check in the job log: a reset that suddenly clears 900 cells instead of 9 is pointing at the wrong range.",[254,1699,1701],{"id":1700},"step-6-shrink-the-used-range-after-clearing-everything","Step 6 — Shrink the used range after clearing everything",[10,1703,1704,1705,1708],{},"A cell with no value but a style is still a cell as far as the file is concerned, so clearing contents alone leaves ",[14,1706,1707],{},"max_row"," where it was. Clearing formats as well lets openpyxl drop the cells when it saves:",[259,1710,1712],{"className":296,"code":1711,"language":298,"meta":264,"style":264},"wb = load_workbook(\"template.xlsx\")\nws = wb[\"Input\"]\nprint(ws.max_row)\nclear_range(ws, \"A3:D5\", contents=True, formats=True, comments=True, links=True)\nwb.save(\"cleared.xlsx\")\nprint(load_workbook(\"cleared.xlsx\")[\"Input\"].max_row)\n# 2 — only the title and header rows remain\n",[14,1713,1714,1726,1738,1745,1789,1798,1815],{"__ignoreMap":264},[268,1715,1716,1718,1720,1722,1724],{"class":270,"line":271},[268,1717,442],{"class":309},[268,1719,445],{"class":305},[268,1721,448],{"class":309},[268,1723,451],{"class":278},[268,1725,454],{"class":309},[268,1727,1728,1730,1732,1734,1736],{"class":270,"line":319},[268,1729,459],{"class":309},[268,1731,445],{"class":305},[268,1733,464],{"class":309},[268,1735,467],{"class":278},[268,1737,470],{"class":309},[268,1739,1740,1742],{"class":270,"line":332},[268,1741,491],{"class":382},[268,1743,1744],{"class":309},"(ws.max_row)\n",[268,1746,1747,1749,1751,1753,1756,1758,1760,1762,1765,1767,1769,1771,1774,1776,1778,1780,1783,1785,1787],{"class":270,"line":339},[268,1748,927],{"class":309},[268,1750,1333],{"class":278},[268,1752,406],{"class":309},[268,1754,1755],{"class":1556},"contents",[268,1757,445],{"class":305},[268,1759,787],{"class":382},[268,1761,406],{"class":309},[268,1763,1764],{"class":1556},"formats",[268,1766,445],{"class":305},[268,1768,787],{"class":382},[268,1770,406],{"class":309},[268,1772,1773],{"class":1556},"comments",[268,1775,445],{"class":305},[268,1777,787],{"class":382},[268,1779,406],{"class":309},[268,1781,1782],{"class":1556},"links",[268,1784,445],{"class":305},[268,1786,787],{"class":382},[268,1788,454],{"class":309},[268,1790,1791,1793,1796],{"class":270,"line":352},[268,1792,1377],{"class":309},[268,1794,1795],{"class":278},"\"cleared.xlsx\"",[268,1797,454],{"class":309},[268,1799,1800,1802,1805,1807,1810,1812],{"class":270,"line":389},[268,1801,491],{"class":382},[268,1803,1804],{"class":309},"(load_workbook(",[268,1806,1795],{"class":278},[268,1808,1809],{"class":309},")[",[268,1811,467],{"class":278},[268,1813,1814],{"class":309},"].max_row)\n",[268,1816,1817],{"class":270,"line":737},[268,1818,1819],{"class":504},"# 2 — only the title and header rows remain\n",[10,1821,1822,1823,1826,1827,1831],{},"When whole rows are being emptied, ",[14,1824,1825],{},"ws.delete_rows(3, 3)"," does the same job in one call and also removes row heights, but it shifts everything below — fine at the bottom of a sheet, disruptive in the middle of a report. ",[19,1828,1830],{"href":1829},"\u002Fgetting-started-with-python-excel-automation\u002Ftroubleshooting-common-python-excel-errors\u002Ffix-openpyxl-max-row-counting-empty-rows\u002F","Fix openpyxl max_row Counting Empty Rows"," covers the used range in detail.",[25,1833,34,1838,34,1841,34,1844,34,1847,34,1852,34,1859,34,1863,34,1867,34,1871,34,1874,34,1877,34,1884,34,1889,34,1893,34,1899,34,1903,34,1907,34,1910,34,1913,34,1917,34,1920,34,1923,34,1929,34,1931,34,1933,34,1936,34,1939,34,1943,34,1946,34,1949,34,1956,34,1959,34,1961,34,1963,34,1966,34,1970,34,1973,34,1978,34,1985,34,1990,34,1994],{"viewBox":1834,"role":28,"ariaLabelledBy":1835,"xmlns":32,"style":33},"4 0 752 290",[1836,1837],"clr-choose-t","clr-choose-d",[36,1839,1840],{"id":1836},"Choosing how to clear",[40,1842,1843],{"id":1837},"A decision chart. To refill a template next run, clear constants only and keep formulas and formats. To remove old numbers but keep the look, set value to None. To strip styling from an export, set style to Normal. To remove the rows entirely, including heights, use delete_rows.",[44,1845],{"x":46,"y":47,"width":48,"height":1846,"fill":50},"290",[44,1848],{"x":1849,"y":54,"width":1850,"height":1851,"rx":1133,"fill":63,"stroke":64,"style":1121},"236.8","286.3","75.5",[1135,1853,1855],{"transform":1854},"translate(368.0,29.0) scale(1.000)",[1139,1856],{"d":1857,"fill":1142,"stroke":1858,"style":1144},"M11 4a7 7 0 1 0 .01 0z M16 16l5 5","var(--brand-strong,#4338ca)",[67,1860,1862],{"x":984,"y":1851,"style":1861},"font-size:13.5px;font-weight:700;fill:var(--brand-strong,#4338ca);text-anchor:middle","What should remain afterwards?",[270,1864],{"x1":984,"y1":1865,"x2":984,"y2":1866,"stroke":64,"style":1121},"91.5","111.5",[270,1868],{"x1":1869,"y1":1866,"x2":1870,"y2":1866,"stroke":64,"style":1121},"104.0","656.0",[270,1872],{"x1":1869,"y1":1866,"x2":1869,"y2":1873,"stroke":64,"style":1121},"157.5",[1123,1875],{"points":1876,"fill":1126},"104.0,161.5 99.0,152.5 109.0,152.5",[44,1878],{"x":1879,"y":1880,"width":1881,"height":1882,"rx":1883,"fill":50,"stroke":57,"style":65},"31.5","121.5","144.9","21.0","10",[67,1885,1888],{"x":1869,"y":1886,"style":1887},"136.0","font-size:11.5px;font-weight:700;fill:var(--muted,#5b6780);text-anchor:middle","formulas and formats",[44,1890],{"x":53,"y":1891,"width":1892,"height":1132,"rx":1133,"fill":1075,"stroke":1076,"style":1121},"163.5","168.0",[1135,1894,1896],{"transform":1895},"translate(92.0,185.2) scale(1.000)",[1139,1897],{"d":1898,"fill":1142,"stroke":1143,"style":1144},"M4 4h16v16H4z M4 9h16 M4 14h16 M10 4v16",[67,1900,1902],{"x":1869,"y":1901,"style":1149},"231.8","clear_inputs()",[67,1904,1906],{"x":1869,"y":1905,"style":117},"251.2","constants only",[270,1908],{"x1":1909,"y1":1866,"x2":1909,"y2":1873,"stroke":64,"style":1121},"288.0",[1123,1911],{"points":1912,"fill":1126},"288.0,161.5 283.0,152.5 293.0,152.5",[44,1914],{"x":1915,"y":1880,"width":1916,"height":1882,"rx":1883,"fill":50,"stroke":57,"style":65},"241.7","92.7",[67,1918,1919],{"x":1909,"y":1886,"style":1887},"formats only",[44,1921],{"x":1922,"y":1891,"width":1892,"height":1132,"rx":1133,"fill":63,"stroke":64,"style":1121},"204.0",[1135,1924,1926],{"transform":1925},"translate(276.0,185.2) scale(1.000)",[1139,1927],{"d":1928,"fill":1142,"stroke":1858,"style":1144},"M3 5h18v14H3z M3 10h18 M3 15h18 M9 5v14",[67,1930,118],{"x":1909,"y":1901,"style":1861},[67,1932,111],{"x":1909,"y":1905,"style":117},[270,1934],{"x1":1935,"y1":1866,"x2":1935,"y2":1873,"stroke":64,"style":1121},"472.0",[1123,1937],{"points":1938,"fill":1126},"472.0,161.5 467.0,152.5 477.0,152.5",[44,1940],{"x":1941,"y":1880,"width":1942,"height":1882,"rx":1883,"fill":50,"stroke":57,"style":65},"429.3","85.3",[67,1944,1945],{"x":1935,"y":1886,"style":1887},"values only",[44,1947],{"x":1948,"y":1891,"width":1892,"height":1132,"rx":1133,"fill":1068,"stroke":1069,"style":1121},"388.0",[1135,1950,1952],{"transform":1951},"translate(460.0,185.2) scale(1.000)",[1139,1953],{"d":1954,"fill":1142,"stroke":1955,"style":1144},"M3 5h18l-7 8v6l-4 2v-8z","var(--gold-ink,#7a4e06)",[67,1957,149],{"x":1935,"y":1901,"style":1958},"font-size:13.5px;font-weight:700;fill:var(--gold-ink,#7a4e06);text-anchor:middle",[67,1960,143],{"x":1935,"y":1905,"style":117},[270,1962],{"x1":1870,"y1":1866,"x2":1870,"y2":1873,"stroke":64,"style":1121},[1123,1964],{"points":1965,"fill":1126},"656.0,161.5 651.0,152.5 661.0,152.5",[44,1967],{"x":1968,"y":1880,"width":1969,"height":1882,"rx":1883,"fill":50,"stroke":57,"style":65},"609.0","94.0",[67,1971,1972],{"x":1870,"y":1886,"style":1887},"nothing at all",[44,1974],{"x":1975,"y":1891,"width":1892,"height":1132,"rx":1133,"fill":1976,"stroke":1977,"style":1121},"572.0","#fee8f2","var(--accent,#f43f8f)",[1135,1979,1981],{"transform":1980},"translate(644.0,176.5) scale(1.000)",[1139,1982],{"d":1983,"fill":1142,"stroke":1984,"style":1144},"M4 7h16 M10 11v6 M14 11v6 M6 7l1 13h10l1-13 M9 7V4h6v3","var(--accent-ink,#be185d)",[67,1986,1989],{"x":1870,"y":1987,"style":1988},"223.0","font-size:13.5px;font-weight:700;fill:var(--accent-ink,#be185d);text-anchor:middle","delete_rows()",[67,1991,1993],{"x":1870,"y":1992,"style":117},"242.5","rows removed and",[67,1995,1997],{"x":1870,"y":1996,"style":117},"260.0","shifted",[254,1999,2001],{"id":2000},"what-clearing-does-not-touch","What clearing does not touch",[10,2003,2004,2005,2009],{},"Some features are stored for ranges, not cells, and survive every step on this page: conditional formatting rules, data validation (dropdowns), Excel tables, defined names and print areas. Clearing A3:D5 leaves a dropdown rule on B3:B5 in place, which is usually what a template wants. When they must go, remove them through their own collections — ",[19,2006,2008],{"href":2007},"\u002Fadvanced-data-transformation-and-cleaning\u002Fapplying-conditional-formatting-with-openpyxl\u002Flist-and-remove-conditional-formatting-with-openpyxl\u002F","List and Remove Conditional Formatting with openpyxl"," shows how for formatting rules.",[254,2011,2013],{"id":2012},"common-pitfalls","Common pitfalls",[2015,2016,2017,2028,2037,2046,2054],"ul",{},[2018,2019,2020,2027],"li",{},[2021,2022,2023,2024,2026],"strong",{},"Expecting ",[14,2025,118],{}," to remove formatting."," It clears contents only.",[2018,2029,2030,2036],{},[2021,2031,2032,2033,2035],{},"Clearing with ",[14,2034,1395],{},"."," The workbook's formulas become cached values; saving loses them.",[2018,2038,2039,2042,2043,2045],{},[2021,2040,2041],{},"Forgetting merged cells."," Skip ",[14,2044,651],{}," objects or unmerge first.",[2018,2047,2048,1392,2051,2053],{},[2021,2049,2050],{},"Resetting attributes one at a time.",[14,2052,149],{}," is complete; hand-built resets miss borders or number formats.",[2018,2055,2056,2059],{},[2021,2057,2058],{},"Clearing comments by clearing contents."," Comments and links need their own assignments.",[254,2061,2063],{"id":2062},"performance-notes","Performance notes",[10,2065,2066],{},"Clearing is a per-cell loop and handles tens of thousands of cells per second. For very large areas, reconsider the approach: if the whole data region is being replaced, deleting the rows or writing into a fresh copy of the template is faster than visiting every cell.",[254,2068,2070],{"id":2069},"conclusion","Conclusion",[10,2072,2073,2076,2077,2080,2081,2084,2085,2088,2089,2091],{},[14,2074,2075],{},"cell.value = None"," is Clear Contents, ",[14,2078,2079],{},"cell.style = \"Normal\""," is Clear Formats, and ",[14,2082,2083],{},"cell.comment = None"," and ",[14,2086,2087],{},"cell.hyperlink = None"," clear notes and links. Loop over a range with a helper that skips ",[14,2090,651],{}," placeholders, clear only constants when resetting a template so its formulas survive, and reset formats too when the used range should shrink. Range-level features — conditional formats, validation, tables — need their own removal.",[254,2093,2095],{"id":2094},"frequently-asked-questions","Frequently asked questions",[10,2097,2098,2101],{},[2021,2099,2100],{},"Does setting cell.value = None remove formatting?","\nNo. It clears the value only. Font, fill, borders, number format, comments and hyperlinks stay, which is what you want when refilling a template.",[10,2103,2104,2107],{},[2021,2105,2106],{},"How do I remove all formatting from a cell?","\nAssign cell.style = \"Normal\". That resets font, fill, border, alignment, protection and number format to the workbook's default style. Comments and hyperlinks are separate and must be cleared on their own.",[10,2109,2110,2113],{},[2021,2111,2112],{},"Why does my clearing loop raise a MergedCell error?","\nThe range includes cells covered by a merge, and those cannot be assigned a value, not even None. Skip MergedCell objects in the loop, or unmerge the range first.",[10,2115,2116,2119],{},[2021,2117,2118],{},"Why does max_row stay large after clearing?","\nCells that still carry a style count as used. Resetting the style to Normal, or deleting the rows, lets openpyxl drop them, and max_row shrinks after the file is saved and reloaded.",[254,2121,2123],{"id":2122},"related","Related",[2015,2125,2126,2132,2139,2146],{},[2018,2127,2128,2129,2131],{},"Up one level: ",[19,2130,22],{"href":21}," — editing cells and ranges.",[2018,2133,2134,2138],{},[19,2135,2137],{"href":2136},"\u002Fgetting-started-with-python-excel-automation\u002Fusing-openpyxl-for-excel-file-manipulation\u002Fcopy-cell-styles-with-openpyxl\u002F","Copy Cell Styles from One Cell to Another with openpyxl"," — the opposite of clearing formats.",[2018,2140,2141,2145],{},[19,2142,2144],{"href":2143},"\u002Fautomating-reporting-workflows\u002Fgenerating-excel-reports-from-templates\u002Fpopulate-excel-template-without-losing-formatting\u002F","Populate an Excel Template Without Losing Formatting"," — refilling after a reset.",[2018,2147,2148,2152],{},[19,2149,2151],{"href":2150},"\u002Fgetting-started-with-python-excel-automation\u002Fusing-openpyxl-for-excel-file-manipulation\u002Fmove-a-range-of-cells-with-openpyxl\u002F","Move a Range of Cells with openpyxl move_range"," — relocating blocks instead of clearing them.",[637,2154,2155],{},"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 .sP0c6, html code.shiki .sP0c6{--shiki-default:#005CC5;--shiki-dark:#91CBFF}html pre.shiki code .s-wDw, html code.shiki .s-wDw{--shiki-default:#6A737D;--shiki-dark:#BDC4CC}html pre.shiki code .sa561, html code.shiki .sa561{--shiki-default:#E36209;--shiki-dark:#FFB757}",{"title":264,"searchDepth":319,"depth":319,"links":2157},[2158,2159,2160,2161,2162,2163,2164,2165,2166,2167,2168,2169,2170],{"id":256,"depth":319,"text":257},{"id":424,"depth":319,"text":425},{"id":514,"depth":319,"text":515},{"id":579,"depth":319,"text":580},{"id":644,"depth":319,"text":645},{"id":1161,"depth":319,"text":1162},{"id":1700,"depth":319,"text":1701},{"id":2000,"depth":319,"text":2001},{"id":2012,"depth":319,"text":2013},{"id":2062,"depth":319,"text":2063},{"id":2069,"depth":319,"text":2070},{"id":2094,"depth":319,"text":2095},{"id":2122,"depth":319,"text":2123},"2026-09-25","Reproduce Excel's Clear menu in Python: clear values but keep formatting, reset formatting but keep values, remove comments and hyperlinks, or clear everything. Covers clearing a template's input area while keeping its formulas, and why merged cells make a simple clearing loop fail.","md",[2175,2177,2179,2181],{"q":2100,"a":2176},"No. It clears the value only. Font, fill, borders, number format, comments and hyperlinks stay, which is what you want when refilling a template.",{"q":2106,"a":2178},"Assign cell.style = \"Normal\". That resets font, fill, border, alignment, protection and number format to the workbook's default style. Comments and hyperlinks are separate and must be cleared on their own.",{"q":2112,"a":2180},"The range includes cells covered by a merge, and those cannot be assigned a value, not even None. Skip MergedCell objects in the loop, or unmerge the range first.",{"q":2118,"a":2182},"Cells that still carry a style count as used. Resetting the style to Normal, or deleting the rows, lets openpyxl drop them, and max_row shrinks after the file is saved and reloaded.","clear cell contents and formatting in a range with openpyxl",null,{"breadcrumb":2186},[2187,2190,2193],{"name":2188,"item":2189},"Home","\u002F",{"name":2191,"item":2192},"Getting Started with Python Excel Automation","\u002Fgetting-started-with-python-excel-automation\u002F",{"name":22,"item":21},"\u002Fgetting-started-with-python-excel-automation\u002Fusing-openpyxl-for-excel-file-manipulation\u002Fclear-cell-contents-and-formatting-with-openpyxl",{"title":2196,"description":2197},"openpyxl: Clear Cell Values, Formatting, Comments and Links","Clear contents, formats, comments and hyperlinks in openpyxl the way Excel's Clear menu does: value = None, style = \"Normal\", keeping formulas in templates, skipping merged cells and shrinking the used range.","clear-cell-contents-and-formatting-with-openpyxl","getting-started-with-python-excel-automation\u002Fusing-openpyxl-for-excel-file-manipulation\u002Fclear-cell-contents-and-formatting-with-openpyxl\u002Findex",[72,2201,2202],"cell-styling","report-layouts","how-to","p46bLKM9r-UaAnKDzC6tbl89GbIvWyEo3VBRzl57ptM",[2206,2209],{"title":22,"path":2207,"stem":2208,"children":-1},"\u002Fgetting-started-with-python-excel-automation\u002Fusing-openpyxl-for-excel-file-manipulation","getting-started-with-python-excel-automation\u002Fusing-openpyxl-for-excel-file-manipulation\u002Findex",{"title":2210,"path":2211,"stem":2212,"children":-1},"Convert Excel Column Letters and Numbers in Python","\u002Fgetting-started-with-python-excel-automation\u002Fusing-openpyxl-for-excel-file-manipulation\u002Fconvert-column-letters-and-numbers-with-openpyxl","getting-started-with-python-excel-automation\u002Fusing-openpyxl-for-excel-file-manipulation\u002Fconvert-column-letters-and-numbers-with-openpyxl\u002Findex",[2214,2216],{"path":2215,"title":2191},"\u002Fgetting-started-with-python-excel-automation",{"path":2207,"title":22},[],[2219,2223,2226,2229,2232,2235],{"path":2220,"title":2221,"kind":2222},"\u002Fadvanced-data-transformation-and-cleaning\u002Fapplying-conditional-formatting-with-openpyxl","Applying Conditional Formatting With openpyxl","guide",{"path":2224,"title":2225,"kind":2203},"\u002Fadvanced-data-transformation-and-cleaning\u002Fapplying-conditional-formatting-with-openpyxl\u002Fadd-data-bars-and-colour-scales-with-openpyxl","Add Data Bars and Colour Scales with openpyxl",{"path":2227,"title":2228,"kind":2203},"\u002Fadvanced-data-transformation-and-cleaning\u002Fapplying-conditional-formatting-with-openpyxl\u002Fadd-icon-sets-with-openpyxl","Add Icon Sets to Excel Cells with openpyxl",{"path":2230,"title":2231,"kind":2203},"\u002Fadvanced-data-transformation-and-cleaning\u002Fapplying-conditional-formatting-with-openpyxl\u002Fapply-a-colour-scale-per-row-or-per-column-with-openpyxl","Apply a Colour Scale per Row or per Column with openpyxl",{"path":2233,"title":2234,"kind":2203},"\u002Fadvanced-data-transformation-and-cleaning\u002Fapplying-conditional-formatting-with-openpyxl\u002Fcontrol-conditional-formatting-rule-order-and-stop-if-true","Control Conditional Formatting Rule Order and Stop If True",{"path":2236,"title":2237,"kind":2203},"\u002Fadvanced-data-transformation-and-cleaning\u002Fapplying-conditional-formatting-with-openpyxl\u002Fhighlight-an-entire-row-based-on-a-cell-value-with-openpyxl","Highlight an Entire Row Based on a Cell Value with openpyxl",1790972069738]