[{"data":1,"prerenderedAt":2350},["ShallowReactive",2],{"doc:\u002Fgetting-started-with-python-excel-automation\u002Fworking-with-multiple-excel-sheets-in-python\u002Flist-every-sheet-with-its-size-and-visibility":3,"surround:\u002Fgetting-started-with-python-excel-automation\u002Fworking-with-multiple-excel-sheets-in-python\u002Flist-every-sheet-with-its-size-and-visibility":2316,"ancestors:\u002Fgetting-started-with-python-excel-automation\u002Fworking-with-multiple-excel-sheets-in-python\u002Flist-every-sheet-with-its-size-and-visibility":2325,"children:\u002Fgetting-started-with-python-excel-automation\u002Fworking-with-multiple-excel-sheets-in-python\u002Flist-every-sheet-with-its-size-and-visibility":2330,"related:\u002Fgetting-started-with-python-excel-automation\u002Fworking-with-multiple-excel-sheets-in-python\u002Flist-every-sheet-with-its-size-and-visibility":2331},{"id":4,"title":5,"body":6,"dateModified":2283,"datePublished":2283,"description":2284,"extension":2285,"faq":2286,"keyword":2295,"kind":2296,"meta":2297,"navigation":110,"path":2305,"seo":2306,"slug":2309,"stem":2310,"topics":2311,"type":2314,"__hash__":2315},"docs\u002Fgetting-started-with-python-excel-automation\u002Fworking-with-multiple-excel-sheets-in-python\u002Flist-every-sheet-with-its-size-and-visibility\u002Findex.md","List Every Sheet with Its Size and Visibility",{"type":7,"value":8,"toc":2273},"minimark",[9,29,34,62,65,69,626,672,966,970,1406,1419,1495,1676,1679,1683,2121,2124,2128,2177,2181,2184,2188,2206,2215,2223,2236,2240,2269],[10,11,12,13,17,18,22,23,28],"p",{},"Before changing, migrating or cleaning up a workbook you did not build, it helps to know what is in it. How many sheets are there, including the ones nobody can see? Which ones hold data, which hold only formulas, which have charts? Is there a sheet whose used range claims a million rows because someone once formatted a whole column? Excel's own interface answers these questions one sheet at a time, and it hides ",[14,15,16],"em",{},"very hidden"," sheets entirely — they do not even appear in the Unhide dialog. A short openpyxl script answers them all at once. This page builds a sheet inventory: visibility state, sheet type, the used range Excel reports compared with the range that really contains values, counts of formulas, tables, charts, images, merged ranges and validation rules, protection, and the number of bytes each sheet occupies inside the ",[19,20,21],"code",{},".xlsx"," file, for one workbook or a whole folder. It belongs to ",[24,25,27],"a",{"href":26},"\u002Fgetting-started-with-python-excel-automation\u002Fworking-with-multiple-excel-sheets-in-python\u002F","Working with Multiple Excel Sheets in Python",".",[30,31,33],"h2",{"id":32},"prerequisites","Prerequisites",[35,36,41],"pre",{"className":37,"code":38,"language":39,"meta":40,"style":40},"language-bash shiki shiki-themes github-light github-dark-high-contrast","pip install openpyxl pandas\n","bash","",[19,42,43],{"__ignoreMap":40},[44,45,48,52,56,59],"span",{"class":46,"line":47},"line",1,[44,49,51],{"class":50},"sMTad","pip",[44,53,55],{"class":54},"srMev"," install",[44,57,58],{"class":54}," openpyxl",[44,60,61],{"class":54}," pandas\n",[10,63,64],{},"The example workbook has six sheets: a data sheet with a table, a summary with formulas, a merged heading, a chart and a logo, an input sheet with a dropdown and protection, an old sheet where 20,000 rows were once filled white, a hidden lookup sheet and a very hidden calculation sheet. Only four of them are visible in Excel's tab bar.",[30,66,68],{"id":67},"step-1-one-row-per-sheet","Step 1 — One row per sheet",[35,70,74],{"className":71,"code":72,"language":73,"meta":40,"style":40},"language-python shiki shiki-themes github-light github-dark-high-contrast","from openpyxl import load_workbook\nfrom openpyxl.worksheet.worksheet import Worksheet\n\ndef real_extent(ws):\n    \"\"\"Last row and column that actually contain a value (ignoring formatting-only cells).\"\"\"\n    last_r = last_c = 0\n    for row in ws.iter_rows():\n        for c in row:\n            if c.value is not None:\n                last_r, last_c = max(last_r, c.row), max(last_c, c.column)\n    return last_r, last_c\n\ndef inventory(path):\n    wb = load_workbook(path)\n    rows = []\n    for position, sheet in enumerate(wb._sheets, start=1):\n        info = {\"File\": str(path), \"Position\": position, \"Sheet\": sheet.title, \"State\": sheet.sheet_state,\n                \"Type\": \"worksheet\" if isinstance(sheet, Worksheet) else \"chart sheet\"}\n        if isinstance(sheet, Worksheet):\n            last_r, last_c = real_extent(sheet)\n            info.update({\n                \"Reported range\": sheet.dimensions, \"Reported rows\": sheet.max_row,\n                \"Rows with data\": last_r, \"Columns with data\": last_c,\n                \"Formulas\": sum(1 for r in sheet.iter_rows() for c in r if c.data_type == \"f\"),\n                \"Tables\": len(sheet.tables), \"Charts\": len(sheet._charts), \"Images\": len(sheet._images),\n                \"Merged ranges\": len(sheet.merged_cells.ranges),\n                \"Validation rules\": len(sheet.data_validations.dataValidation),\n                \"Protected\": bool(sheet.protection.sheet)})\n        rows.append(info)\n    return rows\n\nimport pandas as pd\ninv = pd.DataFrame(inventory(\"finance_model.xlsx\"))\nprint(inv.drop(columns=\"File\").to_string(index=False))\n","python",[19,75,76,92,105,112,125,131,149,164,178,199,219,228,233,244,255,266,294,335,364,375,386,392,407,422,473,507,520,533,547,553,561,566,580,597],{"__ignoreMap":40},[44,77,78,82,86,89],{"class":46,"line":47},[44,79,81],{"class":80},"s-kum","from",[44,83,85],{"class":84},"skGVy"," openpyxl ",[44,87,88],{"class":80},"import",[44,90,91],{"class":84}," load_workbook\n",[44,93,95,97,100,102],{"class":46,"line":94},2,[44,96,81],{"class":80},[44,98,99],{"class":84}," openpyxl.worksheet.worksheet ",[44,101,88],{"class":80},[44,103,104],{"class":84}," Worksheet\n",[44,106,108],{"class":46,"line":107},3,[44,109,111],{"emptyLinePlaceholder":110},true,"\n",[44,113,115,118,122],{"class":46,"line":114},4,[44,116,117],{"class":80},"def",[44,119,121],{"class":120},"s_Opv"," real_extent",[44,123,124],{"class":84},"(ws):\n",[44,126,128],{"class":46,"line":127},5,[44,129,130],{"class":54},"    \"\"\"Last row and column that actually contain a value (ignoring formatting-only cells).\"\"\"\n",[44,132,134,137,140,143,145],{"class":46,"line":133},6,[44,135,136],{"class":84},"    last_r ",[44,138,139],{"class":80},"=",[44,141,142],{"class":84}," last_c ",[44,144,139],{"class":80},[44,146,148],{"class":147},"sP0c6"," 0\n",[44,150,152,155,158,161],{"class":46,"line":151},7,[44,153,154],{"class":80},"    for",[44,156,157],{"class":84}," row ",[44,159,160],{"class":80},"in",[44,162,163],{"class":84}," ws.iter_rows():\n",[44,165,167,170,173,175],{"class":46,"line":166},8,[44,168,169],{"class":80},"        for",[44,171,172],{"class":84}," c ",[44,174,160],{"class":80},[44,176,177],{"class":84}," row:\n",[44,179,181,184,187,190,193,196],{"class":46,"line":180},9,[44,182,183],{"class":80},"            if",[44,185,186],{"class":84}," c.value ",[44,188,189],{"class":80},"is",[44,191,192],{"class":80}," not",[44,194,195],{"class":147}," None",[44,197,198],{"class":84},":\n",[44,200,202,205,207,210,213,216],{"class":46,"line":201},10,[44,203,204],{"class":84},"                last_r, last_c ",[44,206,139],{"class":80},[44,208,209],{"class":147}," max",[44,211,212],{"class":84},"(last_r, c.row), ",[44,214,215],{"class":147},"max",[44,217,218],{"class":84},"(last_c, c.column)\n",[44,220,222,225],{"class":46,"line":221},11,[44,223,224],{"class":80},"    return",[44,226,227],{"class":84}," last_r, last_c\n",[44,229,231],{"class":46,"line":230},12,[44,232,111],{"emptyLinePlaceholder":110},[44,234,236,238,241],{"class":46,"line":235},13,[44,237,117],{"class":80},[44,239,240],{"class":120}," inventory",[44,242,243],{"class":84},"(path):\n",[44,245,247,250,252],{"class":46,"line":246},14,[44,248,249],{"class":84},"    wb ",[44,251,139],{"class":80},[44,253,254],{"class":84}," load_workbook(path)\n",[44,256,258,261,263],{"class":46,"line":257},15,[44,259,260],{"class":84},"    rows ",[44,262,139],{"class":80},[44,264,265],{"class":84}," []\n",[44,267,269,271,274,276,279,282,286,288,291],{"class":46,"line":268},16,[44,270,154],{"class":80},[44,272,273],{"class":84}," position, sheet ",[44,275,160],{"class":80},[44,277,278],{"class":147}," enumerate",[44,280,281],{"class":84},"(wb._sheets, ",[44,283,285],{"class":284},"sa561","start",[44,287,139],{"class":80},[44,289,290],{"class":147},"1",[44,292,293],{"class":84},"):\n",[44,295,297,300,302,305,308,311,314,317,320,323,326,329,332],{"class":46,"line":296},17,[44,298,299],{"class":84},"        info ",[44,301,139],{"class":80},[44,303,304],{"class":84}," {",[44,306,307],{"class":54},"\"File\"",[44,309,310],{"class":84},": ",[44,312,313],{"class":147},"str",[44,315,316],{"class":84},"(path), ",[44,318,319],{"class":54},"\"Position\"",[44,321,322],{"class":84},": position, ",[44,324,325],{"class":54},"\"Sheet\"",[44,327,328],{"class":84},": sheet.title, ",[44,330,331],{"class":54},"\"State\"",[44,333,334],{"class":84},": sheet.sheet_state,\n",[44,336,338,341,343,346,349,352,355,358,361],{"class":46,"line":337},18,[44,339,340],{"class":54},"                \"Type\"",[44,342,310],{"class":84},[44,344,345],{"class":54},"\"worksheet\"",[44,347,348],{"class":80}," if",[44,350,351],{"class":147}," isinstance",[44,353,354],{"class":84},"(sheet, Worksheet) ",[44,356,357],{"class":80},"else",[44,359,360],{"class":54}," \"chart sheet\"",[44,362,363],{"class":84},"}\n",[44,365,367,370,372],{"class":46,"line":366},19,[44,368,369],{"class":80},"        if",[44,371,351],{"class":147},[44,373,374],{"class":84},"(sheet, Worksheet):\n",[44,376,378,381,383],{"class":46,"line":377},20,[44,379,380],{"class":84},"            last_r, last_c ",[44,382,139],{"class":80},[44,384,385],{"class":84}," real_extent(sheet)\n",[44,387,389],{"class":46,"line":388},21,[44,390,391],{"class":84},"            info.update({\n",[44,393,395,398,401,404],{"class":46,"line":394},22,[44,396,397],{"class":54},"                \"Reported range\"",[44,399,400],{"class":84},": sheet.dimensions, ",[44,402,403],{"class":54},"\"Reported rows\"",[44,405,406],{"class":84},": sheet.max_row,\n",[44,408,410,413,416,419],{"class":46,"line":409},23,[44,411,412],{"class":54},"                \"Rows with data\"",[44,414,415],{"class":84},": last_r, ",[44,417,418],{"class":54},"\"Columns with data\"",[44,420,421],{"class":84},": last_c,\n",[44,423,425,428,430,433,436,438,441,444,446,449,452,454,456,458,461,464,467,470],{"class":46,"line":424},24,[44,426,427],{"class":54},"                \"Formulas\"",[44,429,310],{"class":84},[44,431,432],{"class":147},"sum",[44,434,435],{"class":84},"(",[44,437,290],{"class":147},[44,439,440],{"class":80}," for",[44,442,443],{"class":84}," r ",[44,445,160],{"class":80},[44,447,448],{"class":84}," sheet.iter_rows() ",[44,450,451],{"class":80},"for",[44,453,172],{"class":84},[44,455,160],{"class":80},[44,457,443],{"class":84},[44,459,460],{"class":80},"if",[44,462,463],{"class":84}," c.data_type ",[44,465,466],{"class":80},"==",[44,468,469],{"class":54}," \"f\"",[44,471,472],{"class":84},"),\n",[44,474,476,479,481,484,487,490,492,494,497,500,502,504],{"class":46,"line":475},25,[44,477,478],{"class":54},"                \"Tables\"",[44,480,310],{"class":84},[44,482,483],{"class":147},"len",[44,485,486],{"class":84},"(sheet.tables), ",[44,488,489],{"class":54},"\"Charts\"",[44,491,310],{"class":84},[44,493,483],{"class":147},[44,495,496],{"class":84},"(sheet._charts), ",[44,498,499],{"class":54},"\"Images\"",[44,501,310],{"class":84},[44,503,483],{"class":147},[44,505,506],{"class":84},"(sheet._images),\n",[44,508,510,513,515,517],{"class":46,"line":509},26,[44,511,512],{"class":54},"                \"Merged ranges\"",[44,514,310],{"class":84},[44,516,483],{"class":147},[44,518,519],{"class":84},"(sheet.merged_cells.ranges),\n",[44,521,523,526,528,530],{"class":46,"line":522},27,[44,524,525],{"class":54},"                \"Validation rules\"",[44,527,310],{"class":84},[44,529,483],{"class":147},[44,531,532],{"class":84},"(sheet.data_validations.dataValidation),\n",[44,534,536,539,541,544],{"class":46,"line":535},28,[44,537,538],{"class":54},"                \"Protected\"",[44,540,310],{"class":84},[44,542,543],{"class":147},"bool",[44,545,546],{"class":84},"(sheet.protection.sheet)})\n",[44,548,550],{"class":46,"line":549},29,[44,551,552],{"class":84},"        rows.append(info)\n",[44,554,556,558],{"class":46,"line":555},30,[44,557,224],{"class":80},[44,559,560],{"class":84}," rows\n",[44,562,564],{"class":46,"line":563},31,[44,565,111],{"emptyLinePlaceholder":110},[44,567,569,571,574,577],{"class":46,"line":568},32,[44,570,88],{"class":80},[44,572,573],{"class":84}," pandas ",[44,575,576],{"class":80},"as",[44,578,579],{"class":84}," pd\n",[44,581,583,586,588,591,594],{"class":46,"line":582},33,[44,584,585],{"class":84},"inv ",[44,587,139],{"class":80},[44,589,590],{"class":84}," pd.DataFrame(inventory(",[44,592,593],{"class":54},"\"finance_model.xlsx\"",[44,595,596],{"class":84},"))\n",[44,598,600,603,606,609,611,613,616,619,621,624],{"class":46,"line":599},34,[44,601,602],{"class":147},"print",[44,604,605],{"class":84},"(inv.drop(",[44,607,608],{"class":284},"columns",[44,610,139],{"class":80},[44,612,307],{"class":54},[44,614,615],{"class":84},").to_string(",[44,617,618],{"class":284},"index",[44,620,139],{"class":80},[44,622,623],{"class":147},"False",[44,625,596],{"class":84},[10,627,628,631,632,635,636,639,640,643,644,647,648,651,652,655,656,659,660,663,664,667,668,671],{},[19,629,630],{},"wb._sheets"," holds every sheet in tab order, worksheets and chart sheets alike, which is what an inventory needs; the public ",[19,633,634],{},"wb.worksheets"," leaves chart sheets out. ",[19,637,638],{},"sheet_state"," is the visibility — ",[19,641,642],{},"visible",", ",[19,645,646],{},"hidden",", or ",[19,649,650],{},"veryHidden",", the state that can only be set or undone through code or the VBA editor. The two size columns are deliberately different. ",[19,653,654],{},"dimensions"," and ",[19,657,658],{},"max_row"," are what Excel will treat as the used range, and they count any cell that has been touched, including cells with formatting and no value. ",[14,661,662],{},"Rows with data"," counts only cells that hold a value. The gap between them is the point: the ",[14,665,666],{},"Old layout"," sheet reports 19,999 rows used but has data in one, which is the classic cause of a workbook that scrolls forever and opens slowly. The other columns count what makes a sheet more than a grid of values: formulas (cells whose data type is ",[19,669,670],{},"f","), tables, charts, images, merged ranges and validation rules, plus whether the sheet is protected.",[673,674,682,683,682,687,682,691,682,699,682,708,682,712,682,719,682,723,682,727,682,731,682,735,682,739,682,743,682,747,682,751,682,755,682,759,682,764,682,768,682,770,682,773,682,775,682,778,682,780,682,782,682,784,682,787,682,790,682,794,682,796,682,800,682,802,682,804,682,806,682,809,682,811,682,813,682,815,682,818,682,821,682,825,682,827,682,830,682,832,682,834,682,836,682,839,682,841,682,843,682,845,682,848,682,851,682,855,682,857,682,860,682,862,682,864,682,866,682,868,682,870,682,872,682,874,682,877,682,880,682,883,682,885,682,887,682,889,682,891,682,895,682,899,682,901,682,903,682,905,682,908,682,911,682,915,682,917,682,920,682,924,682,927,682,929,682,931,682,933,682,935,682,937,682,940,682,944,682,946,682,949,682,951,682,953,682,955,682,957,682,959,682,961,682,963],"svg",{"viewBox":675,"role":676,"ariaLabelledBy":677,"xmlns":680,"style":681},"30 0 700 252","img",[678,679],"inv-table-t","inv-table-d","http:\u002F\u002Fwww.w3.org\u002F2000\u002Fsvg","width:100%;max-width:700px;height:auto;display:block;margin:1.5rem auto;font-family:Inter,ui-sans-serif,system-ui,sans-serif","\n  ",[684,685,686],"title",{"id":678},"The inventory of the example workbook",[688,689,690],"desc",{"id":679},"Data is visible with 501 rows and a table. Summary is visible with three formulas, a chart, an image and a merged range. Inputs is visible, protected, with one validation rule. Old layout reports 19,999 rows but has data in one. Lookups is hidden and Calc is very hidden with one formula.",[692,693],"rect",{"x":694,"y":695,"width":696,"height":697,"fill":698},"30","0","700","252","#ffffff",[692,700],{"x":701,"y":702,"width":703,"height":704,"rx":695,"fill":705,"stroke":706,"style":707},"46.2","16.0","32.0","24.0","#e7ebef","var(--line,#cdd5e6)","stroke-width:1px",[692,709],{"x":710,"y":702,"width":711,"height":704,"rx":695,"fill":705,"stroke":706,"style":707},"78.2","86.6",[713,714,718],"text",{"x":715,"y":716,"style":717},"121.5","33.0","font-size:11px;font-weight:600;fill:var(--muted,#5b6780);text-anchor:middle","A",[692,720],{"x":721,"y":702,"width":722,"height":704,"rx":695,"fill":705,"stroke":706,"style":707},"164.8","95.8",[713,724,726],{"x":725,"y":716,"style":717},"212.7","B",[692,728],{"x":729,"y":702,"width":730,"height":704,"rx":695,"fill":705,"stroke":706,"style":707},"260.6","114.2",[713,732,734],{"x":733,"y":716,"style":717},"317.8","C",[692,736],{"x":737,"y":702,"width":738,"height":704,"rx":695,"fill":705,"stroke":706,"style":707},"374.9","117.5",[713,740,742],{"x":741,"y":716,"style":717},"433.6","D",[692,744],{"x":745,"y":702,"width":746,"height":704,"rx":695,"fill":705,"stroke":706,"style":707},"492.4","221.4",[713,748,750],{"x":749,"y":716,"style":717},"603.1","E",[692,752],{"x":701,"y":753,"width":703,"height":754,"rx":695,"fill":705,"stroke":706,"style":707},"40.0","28.0",[713,756,290],{"x":757,"y":758,"style":717},"62.2","59.0",[692,760],{"x":710,"y":753,"width":711,"height":754,"rx":695,"fill":761,"stroke":762,"style":763},"#f0f4ff","var(--brand,#5b5cf0)","stroke-width:1.5px",[713,765,767],{"x":715,"y":758,"style":766},"font-size:12px;font-weight:700;fill:var(--brand-strong,#4338ca);text-anchor:middle","Sheet",[692,769],{"x":721,"y":753,"width":722,"height":754,"rx":695,"fill":761,"stroke":762,"style":763},[713,771,772],{"x":725,"y":758,"style":766},"State",[692,774],{"x":729,"y":753,"width":730,"height":754,"rx":695,"fill":761,"stroke":762,"style":763},[713,776,777],{"x":733,"y":758,"style":766},"Reported rows",[692,779],{"x":737,"y":753,"width":738,"height":754,"rx":695,"fill":761,"stroke":762,"style":763},[713,781,662],{"x":741,"y":758,"style":766},[692,783],{"x":745,"y":753,"width":746,"height":754,"rx":695,"fill":761,"stroke":762,"style":763},[713,785,786],{"x":749,"y":758,"style":766},"Contents",[692,788],{"x":701,"y":789,"width":703,"height":754,"rx":695,"fill":705,"stroke":706,"style":707},"68.0",[713,791,793],{"x":757,"y":792,"style":717},"87.0","2",[692,795],{"x":710,"y":789,"width":711,"height":754,"rx":695,"fill":698,"stroke":706,"style":707},[713,797,799],{"x":715,"y":792,"style":798},"font-size:12px;font-weight:400;fill:var(--text,#172033);text-anchor:middle","Data",[692,801],{"x":721,"y":789,"width":722,"height":754,"rx":695,"fill":698,"stroke":706,"style":707},[713,803,642],{"x":725,"y":792,"style":798},[692,805],{"x":729,"y":789,"width":730,"height":754,"rx":695,"fill":698,"stroke":706,"style":707},[713,807,808],{"x":733,"y":792,"style":798},"501",[692,810],{"x":737,"y":789,"width":738,"height":754,"rx":695,"fill":698,"stroke":706,"style":707},[713,812,808],{"x":741,"y":792,"style":798},[692,814],{"x":745,"y":789,"width":746,"height":754,"rx":695,"fill":698,"stroke":706,"style":707},[713,816,817],{"x":749,"y":792,"style":798},"1 table",[692,819],{"x":701,"y":820,"width":703,"height":754,"rx":695,"fill":705,"stroke":706,"style":707},"96.0",[713,822,824],{"x":757,"y":823,"style":717},"115.0","3",[692,826],{"x":710,"y":820,"width":711,"height":754,"rx":695,"fill":698,"stroke":706,"style":707},[713,828,829],{"x":715,"y":823,"style":798},"Summary",[692,831],{"x":721,"y":820,"width":722,"height":754,"rx":695,"fill":698,"stroke":706,"style":707},[713,833,642],{"x":725,"y":823,"style":798},[692,835],{"x":729,"y":820,"width":730,"height":754,"rx":695,"fill":698,"stroke":706,"style":707},[713,837,838],{"x":733,"y":823,"style":798},"5",[692,840],{"x":737,"y":820,"width":738,"height":754,"rx":695,"fill":698,"stroke":706,"style":707},[713,842,838],{"x":741,"y":823,"style":798},[692,844],{"x":745,"y":820,"width":746,"height":754,"rx":695,"fill":698,"stroke":706,"style":707},[713,846,847],{"x":749,"y":823,"style":798},"3 formulas, chart, image, merge",[692,849],{"x":701,"y":850,"width":703,"height":754,"rx":695,"fill":705,"stroke":706,"style":707},"124.0",[713,852,854],{"x":757,"y":853,"style":717},"143.0","4",[692,856],{"x":710,"y":850,"width":711,"height":754,"rx":695,"fill":698,"stroke":706,"style":707},[713,858,859],{"x":715,"y":853,"style":798},"Inputs",[692,861],{"x":721,"y":850,"width":722,"height":754,"rx":695,"fill":698,"stroke":706,"style":707},[713,863,642],{"x":725,"y":853,"style":798},[692,865],{"x":729,"y":850,"width":730,"height":754,"rx":695,"fill":698,"stroke":706,"style":707},[713,867,290],{"x":733,"y":853,"style":798},[692,869],{"x":737,"y":850,"width":738,"height":754,"rx":695,"fill":698,"stroke":706,"style":707},[713,871,290],{"x":741,"y":853,"style":798},[692,873],{"x":745,"y":850,"width":746,"height":754,"rx":695,"fill":698,"stroke":706,"style":707},[713,875,876],{"x":749,"y":853,"style":798},"validation, protected",[692,878],{"x":701,"y":879,"width":703,"height":754,"rx":695,"fill":705,"stroke":706,"style":707},"152.0",[713,881,838],{"x":757,"y":882,"style":717},"171.0",[692,884],{"x":710,"y":879,"width":711,"height":754,"rx":695,"fill":698,"stroke":706,"style":707},[713,886,666],{"x":715,"y":882,"style":798},[692,888],{"x":721,"y":879,"width":722,"height":754,"rx":695,"fill":698,"stroke":706,"style":707},[713,890,642],{"x":725,"y":882,"style":798},[692,892],{"x":729,"y":879,"width":730,"height":754,"rx":695,"fill":893,"stroke":894,"style":763},"#fce9e9","var(--danger,#dc2626)",[713,896,898],{"x":733,"y":882,"style":897},"font-size:12px;font-weight:700;fill:var(--accent-ink,#be185d);text-anchor:middle","19,999",[692,900],{"x":737,"y":879,"width":738,"height":754,"rx":695,"fill":698,"stroke":706,"style":707},[713,902,290],{"x":741,"y":882,"style":798},[692,904],{"x":745,"y":879,"width":746,"height":754,"rx":695,"fill":698,"stroke":706,"style":707},[713,906,907],{"x":749,"y":882,"style":798},"formatting only",[692,909],{"x":701,"y":910,"width":703,"height":754,"rx":695,"fill":705,"stroke":706,"style":707},"180.0",[713,912,914],{"x":757,"y":913,"style":717},"199.0","6",[692,916],{"x":710,"y":910,"width":711,"height":754,"rx":695,"fill":698,"stroke":706,"style":707},[713,918,919],{"x":715,"y":913,"style":798},"Lookups",[692,921],{"x":721,"y":910,"width":722,"height":754,"rx":695,"fill":922,"stroke":923,"style":763},"#fdefd8","var(--gold,#b4740a)",[713,925,646],{"x":725,"y":913,"style":926},"font-size:12px;font-weight:700;fill:var(--gold-ink,#7a4e06);text-anchor:middle",[692,928],{"x":729,"y":910,"width":730,"height":754,"rx":695,"fill":698,"stroke":706,"style":707},[713,930,793],{"x":733,"y":913,"style":798},[692,932],{"x":737,"y":910,"width":738,"height":754,"rx":695,"fill":698,"stroke":706,"style":707},[713,934,793],{"x":741,"y":913,"style":798},[692,936],{"x":745,"y":910,"width":746,"height":754,"rx":695,"fill":698,"stroke":706,"style":707},[692,938],{"x":701,"y":939,"width":703,"height":754,"rx":695,"fill":705,"stroke":706,"style":707},"208.0",[713,941,943],{"x":757,"y":942,"style":717},"227.0","7",[692,945],{"x":710,"y":939,"width":711,"height":754,"rx":695,"fill":698,"stroke":706,"style":707},[713,947,948],{"x":715,"y":942,"style":798},"Calc",[692,950],{"x":721,"y":939,"width":722,"height":754,"rx":695,"fill":893,"stroke":894,"style":763},[713,952,650],{"x":725,"y":942,"style":897},[692,954],{"x":729,"y":939,"width":730,"height":754,"rx":695,"fill":698,"stroke":706,"style":707},[713,956,290],{"x":733,"y":942,"style":798},[692,958],{"x":737,"y":939,"width":738,"height":754,"rx":695,"fill":698,"stroke":706,"style":707},[713,960,290],{"x":741,"y":942,"style":798},[692,962],{"x":745,"y":939,"width":746,"height":754,"rx":695,"fill":698,"stroke":706,"style":707},[713,964,965],{"x":749,"y":942,"style":798},"1 formula",[30,967,969],{"id":968},"step-2-how-much-of-the-file-each-sheet-takes","Step 2 — How much of the file each sheet takes",[35,971,973],{"className":71,"code":972,"language":73,"meta":40,"style":40},"import zipfile\nimport xml.etree.ElementTree as ET\n\nNS = {\"m\": \"http:\u002F\u002Fschemas.openxmlformats.org\u002Fspreadsheetml\u002F2006\u002Fmain\",\n      \"r\": \"http:\u002F\u002Fschemas.openxmlformats.org\u002FofficeDocument\u002F2006\u002Frelationships\",\n      \"p\": \"http:\u002F\u002Fschemas.openxmlformats.org\u002Fpackage\u002F2006\u002Frelationships\"}\n\ndef part_sizes(path):\n    \"\"\"Compressed and uncompressed size of each sheet's XML inside the .xlsx package.\"\"\"\n    with zipfile.ZipFile(path) as z:\n        rels = ET.fromstring(z.read(\"xl\u002F_rels\u002Fworkbook.xml.rels\"))\n        target = {r.get(\"Id\"): r.get(\"Target\").lstrip(\"\u002F\").removeprefix(\"xl\u002F\") for r in rels.findall(\"p:Relationship\", NS)}\n        book = ET.fromstring(z.read(\"xl\u002Fworkbook.xml\"))\n        sizes = {}\n        for s in book.findall(\"m:sheets\u002Fm:sheet\", NS):\n            info = z.getinfo(\"xl\u002F\" + target[s.get(f\"{{{NS['r']}}}id\")])\n            sizes[s.get(\"name\")] = (info.compress_size, info.file_size)\n    return sizes\n\nsizes = part_sizes(\"finance_model.xlsx\")\ninv[\"Stored KB\"] = inv[\"Sheet\"].map(lambda s: round(sizes[s][0] \u002F 1024, 1))\ninv[\"Unpacked KB\"] = inv[\"Sheet\"].map(lambda s: round(sizes[s][1] \u002F 1024, 1))\nprint(inv[[\"Sheet\", \"State\", \"Rows with data\", \"Stored KB\", \"Unpacked KB\"]].to_string(index=False))\n",[19,974,975,982,994,998,1019,1031,1043,1047,1056,1061,1074,1092,1145,1161,1171,1192,1239,1255,1262,1266,1281,1330,1369],{"__ignoreMap":40},[44,976,977,979],{"class":46,"line":47},[44,978,88],{"class":80},[44,980,981],{"class":84}," zipfile\n",[44,983,984,986,989,991],{"class":46,"line":94},[44,985,88],{"class":80},[44,987,988],{"class":84}," xml.etree.ElementTree ",[44,990,576],{"class":80},[44,992,993],{"class":147}," ET\n",[44,995,996],{"class":46,"line":107},[44,997,111],{"emptyLinePlaceholder":110},[44,999,1000,1003,1006,1008,1011,1013,1016],{"class":46,"line":114},[44,1001,1002],{"class":147},"NS",[44,1004,1005],{"class":80}," =",[44,1007,304],{"class":84},[44,1009,1010],{"class":54},"\"m\"",[44,1012,310],{"class":84},[44,1014,1015],{"class":54},"\"http:\u002F\u002Fschemas.openxmlformats.org\u002Fspreadsheetml\u002F2006\u002Fmain\"",[44,1017,1018],{"class":84},",\n",[44,1020,1021,1024,1026,1029],{"class":46,"line":127},[44,1022,1023],{"class":54},"      \"r\"",[44,1025,310],{"class":84},[44,1027,1028],{"class":54},"\"http:\u002F\u002Fschemas.openxmlformats.org\u002FofficeDocument\u002F2006\u002Frelationships\"",[44,1030,1018],{"class":84},[44,1032,1033,1036,1038,1041],{"class":46,"line":133},[44,1034,1035],{"class":54},"      \"p\"",[44,1037,310],{"class":84},[44,1039,1040],{"class":54},"\"http:\u002F\u002Fschemas.openxmlformats.org\u002Fpackage\u002F2006\u002Frelationships\"",[44,1042,363],{"class":84},[44,1044,1045],{"class":46,"line":151},[44,1046,111],{"emptyLinePlaceholder":110},[44,1048,1049,1051,1054],{"class":46,"line":166},[44,1050,117],{"class":80},[44,1052,1053],{"class":120}," part_sizes",[44,1055,243],{"class":84},[44,1057,1058],{"class":46,"line":180},[44,1059,1060],{"class":54},"    \"\"\"Compressed and uncompressed size of each sheet's XML inside the .xlsx package.\"\"\"\n",[44,1062,1063,1066,1069,1071],{"class":46,"line":201},[44,1064,1065],{"class":80},"    with",[44,1067,1068],{"class":84}," zipfile.ZipFile(path) ",[44,1070,576],{"class":80},[44,1072,1073],{"class":84}," z:\n",[44,1075,1076,1079,1081,1084,1087,1090],{"class":46,"line":221},[44,1077,1078],{"class":84},"        rels ",[44,1080,139],{"class":80},[44,1082,1083],{"class":147}," ET",[44,1085,1086],{"class":84},".fromstring(z.read(",[44,1088,1089],{"class":54},"\"xl\u002F_rels\u002Fworkbook.xml.rels\"",[44,1091,596],{"class":84},[44,1093,1094,1097,1099,1102,1105,1108,1111,1114,1117,1120,1123,1126,1128,1130,1132,1135,1138,1140,1142],{"class":46,"line":230},[44,1095,1096],{"class":84},"        target ",[44,1098,139],{"class":80},[44,1100,1101],{"class":84}," {r.get(",[44,1103,1104],{"class":54},"\"Id\"",[44,1106,1107],{"class":84},"): r.get(",[44,1109,1110],{"class":54},"\"Target\"",[44,1112,1113],{"class":84},").lstrip(",[44,1115,1116],{"class":54},"\"\u002F\"",[44,1118,1119],{"class":84},").removeprefix(",[44,1121,1122],{"class":54},"\"xl\u002F\"",[44,1124,1125],{"class":84},") ",[44,1127,451],{"class":80},[44,1129,443],{"class":84},[44,1131,160],{"class":80},[44,1133,1134],{"class":84}," rels.findall(",[44,1136,1137],{"class":54},"\"p:Relationship\"",[44,1139,643],{"class":84},[44,1141,1002],{"class":147},[44,1143,1144],{"class":84},")}\n",[44,1146,1147,1150,1152,1154,1156,1159],{"class":46,"line":235},[44,1148,1149],{"class":84},"        book ",[44,1151,139],{"class":80},[44,1153,1083],{"class":147},[44,1155,1086],{"class":84},[44,1157,1158],{"class":54},"\"xl\u002Fworkbook.xml\"",[44,1160,596],{"class":84},[44,1162,1163,1166,1168],{"class":46,"line":246},[44,1164,1165],{"class":84},"        sizes ",[44,1167,139],{"class":80},[44,1169,1170],{"class":84}," {}\n",[44,1172,1173,1175,1178,1180,1183,1186,1188,1190],{"class":46,"line":257},[44,1174,169],{"class":80},[44,1176,1177],{"class":84}," s ",[44,1179,160],{"class":80},[44,1181,1182],{"class":84}," book.findall(",[44,1184,1185],{"class":54},"\"m:sheets\u002Fm:sheet\"",[44,1187,643],{"class":84},[44,1189,1002],{"class":147},[44,1191,293],{"class":84},[44,1193,1194,1197,1199,1202,1204,1207,1210,1212,1215,1219,1221,1224,1227,1230,1233,1236],{"class":46,"line":268},[44,1195,1196],{"class":84},"            info ",[44,1198,139],{"class":80},[44,1200,1201],{"class":84}," z.getinfo(",[44,1203,1122],{"class":54},[44,1205,1206],{"class":80}," +",[44,1208,1209],{"class":84}," target[s.get(",[44,1211,670],{"class":80},[44,1213,1214],{"class":54},"\"",[44,1216,1218],{"class":1217},"sSjpA","{{{",[44,1220,1002],{"class":147},[44,1222,1223],{"class":84},"[",[44,1225,1226],{"class":54},"'r'",[44,1228,1229],{"class":84},"]",[44,1231,1232],{"class":1217},"}}}",[44,1234,1235],{"class":54},"id\"",[44,1237,1238],{"class":84},")])\n",[44,1240,1241,1244,1247,1250,1252],{"class":46,"line":296},[44,1242,1243],{"class":84},"            sizes[s.get(",[44,1245,1246],{"class":54},"\"name\"",[44,1248,1249],{"class":84},")] ",[44,1251,139],{"class":80},[44,1253,1254],{"class":84}," (info.compress_size, info.file_size)\n",[44,1256,1257,1259],{"class":46,"line":337},[44,1258,224],{"class":80},[44,1260,1261],{"class":84}," sizes\n",[44,1263,1264],{"class":46,"line":366},[44,1265,111],{"emptyLinePlaceholder":110},[44,1267,1268,1271,1273,1276,1278],{"class":46,"line":377},[44,1269,1270],{"class":84},"sizes ",[44,1272,139],{"class":80},[44,1274,1275],{"class":84}," part_sizes(",[44,1277,593],{"class":54},[44,1279,1280],{"class":84},")\n",[44,1282,1283,1286,1289,1292,1294,1297,1299,1302,1305,1308,1311,1314,1316,1318,1321,1324,1326,1328],{"class":46,"line":388},[44,1284,1285],{"class":84},"inv[",[44,1287,1288],{"class":54},"\"Stored KB\"",[44,1290,1291],{"class":84},"] ",[44,1293,139],{"class":80},[44,1295,1296],{"class":84}," inv[",[44,1298,325],{"class":54},[44,1300,1301],{"class":84},"].map(",[44,1303,1304],{"class":80},"lambda",[44,1306,1307],{"class":84}," s: ",[44,1309,1310],{"class":147},"round",[44,1312,1313],{"class":84},"(sizes[s][",[44,1315,695],{"class":147},[44,1317,1291],{"class":84},[44,1319,1320],{"class":80},"\u002F",[44,1322,1323],{"class":147}," 1024",[44,1325,643],{"class":84},[44,1327,290],{"class":147},[44,1329,596],{"class":84},[44,1331,1332,1334,1337,1339,1341,1343,1345,1347,1349,1351,1353,1355,1357,1359,1361,1363,1365,1367],{"class":46,"line":394},[44,1333,1285],{"class":84},[44,1335,1336],{"class":54},"\"Unpacked KB\"",[44,1338,1291],{"class":84},[44,1340,139],{"class":80},[44,1342,1296],{"class":84},[44,1344,325],{"class":54},[44,1346,1301],{"class":84},[44,1348,1304],{"class":80},[44,1350,1307],{"class":84},[44,1352,1310],{"class":147},[44,1354,1313],{"class":84},[44,1356,290],{"class":147},[44,1358,1291],{"class":84},[44,1360,1320],{"class":80},[44,1362,1323],{"class":147},[44,1364,643],{"class":84},[44,1366,290],{"class":147},[44,1368,596],{"class":84},[44,1370,1371,1373,1376,1378,1380,1382,1384,1387,1389,1391,1393,1395,1398,1400,1402,1404],{"class":46,"line":409},[44,1372,602],{"class":147},[44,1374,1375],{"class":84},"(inv[[",[44,1377,325],{"class":54},[44,1379,643],{"class":84},[44,1381,331],{"class":54},[44,1383,643],{"class":84},[44,1385,1386],{"class":54},"\"Rows with data\"",[44,1388,643],{"class":84},[44,1390,1288],{"class":54},[44,1392,643],{"class":84},[44,1394,1336],{"class":54},[44,1396,1397],{"class":84},"]].to_string(",[44,1399,618],{"class":284},[44,1401,139],{"class":80},[44,1403,623],{"class":147},[44,1405,596],{"class":84},[10,1407,1408,1409,1411,1412,1414,1415,28],{},"An ",[19,1410,21],{}," file is a zip archive with one XML part per sheet. The workbook part lists the sheets and a relationships part maps each to its file; parsing both with ElementTree, rather than matching them with regular expressions, copes with the attributes appearing in any order, which they do between writers. Following the two gives every sheet's compressed size in the archive and its unpacked size, which is roughly what Excel has to parse when it opens the file. The ",[14,1413,666],{}," sheet, with one value and twenty thousand formatted cells, takes 974.8 KB unpacked — almost fifteen times the 65.9 KB of the data sheet with its 1,500 values, and more than every other sheet in the workbook put together. The compressed size understates the problem because repetitive XML compresses very well, so the unpacked size is the better guide to opening time. Finding and fixing such sheets is covered in ",[24,1416,1418],{"href":1417},"\u002Fadvanced-data-transformation-and-cleaning\u002Fworking-with-large-excel-files-in-python\u002Ffind-out-why-an-excel-file-is-slow-to-open\u002F","Find Out Why an Excel File Is Slow to Open",[673,1420,682,1426,682,1429,682,1432,682,1436,682,1443,682,1449,682,1454,682,1458,682,1462,682,1466,682,1470,682,1475,682,1479,682,1483,682,1486,682,1489,682,1492],{"viewBox":1421,"role":676,"ariaLabelledBy":1422,"xmlns":680,"style":1425},"4 0 752 199",[1423,1424],"inv-ranges-t","inv-ranges-d","width:100%;max-width:752px;height:auto;display:block;margin:1.5rem auto;font-family:Inter,ui-sans-serif,system-ui,sans-serif",[684,1427,1428],{"id":1423},"Reported range or real data",[688,1430,1431],{"id":1424},"The reported range counts every cell that has been touched, including formatting with no value, and is what Excel uses for scrolling and the used range. The range with data counts only cells that hold values. A large gap means formatting-only cells that slow the file down.",[692,1433],{"x":854,"y":695,"width":1434,"height":1435,"fill":698},"752","199",[692,1437],{"x":1438,"y":702,"width":1439,"height":1440,"rx":1441,"fill":922,"stroke":923,"style":1442},"20.0","351.0","167.0","14","stroke-width:2px",[713,1444,1448],{"x":1445,"y":1446,"style":1447},"195.5","44.0","font-size:14px;font-weight:700;fill:var(--gold-ink,#7a4e06);text-anchor:middle","Reported range",[46,1450],{"x1":1451,"y1":1452,"x2":1453,"y2":1452,"stroke":923,"style":707},"36.0","57.0","355.0",[713,1455,1457],{"x":1445,"y":1456,"style":798},"77.0","ws.dimensions, ws.max_row",[713,1459,1461],{"x":1445,"y":1460,"style":798},"103.0","includes formatted empty cells",[713,1463,1465],{"x":1445,"y":1464,"style":798},"129.0","what Excel scrolls to",[713,1467,1469],{"x":1445,"y":1468,"style":798},"155.0","Old layout: 19,999 rows",[692,1471],{"x":1472,"y":702,"width":1439,"height":1440,"rx":1441,"fill":1473,"stroke":1474,"style":1442},"389.0","#d9f4f1","var(--teal,#0f9488)",[713,1476,662],{"x":1477,"y":1446,"style":1478},"564.5","font-size:14px;font-weight:700;fill:var(--teal-ink,#0b6157);text-anchor:middle",[46,1480],{"x1":1481,"y1":1452,"x2":1482,"y2":1452,"stroke":1474,"style":707},"405.0","724.0",[713,1484,1485],{"x":1477,"y":1456,"style":798},"cells with a value",[713,1487,1488],{"x":1477,"y":1460,"style":798},"ignores formatting only",[713,1490,1491],{"x":1477,"y":1464,"style":798},"the real content",[713,1493,1494],{"x":1477,"y":1468,"style":798},"Old layout: 1 row",[673,1496,682,1502,682,1505,682,1508,682,1513,682,1516,682,1519,682,1522,682,1526,682,1529,682,1533,682,1536,682,1540,682,1543,682,1545,682,1548,682,1550,682,1552,682,1554,682,1557,682,1559,682,1562,682,1564,682,1567,682,1569,682,1571,682,1573,682,1575,682,1577,682,1580,682,1582,682,1585,682,1587,682,1590,682,1592,682,1594,682,1596,682,1598,682,1600,682,1602,682,1604,682,1607,682,1609,682,1612,682,1614,682,1616,682,1618,682,1620,682,1622,682,1624,682,1626,682,1629,682,1631,682,1634,682,1636,682,1638,682,1640,682,1642,682,1644,682,1646,682,1648,682,1651,682,1653,682,1656,682,1658,682,1660,682,1662,682,1664,682,1666,682,1668,682,1670,682,1672,682,1674],{"viewBox":1497,"role":676,"ariaLabelledBy":1498,"xmlns":680,"style":1501},"175 0 410 224",[1499,1500],"inv-sizes-t","inv-sizes-d","width:100%;max-width:410px;height:auto;display:block;margin:1.5rem auto;font-family:Inter,ui-sans-serif,system-ui,sans-serif",[684,1503,1504],{"id":1499},"Unpacked size of each sheet",[688,1506,1507],{"id":1500},"The Old layout sheet takes 974.8 kilobytes unpacked for one value, against 65.9 kilobytes for the Data sheet with 1,500 values. The other four sheets take about a kilobyte each.",[692,1509],{"x":1510,"y":695,"width":1511,"height":1512,"fill":698},"175","410","224",[692,1514],{"x":1515,"y":702,"width":703,"height":704,"rx":695,"fill":705,"stroke":706,"style":707},"191.2",[692,1517],{"x":1518,"y":702,"width":711,"height":704,"rx":695,"fill":705,"stroke":706,"style":707},"223.2",[713,1520,718],{"x":1521,"y":716,"style":717},"266.5",[692,1523],{"x":1524,"y":702,"width":1525,"height":704,"rx":695,"fill":705,"stroke":706,"style":707},"309.8","66.6",[713,1527,726],{"x":1528,"y":716,"style":717},"343.1",[692,1530],{"x":1531,"y":702,"width":1532,"height":704,"rx":695,"fill":705,"stroke":706,"style":707},"376.3","85.6",[713,1534,734],{"x":1535,"y":716,"style":717},"419.1",[692,1537],{"x":1538,"y":702,"width":1539,"height":704,"rx":695,"fill":705,"stroke":706,"style":707},"461.9","106.9",[713,1541,742],{"x":1542,"y":716,"style":717},"515.3",[692,1544],{"x":1515,"y":753,"width":703,"height":754,"rx":695,"fill":705,"stroke":706,"style":707},[713,1546,290],{"x":1547,"y":758,"style":717},"207.2",[692,1549],{"x":1518,"y":753,"width":711,"height":754,"rx":695,"fill":761,"stroke":762,"style":763},[713,1551,767],{"x":1521,"y":758,"style":766},[692,1553],{"x":1524,"y":753,"width":1525,"height":754,"rx":695,"fill":761,"stroke":762,"style":763},[713,1555,1556],{"x":1528,"y":758,"style":766},"Values",[692,1558],{"x":1531,"y":753,"width":1532,"height":754,"rx":695,"fill":761,"stroke":762,"style":763},[713,1560,1561],{"x":1535,"y":758,"style":766},"Stored KB",[692,1563],{"x":1538,"y":753,"width":1539,"height":754,"rx":695,"fill":761,"stroke":762,"style":763},[713,1565,1566],{"x":1542,"y":758,"style":766},"Unpacked KB",[692,1568],{"x":1515,"y":789,"width":703,"height":754,"rx":695,"fill":705,"stroke":706,"style":707},[713,1570,793],{"x":1547,"y":792,"style":717},[692,1572],{"x":1518,"y":789,"width":711,"height":754,"rx":695,"fill":698,"stroke":706,"style":707},[713,1574,799],{"x":1521,"y":792,"style":798},[692,1576],{"x":1524,"y":789,"width":1525,"height":754,"rx":695,"fill":698,"stroke":706,"style":707},[713,1578,1579],{"x":1528,"y":792,"style":798},"1,503",[692,1581],{"x":1531,"y":789,"width":1532,"height":754,"rx":695,"fill":698,"stroke":706,"style":707},[713,1583,1584],{"x":1535,"y":792,"style":798},"9.7",[692,1586],{"x":1538,"y":789,"width":1539,"height":754,"rx":695,"fill":698,"stroke":706,"style":707},[713,1588,1589],{"x":1542,"y":792,"style":798},"65.9",[692,1591],{"x":1515,"y":820,"width":703,"height":754,"rx":695,"fill":705,"stroke":706,"style":707},[713,1593,824],{"x":1547,"y":823,"style":717},[692,1595],{"x":1518,"y":820,"width":711,"height":754,"rx":695,"fill":698,"stroke":706,"style":707},[713,1597,829],{"x":1521,"y":823,"style":798},[692,1599],{"x":1524,"y":820,"width":1525,"height":754,"rx":695,"fill":698,"stroke":706,"style":707},[713,1601,838],{"x":1528,"y":823,"style":798},[692,1603],{"x":1531,"y":820,"width":1532,"height":754,"rx":695,"fill":698,"stroke":706,"style":707},[713,1605,1606],{"x":1535,"y":823,"style":798},"0.5",[692,1608],{"x":1538,"y":820,"width":1539,"height":754,"rx":695,"fill":698,"stroke":706,"style":707},[713,1610,1611],{"x":1542,"y":823,"style":798},"1.0",[692,1613],{"x":1515,"y":850,"width":703,"height":754,"rx":695,"fill":705,"stroke":706,"style":707},[713,1615,854],{"x":1547,"y":853,"style":717},[692,1617],{"x":1518,"y":850,"width":711,"height":754,"rx":695,"fill":698,"stroke":706,"style":707},[713,1619,666],{"x":1521,"y":853,"style":798},[692,1621],{"x":1524,"y":850,"width":1525,"height":754,"rx":695,"fill":698,"stroke":706,"style":707},[713,1623,290],{"x":1528,"y":853,"style":798},[692,1625],{"x":1531,"y":850,"width":1532,"height":754,"rx":695,"fill":698,"stroke":706,"style":707},[713,1627,1628],{"x":1535,"y":853,"style":798},"101.5",[692,1630],{"x":1538,"y":850,"width":1539,"height":754,"rx":695,"fill":893,"stroke":894,"style":763},[713,1632,1633],{"x":1542,"y":853,"style":897},"974.8",[692,1635],{"x":1515,"y":879,"width":703,"height":754,"rx":695,"fill":705,"stroke":706,"style":707},[713,1637,838],{"x":1547,"y":882,"style":717},[692,1639],{"x":1518,"y":879,"width":711,"height":754,"rx":695,"fill":698,"stroke":706,"style":707},[713,1641,919],{"x":1521,"y":882,"style":798},[692,1643],{"x":1524,"y":879,"width":1525,"height":754,"rx":695,"fill":698,"stroke":706,"style":707},[713,1645,854],{"x":1528,"y":882,"style":798},[692,1647],{"x":1531,"y":879,"width":1532,"height":754,"rx":695,"fill":698,"stroke":706,"style":707},[713,1649,1650],{"x":1535,"y":882,"style":798},"0.3",[692,1652],{"x":1538,"y":879,"width":1539,"height":754,"rx":695,"fill":698,"stroke":706,"style":707},[713,1654,1655],{"x":1542,"y":882,"style":798},"0.7",[692,1657],{"x":1515,"y":910,"width":703,"height":754,"rx":695,"fill":705,"stroke":706,"style":707},[713,1659,914],{"x":1547,"y":913,"style":717},[692,1661],{"x":1518,"y":910,"width":711,"height":754,"rx":695,"fill":698,"stroke":706,"style":707},[713,1663,948],{"x":1521,"y":913,"style":798},[692,1665],{"x":1524,"y":910,"width":1525,"height":754,"rx":695,"fill":698,"stroke":706,"style":707},[713,1667,290],{"x":1528,"y":913,"style":798},[692,1669],{"x":1531,"y":910,"width":1532,"height":754,"rx":695,"fill":698,"stroke":706,"style":707},[713,1671,1650],{"x":1535,"y":913,"style":798},[692,1673],{"x":1538,"y":910,"width":1539,"height":754,"rx":695,"fill":698,"stroke":706,"style":707},[713,1675,1606],{"x":1542,"y":913,"style":798},[10,1677,1678],{},"Deleting the formatted rows on the old sheet — or the sheet itself, if it is truly archived — would cut the unpacked size of the whole workbook by more than nine tenths. That is the kind of finding that justifies running an inventory before any clean-up: the problem is concentrated in one place that nobody would have guessed from looking at the tabs.",[30,1680,1682],{"id":1681},"step-3-a-folder-of-workbooks-into-one-report","Step 3 — A folder of workbooks into one report",[35,1684,1686],{"className":71,"code":1685,"language":73,"meta":40,"style":40},"from pathlib import Path\n\ndef inventory_folder(folder):\n    rows = []\n    for path in sorted(Path(folder).glob(\"*.xlsx\")):\n        if path.name.startswith(\"~$\"):\n            continue                                       # Excel lock files\n        try:\n            sizes = part_sizes(path)\n            for r in inventory(path):\n                r[\"Unpacked KB\"] = round(sizes.get(r[\"Sheet\"], (0, 0))[1] \u002F 1024, 1)\n                rows.append(r)\n        except Exception as e:\n            rows.append({\"File\": str(path), \"Sheet\": \"\", \"State\": f\"could not open: {type(e).__name__}\"})\n    return pd.DataFrame(rows)\n\nPath(\"models\").mkdir(exist_ok=True)\nPath(\"finance_model.xlsx\").replace(\"models\u002Ffinance_model.xlsx\")\nreport = inventory_folder(\"models\")\nflags = report[(report[\"State\"] != \"visible\") | (report[\"Reported rows\"] > 10 * report[\"Rows with data\"].clip(lower=1))]\nwith pd.ExcelWriter(\"workbook_inventory.xlsx\") as xw:\n    report.to_excel(xw, sheet_name=\"Sheets\", index=False)\n    flags.to_excel(xw, sheet_name=\"Look at these\", index=False)\nprint(flags[[\"Sheet\", \"State\", \"Reported rows\", \"Rows with data\"]].to_string(index=False))\n",[19,1687,1688,1700,1704,1714,1722,1743,1755,1764,1771,1781,1793,1838,1843,1857,1908,1915,1919,1940,1954,1968,2027,2045,2068,2090],{"__ignoreMap":40},[44,1689,1690,1692,1695,1697],{"class":46,"line":47},[44,1691,81],{"class":80},[44,1693,1694],{"class":84}," pathlib ",[44,1696,88],{"class":80},[44,1698,1699],{"class":84}," Path\n",[44,1701,1702],{"class":46,"line":94},[44,1703,111],{"emptyLinePlaceholder":110},[44,1705,1706,1708,1711],{"class":46,"line":107},[44,1707,117],{"class":80},[44,1709,1710],{"class":120}," inventory_folder",[44,1712,1713],{"class":84},"(folder):\n",[44,1715,1716,1718,1720],{"class":46,"line":114},[44,1717,260],{"class":84},[44,1719,139],{"class":80},[44,1721,265],{"class":84},[44,1723,1724,1726,1729,1731,1734,1737,1740],{"class":46,"line":127},[44,1725,154],{"class":80},[44,1727,1728],{"class":84}," path ",[44,1730,160],{"class":80},[44,1732,1733],{"class":147}," sorted",[44,1735,1736],{"class":84},"(Path(folder).glob(",[44,1738,1739],{"class":54},"\"*.xlsx\"",[44,1741,1742],{"class":84},")):\n",[44,1744,1745,1747,1750,1753],{"class":46,"line":133},[44,1746,369],{"class":80},[44,1748,1749],{"class":84}," path.name.startswith(",[44,1751,1752],{"class":54},"\"~$\"",[44,1754,293],{"class":84},[44,1756,1757,1760],{"class":46,"line":151},[44,1758,1759],{"class":80},"            continue",[44,1761,1763],{"class":1762},"s-wDw","                                       # Excel lock files\n",[44,1765,1766,1769],{"class":46,"line":166},[44,1767,1768],{"class":80},"        try",[44,1770,198],{"class":84},[44,1772,1773,1776,1778],{"class":46,"line":180},[44,1774,1775],{"class":84},"            sizes ",[44,1777,139],{"class":80},[44,1779,1780],{"class":84}," part_sizes(path)\n",[44,1782,1783,1786,1788,1790],{"class":46,"line":201},[44,1784,1785],{"class":80},"            for",[44,1787,443],{"class":84},[44,1789,160],{"class":80},[44,1791,1792],{"class":84}," inventory(path):\n",[44,1794,1795,1798,1800,1802,1804,1807,1810,1812,1815,1817,1819,1821,1824,1826,1828,1830,1832,1834,1836],{"class":46,"line":221},[44,1796,1797],{"class":84},"                r[",[44,1799,1336],{"class":54},[44,1801,1291],{"class":84},[44,1803,139],{"class":80},[44,1805,1806],{"class":147}," round",[44,1808,1809],{"class":84},"(sizes.get(r[",[44,1811,325],{"class":54},[44,1813,1814],{"class":84},"], (",[44,1816,695],{"class":147},[44,1818,643],{"class":84},[44,1820,695],{"class":147},[44,1822,1823],{"class":84},"))[",[44,1825,290],{"class":147},[44,1827,1291],{"class":84},[44,1829,1320],{"class":80},[44,1831,1323],{"class":147},[44,1833,643],{"class":84},[44,1835,290],{"class":147},[44,1837,1280],{"class":84},[44,1839,1840],{"class":46,"line":230},[44,1841,1842],{"class":84},"                rows.append(r)\n",[44,1844,1845,1848,1851,1854],{"class":46,"line":235},[44,1846,1847],{"class":80},"        except",[44,1849,1850],{"class":147}," Exception",[44,1852,1853],{"class":80}," as",[44,1855,1856],{"class":84}," e:\n",[44,1858,1859,1862,1864,1866,1868,1870,1872,1874,1877,1879,1881,1883,1885,1888,1891,1894,1897,1900,1903,1905],{"class":46,"line":246},[44,1860,1861],{"class":84},"            rows.append({",[44,1863,307],{"class":54},[44,1865,310],{"class":84},[44,1867,313],{"class":147},[44,1869,316],{"class":84},[44,1871,325],{"class":54},[44,1873,310],{"class":84},[44,1875,1876],{"class":54},"\"\"",[44,1878,643],{"class":84},[44,1880,331],{"class":54},[44,1882,310],{"class":84},[44,1884,670],{"class":80},[44,1886,1887],{"class":54},"\"could not open: ",[44,1889,1890],{"class":1217},"{",[44,1892,1893],{"class":147},"type",[44,1895,1896],{"class":84},"(e).",[44,1898,1899],{"class":147},"__name__",[44,1901,1902],{"class":1217},"}",[44,1904,1214],{"class":54},[44,1906,1907],{"class":84},"})\n",[44,1909,1910,1912],{"class":46,"line":257},[44,1911,224],{"class":80},[44,1913,1914],{"class":84}," pd.DataFrame(rows)\n",[44,1916,1917],{"class":46,"line":268},[44,1918,111],{"emptyLinePlaceholder":110},[44,1920,1921,1924,1927,1930,1933,1935,1938],{"class":46,"line":296},[44,1922,1923],{"class":84},"Path(",[44,1925,1926],{"class":54},"\"models\"",[44,1928,1929],{"class":84},").mkdir(",[44,1931,1932],{"class":284},"exist_ok",[44,1934,139],{"class":80},[44,1936,1937],{"class":147},"True",[44,1939,1280],{"class":84},[44,1941,1942,1944,1946,1949,1952],{"class":46,"line":337},[44,1943,1923],{"class":84},[44,1945,593],{"class":54},[44,1947,1948],{"class":84},").replace(",[44,1950,1951],{"class":54},"\"models\u002Ffinance_model.xlsx\"",[44,1953,1280],{"class":84},[44,1955,1956,1959,1961,1964,1966],{"class":46,"line":366},[44,1957,1958],{"class":84},"report ",[44,1960,139],{"class":80},[44,1962,1963],{"class":84}," inventory_folder(",[44,1965,1926],{"class":54},[44,1967,1280],{"class":84},[44,1969,1970,1973,1975,1978,1980,1982,1985,1988,1990,1993,1996,1998,2000,2003,2006,2009,2012,2014,2017,2020,2022,2024],{"class":46,"line":377},[44,1971,1972],{"class":84},"flags ",[44,1974,139],{"class":80},[44,1976,1977],{"class":84}," report[(report[",[44,1979,331],{"class":54},[44,1981,1291],{"class":84},[44,1983,1984],{"class":80},"!=",[44,1986,1987],{"class":54}," \"visible\"",[44,1989,1125],{"class":84},[44,1991,1992],{"class":80},"|",[44,1994,1995],{"class":84}," (report[",[44,1997,403],{"class":54},[44,1999,1291],{"class":84},[44,2001,2002],{"class":80},">",[44,2004,2005],{"class":147}," 10",[44,2007,2008],{"class":80}," *",[44,2010,2011],{"class":84}," report[",[44,2013,1386],{"class":54},[44,2015,2016],{"class":84},"].clip(",[44,2018,2019],{"class":284},"lower",[44,2021,139],{"class":80},[44,2023,290],{"class":147},[44,2025,2026],{"class":84},"))]\n",[44,2028,2029,2032,2035,2038,2040,2042],{"class":46,"line":388},[44,2030,2031],{"class":80},"with",[44,2033,2034],{"class":84}," pd.ExcelWriter(",[44,2036,2037],{"class":54},"\"workbook_inventory.xlsx\"",[44,2039,1125],{"class":84},[44,2041,576],{"class":80},[44,2043,2044],{"class":84}," xw:\n",[44,2046,2047,2050,2053,2055,2058,2060,2062,2064,2066],{"class":46,"line":394},[44,2048,2049],{"class":84},"    report.to_excel(xw, ",[44,2051,2052],{"class":284},"sheet_name",[44,2054,139],{"class":80},[44,2056,2057],{"class":54},"\"Sheets\"",[44,2059,643],{"class":84},[44,2061,618],{"class":284},[44,2063,139],{"class":80},[44,2065,623],{"class":147},[44,2067,1280],{"class":84},[44,2069,2070,2073,2075,2077,2080,2082,2084,2086,2088],{"class":46,"line":409},[44,2071,2072],{"class":84},"    flags.to_excel(xw, ",[44,2074,2052],{"class":284},[44,2076,139],{"class":80},[44,2078,2079],{"class":54},"\"Look at these\"",[44,2081,643],{"class":84},[44,2083,618],{"class":284},[44,2085,139],{"class":80},[44,2087,623],{"class":147},[44,2089,1280],{"class":84},[44,2091,2092,2094,2097,2099,2101,2103,2105,2107,2109,2111,2113,2115,2117,2119],{"class":46,"line":424},[44,2093,602],{"class":147},[44,2095,2096],{"class":84},"(flags[[",[44,2098,325],{"class":54},[44,2100,643],{"class":84},[44,2102,331],{"class":54},[44,2104,643],{"class":84},[44,2106,403],{"class":54},[44,2108,643],{"class":84},[44,2110,1386],{"class":54},[44,2112,1397],{"class":84},[44,2114,618],{"class":284},[44,2116,139],{"class":80},[44,2118,623],{"class":147},[44,2120,596],{"class":84},[10,2122,2123],{},"Wrapped in a loop over a folder, the same functions produce an inventory of every workbook a team keeps on a share, with one row per sheet and the file name as the first column. Lock files left by Excel are skipped, and a file that cannot be opened gets a row saying so rather than stopping the run. A second sheet lists the rows worth a look: sheets that are not visible, and sheets whose reported rows are more than ten times the rows that hold data. In this example that flags the hidden lookup sheet, the very hidden calculation sheet — which nobody browsing the workbook would know existed — and the old sheet full of formatting. The very hidden sheet is the one to look at first: it holds a formula built on the visible summary — a calculation someone set up deliberately and hid from view, which other workbooks, macros or reports may read. Nobody opening the file in Excel would know it was there, so it should be understood before anything in the workbook is renamed, moved or deleted.",[30,2125,2127],{"id":2126},"common-pitfalls","Common pitfalls",[2129,2130,2131,2145,2157,2165,2171],"ul",{},[2132,2133,2134,2141,2142,2144],"li",{},[2135,2136,2137,2138,2140],"strong",{},"Using ",[19,2139,634],{}," for an inventory."," It omits chart sheets; ",[19,2143,630],{}," has them all.",[2132,2146,2147,2150,2151,2153,2154,2156],{},[2135,2148,2149],{},"Missing very hidden sheets."," Check ",[19,2152,638],{}," for ",[19,2155,650],{},"; Excel's Unhide list does not show them.",[2132,2158,2159,2164],{},[2135,2160,2161,2162,28],{},"Trusting ",[19,2163,658],{}," It includes formatting-only cells; count cells with values for the real size.",[2132,2166,2167,2170],{},[2135,2168,2169],{},"Compressed sizes only."," Unpacked XML size is closer to the work Excel does when opening the file.",[2132,2172,2173,2176],{},[2135,2174,2175],{},"One bad file stopping the run."," Catch errors per file and record them.",[30,2178,2180],{"id":2179},"conclusion","Conclusion",[10,2182,2183],{},"A sheet inventory lists every sheet in tab order with its visibility — including very hidden ones — and type, the used range Excel reports next to the range that actually holds values, counts of formulas, tables, charts, images, merged ranges and validation rules, protection, and the sheet's size inside the file. Built with openpyxl and a look inside the zip package, it runs over a whole folder and flags hidden sheets and sheets bloated by formatting.",[30,2185,2187],{"id":2186},"frequently-asked-questions","Frequently asked questions",[10,2189,2190,2193,2194,2196,2197,2199,2200,2203,2204,28],{},[2135,2191,2192],{},"How do I list all sheets including hidden ones with openpyxl?","\nIterate over ",[19,2195,630],{}," (or ",[19,2198,634],{}," plus ",[19,2201,2202],{},"wb.chartsheets",") and read each sheet's ",[19,2205,638],{},[10,2207,2208,2211,2212,2214],{},[2135,2209,2210],{},"What is a very hidden sheet?","\nA sheet with state ",[19,2213,650],{},", which does not appear in Excel's Unhide dialog and can only be made visible through code or the VBA editor.",[10,2216,2217,2220,2222],{},[2135,2218,2219],{},"Why does openpyxl report many more rows than my sheet has?",[19,2221,658],{}," counts every cell that has been formatted or touched, not only cells with values.",[10,2224,2225,2228,2229,2231,2232,2235],{},[2135,2226,2227],{},"How do I find which sheet makes an Excel file large?","\nOpen the ",[19,2230,21],{}," as a zip file and compare the sizes of the ",[19,2233,2234],{},"xl\u002Fworksheets\u002Fsheet*.xml"," parts.",[30,2237,2239],{"id":2238},"related","Related",[2129,2241,2242,2248,2255,2262],{},[2132,2243,2244,2245,2247],{},"Up one level: ",[24,2246,27],{"href":26}," — many sheets and files.",[2132,2249,2250,2254],{},[24,2251,2253],{"href":2252},"\u002Fformatting-and-charting-excel-reports-with-python\u002Fprotecting-and-sharing-excel-workbooks\u002Fhide-sheets-rows-and-columns-with-openpyxl\u002F","Hide Sheets, Rows and Columns with openpyxl"," — setting the states.",[2132,2256,2257,2261],{},[24,2258,2260],{"href":2259},"\u002Fgetting-started-with-python-excel-automation\u002Fworking-with-excel-formulas-in-python\u002Faudit-every-formula-in-a-workbook-with-python\u002F","Audit Every Formula in a Workbook with Python"," — looking inside the formulas.",[2132,2263,2264,2268],{},[24,2265,2267],{"href":2266},"\u002Fformatting-and-charting-excel-reports-with-python\u002Fprotecting-and-sharing-excel-workbooks\u002Fremove-hidden-data-before-sharing-an-excel-file\u002F","Remove Hidden Data Before Sharing an Excel File"," — what to do about hidden sheets.",[2270,2271,2272],"style",{},"html pre.shiki code .sMTad, html code.shiki .sMTad{--shiki-default:#6F42C1;--shiki-dark:#FFB757}html pre.shiki code .srMev, html code.shiki .srMev{--shiki-default:#032F62;--shiki-dark:#ADDCFF}html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html.dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html pre.shiki code .s-kum, html code.shiki .s-kum{--shiki-default:#D73A49;--shiki-dark:#FF9492}html pre.shiki code .skGVy, html code.shiki .skGVy{--shiki-default:#24292E;--shiki-dark:#F0F3F6}html pre.shiki code .s_Opv, html code.shiki .s_Opv{--shiki-default:#6F42C1;--shiki-dark:#DBB7FF}html pre.shiki code .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":40,"searchDepth":94,"depth":94,"links":2274},[2275,2276,2277,2278,2279,2280,2281,2282],{"id":32,"depth":94,"text":33},{"id":67,"depth":94,"text":68},{"id":968,"depth":94,"text":969},{"id":1681,"depth":94,"text":1682},{"id":2126,"depth":94,"text":2127},{"id":2179,"depth":94,"text":2180},{"id":2186,"depth":94,"text":2187},{"id":2238,"depth":94,"text":2239},"2026-10-02","Produce an inventory of a workbook, or a folder of workbooks, with one row per sheet: visible, hidden or very hidden, chart sheet or worksheet, the used range Excel reports against the range that actually holds data, counts of formulas, tables, charts, images, merged cells and validation rules, protection, and the space each sheet takes inside the file — written to an Excel report.","md",[2287,2289,2291,2293],{"q":2192,"a":2288},"Iterate over wb._sheets (or wb.worksheets plus wb.chartsheets) and read each sheet's sheet_state.",{"q":2210,"a":2290},"A sheet with state veryHidden, which does not appear in Excel's Unhide dialog and can only be made visible through code or the VBA editor.",{"q":2219,"a":2292},"max_row counts every cell that has been formatted or touched, not only cells with values.",{"q":2227,"a":2294},"Open the .xlsx as a zip file and compare the sizes of the xl\u002Fworksheets\u002Fsheet*.xml parts.","list sheets size visibility openpyxl",null,{"breadcrumb":2298},[2299,2301,2304],{"name":2300,"item":1320},"Home",{"name":2302,"item":2303},"Getting Started with Python Excel Automation","\u002Fgetting-started-with-python-excel-automation\u002F",{"name":27,"item":26},"\u002Fgetting-started-with-python-excel-automation\u002Fworking-with-multiple-excel-sheets-in-python\u002Flist-every-sheet-with-its-size-and-visibility",{"title":2307,"description":2308},"List Every Sheet with Its Size and Visibility in Python","Workbook inventory with openpyxl: sheet state including very hidden, used range versus real data, formulas, tables, charts, images, merged cells, protection and the size of each sheet in the file.","list-every-sheet-with-its-size-and-visibility","getting-started-with-python-excel-automation\u002Fworking-with-multiple-excel-sheets-in-python\u002Flist-every-sheet-with-its-size-and-visibility\u002Findex",[2312,2313],"sheets-and-files","openpyxl","how-to","dznrp2CC0_i0dTljRBvSoB_xsT0P0G7Ms6qmTjPh0B4",[2317,2321],{"title":2318,"path":2319,"stem":2320,"children":-1},"Create a Sheet for Each Group in a DataFrame","\u002Fgetting-started-with-python-excel-automation\u002Fworking-with-multiple-excel-sheets-in-python\u002Fcreate-a-sheet-for-each-group-in-a-dataframe","getting-started-with-python-excel-automation\u002Fworking-with-multiple-excel-sheets-in-python\u002Fcreate-a-sheet-for-each-group-in-a-dataframe\u002Findex",{"title":2322,"path":2323,"stem":2324,"children":-1},"Merge Workbooks into One File with a Sheet per Source","\u002Fgetting-started-with-python-excel-automation\u002Fworking-with-multiple-excel-sheets-in-python\u002Fmerge-workbooks-into-one-file-with-a-sheet-per-source","getting-started-with-python-excel-automation\u002Fworking-with-multiple-excel-sheets-in-python\u002Fmerge-workbooks-into-one-file-with-a-sheet-per-source\u002Findex",[2326,2328],{"path":2327,"title":2302},"\u002Fgetting-started-with-python-excel-automation",{"path":2329,"title":27},"\u002Fgetting-started-with-python-excel-automation\u002Fworking-with-multiple-excel-sheets-in-python",[],[2332,2335,2338,2341,2344,2347],{"path":2333,"title":2334,"kind":2314},"\u002Fautomating-reporting-workflows\u002Fbuilding-finance-and-operations-reports\u002Fconsolidate-timesheets-from-many-workbooks","Consolidate Timesheets from Many Workbooks with Python",{"path":2336,"title":2337,"kind":2314},"\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":2339,"title":2340,"kind":2314},"\u002Fadvanced-data-transformation-and-cleaning\u002Fmerging-and-joining-excel-dataframes\u002Fappend-new-rows-to-a-master-excel-file-without-duplicates","Append New Rows to a Master Excel File Without Duplicates",{"path":2342,"title":2343,"kind":2314},"\u002Fadvanced-data-transformation-and-cleaning\u002Fmerging-and-joining-excel-dataframes\u002Fconcatenate-excel-sheets-with-different-columns","Concatenate Excel Sheets with Different Columns",{"path":2345,"title":2346,"kind":2314},"\u002Fadvanced-data-transformation-and-cleaning\u002Fmerging-and-joining-excel-dataframes\u002Fmerge-excel-files-with-different-column-names","Merge Excel Files with Different Column Names in pandas",{"path":2348,"title":2349,"kind":2314},"\u002Fadvanced-data-transformation-and-cleaning\u002Fmerging-and-joining-excel-dataframes\u002Fmerge-more-than-two-excel-files-on-a-key-column","Merge More Than Two Excel Files on a Key Column",1790972076145]