[{"data":1,"prerenderedAt":2354},["ShallowReactive",2],{"doc:\u002Fgetting-started-with-python-excel-automation\u002Fusing-openpyxl-for-excel-file-manipulation\u002Funmerge-cells-and-fill-values-with-openpyxl":3,"surround:\u002Fgetting-started-with-python-excel-automation\u002Fusing-openpyxl-for-excel-file-manipulation\u002Funmerge-cells-and-fill-values-with-openpyxl":2320,"ancestors:\u002Fgetting-started-with-python-excel-automation\u002Fusing-openpyxl-for-excel-file-manipulation\u002Funmerge-cells-and-fill-values-with-openpyxl":2329,"children:\u002Fgetting-started-with-python-excel-automation\u002Fusing-openpyxl-for-excel-file-manipulation\u002Funmerge-cells-and-fill-values-with-openpyxl":2334,"related:\u002Fgetting-started-with-python-excel-automation\u002Fusing-openpyxl-for-excel-file-manipulation\u002Funmerge-cells-and-fill-values-with-openpyxl":2335},{"id":4,"title":5,"body":6,"dateModified":2286,"datePublished":2286,"description":2287,"extension":2288,"faq":2289,"keyword":2298,"kind":2299,"meta":2300,"navigation":449,"path":2309,"seo":2310,"slug":2313,"stem":2314,"topics":2315,"type":2318,"__hash__":2319},"docs\u002Fgetting-started-with-python-excel-automation\u002Fusing-openpyxl-for-excel-file-manipulation\u002Funmerge-cells-and-fill-values-with-openpyxl\u002Findex.md","Unmerge Cells and Fill the Values with openpyxl",{"type":7,"value":8,"toc":2273},"minimark",[9,19,372,377,405,408,721,725,728,866,898,902,910,1126,1137,1296,1300,1303,1543,1554,1558,1561,1890,1897,2007,2010,2014,2017,2119,2130,2134,2178,2182,2196,2200,2209,2213,2219,2225,2231,2237,2241,2270],[10,11,12,13,18],"p",{},"Merged cells are the most common reason a sheet that looks like a table does not behave like one. A region name merged down over five rows reads fine on screen, but Excel stores it only once, in the top-left cell; the other four cells are empty. Sort the sheet and the region detaches from its rows; read it with a script and four rows have no region at all. The fix is to unmerge every range and copy the value into each cell it used to cover. This guide, part of ",[14,15,17],"a",{"href":16},"\u002Fgetting-started-with-python-excel-automation\u002Fusing-openpyxl-for-excel-file-manipulation\u002F","Using openpyxl for Excel File Manipulation",", does that with openpyxl, keeps the formatting, and covers the cases where merge information is not available.",[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,120,29,125,29,127,29,131,29,133,29,136,29,139,29,142,29,144,29,147,29,149,29,152,29,155,29,159,29,161,29,164,29,166,29,169,29,172,29,176,29,179,29,183,29,185,29,188,29,190,29,193,29,196,29,200,29,202,29,205,29,207,29,210,29,213,29,216,29,219,29,222,29,225,29,228,29,231,29,233,29,236,29,238,29,240,29,242,29,244,29,246,29,248,29,250,29,252,29,256,29,259,29,261,29,263,29,265,29,267,29,269,29,271,29,273,29,275,29,277,29,279,29,281,29,283,29,285,29,287,29,289,29,291,29,293,29,295,29,297,29,299,29,301,29,303,29,305,29,307,29,309,29,311,29,313,29,315,29,317,29,319,29,321,29,323,29,325,29,327,29,329,29,331,29,337,29,341,29,348,29,353,29,361,29,367],"svg",{"viewBox":22,"role":23,"ariaLabelledBy":24,"xmlns":27,"style":28},"76 0 607 274","img",[25,26],"unmerge-before-after-t","unmerge-before-after-d","http:\u002F\u002Fwww.w3.org\u002F2000\u002Fsvg","width:100%;max-width:607px;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},"Unmerging a merged region column and filling its values",[35,36,37],"desc",{"id":26},"Before, North is merged over three rows and South over two, so only the first row of each group holds a value. After unmerging and filling, every row carries its region, which makes the sheet sortable and filterable.",[39,40],"rect",{"x":41,"y":42,"width":43,"height":44,"fill":45},"76","0","607","274","#ffffff",[39,47],{"x":48,"y":49,"width":50,"height":51,"rx":42,"fill":52,"stroke":53,"style":54},"92.6","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},"124.6","66.7",[60,61,65],"text",{"x":62,"y":63,"style":64},"157.9","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},"191.3","48.6",[60,71,73],{"x":72,"y":63,"style":64},"215.6","B",[39,75],{"x":76,"y":49,"width":77,"height":51,"rx":42,"fill":52,"stroke":53,"style":54},"239.9","44.0",[60,79,81],{"x":80,"y":63,"style":64},"261.9","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},"108.6","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","Region",[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},"Rep",[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},"Q1",[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":116,"rx":42,"fill":117,"stroke":118,"style":119},"84.0","#f0f4ff","var(--brand,#5b5cf0)","stroke-width:1.5px",[60,121,124],{"x":62,"y":122,"style":123},"139.0","font-size:12px;font-weight:700;fill:var(--brand-strong,#4338ca);text-anchor:middle","North",[39,126],{"x":68,"y":109,"width":69,"height":85,"rx":42,"fill":45,"stroke":53,"style":54},[60,128,130],{"x":72,"y":112,"style":129},"font-size:12px;font-weight:400;fill:var(--text,#172033);text-anchor:middle","Ana",[39,132],{"x":76,"y":109,"width":77,"height":85,"rx":42,"fill":45,"stroke":53,"style":54},[60,134,135],{"x":80,"y":112,"style":129},"10",[39,137],{"x":48,"y":138,"width":50,"height":85,"rx":42,"fill":52,"stroke":53,"style":54},"120.0",[60,140,141],{"x":88,"y":122,"style":64},"3",[39,143],{"x":68,"y":138,"width":69,"height":85,"rx":42,"fill":45,"stroke":53,"style":54},[60,145,146],{"x":72,"y":122,"style":129},"Ben",[39,148],{"x":76,"y":138,"width":77,"height":85,"rx":42,"fill":45,"stroke":53,"style":54},[60,150,151],{"x":80,"y":122,"style":129},"12",[39,153],{"x":48,"y":154,"width":50,"height":85,"rx":42,"fill":52,"stroke":53,"style":54},"148.0",[60,156,158],{"x":88,"y":157,"style":64},"167.0","4",[39,160],{"x":68,"y":154,"width":69,"height":85,"rx":42,"fill":45,"stroke":53,"style":54},[60,162,163],{"x":72,"y":157,"style":129},"Cy",[39,165],{"x":76,"y":154,"width":77,"height":85,"rx":42,"fill":45,"stroke":53,"style":54},[60,167,168],{"x":80,"y":157,"style":129},"9",[39,170],{"x":48,"y":171,"width":50,"height":85,"rx":42,"fill":52,"stroke":53,"style":54},"176.0",[60,173,175],{"x":88,"y":174,"style":64},"195.0","5",[39,177],{"x":57,"y":171,"width":58,"height":178,"rx":42,"fill":117,"stroke":118,"style":119},"56.0",[60,180,182],{"x":62,"y":181,"style":123},"209.0","South",[39,184],{"x":68,"y":171,"width":69,"height":85,"rx":42,"fill":45,"stroke":53,"style":54},[60,186,187],{"x":72,"y":174,"style":129},"Dee",[39,189],{"x":76,"y":171,"width":77,"height":85,"rx":42,"fill":45,"stroke":53,"style":54},[60,191,192],{"x":80,"y":174,"style":129},"7",[39,194],{"x":48,"y":195,"width":50,"height":85,"rx":42,"fill":52,"stroke":53,"style":54},"204.0",[60,197,199],{"x":88,"y":198,"style":64},"223.0","6",[39,201],{"x":68,"y":195,"width":69,"height":85,"rx":42,"fill":45,"stroke":53,"style":54},[60,203,204],{"x":72,"y":198,"style":129},"Eve",[39,206],{"x":76,"y":195,"width":77,"height":85,"rx":42,"fill":45,"stroke":53,"style":54},[60,208,209],{"x":80,"y":198,"style":129},"8",[39,211],{"x":212,"y":49,"width":50,"height":51,"rx":42,"fill":52,"stroke":53,"style":54},"476.1",[39,214],{"x":215,"y":49,"width":58,"height":51,"rx":42,"fill":52,"stroke":53,"style":54},"508.1",[60,217,65],{"x":218,"y":63,"style":64},"541.5",[39,220],{"x":221,"y":49,"width":69,"height":51,"rx":42,"fill":52,"stroke":53,"style":54},"574.8",[60,223,73],{"x":224,"y":63,"style":64},"599.1",[39,226],{"x":227,"y":49,"width":77,"height":51,"rx":42,"fill":52,"stroke":53,"style":54},"623.4",[60,229,81],{"x":230,"y":63,"style":64},"645.4",[39,232],{"x":212,"y":84,"width":50,"height":85,"rx":42,"fill":52,"stroke":53,"style":54},[60,234,90],{"x":235,"y":89,"style":64},"492.1",[39,237],{"x":215,"y":84,"width":58,"height":85,"rx":42,"fill":52,"stroke":53,"style":119},[60,239,96],{"x":218,"y":89,"style":95},[39,241],{"x":221,"y":84,"width":69,"height":85,"rx":42,"fill":45,"stroke":53,"style":54},[60,243,101],{"x":224,"y":89,"style":95},[39,245],{"x":227,"y":84,"width":77,"height":85,"rx":42,"fill":45,"stroke":53,"style":54},[60,247,106],{"x":230,"y":89,"style":95},[39,249],{"x":212,"y":109,"width":50,"height":85,"rx":42,"fill":52,"stroke":53,"style":54},[60,251,113],{"x":235,"y":112,"style":64},[39,253],{"x":215,"y":109,"width":58,"height":85,"rx":42,"fill":254,"stroke":255,"style":119},"#d9f4f1","var(--teal,#0f9488)",[60,257,124],{"x":218,"y":112,"style":258},"font-size:12px;font-weight:700;fill:var(--teal-ink,#0b6157);text-anchor:middle",[39,260],{"x":221,"y":109,"width":69,"height":85,"rx":42,"fill":45,"stroke":53,"style":54},[60,262,130],{"x":224,"y":112,"style":129},[39,264],{"x":227,"y":109,"width":77,"height":85,"rx":42,"fill":45,"stroke":53,"style":54},[60,266,135],{"x":230,"y":112,"style":129},[39,268],{"x":212,"y":138,"width":50,"height":85,"rx":42,"fill":52,"stroke":53,"style":54},[60,270,141],{"x":235,"y":122,"style":64},[39,272],{"x":215,"y":138,"width":58,"height":85,"rx":42,"fill":254,"stroke":255,"style":119},[60,274,124],{"x":218,"y":122,"style":258},[39,276],{"x":221,"y":138,"width":69,"height":85,"rx":42,"fill":45,"stroke":53,"style":54},[60,278,146],{"x":224,"y":122,"style":129},[39,280],{"x":227,"y":138,"width":77,"height":85,"rx":42,"fill":45,"stroke":53,"style":54},[60,282,151],{"x":230,"y":122,"style":129},[39,284],{"x":212,"y":154,"width":50,"height":85,"rx":42,"fill":52,"stroke":53,"style":54},[60,286,158],{"x":235,"y":157,"style":64},[39,288],{"x":215,"y":154,"width":58,"height":85,"rx":42,"fill":254,"stroke":255,"style":119},[60,290,124],{"x":218,"y":157,"style":258},[39,292],{"x":221,"y":154,"width":69,"height":85,"rx":42,"fill":45,"stroke":53,"style":54},[60,294,163],{"x":224,"y":157,"style":129},[39,296],{"x":227,"y":154,"width":77,"height":85,"rx":42,"fill":45,"stroke":53,"style":54},[60,298,168],{"x":230,"y":157,"style":129},[39,300],{"x":212,"y":171,"width":50,"height":85,"rx":42,"fill":52,"stroke":53,"style":54},[60,302,175],{"x":235,"y":174,"style":64},[39,304],{"x":215,"y":171,"width":58,"height":85,"rx":42,"fill":254,"stroke":255,"style":119},[60,306,182],{"x":218,"y":174,"style":258},[39,308],{"x":221,"y":171,"width":69,"height":85,"rx":42,"fill":45,"stroke":53,"style":54},[60,310,187],{"x":224,"y":174,"style":129},[39,312],{"x":227,"y":171,"width":77,"height":85,"rx":42,"fill":45,"stroke":53,"style":54},[60,314,192],{"x":230,"y":174,"style":129},[39,316],{"x":212,"y":195,"width":50,"height":85,"rx":42,"fill":52,"stroke":53,"style":54},[60,318,199],{"x":235,"y":198,"style":64},[39,320],{"x":215,"y":195,"width":58,"height":85,"rx":42,"fill":254,"stroke":255,"style":119},[60,322,182],{"x":218,"y":198,"style":258},[39,324],{"x":221,"y":195,"width":69,"height":85,"rx":42,"fill":45,"stroke":53,"style":54},[60,326,204],{"x":224,"y":198,"style":129},[39,328],{"x":227,"y":195,"width":77,"height":85,"rx":42,"fill":45,"stroke":53,"style":54},[60,330,209],{"x":230,"y":198,"style":129},[60,332,336],{"x":333,"y":334,"style":335},"188.2","29.0","font-size:12.5px;font-weight:700;fill:var(--muted,#5b6780);text-anchor:middle","before",[60,338,340],{"x":339,"y":334,"style":335},"571.8","after",[342,343],"line",{"x1":344,"y1":345,"x2":346,"y2":345,"stroke":118,"style":347},"293.9","136.0","462.1","stroke-width:2px",[349,350],"polygon",{"points":351,"fill":352},"466.1,136.0 457.1,141.0 457.1,131.0","#5b5cf0",[39,354],{"x":355,"y":356,"width":357,"height":358,"rx":359,"fill":45,"stroke":53,"style":360},"319.1","103.0","121.8","22.0","11","stroke-width:1.2px",[60,362,366],{"x":363,"y":364,"style":365},"380.0","118.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","unmerge + fill",[60,368,371],{"x":363,"y":369,"style":370},"254.0","font-size:12.5px;font-weight:400;fill:var(--muted,#5b6780);text-anchor:middle","the merged value lives only in the top-left cell; after filling, every row carries its own key",[373,374,376],"h2",{"id":375},"prerequisites","Prerequisites",[378,379,384],"pre",{"className":380,"code":381,"language":382,"meta":383,"style":383},"language-bash shiki shiki-themes github-light github-dark-high-contrast","pip install openpyxl pandas\n","bash","",[385,386,387],"code",{"__ignoreMap":383},[388,389,391,395,399,402],"span",{"class":342,"line":390},1,[388,392,394],{"class":393},"sMTad","pip",[388,396,398],{"class":397},"srMev"," install",[388,400,401],{"class":397}," openpyxl",[388,403,404],{"class":397}," pandas\n",[10,406,407],{},"The example sheet has regions merged down column A and a note merged across D1:E1 — one vertical and one horizontal merge:",[378,409,413],{"className":410,"code":411,"language":412,"meta":383,"style":383},"language-python shiki shiki-themes github-light github-dark-high-contrast","from openpyxl import Workbook, load_workbook\nfrom openpyxl.styles import Alignment, Border, Side\n\nwb = Workbook()\nws = wb.active\nws.title = \"Reps\"\nfor row in [[\"Region\", \"Rep\", \"Q1\"], [\"North\", \"Ana\", 10], [None, \"Ben\", 12],\n            [None, \"Cy\", 9], [\"South\", \"Dee\", 7], [None, \"Eve\", 8]]:\n    ws.append(row)\nws[\"D1\"] = \"Provisional\"\nws.merge_cells(\"A2:A4\")\nws.merge_cells(\"A5:A6\")\nws.merge_cells(\"D1:E1\")\nws[\"A2\"].alignment = Alignment(vertical=\"center\")\nws[\"A2\"].border = Border(left=Side(style=\"thin\"))\nwb.save(\"merged.xlsx\")\n","python",[385,414,415,431,444,451,463,474,485,547,594,600,617,629,639,649,676,710],{"__ignoreMap":383},[388,416,417,421,425,428],{"class":342,"line":390},[388,418,420],{"class":419},"s-kum","from",[388,422,424],{"class":423},"skGVy"," openpyxl ",[388,426,427],{"class":419},"import",[388,429,430],{"class":423}," Workbook, load_workbook\n",[388,432,434,436,439,441],{"class":342,"line":433},2,[388,435,420],{"class":419},[388,437,438],{"class":423}," openpyxl.styles ",[388,440,427],{"class":419},[388,442,443],{"class":423}," Alignment, Border, Side\n",[388,445,447],{"class":342,"line":446},3,[388,448,450],{"emptyLinePlaceholder":449},true,"\n",[388,452,454,457,460],{"class":342,"line":453},4,[388,455,456],{"class":423},"wb ",[388,458,459],{"class":419},"=",[388,461,462],{"class":423}," Workbook()\n",[388,464,466,469,471],{"class":342,"line":465},5,[388,467,468],{"class":423},"ws ",[388,470,459],{"class":419},[388,472,473],{"class":423}," wb.active\n",[388,475,477,480,482],{"class":342,"line":476},6,[388,478,479],{"class":423},"ws.title ",[388,481,459],{"class":419},[388,483,484],{"class":397}," \"Reps\"\n",[388,486,488,491,494,497,500,503,506,509,511,514,517,520,522,525,527,530,532,535,537,540,542,544],{"class":342,"line":487},7,[388,489,490],{"class":419},"for",[388,492,493],{"class":423}," row ",[388,495,496],{"class":419},"in",[388,498,499],{"class":423}," [[",[388,501,502],{"class":397},"\"Region\"",[388,504,505],{"class":423},", ",[388,507,508],{"class":397},"\"Rep\"",[388,510,505],{"class":423},[388,512,513],{"class":397},"\"Q1\"",[388,515,516],{"class":423},"], [",[388,518,519],{"class":397},"\"North\"",[388,521,505],{"class":423},[388,523,524],{"class":397},"\"Ana\"",[388,526,505],{"class":423},[388,528,135],{"class":529},"sP0c6",[388,531,516],{"class":423},[388,533,534],{"class":529},"None",[388,536,505],{"class":423},[388,538,539],{"class":397},"\"Ben\"",[388,541,505],{"class":423},[388,543,151],{"class":529},[388,545,546],{"class":423},"],\n",[388,548,550,553,555,557,560,562,564,566,569,571,574,576,578,580,582,584,587,589,591],{"class":342,"line":549},8,[388,551,552],{"class":423},"            [",[388,554,534],{"class":529},[388,556,505],{"class":423},[388,558,559],{"class":397},"\"Cy\"",[388,561,505],{"class":423},[388,563,168],{"class":529},[388,565,516],{"class":423},[388,567,568],{"class":397},"\"South\"",[388,570,505],{"class":423},[388,572,573],{"class":397},"\"Dee\"",[388,575,505],{"class":423},[388,577,192],{"class":529},[388,579,516],{"class":423},[388,581,534],{"class":529},[388,583,505],{"class":423},[388,585,586],{"class":397},"\"Eve\"",[388,588,505],{"class":423},[388,590,209],{"class":529},[388,592,593],{"class":423},"]]:\n",[388,595,597],{"class":342,"line":596},9,[388,598,599],{"class":423},"    ws.append(row)\n",[388,601,603,606,609,612,614],{"class":342,"line":602},10,[388,604,605],{"class":423},"ws[",[388,607,608],{"class":397},"\"D1\"",[388,610,611],{"class":423},"] ",[388,613,459],{"class":419},[388,615,616],{"class":397}," \"Provisional\"\n",[388,618,620,623,626],{"class":342,"line":619},11,[388,621,622],{"class":423},"ws.merge_cells(",[388,624,625],{"class":397},"\"A2:A4\"",[388,627,628],{"class":423},")\n",[388,630,632,634,637],{"class":342,"line":631},12,[388,633,622],{"class":423},[388,635,636],{"class":397},"\"A5:A6\"",[388,638,628],{"class":423},[388,640,642,644,647],{"class":342,"line":641},13,[388,643,622],{"class":423},[388,645,646],{"class":397},"\"D1:E1\"",[388,648,628],{"class":423},[388,650,652,654,657,660,662,665,669,671,674],{"class":342,"line":651},14,[388,653,605],{"class":423},[388,655,656],{"class":397},"\"A2\"",[388,658,659],{"class":423},"].alignment ",[388,661,459],{"class":419},[388,663,664],{"class":423}," Alignment(",[388,666,668],{"class":667},"sa561","vertical",[388,670,459],{"class":419},[388,672,673],{"class":397},"\"center\"",[388,675,628],{"class":423},[388,677,679,681,683,686,688,691,694,696,699,702,704,707],{"class":342,"line":678},15,[388,680,605],{"class":423},[388,682,656],{"class":397},[388,684,685],{"class":423},"].border ",[388,687,459],{"class":419},[388,689,690],{"class":423}," Border(",[388,692,693],{"class":667},"left",[388,695,459],{"class":419},[388,697,698],{"class":423},"Side(",[388,700,701],{"class":667},"style",[388,703,459],{"class":419},[388,705,706],{"class":397},"\"thin\"",[388,708,709],{"class":423},"))\n",[388,711,713,716,719],{"class":342,"line":712},16,[388,714,715],{"class":423},"wb.save(",[388,717,718],{"class":397},"\"merged.xlsx\"",[388,720,628],{"class":423},[373,722,724],{"id":723},"step-1-see-what-openpyxl-gives-you-for-a-merged-range","Step 1 — See what openpyxl gives you for a merged range",[10,726,727],{},"Load the workbook normally and look at a cell inside a merged range:",[378,729,731],{"className":410,"code":730,"language":412,"meta":383,"style":383},"ws = load_workbook(\"merged.xlsx\")[\"Reps\"]\nprint(type(ws[\"A3\"]).__name__, ws[\"A3\"].value)   # MergedCell None\nprint(sorted(r.coord for r in ws.merged_cells.ranges))\n# ['A2:A4', 'A5:A6', 'D1:E1']\n\ntry:\n    ws[\"A3\"] = \"North\"\nexcept AttributeError as exc:\n    print(exc)                                    # 'MergedCell' object attribute 'value' is read-only\n",[385,732,733,753,788,810,815,819,827,841,855],{"__ignoreMap":383},[388,734,735,737,739,742,744,747,750],{"class":342,"line":390},[388,736,468],{"class":423},[388,738,459],{"class":419},[388,740,741],{"class":423}," load_workbook(",[388,743,718],{"class":397},[388,745,746],{"class":423},")[",[388,748,749],{"class":397},"\"Reps\"",[388,751,752],{"class":423},"]\n",[388,754,755,758,761,764,767,770,773,776,779,781,784],{"class":342,"line":433},[388,756,757],{"class":529},"print",[388,759,760],{"class":423},"(",[388,762,763],{"class":529},"type",[388,765,766],{"class":423},"(ws[",[388,768,769],{"class":397},"\"A3\"",[388,771,772],{"class":423},"]).",[388,774,775],{"class":529},"__name__",[388,777,778],{"class":423},", ws[",[388,780,769],{"class":397},[388,782,783],{"class":423},"].value)   ",[388,785,787],{"class":786},"s-wDw","# MergedCell None\n",[388,789,790,792,794,797,800,802,805,807],{"class":342,"line":446},[388,791,757],{"class":529},[388,793,760],{"class":423},[388,795,796],{"class":529},"sorted",[388,798,799],{"class":423},"(r.coord ",[388,801,490],{"class":419},[388,803,804],{"class":423}," r ",[388,806,496],{"class":419},[388,808,809],{"class":423}," ws.merged_cells.ranges))\n",[388,811,812],{"class":342,"line":453},[388,813,814],{"class":786},"# ['A2:A4', 'A5:A6', 'D1:E1']\n",[388,816,817],{"class":342,"line":465},[388,818,450],{"emptyLinePlaceholder":449},[388,820,821,824],{"class":342,"line":476},[388,822,823],{"class":419},"try",[388,825,826],{"class":423},":\n",[388,828,829,832,834,836,838],{"class":342,"line":487},[388,830,831],{"class":423},"    ws[",[388,833,769],{"class":397},[388,835,611],{"class":423},[388,837,459],{"class":419},[388,839,840],{"class":397}," \"North\"\n",[388,842,843,846,849,852],{"class":342,"line":549},[388,844,845],{"class":419},"except",[388,847,848],{"class":529}," AttributeError",[388,850,851],{"class":419}," as",[388,853,854],{"class":423}," exc:\n",[388,856,857,860,863],{"class":342,"line":596},[388,858,859],{"class":529},"    print",[388,861,862],{"class":423},"(exc)                                    ",[388,864,865],{"class":786},"# 'MergedCell' object attribute 'value' is read-only\n",[10,867,868,869,872,873,876,877,880,881,505,884,505,887,505,890,893,894,897],{},"Every cell except the top-left of a range is a ",[385,870,871],{},"MergedCell"," — a placeholder with no value that refuses writes. ",[385,874,875],{},"ws.merged_cells.ranges"," lists the ranges as ",[385,878,879],{},"CellRange"," objects with ",[385,882,883],{},"min_row",[385,885,886],{},"max_row",[385,888,889],{},"min_col",[385,891,892],{},"max_col"," and a ",[385,895,896],{},"coord"," string, which is everything the fix needs.",[373,899,901],{"id":900},"step-2-unmerge-every-range-and-fill-it","Step 2 — Unmerge every range and fill it",[10,903,904,905,909],{},"For each range: remember the top-left value, unmerge, then write that value into every cell of the former range. Iterate over a ",[906,907,908],"em",{},"copy"," of the range list, because unmerging removes entries from the collection you are looping over:",[378,911,913],{"className":410,"code":912,"language":412,"meta":383,"style":383},"def unmerge_and_fill(ws) -> int:\n    ranges = list(ws.merged_cells.ranges)\n    for rng in ranges:\n        top_left = ws.cell(rng.min_row, rng.min_col)\n        value = top_left.value\n        ws.unmerge_cells(rng.coord)\n        for row in ws.iter_rows(min_row=rng.min_row, max_row=rng.max_row,\n                                min_col=rng.min_col, max_col=rng.max_col):\n            for cell in row:\n                cell.value = value\n    return len(ranges)\n\nprint(unmerge_and_fill(ws))                           # 3\nprint([ws.cell(r, 1).value for r in range(1, 7)])\n# ['Region', 'North', 'North', 'North', 'South', 'South']\nprint(ws[\"E1\"].value, ws.merged_cells.ranges)         # Provisional set()\n",[385,914,915,932,945,958,968,978,983,1009,1026,1039,1049,1060,1064,1074,1106,1111],{"__ignoreMap":383},[388,916,917,920,924,927,930],{"class":342,"line":390},[388,918,919],{"class":419},"def",[388,921,923],{"class":922},"s_Opv"," unmerge_and_fill",[388,925,926],{"class":423},"(ws) -> ",[388,928,929],{"class":529},"int",[388,931,826],{"class":423},[388,933,934,937,939,942],{"class":342,"line":433},[388,935,936],{"class":423},"    ranges ",[388,938,459],{"class":419},[388,940,941],{"class":529}," list",[388,943,944],{"class":423},"(ws.merged_cells.ranges)\n",[388,946,947,950,953,955],{"class":342,"line":446},[388,948,949],{"class":419},"    for",[388,951,952],{"class":423}," rng ",[388,954,496],{"class":419},[388,956,957],{"class":423}," ranges:\n",[388,959,960,963,965],{"class":342,"line":453},[388,961,962],{"class":423},"        top_left ",[388,964,459],{"class":419},[388,966,967],{"class":423}," ws.cell(rng.min_row, rng.min_col)\n",[388,969,970,973,975],{"class":342,"line":465},[388,971,972],{"class":423},"        value ",[388,974,459],{"class":419},[388,976,977],{"class":423}," top_left.value\n",[388,979,980],{"class":342,"line":476},[388,981,982],{"class":423},"        ws.unmerge_cells(rng.coord)\n",[388,984,985,988,990,992,995,997,999,1002,1004,1006],{"class":342,"line":487},[388,986,987],{"class":419},"        for",[388,989,493],{"class":423},[388,991,496],{"class":419},[388,993,994],{"class":423}," ws.iter_rows(",[388,996,883],{"class":667},[388,998,459],{"class":419},[388,1000,1001],{"class":423},"rng.min_row, ",[388,1003,886],{"class":667},[388,1005,459],{"class":419},[388,1007,1008],{"class":423},"rng.max_row,\n",[388,1010,1011,1014,1016,1019,1021,1023],{"class":342,"line":549},[388,1012,1013],{"class":667},"                                min_col",[388,1015,459],{"class":419},[388,1017,1018],{"class":423},"rng.min_col, ",[388,1020,892],{"class":667},[388,1022,459],{"class":419},[388,1024,1025],{"class":423},"rng.max_col):\n",[388,1027,1028,1031,1034,1036],{"class":342,"line":596},[388,1029,1030],{"class":419},"            for",[388,1032,1033],{"class":423}," cell ",[388,1035,496],{"class":419},[388,1037,1038],{"class":423}," row:\n",[388,1040,1041,1044,1046],{"class":342,"line":602},[388,1042,1043],{"class":423},"                cell.value ",[388,1045,459],{"class":419},[388,1047,1048],{"class":423}," value\n",[388,1050,1051,1054,1057],{"class":342,"line":619},[388,1052,1053],{"class":419},"    return",[388,1055,1056],{"class":529}," len",[388,1058,1059],{"class":423},"(ranges)\n",[388,1061,1062],{"class":342,"line":631},[388,1063,450],{"emptyLinePlaceholder":449},[388,1065,1066,1068,1071],{"class":342,"line":641},[388,1067,757],{"class":529},[388,1069,1070],{"class":423},"(unmerge_and_fill(ws))                           ",[388,1072,1073],{"class":786},"# 3\n",[388,1075,1076,1078,1081,1083,1086,1088,1090,1092,1095,1097,1099,1101,1103],{"class":342,"line":651},[388,1077,757],{"class":529},[388,1079,1080],{"class":423},"([ws.cell(r, ",[388,1082,90],{"class":529},[388,1084,1085],{"class":423},").value ",[388,1087,490],{"class":419},[388,1089,804],{"class":423},[388,1091,496],{"class":419},[388,1093,1094],{"class":529}," range",[388,1096,760],{"class":423},[388,1098,90],{"class":529},[388,1100,505],{"class":423},[388,1102,192],{"class":529},[388,1104,1105],{"class":423},")])\n",[388,1107,1108],{"class":342,"line":678},[388,1109,1110],{"class":786},"# ['Region', 'North', 'North', 'North', 'South', 'South']\n",[388,1112,1113,1115,1117,1120,1123],{"class":342,"line":712},[388,1114,757],{"class":529},[388,1116,766],{"class":423},[388,1118,1119],{"class":397},"\"E1\"",[388,1121,1122],{"class":423},"].value, ws.merged_cells.ranges)         ",[388,1124,1125],{"class":786},"# Provisional set()\n",[10,1127,1128,1129,1132,1133,1136],{},"The horizontal merge is handled by the same loop: ",[385,1130,1131],{},"D1:E1"," becomes two cells that both read ",[385,1134,1135],{},"Provisional",". Whether that is what you want depends on the range — for a label spanning two header columns, a duplicated label is usually right; for a title merged across a whole table, you probably want it in the first cell only. Step 4 shows how to choose per range.",[20,1138,29,1144,29,1147,29,1150,29,1154,29,1160,29,1171,29,1177,29,1182,29,1189,29,1193,29,1198,29,1201,29,1203,29,1210,29,1216,29,1220,29,1224,29,1228,29,1230,29,1234,29,1237,29,1240,29,1246,29,1250,29,1253,29,1256,29,1259,29,1261,29,1265,29,1268,29,1271,29,1278,29,1283,29,1286,29,1290,29,1292],{"viewBox":1139,"role":23,"ariaLabelledBy":1140,"xmlns":27,"style":1143},"4 0 752 176",[1141,1142],"unmerge-steps-t","unmerge-steps-d","width:100%;max-width:752px;height:auto;display:block;margin:1.5rem auto;font-family:Inter,ui-sans-serif,system-ui,sans-serif",[31,1145,1146],{"id":1141},"What unmerge_and_fill does for each merged range",[35,1148,1149],{"id":1142},"For each merged range, read the value from its top-left cell, call unmerge_cells so the placeholders become ordinary cells, write the saved value into every cell of the range, then copy the top-left style so the block keeps its look.",[39,1151],{"x":158,"y":42,"width":1152,"height":1153,"fill":45},"752","176",[39,1155],{"x":1156,"y":1157,"width":1158,"height":1159,"rx":151,"fill":52,"stroke":53,"style":347},"20.0","16.0","153.0","118.5",[1161,1162,1164],"g",{"transform":1163},"translate(84.5,41.8) scale(1.000)",[1165,1166],"path",{"d":1167,"fill":1168,"stroke":1169,"style":1170},"M11 4a7 7 0 1 0 .01 0z M16 16l5 5","none","var(--text,#172033)","stroke-width:1.80px;stroke-linecap:round;stroke-linejoin:round",[60,1172,1176],{"x":1173,"y":1174,"style":1175},"96.5","88.2","font-size:13.5px;font-weight:700;fill:var(--text,#172033);text-anchor:middle","Read top-left",[60,1178,1181],{"x":1173,"y":1179,"style":1180},"107.8","font-size:11.5px;font-weight:400;fill:var(--text,#172033);text-anchor:middle","the only stored value",[1183,1184],"circle",{"cx":1185,"cy":50,"r":1186,"fill":1187,"stroke":1168,"style":1188},"36.0","11.0","#5b6780","stroke-width:0px",[60,1190,90],{"x":1185,"y":1191,"style":1192},"36.5","font-size:12px;font-weight:700;fill:#ffffff;text-anchor:middle",[342,1194],{"x1":1195,"y1":1196,"x2":1197,"y2":1196,"stroke":118,"style":347},"178.0","75.2","200.0",[349,1199],{"points":1200,"fill":352},"204.0,75.2 195.0,80.2 195.0,70.2",[39,1202],{"x":181,"y":1157,"width":1158,"height":1159,"rx":151,"fill":117,"stroke":118,"style":347},[1161,1204,1206],{"transform":1205},"translate(273.5,33.0) scale(1.000)",[1165,1207],{"d":1208,"fill":1168,"stroke":1209,"style":1170},"M4 12h6 M10 12l6-6h4 M10 12l6 6h4 M17 3l3 3-3 3 M17 15l3 3-3 3","var(--brand-strong,#4338ca)",[60,1211,1215],{"x":1212,"y":1213,"style":1214},"285.5","79.5","font-size:13.5px;font-weight:700;fill:var(--brand-strong,#4338ca);text-anchor:middle","unmerge_cells",[60,1217,1219],{"x":1212,"y":1218,"style":1180},"99.0","placeholders become",[60,1221,1223],{"x":1212,"y":1222,"style":1180},"116.5","cells",[1183,1225],{"cx":1226,"cy":50,"r":1186,"fill":1227,"stroke":1168,"style":1188},"225.0","#4338ca",[60,1229,113],{"x":1226,"y":1191,"style":1192},[342,1231],{"x1":1232,"y1":1196,"x2":1233,"y2":1196,"stroke":118,"style":347},"367.0","389.0",[349,1235],{"points":1236,"fill":352},"393.0,75.2 384.0,80.2 384.0,70.2",[39,1238],{"x":1239,"y":1157,"width":1158,"height":1159,"rx":151,"fill":117,"stroke":118,"style":347},"398.0",[1161,1241,1243],{"transform":1242},"translate(462.5,33.0) scale(1.000)",[1165,1244],{"d":1245,"fill":1168,"stroke":1209,"style":1170},"M3 5h18v14H3z M3 10h18 M3 15h18 M9 5v14",[60,1247,1249],{"x":1248,"y":1213,"style":1214},"474.5","Fill the block",[60,1251,1252],{"x":1248,"y":1218,"style":1180},"same value",[60,1254,1255],{"x":1248,"y":1222,"style":1180},"everywhere",[1183,1257],{"cx":1258,"cy":50,"r":1186,"fill":1227,"stroke":1168,"style":1188},"414.0",[60,1260,141],{"x":1258,"y":1191,"style":1192},[342,1262],{"x1":1263,"y1":1196,"x2":1264,"y2":1196,"stroke":118,"style":347},"556.0","578.0",[349,1266],{"points":1267,"fill":352},"582.0,75.2 573.0,80.2 573.0,70.2",[39,1269],{"x":1270,"y":1157,"width":1158,"height":1159,"rx":151,"fill":254,"stroke":255,"style":347},"587.0",[1161,1272,1274],{"transform":1273},"translate(651.5,41.8) scale(1.000)",[1165,1275],{"d":1276,"fill":1168,"stroke":1277,"style":1170},"M12 3l9 5-9 5-9-5z M3 13l9 5 9-5 M3 17l9 5 9-5","var(--teal-ink,#0b6157)",[60,1279,1282],{"x":1280,"y":1174,"style":1281},"663.5","font-size:13.5px;font-weight:700;fill:var(--teal-ink,#0b6157);text-anchor:middle","Copy style",[60,1284,1285],{"x":1280,"y":1179,"style":1180},"borders, alignment",[1183,1287],{"cx":1288,"cy":50,"r":1186,"fill":1289,"stroke":1168,"style":1188},"603.0","#0b6157",[60,1291,158],{"x":1288,"y":1191,"style":1192},[60,1293,1295],{"x":363,"y":1294,"style":370},"156.5","loop over list(ws.merged_cells.ranges) — unmerging changes the collection while you iterate",[373,1297,1299],{"id":1298},"step-3-keep-the-formatting","Step 3 — Keep the formatting",[10,1301,1302],{},"Unmerging leaves the style on the top-left cell, but the newly ordinary cells take the default style, so a bordered, centred block can come out patchy. Copy the top-left cell's style to the rest of the range while filling:",[378,1304,1306],{"className":410,"code":1305,"language":412,"meta":383,"style":383},"from copy import copy\n\ndef unmerge_fill_styled(ws) -> None:\n    for rng in list(ws.merged_cells.ranges):\n        top_left = ws.cell(rng.min_row, rng.min_col)\n        value = top_left.value\n        styles = {a: copy(getattr(top_left, a)) for a in (\"font\", \"fill\", \"border\", \"alignment\", \"number_format\")}\n        ws.unmerge_cells(rng.coord)\n        for row in ws.iter_rows(min_row=rng.min_row, max_row=rng.max_row,\n                                min_col=rng.min_col, max_col=rng.max_col):\n            for cell in row:\n                cell.value = value\n                for attr, style in styles.items():\n                    setattr(cell, attr, copy(style))\n\nws = load_workbook(\"merged.xlsx\")[\"Reps\"]\nunmerge_fill_styled(ws)\nprint(ws[\"A3\"].alignment.vertical, ws[\"A3\"].border.left.style)   # center thin\n",[385,1307,1308,1320,1324,1337,1350,1358,1366,1418,1422,1444,1458,1468,1476,1489,1497,1501,1517,1523],{"__ignoreMap":383},[388,1309,1310,1312,1315,1317],{"class":342,"line":390},[388,1311,420],{"class":419},[388,1313,1314],{"class":423}," copy ",[388,1316,427],{"class":419},[388,1318,1319],{"class":423}," copy\n",[388,1321,1322],{"class":342,"line":433},[388,1323,450],{"emptyLinePlaceholder":449},[388,1325,1326,1328,1331,1333,1335],{"class":342,"line":446},[388,1327,919],{"class":419},[388,1329,1330],{"class":922}," unmerge_fill_styled",[388,1332,926],{"class":423},[388,1334,534],{"class":529},[388,1336,826],{"class":423},[388,1338,1339,1341,1343,1345,1347],{"class":342,"line":453},[388,1340,949],{"class":419},[388,1342,952],{"class":423},[388,1344,496],{"class":419},[388,1346,941],{"class":529},[388,1348,1349],{"class":423},"(ws.merged_cells.ranges):\n",[388,1351,1352,1354,1356],{"class":342,"line":465},[388,1353,962],{"class":423},[388,1355,459],{"class":419},[388,1357,967],{"class":423},[388,1359,1360,1362,1364],{"class":342,"line":476},[388,1361,972],{"class":423},[388,1363,459],{"class":419},[388,1365,977],{"class":423},[388,1367,1368,1371,1373,1376,1379,1382,1384,1387,1389,1392,1395,1397,1400,1402,1405,1407,1410,1412,1415],{"class":342,"line":487},[388,1369,1370],{"class":423},"        styles ",[388,1372,459],{"class":419},[388,1374,1375],{"class":423}," {a: copy(",[388,1377,1378],{"class":529},"getattr",[388,1380,1381],{"class":423},"(top_left, a)) ",[388,1383,490],{"class":419},[388,1385,1386],{"class":423}," a ",[388,1388,496],{"class":419},[388,1390,1391],{"class":423}," (",[388,1393,1394],{"class":397},"\"font\"",[388,1396,505],{"class":423},[388,1398,1399],{"class":397},"\"fill\"",[388,1401,505],{"class":423},[388,1403,1404],{"class":397},"\"border\"",[388,1406,505],{"class":423},[388,1408,1409],{"class":397},"\"alignment\"",[388,1411,505],{"class":423},[388,1413,1414],{"class":397},"\"number_format\"",[388,1416,1417],{"class":423},")}\n",[388,1419,1420],{"class":342,"line":549},[388,1421,982],{"class":423},[388,1423,1424,1426,1428,1430,1432,1434,1436,1438,1440,1442],{"class":342,"line":596},[388,1425,987],{"class":419},[388,1427,493],{"class":423},[388,1429,496],{"class":419},[388,1431,994],{"class":423},[388,1433,883],{"class":667},[388,1435,459],{"class":419},[388,1437,1001],{"class":423},[388,1439,886],{"class":667},[388,1441,459],{"class":419},[388,1443,1008],{"class":423},[388,1445,1446,1448,1450,1452,1454,1456],{"class":342,"line":602},[388,1447,1013],{"class":667},[388,1449,459],{"class":419},[388,1451,1018],{"class":423},[388,1453,892],{"class":667},[388,1455,459],{"class":419},[388,1457,1025],{"class":423},[388,1459,1460,1462,1464,1466],{"class":342,"line":619},[388,1461,1030],{"class":419},[388,1463,1033],{"class":423},[388,1465,496],{"class":419},[388,1467,1038],{"class":423},[388,1469,1470,1472,1474],{"class":342,"line":631},[388,1471,1043],{"class":423},[388,1473,459],{"class":419},[388,1475,1048],{"class":423},[388,1477,1478,1481,1484,1486],{"class":342,"line":641},[388,1479,1480],{"class":419},"                for",[388,1482,1483],{"class":423}," attr, style ",[388,1485,496],{"class":419},[388,1487,1488],{"class":423}," styles.items():\n",[388,1490,1491,1494],{"class":342,"line":651},[388,1492,1493],{"class":529},"                    setattr",[388,1495,1496],{"class":423},"(cell, attr, copy(style))\n",[388,1498,1499],{"class":342,"line":678},[388,1500,450],{"emptyLinePlaceholder":449},[388,1502,1503,1505,1507,1509,1511,1513,1515],{"class":342,"line":712},[388,1504,468],{"class":423},[388,1506,459],{"class":419},[388,1508,741],{"class":423},[388,1510,718],{"class":397},[388,1512,746],{"class":423},[388,1514,749],{"class":397},[388,1516,752],{"class":423},[388,1518,1520],{"class":342,"line":1519},17,[388,1521,1522],{"class":423},"unmerge_fill_styled(ws)\n",[388,1524,1526,1528,1530,1532,1535,1537,1540],{"class":342,"line":1525},18,[388,1527,757],{"class":529},[388,1529,766],{"class":423},[388,1531,769],{"class":397},[388,1533,1534],{"class":423},"].alignment.vertical, ws[",[388,1536,769],{"class":397},[388,1538,1539],{"class":423},"].border.left.style)   ",[388,1541,1542],{"class":786},"# center thin\n",[10,1544,1545,1546,1548,1549,1553],{},"Capture the styles ",[906,1547,336],{}," unmerging, while the top-left cell is guaranteed to hold them. The attribute-by-attribute copy is the same technique explained in ",[14,1550,1552],{"href":1551},"\u002Fgetting-started-with-python-excel-automation\u002Fusing-openpyxl-for-excel-file-manipulation\u002Fcopy-cell-styles-with-openpyxl\u002F","Copy Cell Styles from One Cell to Another with openpyxl",".",[373,1555,1557],{"id":1556},"step-4-decide-per-range-fill-keep-first-or-leave-merged","Step 4 — Decide per range: fill, keep first, or leave merged",[10,1559,1560],{},"Not every merge should be filled. A reasonable rule set: fill vertical merges inside the data area (those are keys), keep only the first cell for wide horizontal merges in the title rows (those are headings), and leave anything outside the table alone. Encode it as a small policy function:",[378,1562,1564],{"className":410,"code":1563,"language":412,"meta":383,"style":383},"def policy(rng, header_rows: int = 1) -> str:\n    if rng.max_row \u003C= header_rows and rng.max_col - rng.min_col >= 1:\n        return \"first\"          # a heading spanning columns\n    if rng.min_col == rng.max_col:\n        return \"fill\"           # a key merged down one column\n    return \"fill\"\n\ndef unmerge_with_policy(ws) -> dict:\n    counts = {\"fill\": 0, \"first\": 0}\n    for rng in list(ws.merged_cells.ranges):\n        action = policy(rng)\n        value = ws.cell(rng.min_row, rng.min_col).value\n        ws.unmerge_cells(rng.coord)\n        if action == \"fill\":\n            for row in ws.iter_rows(min_row=rng.min_row, max_row=rng.max_row,\n                                    min_col=rng.min_col, max_col=rng.max_col):\n                for cell in row:\n                    cell.value = value\n        counts[action] += 1\n    return counts\n\nws = load_workbook(\"merged.xlsx\")[\"Reps\"]\nprint(unmerge_with_policy(ws))              # {'fill': 2, 'first': 1}\nprint(ws[\"D1\"].value, ws[\"E1\"].value)       # Provisional None\n",[385,1565,1566,1592,1625,1636,1648,1658,1665,1669,1683,1712,1724,1734,1743,1747,1761,1783,1798,1808,1817,1829,1837,1842,1859,1870],{"__ignoreMap":383},[388,1567,1568,1570,1573,1576,1578,1581,1584,1587,1590],{"class":342,"line":390},[388,1569,919],{"class":419},[388,1571,1572],{"class":922}," policy",[388,1574,1575],{"class":423},"(rng, header_rows: ",[388,1577,929],{"class":529},[388,1579,1580],{"class":419}," =",[388,1582,1583],{"class":529}," 1",[388,1585,1586],{"class":423},") -> ",[388,1588,1589],{"class":529},"str",[388,1591,826],{"class":423},[388,1593,1594,1597,1600,1603,1606,1609,1612,1615,1618,1621,1623],{"class":342,"line":433},[388,1595,1596],{"class":419},"    if",[388,1598,1599],{"class":423}," rng.max_row ",[388,1601,1602],{"class":419},"\u003C=",[388,1604,1605],{"class":423}," header_rows ",[388,1607,1608],{"class":419},"and",[388,1610,1611],{"class":423}," rng.max_col ",[388,1613,1614],{"class":419},"-",[388,1616,1617],{"class":423}," rng.min_col ",[388,1619,1620],{"class":419},">=",[388,1622,1583],{"class":529},[388,1624,826],{"class":423},[388,1626,1627,1630,1633],{"class":342,"line":446},[388,1628,1629],{"class":419},"        return",[388,1631,1632],{"class":397}," \"first\"",[388,1634,1635],{"class":786},"          # a heading spanning columns\n",[388,1637,1638,1640,1642,1645],{"class":342,"line":453},[388,1639,1596],{"class":419},[388,1641,1617],{"class":423},[388,1643,1644],{"class":419},"==",[388,1646,1647],{"class":423}," rng.max_col:\n",[388,1649,1650,1652,1655],{"class":342,"line":465},[388,1651,1629],{"class":419},[388,1653,1654],{"class":397}," \"fill\"",[388,1656,1657],{"class":786},"           # a key merged down one column\n",[388,1659,1660,1662],{"class":342,"line":476},[388,1661,1053],{"class":419},[388,1663,1664],{"class":397}," \"fill\"\n",[388,1666,1667],{"class":342,"line":487},[388,1668,450],{"emptyLinePlaceholder":449},[388,1670,1671,1673,1676,1678,1681],{"class":342,"line":549},[388,1672,919],{"class":419},[388,1674,1675],{"class":922}," unmerge_with_policy",[388,1677,926],{"class":423},[388,1679,1680],{"class":529},"dict",[388,1682,826],{"class":423},[388,1684,1685,1688,1690,1693,1695,1698,1700,1702,1705,1707,1709],{"class":342,"line":596},[388,1686,1687],{"class":423},"    counts ",[388,1689,459],{"class":419},[388,1691,1692],{"class":423}," {",[388,1694,1399],{"class":397},[388,1696,1697],{"class":423},": ",[388,1699,42],{"class":529},[388,1701,505],{"class":423},[388,1703,1704],{"class":397},"\"first\"",[388,1706,1697],{"class":423},[388,1708,42],{"class":529},[388,1710,1711],{"class":423},"}\n",[388,1713,1714,1716,1718,1720,1722],{"class":342,"line":602},[388,1715,949],{"class":419},[388,1717,952],{"class":423},[388,1719,496],{"class":419},[388,1721,941],{"class":529},[388,1723,1349],{"class":423},[388,1725,1726,1729,1731],{"class":342,"line":619},[388,1727,1728],{"class":423},"        action ",[388,1730,459],{"class":419},[388,1732,1733],{"class":423}," policy(rng)\n",[388,1735,1736,1738,1740],{"class":342,"line":631},[388,1737,972],{"class":423},[388,1739,459],{"class":419},[388,1741,1742],{"class":423}," ws.cell(rng.min_row, rng.min_col).value\n",[388,1744,1745],{"class":342,"line":641},[388,1746,982],{"class":423},[388,1748,1749,1752,1755,1757,1759],{"class":342,"line":651},[388,1750,1751],{"class":419},"        if",[388,1753,1754],{"class":423}," action ",[388,1756,1644],{"class":419},[388,1758,1654],{"class":397},[388,1760,826],{"class":423},[388,1762,1763,1765,1767,1769,1771,1773,1775,1777,1779,1781],{"class":342,"line":678},[388,1764,1030],{"class":419},[388,1766,493],{"class":423},[388,1768,496],{"class":419},[388,1770,994],{"class":423},[388,1772,883],{"class":667},[388,1774,459],{"class":419},[388,1776,1001],{"class":423},[388,1778,886],{"class":667},[388,1780,459],{"class":419},[388,1782,1008],{"class":423},[388,1784,1785,1788,1790,1792,1794,1796],{"class":342,"line":712},[388,1786,1787],{"class":667},"                                    min_col",[388,1789,459],{"class":419},[388,1791,1018],{"class":423},[388,1793,892],{"class":667},[388,1795,459],{"class":419},[388,1797,1025],{"class":423},[388,1799,1800,1802,1804,1806],{"class":342,"line":1519},[388,1801,1480],{"class":419},[388,1803,1033],{"class":423},[388,1805,496],{"class":419},[388,1807,1038],{"class":423},[388,1809,1810,1813,1815],{"class":342,"line":1525},[388,1811,1812],{"class":423},"                    cell.value ",[388,1814,459],{"class":419},[388,1816,1048],{"class":423},[388,1818,1820,1823,1826],{"class":342,"line":1819},19,[388,1821,1822],{"class":423},"        counts[action] ",[388,1824,1825],{"class":419},"+=",[388,1827,1828],{"class":529}," 1\n",[388,1830,1832,1834],{"class":342,"line":1831},20,[388,1833,1053],{"class":419},[388,1835,1836],{"class":423}," counts\n",[388,1838,1840],{"class":342,"line":1839},21,[388,1841,450],{"emptyLinePlaceholder":449},[388,1843,1845,1847,1849,1851,1853,1855,1857],{"class":342,"line":1844},22,[388,1846,468],{"class":423},[388,1848,459],{"class":419},[388,1850,741],{"class":423},[388,1852,718],{"class":397},[388,1854,746],{"class":423},[388,1856,749],{"class":397},[388,1858,752],{"class":423},[388,1860,1862,1864,1867],{"class":342,"line":1861},23,[388,1863,757],{"class":529},[388,1865,1866],{"class":423},"(unmerge_with_policy(ws))              ",[388,1868,1869],{"class":786},"# {'fill': 2, 'first': 1}\n",[388,1871,1873,1875,1877,1879,1882,1884,1887],{"class":342,"line":1872},24,[388,1874,757],{"class":529},[388,1876,766],{"class":423},[388,1878,608],{"class":397},[388,1880,1881],{"class":423},"].value, ws[",[388,1883,1119],{"class":397},[388,1885,1886],{"class":423},"].value)       ",[388,1888,1889],{"class":786},"# Provisional None\n",[10,1891,1892,1893,1896],{},"The heading now lives only in D1, while both region blocks are filled. Adjust ",[385,1894,1895],{},"header_rows"," to the height of your title block.",[20,1898,29,1903,29,1906,29,1909,29,1912,29,1917,29,1922,29,1925,29,1929,29,1933,29,1936,29,1939,29,1945,29,1949,29,1956,29,1961,29,1965,29,1967,29,1970,29,1974,29,1977,29,1980,29,1983,29,1986,29,1988,29,1991,29,1995,29,1998,29,2001,29,2004],{"viewBox":1899,"role":23,"ariaLabelledBy":1900,"xmlns":27,"style":1143},"4 0 752 238",[1901,1902],"unmerge-policy-t","unmerge-policy-d",[31,1904,1905],{"id":1901},"Deciding what to do with each merged range",[35,1907,1908],{"id":1902},"A merged range in the title rows that spans several columns is a heading, so keep the value in its first cell only. A range merged down a single column inside the data is a key, so fill every cell. A range outside the table, such as a footer note, can be left merged.",[39,1910],{"x":158,"y":42,"width":1152,"height":1911,"fill":45},"238",[39,1913],{"x":1914,"y":1157,"width":1915,"height":1916,"rx":151,"fill":117,"stroke":118,"style":347},"160.6","438.9","75.5",[1161,1918,1920],{"transform":1919},"translate(368.0,29.0) scale(1.000)",[1165,1921],{"d":1167,"fill":1168,"stroke":1209,"style":1170},[60,1923,1924],{"x":363,"y":1916,"style":1214},"Where is the merged range and which way does it run?",[342,1926],{"x1":363,"y1":1927,"x2":363,"y2":1928,"stroke":118,"style":347},"91.5","111.5",[342,1930],{"x1":1931,"y1":1928,"x2":1932,"y2":1928,"stroke":118,"style":347},"134.7","625.3",[342,1934],{"x1":1931,"y1":1928,"x2":1931,"y2":1935,"stroke":118,"style":347},"157.5",[349,1937],{"points":1938,"fill":352},"134.7,161.5 129.7,152.5 139.7,152.5",[39,1940],{"x":1941,"y":1942,"width":1943,"height":1944,"rx":135,"fill":45,"stroke":53,"style":360},"74.8","121.5","119.6","21.0",[60,1946,1948],{"x":1931,"y":345,"style":1947},"font-size:11.5px;font-weight:700;fill:var(--muted,#5b6780);text-anchor:middle","title rows, across",[39,1950],{"x":1156,"y":1951,"width":1952,"height":1953,"rx":151,"fill":1954,"stroke":1955,"style":347},"163.5","229.3","59.0","#fdefd8","var(--gold,#b4740a)",[60,1957,1960],{"x":1931,"y":1958,"style":1959},"189.0","font-size:13.5px;font-weight:700;fill:var(--gold-ink,#7a4e06);text-anchor:middle","keep first cell",[60,1962,1964],{"x":1931,"y":1963,"style":1180},"208.5","a heading",[342,1966],{"x1":363,"y1":1928,"x2":363,"y2":1935,"stroke":118,"style":347},[349,1968],{"points":1969,"fill":352},"380.0,161.5 375.0,152.5 385.0,152.5",[39,1971],{"x":1972,"y":1942,"width":1973,"height":1944,"rx":135,"fill":45,"stroke":53,"style":360},"323.6","112.8",[60,1975,1976],{"x":363,"y":345,"style":1947},"data area, down",[39,1978],{"x":1979,"y":1951,"width":1952,"height":1953,"rx":151,"fill":254,"stroke":255,"style":347},"265.3",[60,1981,1982],{"x":363,"y":1958,"style":1281},"fill every cell",[60,1984,1985],{"x":363,"y":1963,"style":1180},"a key for each row",[342,1987],{"x1":1932,"y1":1928,"x2":1932,"y2":1935,"stroke":118,"style":347},[349,1989],{"points":1990,"fill":352},"625.3,161.5 620.3,152.5 630.3,152.5",[39,1992],{"x":1993,"y":1942,"width":1994,"height":1944,"rx":135,"fill":45,"stroke":53,"style":360},"567.1","116.6",[60,1996,1997],{"x":1932,"y":345,"style":1947},"outside the table",[39,1999],{"x":2000,"y":1951,"width":1952,"height":1953,"rx":151,"fill":52,"stroke":53,"style":347},"510.7",[60,2002,2003],{"x":1932,"y":1958,"style":1175},"leave it merged",[60,2005,2006],{"x":1932,"y":1963,"style":1180},"footers and notes",[10,2008,2009],{},"Writing the policy down as code, rather than unmerging everything the same way, also documents your understanding of the layout. When a new version of the sheet adds a merged footer, the policy makes you decide what it means instead of quietly filling it into cells that downstream code will read as data.",[373,2011,2013],{"id":2012},"when-you-only-need-the-data-the-pandas-route","When you only need the data: the pandas route",[10,2015,2016],{},"If the goal is a DataFrame rather than a fixed workbook, you do not need openpyxl at all. pandas reads a vertical merge as a value followed by missing cells, and forward-filling that column restores it:",[378,2018,2020],{"className":410,"code":2019,"language":412,"meta":383,"style":383},"import pandas as pd\n\ndf = pd.read_excel(\"merged.xlsx\", sheet_name=\"Reps\", usecols=\"A:C\")\nprint(df[\"Region\"].tolist())               # ['North', nan, nan, 'South', nan]\ndf[\"Region\"] = df[\"Region\"].ffill()\nprint(df[\"Region\"].tolist())               # ['North', 'North', 'North', 'South', 'South']\n",[385,2021,2022,2035,2039,2072,2087,2106],{"__ignoreMap":383},[388,2023,2024,2026,2029,2032],{"class":342,"line":390},[388,2025,427],{"class":419},[388,2027,2028],{"class":423}," pandas ",[388,2030,2031],{"class":419},"as",[388,2033,2034],{"class":423}," pd\n",[388,2036,2037],{"class":342,"line":433},[388,2038,450],{"emptyLinePlaceholder":449},[388,2040,2041,2044,2046,2049,2051,2053,2056,2058,2060,2062,2065,2067,2070],{"class":342,"line":446},[388,2042,2043],{"class":423},"df ",[388,2045,459],{"class":419},[388,2047,2048],{"class":423}," pd.read_excel(",[388,2050,718],{"class":397},[388,2052,505],{"class":423},[388,2054,2055],{"class":667},"sheet_name",[388,2057,459],{"class":419},[388,2059,749],{"class":397},[388,2061,505],{"class":423},[388,2063,2064],{"class":667},"usecols",[388,2066,459],{"class":419},[388,2068,2069],{"class":397},"\"A:C\"",[388,2071,628],{"class":423},[388,2073,2074,2076,2079,2081,2084],{"class":342,"line":453},[388,2075,757],{"class":529},[388,2077,2078],{"class":423},"(df[",[388,2080,502],{"class":397},[388,2082,2083],{"class":423},"].tolist())               ",[388,2085,2086],{"class":786},"# ['North', nan, nan, 'South', nan]\n",[388,2088,2089,2092,2094,2096,2098,2101,2103],{"class":342,"line":465},[388,2090,2091],{"class":423},"df[",[388,2093,502],{"class":397},[388,2095,611],{"class":423},[388,2097,459],{"class":419},[388,2099,2100],{"class":423}," df[",[388,2102,502],{"class":397},[388,2104,2105],{"class":423},"].ffill()\n",[388,2107,2108,2110,2112,2114,2116],{"class":342,"line":476},[388,2109,757],{"class":529},[388,2111,2078],{"class":423},[388,2113,502],{"class":397},[388,2115,2083],{"class":423},[388,2117,2118],{"class":786},"# ['North', 'North', 'North', 'South', 'South']\n",[10,2120,2121,2122,2125,2126,1553],{},"This is quicker, but it cannot tell a merged blank from a genuinely empty cell — ",[385,2123,2124],{},"ffill"," fills both. When some blanks must stay blank, use the openpyxl route, which knows exactly which cells were merged. The pandas side, including multi-row headers, is covered in ",[14,2127,2129],{"href":2128},"\u002Fgetting-started-with-python-excel-automation\u002Freading-excel-files-with-pandas\u002Fhandle-merged-cells-when-reading-excel-with-pandas\u002F","Handle Merged Cells When Reading Excel with pandas",[373,2131,2133],{"id":2132},"common-pitfalls","Common pitfalls",[2135,2136,2137,2153,2162,2172],"ul",{},[2138,2139,2140,2144,2145,2148,2149,2152],"li",{},[2141,2142,2143],"strong",{},"Read-only mode has no merge information."," ",[385,2146,2147],{},"load_workbook(..., read_only=True)"," returns worksheets without ",[385,2150,2151],{},"merged_cells",", so the ranges cannot be found. Load normally for this job.",[2138,2154,2155,2158,2159,1553],{},[2141,2156,2157],{},"Mutating the range set while iterating."," Always loop over ",[385,2160,2161],{},"list(ws.merged_cells.ranges)",[2138,2163,2164,2167,2168,2171],{},[2141,2165,2166],{},"Formulas in merged cells."," The top-left cell may hold a formula. Copying it verbatim into the other cells copies the formula text, whose relative references then point at the wrong cells. Copy the cached value (load with ",[385,2169,2170],{},"data_only=True",") or rewrite the formula per cell.",[2138,2173,2174,2177],{},[2141,2175,2176],{},"Merges that cross the table edge."," A title merged across columns A:H above a table of five columns will be filled into three extra cells if you use plain fill. Use a policy as in Step 4.",[373,2179,2181],{"id":2180},"performance-and-scale-notes","Performance and scale notes",[10,2183,2184,2185,2188,2189,2191,2192,1553],{},"The work is proportional to the number of cells covered by merges, not to the size of the sheet, so even large sheets unmerge in well under a second unless they are merged almost everywhere. Loading the workbook without ",[385,2186,2187],{},"read_only"," is the real cost on big files; if the sheet is huge and the merges only affect one key column, the pandas ",[385,2190,2124],{}," route avoids loading styles at all. For whole-sheet clean-ups of human-built layouts — merged headers, subtotal rows, stacked tables — see ",[14,2193,2195],{"href":2194},"\u002Fadvanced-data-transformation-and-cleaning\u002Fextracting-data-from-messy-excel-sheets\u002F","Extracting Data from Messy Excel Sheets",[373,2197,2199],{"id":2198},"conclusion","Conclusion",[10,2201,2202,2203,2205,2206,2208],{},"Merged ranges keep their value in the top-left cell only. With openpyxl, list the ranges from ",[385,2204,875],{},", loop over a copy, unmerge each one, write the saved value into every cell and copy the top-left style so the block keeps its look. Decide per range whether a heading should be duplicated or kept once, and use pandas ",[385,2207,2124],{}," instead when a DataFrame is all you need and every blank in the key column really is a merge.",[373,2210,2212],{"id":2211},"frequently-asked-questions","Frequently asked questions",[10,2214,2215,2218],{},[2141,2216,2217],{},"Why do merged cells read as None in openpyxl?","\nExcel stores the value only in the top-left cell of a merged range. The other cells are placeholders, which openpyxl represents as MergedCell objects whose value is always None and cannot be set.",[10,2220,2221,2224],{},[2141,2222,2223],{},"How do I unmerge every merged cell in a sheet?","\nLoop over a copy of ws.merged_cells.ranges — list(...) — and call ws.unmerge_cells(rng.coord) for each. Copying the collection first matters because unmerging changes it while you iterate.",[10,2226,2227,2230],{},[2141,2228,2229],{},"Does read_only mode tell me which cells are merged?","\nNo. A read-only worksheet has no merged_cells attribute, so you cannot find merged ranges while streaming. Load the workbook normally for this job.",[10,2232,2233,2236],{},[2141,2234,2235],{},"Should I fill merged values with pandas instead?","\nIf the merges run straight down one column, reading with pandas and calling ffill on that column is quicker and gives the same result. Use openpyxl when merges run across columns, when you need to save the workbook back, or when blanks that are not merges must stay blank.",[373,2238,2240],{"id":2239},"related","Related",[2135,2242,2243,2249,2256,2263],{},[2138,2244,2245,2246,2248],{},"Up one level: ",[14,2247,17],{"href":16}," — the openpyxl object model.",[2138,2250,2251,2255],{},[14,2252,2254],{"href":2253},"\u002Fadvanced-data-transformation-and-cleaning\u002Fhandling-missing-data-in-excel-reports\u002Fforward-fill-blank-cells-in-grouped-excel-reports\u002F","Forward Fill Blank Cells in Grouped Excel Reports"," — the same shape without merges.",[2138,2257,2258,2262],{},[14,2259,2261],{"href":2260},"\u002Fformatting-and-charting-excel-reports-with-python\u002Fstyling-excel-cells-with-openpyxl\u002Fmerge-cells-and-centre-a-report-title-with-openpyxl\u002F","Merge Cells and Centre a Report Title with openpyxl"," — when merging is the right call.",[2138,2264,2265,2269],{},[14,2266,2268],{"href":2267},"\u002Fadvanced-data-transformation-and-cleaning\u002Fextracting-data-from-messy-excel-sheets\u002Fread-excel-with-multi-row-headers-in-pandas\u002F","Read Excel with Multi-Row Headers in pandas"," — merged header rows on the pandas side.",[701,2271,2272],{},"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":383,"searchDepth":433,"depth":433,"links":2274},[2275,2276,2277,2278,2279,2280,2281,2282,2283,2284,2285],{"id":375,"depth":433,"text":376},{"id":723,"depth":433,"text":724},{"id":900,"depth":433,"text":901},{"id":1298,"depth":433,"text":1299},{"id":1556,"depth":433,"text":1557},{"id":2012,"depth":433,"text":2013},{"id":2132,"depth":433,"text":2133},{"id":2180,"depth":433,"text":2181},{"id":2198,"depth":433,"text":2199},{"id":2211,"depth":433,"text":2212},{"id":2239,"depth":433,"text":2240},"2026-09-23","Turn merged cells into a proper table — find every merged range, unmerge it, copy the top-left value into each cell, keep the formatting, and handle the read-only and pandas cases where merge information is missing.","md",[2290,2292,2294,2296],{"q":2217,"a":2291},"Excel stores the value only in the top-left cell of a merged range. The other cells are placeholders, which openpyxl represents as MergedCell objects whose value is always None and cannot be set.",{"q":2223,"a":2293},"Loop over a copy of ws.merged_cells.ranges — list(...) — and call ws.unmerge_cells(rng.coord) for each. Copying the collection first matters because unmerging changes it while you iterate.",{"q":2229,"a":2295},"No. A read-only worksheet has no merged_cells attribute, so you cannot find merged ranges while streaming. Load the workbook normally for this job.",{"q":2235,"a":2297},"If the merges run straight down one column, reading with pandas and calling ffill on that column is quicker and gives the same result. Use openpyxl when merges run across columns, when you need to save the workbook back, or when blanks that are not merges must stay blank.","unmerge cells and fill the values with openpyxl",null,{"breadcrumb":2301},[2302,2305,2308],{"name":2303,"item":2304},"Home","\u002F",{"name":2306,"item":2307},"Getting Started with Python Excel Automation","\u002Fgetting-started-with-python-excel-automation\u002F",{"name":17,"item":16},"\u002Fgetting-started-with-python-excel-automation\u002Fusing-openpyxl-for-excel-file-manipulation\u002Funmerge-cells-and-fill-values-with-openpyxl",{"title":2311,"description":2312},"Unmerge Excel Cells and Fill Down Values with openpyxl","Unmerge all merged cells in a sheet with openpyxl and fill each former range with its value — MergedCell read-only errors, preserving borders, vertical versus horizontal merges, and a pandas fallback.","unmerge-cells-and-fill-values-with-openpyxl","getting-started-with-python-excel-automation\u002Fusing-openpyxl-for-excel-file-manipulation\u002Funmerge-cells-and-fill-values-with-openpyxl\u002Findex",[2316,2317],"messy-sheets","openpyxl","how-to","r5oFFwkBqwGQ1lngviUENFYf1cWyigTKspntvbilzsg",[2321,2325],{"title":2322,"path":2323,"stem":2324,"children":-1},"Transpose a Range of Cells with openpyxl","\u002Fgetting-started-with-python-excel-automation\u002Fusing-openpyxl-for-excel-file-manipulation\u002Ftranspose-a-range-of-cells-with-openpyxl","getting-started-with-python-excel-automation\u002Fusing-openpyxl-for-excel-file-manipulation\u002Ftranspose-a-range-of-cells-with-openpyxl\u002Findex",{"title":2326,"path":2327,"stem":2328,"children":-1},"Use Theme Colours and Tints in openpyxl","\u002Fgetting-started-with-python-excel-automation\u002Fusing-openpyxl-for-excel-file-manipulation\u002Fuse-theme-colours-and-tints-in-openpyxl","getting-started-with-python-excel-automation\u002Fusing-openpyxl-for-excel-file-manipulation\u002Fuse-theme-colours-and-tints-in-openpyxl\u002Findex",[2330,2332],{"path":2331,"title":2306},"\u002Fgetting-started-with-python-excel-automation",{"path":2333,"title":17},"\u002Fgetting-started-with-python-excel-automation\u002Fusing-openpyxl-for-excel-file-manipulation",[],[2336,2339,2342,2345,2348,2351],{"path":2337,"title":2195,"kind":2338},"\u002Fadvanced-data-transformation-and-cleaning\u002Fextracting-data-from-messy-excel-sheets","guide",{"path":2340,"title":2341,"kind":2318},"\u002Fadvanced-data-transformation-and-cleaning\u002Fextracting-data-from-messy-excel-sheets\u002Fcombine-sheets-with-different-layouts-into-one-table","Combine Sheets with Different Layouts into One Table",{"path":2343,"title":2344,"kind":2318},"\u002Fadvanced-data-transformation-and-cleaning\u002Fextracting-data-from-messy-excel-sheets\u002Fextract-hyperlink-urls-from-excel-cells","Extract Hyperlink URLs from Excel Cells with openpyxl",{"path":2346,"title":2347,"kind":2318},"\u002Fadvanced-data-transformation-and-cleaning\u002Fextracting-data-from-messy-excel-sheets\u002Fextract-report-header-fields-from-an-excel-sheet","Extract Report Header Fields from an Excel Sheet with Python",{"path":2349,"title":2350,"kind":2318},"\u002Fadvanced-data-transformation-and-cleaning\u002Fextracting-data-from-messy-excel-sheets\u002Ffind-the-header-row-in-an-excel-sheet-with-a-shifting-layout","Find the Header Row in an Excel Sheet with a Shifting Layout",{"path":2352,"title":2353,"kind":2318},"\u002Fadvanced-data-transformation-and-cleaning\u002Fextracting-data-from-messy-excel-sheets\u002Fparse-numbers-with-units-in-excel-cells","Parse Numbers with Units in Excel Cells",1790972072227]