[{"data":1,"prerenderedAt":1787},["ShallowReactive",2],{"doc:\u002Fgetting-started-with-python-excel-automation\u002Fworking-with-multiple-excel-sheets-in-python\u002Fcopy-a-sheet-between-excel-workbooks-with-python":3,"surround:\u002Fgetting-started-with-python-excel-automation\u002Fworking-with-multiple-excel-sheets-in-python\u002Fcopy-a-sheet-between-excel-workbooks-with-python":1779},{"id":4,"title":5,"body":6,"dateModified":1747,"datePublished":1747,"description":1748,"extension":1749,"faq":1750,"meta":1760,"navigation":248,"path":1771,"seo":1772,"slug":1775,"stem":1776,"type":1777,"__hash__":1778},"docs\u002Fgetting-started-with-python-excel-automation\u002Fworking-with-multiple-excel-sheets-in-python\u002Fcopy-a-sheet-between-excel-workbooks-with-python\u002Findex.md","Copy a Sheet Between Excel Workbooks with Python",{"type":7,"value":8,"toc":1733},"minimark",[9,18,32,171,176,200,203,207,556,560,563,631,637,641,644,1075,1085,1091,1095,1109,1162,1175,1256,1260,1263,1338,1341,1345,1348,1455,1462,1475,1479,1619,1623,1626,1633,1637,1642,1646,1656,1665,1671,1680,1684,1687,1696,1699,1729],[10,11,12,13,17],"p",{},"\"Copy this sheet into that workbook\" sounds like a one-liner, and openpyxl does have ",[14,15,16],"code",{},"copy_worksheet"," — but it only copies within a single workbook, and the reason is worth understanding before you go looking for a workaround. A worksheet is not self-contained: its cells reference the workbook's shared string table, its formats index into the workbook's style table, and its formulas may point at defined names that live at workbook level. Move the object and every one of those references points at the wrong place.",[10,19,20,21,25,26,31],{},"So a cross-workbook copy is always a ",[22,23,24],"em",{},"rebuild",", and the question becomes which parts you need to carry. This guide, part of ",[27,28,30],"a",{"href":29},"\u002Fgetting-started-with-python-excel-automation\u002Fworking-with-multiple-excel-sheets-in-python\u002F","Working with Multiple Excel Sheets in Python",", covers the three approaches and what each one loses.",[33,34,42,43,42,47,42,51,42,58,42,68,42,75,42,82,42,88,42,93,42,99,42,103,42,109,42,113,42,116,42,121,42,126,42,129,42,133,42,137,42,141,42,144,42,148,42,151,42,154,42,161,42,166],"svg",{"viewBox":35,"role":36,"ariaLabelledBy":37,"xmlns":40,"style":41},"0 0 740 244","img",[38,39],"cp-why-t","cp-why-d","http:\u002F\u002Fwww.w3.org\u002F2000\u002Fsvg","width:100%;max-width:740px;height:auto;display:block;margin:1.5rem auto;font-family:Inter,ui-sans-serif,system-ui,sans-serif","\n  ",[44,45,46],"title",{"id":38},"Why a worksheet cannot simply move between workbooks",[48,49,50],"desc",{"id":39},"A worksheet's cells reference workbook-level tables: shared strings, the style table and defined names. Inside one workbook copy_worksheet can reuse those references. Across workbooks the indices mean different things, so the sheet has to be rebuilt cell by cell in the target.",[52,53],"rect",{"x":54,"y":54,"width":55,"height":56,"fill":57},"0","740","244","#ffffff",[52,59],{"x":60,"y":61,"width":62,"height":63,"rx":64,"fill":65,"stroke":66,"style":67},"24","44","300","172","14","#ebebfd","var(--brand,#5b5cf0)","stroke-width:2px",[69,70,74],"text",{"x":71,"y":72,"style":73},"174","72","font-size:12.5px;font-weight:700;fill:var(--brand-strong,#4338ca);text-anchor:middle","source workbook",[52,76],{"x":77,"y":78,"width":79,"height":80,"rx":81,"fill":57,"stroke":66},"48","88","120","40","8",[69,83,87],{"x":84,"y":85,"style":86},"108","113","font-size:11px;fill:var(--text,#172033);text-anchor:middle","Sheet \"Q1\"",[52,89],{"x":90,"y":78,"width":79,"height":80,"rx":81,"fill":91,"stroke":92},"180","#f0f4ff","var(--line,#cdd5e6)",[69,94,98],{"x":95,"y":96,"style":97},"240","107","font-size:10.5px;fill:var(--muted,#5b6780);text-anchor:middle","shared strings",[69,100,102],{"x":95,"y":101,"style":97},"122","style table",[104,105],"line",{"x1":106,"y1":84,"x2":107,"y2":84,"stroke":108,"style":67},"168","176","var(--muted,#5b6780)",[69,110,112],{"x":71,"y":111,"style":86},"156","cell 0 means \"North\", format 12",[69,114,115],{"x":71,"y":90,"style":86},"means bold currency — in THIS file",[52,117],{"x":118,"y":61,"width":62,"height":63,"rx":64,"fill":119,"stroke":120,"style":67},"416","#fdefd8","var(--gold,#b4740a)",[69,122,125],{"x":123,"y":72,"style":124},"566","font-size:12.5px;font-weight:700;fill:var(--gold-ink,#7a4e06);text-anchor:middle","target workbook",[52,127],{"x":128,"y":78,"width":79,"height":80,"rx":81,"fill":57,"stroke":120},"440",[69,130,132],{"x":131,"y":85,"style":86},"500","new sheet",[52,134],{"x":135,"y":78,"width":79,"height":80,"rx":81,"fill":136,"stroke":92},"572","#f4ecdd",[69,138,140],{"x":139,"y":96,"style":97},"632","its own strings",[69,142,143],{"x":139,"y":101,"style":97},"its own styles",[104,145],{"x1":146,"y1":84,"x2":147,"y2":84,"stroke":108,"style":67},"560","568",[69,149,150],{"x":123,"y":111,"style":86},"index 12 here is a different format,",[69,152,153],{"x":123,"y":90,"style":86},"so values and styles must be re-created",[104,155],{"x1":156,"y1":157,"x2":158,"y2":157,"stroke":159,"style":160},"330","130","410","var(--accent-ink,#be185d)","stroke-width:2px;stroke-dasharray:5 4",[162,163],"polygon",{"points":164,"fill":165},"414,130 402,125 402,135","#d81b73",[69,167,24],{"x":168,"y":169,"style":170},"370","118","font-size:11px;font-weight:700;fill:var(--accent-ink,#be185d);text-anchor:middle",[172,173,175],"h2",{"id":174},"prerequisites","Prerequisites",[177,178,183],"pre",{"className":179,"code":180,"language":181,"meta":182,"style":182},"language-bash shiki shiki-themes github-light github-dark-high-contrast","pip install openpyxl\n","bash","",[14,184,185],{"__ignoreMap":182},[186,187,189,193,197],"span",{"class":104,"line":188},1,[186,190,192],{"class":191},"sMTad","pip",[186,194,196],{"class":195},"srMev"," install",[186,198,199],{"class":195}," openpyxl\n",[10,201,202],{},"Two workbooks to work with. The examples generate them, so the whole guide runs as written.",[172,204,206],{"id":205},"step-1-create-a-source-and-a-target","Step 1: Create a source and a target",[177,208,212],{"className":209,"code":210,"language":211,"meta":182,"style":182},"language-python shiki shiki-themes github-light github-dark-high-contrast","from openpyxl import Workbook\nfrom openpyxl.styles import Font, PatternFill\n\nsrc = Workbook()\nws = src.active\nws.title = \"Q1\"\nws.append([\"Region\", \"Amount\"])\nws.append([\"North\", 150.25])\nws.append([\"South\", 274.75])\nws.append([\"Total\", \"=SUM(B2:B3)\"])\n\nfor cell in ws[1]:\n    cell.font = Font(bold=True, color=\"FFFFFF\")\n    cell.fill = PatternFill(\"solid\", start_color=\"1F4E78\")\nfor cell in ws[\"B\"][1:]:\n    cell.number_format = '#,##0.00'\nws.column_dimensions[\"A\"].width = 16\nws.column_dimensions[\"B\"].width = 14\nws.freeze_panes = \"A2\"\nsrc.save(\"source.xlsx\")\n\ntarget = Workbook()\ntarget.active.title = \"Overview\"\ntarget.save(\"target.xlsx\")\n","python",[14,213,214,230,243,250,262,273,284,302,318,333,348,353,374,407,433,455,466,483,497,508,519,524,534,545],{"__ignoreMap":182},[186,215,216,220,224,227],{"class":104,"line":188},[186,217,219],{"class":218},"s-kum","from",[186,221,223],{"class":222},"skGVy"," openpyxl ",[186,225,226],{"class":218},"import",[186,228,229],{"class":222}," Workbook\n",[186,231,233,235,238,240],{"class":104,"line":232},2,[186,234,219],{"class":218},[186,236,237],{"class":222}," openpyxl.styles ",[186,239,226],{"class":218},[186,241,242],{"class":222}," Font, PatternFill\n",[186,244,246],{"class":104,"line":245},3,[186,247,249],{"emptyLinePlaceholder":248},true,"\n",[186,251,253,256,259],{"class":104,"line":252},4,[186,254,255],{"class":222},"src ",[186,257,258],{"class":218},"=",[186,260,261],{"class":222}," Workbook()\n",[186,263,265,268,270],{"class":104,"line":264},5,[186,266,267],{"class":222},"ws ",[186,269,258],{"class":218},[186,271,272],{"class":222}," src.active\n",[186,274,276,279,281],{"class":104,"line":275},6,[186,277,278],{"class":222},"ws.title ",[186,280,258],{"class":218},[186,282,283],{"class":195}," \"Q1\"\n",[186,285,287,290,293,296,299],{"class":104,"line":286},7,[186,288,289],{"class":222},"ws.append([",[186,291,292],{"class":195},"\"Region\"",[186,294,295],{"class":222},", ",[186,297,298],{"class":195},"\"Amount\"",[186,300,301],{"class":222},"])\n",[186,303,305,307,310,312,316],{"class":104,"line":304},8,[186,306,289],{"class":222},[186,308,309],{"class":195},"\"North\"",[186,311,295],{"class":222},[186,313,315],{"class":314},"sP0c6","150.25",[186,317,301],{"class":222},[186,319,321,323,326,328,331],{"class":104,"line":320},9,[186,322,289],{"class":222},[186,324,325],{"class":195},"\"South\"",[186,327,295],{"class":222},[186,329,330],{"class":314},"274.75",[186,332,301],{"class":222},[186,334,336,338,341,343,346],{"class":104,"line":335},10,[186,337,289],{"class":222},[186,339,340],{"class":195},"\"Total\"",[186,342,295],{"class":222},[186,344,345],{"class":195},"\"=SUM(B2:B3)\"",[186,347,301],{"class":222},[186,349,351],{"class":104,"line":350},11,[186,352,249],{"emptyLinePlaceholder":248},[186,354,356,359,362,365,368,371],{"class":104,"line":355},12,[186,357,358],{"class":218},"for",[186,360,361],{"class":222}," cell ",[186,363,364],{"class":218},"in",[186,366,367],{"class":222}," ws[",[186,369,370],{"class":314},"1",[186,372,373],{"class":222},"]:\n",[186,375,377,380,382,385,389,391,394,396,399,401,404],{"class":104,"line":376},13,[186,378,379],{"class":222},"    cell.font ",[186,381,258],{"class":218},[186,383,384],{"class":222}," Font(",[186,386,388],{"class":387},"sa561","bold",[186,390,258],{"class":218},[186,392,393],{"class":314},"True",[186,395,295],{"class":222},[186,397,398],{"class":387},"color",[186,400,258],{"class":218},[186,402,403],{"class":195},"\"FFFFFF\"",[186,405,406],{"class":222},")\n",[186,408,410,413,415,418,421,423,426,428,431],{"class":104,"line":409},14,[186,411,412],{"class":222},"    cell.fill ",[186,414,258],{"class":218},[186,416,417],{"class":222}," PatternFill(",[186,419,420],{"class":195},"\"solid\"",[186,422,295],{"class":222},[186,424,425],{"class":387},"start_color",[186,427,258],{"class":218},[186,429,430],{"class":195},"\"1F4E78\"",[186,432,406],{"class":222},[186,434,436,438,440,442,444,447,450,452],{"class":104,"line":435},15,[186,437,358],{"class":218},[186,439,361],{"class":222},[186,441,364],{"class":218},[186,443,367],{"class":222},[186,445,446],{"class":195},"\"B\"",[186,448,449],{"class":222},"][",[186,451,370],{"class":314},[186,453,454],{"class":222},":]:\n",[186,456,458,461,463],{"class":104,"line":457},16,[186,459,460],{"class":222},"    cell.number_format ",[186,462,258],{"class":218},[186,464,465],{"class":195}," '#,##0.00'\n",[186,467,469,472,475,478,480],{"class":104,"line":468},17,[186,470,471],{"class":222},"ws.column_dimensions[",[186,473,474],{"class":195},"\"A\"",[186,476,477],{"class":222},"].width ",[186,479,258],{"class":218},[186,481,482],{"class":314}," 16\n",[186,484,486,488,490,492,494],{"class":104,"line":485},18,[186,487,471],{"class":222},[186,489,446],{"class":195},[186,491,477],{"class":222},[186,493,258],{"class":218},[186,495,496],{"class":314}," 14\n",[186,498,500,503,505],{"class":104,"line":499},19,[186,501,502],{"class":222},"ws.freeze_panes ",[186,504,258],{"class":218},[186,506,507],{"class":195}," \"A2\"\n",[186,509,511,514,517],{"class":104,"line":510},20,[186,512,513],{"class":222},"src.save(",[186,515,516],{"class":195},"\"source.xlsx\"",[186,518,406],{"class":222},[186,520,522],{"class":104,"line":521},21,[186,523,249],{"emptyLinePlaceholder":248},[186,525,527,530,532],{"class":104,"line":526},22,[186,528,529],{"class":222},"target ",[186,531,258],{"class":218},[186,533,261],{"class":222},[186,535,537,540,542],{"class":104,"line":536},23,[186,538,539],{"class":222},"target.active.title ",[186,541,258],{"class":218},[186,543,544],{"class":195}," \"Overview\"\n",[186,546,548,551,554],{"class":104,"line":547},24,[186,549,550],{"class":222},"target.save(",[186,552,553],{"class":195},"\"target.xlsx\"",[186,555,406],{"class":222},[172,557,559],{"id":558},"step-2-copying-within-one-workbook","Step 2: Copying within one workbook",[10,561,562],{},"Inside a single file, openpyxl does it properly — including styles, dimensions and merged ranges:",[177,564,566],{"className":209,"code":565,"language":211,"meta":182,"style":182},"from openpyxl import load_workbook\n\nwb = load_workbook(\"source.xlsx\")\ncopy = wb.copy_worksheet(wb[\"Q1\"])\ncopy.title = \"Q1 (working)\"\nwb.save(\"source.xlsx\")\n",[14,567,568,579,583,597,612,622],{"__ignoreMap":182},[186,569,570,572,574,576],{"class":104,"line":188},[186,571,219],{"class":218},[186,573,223],{"class":222},[186,575,226],{"class":218},[186,577,578],{"class":222}," load_workbook\n",[186,580,581],{"class":104,"line":232},[186,582,249],{"emptyLinePlaceholder":248},[186,584,585,588,590,593,595],{"class":104,"line":245},[186,586,587],{"class":222},"wb ",[186,589,258],{"class":218},[186,591,592],{"class":222}," load_workbook(",[186,594,516],{"class":195},[186,596,406],{"class":222},[186,598,599,602,604,607,610],{"class":104,"line":252},[186,600,601],{"class":222},"copy ",[186,603,258],{"class":218},[186,605,606],{"class":222}," wb.copy_worksheet(wb[",[186,608,609],{"class":195},"\"Q1\"",[186,611,301],{"class":222},[186,613,614,617,619],{"class":104,"line":264},[186,615,616],{"class":222},"copy.title ",[186,618,258],{"class":218},[186,620,621],{"class":195}," \"Q1 (working)\"\n",[186,623,624,627,629],{"class":104,"line":275},[186,625,626],{"class":222},"wb.save(",[186,628,516],{"class":195},[186,630,406],{"class":222},[10,632,633,634,636],{},"This is the case ",[14,635,16],{}," is for, and it is worth knowing it exists because the common use — duplicating a template tab per region before filling it in — lives entirely inside one workbook. Note that it copies values and formatting but not images or charts, which openpyxl does not duplicate.",[172,638,640],{"id":639},"step-3-copying-across-workbooks-cell-by-cell","Step 3: Copying across workbooks, cell by cell",[10,642,643],{},"Across files, write the copy yourself. The version below carries values, number formats, fonts, fills, borders, alignment, column widths, row heights and merged ranges:",[177,645,647],{"className":209,"code":646,"language":211,"meta":182,"style":182},"from copy import copy as copy_style\n\nfrom openpyxl import load_workbook\n\n\ndef copy_sheet(source_ws, target_wb, title=None, values_only=False):\n    \"\"\"Re-create a worksheet in another workbook. Returns the new sheet.\"\"\"\n    new = target_wb.create_sheet(title or source_ws.title)\n\n    for row in source_ws.iter_rows():\n        for cell in row:\n            fresh = new.cell(row=cell.row, column=cell.column, value=cell.value)\n            if values_only or not cell.has_style:\n                continue\n            fresh.font = copy_style(cell.font)\n            fresh.fill = copy_style(cell.fill)\n            fresh.border = copy_style(cell.border)\n            fresh.alignment = copy_style(cell.alignment)\n            fresh.number_format = cell.number_format\n            fresh.protection = copy_style(cell.protection)\n\n    for letter, dim in source_ws.column_dimensions.items():\n        new.column_dimensions[letter].width = dim.width\n        new.column_dimensions[letter].hidden = dim.hidden\n    for idx, dim in source_ws.row_dimensions.items():\n        new.row_dimensions[idx].height = dim.height\n\n    for rng in source_ws.merged_cells.ranges:\n        new.merge_cells(str(rng))\n\n    new.freeze_panes = source_ws.freeze_panes\n    new.sheet_format.defaultColWidth = source_ws.sheet_format.defaultColWidth\n    return new\n\n\nsrc_wb = load_workbook(\"source.xlsx\")\ntgt_wb = load_workbook(\"target.xlsx\")\ncopy_sheet(src_wb[\"Q1\"], tgt_wb, title=\"Q1 copy\")\ntgt_wb.save(\"target.xlsx\")\n",[14,648,649,666,670,680,684,688,716,721,737,741,754,766,800,816,821,831,841,851,861,871,881,885,897,907,917,930,941,946,959,971,976,987,998,1007,1012,1017,1031,1045,1065],{"__ignoreMap":182},[186,650,651,653,656,658,660,663],{"class":104,"line":188},[186,652,219],{"class":218},[186,654,655],{"class":222}," copy ",[186,657,226],{"class":218},[186,659,655],{"class":222},[186,661,662],{"class":218},"as",[186,664,665],{"class":222}," copy_style\n",[186,667,668],{"class":104,"line":232},[186,669,249],{"emptyLinePlaceholder":248},[186,671,672,674,676,678],{"class":104,"line":245},[186,673,219],{"class":218},[186,675,223],{"class":222},[186,677,226],{"class":218},[186,679,578],{"class":222},[186,681,682],{"class":104,"line":252},[186,683,249],{"emptyLinePlaceholder":248},[186,685,686],{"class":104,"line":264},[186,687,249],{"emptyLinePlaceholder":248},[186,689,690,693,697,700,702,705,708,710,713],{"class":104,"line":275},[186,691,692],{"class":218},"def",[186,694,696],{"class":695},"s_Opv"," copy_sheet",[186,698,699],{"class":222},"(source_ws, target_wb, title",[186,701,258],{"class":218},[186,703,704],{"class":314},"None",[186,706,707],{"class":222},", values_only",[186,709,258],{"class":218},[186,711,712],{"class":314},"False",[186,714,715],{"class":222},"):\n",[186,717,718],{"class":104,"line":286},[186,719,720],{"class":195},"    \"\"\"Re-create a worksheet in another workbook. Returns the new sheet.\"\"\"\n",[186,722,723,726,728,731,734],{"class":104,"line":304},[186,724,725],{"class":222},"    new ",[186,727,258],{"class":218},[186,729,730],{"class":222}," target_wb.create_sheet(title ",[186,732,733],{"class":218},"or",[186,735,736],{"class":222}," source_ws.title)\n",[186,738,739],{"class":104,"line":320},[186,740,249],{"emptyLinePlaceholder":248},[186,742,743,746,749,751],{"class":104,"line":335},[186,744,745],{"class":218},"    for",[186,747,748],{"class":222}," row ",[186,750,364],{"class":218},[186,752,753],{"class":222}," source_ws.iter_rows():\n",[186,755,756,759,761,763],{"class":104,"line":350},[186,757,758],{"class":218},"        for",[186,760,361],{"class":222},[186,762,364],{"class":218},[186,764,765],{"class":222}," row:\n",[186,767,768,771,773,776,779,781,784,787,789,792,795,797],{"class":104,"line":355},[186,769,770],{"class":222},"            fresh ",[186,772,258],{"class":218},[186,774,775],{"class":222}," new.cell(",[186,777,778],{"class":387},"row",[186,780,258],{"class":218},[186,782,783],{"class":222},"cell.row, ",[186,785,786],{"class":387},"column",[186,788,258],{"class":218},[186,790,791],{"class":222},"cell.column, ",[186,793,794],{"class":387},"value",[186,796,258],{"class":218},[186,798,799],{"class":222},"cell.value)\n",[186,801,802,805,808,810,813],{"class":104,"line":376},[186,803,804],{"class":218},"            if",[186,806,807],{"class":222}," values_only ",[186,809,733],{"class":218},[186,811,812],{"class":218}," not",[186,814,815],{"class":222}," cell.has_style:\n",[186,817,818],{"class":104,"line":409},[186,819,820],{"class":218},"                continue\n",[186,822,823,826,828],{"class":104,"line":435},[186,824,825],{"class":222},"            fresh.font ",[186,827,258],{"class":218},[186,829,830],{"class":222}," copy_style(cell.font)\n",[186,832,833,836,838],{"class":104,"line":457},[186,834,835],{"class":222},"            fresh.fill ",[186,837,258],{"class":218},[186,839,840],{"class":222}," copy_style(cell.fill)\n",[186,842,843,846,848],{"class":104,"line":468},[186,844,845],{"class":222},"            fresh.border ",[186,847,258],{"class":218},[186,849,850],{"class":222}," copy_style(cell.border)\n",[186,852,853,856,858],{"class":104,"line":485},[186,854,855],{"class":222},"            fresh.alignment ",[186,857,258],{"class":218},[186,859,860],{"class":222}," copy_style(cell.alignment)\n",[186,862,863,866,868],{"class":104,"line":499},[186,864,865],{"class":222},"            fresh.number_format ",[186,867,258],{"class":218},[186,869,870],{"class":222}," cell.number_format\n",[186,872,873,876,878],{"class":104,"line":510},[186,874,875],{"class":222},"            fresh.protection ",[186,877,258],{"class":218},[186,879,880],{"class":222}," copy_style(cell.protection)\n",[186,882,883],{"class":104,"line":521},[186,884,249],{"emptyLinePlaceholder":248},[186,886,887,889,892,894],{"class":104,"line":526},[186,888,745],{"class":218},[186,890,891],{"class":222}," letter, dim ",[186,893,364],{"class":218},[186,895,896],{"class":222}," source_ws.column_dimensions.items():\n",[186,898,899,902,904],{"class":104,"line":536},[186,900,901],{"class":222},"        new.column_dimensions[letter].width ",[186,903,258],{"class":218},[186,905,906],{"class":222}," dim.width\n",[186,908,909,912,914],{"class":104,"line":547},[186,910,911],{"class":222},"        new.column_dimensions[letter].hidden ",[186,913,258],{"class":218},[186,915,916],{"class":222}," dim.hidden\n",[186,918,920,922,925,927],{"class":104,"line":919},25,[186,921,745],{"class":218},[186,923,924],{"class":222}," idx, dim ",[186,926,364],{"class":218},[186,928,929],{"class":222}," source_ws.row_dimensions.items():\n",[186,931,933,936,938],{"class":104,"line":932},26,[186,934,935],{"class":222},"        new.row_dimensions[idx].height ",[186,937,258],{"class":218},[186,939,940],{"class":222}," dim.height\n",[186,942,944],{"class":104,"line":943},27,[186,945,249],{"emptyLinePlaceholder":248},[186,947,949,951,954,956],{"class":104,"line":948},28,[186,950,745],{"class":218},[186,952,953],{"class":222}," rng ",[186,955,364],{"class":218},[186,957,958],{"class":222}," source_ws.merged_cells.ranges:\n",[186,960,962,965,968],{"class":104,"line":961},29,[186,963,964],{"class":222},"        new.merge_cells(",[186,966,967],{"class":314},"str",[186,969,970],{"class":222},"(rng))\n",[186,972,974],{"class":104,"line":973},30,[186,975,249],{"emptyLinePlaceholder":248},[186,977,979,982,984],{"class":104,"line":978},31,[186,980,981],{"class":222},"    new.freeze_panes ",[186,983,258],{"class":218},[186,985,986],{"class":222}," source_ws.freeze_panes\n",[186,988,990,993,995],{"class":104,"line":989},32,[186,991,992],{"class":222},"    new.sheet_format.defaultColWidth ",[186,994,258],{"class":218},[186,996,997],{"class":222}," source_ws.sheet_format.defaultColWidth\n",[186,999,1001,1004],{"class":104,"line":1000},33,[186,1002,1003],{"class":218},"    return",[186,1005,1006],{"class":222}," new\n",[186,1008,1010],{"class":104,"line":1009},34,[186,1011,249],{"emptyLinePlaceholder":248},[186,1013,1015],{"class":104,"line":1014},35,[186,1016,249],{"emptyLinePlaceholder":248},[186,1018,1020,1023,1025,1027,1029],{"class":104,"line":1019},36,[186,1021,1022],{"class":222},"src_wb ",[186,1024,258],{"class":218},[186,1026,592],{"class":222},[186,1028,516],{"class":195},[186,1030,406],{"class":222},[186,1032,1034,1037,1039,1041,1043],{"class":104,"line":1033},37,[186,1035,1036],{"class":222},"tgt_wb ",[186,1038,258],{"class":218},[186,1040,592],{"class":222},[186,1042,553],{"class":195},[186,1044,406],{"class":222},[186,1046,1048,1051,1053,1056,1058,1060,1063],{"class":104,"line":1047},38,[186,1049,1050],{"class":222},"copy_sheet(src_wb[",[186,1052,609],{"class":195},[186,1054,1055],{"class":222},"], tgt_wb, ",[186,1057,44],{"class":387},[186,1059,258],{"class":218},[186,1061,1062],{"class":195},"\"Q1 copy\"",[186,1064,406],{"class":222},[186,1066,1068,1071,1073],{"class":104,"line":1067},39,[186,1069,1070],{"class":222},"tgt_wb.save(",[186,1072,553],{"class":195},[186,1074,406],{"class":222},[10,1076,1077,1080,1081,1084],{},[14,1078,1079],{},"copy(cell.font)"," rather than ",[14,1082,1083],{},"fresh.font = cell.font"," is the detail that matters. openpyxl style objects are shared and immutable-by-convention; assigning the source's object directly binds a style belonging to another workbook's table, and the result is either ignored on save or carried incorrectly. Copying the object first gives the target workbook its own instance to register.",[10,1086,1087,1090],{},[14,1088,1089],{},"cell.has_style"," skips the work for unstyled cells, which on a large sheet is most of them and makes the copy noticeably faster.",[172,1092,1094],{"id":1093},"step-4-decide-what-to-do-about-formulas","Step 4: Decide what to do about formulas",[10,1096,1097,1098,1101,1102,1104,1105,1108],{},"A copied formula is copied as text — ",[14,1099,1100],{},"=SUM(B2:B3)"," still says ",[14,1103,1100],{}," in the new file. That is correct when the supporting rows came too, and wrong when they did not. When the target only needs numbers, read the source with ",[14,1106,1107],{},"data_only=True",":",[177,1110,1112],{"className":209,"code":1111,"language":211,"meta":182,"style":182},"values_wb = load_workbook(\"source.xlsx\", data_only=True)\ncopy_sheet(values_wb[\"Q1\"], tgt_wb, title=\"Q1 values\")\ntgt_wb.save(\"target.xlsx\")\n",[14,1113,1114,1136,1154],{"__ignoreMap":182},[186,1115,1116,1119,1121,1123,1125,1127,1130,1132,1134],{"class":104,"line":188},[186,1117,1118],{"class":222},"values_wb ",[186,1120,258],{"class":218},[186,1122,592],{"class":222},[186,1124,516],{"class":195},[186,1126,295],{"class":222},[186,1128,1129],{"class":387},"data_only",[186,1131,258],{"class":218},[186,1133,393],{"class":314},[186,1135,406],{"class":222},[186,1137,1138,1141,1143,1145,1147,1149,1152],{"class":104,"line":232},[186,1139,1140],{"class":222},"copy_sheet(values_wb[",[186,1142,609],{"class":195},[186,1144,1055],{"class":222},[186,1146,44],{"class":387},[186,1148,258],{"class":218},[186,1150,1151],{"class":195},"\"Q1 values\"",[186,1153,406],{"class":222},[186,1155,1156,1158,1160],{"class":104,"line":245},[186,1157,1070],{"class":222},[186,1159,553],{"class":195},[186,1161,406],{"class":222},[10,1163,1164,1166,1167,1169,1170,1174],{},[14,1165,1107],{}," returns the value Excel cached the last time it saved the file. If the workbook was generated by openpyxl and never opened in Excel, there is no cached value and every formula cell reads as ",[14,1168,704],{}," — the behaviour explained in ",[27,1171,1173],{"href":1172},"\u002Fgetting-started-with-python-excel-automation\u002Fworking-with-excel-formulas-in-python\u002Fread-formula-results-with-openpyxl-data-only\u002F","Read Formula Results with openpyxl data_only",". Check for that before relying on it, or compute the totals in Python instead.",[33,1176,42,1181,42,1184,42,1187,42,1190,42,1198,42,1204,42,1209,42,1213,42,1217,42,1221,42,1224,42,1229,42,1233,42,1238,42,1241,42,1244,42,1247,42,1250,42,1253],{"viewBox":1177,"role":36,"ariaLabelledBy":1178,"xmlns":40,"style":41},"0 0 740 250",[1179,1180],"cp-survive-t","cp-survive-d",[44,1182,1183],{"id":1179},"What survives a cell-by-cell copy and what does not",[48,1185,1186],{"id":1180},"Values, number formats, fonts, fills, borders, alignment, column widths, row heights, merged ranges and frozen panes all carry across when copied explicitly. Charts, images, conditional formatting, data validation, comments, defined names and pivot tables do not, and have to be recreated on the target sheet.",[52,1188],{"x":54,"y":54,"width":55,"height":1189,"fill":57},"250",[52,1191],{"x":1192,"y":1193,"width":1194,"height":1195,"rx":64,"fill":1196,"stroke":1197,"style":67},"16","34","344","196","#d9f4f1","var(--teal,#0f9488)",[69,1199,1203],{"x":1200,"y":1201,"style":1202},"188","62","font-size:12.5px;font-weight:700;fill:var(--teal-ink,#0b6157);text-anchor:middle","carried by the loop above",[69,1205,1208],{"x":1200,"y":1206,"style":1207},"92","font-size:11.5px;fill:var(--text,#172033);text-anchor:middle","cell values and formula text",[69,1210,1212],{"x":1200,"y":1211,"style":1207},"114","number formats",[69,1214,1216],{"x":1200,"y":1215,"style":1207},"136","font, fill, border, alignment",[69,1218,1220],{"x":1200,"y":1219,"style":1207},"158","column widths and row heights",[69,1222,1223],{"x":1200,"y":90,"style":1207},"merged ranges and frozen panes",[69,1225,1228],{"x":1200,"y":1226,"style":1227},"210","font-size:11px;fill:var(--muted,#5b6780);text-anchor:middle","everything a reader sees in the grid",[52,1230],{"x":1231,"y":1193,"width":1194,"height":1195,"rx":64,"fill":1232,"stroke":159,"style":67},"380","#fce9e9",[69,1234,1237],{"x":1235,"y":1201,"style":1236},"552","font-size:12.5px;font-weight:700;fill:var(--accent-ink,#be185d);text-anchor:middle","not carried — recreate or copy the file",[69,1239,1240],{"x":1235,"y":1206,"style":1207},"charts and images",[69,1242,1243],{"x":1235,"y":1211,"style":1207},"conditional formatting rules",[69,1245,1246],{"x":1235,"y":1215,"style":1207},"data validation dropdowns",[69,1248,1249],{"x":1235,"y":1219,"style":1207},"comments and defined names",[69,1251,1252],{"x":1235,"y":90,"style":1207},"pivot tables and slicers",[69,1254,1255],{"x":1235,"y":1226,"style":1227},"objects that live above the cell grid",[172,1257,1259],{"id":1258},"step-4b-decide-which-route-the-job-actually-needs","Step 4b: Decide which route the job actually needs",[10,1261,1262],{},"Three approaches, and the choice is usually settled by one question — does the target workbook already have content that must be kept?",[33,1264,42,1269,42,1272,42,1275,42,1278,42,1282,42,1286,42,1289,42,1292,42,1296,42,1299,42,1302,42,1306,42,1309,42,1312,42,1315,42,1318,42,1321,42,1326,42,1329,42,1332,42,1335],{"viewBox":1265,"role":36,"ariaLabelledBy":1266,"xmlns":40,"style":41},"0 0 740 226",[1267,1268],"cp-route-t","cp-route-d",[44,1270,1271],{"id":1267},"Choosing between duplicating, rebuilding and copying the file",[48,1273,1274],{"id":1268},"If the source and the target are the same workbook, copy_worksheet does everything. If the target is a new file, copying the whole file and deleting the unwanted sheets keeps charts and rules intact. Only when the sheet must join an existing workbook with content of its own is the cell-by-cell rebuild necessary.",[52,1276],{"x":54,"y":54,"width":55,"height":1277,"fill":57},"226",[52,1279],{"x":1192,"y":1193,"width":1280,"height":1281,"rx":64,"fill":1196,"stroke":1197,"style":67},"228","170",[69,1283,1285],{"x":157,"y":1201,"style":1284},"font-size:12px;font-weight:700;fill:var(--teal-ink,#0b6157);text-anchor:middle","same workbook",[69,1287,1288],{"x":157,"y":1206,"style":1207},"wb.copy_worksheet(ws)",[69,1290,1291],{"x":157,"y":79,"style":1227},"values, styles, widths,",[69,1293,1295],{"x":157,"y":1294,"style":1227},"138","merges — all handled",[69,1297,1298],{"x":157,"y":63,"style":1227},"one line, nothing lost",[52,1300],{"x":1301,"y":1193,"width":1280,"height":1281,"rx":64,"fill":65,"stroke":66,"style":67},"256",[69,1303,1305],{"x":168,"y":1201,"style":1304},"font-size:12px;font-weight:700;fill:var(--brand-strong,#4338ca);text-anchor:middle","a new file",[69,1307,1308],{"x":168,"y":1206,"style":1207},"shutil.copy, then delete",[69,1310,1311],{"x":168,"y":79,"style":1227},"charts, images, rules",[69,1313,1314],{"x":168,"y":1294,"style":1227},"and validation survive",[69,1316,1317],{"x":168,"y":63,"style":1227},"nothing is rebuilt",[52,1319],{"x":1320,"y":1193,"width":1280,"height":1281,"rx":64,"fill":119,"stroke":120,"style":67},"496",[69,1322,1325],{"x":1323,"y":1201,"style":1324},"610","font-size:12px;font-weight:700;fill:var(--gold-ink,#7a4e06);text-anchor:middle","into an existing book",[69,1327,1328],{"x":1323,"y":1206,"style":1207},"rebuild cell by cell",[69,1330,1331],{"x":1323,"y":79,"style":1227},"recreate charts, rules",[69,1333,1334],{"x":1323,"y":1294,"style":1227},"and validation yourself",[69,1336,1337],{"x":1323,"y":63,"style":1227},"the only route that works",[10,1339,1340],{},"Most requests that sound like the third case are really the second. \"Put the Q1 sheet into a workbook for the auditor\" does not need an existing target — it needs a file containing that sheet, which the copy-and-delete route produces in two lines with nothing lost. Reach for the rebuild only when the destination workbook is genuinely established and must keep what it already holds.",[172,1342,1344],{"id":1343},"step-5-when-the-answer-is-to-copy-the-file","Step 5: When the answer is to copy the file",[10,1346,1347],{},"If the sheet carries charts, validation or conditional formatting, rebuilding it faithfully is more work than it is worth. Copy the whole file and remove what you do not want:",[177,1349,1351],{"className":209,"code":1350,"language":211,"meta":182,"style":182},"import shutil\n\nfrom openpyxl import load_workbook\n\nshutil.copy(\"source.xlsx\", \"extract.xlsx\")\n\nwb = load_workbook(\"extract.xlsx\")\nfor name in list(wb.sheetnames):\n    if name != \"Q1\":\n        del wb[name]\nwb.save(\"extract.xlsx\")\n",[14,1352,1353,1360,1364,1374,1378,1392,1396,1408,1423,1439,1447],{"__ignoreMap":182},[186,1354,1355,1357],{"class":104,"line":188},[186,1356,226],{"class":218},[186,1358,1359],{"class":222}," shutil\n",[186,1361,1362],{"class":104,"line":232},[186,1363,249],{"emptyLinePlaceholder":248},[186,1365,1366,1368,1370,1372],{"class":104,"line":245},[186,1367,219],{"class":218},[186,1369,223],{"class":222},[186,1371,226],{"class":218},[186,1373,578],{"class":222},[186,1375,1376],{"class":104,"line":252},[186,1377,249],{"emptyLinePlaceholder":248},[186,1379,1380,1383,1385,1387,1390],{"class":104,"line":264},[186,1381,1382],{"class":222},"shutil.copy(",[186,1384,516],{"class":195},[186,1386,295],{"class":222},[186,1388,1389],{"class":195},"\"extract.xlsx\"",[186,1391,406],{"class":222},[186,1393,1394],{"class":104,"line":275},[186,1395,249],{"emptyLinePlaceholder":248},[186,1397,1398,1400,1402,1404,1406],{"class":104,"line":286},[186,1399,587],{"class":222},[186,1401,258],{"class":218},[186,1403,592],{"class":222},[186,1405,1389],{"class":195},[186,1407,406],{"class":222},[186,1409,1410,1412,1415,1417,1420],{"class":104,"line":304},[186,1411,358],{"class":218},[186,1413,1414],{"class":222}," name ",[186,1416,364],{"class":218},[186,1418,1419],{"class":314}," list",[186,1421,1422],{"class":222},"(wb.sheetnames):\n",[186,1424,1425,1428,1430,1433,1436],{"class":104,"line":320},[186,1426,1427],{"class":218},"    if",[186,1429,1414],{"class":222},[186,1431,1432],{"class":218},"!=",[186,1434,1435],{"class":195}," \"Q1\"",[186,1437,1438],{"class":222},":\n",[186,1440,1441,1444],{"class":104,"line":335},[186,1442,1443],{"class":218},"        del",[186,1445,1446],{"class":222}," wb[name]\n",[186,1448,1449,1451,1453],{"class":104,"line":350},[186,1450,626],{"class":222},[186,1452,1389],{"class":195},[186,1454,406],{"class":222},[10,1456,1457,1458,1461],{},"Nothing is rebuilt, so nothing is lost — charts, images, rules and all. The limitation is that this produces a ",[22,1459,1460],{},"new"," file containing the sheet, rather than adding the sheet to an existing workbook that already has content of its own. When the requirement really is \"add this sheet to that established workbook\", the cell-by-cell copy plus recreating the extras is the only route openpyxl offers.",[10,1463,1464,1465,1469,1470,1474],{},"Copying rules and validation onto the new sheet is straightforward if you know what they were, and both are covered in ",[27,1466,1468],{"href":1467},"\u002Fadvanced-data-transformation-and-cleaning\u002Fapplying-conditional-formatting-with-openpyxl\u002F","Applying Conditional Formatting with openpyxl"," and ",[27,1471,1473],{"href":1472},"\u002Fadvanced-data-transformation-and-cleaning\u002Fvalidating-excel-data-with-python\u002Fadd-dropdown-data-validation-to-excel-with-openpyxl\u002F","Add Dropdown Data Validation to Excel with openpyxl",".",[172,1476,1478],{"id":1477},"common-pitfalls-and-gotchas","Common pitfalls and gotchas",[1480,1481,1482,1498],"table",{},[1483,1484,1485],"thead",{},[1486,1487,1488,1492,1495],"tr",{},[1489,1490,1491],"th",{},"Symptom",[1489,1493,1494],{},"Cause",[1489,1496,1497],{},"Fix",[1499,1500,1501,1518,1535,1549,1564,1575,1590,1604],"tbody",{},[1486,1502,1503,1512,1515],{},[1504,1505,1506,1509,1510],"td",{},[14,1507,1508],{},"ValueError"," from ",[14,1511,16],{},[1504,1513,1514],{},"Used across two workbooks",[1504,1516,1517],{},"Copy cell by cell, or copy the file",[1486,1519,1520,1523,1526],{},[1504,1521,1522],{},"Styles missing after the copy",[1504,1524,1525],{},"Style objects assigned, not copied",[1504,1527,1528,1530,1531,1534],{},[14,1529,1079],{}," from the ",[14,1532,1533],{},"copy"," module",[1486,1536,1537,1543,1546],{},[1504,1538,1539,1540],{},"Formulas show ",[14,1541,1542],{},"#REF!",[1504,1544,1545],{},"Referenced rows were not copied",[1504,1547,1548],{},"Copy the supporting range, or copy values",[1486,1550,1551,1556,1561],{},[1504,1552,1553,1554],{},"Formula cells read as ",[14,1555,704],{},[1504,1557,1558,1560],{},[14,1559,1107],{}," on a file Excel never opened",[1504,1562,1563],{},"Compute in Python, or open and save once in Excel",[1486,1565,1566,1569,1572],{},[1504,1567,1568],{},"Charts and images vanished",[1504,1570,1571],{},"Not handled by a cell copy",[1504,1573,1574],{},"Copy the file, or recreate them",[1486,1576,1577,1580,1583],{},[1504,1578,1579],{},"Columns are all default width",[1504,1581,1582],{},"Column dimensions not copied",[1504,1584,1585,1586,1589],{},"Copy ",[14,1587,1588],{},"column_dimensions"," explicitly",[1486,1591,1592,1595,1598],{},[1504,1593,1594],{},"Merged cells lost",[1504,1596,1597],{},"Merged ranges not copied",[1504,1599,1600,1601],{},"Iterate ",[14,1602,1603],{},"merged_cells.ranges",[1486,1605,1606,1609,1612],{},[1504,1607,1608],{},"Copy is slow on a large sheet",[1504,1610,1611],{},"Styling every cell including empties",[1504,1613,1614,1615,1618],{},"Skip cells where ",[14,1616,1617],{},"has_style"," is false",[172,1620,1622],{"id":1621},"performance-and-scale-notes","Performance and scale notes",[10,1624,1625],{},"A cell-by-cell copy touches every cell twice — once to read, once to write — and building a style object per cell is the expensive half. On a 100,000-row sheet, skipping unstyled cells and setting formats at the column level instead can cut the copy time substantially.",[10,1627,1628,1629,1632],{},"For bulk work, ",[14,1630,1631],{},"shutil.copy"," is effectively free regardless of size, because it never parses the workbook at all. That makes the file-copy route the right default whenever the requirement can be expressed as \"this workbook, minus some sheets\" rather than \"this sheet, added to that workbook\".",[172,1634,1636],{"id":1635},"conclusion","Conclusion",[10,1638,1639,1641],{},[14,1640,16],{}," duplicates a sheet inside one workbook and nothing more, because a worksheet's cells point at workbook-level string and style tables. Across files, rebuild: copy values and formula text, copy each style object rather than assigning it, and carry the column widths, row heights, merged ranges and panes. Decide deliberately whether formulas should travel as formulas or as values. And when the sheet carries charts, rules or validation, copy the file and delete the other sheets — nothing rebuilt is nothing lost.",[172,1643,1645],{"id":1644},"frequently-asked-questions","Frequently asked questions",[10,1647,1648,1655],{},[1649,1650,1651,1652,1654],"strong",{},"Why does ",[14,1653,16],{}," fail across workbooks?","\nIt is documented as working only within the same workbook. A worksheet holds references to its parent's shared strings, styles and defined names, so moving the object itself would carry broken references — openpyxl raises rather than producing a corrupt file.",[10,1657,1658,1661,1662,1664],{},[1649,1659,1660],{},"What is the simplest way to copy a sheet to another file?","\nCopy the whole file with ",[14,1663,1631],{}," and delete the sheets you do not want. Everything survives, because nothing was rebuilt.",[10,1666,1667,1670],{},[1649,1668,1669],{},"Do charts and images copy across?","\nNot with a cell-by-cell copy. openpyxl does not re-anchor chart or image objects into a different workbook, so those have to be recreated on the target.",[10,1672,1673,1676,1677,1679],{},[1649,1674,1675],{},"How do I copy only the values?","\nRead the source with ",[14,1678,1107],{}," and write the values into the target sheet. That gives numbers instead of formulas, which is what you want when the target has no supporting data.",[172,1681,1683],{"id":1682},"related","Related",[10,1685,1686],{},"Up to the parent guide:",[1688,1689,1690],"ul",{},[1691,1692,1693,1695],"li",{},[27,1694,30],{"href":29}," — the wider set of sheet-level operations.",[10,1697,1698],{},"Related guides:",[1688,1700,1701,1708,1715,1722],{},[1691,1702,1703,1707],{},[27,1704,1706],{"href":1705},"\u002Fgetting-started-with-python-excel-automation\u002Fworking-with-multiple-excel-sheets-in-python\u002Frename-reorder-and-delete-excel-sheets-with-openpyxl\u002F","Rename, Reorder and Delete Excel Sheets with openpyxl"," — tidying the workbook after a copy.",[1691,1709,1710,1714],{},[27,1711,1713],{"href":1712},"\u002Fautomating-reporting-workflows\u002Fgenerating-excel-reports-from-templates\u002Fpopulate-excel-template-without-losing-formatting\u002F","Populate an Excel Template Without Losing Formatting"," — the template-duplication case that avoids copying altogether.",[1691,1716,1717,1719,1720,1474],{},[27,1718,1173],{"href":1172}," — why a copied formula can read as ",[14,1721,704],{},[1691,1723,1724,1728],{},[27,1725,1727],{"href":1726},"\u002Fgetting-started-with-python-excel-automation\u002Fworking-with-multiple-excel-sheets-in-python\u002Fread-all-sheets-from-an-excel-file-into-dataframes\u002F","Read All Sheets from an Excel File into DataFrames"," — when you want the data rather than the sheet.",[1730,1731,1732],"style",{},"html pre.shiki code .sMTad, html code.shiki .sMTad{--shiki-default:#6F42C1;--shiki-dark:#FFB757}html pre.shiki code .srMev, html code.shiki .srMev{--shiki-default:#032F62;--shiki-dark:#ADDCFF}html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html.dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html pre.shiki code .s-kum, html code.shiki .s-kum{--shiki-default:#D73A49;--shiki-dark:#FF9492}html pre.shiki code .skGVy, html code.shiki .skGVy{--shiki-default:#24292E;--shiki-dark:#F0F3F6}html pre.shiki code .sP0c6, html code.shiki .sP0c6{--shiki-default:#005CC5;--shiki-dark:#91CBFF}html pre.shiki code .sa561, html code.shiki .sa561{--shiki-default:#E36209;--shiki-dark:#FFB757}html pre.shiki code .s_Opv, html code.shiki .s_Opv{--shiki-default:#6F42C1;--shiki-dark:#DBB7FF}",{"title":182,"searchDepth":232,"depth":232,"links":1734},[1735,1736,1737,1738,1739,1740,1741,1742,1743,1744,1745,1746],{"id":174,"depth":232,"text":175},{"id":205,"depth":232,"text":206},{"id":558,"depth":232,"text":559},{"id":639,"depth":232,"text":640},{"id":1093,"depth":232,"text":1094},{"id":1258,"depth":232,"text":1259},{"id":1343,"depth":232,"text":1344},{"id":1477,"depth":232,"text":1478},{"id":1621,"depth":232,"text":1622},{"id":1635,"depth":232,"text":1636},{"id":1644,"depth":232,"text":1645},{"id":1682,"depth":232,"text":1683},"2026-08-10","openpyxl's copy_worksheet only works inside one workbook — here is what actually happens when you copy across files, how to carry values and styles over, and when to copy the file instead.","md",[1751,1754,1756,1758],{"q":1752,"a":1753},"Why does copy_worksheet fail across workbooks?","It is documented as working only within the same workbook. A worksheet holds references to its parent's shared strings, styles and defined names, so moving the object itself would carry broken references — openpyxl raises rather than producing a corrupt file.",{"q":1660,"a":1755},"Copy the whole file with shutil.copy and delete the sheets you do not want. Everything survives, because nothing was rebuilt.",{"q":1669,"a":1757},"Not with a cell-by-cell copy. openpyxl does not re-anchor chart or image objects into a different workbook, so those have to be recreated on the target.",{"q":1675,"a":1759},"Read the source with data_only=True and write the values into the target sheet. That gives numbers instead of formulas, which is what you want when the target has no supporting data.",{"breadcrumb":1761},[1762,1765,1768,1769],{"name":1763,"item":1764},"Home","\u002F",{"name":1766,"item":1767},"Getting Started with Python Excel Automation","\u002Fgetting-started-with-python-excel-automation\u002F",{"name":30,"item":29},{"name":5,"item":1770},"\u002Fgetting-started-with-python-excel-automation\u002Fworking-with-multiple-excel-sheets-in-python\u002Fcopy-a-sheet-between-excel-workbooks-with-python\u002F","\u002Fgetting-started-with-python-excel-automation\u002Fworking-with-multiple-excel-sheets-in-python\u002Fcopy-a-sheet-between-excel-workbooks-with-python",{"title":1773,"description":1774},"Copy a Sheet Between Excel Workbooks (Python)","Copy worksheets in Python: openpyxl copy_worksheet within a workbook, a values-and-styles copy across workbooks, what does not survive, and the file-copy alternative.","copy-a-sheet-between-excel-workbooks-with-python","getting-started-with-python-excel-automation\u002Fworking-with-multiple-excel-sheets-in-python\u002Fcopy-a-sheet-between-excel-workbooks-with-python\u002Findex","how-to","gR-w7HnTF-UYIkz141hPxVo46M1TTET_PMXLaEksIXA",[1780,1784],{"title":1781,"path":1782,"stem":1783,"children":-1},"Combine Multiple Excel Files into One in Python","\u002Fgetting-started-with-python-excel-automation\u002Fworking-with-multiple-excel-sheets-in-python\u002Fcombine-multiple-excel-files-into-one-python","getting-started-with-python-excel-automation\u002Fworking-with-multiple-excel-sheets-in-python\u002Fcombine-multiple-excel-files-into-one-python\u002Findex",{"title":1727,"path":1785,"stem":1786,"children":-1},"\u002Fgetting-started-with-python-excel-automation\u002Fworking-with-multiple-excel-sheets-in-python\u002Fread-all-sheets-from-an-excel-file-into-dataframes","getting-started-with-python-excel-automation\u002Fworking-with-multiple-excel-sheets-in-python\u002Fread-all-sheets-from-an-excel-file-into-dataframes\u002Findex",1786800028716]