[{"data":1,"prerenderedAt":2452},["ShallowReactive",2],{"doc:\u002Fadvanced-data-transformation-and-cleaning\u002Fapplying-conditional-formatting-with-openpyxl\u002Flist-and-remove-conditional-formatting-with-openpyxl":3,"surround:\u002Fadvanced-data-transformation-and-cleaning\u002Fapplying-conditional-formatting-with-openpyxl\u002Flist-and-remove-conditional-formatting-with-openpyxl":2419,"ancestors:\u002Fadvanced-data-transformation-and-cleaning\u002Fapplying-conditional-formatting-with-openpyxl\u002Flist-and-remove-conditional-formatting-with-openpyxl":2428,"children:\u002Fadvanced-data-transformation-and-cleaning\u002Fapplying-conditional-formatting-with-openpyxl\u002Flist-and-remove-conditional-formatting-with-openpyxl":2433,"related:\u002Fadvanced-data-transformation-and-cleaning\u002Fapplying-conditional-formatting-with-openpyxl\u002Flist-and-remove-conditional-formatting-with-openpyxl":2434},{"id":4,"title":5,"body":6,"dateModified":2385,"datePublished":2385,"description":2386,"extension":2387,"faq":2388,"keyword":2397,"kind":2398,"meta":2399,"navigation":458,"path":2409,"seo":2410,"slug":2412,"stem":2413,"topics":2414,"type":2417,"__hash__":2418},"docs\u002Fadvanced-data-transformation-and-cleaning\u002Fapplying-conditional-formatting-with-openpyxl\u002Flist-and-remove-conditional-formatting-with-openpyxl\u002Findex.md","List and Remove Conditional Formatting with openpyxl",{"type":7,"value":8,"toc":2372},"minimark",[9,19,355,360,388,391,775,779,793,1043,1058,1062,1065,1201,1204,1362,1366,1380,1637,1644,1648,1651,1792,1799,1803,1809,1961,1972,2098,2102,2105,2260,2263,2267,2294,2298,2307,2311,2317,2323,2329,2335,2339,2368],[10,11,12,13,18],"p",{},"Conditional formatting accumulates. Every rerun of a report script adds its rules again, people copy and paste formatted ranges, and after a year a sheet can carry dozens of overlapping rules that slow Excel down and make the Manage Rules dialog unreadable. openpyxl can read every rule, but it has no method for deleting one — you rebuild the list without the rules you do not want. This guide, part of ",[14,15,17],"a",{"href":16},"\u002Fadvanced-data-transformation-and-cleaning\u002Fapplying-conditional-formatting-with-openpyxl\u002F","Applying Conditional Formatting with openpyxl",", turns the rules into an inventory you can read and then cleans them up precisely.",[20,21,29,30,29,34,29,38,29,46,29,55,29,59,29,66,29,70,29,74,29,78,29,82,29,86,29,91,29,93,29,97,29,99,29,102,29,104,29,107,29,110,29,114,29,116,29,120,29,122,29,125,29,127,29,130,29,133,29,136,29,138,29,140,29,142,29,144,29,146,29,148,29,151,29,155,29,157,29,159,29,161,29,163,29,165,29,167,29,170,29,174,29,176,29,179,29,181,29,184,29,186,29,189,29,192,29,196,29,198,29,200,29,202,29,205,29,207,29,210,29,213,29,217,29,219,29,222,29,224,29,227,29,229,29,231,29,234,29,238,29,241,29,244,29,247,29,250,29,253,29,255,29,258,29,260,29,262,29,264,29,266,29,268,29,270,29,272,29,274,29,276,29,278,29,280,29,282,29,284,29,286,29,288,29,290,29,292,29,294,29,296,29,298,29,300,29,302,29,304,29,306,29,308,29,310,29,312,29,314,29,316,29,318,29,324,29,328,29,336,29,341,29,349],"svg",{"viewBox":22,"role":23,"ariaLabelledBy":24,"xmlns":27,"style":28},"3 0 753 276","img",[25,26],"cl-overview-t","cl-overview-d","http:\u002F\u002Fwww.w3.org\u002F2000\u002Fsvg","width:100%;max-width:753px;height:auto;display:block;margin:1.5rem auto;font-family:Inter,ui-sans-serif,system-ui,sans-serif","\n  ",[31,32,33],"title",{"id":25},"A cluttered rule list before and after cleaning",[35,36,37],"desc",{"id":26},"Before cleaning, the Sales sheet has the same greater-than-150 rule three times on B2:B20, a formula rule, a colour scale and a data bar. After removing duplicates and the data bar, one greater-than rule, the formula rule and the colour scale remain.",[39,40],"rect",{"x":41,"y":42,"width":43,"height":44,"fill":45},"3","0","753","276","#ffffff",[39,47],{"x":48,"y":49,"width":50,"height":51,"rx":42,"fill":52,"stroke":53,"style":54},"20.0","40.0","32.0","24.0","#e7ebef","var(--line,#cdd5e6)","stroke-width:1px",[39,56],{"x":57,"y":49,"width":58,"height":51,"rx":42,"fill":52,"stroke":53,"style":54},"52.0","62.4",[60,61,65],"text",{"x":62,"y":63,"style":64},"83.2","57.0","font-size:11px;font-weight:600;fill:var(--muted,#5b6780);text-anchor:middle","A",[39,67],{"x":68,"y":49,"width":69,"height":51,"rx":42,"fill":52,"stroke":53,"style":54},"114.4","81.1",[60,71,73],{"x":72,"y":63,"style":64},"155.0","B",[39,75],{"x":76,"y":49,"width":77,"height":51,"rx":42,"fill":52,"stroke":53,"style":54},"195.5","79.7",[60,79,81],{"x":80,"y":63,"style":64},"235.4","C",[39,83],{"x":48,"y":84,"width":50,"height":85,"rx":42,"fill":52,"stroke":53,"style":54},"64.0","28.0",[60,87,90],{"x":88,"y":89,"style":64},"36.0","83.0","1",[39,92],{"x":57,"y":84,"width":58,"height":85,"rx":42,"fill":45,"stroke":53,"style":54},[60,94,96],{"x":62,"y":89,"style":95},"font-size:12px;font-weight:700;fill:var(--text,#172033);text-anchor:middle","range",[39,98],{"x":68,"y":84,"width":69,"height":85,"rx":42,"fill":45,"stroke":53,"style":54},[60,100,101],{"x":72,"y":89,"style":95},"type",[39,103],{"x":76,"y":84,"width":77,"height":85,"rx":42,"fill":45,"stroke":53,"style":54},[60,105,106],{"x":80,"y":89,"style":95},"rule",[39,108],{"x":48,"y":109,"width":50,"height":85,"rx":42,"fill":52,"stroke":53,"style":54},"92.0",[60,111,113],{"x":88,"y":112,"style":64},"111.0","2",[39,115],{"x":57,"y":109,"width":58,"height":85,"rx":42,"fill":45,"stroke":53,"style":54},[60,117,119],{"x":62,"y":112,"style":118},"font-size:12px;font-weight:400;fill:var(--text,#172033);text-anchor:middle","B2:B20",[39,121],{"x":68,"y":109,"width":69,"height":85,"rx":42,"fill":45,"stroke":53,"style":54},[60,123,124],{"x":72,"y":112,"style":118},"cellIs",[39,126],{"x":76,"y":109,"width":77,"height":85,"rx":42,"fill":45,"stroke":53,"style":54},[60,128,129],{"x":80,"y":112,"style":118},"> 150",[39,131],{"x":48,"y":132,"width":50,"height":85,"rx":42,"fill":52,"stroke":53,"style":54},"120.0",[60,134,41],{"x":88,"y":135,"style":64},"139.0",[39,137],{"x":57,"y":132,"width":58,"height":85,"rx":42,"fill":45,"stroke":53,"style":54},[60,139,119],{"x":62,"y":135,"style":118},[39,141],{"x":68,"y":132,"width":69,"height":85,"rx":42,"fill":45,"stroke":53,"style":54},[60,143,124],{"x":72,"y":135,"style":118},[39,145],{"x":76,"y":132,"width":77,"height":85,"rx":42,"fill":45,"stroke":53,"style":54},[60,147,129],{"x":80,"y":135,"style":118},[39,149],{"x":48,"y":150,"width":50,"height":85,"rx":42,"fill":52,"stroke":53,"style":54},"148.0",[60,152,154],{"x":88,"y":153,"style":64},"167.0","4",[39,156],{"x":57,"y":150,"width":58,"height":85,"rx":42,"fill":45,"stroke":53,"style":54},[60,158,119],{"x":62,"y":153,"style":118},[39,160],{"x":68,"y":150,"width":69,"height":85,"rx":42,"fill":45,"stroke":53,"style":54},[60,162,124],{"x":72,"y":153,"style":118},[39,164],{"x":76,"y":150,"width":77,"height":85,"rx":42,"fill":45,"stroke":53,"style":54},[60,166,129],{"x":80,"y":153,"style":118},[39,168],{"x":48,"y":169,"width":50,"height":85,"rx":42,"fill":52,"stroke":53,"style":54},"176.0",[60,171,173],{"x":88,"y":172,"style":64},"195.0","5",[39,175],{"x":57,"y":169,"width":58,"height":85,"rx":42,"fill":45,"stroke":53,"style":54},[60,177,178],{"x":62,"y":172,"style":118},"A2:B20",[39,180],{"x":68,"y":169,"width":69,"height":85,"rx":42,"fill":45,"stroke":53,"style":54},[60,182,183],{"x":72,"y":172,"style":118},"expression",[39,185],{"x":76,"y":169,"width":77,"height":85,"rx":42,"fill":45,"stroke":53,"style":54},[60,187,188],{"x":80,"y":172,"style":118},"$B2\u003C50",[39,190],{"x":48,"y":191,"width":50,"height":85,"rx":42,"fill":52,"stroke":53,"style":54},"204.0",[60,193,195],{"x":88,"y":194,"style":64},"223.0","6",[39,197],{"x":57,"y":191,"width":58,"height":85,"rx":42,"fill":45,"stroke":53,"style":54},[60,199,119],{"x":62,"y":194,"style":118},[39,201],{"x":68,"y":191,"width":69,"height":85,"rx":42,"fill":45,"stroke":53,"style":54},[60,203,204],{"x":72,"y":194,"style":118},"colorScale",[39,206],{"x":76,"y":191,"width":77,"height":85,"rx":42,"fill":45,"stroke":53,"style":54},[60,208,209],{"x":80,"y":194,"style":118},"min → max",[39,211],{"x":48,"y":212,"width":50,"height":85,"rx":42,"fill":52,"stroke":53,"style":54},"232.0",[60,214,216],{"x":88,"y":215,"style":64},"251.0","7",[39,218],{"x":57,"y":212,"width":58,"height":85,"rx":42,"fill":45,"stroke":53,"style":54},[60,220,221],{"x":62,"y":215,"style":118},"C2:C20",[39,223],{"x":68,"y":212,"width":69,"height":85,"rx":42,"fill":45,"stroke":53,"style":54},[60,225,226],{"x":72,"y":215,"style":118},"dataBar",[39,228],{"x":76,"y":212,"width":77,"height":85,"rx":42,"fill":45,"stroke":53,"style":54},[60,230,209],{"x":80,"y":215,"style":118},[39,232],{"x":233,"y":49,"width":50,"height":51,"rx":42,"fill":52,"stroke":53,"style":54},"485.6",[39,235],{"x":236,"y":49,"width":237,"height":51,"rx":42,"fill":52,"stroke":53,"style":54},"517.6","61.7",[60,239,65],{"x":240,"y":63,"style":64},"548.4",[39,242],{"x":243,"y":49,"width":69,"height":51,"rx":42,"fill":52,"stroke":53,"style":54},"579.2",[60,245,73],{"x":246,"y":63,"style":64},"619.8",[39,248],{"x":249,"y":49,"width":77,"height":51,"rx":42,"fill":52,"stroke":53,"style":54},"660.3",[60,251,81],{"x":252,"y":63,"style":64},"700.2",[39,254],{"x":233,"y":84,"width":50,"height":85,"rx":42,"fill":52,"stroke":53,"style":54},[60,256,90],{"x":257,"y":89,"style":64},"501.6",[39,259],{"x":236,"y":84,"width":237,"height":85,"rx":42,"fill":45,"stroke":53,"style":54},[60,261,96],{"x":240,"y":89,"style":95},[39,263],{"x":243,"y":84,"width":69,"height":85,"rx":42,"fill":45,"stroke":53,"style":54},[60,265,101],{"x":246,"y":89,"style":95},[39,267],{"x":249,"y":84,"width":77,"height":85,"rx":42,"fill":45,"stroke":53,"style":54},[60,269,106],{"x":252,"y":89,"style":95},[39,271],{"x":233,"y":109,"width":50,"height":85,"rx":42,"fill":52,"stroke":53,"style":54},[60,273,113],{"x":257,"y":112,"style":64},[39,275],{"x":236,"y":109,"width":237,"height":85,"rx":42,"fill":45,"stroke":53,"style":54},[60,277,119],{"x":240,"y":112,"style":118},[39,279],{"x":243,"y":109,"width":69,"height":85,"rx":42,"fill":45,"stroke":53,"style":54},[60,281,124],{"x":246,"y":112,"style":118},[39,283],{"x":249,"y":109,"width":77,"height":85,"rx":42,"fill":45,"stroke":53,"style":54},[60,285,129],{"x":252,"y":112,"style":118},[39,287],{"x":233,"y":132,"width":50,"height":85,"rx":42,"fill":52,"stroke":53,"style":54},[60,289,41],{"x":257,"y":135,"style":64},[39,291],{"x":236,"y":132,"width":237,"height":85,"rx":42,"fill":45,"stroke":53,"style":54},[60,293,178],{"x":240,"y":135,"style":118},[39,295],{"x":243,"y":132,"width":69,"height":85,"rx":42,"fill":45,"stroke":53,"style":54},[60,297,183],{"x":246,"y":135,"style":118},[39,299],{"x":249,"y":132,"width":77,"height":85,"rx":42,"fill":45,"stroke":53,"style":54},[60,301,188],{"x":252,"y":135,"style":118},[39,303],{"x":233,"y":150,"width":50,"height":85,"rx":42,"fill":52,"stroke":53,"style":54},[60,305,154],{"x":257,"y":153,"style":64},[39,307],{"x":236,"y":150,"width":237,"height":85,"rx":42,"fill":45,"stroke":53,"style":54},[60,309,119],{"x":240,"y":153,"style":118},[39,311],{"x":243,"y":150,"width":69,"height":85,"rx":42,"fill":45,"stroke":53,"style":54},[60,313,204],{"x":246,"y":153,"style":118},[39,315],{"x":249,"y":150,"width":77,"height":85,"rx":42,"fill":45,"stroke":53,"style":54},[60,317,209],{"x":252,"y":153,"style":118},[60,319,323],{"x":320,"y":321,"style":322},"147.6","29.0","font-size:12.5px;font-weight:700;fill:var(--muted,#5b6780);text-anchor:middle","before",[60,325,327],{"x":326,"y":321,"style":322},"612.8","after",[329,330],"line",{"x1":331,"y1":332,"x2":333,"y2":332,"stroke":334,"style":335},"285.2","108.0","471.6","var(--brand,#5b5cf0)","stroke-width:2px",[337,338],"polygon",{"points":339,"fill":340},"475.6,108.0 466.6,113.0 466.6,103.0","#5b5cf0",[39,342],{"x":343,"y":344,"width":345,"height":346,"rx":347,"fill":45,"stroke":53,"style":348},"312.2","75.0","136.3","22.0","11","stroke-width:1.2px",[60,350,354],{"x":351,"y":352,"style":353},"380.4","90.0","font-size:11.5px;font-weight:400;fill:var(--brand-strong,#4338ca);text-anchor:middle;font-family:ui-monospace,SFMono-Regular,Menlo,Consolas,monospace","rebuild the list",[356,357,359],"h2",{"id":358},"prerequisites","Prerequisites",[361,362,367],"pre",{"className":363,"code":364,"language":365,"meta":366,"style":366},"language-bash shiki shiki-themes github-light github-dark-high-contrast","pip install openpyxl pandas\n","bash","",[368,369,370],"code",{"__ignoreMap":366},[371,372,374,378,382,385],"span",{"class":329,"line":373},1,[371,375,377],{"class":376},"sMTad","pip",[371,379,381],{"class":380},"srMev"," install",[371,383,384],{"class":380}," openpyxl",[371,386,387],{"class":380}," pandas\n",[10,389,390],{},"A sheet with the kind of clutter a rerun script leaves behind — the same rule three times — plus a formula rule, a colour scale and a data bar:",[361,392,396],{"className":393,"code":394,"language":395,"meta":366,"style":366},"language-python shiki shiki-themes github-light github-dark-high-contrast","from openpyxl import Workbook, load_workbook\nfrom openpyxl.formatting.formatting import ConditionalFormattingList\nfrom openpyxl.formatting.rule import CellIsRule, ColorScaleRule, DataBarRule, FormulaRule\nfrom openpyxl.styles import PatternFill\n\nwb = Workbook()\nws = wb.active\nws.title = \"Sales\"\nfor r in range(1, 21):\n    ws.append([r, r * 10, r * 5])\nred = PatternFill(\"solid\", fgColor=\"FCE9E9\")\nfor _ in range(3):                                   # the same rule added by three runs\n    ws.conditional_formatting.add(\"B2:B20\", CellIsRule(operator=\"greaterThan\", formula=[\"150\"], fill=red))\nws.conditional_formatting.add(\"A2:B20\", FormulaRule(formula=[\"$B2\u003C50\"], fill=red))\nws.conditional_formatting.add(\"B2:B20\", ColorScaleRule(start_type=\"min\", start_color=\"FFFFFF\",\n                                                       end_type=\"max\", end_color=\"5B5CF0\"))\nws.conditional_formatting.add(\"C2:C20\", DataBarRule(start_type=\"min\", end_type=\"max\", color=\"0B6157\"))\nwb.save(\"report.xlsx\")\n","python",[368,397,398,414,427,440,453,460,472,483,494,524,547,575,598,642,671,702,726,764],{"__ignoreMap":366},[371,399,400,404,408,411],{"class":329,"line":373},[371,401,403],{"class":402},"s-kum","from",[371,405,407],{"class":406},"skGVy"," openpyxl ",[371,409,410],{"class":402},"import",[371,412,413],{"class":406}," Workbook, load_workbook\n",[371,415,417,419,422,424],{"class":329,"line":416},2,[371,418,403],{"class":402},[371,420,421],{"class":406}," openpyxl.formatting.formatting ",[371,423,410],{"class":402},[371,425,426],{"class":406}," ConditionalFormattingList\n",[371,428,430,432,435,437],{"class":329,"line":429},3,[371,431,403],{"class":402},[371,433,434],{"class":406}," openpyxl.formatting.rule ",[371,436,410],{"class":402},[371,438,439],{"class":406}," CellIsRule, ColorScaleRule, DataBarRule, FormulaRule\n",[371,441,443,445,448,450],{"class":329,"line":442},4,[371,444,403],{"class":402},[371,446,447],{"class":406}," openpyxl.styles ",[371,449,410],{"class":402},[371,451,452],{"class":406}," PatternFill\n",[371,454,456],{"class":329,"line":455},5,[371,457,459],{"emptyLinePlaceholder":458},true,"\n",[371,461,463,466,469],{"class":329,"line":462},6,[371,464,465],{"class":406},"wb ",[371,467,468],{"class":402},"=",[371,470,471],{"class":406}," Workbook()\n",[371,473,475,478,480],{"class":329,"line":474},7,[371,476,477],{"class":406},"ws ",[371,479,468],{"class":402},[371,481,482],{"class":406}," wb.active\n",[371,484,486,489,491],{"class":329,"line":485},8,[371,487,488],{"class":406},"ws.title ",[371,490,468],{"class":402},[371,492,493],{"class":380}," \"Sales\"\n",[371,495,497,500,503,506,510,513,515,518,521],{"class":329,"line":496},9,[371,498,499],{"class":402},"for",[371,501,502],{"class":406}," r ",[371,504,505],{"class":402},"in",[371,507,509],{"class":508},"sP0c6"," range",[371,511,512],{"class":406},"(",[371,514,90],{"class":508},[371,516,517],{"class":406},", ",[371,519,520],{"class":508},"21",[371,522,523],{"class":406},"):\n",[371,525,527,530,533,536,539,541,544],{"class":329,"line":526},10,[371,528,529],{"class":406},"    ws.append([r, r ",[371,531,532],{"class":402},"*",[371,534,535],{"class":508}," 10",[371,537,538],{"class":406},", r ",[371,540,532],{"class":402},[371,542,543],{"class":508}," 5",[371,545,546],{"class":406},"])\n",[371,548,550,553,555,558,561,563,567,569,572],{"class":329,"line":549},11,[371,551,552],{"class":406},"red ",[371,554,468],{"class":402},[371,556,557],{"class":406}," PatternFill(",[371,559,560],{"class":380},"\"solid\"",[371,562,517],{"class":406},[371,564,566],{"class":565},"sa561","fgColor",[371,568,468],{"class":402},[371,570,571],{"class":380},"\"FCE9E9\"",[371,573,574],{"class":406},")\n",[371,576,578,580,583,585,587,589,591,594],{"class":329,"line":577},12,[371,579,499],{"class":402},[371,581,582],{"class":406}," _ ",[371,584,505],{"class":402},[371,586,509],{"class":508},[371,588,512],{"class":406},[371,590,41],{"class":508},[371,592,593],{"class":406},"):                                   ",[371,595,597],{"class":596},"s-wDw","# the same rule added by three runs\n",[371,599,601,604,607,610,613,615,618,620,623,625,628,631,634,637,639],{"class":329,"line":600},13,[371,602,603],{"class":406},"    ws.conditional_formatting.add(",[371,605,606],{"class":380},"\"B2:B20\"",[371,608,609],{"class":406},", CellIsRule(",[371,611,612],{"class":565},"operator",[371,614,468],{"class":402},[371,616,617],{"class":380},"\"greaterThan\"",[371,619,517],{"class":406},[371,621,622],{"class":565},"formula",[371,624,468],{"class":402},[371,626,627],{"class":406},"[",[371,629,630],{"class":380},"\"150\"",[371,632,633],{"class":406},"], ",[371,635,636],{"class":565},"fill",[371,638,468],{"class":402},[371,640,641],{"class":406},"red))\n",[371,643,645,648,651,654,656,658,660,663,665,667,669],{"class":329,"line":644},14,[371,646,647],{"class":406},"ws.conditional_formatting.add(",[371,649,650],{"class":380},"\"A2:B20\"",[371,652,653],{"class":406},", FormulaRule(",[371,655,622],{"class":565},[371,657,468],{"class":402},[371,659,627],{"class":406},[371,661,662],{"class":380},"\"$B2\u003C50\"",[371,664,633],{"class":406},[371,666,636],{"class":565},[371,668,468],{"class":402},[371,670,641],{"class":406},[371,672,674,676,678,681,684,686,689,691,694,696,699],{"class":329,"line":673},15,[371,675,647],{"class":406},[371,677,606],{"class":380},[371,679,680],{"class":406},", ColorScaleRule(",[371,682,683],{"class":565},"start_type",[371,685,468],{"class":402},[371,687,688],{"class":380},"\"min\"",[371,690,517],{"class":406},[371,692,693],{"class":565},"start_color",[371,695,468],{"class":402},[371,697,698],{"class":380},"\"FFFFFF\"",[371,700,701],{"class":406},",\n",[371,703,705,708,710,713,715,718,720,723],{"class":329,"line":704},16,[371,706,707],{"class":565},"                                                       end_type",[371,709,468],{"class":402},[371,711,712],{"class":380},"\"max\"",[371,714,517],{"class":406},[371,716,717],{"class":565},"end_color",[371,719,468],{"class":402},[371,721,722],{"class":380},"\"5B5CF0\"",[371,724,725],{"class":406},"))\n",[371,727,729,731,734,737,739,741,743,745,748,750,752,754,757,759,762],{"class":329,"line":728},17,[371,730,647],{"class":406},[371,732,733],{"class":380},"\"C2:C20\"",[371,735,736],{"class":406},", DataBarRule(",[371,738,683],{"class":565},[371,740,468],{"class":402},[371,742,688],{"class":380},[371,744,517],{"class":406},[371,746,747],{"class":565},"end_type",[371,749,468],{"class":402},[371,751,712],{"class":380},[371,753,517],{"class":406},[371,755,756],{"class":565},"color",[371,758,468],{"class":402},[371,760,761],{"class":380},"\"0B6157\"",[371,763,725],{"class":406},[371,765,767,770,773],{"class":329,"line":766},18,[371,768,769],{"class":406},"wb.save(",[371,771,772],{"class":380},"\"report.xlsx\"",[371,774,574],{"class":406},[356,776,778],{"id":777},"step-1-list-every-rule-as-a-table","Step 1 — List every rule as a table",[10,780,781,784,785,788,789,792],{},[368,782,783],{},"ws.conditional_formatting"," iterates over range groups; each has an ",[368,786,787],{},"sqref"," and a list of ",[368,790,791],{},"rules",". Flatten them into rows, across every sheet, and a DataFrame makes the inventory easy to sort and filter:",[361,794,796],{"className":393,"code":795,"language":395,"meta":366,"style":366},"import pandas as pd\n\ndef rule_inventory(path):\n    rows = []\n    wb = load_workbook(path)\n    for ws in wb.worksheets:\n        for cf in ws.conditional_formatting:\n            for rule in cf.rules:\n                fill = rule.dxf.fill.fgColor.rgb if rule.dxf and rule.dxf.fill else None\n                rows.append({\"sheet\": ws.title, \"range\": str(cf.sqref), \"type\": rule.type,\n                             \"priority\": rule.priority, \"operator\": rule.operator,\n                             \"formula\": \"; \".join(rule.formula or []), \"fill\": fill})\n    return pd.DataFrame(rows).sort_values([\"sheet\", \"priority\"])\n\ninventory = rule_inventory(\"report.xlsx\")\nprint(inventory[[\"range\", \"type\", \"priority\", \"formula\"]].values.tolist())\n",[368,797,798,811,815,827,837,847,860,873,886,914,943,957,982,999,1003,1017],{"__ignoreMap":366},[371,799,800,802,805,808],{"class":329,"line":373},[371,801,410],{"class":402},[371,803,804],{"class":406}," pandas ",[371,806,807],{"class":402},"as",[371,809,810],{"class":406}," pd\n",[371,812,813],{"class":329,"line":416},[371,814,459],{"emptyLinePlaceholder":458},[371,816,817,820,824],{"class":329,"line":429},[371,818,819],{"class":402},"def",[371,821,823],{"class":822},"s_Opv"," rule_inventory",[371,825,826],{"class":406},"(path):\n",[371,828,829,832,834],{"class":329,"line":442},[371,830,831],{"class":406},"    rows ",[371,833,468],{"class":402},[371,835,836],{"class":406}," []\n",[371,838,839,842,844],{"class":329,"line":455},[371,840,841],{"class":406},"    wb ",[371,843,468],{"class":402},[371,845,846],{"class":406}," load_workbook(path)\n",[371,848,849,852,855,857],{"class":329,"line":462},[371,850,851],{"class":402},"    for",[371,853,854],{"class":406}," ws ",[371,856,505],{"class":402},[371,858,859],{"class":406}," wb.worksheets:\n",[371,861,862,865,868,870],{"class":329,"line":474},[371,863,864],{"class":402},"        for",[371,866,867],{"class":406}," cf ",[371,869,505],{"class":402},[371,871,872],{"class":406}," ws.conditional_formatting:\n",[371,874,875,878,881,883],{"class":329,"line":485},[371,876,877],{"class":402},"            for",[371,879,880],{"class":406}," rule ",[371,882,505],{"class":402},[371,884,885],{"class":406}," cf.rules:\n",[371,887,888,891,893,896,899,902,905,908,911],{"class":329,"line":496},[371,889,890],{"class":406},"                fill ",[371,892,468],{"class":402},[371,894,895],{"class":406}," rule.dxf.fill.fgColor.rgb ",[371,897,898],{"class":402},"if",[371,900,901],{"class":406}," rule.dxf ",[371,903,904],{"class":402},"and",[371,906,907],{"class":406}," rule.dxf.fill ",[371,909,910],{"class":402},"else",[371,912,913],{"class":508}," None\n",[371,915,916,919,922,925,928,931,934,937,940],{"class":329,"line":526},[371,917,918],{"class":406},"                rows.append({",[371,920,921],{"class":380},"\"sheet\"",[371,923,924],{"class":406},": ws.title, ",[371,926,927],{"class":380},"\"range\"",[371,929,930],{"class":406},": ",[371,932,933],{"class":508},"str",[371,935,936],{"class":406},"(cf.sqref), ",[371,938,939],{"class":380},"\"type\"",[371,941,942],{"class":406},": rule.type,\n",[371,944,945,948,951,954],{"class":329,"line":549},[371,946,947],{"class":380},"                             \"priority\"",[371,949,950],{"class":406},": rule.priority, ",[371,952,953],{"class":380},"\"operator\"",[371,955,956],{"class":406},": rule.operator,\n",[371,958,959,962,964,967,970,973,976,979],{"class":329,"line":577},[371,960,961],{"class":380},"                             \"formula\"",[371,963,930],{"class":406},[371,965,966],{"class":380},"\"; \"",[371,968,969],{"class":406},".join(rule.formula ",[371,971,972],{"class":402},"or",[371,974,975],{"class":406}," []), ",[371,977,978],{"class":380},"\"fill\"",[371,980,981],{"class":406},": fill})\n",[371,983,984,987,990,992,994,997],{"class":329,"line":600},[371,985,986],{"class":402},"    return",[371,988,989],{"class":406}," pd.DataFrame(rows).sort_values([",[371,991,921],{"class":380},[371,993,517],{"class":406},[371,995,996],{"class":380},"\"priority\"",[371,998,546],{"class":406},[371,1000,1001],{"class":329,"line":644},[371,1002,459],{"emptyLinePlaceholder":458},[371,1004,1005,1008,1010,1013,1015],{"class":329,"line":673},[371,1006,1007],{"class":406},"inventory ",[371,1009,468],{"class":402},[371,1011,1012],{"class":406}," rule_inventory(",[371,1014,772],{"class":380},[371,1016,574],{"class":406},[371,1018,1019,1022,1025,1027,1029,1031,1033,1035,1037,1040],{"class":329,"line":704},[371,1020,1021],{"class":508},"print",[371,1023,1024],{"class":406},"(inventory[[",[371,1026,927],{"class":380},[371,1028,517],{"class":406},[371,1030,939],{"class":380},[371,1032,517],{"class":406},[371,1034,996],{"class":380},[371,1036,517],{"class":406},[371,1038,1039],{"class":380},"\"formula\"",[371,1041,1042],{"class":406},"]].values.tolist())\n",[10,1044,1045,1046,517,1048,517,1050,517,1052,517,1054,1057],{},"Each rule shows its range, type — ",[368,1047,124],{},[368,1049,183],{},[368,1051,204],{},[368,1053,226],{},[368,1055,1056],{},"iconSet"," and so on — priority, formula and the fill colour of its format. Rules with a lower priority number are evaluated first. Writing the inventory to a sheet of its own is a useful audit before a clean-up, and a before-and-after pair of inventories documents what changed.",[356,1059,1061],{"id":1060},"step-2-find-duplicates","Step 2 — Find duplicates",[10,1063,1064],{},"Two rules are duplicates when they cover the same range with the same type, operator, formula and format. Build a key from those parts and count:",[361,1066,1068],{"className":393,"code":1067,"language":395,"meta":366,"style":366},"def rule_key(sqref, rule):\n    fill = rule.dxf.fill.fgColor.rgb if rule.dxf and rule.dxf.fill else None\n    return (str(sqref), rule.type, rule.operator, tuple(rule.formula or []), fill)\n\nkey_cols = [\"range\", \"type\", \"operator\", \"formula\", \"fill\"]\ndupes = inventory[inventory.duplicated(key_cols, keep=False)]\nprint(len(dupes), \"rows share a key\")          # 3 rows share a key\n",[368,1069,1070,1080,1101,1124,1128,1159,1180],{"__ignoreMap":366},[371,1071,1072,1074,1077],{"class":329,"line":373},[371,1073,819],{"class":402},[371,1075,1076],{"class":822}," rule_key",[371,1078,1079],{"class":406},"(sqref, rule):\n",[371,1081,1082,1085,1087,1089,1091,1093,1095,1097,1099],{"class":329,"line":416},[371,1083,1084],{"class":406},"    fill ",[371,1086,468],{"class":402},[371,1088,895],{"class":406},[371,1090,898],{"class":402},[371,1092,901],{"class":406},[371,1094,904],{"class":402},[371,1096,907],{"class":406},[371,1098,910],{"class":402},[371,1100,913],{"class":508},[371,1102,1103,1105,1108,1110,1113,1116,1119,1121],{"class":329,"line":429},[371,1104,986],{"class":402},[371,1106,1107],{"class":406}," (",[371,1109,933],{"class":508},[371,1111,1112],{"class":406},"(sqref), rule.type, rule.operator, ",[371,1114,1115],{"class":508},"tuple",[371,1117,1118],{"class":406},"(rule.formula ",[371,1120,972],{"class":402},[371,1122,1123],{"class":406}," []), fill)\n",[371,1125,1126],{"class":329,"line":442},[371,1127,459],{"emptyLinePlaceholder":458},[371,1129,1130,1133,1135,1138,1140,1142,1144,1146,1148,1150,1152,1154,1156],{"class":329,"line":455},[371,1131,1132],{"class":406},"key_cols ",[371,1134,468],{"class":402},[371,1136,1137],{"class":406}," [",[371,1139,927],{"class":380},[371,1141,517],{"class":406},[371,1143,939],{"class":380},[371,1145,517],{"class":406},[371,1147,953],{"class":380},[371,1149,517],{"class":406},[371,1151,1039],{"class":380},[371,1153,517],{"class":406},[371,1155,978],{"class":380},[371,1157,1158],{"class":406},"]\n",[371,1160,1161,1164,1166,1169,1172,1174,1177],{"class":329,"line":462},[371,1162,1163],{"class":406},"dupes ",[371,1165,468],{"class":402},[371,1167,1168],{"class":406}," inventory[inventory.duplicated(key_cols, ",[371,1170,1171],{"class":565},"keep",[371,1173,468],{"class":402},[371,1175,1176],{"class":508},"False",[371,1178,1179],{"class":406},")]\n",[371,1181,1182,1184,1186,1189,1192,1195,1198],{"class":329,"line":474},[371,1183,1021],{"class":508},[371,1185,512],{"class":406},[371,1187,1188],{"class":508},"len",[371,1190,1191],{"class":406},"(dupes), ",[371,1193,1194],{"class":380},"\"rows share a key\"",[371,1196,1197],{"class":406},")          ",[371,1199,1200],{"class":596},"# 3 rows share a key\n",[10,1202,1203],{},"Colour scales, data bars and icon sets carry their settings in sub-objects rather than a formula; for those, add the relevant parts — the scale's colours, the icon set name and thresholds — to the key if you need to tell similar rules apart.",[20,1205,29,1211,29,1214,29,1217,29,1221,29,1228,29,1239,29,1245,29,1250,29,1255,29,1258,29,1263,29,1270,29,1276,29,1280,29,1284,29,1288,29,1291,29,1296,29,1303,29,1308,29,1311,29,1313,29,1317,29,1320,29,1323,29,1329,29,1333,29,1336,29,1339,29,1343,29,1346,29,1349,29,1355,29,1359],{"viewBox":1206,"role":23,"ariaLabelledBy":1207,"xmlns":27,"style":1210},"4 0 752 142",[1208,1209],"cl-flow-t","cl-flow-d","width:100%;max-width:752px;height:auto;display:block;margin:1.5rem auto;font-family:Inter,ui-sans-serif,system-ui,sans-serif",[31,1212,1213],{"id":1208},"Cleaning conditional formatting safely",[35,1215,1216],{"id":1209},"Load the workbook, write an inventory of every rule, decide which to keep by range, type or duplicate key, rebuild the rule list with only those, renumber priorities if wanted, save a copy and compare a new inventory with the old one.",[39,1218],{"x":154,"y":42,"width":1219,"height":1220,"fill":45},"752","142",[39,1222],{"x":48,"y":1223,"width":1224,"height":1225,"rx":1226,"fill":1227,"stroke":334,"style":335},"16.0","115.2","110.5","12","#f0f4ff",[1229,1230,1232],"g",{"transform":1231},"translate(65.6,37.8) scale(1.000)",[1233,1234],"path",{"d":1235,"fill":1236,"stroke":1237,"style":1238},"M11 4a7 7 0 1 0 .01 0z M16 16l5 5","none","var(--brand-strong,#4338ca)","stroke-width:1.80px;stroke-linecap:round;stroke-linejoin:round",[60,1240,1244],{"x":1241,"y":1242,"style":1243},"77.6","84.2","font-size:13.5px;font-weight:700;fill:var(--brand-strong,#4338ca);text-anchor:middle","Inventory",[60,1246,1249],{"x":1241,"y":1247,"style":1248},"103.8","font-size:11.5px;font-weight:400;fill:var(--text,#172033);text-anchor:middle","every sheet",[329,1251],{"x1":1252,"y1":1253,"x2":1254,"y2":1253,"stroke":334,"style":335},"140.2","71.2","162.2",[337,1256],{"points":1257,"fill":340},"166.2,71.2 157.2,76.2 157.2,66.2",[39,1259],{"x":1260,"y":1223,"width":1224,"height":1225,"rx":1226,"fill":1261,"stroke":1262,"style":335},"171.2","#fdefd8","var(--gold,#b4740a)",[1229,1264,1266],{"transform":1265},"translate(216.8,29.0) scale(1.000)",[1233,1267],{"d":1268,"fill":1236,"stroke":1269,"style":1238},"M3 5h18l-7 8v6l-4 2v-8z","var(--gold-ink,#7a4e06)",[60,1271,1275],{"x":1272,"y":1273,"style":1274},"228.8","75.5","font-size:13.5px;font-weight:700;fill:var(--gold-ink,#7a4e06);text-anchor:middle","Decide",[60,1277,1279],{"x":1272,"y":1278,"style":1248},"95.0","range, type,",[60,1281,1283],{"x":1272,"y":1282,"style":1248},"112.5","duplicate",[329,1285],{"x1":1286,"y1":1253,"x2":1287,"y2":1253,"stroke":334,"style":335},"291.4","313.4",[337,1289],{"points":1290,"fill":340},"317.4,71.2 308.4,76.2 308.4,66.2",[39,1292],{"x":1293,"y":1223,"width":1224,"height":1225,"rx":1226,"fill":1294,"stroke":1295,"style":335},"322.4","#d9f4f1","var(--teal,#0f9488)",[1229,1297,1299],{"transform":1298},"translate(368.0,29.0) scale(1.000)",[1233,1300],{"d":1301,"fill":1236,"stroke":1302,"style":1238},"M20 11a8 8 0 1 0-2.3 5.7 M20 4v7h-7","var(--teal-ink,#0b6157)",[60,1304,1307],{"x":1305,"y":1273,"style":1306},"380.0","font-size:13.5px;font-weight:700;fill:var(--teal-ink,#0b6157);text-anchor:middle","Rebuild list",[60,1309,1310],{"x":1305,"y":1278,"style":1248},"keep chosen",[60,1312,791],{"x":1305,"y":1282,"style":1248},[329,1314],{"x1":1315,"y1":1253,"x2":1316,"y2":1253,"stroke":334,"style":335},"442.6","464.6",[337,1318],{"points":1319,"fill":340},"468.6,71.2 459.6,76.2 459.6,66.2",[39,1321],{"x":1322,"y":1223,"width":1224,"height":1225,"rx":1226,"fill":1227,"stroke":334,"style":335},"473.6",[1229,1324,1326],{"transform":1325},"translate(519.2,29.0) scale(1.000)",[1233,1327],{"d":1328,"fill":1236,"stroke":1237,"style":1238},"M6 3h9l4 4v14H6z M15 3v4h4 M9.5 11.5l4.5 6 M14 11.5l-4.5 6",[60,1330,1332],{"x":1331,"y":1273,"style":1243},"531.2","Save a copy",[60,1334,1335],{"x":1331,"y":1278,"style":1248},"never overwrite",[60,1337,1338],{"x":1331,"y":1282,"style":1248},"first",[329,1340],{"x1":1341,"y1":1253,"x2":1342,"y2":1253,"stroke":334,"style":335},"593.8","615.8",[337,1344],{"points":1345,"fill":340},"619.8,71.2 610.8,76.2 610.8,66.2",[39,1347],{"x":1348,"y":1223,"width":1224,"height":1225,"rx":1226,"fill":1227,"stroke":334,"style":335},"624.8",[1229,1350,1352],{"transform":1351},"translate(670.4,37.8) scale(1.000)",[1233,1353],{"d":1354,"fill":1236,"stroke":1237,"style":1238},"M5 12.5l4.5 4.5L19 7",[60,1356,1358],{"x":1357,"y":1242,"style":1243},"682.4","Compare",[60,1360,1361],{"x":1357,"y":1247,"style":1248},"new inventory",[356,1363,1365],{"id":1364},"step-3-remove-rules-by-rebuilding-the-list","Step 3 — Remove rules by rebuilding the list",[10,1367,1368,1371,1372,1375,1376,1379],{},[368,1369,1370],{},"ConditionalFormattingList"," has an ",[368,1373,1374],{},"add"," method but no ",[368,1377,1378],{},"remove",". To delete rules, create a new list, add back only the rules you want to keep, and assign it to the sheet. A small function with a \"keep\" test covers every case:",[361,1381,1383],{"className":393,"code":1382,"language":395,"meta":366,"style":366},"def filter_rules(ws, keep):\n    old = ws.conditional_formatting\n    new = ConditionalFormattingList()\n    for cf in old:\n        for rule in cf.rules:\n            if keep(cf.sqref, rule):\n                new.add(str(cf.sqref), rule)\n    ws.conditional_formatting = new\n\nwb = load_workbook(\"report.xlsx\")\nws = wb[\"Sales\"]\n\nseen = set()\ndef keep_first_copy(sqref, rule):\n    key = rule_key(sqref, rule)\n    if key in seen:\n        return False\n    seen.add(key)\n    return True\n\nfilter_rules(ws, keep_first_copy)\nfilter_rules(ws, lambda sqref, rule: rule.type != \"dataBar\")       # drop data bars\nwb.save(\"report_clean.xlsx\")\nprint(rule_inventory(\"report_clean.xlsx\")[[\"range\", \"type\"]].values.tolist())\n# [['B2:B20', 'cellIs'], ['A2:B20', 'expression'], ['B2:B20', 'colorScale']]\n",[368,1384,1385,1395,1405,1415,1426,1436,1444,1454,1464,1468,1481,1495,1499,1512,1521,1531,1544,1552,1557,1565,1570,1576,1600,1610,1631],{"__ignoreMap":366},[371,1386,1387,1389,1392],{"class":329,"line":373},[371,1388,819],{"class":402},[371,1390,1391],{"class":822}," filter_rules",[371,1393,1394],{"class":406},"(ws, keep):\n",[371,1396,1397,1400,1402],{"class":329,"line":416},[371,1398,1399],{"class":406},"    old ",[371,1401,468],{"class":402},[371,1403,1404],{"class":406}," ws.conditional_formatting\n",[371,1406,1407,1410,1412],{"class":329,"line":429},[371,1408,1409],{"class":406},"    new ",[371,1411,468],{"class":402},[371,1413,1414],{"class":406}," ConditionalFormattingList()\n",[371,1416,1417,1419,1421,1423],{"class":329,"line":442},[371,1418,851],{"class":402},[371,1420,867],{"class":406},[371,1422,505],{"class":402},[371,1424,1425],{"class":406}," old:\n",[371,1427,1428,1430,1432,1434],{"class":329,"line":455},[371,1429,864],{"class":402},[371,1431,880],{"class":406},[371,1433,505],{"class":402},[371,1435,885],{"class":406},[371,1437,1438,1441],{"class":329,"line":462},[371,1439,1440],{"class":402},"            if",[371,1442,1443],{"class":406}," keep(cf.sqref, rule):\n",[371,1445,1446,1449,1451],{"class":329,"line":474},[371,1447,1448],{"class":406},"                new.add(",[371,1450,933],{"class":508},[371,1452,1453],{"class":406},"(cf.sqref), rule)\n",[371,1455,1456,1459,1461],{"class":329,"line":485},[371,1457,1458],{"class":406},"    ws.conditional_formatting ",[371,1460,468],{"class":402},[371,1462,1463],{"class":406}," new\n",[371,1465,1466],{"class":329,"line":496},[371,1467,459],{"emptyLinePlaceholder":458},[371,1469,1470,1472,1474,1477,1479],{"class":329,"line":526},[371,1471,465],{"class":406},[371,1473,468],{"class":402},[371,1475,1476],{"class":406}," load_workbook(",[371,1478,772],{"class":380},[371,1480,574],{"class":406},[371,1482,1483,1485,1487,1490,1493],{"class":329,"line":549},[371,1484,477],{"class":406},[371,1486,468],{"class":402},[371,1488,1489],{"class":406}," wb[",[371,1491,1492],{"class":380},"\"Sales\"",[371,1494,1158],{"class":406},[371,1496,1497],{"class":329,"line":577},[371,1498,459],{"emptyLinePlaceholder":458},[371,1500,1501,1504,1506,1509],{"class":329,"line":600},[371,1502,1503],{"class":406},"seen ",[371,1505,468],{"class":402},[371,1507,1508],{"class":508}," set",[371,1510,1511],{"class":406},"()\n",[371,1513,1514,1516,1519],{"class":329,"line":644},[371,1515,819],{"class":402},[371,1517,1518],{"class":822}," keep_first_copy",[371,1520,1079],{"class":406},[371,1522,1523,1526,1528],{"class":329,"line":673},[371,1524,1525],{"class":406},"    key ",[371,1527,468],{"class":402},[371,1529,1530],{"class":406}," rule_key(sqref, rule)\n",[371,1532,1533,1536,1539,1541],{"class":329,"line":704},[371,1534,1535],{"class":402},"    if",[371,1537,1538],{"class":406}," key ",[371,1540,505],{"class":402},[371,1542,1543],{"class":406}," seen:\n",[371,1545,1546,1549],{"class":329,"line":728},[371,1547,1548],{"class":402},"        return",[371,1550,1551],{"class":508}," False\n",[371,1553,1554],{"class":329,"line":766},[371,1555,1556],{"class":406},"    seen.add(key)\n",[371,1558,1560,1562],{"class":329,"line":1559},19,[371,1561,986],{"class":402},[371,1563,1564],{"class":508}," True\n",[371,1566,1568],{"class":329,"line":1567},20,[371,1569,459],{"emptyLinePlaceholder":458},[371,1571,1573],{"class":329,"line":1572},21,[371,1574,1575],{"class":406},"filter_rules(ws, keep_first_copy)\n",[371,1577,1579,1582,1585,1588,1591,1594,1597],{"class":329,"line":1578},22,[371,1580,1581],{"class":406},"filter_rules(ws, ",[371,1583,1584],{"class":402},"lambda",[371,1586,1587],{"class":406}," sqref, rule: rule.type ",[371,1589,1590],{"class":402},"!=",[371,1592,1593],{"class":380}," \"dataBar\"",[371,1595,1596],{"class":406},")       ",[371,1598,1599],{"class":596},"# drop data bars\n",[371,1601,1603,1605,1608],{"class":329,"line":1602},23,[371,1604,769],{"class":406},[371,1606,1607],{"class":380},"\"report_clean.xlsx\"",[371,1609,574],{"class":406},[371,1611,1613,1615,1618,1620,1623,1625,1627,1629],{"class":329,"line":1612},24,[371,1614,1021],{"class":508},[371,1616,1617],{"class":406},"(rule_inventory(",[371,1619,1607],{"class":380},[371,1621,1622],{"class":406},")[[",[371,1624,927],{"class":380},[371,1626,517],{"class":406},[371,1628,939],{"class":380},[371,1630,1042],{"class":406},[371,1632,1634],{"class":329,"line":1633},25,[371,1635,1636],{"class":596},"# [['B2:B20', 'cellIs'], ['A2:B20', 'expression'], ['B2:B20', 'colorScale']]\n",[10,1638,1639,1640,1643],{},"The kept rules keep their original priorities and formats — the ",[368,1641,1642],{},"dxf"," loaded with each rule is written back with it. Saving to a new file, as here, leaves the original untouched until the inventory confirms the result.",[356,1645,1647],{"id":1646},"step-4-remove-the-rules-that-touch-a-range","Step 4 — Remove the rules that touch a range",[10,1649,1650],{},"To clear formatting from a region — before rewriting a table, for example — drop every rule whose range overlaps it. openpyxl's range objects can test that for you:",[361,1652,1654],{"className":393,"code":1653,"language":395,"meta":366,"style":366},"from openpyxl.worksheet.cell_range import CellRange\n\ndef overlaps(sqref, target):\n    t = CellRange(target)\n    return any(not r.isdisjoint(t) for r in sqref.ranges)\n\nwb = load_workbook(\"report.xlsx\")\nws = wb[\"Sales\"]\nfilter_rules(ws, lambda sqref, rule: not overlaps(sqref, \"C1:C20\"))\nprint(sorted({str(cf.sqref) for cf in ws.conditional_formatting}))      # ['A2:B20', 'B2:B20']\n",[368,1655,1656,1668,1672,1682,1692,1716,1720,1732,1744,1763],{"__ignoreMap":366},[371,1657,1658,1660,1663,1665],{"class":329,"line":373},[371,1659,403],{"class":402},[371,1661,1662],{"class":406}," openpyxl.worksheet.cell_range ",[371,1664,410],{"class":402},[371,1666,1667],{"class":406}," CellRange\n",[371,1669,1670],{"class":329,"line":416},[371,1671,459],{"emptyLinePlaceholder":458},[371,1673,1674,1676,1679],{"class":329,"line":429},[371,1675,819],{"class":402},[371,1677,1678],{"class":822}," overlaps",[371,1680,1681],{"class":406},"(sqref, target):\n",[371,1683,1684,1687,1689],{"class":329,"line":442},[371,1685,1686],{"class":406},"    t ",[371,1688,468],{"class":402},[371,1690,1691],{"class":406}," CellRange(target)\n",[371,1693,1694,1696,1699,1701,1704,1707,1709,1711,1713],{"class":329,"line":455},[371,1695,986],{"class":402},[371,1697,1698],{"class":508}," any",[371,1700,512],{"class":406},[371,1702,1703],{"class":402},"not",[371,1705,1706],{"class":406}," r.isdisjoint(t) ",[371,1708,499],{"class":402},[371,1710,502],{"class":406},[371,1712,505],{"class":402},[371,1714,1715],{"class":406}," sqref.ranges)\n",[371,1717,1718],{"class":329,"line":462},[371,1719,459],{"emptyLinePlaceholder":458},[371,1721,1722,1724,1726,1728,1730],{"class":329,"line":474},[371,1723,465],{"class":406},[371,1725,468],{"class":402},[371,1727,1476],{"class":406},[371,1729,772],{"class":380},[371,1731,574],{"class":406},[371,1733,1734,1736,1738,1740,1742],{"class":329,"line":485},[371,1735,477],{"class":406},[371,1737,468],{"class":402},[371,1739,1489],{"class":406},[371,1741,1492],{"class":380},[371,1743,1158],{"class":406},[371,1745,1746,1748,1750,1753,1755,1758,1761],{"class":329,"line":496},[371,1747,1581],{"class":406},[371,1749,1584],{"class":402},[371,1751,1752],{"class":406}," sqref, rule: ",[371,1754,1703],{"class":402},[371,1756,1757],{"class":406}," overlaps(sqref, ",[371,1759,1760],{"class":380},"\"C1:C20\"",[371,1762,725],{"class":406},[371,1764,1765,1767,1769,1772,1775,1777,1780,1782,1784,1786,1789],{"class":329,"line":526},[371,1766,1021],{"class":508},[371,1768,512],{"class":406},[371,1770,1771],{"class":508},"sorted",[371,1773,1774],{"class":406},"({",[371,1776,933],{"class":508},[371,1778,1779],{"class":406},"(cf.sqref) ",[371,1781,499],{"class":402},[371,1783,867],{"class":406},[371,1785,505],{"class":402},[371,1787,1788],{"class":406}," ws.conditional_formatting}))      ",[371,1790,1791],{"class":596},"# ['A2:B20', 'B2:B20']\n",[10,1793,1794,1795,1798],{},"This removes the whole rule even if it also covers cells outside the target, which is usually what you want: a rule half-applied to a rewritten table is more confusing than none. To clear a sheet completely, skip the function and assign an empty ",[368,1796,1797],{},"ConditionalFormattingList()",".",[356,1800,1802],{"id":1801},"step-5-renumber-priorities","Step 5 — Renumber priorities",[10,1804,1805,1806,1808],{},"After removals, priorities have gaps — 1, 4, 5 — which Excel accepts. If a script is about to add new rules and you want predictable ordering, renumber the kept ones by resetting their priority to 0 before re-adding; ",[368,1807,1374],{}," treats 0 as unset and assigns 1, 2, 3 in order:",[361,1810,1812],{"className":393,"code":1811,"language":395,"meta":366,"style":366},"wb = load_workbook(\"report_clean.xlsx\")\nws = wb[\"Sales\"]\nordered = sorted(((cf.sqref, r) for cf in ws.conditional_formatting for r in cf.rules),\n                 key=lambda pair: pair[1].priority)\nws.conditional_formatting = ConditionalFormattingList()\nfor sqref, rule in ordered:\n    rule.priority = 0                   # 0 tells add() to assign the next number\n    ws.conditional_formatting.add(str(sqref), rule)\nprint(sorted((r.priority, r.type) for cf in ws.conditional_formatting for r in cf.rules))\n# [(1, 'cellIs'), (2, 'expression'), (3, 'colorScale')]\n",[368,1813,1814,1826,1838,1869,1885,1894,1906,1919,1928,1956],{"__ignoreMap":366},[371,1815,1816,1818,1820,1822,1824],{"class":329,"line":373},[371,1817,465],{"class":406},[371,1819,468],{"class":402},[371,1821,1476],{"class":406},[371,1823,1607],{"class":380},[371,1825,574],{"class":406},[371,1827,1828,1830,1832,1834,1836],{"class":329,"line":416},[371,1829,477],{"class":406},[371,1831,468],{"class":402},[371,1833,1489],{"class":406},[371,1835,1492],{"class":380},[371,1837,1158],{"class":406},[371,1839,1840,1843,1845,1848,1851,1853,1855,1857,1860,1862,1864,1866],{"class":329,"line":429},[371,1841,1842],{"class":406},"ordered ",[371,1844,468],{"class":402},[371,1846,1847],{"class":508}," sorted",[371,1849,1850],{"class":406},"(((cf.sqref, r) ",[371,1852,499],{"class":402},[371,1854,867],{"class":406},[371,1856,505],{"class":402},[371,1858,1859],{"class":406}," ws.conditional_formatting ",[371,1861,499],{"class":402},[371,1863,502],{"class":406},[371,1865,505],{"class":402},[371,1867,1868],{"class":406}," cf.rules),\n",[371,1870,1871,1874,1877,1880,1882],{"class":329,"line":442},[371,1872,1873],{"class":565},"                 key",[371,1875,1876],{"class":402},"=lambda",[371,1878,1879],{"class":406}," pair: pair[",[371,1881,90],{"class":508},[371,1883,1884],{"class":406},"].priority)\n",[371,1886,1887,1890,1892],{"class":329,"line":455},[371,1888,1889],{"class":406},"ws.conditional_formatting ",[371,1891,468],{"class":402},[371,1893,1414],{"class":406},[371,1895,1896,1898,1901,1903],{"class":329,"line":462},[371,1897,499],{"class":402},[371,1899,1900],{"class":406}," sqref, rule ",[371,1902,505],{"class":402},[371,1904,1905],{"class":406}," ordered:\n",[371,1907,1908,1911,1913,1916],{"class":329,"line":474},[371,1909,1910],{"class":406},"    rule.priority ",[371,1912,468],{"class":402},[371,1914,1915],{"class":508}," 0",[371,1917,1918],{"class":596},"                   # 0 tells add() to assign the next number\n",[371,1920,1921,1923,1925],{"class":329,"line":485},[371,1922,603],{"class":406},[371,1924,933],{"class":508},[371,1926,1927],{"class":406},"(sqref), rule)\n",[371,1929,1930,1932,1934,1936,1939,1941,1943,1945,1947,1949,1951,1953],{"class":329,"line":496},[371,1931,1021],{"class":508},[371,1933,512],{"class":406},[371,1935,1771],{"class":508},[371,1937,1938],{"class":406},"((r.priority, r.type) ",[371,1940,499],{"class":402},[371,1942,867],{"class":406},[371,1944,505],{"class":402},[371,1946,1859],{"class":406},[371,1948,499],{"class":402},[371,1950,502],{"class":406},[371,1952,505],{"class":402},[371,1954,1955],{"class":406}," cf.rules))\n",[371,1957,1958],{"class":329,"line":526},[371,1959,1960],{"class":596},"# [(1, 'cellIs'), (2, 'expression'), (3, 'colorScale')]\n",[10,1962,1963,1964,1967,1968,1798],{},"Sorting by the old priority first keeps the evaluation order the same, so nothing changes visually; only the numbers are tidied. How priorities and ",[368,1965,1966],{},"stopIfTrue"," interact is shown in ",[14,1969,1971],{"href":1970},"\u002Fadvanced-data-transformation-and-cleaning\u002Fapplying-conditional-formatting-with-openpyxl\u002Fhighlight-overdue-dates-with-openpyxl\u002F","Highlight Overdue Dates in Excel with openpyxl",[20,1973,29,1978,29,1981,29,1984,29,1987,29,1992,29,1998,29,2003,29,2007,29,2012,29,2018,29,2022,29,2027,29,2031,29,2036,29,2040,29,2045,29,2048,29,2054,29,2059,29,2063,29,2067,29,2074,29,2077,29,2082,29,2085,29,2090,29,2093],{"viewBox":1974,"role":23,"ariaLabelledBy":1975,"xmlns":27,"style":1210},"4 0 752 233",[1976,1977],"cl-readable-t","cl-readable-d",[31,1979,1980],{"id":1976},"What openpyxl can and cannot see",[35,1982,1983],{"id":1977},"openpyxl reads and writes the classic rule types — cell comparisons, formulas, colour scales, standard data bars and the built-in icon sets. Rules stored in Excel's later extension format, such as data bars with negative-value styling or newer icon sets, are not loaded, so they neither appear in the inventory nor survive a save.",[39,1985],{"x":154,"y":42,"width":1219,"height":1986,"fill":45},"233",[39,1988],{"x":48,"y":1223,"width":1989,"height":1990,"rx":1991,"fill":1294,"stroke":1295,"style":335},"351.0","201.0","14",[1229,1993,1995],{"transform":1994},"translate(182.5,29.0) scale(1.083)",[1233,1996],{"d":1354,"fill":1236,"stroke":1302,"style":1997},"stroke-width:1.66px;stroke-linecap:round;stroke-linejoin:round",[60,1999,2002],{"x":76,"y":2000,"style":2001},"78.0","font-size:14px;font-weight:700;fill:var(--teal-ink,#0b6157);text-anchor:middle","Read and kept",[329,2004],{"x1":88,"y1":2005,"x2":2006,"y2":2005,"stroke":1295,"style":54},"91.0","355.0",[60,2008,2011],{"x":2009,"y":112,"style":2010},"60.0","font-size:12px;font-weight:400;fill:var(--text,#172033);text-anchor:start","cellIs and expression rules",[1229,2013,2015],{"transform":2014},"translate(38.5,99.5) scale(0.625)",[1233,2016],{"d":1354,"fill":1236,"stroke":1295,"style":2017},"stroke-width:2.88px;stroke-linecap:round;stroke-linejoin:round",[60,2019,2021],{"x":2009,"y":2020,"style":2010},"137.0","colour scales",[1229,2023,2025],{"transform":2024},"translate(38.5,125.5) scale(0.625)",[1233,2026],{"d":1354,"fill":1236,"stroke":1295,"style":2017},[60,2028,2030],{"x":2009,"y":2029,"style":2010},"163.0","standard data bars",[1229,2032,2034],{"transform":2033},"translate(38.5,151.5) scale(0.625)",[1233,2035],{"d":1354,"fill":1236,"stroke":1295,"style":2017},[60,2037,2039],{"x":2009,"y":2038,"style":2010},"189.0","built-in icon sets",[1229,2041,2043],{"transform":2042},"translate(38.5,177.5) scale(0.625)",[1233,2044],{"d":1354,"fill":1236,"stroke":1295,"style":2017},[39,2046],{"x":2047,"y":1223,"width":1989,"height":1990,"rx":1991,"fill":1261,"stroke":1262,"style":335},"389.0",[1229,2049,2051],{"transform":2050},"translate(551.5,29.0) scale(1.083)",[1233,2052],{"d":2053,"fill":1236,"stroke":1269,"style":1997},"M12 3.5l9.5 17h-19z M12 10v5 M12 17.8v.4",[60,2055,2058],{"x":2056,"y":2000,"style":2057},"564.5","font-size:14px;font-weight:700;fill:var(--gold-ink,#7a4e06);text-anchor:middle","Not read, dropped on save",[329,2060],{"x1":2061,"y1":2005,"x2":2062,"y2":2005,"stroke":1262,"style":54},"405.0","724.0",[60,2064,2066],{"x":2065,"y":112,"style":2010},"429.0","extension data bar settings",[1229,2068,2070],{"transform":2069},"translate(407.5,99.5) scale(0.625)",[1233,2071],{"d":2072,"fill":1236,"stroke":2073,"style":2017},"M6 6l12 12 M18 6L6 18","var(--accent,#f43f8f)",[60,2075,2076],{"x":2065,"y":2020,"style":2010},"newer icon sets",[1229,2078,2080],{"transform":2079},"translate(407.5,125.5) scale(0.625)",[1233,2081],{"d":2072,"fill":1236,"stroke":2073,"style":2017},[60,2083,2084],{"x":2065,"y":2029,"style":2010},"rules stored only in extensions",[1229,2086,2088],{"transform":2087},"translate(407.5,151.5) scale(0.625)",[1233,2089],{"d":2072,"fill":1236,"stroke":2073,"style":2017},[60,2091,2092],{"x":2065,"y":2038,"style":2010},"check in Excel afterwards",[1229,2094,2096],{"transform":2095},"translate(407.5,177.5) scale(0.625)",[1233,2097],{"d":2053,"fill":1236,"stroke":1262,"style":2017},[356,2099,2101],{"id":2100},"step-6-stop-the-duplicates-at-the-source","Step 6 — Stop the duplicates at the source",[10,2103,2104],{},"Cleaning a file once does not help if the script that created the clutter runs again tomorrow. Make scripts that edit existing workbooks idempotent: before adding its rules, a script removes any rule on the ranges it owns, then adds its current set. Running it once or fifty times leaves the same rules behind:",[361,2106,2108],{"className":393,"code":2107,"language":395,"meta":366,"style":366},"def set_rules(ws, target, rules):\n    filter_rules(ws, lambda sqref, rule: not overlaps(sqref, target))\n    for rule in rules:\n        ws.conditional_formatting.add(target, rule)\n\nwb = load_workbook(\"report_clean.xlsx\")\nws = wb[\"Sales\"]\nfor _ in range(3):                                   # three runs of the same script\n    set_rules(ws, \"B2:B20\", [CellIsRule(operator=\"greaterThan\", formula=[\"150\"], fill=red)])\nprint(sum(len(cf.rules) for cf in ws.conditional_formatting))   # 1\n",[368,2109,2110,2120,2134,2145,2150,2154,2166,2178,2197,2232],{"__ignoreMap":366},[371,2111,2112,2114,2117],{"class":329,"line":373},[371,2113,819],{"class":402},[371,2115,2116],{"class":822}," set_rules",[371,2118,2119],{"class":406},"(ws, target, rules):\n",[371,2121,2122,2125,2127,2129,2131],{"class":329,"line":416},[371,2123,2124],{"class":406},"    filter_rules(ws, ",[371,2126,1584],{"class":402},[371,2128,1752],{"class":406},[371,2130,1703],{"class":402},[371,2132,2133],{"class":406}," overlaps(sqref, target))\n",[371,2135,2136,2138,2140,2142],{"class":329,"line":429},[371,2137,851],{"class":402},[371,2139,880],{"class":406},[371,2141,505],{"class":402},[371,2143,2144],{"class":406}," rules:\n",[371,2146,2147],{"class":329,"line":442},[371,2148,2149],{"class":406},"        ws.conditional_formatting.add(target, rule)\n",[371,2151,2152],{"class":329,"line":455},[371,2153,459],{"emptyLinePlaceholder":458},[371,2155,2156,2158,2160,2162,2164],{"class":329,"line":462},[371,2157,465],{"class":406},[371,2159,468],{"class":402},[371,2161,1476],{"class":406},[371,2163,1607],{"class":380},[371,2165,574],{"class":406},[371,2167,2168,2170,2172,2174,2176],{"class":329,"line":474},[371,2169,477],{"class":406},[371,2171,468],{"class":402},[371,2173,1489],{"class":406},[371,2175,1492],{"class":380},[371,2177,1158],{"class":406},[371,2179,2180,2182,2184,2186,2188,2190,2192,2194],{"class":329,"line":485},[371,2181,499],{"class":402},[371,2183,582],{"class":406},[371,2185,505],{"class":402},[371,2187,509],{"class":508},[371,2189,512],{"class":406},[371,2191,41],{"class":508},[371,2193,593],{"class":406},[371,2195,2196],{"class":596},"# three runs of the same script\n",[371,2198,2199,2202,2204,2207,2209,2211,2213,2215,2217,2219,2221,2223,2225,2227,2229],{"class":329,"line":496},[371,2200,2201],{"class":406},"    set_rules(ws, ",[371,2203,606],{"class":380},[371,2205,2206],{"class":406},", [CellIsRule(",[371,2208,612],{"class":565},[371,2210,468],{"class":402},[371,2212,617],{"class":380},[371,2214,517],{"class":406},[371,2216,622],{"class":565},[371,2218,468],{"class":402},[371,2220,627],{"class":406},[371,2222,630],{"class":380},[371,2224,633],{"class":406},[371,2226,636],{"class":565},[371,2228,468],{"class":402},[371,2230,2231],{"class":406},"red)])\n",[371,2233,2234,2236,2238,2241,2243,2245,2248,2250,2252,2254,2257],{"class":329,"line":526},[371,2235,1021],{"class":508},[371,2237,512],{"class":406},[371,2239,2240],{"class":508},"sum",[371,2242,512],{"class":406},[371,2244,1188],{"class":508},[371,2246,2247],{"class":406},"(cf.rules) ",[371,2249,499],{"class":402},[371,2251,867],{"class":406},[371,2253,505],{"class":402},[371,2255,2256],{"class":406}," ws.conditional_formatting))   ",[371,2258,2259],{"class":596},"# 1\n",[10,2261,2262],{},"After three runs there is exactly one rule, not three. Note what else went: the colour scale on B2:B20 and the formula rule on A2:B20 both touched the target, so both were removed on the first run. That is the trade-off of range ownership: a script clears everything touching its range, so give each script its own columns or sheet, and keep rules that span several owners in one place. Adding the inventory from Step 1 to the script's test run shows at once whether a change removed more than intended.",[356,2264,2266],{"id":2265},"common-pitfalls","Common pitfalls",[2268,2269,2270,2282,2288],"ul",{},[2271,2272,2273,2277,2278,1798],"li",{},[2274,2275,2276],"strong",{},"Assuming the inventory is complete."," Rules stored in Excel's extension format are invisible to openpyxl and are dropped when it saves. For workbooks built in recent Excel versions, check the cleaned file in Excel; see ",[14,2279,2281],{"href":2280},"\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",[2271,2283,2284,2287],{},[2274,2285,2286],{},"Deduplicating on the formula alone."," Two rules with the same formula but different fills are different rules. Include the format in the key.",[2271,2289,2290,2293],{},[2274,2291,2292],{},"Fixing the symptom only."," If a script created the duplicates, clean the file and change the script to clear its own rules before adding them.",[356,2295,2297],{"id":2296},"conclusion","Conclusion",[10,2299,2300,2301,2303,2304,2306],{},"openpyxl exposes every classic conditional formatting rule through ",[368,2302,783],{},": iterate it into an inventory of ranges, types, priorities, formulas and fills. There is no delete method, so remove rules by building a new ",[368,2305,1370],{}," with the ones you keep — filtering by duplicate key, type or overlapping range — and assign it back. Renumber priorities in their old order if you need tidy numbers, save to a copy, and compare inventories before replacing the original.",[356,2308,2310],{"id":2309},"frequently-asked-questions","Frequently asked questions",[10,2312,2313,2316],{},[2274,2314,2315],{},"How do I list all conditional formatting rules with openpyxl?","\nIterate ws.conditional_formatting. Each item has an sqref (the range) and a rules list; each rule has type, priority, operator, formula and a dxf with its fill and font.",[10,2318,2319,2322],{},[2274,2320,2321],{},"How do I delete a conditional formatting rule with openpyxl?","\nopenpyxl has no remove method, so build a new ConditionalFormattingList, add back only the rules you want to keep, and assign it to ws.conditional_formatting before saving.",[10,2324,2325,2328],{},[2274,2326,2327],{},"How do I remove all conditional formatting from a sheet?","\nAssign an empty ConditionalFormattingList to ws.conditional_formatting and save the workbook.",[10,2330,2331,2334],{},[2274,2332,2333],{},"Why do I have the same rule many times?","\nA script that opens an existing workbook and adds a rule adds another copy each time it runs. List the rules, drop exact duplicates, and change the script to clear its own rules before adding them.",[356,2336,2338],{"id":2337},"related","Related",[2268,2340,2341,2347,2354,2361],{},[2271,2342,2343,2344,2346],{},"Up one level: ",[14,2345,17],{"href":16}," — rules that follow the data.",[2271,2348,2349,2353],{},[14,2350,2352],{"href":2351},"\u002Fadvanced-data-transformation-and-cleaning\u002Fapplying-conditional-formatting-with-openpyxl\u002Fopenpyxl-apply-conditional-formatting-to-range\u002F","openpyxl: Apply Conditional Formatting to a Range"," — adding rules in the first place.",[2271,2355,2356,2360],{},[14,2357,2359],{"href":2358},"\u002Fadvanced-data-transformation-and-cleaning\u002Fapplying-conditional-formatting-with-openpyxl\u002Fadd-icon-sets-with-openpyxl\u002F","Add Icon Sets to Excel Cells with openpyxl"," — icon rules and their thresholds.",[2271,2362,2363,2367],{},[14,2364,2366],{"href":2365},"\u002Fadvanced-data-transformation-and-cleaning\u002Fapplying-conditional-formatting-with-openpyxl\u002Fhighlight-duplicate-values-in-excel-with-openpyxl\u002F","Highlight Duplicate Values in Excel with openpyxl"," — a rule type worth auditing.",[2369,2370,2371],"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 .sP0c6, html code.shiki .sP0c6{--shiki-default:#005CC5;--shiki-dark:#91CBFF}html pre.shiki code .sa561, html code.shiki .sa561{--shiki-default:#E36209;--shiki-dark:#FFB757}html pre.shiki code .s-wDw, html code.shiki .s-wDw{--shiki-default:#6A737D;--shiki-dark:#BDC4CC}html pre.shiki code .s_Opv, html code.shiki .s_Opv{--shiki-default:#6F42C1;--shiki-dark:#DBB7FF}",{"title":366,"searchDepth":416,"depth":416,"links":2373},[2374,2375,2376,2377,2378,2379,2380,2381,2382,2383,2384],{"id":358,"depth":416,"text":359},{"id":777,"depth":416,"text":778},{"id":1060,"depth":416,"text":1061},{"id":1364,"depth":416,"text":1365},{"id":1646,"depth":416,"text":1647},{"id":1801,"depth":416,"text":1802},{"id":2100,"depth":416,"text":2101},{"id":2265,"depth":416,"text":2266},{"id":2296,"depth":416,"text":2297},{"id":2309,"depth":416,"text":2310},{"id":2337,"depth":416,"text":2338},"2026-09-23","See every conditional formatting rule in a workbook — range, type, priority, formula and fill — as a table, then remove rules by range, by type or all at once, collapse duplicates that pile up when scripts rerun, and renumber priorities, all with openpyxl.","md",[2389,2391,2393,2395],{"q":2315,"a":2390},"Iterate ws.conditional_formatting. Each item has an sqref (the range) and a rules list; each rule has type, priority, operator, formula and a dxf with its fill and font.",{"q":2321,"a":2392},"openpyxl has no remove method, so build a new ConditionalFormattingList, add back only the rules you want to keep, and assign it to ws.conditional_formatting before saving.",{"q":2327,"a":2394},"Assign an empty ConditionalFormattingList to ws.conditional_formatting and save the workbook.",{"q":2333,"a":2396},"A script that opens an existing workbook and adds a rule adds another copy each time it runs. List the rules, drop exact duplicates, and change the script to clear its own rules before adding them.","list and remove conditional formatting with openpyxl",null,{"breadcrumb":2400},[2401,2404,2407],{"name":2402,"item":2403},"Home","\u002F",{"name":2405,"item":2406},"Advanced Data Transformation and Cleaning for Excel Automation","\u002Fadvanced-data-transformation-and-cleaning\u002F",{"name":2408,"item":16},"Applying Conditional Formatting With openpyxl","\u002Fadvanced-data-transformation-and-cleaning\u002Fapplying-conditional-formatting-with-openpyxl\u002Flist-and-remove-conditional-formatting-with-openpyxl",{"title":5,"description":2411},"Inventory conditional formatting rules with openpyxl across sheets, delete rules for a range or cell, remove duplicate rules added by repeated runs, clear a sheet's rules, keep priorities in order and know which Excel rules openpyxl cannot read.","list-and-remove-conditional-formatting-with-openpyxl","advanced-data-transformation-and-cleaning\u002Fapplying-conditional-formatting-with-openpyxl\u002Flist-and-remove-conditional-formatting-with-openpyxl\u002Findex",[2415,2416],"conditional-formatting","openpyxl","how-to","YoPqnB_0ZZfTghfrFXbwVw6x83tWG4GP98jEo6SuKlk",[2420,2424],{"title":2421,"path":2422,"stem":2423,"children":-1},"Highlight Weekends and Holidays in a Date Column","\u002Fadvanced-data-transformation-and-cleaning\u002Fapplying-conditional-formatting-with-openpyxl\u002Fhighlight-weekends-and-holidays-in-a-date-column","advanced-data-transformation-and-cleaning\u002Fapplying-conditional-formatting-with-openpyxl\u002Fhighlight-weekends-and-holidays-in-a-date-column\u002Findex",{"title":2425,"path":2426,"stem":2427,"children":-1},"Apply Conditional Formatting to a Range in openpyxl","\u002Fadvanced-data-transformation-and-cleaning\u002Fapplying-conditional-formatting-with-openpyxl\u002Fopenpyxl-apply-conditional-formatting-to-range","advanced-data-transformation-and-cleaning\u002Fapplying-conditional-formatting-with-openpyxl\u002Fopenpyxl-apply-conditional-formatting-to-range\u002Findex",[2429,2431],{"path":2430,"title":2408},"\u002Fadvanced-data-transformation-and-cleaning\u002Fapplying-conditional-formatting-with-openpyxl",{"path":2432,"title":2405},"\u002Fadvanced-data-transformation-and-cleaning",[],[2435,2438,2441,2443,2446,2449],{"path":2436,"title":2437,"kind":2417},"\u002Fformatting-and-charting-excel-reports-with-python\u002Fbuilding-excel-reports-with-xlsxwriter\u002Fapply-conditional-formatting-with-xlsxwriter","Apply Conditional Formatting with xlsxwriter",{"path":2439,"title":2440,"kind":2417},"\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":2442,"title":2359,"kind":2417},"\u002Fadvanced-data-transformation-and-cleaning\u002Fapplying-conditional-formatting-with-openpyxl\u002Fadd-icon-sets-with-openpyxl",{"path":2444,"title":2445,"kind":2417},"\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":2447,"title":2448,"kind":2417},"\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":2450,"title":2451,"kind":2417},"\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",1790972078411]