[{"data":1,"prerenderedAt":2494},["ShallowReactive",2],{"doc:\u002Fformatting-and-charting-excel-reports-with-python\u002Fstyling-excel-cells-with-openpyxl\u002Fapply-gradient-and-pattern-fills-with-openpyxl":3,"surround:\u002Fformatting-and-charting-excel-reports-with-python\u002Fstyling-excel-cells-with-openpyxl\u002Fapply-gradient-and-pattern-fills-with-openpyxl":2460,"ancestors:\u002Fformatting-and-charting-excel-reports-with-python\u002Fstyling-excel-cells-with-openpyxl\u002Fapply-gradient-and-pattern-fills-with-openpyxl":2469,"children:\u002Fformatting-and-charting-excel-reports-with-python\u002Fstyling-excel-cells-with-openpyxl\u002Fapply-gradient-and-pattern-fills-with-openpyxl":2474,"related:\u002Fformatting-and-charting-excel-reports-with-python\u002Fstyling-excel-cells-with-openpyxl\u002Fapply-gradient-and-pattern-fills-with-openpyxl":2475},{"id":4,"title":5,"body":6,"dateModified":2427,"datePublished":2427,"description":2428,"extension":2429,"faq":2430,"keyword":2439,"kind":2440,"meta":2441,"navigation":126,"path":2449,"seo":2450,"slug":2453,"stem":2454,"topics":2455,"type":2458,"__hash__":2459},"docs\u002Fformatting-and-charting-excel-reports-with-python\u002Fstyling-excel-cells-with-openpyxl\u002Fapply-gradient-and-pattern-fills-with-openpyxl\u002Findex.md","Apply Gradient and Pattern Fills with openpyxl",{"type":7,"value":8,"toc":2414},"minimark",[9,37,42,70,81,85,405,449,587,591,600,754,778,782,795,1087,1099,1232,1236,1246,1477,1496,1500,1605,1619,1623,1626,2067,2078,2256,2260,2327,2331,2349,2353,2359,2365,2371,2377,2381,2410],[10,11,12,13,17,18,21,22,26,27,30,31,36],"p",{},"Cell fills carry a lot of a report's meaning — header bands, input cells shaded differently from formulas, a hatched pattern for \"not applicable\", a gradient bar in a title. openpyxl supports all of Excel's fill types through two classes, ",[14,15,16],"code",{},"PatternFill"," and ",[14,19,20],{},"GradientFill",", and almost every problem people hit comes from one detail: which of the two colours a fill actually paints. A solid fill uses the ",[23,24,25],"em",{},"foreground"," colour, which is counter-intuitive enough that a fill set with only ",[14,28,29],{},"bgColor"," comes out black. This page goes through solid, pattern and gradient fills, fills inside conditional formats, and clearing fills, and checks the result by rendering the sheet rather than trusting the code. It belongs to ",[32,33,35],"a",{"href":34},"\u002Fformatting-and-charting-excel-reports-with-python\u002Fstyling-excel-cells-with-openpyxl\u002F","Styling Excel Cells with openpyxl",".",[38,39,41],"h2",{"id":40},"prerequisites","Prerequisites",[43,44,49],"pre",{"className":45,"code":46,"language":47,"meta":48,"style":48},"language-bash shiki shiki-themes github-light github-dark-high-contrast","pip install openpyxl pillow\n","bash","",[14,50,51],{"__ignoreMap":48},[52,53,56,60,64,67],"span",{"class":54,"line":55},"line",1,[52,57,59],{"class":58},"sMTad","pip",[52,61,63],{"class":62},"srMev"," install",[52,65,66],{"class":62}," openpyxl",[52,68,69],{"class":62}," pillow\n",[10,71,72,73,76,77,80],{},"LibreOffice (",[14,74,75],{},"soffice",") and ",[14,78,79],{},"pdftoppm"," (from Poppler) are used in Step 6 to render the sheet and sample the colours; they are optional.",[38,82,84],{"id":83},"step-1-solid-fills-use-fgcolor","Step 1 — Solid fills use fgColor",[43,86,90],{"className":87,"code":88,"language":89,"meta":48,"style":48},"language-python shiki shiki-themes github-light github-dark-high-contrast","from openpyxl import Workbook\nfrom openpyxl.styles import PatternFill, Font\n\nwb = Workbook()\nws = wb.active\nws.title = \"Fills\"\nws.column_dimensions[\"A\"].width = 26\nws.column_dimensions[\"B\"].width = 34\nfor r in range(1, 9):\n    ws.row_dimensions[r].height = 30\n\nws[\"A1\"], ws[\"B1\"] = \"solid, fgColor\", 'PatternFill(\"solid\", fgColor=\"4338CA\")'\nws[\"A1\"].fill = PatternFill(\"solid\", fgColor=\"4338CA\")\nws[\"A1\"].font = Font(color=\"FFFFFF\", bold=True)\nws[\"A2\"], ws[\"B2\"] = \"solid, bgColor only\", 'PatternFill(\"solid\", bgColor=\"4338CA\")'\nws[\"A2\"].fill = PatternFill(\"solid\", bgColor=\"4338CA\")\nprint(ws[\"A2\"].fill.fgColor.rgb, ws[\"A2\"].fill.bgColor.rgb)\n","python",[14,91,92,108,121,128,140,151,162,180,195,225,236,241,269,301,336,361,386],{"__ignoreMap":48},[52,93,94,98,102,105],{"class":54,"line":55},[52,95,97],{"class":96},"s-kum","from",[52,99,101],{"class":100},"skGVy"," openpyxl ",[52,103,104],{"class":96},"import",[52,106,107],{"class":100}," Workbook\n",[52,109,111,113,116,118],{"class":54,"line":110},2,[52,112,97],{"class":96},[52,114,115],{"class":100}," openpyxl.styles ",[52,117,104],{"class":96},[52,119,120],{"class":100}," PatternFill, Font\n",[52,122,124],{"class":54,"line":123},3,[52,125,127],{"emptyLinePlaceholder":126},true,"\n",[52,129,131,134,137],{"class":54,"line":130},4,[52,132,133],{"class":100},"wb ",[52,135,136],{"class":96},"=",[52,138,139],{"class":100}," Workbook()\n",[52,141,143,146,148],{"class":54,"line":142},5,[52,144,145],{"class":100},"ws ",[52,147,136],{"class":96},[52,149,150],{"class":100}," wb.active\n",[52,152,154,157,159],{"class":54,"line":153},6,[52,155,156],{"class":100},"ws.title ",[52,158,136],{"class":96},[52,160,161],{"class":62}," \"Fills\"\n",[52,163,165,168,171,174,176],{"class":54,"line":164},7,[52,166,167],{"class":100},"ws.column_dimensions[",[52,169,170],{"class":62},"\"A\"",[52,172,173],{"class":100},"].width ",[52,175,136],{"class":96},[52,177,179],{"class":178},"sP0c6"," 26\n",[52,181,183,185,188,190,192],{"class":54,"line":182},8,[52,184,167],{"class":100},[52,186,187],{"class":62},"\"B\"",[52,189,173],{"class":100},[52,191,136],{"class":96},[52,193,194],{"class":178}," 34\n",[52,196,198,201,204,207,210,213,216,219,222],{"class":54,"line":197},9,[52,199,200],{"class":96},"for",[52,202,203],{"class":100}," r ",[52,205,206],{"class":96},"in",[52,208,209],{"class":178}," range",[52,211,212],{"class":100},"(",[52,214,215],{"class":178},"1",[52,217,218],{"class":100},", ",[52,220,221],{"class":178},"9",[52,223,224],{"class":100},"):\n",[52,226,228,231,233],{"class":54,"line":227},10,[52,229,230],{"class":100},"    ws.row_dimensions[r].height ",[52,232,136],{"class":96},[52,234,235],{"class":178}," 30\n",[52,237,239],{"class":54,"line":238},11,[52,240,127],{"emptyLinePlaceholder":126},[52,242,244,247,250,253,256,259,261,264,266],{"class":54,"line":243},12,[52,245,246],{"class":100},"ws[",[52,248,249],{"class":62},"\"A1\"",[52,251,252],{"class":100},"], ws[",[52,254,255],{"class":62},"\"B1\"",[52,257,258],{"class":100},"] ",[52,260,136],{"class":96},[52,262,263],{"class":62}," \"solid, fgColor\"",[52,265,218],{"class":100},[52,267,268],{"class":62},"'PatternFill(\"solid\", fgColor=\"4338CA\")'\n",[52,270,272,274,276,279,281,284,287,289,293,295,298],{"class":54,"line":271},13,[52,273,246],{"class":100},[52,275,249],{"class":62},[52,277,278],{"class":100},"].fill ",[52,280,136],{"class":96},[52,282,283],{"class":100}," PatternFill(",[52,285,286],{"class":62},"\"solid\"",[52,288,218],{"class":100},[52,290,292],{"class":291},"sa561","fgColor",[52,294,136],{"class":96},[52,296,297],{"class":62},"\"4338CA\"",[52,299,300],{"class":100},")\n",[52,302,304,306,308,311,313,316,319,321,324,326,329,331,334],{"class":54,"line":303},14,[52,305,246],{"class":100},[52,307,249],{"class":62},[52,309,310],{"class":100},"].font ",[52,312,136],{"class":96},[52,314,315],{"class":100}," Font(",[52,317,318],{"class":291},"color",[52,320,136],{"class":96},[52,322,323],{"class":62},"\"FFFFFF\"",[52,325,218],{"class":100},[52,327,328],{"class":291},"bold",[52,330,136],{"class":96},[52,332,333],{"class":178},"True",[52,335,300],{"class":100},[52,337,339,341,344,346,349,351,353,356,358],{"class":54,"line":338},15,[52,340,246],{"class":100},[52,342,343],{"class":62},"\"A2\"",[52,345,252],{"class":100},[52,347,348],{"class":62},"\"B2\"",[52,350,258],{"class":100},[52,352,136],{"class":96},[52,354,355],{"class":62}," \"solid, bgColor only\"",[52,357,218],{"class":100},[52,359,360],{"class":62},"'PatternFill(\"solid\", bgColor=\"4338CA\")'\n",[52,362,364,366,368,370,372,374,376,378,380,382,384],{"class":54,"line":363},16,[52,365,246],{"class":100},[52,367,343],{"class":62},[52,369,278],{"class":100},[52,371,136],{"class":96},[52,373,283],{"class":100},[52,375,286],{"class":62},[52,377,218],{"class":100},[52,379,29],{"class":291},[52,381,136],{"class":96},[52,383,297],{"class":62},[52,385,300],{"class":100},[52,387,389,392,395,397,400,402],{"class":54,"line":388},17,[52,390,391],{"class":178},"print",[52,393,394],{"class":100},"(ws[",[52,396,343],{"class":62},[52,398,399],{"class":100},"].fill.fgColor.rgb, ws[",[52,401,343],{"class":62},[52,403,404],{"class":100},"].fill.bgColor.rgb)\n",[10,406,407,408,410,411,413,414,417,418,420,421,423,424,426,427,430,431,434,435,437,438,440,441,444,445,448],{},"In Excel's file format, a pattern fill has a pattern colour (",[14,409,292],{},") drawn over a background colour (",[14,412,29],{},"), and a ",[23,415,416],{},"solid"," pattern is 100% pattern — so it shows only ",[14,419,292],{},". Setting just ",[14,422,29],{}," leaves ",[14,425,292],{}," at its default, ",[14,428,429],{},"00000000",", which is black: the printout shows ",[14,432,433],{},"A2","'s foreground as ",[14,436,429],{},", and the cell renders as a black block. Always set ",[14,439,292],{}," (also called ",[14,442,443],{},"start_color",") for solid fills. The colours are hex RGB without ",[14,446,447],{},"#","; an 8-digit value adds an alpha prefix that Excel ignores.",[450,451,459,460,459,464,459,468,459,476,459,486,459,497,459,504,459,510,459,516,459,522,459,526,459,531,459,535,459,540,459,545,459,552,459,557,459,561,459,565,459,571,459,574,459,579,459,582],"svg",{"viewBox":452,"role":453,"ariaLabelledBy":454,"xmlns":457,"style":458},"4 0 752 207","img",[455,456],"fill-fg-t","fill-fg-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  ",[461,462,463],"title",{"id":455},"Which colour a solid fill paints",[465,466,467],"desc",{"id":456},"A solid PatternFill with fgColor set paints that colour. A solid PatternFill with only bgColor set paints the default foreground, black, because a solid pattern shows only the foreground colour.",[469,470],"rect",{"x":471,"y":472,"width":473,"height":474,"fill":475},"4","0","752","207","#ffffff",[469,477],{"x":478,"y":479,"width":480,"height":481,"rx":482,"fill":483,"stroke":484,"style":485},"20.0","16.0","351.0","175.0","14","#d9f4f1","var(--teal,#0f9488)","stroke-width:2px",[487,488,490],"g",{"transform":489},"translate(182.5,29.0) scale(1.083)",[491,492],"path",{"d":493,"fill":494,"stroke":495,"style":496},"M5 12.5l4.5 4.5L19 7","none","var(--teal-ink,#0b6157)","stroke-width:1.66px;stroke-linecap:round;stroke-linejoin:round",[498,499,503],"text",{"x":500,"y":501,"style":502},"195.5","78.0","font-size:14px;font-weight:700;fill:var(--teal-ink,#0b6157);text-anchor:middle","PatternFill(\"solid\", fgColor=…)",[54,505],{"x1":506,"y1":507,"x2":508,"y2":507,"stroke":484,"style":509},"36.0","91.0","355.0","stroke-width:1px",[498,511,515],{"x":512,"y":513,"style":514},"60.0","111.0","font-size:12px;font-weight:400;fill:var(--text,#172033);text-anchor:start","cell shows the colour you set",[487,517,519],{"transform":518},"translate(38.5,99.5) scale(0.625)",[491,520],{"d":493,"fill":494,"stroke":484,"style":521},"stroke-width:2.88px;stroke-linecap:round;stroke-linejoin:round",[498,523,525],{"x":512,"y":524,"style":514},"137.0","fgColor is the pattern colour",[487,527,529],{"transform":528},"translate(38.5,125.5) scale(0.625)",[491,530],{"d":493,"fill":494,"stroke":484,"style":521},[498,532,534],{"x":512,"y":533,"style":514},"163.0","solid = 100% pattern",[487,536,538],{"transform":537},"translate(38.5,151.5) scale(0.625)",[491,539],{"d":493,"fill":494,"stroke":484,"style":521},[469,541],{"x":542,"y":479,"width":480,"height":481,"rx":482,"fill":543,"stroke":544,"style":485},"389.0","#fce9e9","var(--danger,#dc2626)",[487,546,548],{"transform":547},"translate(551.5,29.0) scale(1.083)",[491,549],{"d":550,"fill":494,"stroke":551,"style":496},"M6 6l12 12 M18 6L6 18","var(--accent-ink,#be185d)",[498,553,556],{"x":554,"y":501,"style":555},"564.5","font-size:14px;font-weight:700;fill:var(--accent-ink,#be185d);text-anchor:middle","PatternFill(\"solid\", bgColor=…)",[54,558],{"x1":559,"y1":507,"x2":560,"y2":507,"stroke":544,"style":509},"405.0","724.0",[498,562,564],{"x":563,"y":513,"style":514},"429.0","fgColor stays 00000000",[487,566,568],{"transform":567},"translate(407.5,99.5) scale(0.625)",[491,569],{"d":550,"fill":494,"stroke":570,"style":521},"var(--accent,#f43f8f)",[498,572,573],{"x":563,"y":524,"style":514},"cell renders black",[487,575,577],{"transform":576},"translate(407.5,125.5) scale(0.625)",[491,578],{"d":550,"fill":494,"stroke":570,"style":521},[498,580,581],{"x":563,"y":533,"style":514},"bgColor is hidden behind it",[487,583,585],{"transform":584},"translate(407.5,151.5) scale(0.625)",[491,586],{"d":550,"fill":494,"stroke":570,"style":521},[38,588,590],{"id":589},"step-2-hatched-and-dotted-patterns","Step 2 — Hatched and dotted patterns",[10,592,593,594,596,597,599],{},"The other pattern types draw lines or dots in ",[14,595,292],{}," over ",[14,598,29],{},", which is useful for marking cells that are not applicable, estimated or locked without relying on colour alone:",[43,601,603],{"className":87,"code":602,"language":89,"meta":48,"style":48},"patterns = [\"darkTrellis\", \"lightUp\", \"gray125\"]\nfor i, pattern in enumerate(patterns, start=3):\n    ws.cell(i, 1, pattern).fill = PatternFill(pattern, fgColor=\"5B6780\", bgColor=\"EEF2FF\")\n    ws.cell(i, 2, f'PatternFill(\"{pattern}\", fgColor=\"5B6780\", bgColor=\"EEF2FF\")')\nprint(sorted(PatternFill.patternType.values - {None})[:6], \"…\")\n",[14,604,605,631,656,689,719],{"__ignoreMap":48},[52,606,607,610,612,615,618,620,623,625,628],{"class":54,"line":55},[52,608,609],{"class":100},"patterns ",[52,611,136],{"class":96},[52,613,614],{"class":100}," [",[52,616,617],{"class":62},"\"darkTrellis\"",[52,619,218],{"class":100},[52,621,622],{"class":62},"\"lightUp\"",[52,624,218],{"class":100},[52,626,627],{"class":62},"\"gray125\"",[52,629,630],{"class":100},"]\n",[52,632,633,635,638,640,643,646,649,651,654],{"class":54,"line":110},[52,634,200],{"class":96},[52,636,637],{"class":100}," i, pattern ",[52,639,206],{"class":96},[52,641,642],{"class":178}," enumerate",[52,644,645],{"class":100},"(patterns, ",[52,647,648],{"class":291},"start",[52,650,136],{"class":96},[52,652,653],{"class":178},"3",[52,655,224],{"class":100},[52,657,658,661,663,666,668,671,673,675,678,680,682,684,687],{"class":54,"line":123},[52,659,660],{"class":100},"    ws.cell(i, ",[52,662,215],{"class":178},[52,664,665],{"class":100},", pattern).fill ",[52,667,136],{"class":96},[52,669,670],{"class":100}," PatternFill(pattern, ",[52,672,292],{"class":291},[52,674,136],{"class":96},[52,676,677],{"class":62},"\"5B6780\"",[52,679,218],{"class":100},[52,681,29],{"class":291},[52,683,136],{"class":96},[52,685,686],{"class":62},"\"EEF2FF\"",[52,688,300],{"class":100},[52,690,691,693,696,698,701,704,708,711,714,717],{"class":54,"line":130},[52,692,660],{"class":100},[52,694,695],{"class":178},"2",[52,697,218],{"class":100},[52,699,700],{"class":96},"f",[52,702,703],{"class":62},"'PatternFill(\"",[52,705,707],{"class":706},"sSjpA","{",[52,709,710],{"class":100},"pattern",[52,712,713],{"class":706},"}",[52,715,716],{"class":62},"\", fgColor=\"5B6780\", bgColor=\"EEF2FF\")'",[52,718,300],{"class":100},[52,720,721,723,725,728,731,734,737,740,743,746,749,752],{"class":54,"line":142},[52,722,391],{"class":178},[52,724,212],{"class":100},[52,726,727],{"class":178},"sorted",[52,729,730],{"class":100},"(PatternFill.patternType.values ",[52,732,733],{"class":96},"-",[52,735,736],{"class":100}," {",[52,738,739],{"class":178},"None",[52,741,742],{"class":100},"})[:",[52,744,745],{"class":178},"6",[52,747,748],{"class":100},"], ",[52,750,751],{"class":62},"\"…\"",[52,753,300],{"class":100},[10,755,756,757,760,761,764,765,768,769,772,773,777],{},"Here both colours matter: a slate-grey pattern on a pale indigo background. openpyxl accepts eighteen pattern names, from ",[14,758,759],{},"gray0625"," (sparse dots) through ",[14,762,763],{},"lightUp","\u002F",[14,766,767],{},"darkUp"," (diagonal lines) to ",[14,770,771],{},"darkTrellis"," (cross-hatching); misspelling one raises the \"Value must be one of\" error explained in ",[32,774,776],{"href":775},"\u002Fgetting-started-with-python-excel-automation\u002Ftroubleshooting-common-python-excel-errors\u002Ffix-openpyxl-value-must-be-one-of-errors\u002F","Fix openpyxl \"Value must be one of\" and \"Max value is\" Errors",". Patterns print well in black and white, which is one good reason to use them for status marking in reports that end on paper. Be aware that LibreOffice renders pattern fills as a blended flat colour in its PDF output rather than drawing the hatching, so check patterns in Excel.",[38,779,781],{"id":780},"step-3-gradient-fills","Step 3 — Gradient fills",[10,783,784,786,787,790,791,794],{},[14,785,20],{}," blends between colour stops, either along an angle (",[14,788,789],{},"type=\"linear\"",") or outwards from a point (",[14,792,793],{},"type=\"path\"","):",[43,796,798],{"className":87,"code":797,"language":89,"meta":48,"style":48},"from openpyxl.styles import GradientFill\n\nws[\"A6\"], ws[\"B6\"] = \"linear 0°\", 'GradientFill(degree=0, stop=(\"FFFFFF\", \"4338CA\"))'\nws[\"A6\"].fill = GradientFill(type=\"linear\", degree=0, stop=(\"FFFFFF\", \"4338CA\"))\nws[\"A7\"], ws[\"B7\"] = \"linear 90°, three stops\", \"stop=('0F9488', 'FFFFFF', '0F9488')\"\nws[\"A7\"].fill = GradientFill(type=\"linear\", degree=90, stop=(\"0F9488\", \"FFFFFF\", \"0F9488\"))\nws[\"A8\"], ws[\"B8\"] = \"path from centre\", \"type='path', left=right=top=bottom=0.5\"\nws[\"A8\"].fill = GradientFill(type=\"path\", left=0.5, right=0.5, top=0.5, bottom=0.5, stop=(\"FFFFFF\", \"B4740A\"))\nprint(ws[\"A7\"].fill.type, ws[\"A7\"].fill.degree, [s.color.rgb for s in ws[\"A7\"].fill.stop])\n",[14,799,800,811,815,839,887,911,959,983,1056],{"__ignoreMap":48},[52,801,802,804,806,808],{"class":54,"line":55},[52,803,97],{"class":96},[52,805,115],{"class":100},[52,807,104],{"class":96},[52,809,810],{"class":100}," GradientFill\n",[52,812,813],{"class":54,"line":110},[52,814,127],{"emptyLinePlaceholder":126},[52,816,817,819,822,824,827,829,831,834,836],{"class":54,"line":123},[52,818,246],{"class":100},[52,820,821],{"class":62},"\"A6\"",[52,823,252],{"class":100},[52,825,826],{"class":62},"\"B6\"",[52,828,258],{"class":100},[52,830,136],{"class":96},[52,832,833],{"class":62}," \"linear 0°\"",[52,835,218],{"class":100},[52,837,838],{"class":62},"'GradientFill(degree=0, stop=(\"FFFFFF\", \"4338CA\"))'\n",[52,840,841,843,845,847,849,852,855,857,860,862,865,867,869,871,874,876,878,880,882,884],{"class":54,"line":130},[52,842,246],{"class":100},[52,844,821],{"class":62},[52,846,278],{"class":100},[52,848,136],{"class":96},[52,850,851],{"class":100}," GradientFill(",[52,853,854],{"class":291},"type",[52,856,136],{"class":96},[52,858,859],{"class":62},"\"linear\"",[52,861,218],{"class":100},[52,863,864],{"class":291},"degree",[52,866,136],{"class":96},[52,868,472],{"class":178},[52,870,218],{"class":100},[52,872,873],{"class":291},"stop",[52,875,136],{"class":96},[52,877,212],{"class":100},[52,879,323],{"class":62},[52,881,218],{"class":100},[52,883,297],{"class":62},[52,885,886],{"class":100},"))\n",[52,888,889,891,894,896,899,901,903,906,908],{"class":54,"line":142},[52,890,246],{"class":100},[52,892,893],{"class":62},"\"A7\"",[52,895,252],{"class":100},[52,897,898],{"class":62},"\"B7\"",[52,900,258],{"class":100},[52,902,136],{"class":96},[52,904,905],{"class":62}," \"linear 90°, three stops\"",[52,907,218],{"class":100},[52,909,910],{"class":62},"\"stop=('0F9488', 'FFFFFF', '0F9488')\"\n",[52,912,913,915,917,919,921,923,925,927,929,931,933,935,938,940,942,944,946,949,951,953,955,957],{"class":54,"line":153},[52,914,246],{"class":100},[52,916,893],{"class":62},[52,918,278],{"class":100},[52,920,136],{"class":96},[52,922,851],{"class":100},[52,924,854],{"class":291},[52,926,136],{"class":96},[52,928,859],{"class":62},[52,930,218],{"class":100},[52,932,864],{"class":291},[52,934,136],{"class":96},[52,936,937],{"class":178},"90",[52,939,218],{"class":100},[52,941,873],{"class":291},[52,943,136],{"class":96},[52,945,212],{"class":100},[52,947,948],{"class":62},"\"0F9488\"",[52,950,218],{"class":100},[52,952,323],{"class":62},[52,954,218],{"class":100},[52,956,948],{"class":62},[52,958,886],{"class":100},[52,960,961,963,966,968,971,973,975,978,980],{"class":54,"line":164},[52,962,246],{"class":100},[52,964,965],{"class":62},"\"A8\"",[52,967,252],{"class":100},[52,969,970],{"class":62},"\"B8\"",[52,972,258],{"class":100},[52,974,136],{"class":96},[52,976,977],{"class":62}," \"path from centre\"",[52,979,218],{"class":100},[52,981,982],{"class":62},"\"type='path', left=right=top=bottom=0.5\"\n",[52,984,985,987,989,991,993,995,997,999,1002,1004,1007,1009,1012,1014,1017,1019,1021,1023,1026,1028,1030,1032,1035,1037,1039,1041,1043,1045,1047,1049,1051,1054],{"class":54,"line":182},[52,986,246],{"class":100},[52,988,965],{"class":62},[52,990,278],{"class":100},[52,992,136],{"class":96},[52,994,851],{"class":100},[52,996,854],{"class":291},[52,998,136],{"class":96},[52,1000,1001],{"class":62},"\"path\"",[52,1003,218],{"class":100},[52,1005,1006],{"class":291},"left",[52,1008,136],{"class":96},[52,1010,1011],{"class":178},"0.5",[52,1013,218],{"class":100},[52,1015,1016],{"class":291},"right",[52,1018,136],{"class":96},[52,1020,1011],{"class":178},[52,1022,218],{"class":100},[52,1024,1025],{"class":291},"top",[52,1027,136],{"class":96},[52,1029,1011],{"class":178},[52,1031,218],{"class":100},[52,1033,1034],{"class":291},"bottom",[52,1036,136],{"class":96},[52,1038,1011],{"class":178},[52,1040,218],{"class":100},[52,1042,873],{"class":291},[52,1044,136],{"class":96},[52,1046,212],{"class":100},[52,1048,323],{"class":62},[52,1050,218],{"class":100},[52,1052,1053],{"class":62},"\"B4740A\"",[52,1055,886],{"class":100},[52,1057,1058,1060,1062,1064,1067,1069,1072,1074,1077,1079,1082,1084],{"class":54,"line":197},[52,1059,391],{"class":178},[52,1061,394],{"class":100},[52,1063,893],{"class":62},[52,1065,1066],{"class":100},"].fill.type, ws[",[52,1068,893],{"class":62},[52,1070,1071],{"class":100},"].fill.degree, [s.color.rgb ",[52,1073,200],{"class":96},[52,1075,1076],{"class":100}," s ",[52,1078,206],{"class":96},[52,1080,1081],{"class":100}," ws[",[52,1083,893],{"class":62},[52,1085,1086],{"class":100},"].fill.stop])\n",[10,1088,1089,1092,1093,1095,1096,1098],{},[14,1090,1091],{},"degree=0"," runs left to right, ",[14,1094,937],{}," top to bottom. Stops given as plain colours are spread evenly; three stops make the middle colour sit at the centre, which gives a \"shine\" effect. A ",[14,1097,491],{}," gradient with all four edges at 0.5 radiates from the centre of the cell. Gradients look dated if overused; a single gradient title band is usually plenty. LibreOffice's PDF export approximates gradient fills with a single blended colour, so judge gradients in Excel.",[450,1100,459,1105,459,1108,459,1111,459,1114,459,1119,459,1126,459,1132,459,1135,459,1139,459,1144,459,1149,459,1151,459,1156,459,1158,459,1161,459,1164,459,1168,459,1170,459,1173,459,1175,459,1178,459,1181,459,1185,459,1187,459,1191,459,1193,459,1196,459,1199,459,1203,459,1205,459,1209,459,1211,459,1214,459,1217,459,1221,459,1223,459,1227,459,1229],{"viewBox":1101,"role":453,"ariaLabelledBy":1102,"xmlns":457,"style":458},"4 0 752 242",[1103,1104],"fill-kinds-t","fill-kinds-d",[461,1106,1107],{"id":1103},"The fill types and which colours they use",[465,1109,1110],{"id":1104},"A solid pattern uses only the foreground colour. Other patterns draw the foreground colour over the background colour. Linear gradients blend colour stops along an angle, path gradients from a point. Conditional-format fills should set both colours.",[469,1112],{"x":471,"y":472,"width":473,"height":1113,"fill":475},"242",[469,1115],{"x":478,"y":479,"width":1116,"height":1117,"rx":472,"fill":475,"stroke":1118,"style":509},"202.9","40.0","var(--line,#cdd5e6)",[469,1120],{"x":1121,"y":479,"width":1122,"height":1117,"rx":472,"fill":1123,"stroke":1124,"style":1125},"222.9","258.6","#f0f4ff","var(--brand,#5b5cf0)","stroke-width:1.2px",[498,1127,1131],{"x":1128,"y":1129,"style":1130},"352.2","41.0","font-size:13px;font-weight:700;fill:var(--brand-strong,#4338ca);text-anchor:middle","colours used",[469,1133],{"x":1134,"y":479,"width":1122,"height":1117,"rx":472,"fill":1123,"stroke":1124,"style":1125},"481.4",[498,1136,1138],{"x":1137,"y":1129,"style":1130},"610.7","typical use",[469,1140],{"x":478,"y":1141,"width":1116,"height":1142,"rx":472,"fill":1143,"stroke":1118,"style":509},"56.0","34.0","#e7ebef",[498,1145,1148],{"x":1146,"y":501,"style":1147},"32.0","font-size:12.5px;font-weight:700;fill:var(--text,#172033);text-anchor:start","PatternFill(\"solid\")",[469,1150],{"x":1121,"y":1141,"width":1122,"height":1142,"rx":472,"fill":475,"stroke":1118,"style":509},[498,1152,1155],{"x":1128,"y":1153,"style":1154},"77.0","font-size:11.5px;font-weight:400;fill:var(--text,#172033);text-anchor:middle","fgColor only",[469,1157],{"x":1134,"y":1141,"width":1122,"height":1142,"rx":472,"fill":475,"stroke":1118,"style":509},[498,1159,1160],{"x":1137,"y":1153,"style":1154},"header bands, input cells",[469,1162],{"x":478,"y":1163,"width":1116,"height":1142,"rx":472,"fill":1143,"stroke":1118,"style":509},"90.0",[498,1165,1167],{"x":1146,"y":1166,"style":1147},"112.0","PatternFill(\"darkTrellis\" …)",[469,1169],{"x":1121,"y":1163,"width":1122,"height":1142,"rx":472,"fill":475,"stroke":1118,"style":509},[498,1171,1172],{"x":1128,"y":513,"style":1154},"fgColor over bgColor",[469,1174],{"x":1134,"y":1163,"width":1122,"height":1142,"rx":472,"fill":475,"stroke":1118,"style":509},[498,1176,1177],{"x":1137,"y":513,"style":1154},"not applicable, estimates",[469,1179],{"x":478,"y":1180,"width":1116,"height":1142,"rx":472,"fill":1143,"stroke":1118,"style":509},"124.0",[498,1182,1184],{"x":1146,"y":1183,"style":1147},"146.0","GradientFill(type=\"linear\")",[469,1186],{"x":1121,"y":1180,"width":1122,"height":1142,"rx":472,"fill":475,"stroke":1118,"style":509},[498,1188,1190],{"x":1128,"y":1189,"style":1154},"145.0","stops, along degree",[469,1192],{"x":1134,"y":1180,"width":1122,"height":1142,"rx":472,"fill":475,"stroke":1118,"style":509},[498,1194,1195],{"x":1137,"y":1189,"style":1154},"title bands",[469,1197],{"x":478,"y":1198,"width":1116,"height":1142,"rx":472,"fill":1143,"stroke":1118,"style":509},"158.0",[498,1200,1202],{"x":1146,"y":1201,"style":1147},"180.0","GradientFill(type=\"path\")",[469,1204],{"x":1121,"y":1198,"width":1122,"height":1142,"rx":472,"fill":475,"stroke":1118,"style":509},[498,1206,1208],{"x":1128,"y":1207,"style":1154},"179.0","stops, from a point",[469,1210],{"x":1134,"y":1198,"width":1122,"height":1142,"rx":472,"fill":475,"stroke":1118,"style":509},[498,1212,1213],{"x":1137,"y":1207,"style":1154},"highlights",[469,1215],{"x":478,"y":1216,"width":1116,"height":1142,"rx":472,"fill":1143,"stroke":1118,"style":509},"192.0",[498,1218,1220],{"x":1146,"y":1219,"style":1147},"214.0","Conditional-format fill",[469,1222],{"x":1121,"y":1216,"width":1122,"height":1142,"rx":472,"fill":475,"stroke":1118,"style":509},[498,1224,1226],{"x":1128,"y":1225,"style":1154},"213.0","set fgColor and bgColor",[469,1228],{"x":1134,"y":1216,"width":1122,"height":1142,"rx":472,"fill":475,"stroke":1118,"style":509},[498,1230,1231],{"x":1137,"y":1225,"style":1154},"rule-based colour",[38,1233,1235],{"id":1234},"step-4-fills-in-conditional-formats","Step 4 — Fills in conditional formats",[10,1237,1238,1239,1241,1242,1245],{},"Conditional formats use the same ",[14,1240,16],{}," class, but the differential style stored for the rule has its own conventions: Excel reads the ",[23,1243,1244],{},"background"," colour for a solid fill there. Setting both colours works everywhere:",[43,1247,1249],{"className":87,"code":1248,"language":89,"meta":48,"style":48},"from openpyxl.formatting.rule import CellIsRule\n\nws[\"D1\"], ws[\"D2\"], ws[\"D3\"] = \"Margin\", 0.12, -0.04\ngood = PatternFill(\"solid\", start_color=\"D9F4F1\", end_color=\"D9F4F1\")\nbad = PatternFill(\"solid\", start_color=\"FCE9E9\", end_color=\"FCE9E9\")\nws.conditional_formatting.add(\"D2:D3\", CellIsRule(operator=\"greaterThanOrEqual\", formula=[\"0\"], fill=good))\nws.conditional_formatting.add(\"D2:D3\", CellIsRule(operator=\"lessThan\", formula=[\"0\"], fill=bad))\nwb.save(\"fills.xlsx\")\nprint(\"rules:\", [str(r.sqref) for r in ws.conditional_formatting])\n",[14,1250,1251,1263,1267,1303,1334,1364,1406,1440,1450],{"__ignoreMap":48},[52,1252,1253,1255,1258,1260],{"class":54,"line":55},[52,1254,97],{"class":96},[52,1256,1257],{"class":100}," openpyxl.formatting.rule ",[52,1259,104],{"class":96},[52,1261,1262],{"class":100}," CellIsRule\n",[52,1264,1265],{"class":54,"line":110},[52,1266,127],{"emptyLinePlaceholder":126},[52,1268,1269,1271,1274,1276,1279,1281,1284,1286,1288,1291,1293,1296,1298,1300],{"class":54,"line":123},[52,1270,246],{"class":100},[52,1272,1273],{"class":62},"\"D1\"",[52,1275,252],{"class":100},[52,1277,1278],{"class":62},"\"D2\"",[52,1280,252],{"class":100},[52,1282,1283],{"class":62},"\"D3\"",[52,1285,258],{"class":100},[52,1287,136],{"class":96},[52,1289,1290],{"class":62}," \"Margin\"",[52,1292,218],{"class":100},[52,1294,1295],{"class":178},"0.12",[52,1297,218],{"class":100},[52,1299,733],{"class":96},[52,1301,1302],{"class":178},"0.04\n",[52,1304,1305,1308,1310,1312,1314,1316,1318,1320,1323,1325,1328,1330,1332],{"class":54,"line":130},[52,1306,1307],{"class":100},"good ",[52,1309,136],{"class":96},[52,1311,283],{"class":100},[52,1313,286],{"class":62},[52,1315,218],{"class":100},[52,1317,443],{"class":291},[52,1319,136],{"class":96},[52,1321,1322],{"class":62},"\"D9F4F1\"",[52,1324,218],{"class":100},[52,1326,1327],{"class":291},"end_color",[52,1329,136],{"class":96},[52,1331,1322],{"class":62},[52,1333,300],{"class":100},[52,1335,1336,1339,1341,1343,1345,1347,1349,1351,1354,1356,1358,1360,1362],{"class":54,"line":142},[52,1337,1338],{"class":100},"bad ",[52,1340,136],{"class":96},[52,1342,283],{"class":100},[52,1344,286],{"class":62},[52,1346,218],{"class":100},[52,1348,443],{"class":291},[52,1350,136],{"class":96},[52,1352,1353],{"class":62},"\"FCE9E9\"",[52,1355,218],{"class":100},[52,1357,1327],{"class":291},[52,1359,136],{"class":96},[52,1361,1353],{"class":62},[52,1363,300],{"class":100},[52,1365,1366,1369,1372,1375,1378,1380,1383,1385,1388,1390,1393,1396,1398,1401,1403],{"class":54,"line":153},[52,1367,1368],{"class":100},"ws.conditional_formatting.add(",[52,1370,1371],{"class":62},"\"D2:D3\"",[52,1373,1374],{"class":100},", CellIsRule(",[52,1376,1377],{"class":291},"operator",[52,1379,136],{"class":96},[52,1381,1382],{"class":62},"\"greaterThanOrEqual\"",[52,1384,218],{"class":100},[52,1386,1387],{"class":291},"formula",[52,1389,136],{"class":96},[52,1391,1392],{"class":100},"[",[52,1394,1395],{"class":62},"\"0\"",[52,1397,748],{"class":100},[52,1399,1400],{"class":291},"fill",[52,1402,136],{"class":96},[52,1404,1405],{"class":100},"good))\n",[52,1407,1408,1410,1412,1414,1416,1418,1421,1423,1425,1427,1429,1431,1433,1435,1437],{"class":54,"line":164},[52,1409,1368],{"class":100},[52,1411,1371],{"class":62},[52,1413,1374],{"class":100},[52,1415,1377],{"class":291},[52,1417,136],{"class":96},[52,1419,1420],{"class":62},"\"lessThan\"",[52,1422,218],{"class":100},[52,1424,1387],{"class":291},[52,1426,136],{"class":96},[52,1428,1392],{"class":100},[52,1430,1395],{"class":62},[52,1432,748],{"class":100},[52,1434,1400],{"class":291},[52,1436,136],{"class":96},[52,1438,1439],{"class":100},"bad))\n",[52,1441,1442,1445,1448],{"class":54,"line":182},[52,1443,1444],{"class":100},"wb.save(",[52,1446,1447],{"class":62},"\"fills.xlsx\"",[52,1449,300],{"class":100},[52,1451,1452,1454,1456,1459,1462,1465,1468,1470,1472,1474],{"class":54,"line":197},[52,1453,391],{"class":178},[52,1455,212],{"class":100},[52,1457,1458],{"class":62},"\"rules:\"",[52,1460,1461],{"class":100},", [",[52,1463,1464],{"class":178},"str",[52,1466,1467],{"class":100},"(r.sqref) ",[52,1469,200],{"class":96},[52,1471,203],{"class":100},[52,1473,206],{"class":96},[52,1475,1476],{"class":100}," ws.conditional_formatting])\n",[10,1478,1479,17,1481,1483,1484,17,1486,1488,1489,1491,1492,36],{},[14,1480,443],{},[14,1482,1327],{}," are openpyxl's other names for ",[14,1485,292],{},[14,1487,29],{},"; setting both to the same value makes the rule's fill appear in Excel and LibreOffice alike. LibreOffice accepts either colour on its own, which is why a rule written with only ",[14,1490,292],{}," can look fine in testing and come out uncoloured for Excel users. Rules in general are covered in ",[32,1493,1495],{"href":1494},"\u002Fadvanced-data-transformation-and-cleaning\u002Fapplying-conditional-formatting-with-openpyxl\u002F","Applying Conditional Formatting with openpyxl",[38,1497,1499],{"id":1498},"step-5-remove-a-fill","Step 5 — Remove a fill",[43,1501,1503],{"className":87,"code":1502,"language":89,"meta":48,"style":48},"from openpyxl.styles import PatternFill\n\nws[\"A9\"] = \"fill removed\"\nws[\"A9\"].fill = PatternFill(\"solid\", fgColor=\"FF0000\")\nws[\"A9\"].fill = PatternFill(fill_type=None)\nprint(\"A9 fill type:\", ws[\"A9\"].fill.fill_type)\nwb.save(\"fills.xlsx\")\n",[14,1504,1505,1516,1520,1534,1559,1580,1597],{"__ignoreMap":48},[52,1506,1507,1509,1511,1513],{"class":54,"line":55},[52,1508,97],{"class":96},[52,1510,115],{"class":100},[52,1512,104],{"class":96},[52,1514,1515],{"class":100}," PatternFill\n",[52,1517,1518],{"class":54,"line":110},[52,1519,127],{"emptyLinePlaceholder":126},[52,1521,1522,1524,1527,1529,1531],{"class":54,"line":123},[52,1523,246],{"class":100},[52,1525,1526],{"class":62},"\"A9\"",[52,1528,258],{"class":100},[52,1530,136],{"class":96},[52,1532,1533],{"class":62}," \"fill removed\"\n",[52,1535,1536,1538,1540,1542,1544,1546,1548,1550,1552,1554,1557],{"class":54,"line":130},[52,1537,246],{"class":100},[52,1539,1526],{"class":62},[52,1541,278],{"class":100},[52,1543,136],{"class":96},[52,1545,283],{"class":100},[52,1547,286],{"class":62},[52,1549,218],{"class":100},[52,1551,292],{"class":291},[52,1553,136],{"class":96},[52,1555,1556],{"class":62},"\"FF0000\"",[52,1558,300],{"class":100},[52,1560,1561,1563,1565,1567,1569,1571,1574,1576,1578],{"class":54,"line":142},[52,1562,246],{"class":100},[52,1564,1526],{"class":62},[52,1566,278],{"class":100},[52,1568,136],{"class":96},[52,1570,283],{"class":100},[52,1572,1573],{"class":291},"fill_type",[52,1575,136],{"class":96},[52,1577,739],{"class":178},[52,1579,300],{"class":100},[52,1581,1582,1584,1586,1589,1592,1594],{"class":54,"line":153},[52,1583,391],{"class":178},[52,1585,212],{"class":100},[52,1587,1588],{"class":62},"\"A9 fill type:\"",[52,1590,1591],{"class":100},", ws[",[52,1593,1526],{"class":62},[52,1595,1596],{"class":100},"].fill.fill_type)\n",[52,1598,1599,1601,1603],{"class":54,"line":164},[52,1600,1444],{"class":100},[52,1602,1447],{"class":62},[52,1604,300],{"class":100},[10,1606,1607,1608,1610,1611,1614,1615,36],{},"A ",[14,1609,16],{}," with ",[14,1612,1613],{},"fill_type=None"," means \"no fill\"; colours given alongside it are ignored. This is the way to clear fills selectively — for example, removing the yellow \"needs review\" shading once rows are checked — without touching fonts, borders or number formats. To reset every aspect of a cell's formatting at once, see ",[32,1616,1618],{"href":1617},"\u002Fgetting-started-with-python-excel-automation\u002Fusing-openpyxl-for-excel-file-manipulation\u002Fclear-cell-contents-and-formatting-with-openpyxl\u002F","Clear Cell Contents and Formatting with openpyxl",[38,1620,1622],{"id":1621},"step-6-check-the-result-by-rendering-it","Step 6 — Check the result by rendering it",[10,1624,1625],{},"The fastest way to catch a black-instead-of-indigo mistake is to look. Copy each fill onto a text-free swatch sheet, render it to an image and sample the colour band by band:",[43,1627,1629],{"className":87,"code":1628,"language":89,"meta":48,"style":48},"import subprocess\nfrom copy import copy\nfrom PIL import Image\n\nswatch_wb = Workbook()\nsw = swatch_wb.active\nsw.column_dimensions[\"A\"].width = 40\nfor r in range(1, 10):\n    sw.row_dimensions[r].height = 30\n    sw.cell(r, 1).fill = copy(ws.cell(r, 1).fill)\nswatch_wb.save(\"swatches.xlsx\")\nsubprocess.run([\"soffice\", \"--headless\", \"--convert-to\", \"pdf\", \"swatches.xlsx\"], check=True, capture_output=True)\nsubprocess.run([\"pdftoppm\", \"-png\", \"-r\", \"50\", \"-f\", \"1\", \"-l\", \"1\", \"swatches.pdf\", \"swatches\"], check=True)\nimg = Image.open(\"swatches-1.png\").convert(\"RGB\")\ncolumn = [img.getpixel((80, y)) for y in range(img.height)]\nbands, start = [], 0\nfor y in range(1, len(column) + 1):\n    if y == len(column) or column[y] != column[start]:\n        if y - start >= 8:                                 # ignore gridlines and edges\n            bands.append(\"#%02X%02X%02X\" % column[start])\n        start = y\nprint(bands[1:10])                                         # skip the white page margin\n",[14,1630,1631,1638,1650,1663,1667,1676,1686,1700,1721,1730,1750,1760,1807,1868,1889,1917,1930,1960,1988,2014,2035,2046],{"__ignoreMap":48},[52,1632,1633,1635],{"class":54,"line":55},[52,1634,104],{"class":96},[52,1636,1637],{"class":100}," subprocess\n",[52,1639,1640,1642,1645,1647],{"class":54,"line":110},[52,1641,97],{"class":96},[52,1643,1644],{"class":100}," copy ",[52,1646,104],{"class":96},[52,1648,1649],{"class":100}," copy\n",[52,1651,1652,1654,1657,1660],{"class":54,"line":123},[52,1653,97],{"class":96},[52,1655,1656],{"class":178}," PIL",[52,1658,1659],{"class":96}," import",[52,1661,1662],{"class":100}," Image\n",[52,1664,1665],{"class":54,"line":130},[52,1666,127],{"emptyLinePlaceholder":126},[52,1668,1669,1672,1674],{"class":54,"line":142},[52,1670,1671],{"class":100},"swatch_wb ",[52,1673,136],{"class":96},[52,1675,139],{"class":100},[52,1677,1678,1681,1683],{"class":54,"line":153},[52,1679,1680],{"class":100},"sw ",[52,1682,136],{"class":96},[52,1684,1685],{"class":100}," swatch_wb.active\n",[52,1687,1688,1691,1693,1695,1697],{"class":54,"line":164},[52,1689,1690],{"class":100},"sw.column_dimensions[",[52,1692,170],{"class":62},[52,1694,173],{"class":100},[52,1696,136],{"class":96},[52,1698,1699],{"class":178}," 40\n",[52,1701,1702,1704,1706,1708,1710,1712,1714,1716,1719],{"class":54,"line":182},[52,1703,200],{"class":96},[52,1705,203],{"class":100},[52,1707,206],{"class":96},[52,1709,209],{"class":178},[52,1711,212],{"class":100},[52,1713,215],{"class":178},[52,1715,218],{"class":100},[52,1717,1718],{"class":178},"10",[52,1720,224],{"class":100},[52,1722,1723,1726,1728],{"class":54,"line":197},[52,1724,1725],{"class":100},"    sw.row_dimensions[r].height ",[52,1727,136],{"class":96},[52,1729,235],{"class":178},[52,1731,1732,1735,1737,1740,1742,1745,1747],{"class":54,"line":227},[52,1733,1734],{"class":100},"    sw.cell(r, ",[52,1736,215],{"class":178},[52,1738,1739],{"class":100},").fill ",[52,1741,136],{"class":96},[52,1743,1744],{"class":100}," copy(ws.cell(r, ",[52,1746,215],{"class":178},[52,1748,1749],{"class":100},").fill)\n",[52,1751,1752,1755,1758],{"class":54,"line":238},[52,1753,1754],{"class":100},"swatch_wb.save(",[52,1756,1757],{"class":62},"\"swatches.xlsx\"",[52,1759,300],{"class":100},[52,1761,1762,1765,1768,1770,1773,1775,1778,1780,1783,1785,1787,1789,1792,1794,1796,1798,1801,1803,1805],{"class":54,"line":243},[52,1763,1764],{"class":100},"subprocess.run([",[52,1766,1767],{"class":62},"\"soffice\"",[52,1769,218],{"class":100},[52,1771,1772],{"class":62},"\"--headless\"",[52,1774,218],{"class":100},[52,1776,1777],{"class":62},"\"--convert-to\"",[52,1779,218],{"class":100},[52,1781,1782],{"class":62},"\"pdf\"",[52,1784,218],{"class":100},[52,1786,1757],{"class":62},[52,1788,748],{"class":100},[52,1790,1791],{"class":291},"check",[52,1793,136],{"class":96},[52,1795,333],{"class":178},[52,1797,218],{"class":100},[52,1799,1800],{"class":291},"capture_output",[52,1802,136],{"class":96},[52,1804,333],{"class":178},[52,1806,300],{"class":100},[52,1808,1809,1811,1814,1816,1819,1821,1824,1826,1829,1831,1834,1836,1839,1841,1844,1846,1848,1850,1853,1855,1858,1860,1862,1864,1866],{"class":54,"line":271},[52,1810,1764],{"class":100},[52,1812,1813],{"class":62},"\"pdftoppm\"",[52,1815,218],{"class":100},[52,1817,1818],{"class":62},"\"-png\"",[52,1820,218],{"class":100},[52,1822,1823],{"class":62},"\"-r\"",[52,1825,218],{"class":100},[52,1827,1828],{"class":62},"\"50\"",[52,1830,218],{"class":100},[52,1832,1833],{"class":62},"\"-f\"",[52,1835,218],{"class":100},[52,1837,1838],{"class":62},"\"1\"",[52,1840,218],{"class":100},[52,1842,1843],{"class":62},"\"-l\"",[52,1845,218],{"class":100},[52,1847,1838],{"class":62},[52,1849,218],{"class":100},[52,1851,1852],{"class":62},"\"swatches.pdf\"",[52,1854,218],{"class":100},[52,1856,1857],{"class":62},"\"swatches\"",[52,1859,748],{"class":100},[52,1861,1791],{"class":291},[52,1863,136],{"class":96},[52,1865,333],{"class":178},[52,1867,300],{"class":100},[52,1869,1870,1873,1875,1878,1881,1884,1887],{"class":54,"line":303},[52,1871,1872],{"class":100},"img ",[52,1874,136],{"class":96},[52,1876,1877],{"class":100}," Image.open(",[52,1879,1880],{"class":62},"\"swatches-1.png\"",[52,1882,1883],{"class":100},").convert(",[52,1885,1886],{"class":62},"\"RGB\"",[52,1888,300],{"class":100},[52,1890,1891,1894,1896,1899,1902,1905,1907,1910,1912,1914],{"class":54,"line":338},[52,1892,1893],{"class":100},"column ",[52,1895,136],{"class":96},[52,1897,1898],{"class":100}," [img.getpixel((",[52,1900,1901],{"class":178},"80",[52,1903,1904],{"class":100},", y)) ",[52,1906,200],{"class":96},[52,1908,1909],{"class":100}," y ",[52,1911,206],{"class":96},[52,1913,209],{"class":178},[52,1915,1916],{"class":100},"(img.height)]\n",[52,1918,1919,1922,1924,1927],{"class":54,"line":363},[52,1920,1921],{"class":100},"bands, start ",[52,1923,136],{"class":96},[52,1925,1926],{"class":100}," [], ",[52,1928,1929],{"class":178},"0\n",[52,1931,1932,1934,1936,1938,1940,1942,1944,1946,1949,1952,1955,1958],{"class":54,"line":388},[52,1933,200],{"class":96},[52,1935,1909],{"class":100},[52,1937,206],{"class":96},[52,1939,209],{"class":178},[52,1941,212],{"class":100},[52,1943,215],{"class":178},[52,1945,218],{"class":100},[52,1947,1948],{"class":178},"len",[52,1950,1951],{"class":100},"(column) ",[52,1953,1954],{"class":96},"+",[52,1956,1957],{"class":178}," 1",[52,1959,224],{"class":100},[52,1961,1963,1966,1968,1971,1974,1976,1979,1982,1985],{"class":54,"line":1962},18,[52,1964,1965],{"class":96},"    if",[52,1967,1909],{"class":100},[52,1969,1970],{"class":96},"==",[52,1972,1973],{"class":178}," len",[52,1975,1951],{"class":100},[52,1977,1978],{"class":96},"or",[52,1980,1981],{"class":100}," column[y] ",[52,1983,1984],{"class":96},"!=",[52,1986,1987],{"class":100}," column[start]:\n",[52,1989,1991,1994,1996,1998,2001,2004,2007,2010],{"class":54,"line":1990},19,[52,1992,1993],{"class":96},"        if",[52,1995,1909],{"class":100},[52,1997,733],{"class":96},[52,1999,2000],{"class":100}," start ",[52,2002,2003],{"class":96},">=",[52,2005,2006],{"class":178}," 8",[52,2008,2009],{"class":100},":                                 ",[52,2011,2013],{"class":2012},"s-wDw","# ignore gridlines and edges\n",[52,2015,2017,2020,2023,2026,2029,2032],{"class":54,"line":2016},20,[52,2018,2019],{"class":100},"            bands.append(",[52,2021,2022],{"class":62},"\"#",[52,2024,2025],{"class":706},"%02X%02X%02X",[52,2027,2028],{"class":62},"\"",[52,2030,2031],{"class":96}," %",[52,2033,2034],{"class":100}," column[start])\n",[52,2036,2038,2041,2043],{"class":54,"line":2037},21,[52,2039,2040],{"class":100},"        start ",[52,2042,136],{"class":96},[52,2044,2045],{"class":100}," y\n",[52,2047,2049,2051,2054,2056,2059,2061,2064],{"class":54,"line":2048},22,[52,2050,391],{"class":178},[52,2052,2053],{"class":100},"(bands[",[52,2055,215],{"class":178},[52,2057,2058],{"class":100},":",[52,2060,1718],{"class":178},[52,2062,2063],{"class":100},"])                                         ",[52,2065,2066],{"class":2012},"# skip the white page margin\n",[10,2068,2069,2070,2073,2074,2077],{},"Copying the fill objects onto a fresh sheet without text keeps letters from polluting the samples. Scanning down column A and keeping only bands at least eight pixels tall skips the thin gridlines. The first band is the indigo ",[14,2071,2072],{},"#4338CA"," of the correct solid fill, the second is ",[14,2075,2076],{},"#000000"," — the bgColor-only fill rendered black, exactly as predicted — followed by the pattern and gradient rows as blended flat colours, and white for the cleared fill. The darkTrellis, lightUp and gray125 rows come out as three different greys — the pattern's ink blended with its background in proportion to how much of the cell the pattern covers — and the three gradients as single averaged tints of indigo, teal and gold. A check like this, pinned in a test, is cheap protection for report templates where colour carries meaning: assert that the header band is the brand colour and that no fill renders as pure black.",[450,2079,459,2085,459,2088,459,2091,459,2096,459,2100,459,2104,459,2110,459,2114,459,2118,459,2122,459,2126,459,2129,459,2133,459,2136,459,2140,459,2142,459,2145,459,2147,459,2150,459,2153,459,2156,459,2158,459,2162,459,2164,459,2167,459,2169,459,2173,459,2176,459,2179,459,2181,459,2183,459,2185,459,2188,459,2190,459,2194,459,2196,459,2199,459,2201,459,2204,459,2206,459,2209,459,2211,459,2214,459,2217,459,2221,459,2223,459,2226,459,2228,459,2231,459,2233,459,2236,459,2238,459,2241,459,2243,459,2246,459,2248,459,2251,459,2253],{"viewBox":2080,"role":453,"ariaLabelledBy":2081,"xmlns":457,"style":2084},"195 0 370 224",[2082,2083],"fill-render-t","fill-render-d","width:100%;max-width:370px;height:auto;display:block;margin:1.5rem auto;font-family:Inter,ui-sans-serif,system-ui,sans-serif",[461,2086,2087],{"id":2082},"What the rendered sheet shows in column A",[465,2089,2090],{"id":2083},"The first row has the intended indigo fill. The second row, filled with only bgColor, renders black. The pattern rows render as blended flat colours in LibreOffice and the gradient rows as approximations, so they are checked in Excel.",[469,2092],{"x":2093,"y":472,"width":2094,"height":2095,"fill":475},"195","370","224",[469,2097],{"x":2098,"y":479,"width":1146,"height":2099,"rx":472,"fill":1143,"stroke":1118,"style":509},"211.0","24.0",[469,2101],{"x":2102,"y":479,"width":2103,"height":2099,"rx":472,"fill":1143,"stroke":1118,"style":509},"243.0","60.3",[498,2105,2109],{"x":2106,"y":2107,"style":2108},"273.2","33.0","font-size:11px;font-weight:600;fill:var(--muted,#5b6780);text-anchor:middle","A",[469,2111],{"x":2112,"y":479,"width":2113,"height":2099,"rx":472,"fill":1143,"stroke":1118,"style":509},"303.3","140.9",[498,2115,2117],{"x":2116,"y":2107,"style":2108},"373.8","B",[469,2119],{"x":2120,"y":479,"width":2121,"height":2099,"rx":472,"fill":1143,"stroke":1118,"style":509},"444.2","104.8",[498,2123,2125],{"x":2124,"y":2107,"style":2108},"496.6","C",[469,2127],{"x":2098,"y":1117,"width":1146,"height":2128,"rx":472,"fill":1143,"stroke":1118,"style":509},"28.0",[498,2130,215],{"x":2131,"y":2132,"style":2108},"227.0","59.0",[469,2134],{"x":2102,"y":1117,"width":2103,"height":2128,"rx":472,"fill":1123,"stroke":1124,"style":2135},"stroke-width:1.5px",[498,2137,2139],{"x":2106,"y":2132,"style":2138},"font-size:10.5px;font-weight:700;fill:var(--brand-strong,#4338ca);text-anchor:middle","Cell",[469,2141],{"x":2112,"y":1117,"width":2113,"height":2128,"rx":472,"fill":1123,"stroke":1124,"style":2135},[498,2143,2144],{"x":2116,"y":2132,"style":2138},"Fill",[469,2146],{"x":2120,"y":1117,"width":2121,"height":2128,"rx":472,"fill":1123,"stroke":1124,"style":2135},[498,2148,2149],{"x":2124,"y":2132,"style":2138},"Rendered",[469,2151],{"x":2098,"y":2152,"width":1146,"height":2128,"rx":472,"fill":1143,"stroke":1118,"style":509},"68.0",[498,2154,695],{"x":2131,"y":2155,"style":2108},"87.0",[469,2157],{"x":2102,"y":2152,"width":2103,"height":2128,"rx":472,"fill":475,"stroke":1118,"style":509},[498,2159,2161],{"x":2106,"y":2155,"style":2160},"font-size:10.5px;font-weight:400;fill:var(--text,#172033);text-anchor:middle","A1",[469,2163],{"x":2112,"y":2152,"width":2113,"height":2128,"rx":472,"fill":475,"stroke":1118,"style":509},[498,2165,2166],{"x":2116,"y":2155,"style":2160},"solid fgColor 4338CA",[469,2168],{"x":2120,"y":2152,"width":2121,"height":2128,"rx":472,"fill":483,"stroke":484,"style":2135},[498,2170,2172],{"x":2124,"y":2155,"style":2171},"font-size:10.5px;font-weight:700;fill:var(--teal-ink,#0b6157);text-anchor:middle","indigo ✓",[469,2174],{"x":2098,"y":2175,"width":1146,"height":2128,"rx":472,"fill":1143,"stroke":1118,"style":509},"96.0",[498,2177,653],{"x":2131,"y":2178,"style":2108},"115.0",[469,2180],{"x":2102,"y":2175,"width":2103,"height":2128,"rx":472,"fill":475,"stroke":1118,"style":509},[498,2182,433],{"x":2106,"y":2178,"style":2160},[469,2184],{"x":2112,"y":2175,"width":2113,"height":2128,"rx":472,"fill":475,"stroke":1118,"style":509},[498,2186,2187],{"x":2116,"y":2178,"style":2160},"solid bgColor only",[469,2189],{"x":2120,"y":2175,"width":2121,"height":2128,"rx":472,"fill":543,"stroke":544,"style":2135},[498,2191,2193],{"x":2124,"y":2178,"style":2192},"font-size:10.5px;font-weight:700;fill:var(--accent-ink,#be185d);text-anchor:middle","black ✗",[469,2195],{"x":2098,"y":1180,"width":1146,"height":2128,"rx":472,"fill":1143,"stroke":1118,"style":509},[498,2197,471],{"x":2131,"y":2198,"style":2108},"143.0",[469,2200],{"x":2102,"y":1180,"width":2103,"height":2128,"rx":472,"fill":475,"stroke":1118,"style":509},[498,2202,2203],{"x":2106,"y":2198,"style":2160},"A3–A5",[469,2205],{"x":2112,"y":1180,"width":2113,"height":2128,"rx":472,"fill":475,"stroke":1118,"style":509},[498,2207,2208],{"x":2116,"y":2198,"style":2160},"patterns",[469,2210],{"x":2120,"y":1180,"width":2121,"height":2128,"rx":472,"fill":475,"stroke":1118,"style":509},[498,2212,2213],{"x":2124,"y":2198,"style":2160},"blended colour",[469,2215],{"x":2098,"y":2216,"width":1146,"height":2128,"rx":472,"fill":1143,"stroke":1118,"style":509},"152.0",[498,2218,2220],{"x":2131,"y":2219,"style":2108},"171.0","5",[469,2222],{"x":2102,"y":2216,"width":2103,"height":2128,"rx":472,"fill":475,"stroke":1118,"style":509},[498,2224,2225],{"x":2106,"y":2219,"style":2160},"A6–A8",[469,2227],{"x":2112,"y":2216,"width":2113,"height":2128,"rx":472,"fill":475,"stroke":1118,"style":509},[498,2229,2230],{"x":2116,"y":2219,"style":2160},"gradients",[469,2232],{"x":2120,"y":2216,"width":2121,"height":2128,"rx":472,"fill":475,"stroke":1118,"style":509},[498,2234,2235],{"x":2124,"y":2219,"style":2160},"approximated",[469,2237],{"x":2098,"y":1201,"width":1146,"height":2128,"rx":472,"fill":1143,"stroke":1118,"style":509},[498,2239,745],{"x":2131,"y":2240,"style":2108},"199.0",[469,2242],{"x":2102,"y":1201,"width":2103,"height":2128,"rx":472,"fill":475,"stroke":1118,"style":509},[498,2244,2245],{"x":2106,"y":2240,"style":2160},"A9",[469,2247],{"x":2112,"y":1201,"width":2113,"height":2128,"rx":472,"fill":475,"stroke":1118,"style":509},[498,2249,2250],{"x":2116,"y":2240,"style":2160},"fill_type None",[469,2252],{"x":2120,"y":1201,"width":2121,"height":2128,"rx":472,"fill":475,"stroke":1118,"style":509},[498,2254,2255],{"x":2124,"y":2240,"style":2160},"no fill ✓",[38,2257,2259],{"id":2258},"common-pitfalls","Common pitfalls",[2261,2262,2263,2277,2288,2302,2315,2321],"ul",{},[2264,2265,2266,2270,2271,2273,2274,2276],"li",{},[2267,2268,2269],"strong",{},"bgColor on solid fills."," The cell turns black; use ",[14,2272,292],{}," (",[14,2275,443],{},").",[2264,2278,2279,2282,2283,17,2285,2287],{},[2267,2280,2281],{},"Only one colour on conditional-format fills."," Set ",[14,2284,443],{},[14,2286,1327],{}," to the same value.",[2264,2289,2290,2295,2296,2298,2299,36],{},[2267,2291,2292,2294],{},[14,2293,447],{}," in colour codes."," Use ",[14,2297,297],{},", not ",[14,2300,2301],{},"\"#4338CA\"",[2264,2303,2304,2310,2311,2314],{},[2267,2305,2306,2307,36],{},"Assigning a string to ",[14,2308,2309],{},"cell.fill"," ",[14,2312,2313],{},"cell.fill = \"FFFF00\""," fails only when saving; always assign a fill object.",[2264,2316,2317,2320],{},[2267,2318,2319],{},"Judging patterns and gradients in LibreOffice output."," Its PDF render approximates them; check in Excel.",[2264,2322,2323,2326],{},[2267,2324,2325],{},"Too many distinct fills."," Every unique fill adds a style; reuse a few named fill objects instead of creating a new one per cell.",[38,2328,2330],{"id":2329},"conclusion","Conclusion",[10,2332,2333,2334,2337,2338,596,2340,218,2342,2344,2345,2348],{},"Use ",[14,2335,2336],{},"PatternFill(\"solid\", fgColor=...)"," for plain colours — the foreground is what a solid fill paints, and a bgColor-only fill renders black. Other patterns draw ",[14,2339,292],{},[14,2341,29],{},[14,2343,20],{}," blends stops linearly by angle or outwards along a path, conditional-format fills should set both colours, and ",[14,2346,2347],{},"PatternFill(fill_type=None)"," clears a fill. Render the sheet and sample the colours when fills carry meaning, keeping in mind that LibreOffice approximates patterns and gradients.",[38,2350,2352],{"id":2351},"frequently-asked-questions","Frequently asked questions",[10,2354,2355,2358],{},[2267,2356,2357],{},"Why is my openpyxl cell fill black?","\nYou created a solid PatternFill with only bgColor. A solid fill shows the foreground colour, which defaults to black. Use PatternFill(\"solid\", fgColor=\"4338CA\") instead.",[10,2360,2361,2364],{},[2267,2362,2363],{},"How do I add a gradient fill to a cell with openpyxl?","\nAssign a GradientFill, for example cell.fill = GradientFill(type=\"linear\", degree=90, stop=(\"FFFFFF\", \"4338CA\")). Use type=\"path\" with left, right, top and bottom for a gradient that radiates from a point.",[10,2366,2367,2370],{},[2267,2368,2369],{},"What is the difference between fgColor and bgColor in openpyxl?","\nfgColor is the pattern colour and bgColor the colour behind the pattern. For a solid fill only fgColor is visible; for hatched patterns both are used.",[10,2372,2373,2376],{},[2267,2374,2375],{},"How do I remove a fill from a cell in openpyxl?","\nAssign PatternFill(fill_type=None) to the cell's fill. Other formatting such as fonts and borders is left unchanged.",[38,2378,2380],{"id":2379},"related","Related",[2261,2382,2383,2389,2396,2403],{},[2264,2384,2385,2386,2388],{},"Up one level: ",[32,2387,35],{"href":34}," — formatting cells for reports.",[2264,2390,2391,2395],{},[32,2392,2394],{"href":2393},"\u002Fformatting-and-charting-excel-reports-with-python\u002Fstyling-excel-cells-with-openpyxl\u002Fadd-alternating-row-colors-with-openpyxl\u002F","Add Alternating Row Colors with openpyxl"," — fills applied as banding.",[2264,2397,2398,2402],{},[32,2399,2401],{"href":2400},"\u002Fformatting-and-charting-excel-reports-with-python\u002Fstyling-excel-cells-with-openpyxl\u002Fapply-a-reusable-style-theme-across-an-excel-report\u002F","Apply a Reusable Style Theme Across an Excel Report"," — keeping fills consistent.",[2264,2404,2405,2409],{},[32,2406,2408],{"href":2407},"\u002Fadvanced-data-transformation-and-cleaning\u002Fextracting-data-from-messy-excel-sheets\u002Fread-cell-colours-and-font-styles-as-data-with-openpyxl\u002F","Read Cell Colours and Font Styles as Data with openpyxl"," — reading fills back.",[2411,2412,2413],"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 .sSjpA, html code.shiki .sSjpA{--shiki-default:#005CC5;--shiki-dark:#FF9492}html pre.shiki code .s-wDw, html code.shiki .s-wDw{--shiki-default:#6A737D;--shiki-dark:#BDC4CC}",{"title":48,"searchDepth":110,"depth":110,"links":2415},[2416,2417,2418,2419,2420,2421,2422,2423,2424,2425,2426],{"id":40,"depth":110,"text":41},{"id":83,"depth":110,"text":84},{"id":589,"depth":110,"text":590},{"id":780,"depth":110,"text":781},{"id":1234,"depth":110,"text":1235},{"id":1498,"depth":110,"text":1499},{"id":1621,"depth":110,"text":1622},{"id":2258,"depth":110,"text":2259},{"id":2329,"depth":110,"text":2330},{"id":2351,"depth":110,"text":2352},{"id":2379,"depth":110,"text":2380},"2026-10-02","Fill cells with solid colours, hatching patterns and two-colour gradients from Python: which colour a solid PatternFill really uses (and why a bgColor-only fill turns black), the pattern types and their foreground\u002Fbackground colours, linear and path GradientFill, fills in conditional formats, removing fills, and a rendered check of what each one looks like.","md",[2431,2433,2435,2437],{"q":2357,"a":2432},"You created a solid PatternFill with only bgColor. A solid fill shows the foreground colour, which defaults to black. Use PatternFill(\"solid\", fgColor=\"4338CA\") instead.",{"q":2363,"a":2434},"Assign a GradientFill, for example cell.fill = GradientFill(type=\"linear\", degree=90, stop=(\"FFFFFF\", \"4338CA\")). Use type=\"path\" with left, right, top and bottom for a gradient that radiates from a point.",{"q":2369,"a":2436},"fgColor is the pattern colour and bgColor the colour behind the pattern. For a solid fill only fgColor is visible; for hatched patterns both are used.",{"q":2375,"a":2438},"Assign PatternFill(fill_type=None) to the cell's fill. Other formatting such as fonts and borders is left unchanged.","apply gradient and pattern fills with openpyxl",null,{"breadcrumb":2442},[2443,2445,2448],{"name":2444,"item":764},"Home",{"name":2446,"item":2447},"Formatting and Charting Excel Reports with Python","\u002Fformatting-and-charting-excel-reports-with-python\u002F",{"name":35,"item":34},"\u002Fformatting-and-charting-excel-reports-with-python\u002Fstyling-excel-cells-with-openpyxl\u002Fapply-gradient-and-pattern-fills-with-openpyxl",{"title":2451,"description":2452},"Gradient and Pattern Fills in Excel with openpyxl","PatternFill and GradientFill in openpyxl: solid fills use fgColor (a bgColor-only fill renders black), darkTrellis and other patterns with two colours, linear and path gradients with stops, conditional-format fills, clearing fills, and a PDF render to verify.","apply-gradient-and-pattern-fills-with-openpyxl","formatting-and-charting-excel-reports-with-python\u002Fstyling-excel-cells-with-openpyxl\u002Fapply-gradient-and-pattern-fills-with-openpyxl\u002Findex",[2456,2457],"cell-styling","openpyxl","how-to","eduRF1lo4QyfLpKA-KhN64HvRdKlndeo5RWXLEKt0YM",[2461,2465],{"title":2462,"path":2463,"stem":2464,"children":-1},"Apply Built-In Cell Styles Like Good, Bad and Neutral","\u002Fformatting-and-charting-excel-reports-with-python\u002Fstyling-excel-cells-with-openpyxl\u002Fapply-built-in-cell-styles-like-good-bad-and-neutral","formatting-and-charting-excel-reports-with-python\u002Fstyling-excel-cells-with-openpyxl\u002Fapply-built-in-cell-styles-like-good-bad-and-neutral\u002Findex",{"title":2466,"path":2467,"stem":2468,"children":-1},"Build a Calendar Sheet in Excel with Python","\u002Fformatting-and-charting-excel-reports-with-python\u002Fstyling-excel-cells-with-openpyxl\u002Fbuild-a-calendar-sheet-in-excel-with-python","formatting-and-charting-excel-reports-with-python\u002Fstyling-excel-cells-with-openpyxl\u002Fbuild-a-calendar-sheet-in-excel-with-python\u002Findex",[2470,2472],{"path":2471,"title":2446},"\u002Fformatting-and-charting-excel-reports-with-python",{"path":2473,"title":35},"\u002Fformatting-and-charting-excel-reports-with-python\u002Fstyling-excel-cells-with-openpyxl",[],[2476,2479,2482,2485,2488,2491],{"path":2477,"title":2478,"kind":2458},"\u002Fformatting-and-charting-excel-reports-with-python\u002Fbuilding-excel-reports-with-xlsxwriter\u002Fwrite-rich-text-in-a-cell-with-xlsxwriter","Write Rich Text with Mixed Formats in One Cell with xlsxwriter",{"path":2480,"title":2481,"kind":2458},"\u002Fgetting-started-with-python-excel-automation\u002Fusing-openpyxl-for-excel-file-manipulation\u002Fcopy-cell-styles-with-openpyxl","Copy Cell Styles from One Cell to Another with openpyxl",{"path":2483,"title":2484,"kind":2458},"\u002Fgetting-started-with-python-excel-automation\u002Fwriting-dataframes-to-excel-with-pandas\u002Fauto-fit-column-widths-when-writing-with-pandas","Auto-Fit Column Widths When Writing with pandas",{"path":2486,"title":2487,"kind":2458},"\u002Fgetting-started-with-python-excel-automation\u002Fwriting-dataframes-to-excel-with-pandas\u002Fexport-a-styled-pandas-dataframe-to-excel","Export a Styled pandas DataFrame to Excel",{"path":2489,"title":2490,"kind":2458},"\u002Fautomating-reporting-workflows\u002Fbuilding-finance-and-operations-reports\u002Fgenerate-a-staff-rota-in-excel-with-python","Generate a Staff Rota in Excel with Python",{"path":2492,"title":2493,"kind":2458},"\u002Fautomating-reporting-workflows\u002Fbuilding-multi-sheet-excel-dashboards\u002Fadd-a-table-of-contents-sheet-with-hyperlinks-in-excel","Add a Table of Contents Sheet with Hyperlinks in Excel",1790972117206]