[{"data":1,"prerenderedAt":1712},["ShallowReactive",2],{"doc:\u002Fgetting-started-with-python-excel-automation\u002Fusing-python-in-excel\u002Fpython-in-excel-vs-openpyxl-and-xlwings":3,"surround:\u002Fgetting-started-with-python-excel-automation\u002Fusing-python-in-excel\u002Fpython-in-excel-vs-openpyxl-and-xlwings":1682,"ancestors:\u002Fgetting-started-with-python-excel-automation\u002Fusing-python-in-excel\u002Fpython-in-excel-vs-openpyxl-and-xlwings":1690,"children:\u002Fgetting-started-with-python-excel-automation\u002Fusing-python-in-excel\u002Fpython-in-excel-vs-openpyxl-and-xlwings":1695,"related:\u002Fgetting-started-with-python-excel-automation\u002Fusing-python-in-excel\u002Fpython-in-excel-vs-openpyxl-and-xlwings":1696},{"id":4,"title":5,"body":6,"dateModified":1647,"datePublished":1647,"description":1648,"extension":1649,"faq":1650,"keyword":1659,"kind":1660,"meta":1661,"navigation":302,"path":1670,"seo":1671,"slug":1674,"stem":1675,"topics":1676,"type":1680,"__hash__":1681},"docs\u002Fgetting-started-with-python-excel-automation\u002Fusing-python-in-excel\u002Fpython-in-excel-vs-openpyxl-and-xlwings\u002Findex.md","Python in Excel vs openpyxl and xlwings",{"type":7,"value":8,"toc":1633},"minimark",[9,54,175,180,183,188,273,279,525,530,700,703,707,710,718,812,816,823,835,839,842,846,853,860,1090,1094,1097,1105,1109,1120,1453,1460,1464,1542,1546,1554,1558,1561,1565,1571,1577,1583,1589,1593,1629],[10,11,12,13,17,18,22,23,27,28,31,32,35,36,39,40,43,44,47,48,53],"p",{},"\"Python and Excel\" now means three quite different things. ",[14,15,16],"strong",{},"Python in Excel"," puts Python ",[19,20,21],"em",{},"inside"," a\nworkbook: a ",[24,25,26],"code",{},"=PY"," formula runs in a Microsoft cloud container and returns its result to a cell.\n",[14,29,30],{},"openpyxl, xlsxwriter and pandas"," run Python ",[19,33,34],{},"outside"," Excel: a script reads and writes ",[24,37,38],{},".xlsx"," files\nwithout Excel installed at all. ",[14,41,42],{},"xlwings"," (and pywin32 underneath it on Windows) runs Python ",[19,45,46],{},"alongside","\nExcel: a script drives the running application as if a person were clicking. They overlap less than the\nshared name suggests, and choosing the wrong one produces a solution that fights its tool at every step.\nThis guide from ",[49,50,52],"a",{"href":51},"\u002Fgetting-started-with-python-excel-automation\u002Fusing-python-in-excel\u002F","Using Python in Excel","\ncompares them on the questions that decide real projects.",[55,56,64,65,64,69,64,73,64,80,64,89,64,95,64,102,64,107,64,111,64,115,64,119,64,124,64,129,64,133,64,136,64,139,64,142,64,145,64,150,64,154,64,158,64,161,64,164,64,167,64,170],"svg",{"viewBox":57,"role":58,"ariaLabelledBy":59,"xmlns":62,"style":63},"0 0 760 214","img",[60,61],"pvs-where-t","pvs-where-d","http:\u002F\u002Fwww.w3.org\u002F2000\u002Fsvg","width:100%;max-width:760px;height:auto;display:block;margin:1.5rem auto;font-family:Inter,ui-sans-serif,system-ui,sans-serif","\n  ",[66,67,68],"title",{"id":60},"Where the code runs in each approach",[70,71,72],"desc",{"id":61},"Python in Excel runs in a Microsoft cloud container triggered by a cell. openpyxl and pandas run in a script on any machine and work on files without Excel. xlwings runs in a script on a machine with Excel installed and controls the application.",[74,75],"rect",{"x":76,"y":76,"width":77,"height":78,"fill":79},"0","760","214","#ffffff",[74,81],{"x":82,"y":82,"width":83,"height":84,"rx":85,"fill":86,"stroke":87,"style":88},"20","226.7","150","14","#f0f4ff","var(--brand,#5b5cf0)","stroke-width:2px",[90,91,16],"text",{"x":92,"y":93,"style":94},"133.3","46","font-size:13px;font-weight:700;fill:var(--brand-strong,#4338ca);text-anchor:middle",[96,97],"line",{"x1":98,"y1":99,"x2":100,"y2":99,"stroke":87,"style":101},"36","56","230.7","stroke-width:1px",[90,103,106],{"x":92,"y":104,"style":105},"78","font-size:11.5px;font-weight:400;fill:var(--text,#172033);text-anchor:middle","inside a =PY cell",[90,108,110],{"x":92,"y":109,"style":105},"101","Microsoft cloud container",[90,112,114],{"x":92,"y":113,"style":105},"124","data only via xl()",[90,116,118],{"x":92,"y":117,"style":105},"147","recalculates like a formula",[74,120],{"x":121,"y":82,"width":83,"height":84,"rx":85,"fill":122,"stroke":123,"style":88},"266.7","#d9f4f1","var(--teal,#0f9488)",[90,125,128],{"x":126,"y":93,"style":127},"380","font-size:13px;font-weight:700;fill:var(--teal-ink,#0b6157);text-anchor:middle","openpyxl \u002F pandas",[96,130],{"x1":131,"y1":99,"x2":132,"y2":99,"stroke":123,"style":101},"282.7","477.3",[90,134,135],{"x":126,"y":104,"style":105},"a script, any machine",[90,137,138],{"x":126,"y":109,"style":105},"no Excel needed",[90,140,141],{"x":126,"y":113,"style":105},"reads and writes files",[90,143,144],{"x":126,"y":117,"style":105},"runs on a schedule",[74,146],{"x":147,"y":82,"width":83,"height":84,"rx":85,"fill":148,"stroke":149,"style":88},"513.3","#fdefd8","var(--gold,#b4740a)",[90,151,42],{"x":152,"y":93,"style":153},"626.7","font-size:13px;font-weight:700;fill:var(--gold-ink,#7a4e06);text-anchor:middle",[96,155],{"x1":156,"y1":99,"x2":157,"y2":99,"stroke":149,"style":101},"529.3","724",[90,159,160],{"x":152,"y":104,"style":105},"a script beside Excel",[90,162,163],{"x":152,"y":109,"style":105},"Windows or macOS + Excel",[90,165,166],{"x":152,"y":113,"style":105},"drives the live app",[90,168,169],{"x":152,"y":117,"style":105},"recalc, macros, refresh",[90,171,174],{"x":126,"y":172,"style":173},"200","font-size:12.5px;font-weight:400;fill:var(--muted,#5b6780);text-anchor:middle","inside, outside, alongside — the rest of the differences follow",[176,177,179],"h2",{"id":178},"the-same-job-three-ways","The same job, three ways",[10,181,182],{},"A concrete task makes the differences tangible: summarise a sales table by region and put the result in a workbook.",[10,184,185,187],{},[14,186,16],{}," — a formula in the workbook itself, set to return Excel values:",[189,190,195],"pre",{"className":191,"code":192,"language":193,"meta":194,"style":194},"language-python shiki shiki-themes github-light github-dark-high-contrast","sales = xl(\"Sales[#All]\", headers=True)\nsales.groupby(\"Region\", as_index=False)[\"Amount\"].sum().sort_values(\"Amount\", ascending=False)\n","python","",[24,196,197,232],{"__ignoreMap":194},[198,199,201,205,209,212,216,219,223,225,229],"span",{"class":96,"line":200},1,[198,202,204],{"class":203},"skGVy","sales ",[198,206,208],{"class":207},"s-kum","=",[198,210,211],{"class":203}," xl(",[198,213,215],{"class":214},"srMev","\"Sales[#All]\"",[198,217,218],{"class":203},", ",[198,220,222],{"class":221},"sa561","headers",[198,224,208],{"class":207},[198,226,228],{"class":227},"sP0c6","True",[198,230,231],{"class":203},")\n",[198,233,235,238,241,243,246,248,251,254,257,260,262,264,267,269,271],{"class":96,"line":234},2,[198,236,237],{"class":203},"sales.groupby(",[198,239,240],{"class":214},"\"Region\"",[198,242,218],{"class":203},[198,244,245],{"class":221},"as_index",[198,247,208],{"class":207},[198,249,250],{"class":227},"False",[198,252,253],{"class":203},")[",[198,255,256],{"class":214},"\"Amount\"",[198,258,259],{"class":203},"].sum().sort_values(",[198,261,256],{"class":214},[198,263,218],{"class":203},[198,265,266],{"class":221},"ascending",[198,268,208],{"class":207},[198,270,250],{"class":227},[198,272,231],{"class":203},[10,274,275,278],{},[14,276,277],{},"pandas with openpyxl"," — a script that reads one file and writes another, on any machine:",[189,280,282],{"className":191,"code":281,"language":193,"meta":194,"style":194},"import pandas as pd\n\npd.DataFrame({\n    \"Region\": [\"North\", \"South\", \"North\", \"West\"],\n    \"Amount\": [1200.0, 950.0, 800.0, 400.0],\n}).to_excel(\"sales.xlsx\", sheet_name=\"Sales\", index=False)\n\nsales = pd.read_excel(\"sales.xlsx\", sheet_name=\"Sales\")\nsummary = sales.groupby(\"Region\", as_index=False)[\"Amount\"].sum().sort_values(\"Amount\", ascending=False)\nwith pd.ExcelWriter(\"summary.xlsx\", engine=\"openpyxl\") as writer:\n    summary.to_excel(writer, sheet_name=\"By region\", index=False)\nprint(summary)\n",[24,283,284,298,304,310,339,367,397,402,424,463,493,516],{"__ignoreMap":194},[198,285,286,289,292,295],{"class":96,"line":200},[198,287,288],{"class":207},"import",[198,290,291],{"class":203}," pandas ",[198,293,294],{"class":207},"as",[198,296,297],{"class":203}," pd\n",[198,299,300],{"class":96,"line":234},[198,301,303],{"emptyLinePlaceholder":302},true,"\n",[198,305,307],{"class":96,"line":306},3,[198,308,309],{"class":203},"pd.DataFrame({\n",[198,311,313,316,319,322,324,327,329,331,333,336],{"class":96,"line":312},4,[198,314,315],{"class":214},"    \"Region\"",[198,317,318],{"class":203},": [",[198,320,321],{"class":214},"\"North\"",[198,323,218],{"class":203},[198,325,326],{"class":214},"\"South\"",[198,328,218],{"class":203},[198,330,321],{"class":214},[198,332,218],{"class":203},[198,334,335],{"class":214},"\"West\"",[198,337,338],{"class":203},"],\n",[198,340,342,345,347,350,352,355,357,360,362,365],{"class":96,"line":341},5,[198,343,344],{"class":214},"    \"Amount\"",[198,346,318],{"class":203},[198,348,349],{"class":227},"1200.0",[198,351,218],{"class":203},[198,353,354],{"class":227},"950.0",[198,356,218],{"class":203},[198,358,359],{"class":227},"800.0",[198,361,218],{"class":203},[198,363,364],{"class":227},"400.0",[198,366,338],{"class":203},[198,368,370,373,376,378,381,383,386,388,391,393,395],{"class":96,"line":369},6,[198,371,372],{"class":203},"}).to_excel(",[198,374,375],{"class":214},"\"sales.xlsx\"",[198,377,218],{"class":203},[198,379,380],{"class":221},"sheet_name",[198,382,208],{"class":207},[198,384,385],{"class":214},"\"Sales\"",[198,387,218],{"class":203},[198,389,390],{"class":221},"index",[198,392,208],{"class":207},[198,394,250],{"class":227},[198,396,231],{"class":203},[198,398,400],{"class":96,"line":399},7,[198,401,303],{"emptyLinePlaceholder":302},[198,403,405,407,409,412,414,416,418,420,422],{"class":96,"line":404},8,[198,406,204],{"class":203},[198,408,208],{"class":207},[198,410,411],{"class":203}," pd.read_excel(",[198,413,375],{"class":214},[198,415,218],{"class":203},[198,417,380],{"class":221},[198,419,208],{"class":207},[198,421,385],{"class":214},[198,423,231],{"class":203},[198,425,427,430,432,435,437,439,441,443,445,447,449,451,453,455,457,459,461],{"class":96,"line":426},9,[198,428,429],{"class":203},"summary ",[198,431,208],{"class":207},[198,433,434],{"class":203}," sales.groupby(",[198,436,240],{"class":214},[198,438,218],{"class":203},[198,440,245],{"class":221},[198,442,208],{"class":207},[198,444,250],{"class":227},[198,446,253],{"class":203},[198,448,256],{"class":214},[198,450,259],{"class":203},[198,452,256],{"class":214},[198,454,218],{"class":203},[198,456,266],{"class":221},[198,458,208],{"class":207},[198,460,250],{"class":227},[198,462,231],{"class":203},[198,464,466,469,472,475,477,480,482,485,488,490],{"class":96,"line":465},10,[198,467,468],{"class":207},"with",[198,470,471],{"class":203}," pd.ExcelWriter(",[198,473,474],{"class":214},"\"summary.xlsx\"",[198,476,218],{"class":203},[198,478,479],{"class":221},"engine",[198,481,208],{"class":207},[198,483,484],{"class":214},"\"openpyxl\"",[198,486,487],{"class":203},") ",[198,489,294],{"class":207},[198,491,492],{"class":203}," writer:\n",[198,494,496,499,501,503,506,508,510,512,514],{"class":96,"line":495},11,[198,497,498],{"class":203},"    summary.to_excel(writer, ",[198,500,380],{"class":221},[198,502,208],{"class":207},[198,504,505],{"class":214},"\"By region\"",[198,507,218],{"class":203},[198,509,390],{"class":221},[198,511,208],{"class":207},[198,513,250],{"class":227},[198,515,231],{"class":203},[198,517,519,522],{"class":96,"line":518},12,[198,520,521],{"class":227},"print",[198,523,524],{"class":203},"(summary)\n",[10,526,527,529],{},[14,528,42],{}," — a script that opens the workbook in Excel, writes into it and lets Excel recalculate:",[189,531,533],{"className":191,"code":532,"language":193,"meta":194,"style":194},"import pandas as pd\nimport xlwings as xw\n\nwith xw.App(visible=False) as app:\n    book = app.books.open(\"sales.xlsx\")\n    sales = book.sheets[\"Sales\"].range(\"A1\").expand().options(pd.DataFrame, index=False).value\n    summary = sales.groupby(\"Region\", as_index=False)[\"Amount\"].sum()\n    sheet = book.sheets.add(\"By region\")\n    sheet.range(\"A1\").options(index=False).value = summary\n    book.save(\"summary_live.xlsx\")\n",[24,534,535,545,557,561,582,596,626,652,666,690],{"__ignoreMap":194},[198,536,537,539,541,543],{"class":96,"line":200},[198,538,288],{"class":207},[198,540,291],{"class":203},[198,542,294],{"class":207},[198,544,297],{"class":203},[198,546,547,549,552,554],{"class":96,"line":234},[198,548,288],{"class":207},[198,550,551],{"class":203}," xlwings ",[198,553,294],{"class":207},[198,555,556],{"class":203}," xw\n",[198,558,559],{"class":96,"line":306},[198,560,303],{"emptyLinePlaceholder":302},[198,562,563,565,568,571,573,575,577,579],{"class":96,"line":312},[198,564,468],{"class":207},[198,566,567],{"class":203}," xw.App(",[198,569,570],{"class":221},"visible",[198,572,208],{"class":207},[198,574,250],{"class":227},[198,576,487],{"class":203},[198,578,294],{"class":207},[198,580,581],{"class":203}," app:\n",[198,583,584,587,589,592,594],{"class":96,"line":341},[198,585,586],{"class":203},"    book ",[198,588,208],{"class":207},[198,590,591],{"class":203}," app.books.open(",[198,593,375],{"class":214},[198,595,231],{"class":203},[198,597,598,601,603,606,608,611,614,617,619,621,623],{"class":96,"line":369},[198,599,600],{"class":203},"    sales ",[198,602,208],{"class":207},[198,604,605],{"class":203}," book.sheets[",[198,607,385],{"class":214},[198,609,610],{"class":203},"].range(",[198,612,613],{"class":214},"\"A1\"",[198,615,616],{"class":203},").expand().options(pd.DataFrame, ",[198,618,390],{"class":221},[198,620,208],{"class":207},[198,622,250],{"class":227},[198,624,625],{"class":203},").value\n",[198,627,628,631,633,635,637,639,641,643,645,647,649],{"class":96,"line":399},[198,629,630],{"class":203},"    summary ",[198,632,208],{"class":207},[198,634,434],{"class":203},[198,636,240],{"class":214},[198,638,218],{"class":203},[198,640,245],{"class":221},[198,642,208],{"class":207},[198,644,250],{"class":227},[198,646,253],{"class":203},[198,648,256],{"class":214},[198,650,651],{"class":203},"].sum()\n",[198,653,654,657,659,662,664],{"class":96,"line":404},[198,655,656],{"class":203},"    sheet ",[198,658,208],{"class":207},[198,660,661],{"class":203}," book.sheets.add(",[198,663,505],{"class":214},[198,665,231],{"class":203},[198,667,668,671,673,676,678,680,682,685,687],{"class":96,"line":426},[198,669,670],{"class":203},"    sheet.range(",[198,672,613],{"class":214},[198,674,675],{"class":203},").options(",[198,677,390],{"class":221},[198,679,208],{"class":207},[198,681,250],{"class":227},[198,683,684],{"class":203},").value ",[198,686,208],{"class":207},[198,688,689],{"class":203}," summary\n",[198,691,692,695,698],{"class":96,"line":465},[198,693,694],{"class":203},"    book.save(",[198,696,697],{"class":214},"\"summary_live.xlsx\"",[198,699,231],{"class":203},[10,701,702],{},"The pandas logic is identical in all three. What differs is everything around it: who runs the code, when, on what machine,\nand what happens to the result afterwards.",[176,704,706],{"id":705},"question-1-who-triggers-the-work-and-when","Question 1 — Who triggers the work, and when?",[10,708,709],{},"Python in Excel runs when the workbook calculates: when someone opens it, edits an input, refreshes a query or presses F9. That\nis ideal for analysis a person is actively doing, and useless for a report that must exist at 06:00 before anyone is awake.\nNobody is there to open the workbook.",[10,711,712,713,717],{},"A pandas or openpyxl script runs whenever something starts it — cron, Windows Task Scheduler, a CI job, a web request — which is\nexactly what scheduled reporting needs; see ",[49,714,716],{"href":715},"\u002Fautomating-reporting-workflows\u002Fscheduling-python-excel-scripts-with-cron\u002F","Scheduling Python Excel Scripts with Cron",".\nxlwings can be scheduled too, but it needs an interactive desktop with Excel installed, which makes unattended runs fragile.",[55,719,64,725,64,728,64,731,64,735,64,740,64,746,64,752,64,759,64,766,64,771,64,774,64,777,64,780,64,784,64,788,64,791,64,794,64,797,64,803,64,807],{"viewBox":720,"role":58,"ariaLabelledBy":721,"xmlns":62,"style":724},"0 0 720 212",[722,723],"pvs-schedule-t","pvs-schedule-d","width:100%;max-width:720px;height:auto;display:block;margin:1.5rem auto;font-family:Inter,ui-sans-serif,system-ui,sans-serif",[66,726,727],{"id":722},"Suitability for unattended scheduled runs",[70,729,730],{"id":723},"File-level scripts with pandas and openpyxl are well suited to unattended scheduled runs. xlwings is possible but fragile because it needs a desktop session with Excel. Python in Excel only runs when a person opens or recalculates the workbook.",[74,732],{"x":76,"y":76,"width":733,"height":734,"fill":79},"720","212",[90,736,739],{"x":82,"y":737,"style":738},"30","font-size:12px;font-weight:600;fill:var(--muted,#5b6780);text-anchor:start","fit for a report that must exist before anyone logs in",[74,741],{"x":82,"y":93,"width":742,"height":743,"rx":744,"fill":79,"stroke":745,"style":101},"170","28","6","var(--line,#cdd5e6)",[90,747,751],{"x":748,"y":749,"style":750},"105","65","font-size:12px;font-weight:600;fill:var(--text,#172033);text-anchor:middle","pandas \u002F openpyxl",[74,753],{"x":754,"y":755,"width":756,"height":757,"rx":744,"fill":758,"stroke":745,"style":101},"204","47","330","26","#e7ebef",[74,760],{"x":761,"y":762,"width":763,"height":764,"rx":765,"fill":122,"stroke":123,"style":101},"205","48","311.5","24","5",[90,767,770],{"x":768,"y":749,"style":769},"546","font-size:12px;font-weight:700;fill:var(--teal-ink,#0b6157);text-anchor:start","built for it",[74,772],{"x":82,"y":773,"width":742,"height":743,"rx":744,"fill":79,"stroke":745,"style":101},"90",[90,775,42],{"x":748,"y":776,"style":750},"109",[74,778],{"x":754,"y":779,"width":756,"height":757,"rx":744,"fill":758,"stroke":745,"style":101},"91",[74,781],{"x":761,"y":782,"width":783,"height":764,"rx":765,"fill":148,"stroke":149,"style":101},"92","130",[90,785,787],{"x":768,"y":776,"style":786},"font-size:12px;font-weight:700;fill:var(--gold-ink,#7a4e06);text-anchor:start","needs a desktop",[74,789],{"x":82,"y":790,"width":742,"height":743,"rx":744,"fill":79,"stroke":745,"style":101},"134",[90,792,16],{"x":748,"y":793,"style":750},"153",[74,795],{"x":754,"y":796,"width":756,"height":757,"rx":744,"fill":758,"stroke":745,"style":101},"135",[74,798],{"x":761,"y":799,"width":800,"height":764,"rx":765,"fill":801,"stroke":802,"style":101},"136","14.5","#fee8f2","var(--accent,#f43f8f)",[90,804,806],{"x":768,"y":793,"style":805},"font-size:12px;font-weight:700;fill:var(--accent-ink,#be185d);text-anchor:start","needs a person",[90,808,811],{"x":809,"y":810,"style":173},"360","194","scheduling is the clearest dividing line",[176,813,815],{"id":814},"question-2-what-data-can-the-code-reach","Question 2 — What data can the code reach?",[10,817,818,819,822],{},"This is the second hard boundary. Python in Excel sees only what ",[24,820,821],{},"xl()"," can reference: cells, tables, names and Power Query\nresults in the same workbook. It cannot open files, call APIs or query databases directly, and each calculation's data is\ncapped at 100 MB. That sandbox is deliberate — it is why an organisation can allow it at all — and it means external data must\ncome in through Power Query first.",[10,824,825,826,829,830,834],{},"Scripts reach anything the machine can: databases through SQLAlchemy, REST APIs through ",[24,827,828],{},"requests",", cloud storage, other\nworkbooks by the hundred. If the job starts with \"pull yesterday's orders from the warehouse\", a script is the natural fit, as in\n",[49,831,833],{"href":832},"\u002Fadvanced-data-transformation-and-cleaning\u002Fmoving-data-between-excel-and-databases\u002F","Moving Data Between Excel and Databases",".",[176,836,838],{"id":837},"question-3-which-packages-can-you-use","Question 3 — Which packages can you use?",[10,840,841],{},"Python in Excel ships a curated Anaconda-based set with pandas, NumPy, matplotlib, seaborn and statsmodels imported by default and\nmore available to import, but nothing can be installed. Your own internal library, a niche statistics package or a newer release of\nsomething already present is not available. Scripts can use any package the environment can install, pinned to exact versions in a\nrequirements file, which is also what makes their output reproducible six months later.",[176,843,845],{"id":844},"question-4-what-does-the-output-look-like-and-who-can-open-it","Question 4 — What does the output look like, and who can open it?",[10,847,848,849,852],{},"Python in Excel produces results ",[19,850,851],{},"in a live workbook",": values that update when inputs change, and images of charts. Anyone who opens\nthe file in a client without Python in Excel support sees error values instead of results, so a workbook that leaves your team usually\nneeds its results converted to static values first.",[10,854,855,856,859],{},"openpyxl and xlsxwriter produce ",[19,857,858],{},"ordinary files"," that open anywhere — Excel on any platform, LibreOffice, Google Sheets — with native\ncharts, conditional formats and tables that need nothing special to display. xlwings produces the same ordinary files, but because Excel\nitself saved them, formulas are recalculated and connections refreshed, which file-level libraries cannot do.",[55,861,64,867,64,870,64,873,64,877,64,879,64,881,64,887,64,891,64,895,64,898,64,902,64,905,64,909,64,912,64,917,64,919,64,923,64,925,64,928,64,930,64,934,64,936,64,939,64,942,64,946,64,948,64,951,64,953,64,957,64,959,64,962,64,964,64,967,64,970,64,973,64,975,64,978,64,980,64,983,64,985,64,987,64,989,64,991,64,994,64,998,64,1000,64,1003,64,1005,64,1007,64,1009,64,1011,64,1013,64,1015,64,1017,64,1020,64,1022,64,1025,64,1027,64,1030,64,1032,64,1034,64,1036,64,1038,64,1040,64,1043,64,1045,64,1048,64,1050,64,1052,64,1054,64,1056,64,1058,64,1060,64,1063,64,1067,64,1069,64,1072,64,1074,64,1076,64,1078,64,1080,64,1082,64,1085],{"viewBox":862,"role":58,"ariaLabelledBy":863,"xmlns":62,"style":866},"0 0 556 314",[864,865],"pvs-matrix-t","pvs-matrix-d","width:100%;max-width:556px;height:auto;display:block;margin:1.5rem auto;font-family:Inter,ui-sans-serif,system-ui,sans-serif",[66,868,869],{"id":864},"Capabilities of the three approaches",[70,871,872],{"id":865},"A matrix comparing Python in Excel, openpyxl with pandas, and xlwings on scheduling, external data, installing packages, needing Excel installed, recalculating formulas and live interactive analysis.",[74,874],{"x":76,"y":76,"width":875,"height":876,"fill":79},"556","314",[74,878],{"x":82,"y":82,"width":98,"height":737,"rx":76,"fill":758,"stroke":745,"style":101},[74,880],{"x":99,"y":82,"width":84,"height":737,"rx":76,"fill":758,"stroke":745,"style":101},[90,882,886],{"x":883,"y":884,"style":885},"131","40","font-size:11.5px;font-weight:600;fill:var(--muted,#5b6780);text-anchor:middle","A",[74,888],{"x":889,"y":82,"width":890,"height":737,"rx":76,"fill":758,"stroke":745,"style":101},"206","120",[90,892,894],{"x":893,"y":884,"style":885},"266","B",[74,896],{"x":897,"y":82,"width":890,"height":737,"rx":76,"fill":758,"stroke":745,"style":101},"326",[90,899,901],{"x":900,"y":884,"style":885},"386","C",[74,903],{"x":904,"y":82,"width":773,"height":737,"rx":76,"fill":758,"stroke":745,"style":101},"446",[90,906,908],{"x":907,"y":884,"style":885},"491","D",[74,910],{"x":82,"y":911,"width":98,"height":737,"rx":76,"fill":758,"stroke":745,"style":101},"50",[90,913,916],{"x":914,"y":915,"style":885},"38","70","1",[74,918],{"x":99,"y":911,"width":84,"height":737,"rx":76,"fill":758,"stroke":745,"style":101},[90,920,922],{"x":883,"y":915,"style":921},"font-size:11.5px;font-weight:400;fill:var(--muted,#5b6780);text-anchor:middle","capability",[74,924],{"x":889,"y":911,"width":890,"height":737,"rx":76,"fill":86,"stroke":87,"style":101},[90,926,16],{"x":893,"y":915,"style":927},"font-size:11.5px;font-weight:600;fill:var(--brand-strong,#4338ca);text-anchor:middle",[74,929],{"x":897,"y":911,"width":890,"height":737,"rx":76,"fill":122,"stroke":123,"style":101},[90,931,933],{"x":900,"y":915,"style":932},"font-size:11.5px;font-weight:600;fill:var(--teal-ink,#0b6157);text-anchor:middle","openpyxl\u002Fpandas",[74,935],{"x":904,"y":911,"width":773,"height":737,"rx":76,"fill":148,"stroke":149,"style":101},[90,937,42],{"x":907,"y":915,"style":938},"font-size:11.5px;font-weight:600;fill:var(--gold-ink,#7a4e06);text-anchor:middle",[74,940],{"x":82,"y":941,"width":98,"height":737,"rx":76,"fill":758,"stroke":745,"style":101},"80",[90,943,945],{"x":914,"y":944,"style":885},"100","2",[74,947],{"x":99,"y":941,"width":84,"height":737,"rx":76,"fill":79,"stroke":745,"style":101},[90,949,950],{"x":883,"y":944,"style":105},"unattended schedule",[74,952],{"x":889,"y":941,"width":890,"height":737,"rx":76,"fill":801,"stroke":802,"style":101},[90,954,956],{"x":893,"y":944,"style":955},"font-size:11.5px;font-weight:600;fill:var(--accent-ink,#be185d);text-anchor:middle","no",[74,958],{"x":897,"y":941,"width":890,"height":737,"rx":76,"fill":122,"stroke":123,"style":101},[90,960,961],{"x":900,"y":944,"style":932},"yes",[74,963],{"x":904,"y":941,"width":773,"height":737,"rx":76,"fill":148,"stroke":149,"style":101},[90,965,966],{"x":907,"y":944,"style":938},"fragile",[74,968],{"x":82,"y":969,"width":98,"height":737,"rx":76,"fill":758,"stroke":745,"style":101},"110",[90,971,972],{"x":914,"y":783,"style":885},"3",[74,974],{"x":99,"y":969,"width":84,"height":737,"rx":76,"fill":79,"stroke":745,"style":101},[90,976,977],{"x":883,"y":783,"style":105},"files, APIs, databases",[74,979],{"x":889,"y":969,"width":890,"height":737,"rx":76,"fill":148,"stroke":149,"style":101},[90,981,982],{"x":893,"y":783,"style":938},"via Power Query",[74,984],{"x":897,"y":969,"width":890,"height":737,"rx":76,"fill":122,"stroke":123,"style":101},[90,986,961],{"x":900,"y":783,"style":932},[74,988],{"x":904,"y":969,"width":773,"height":737,"rx":76,"fill":122,"stroke":123,"style":101},[90,990,961],{"x":907,"y":783,"style":932},[74,992],{"x":82,"y":993,"width":98,"height":737,"rx":76,"fill":758,"stroke":745,"style":101},"140",[90,995,997],{"x":914,"y":996,"style":885},"160","4",[74,999],{"x":99,"y":993,"width":84,"height":737,"rx":76,"fill":79,"stroke":745,"style":101},[90,1001,1002],{"x":883,"y":996,"style":105},"install any package",[74,1004],{"x":889,"y":993,"width":890,"height":737,"rx":76,"fill":801,"stroke":802,"style":101},[90,1006,956],{"x":893,"y":996,"style":955},[74,1008],{"x":897,"y":993,"width":890,"height":737,"rx":76,"fill":122,"stroke":123,"style":101},[90,1010,961],{"x":900,"y":996,"style":932},[74,1012],{"x":904,"y":993,"width":773,"height":737,"rx":76,"fill":122,"stroke":123,"style":101},[90,1014,961],{"x":907,"y":996,"style":932},[74,1016],{"x":82,"y":742,"width":98,"height":737,"rx":76,"fill":758,"stroke":745,"style":101},[90,1018,765],{"x":914,"y":1019,"style":885},"190",[74,1021],{"x":99,"y":742,"width":84,"height":737,"rx":76,"fill":79,"stroke":745,"style":101},[90,1023,1024],{"x":883,"y":1019,"style":105},"needs Excel installed",[74,1026],{"x":889,"y":742,"width":890,"height":737,"rx":76,"fill":148,"stroke":149,"style":101},[90,1028,1029],{"x":893,"y":1019,"style":938},"Excel 365",[74,1031],{"x":897,"y":742,"width":890,"height":737,"rx":76,"fill":122,"stroke":123,"style":101},[90,1033,956],{"x":900,"y":1019,"style":932},[74,1035],{"x":904,"y":742,"width":773,"height":737,"rx":76,"fill":148,"stroke":149,"style":101},[90,1037,961],{"x":907,"y":1019,"style":938},[74,1039],{"x":82,"y":172,"width":98,"height":737,"rx":76,"fill":758,"stroke":745,"style":101},[90,1041,744],{"x":914,"y":1042,"style":885},"220",[74,1044],{"x":99,"y":172,"width":84,"height":737,"rx":76,"fill":79,"stroke":745,"style":101},[90,1046,1047],{"x":883,"y":1042,"style":105},"recalculate formulas",[74,1049],{"x":889,"y":172,"width":890,"height":737,"rx":76,"fill":122,"stroke":123,"style":101},[90,1051,961],{"x":893,"y":1042,"style":932},[74,1053],{"x":897,"y":172,"width":890,"height":737,"rx":76,"fill":801,"stroke":802,"style":101},[90,1055,956],{"x":900,"y":1042,"style":955},[74,1057],{"x":904,"y":172,"width":773,"height":737,"rx":76,"fill":122,"stroke":123,"style":101},[90,1059,961],{"x":907,"y":1042,"style":932},[74,1061],{"x":82,"y":1062,"width":98,"height":737,"rx":76,"fill":758,"stroke":745,"style":101},"230",[90,1064,1066],{"x":914,"y":1065,"style":885},"250","7",[74,1068],{"x":99,"y":1062,"width":84,"height":737,"rx":76,"fill":79,"stroke":745,"style":101},[90,1070,1071],{"x":883,"y":1065,"style":105},"live analysis in grid",[74,1073],{"x":889,"y":1062,"width":890,"height":737,"rx":76,"fill":122,"stroke":123,"style":101},[90,1075,961],{"x":893,"y":1065,"style":932},[74,1077],{"x":897,"y":1062,"width":890,"height":737,"rx":76,"fill":801,"stroke":802,"style":101},[90,1079,956],{"x":900,"y":1065,"style":955},[74,1081],{"x":904,"y":1062,"width":773,"height":737,"rx":76,"fill":148,"stroke":149,"style":101},[90,1083,1084],{"x":907,"y":1065,"style":938},"partly",[90,1086,1089],{"x":1087,"y":1088,"style":173},"278","292","no column wins every row; the job decides",[176,1091,1093],{"id":1092},"question-5-who-maintains-it","Question 5 — Who maintains it?",[10,1095,1096],{},"A Python in Excel workbook keeps its code next to its data, which is a genuine advantage for an analyst who owns both: there is no separate\nrepository, environment or deployment. It is also a maintenance risk at scale. Code spread across cells is hard to review, has no version\nhistory beyond the file itself, and cannot be unit-tested in place.",[10,1098,1099,1100,1104],{},"A script lives in version control, runs in CI, and can be tested with ordinary tools — the practices in\n",[49,1101,1103],{"href":1102},"\u002Fautomating-reporting-workflows\u002Ftesting-and-packaging-excel-automation-scripts\u002F","Testing and Packaging Excel Automation Scripts",". The cost is\nthat someone has to own an environment. A reasonable rule: if more than one person edits the logic, or if the output feeds a decision someone\nwill be held to, it belongs in a script.",[176,1106,1108],{"id":1107},"combining-them","Combining them",[10,1110,1111,1112,1115,1116,834],{},"The approaches compose well when each does what it is good at. A scheduled pandas script can build a clean, formatted workbook every morning\nfrom the database, and analysts can then add Python in Excel formulas on top for their own exploration, without either side touching the\nother's work. The script can even write its data as an Excel table so that ",[24,1113,1114],{},"xl(\"Sales[#All]\", headers=True)"," picks up every refresh, using the\ntechnique in ",[49,1117,1119],{"href":1118},"\u002Fformatting-and-charting-excel-reports-with-python\u002Fcreating-excel-tables-and-autofilters-with-python\u002Fcreate-an-excel-table-with-python\u002F","Create an Excel Table with Python",[189,1121,1123],{"className":191,"code":1122,"language":193,"meta":194,"style":194},"import pandas as pd\nfrom openpyxl import load_workbook\nfrom openpyxl.worksheet.table import Table, TableStyleInfo\n\ndata = pd.DataFrame({\"Date\": pd.date_range(\"2026-09-01\", periods=4),\n                     \"Region\": [\"North\", \"South\", \"North\", \"West\"],\n                     \"Rep\": [\"Ana\", \"Cara\", \"Ben\", \"Dev\"],\n                     \"Amount\": [1200.0, 950.0, 800.0, 400.0]})\ndata.to_excel(\"analysis_base.xlsx\", sheet_name=\"Data\", index=False)\n\nbook = load_workbook(\"analysis_base.xlsx\")\nsheet = book[\"Data\"]\ntable = Table(displayName=\"Sales\", ref=f\"A1:D{len(data) + 1}\")\ntable.tableStyleInfo = TableStyleInfo(name=\"TableStyleMedium2\", showRowStripes=True)\nsheet.add_table(table)\nbook.save(\"analysis_base.xlsx\")\nprint(\"wrote table Sales with\", len(data), \"rows\")\n",[24,1124,1125,1135,1148,1160,1164,1195,1218,1245,1269,1296,1300,1314,1329,1384,1414,1420,1430],{"__ignoreMap":194},[198,1126,1127,1129,1131,1133],{"class":96,"line":200},[198,1128,288],{"class":207},[198,1130,291],{"class":203},[198,1132,294],{"class":207},[198,1134,297],{"class":203},[198,1136,1137,1140,1143,1145],{"class":96,"line":234},[198,1138,1139],{"class":207},"from",[198,1141,1142],{"class":203}," openpyxl ",[198,1144,288],{"class":207},[198,1146,1147],{"class":203}," load_workbook\n",[198,1149,1150,1152,1155,1157],{"class":96,"line":306},[198,1151,1139],{"class":207},[198,1153,1154],{"class":203}," openpyxl.worksheet.table ",[198,1156,288],{"class":207},[198,1158,1159],{"class":203}," Table, TableStyleInfo\n",[198,1161,1162],{"class":96,"line":312},[198,1163,303],{"emptyLinePlaceholder":302},[198,1165,1166,1169,1171,1174,1177,1180,1183,1185,1188,1190,1192],{"class":96,"line":341},[198,1167,1168],{"class":203},"data ",[198,1170,208],{"class":207},[198,1172,1173],{"class":203}," pd.DataFrame({",[198,1175,1176],{"class":214},"\"Date\"",[198,1178,1179],{"class":203},": pd.date_range(",[198,1181,1182],{"class":214},"\"2026-09-01\"",[198,1184,218],{"class":203},[198,1186,1187],{"class":221},"periods",[198,1189,208],{"class":207},[198,1191,997],{"class":227},[198,1193,1194],{"class":203},"),\n",[198,1196,1197,1200,1202,1204,1206,1208,1210,1212,1214,1216],{"class":96,"line":369},[198,1198,1199],{"class":214},"                     \"Region\"",[198,1201,318],{"class":203},[198,1203,321],{"class":214},[198,1205,218],{"class":203},[198,1207,326],{"class":214},[198,1209,218],{"class":203},[198,1211,321],{"class":214},[198,1213,218],{"class":203},[198,1215,335],{"class":214},[198,1217,338],{"class":203},[198,1219,1220,1223,1225,1228,1230,1233,1235,1238,1240,1243],{"class":96,"line":399},[198,1221,1222],{"class":214},"                     \"Rep\"",[198,1224,318],{"class":203},[198,1226,1227],{"class":214},"\"Ana\"",[198,1229,218],{"class":203},[198,1231,1232],{"class":214},"\"Cara\"",[198,1234,218],{"class":203},[198,1236,1237],{"class":214},"\"Ben\"",[198,1239,218],{"class":203},[198,1241,1242],{"class":214},"\"Dev\"",[198,1244,338],{"class":203},[198,1246,1247,1250,1252,1254,1256,1258,1260,1262,1264,1266],{"class":96,"line":404},[198,1248,1249],{"class":214},"                     \"Amount\"",[198,1251,318],{"class":203},[198,1253,349],{"class":227},[198,1255,218],{"class":203},[198,1257,354],{"class":227},[198,1259,218],{"class":203},[198,1261,359],{"class":227},[198,1263,218],{"class":203},[198,1265,364],{"class":227},[198,1267,1268],{"class":203},"]})\n",[198,1270,1271,1274,1277,1279,1281,1283,1286,1288,1290,1292,1294],{"class":96,"line":426},[198,1272,1273],{"class":203},"data.to_excel(",[198,1275,1276],{"class":214},"\"analysis_base.xlsx\"",[198,1278,218],{"class":203},[198,1280,380],{"class":221},[198,1282,208],{"class":207},[198,1284,1285],{"class":214},"\"Data\"",[198,1287,218],{"class":203},[198,1289,390],{"class":221},[198,1291,208],{"class":207},[198,1293,250],{"class":227},[198,1295,231],{"class":203},[198,1297,1298],{"class":96,"line":465},[198,1299,303],{"emptyLinePlaceholder":302},[198,1301,1302,1305,1307,1310,1312],{"class":96,"line":495},[198,1303,1304],{"class":203},"book ",[198,1306,208],{"class":207},[198,1308,1309],{"class":203}," load_workbook(",[198,1311,1276],{"class":214},[198,1313,231],{"class":203},[198,1315,1316,1319,1321,1324,1326],{"class":96,"line":518},[198,1317,1318],{"class":203},"sheet ",[198,1320,208],{"class":207},[198,1322,1323],{"class":203}," book[",[198,1325,1285],{"class":214},[198,1327,1328],{"class":203},"]\n",[198,1330,1332,1335,1337,1340,1343,1345,1347,1349,1352,1354,1357,1360,1364,1367,1370,1373,1376,1379,1382],{"class":96,"line":1331},13,[198,1333,1334],{"class":203},"table ",[198,1336,208],{"class":207},[198,1338,1339],{"class":203}," Table(",[198,1341,1342],{"class":221},"displayName",[198,1344,208],{"class":207},[198,1346,385],{"class":214},[198,1348,218],{"class":203},[198,1350,1351],{"class":221},"ref",[198,1353,208],{"class":207},[198,1355,1356],{"class":207},"f",[198,1358,1359],{"class":214},"\"A1:D",[198,1361,1363],{"class":1362},"sSjpA","{",[198,1365,1366],{"class":227},"len",[198,1368,1369],{"class":203},"(data) ",[198,1371,1372],{"class":207},"+",[198,1374,1375],{"class":227}," 1",[198,1377,1378],{"class":1362},"}",[198,1380,1381],{"class":214},"\"",[198,1383,231],{"class":203},[198,1385,1387,1390,1392,1395,1398,1400,1403,1405,1408,1410,1412],{"class":96,"line":1386},14,[198,1388,1389],{"class":203},"table.tableStyleInfo ",[198,1391,208],{"class":207},[198,1393,1394],{"class":203}," TableStyleInfo(",[198,1396,1397],{"class":221},"name",[198,1399,208],{"class":207},[198,1401,1402],{"class":214},"\"TableStyleMedium2\"",[198,1404,218],{"class":203},[198,1406,1407],{"class":221},"showRowStripes",[198,1409,208],{"class":207},[198,1411,228],{"class":227},[198,1413,231],{"class":203},[198,1415,1417],{"class":96,"line":1416},15,[198,1418,1419],{"class":203},"sheet.add_table(table)\n",[198,1421,1423,1426,1428],{"class":96,"line":1422},16,[198,1424,1425],{"class":203},"book.save(",[198,1427,1276],{"class":214},[198,1429,231],{"class":203},[198,1431,1433,1435,1438,1441,1443,1445,1448,1451],{"class":96,"line":1432},17,[198,1434,521],{"class":227},[198,1436,1437],{"class":203},"(",[198,1439,1440],{"class":214},"\"wrote table Sales with\"",[198,1442,218],{"class":203},[198,1444,1366],{"class":227},[198,1446,1447],{"class":203},"(data), ",[198,1449,1450],{"class":214},"\"rows\"",[198,1452,231],{"class":203},[10,1454,1455,1456,834],{},"Where xlwings fits into that picture is the narrow set of steps that need Excel itself: refreshing a Power Query connection, recalculating a\nmodel built from Excel formulas, or running a legacy macro — covered in\n",[49,1457,1459],{"href":1458},"\u002Fgetting-started-with-python-excel-automation\u002Fchoosing-a-python-excel-library\u002Fwhen-to-use-xlwings-instead-of-openpyxl\u002F","When to Use xlwings Instead of openpyxl",[176,1461,1463],{"id":1462},"common-pitfalls","Common pitfalls",[1465,1466,1467,1483],"table",{},[1468,1469,1470],"thead",{},[1471,1472,1473,1477,1480],"tr",{},[1474,1475,1476],"th",{},"Mistake",[1474,1478,1479],{},"Why it hurts",[1474,1481,1482],{},"Better choice",[1484,1485,1486,1498,1509,1520,1531],"tbody",{},[1471,1487,1488,1492,1495],{},[1489,1490,1491],"td",{},"Building a nightly report in Python in Excel",[1489,1493,1494],{},"Nothing runs until someone opens the file",[1489,1496,1497],{},"A scheduled pandas or openpyxl script",[1471,1499,1500,1503,1506],{},[1489,1501,1502],{},"Using xlwings on a Linux server",[1489,1504,1505],{},"There is no Excel to drive",[1489,1507,1508],{},"openpyxl or xlsxwriter",[1471,1510,1511,1514,1517],{},[1489,1512,1513],{},"Sharing a =PY workbook with external clients",[1489,1515,1516],{},"Their Excel may show errors instead of results",[1489,1518,1519],{},"Convert results to values, or generate the file with a script",[1471,1521,1522,1525,1528],{},[1489,1523,1524],{},"Reimplementing interactive analysis as a script",[1489,1526,1527],{},"Every question needs a code change and a rerun",[1489,1529,1530],{},"Python in Excel for exploration",[1471,1532,1533,1536,1539],{},[1489,1534,1535],{},"Calling APIs from a =PY cell",[1489,1537,1538],{},"The runtime has no network access",[1489,1540,1541],{},"Power Query, or a script",[176,1543,1545],{"id":1544},"performance-and-scale-notes","Performance and scale notes",[10,1547,1548,1549,1553],{},"Python in Excel round-trips data to the cloud and caps each calculation at 100 MB, so it suits analysis of workbook-sized data rather than\nbulk processing. File-level libraries scale with the machine and with techniques such as streaming writes — see\n",[49,1550,1552],{"href":1551},"\u002Fadvanced-data-transformation-and-cleaning\u002Fworking-with-large-excel-files-in-python\u002F","Working with Large Excel Files in Python",". xlwings is\nbounded by Excel's own speed and by the cost of crossing the process boundary, so it should move data in whole ranges rather than cell by cell.",[176,1555,1557],{"id":1556},"conclusion","Conclusion",[10,1559,1560],{},"Choose by where the work has to happen. Python in Excel is for interactive analysis inside a workbook by the people who use it, with data that\nalready lives there. openpyxl, xlsxwriter and pandas are for scheduled, reproducible file generation that must run without Excel and reach\nexternal systems. xlwings is for the steps that genuinely need the Excel application — recalculation, refresh, macros. Many real setups use two\nof them: a script to produce the data, and in-cell Python for the questions people ask of it.",[176,1562,1564],{"id":1563},"frequently-asked-questions","Frequently asked questions",[10,1566,1567,1570],{},[14,1568,1569],{},"Does Python in Excel replace xlwings?","\nNo. Python in Excel runs code inside cells in the cloud; xlwings controls Excel from a local script. xlwings can automate the application, reach local files and networks, and run on a schedule, none of which Python in Excel does.",[10,1572,1573,1576],{},[14,1574,1575],{},"Can Python in Excel read the files my openpyxl script writes?","\nNot directly from disk. Open the generated workbook and reference its tables with xl(), or load it into another workbook through Power Query and reference the query.",[10,1578,1579,1582],{},[14,1580,1581],{},"Is Python in Excel free?","\nIt is included with eligible Microsoft 365 plans, and Microsoft offers a paid add-on for faster premium compute. Check the current plan list, because availability has widened over time. openpyxl, pandas and xlwings' open-source edition cost nothing but need a Python environment.",[10,1584,1585,1588],{},[14,1586,1587],{},"Which is best for a beginner?","\nFor analysis of data already in a workbook, Python in Excel has the least setup. For automating a recurring report, start with pandas and openpyxl, which teach skills that transfer to every other kind of automation.",[176,1590,1592],{"id":1591},"related","Related",[1594,1595,1596,1603,1610,1615,1622],"ul",{},[1597,1598,1599,1600,1602],"li",{},"Up one level: ",[49,1601,52],{"href":51}," — the full guide to =PY formulas.",[1597,1604,1605,1609],{},[49,1606,1608],{"href":1607},"\u002Fgetting-started-with-python-excel-automation\u002Fchoosing-a-python-excel-library\u002F","Choosing a Python Excel Library"," — the file-level libraries compared with each other.",[1597,1611,1612,1614],{},[49,1613,1459],{"href":1458}," — the case for driving the application.",[1597,1616,1617,1621],{},[49,1618,1620],{"href":1619},"\u002Fgetting-started-with-python-excel-automation\u002Fchoosing-a-python-excel-library\u002Fopenpyxl-vs-pandas-for-excel-automation\u002F","openpyxl vs pandas for Excel Automation"," — the two script-side tools head to head.",[1597,1623,1624,1628],{},[49,1625,1627],{"href":1626},"\u002Fgetting-started-with-python-excel-automation\u002Fusing-python-in-excel\u002Freference-cells-ranges-and-tables-with-xl-in-python-in-excel\u002F","Reference Cells, Ranges and Tables with xl() in Python in Excel"," — the input side of in-cell Python.",[1630,1631,1632],"style",{},"html pre.shiki code .skGVy, html code.shiki .skGVy{--shiki-default:#24292E;--shiki-dark:#F0F3F6}html pre.shiki code .s-kum, html code.shiki .s-kum{--shiki-default:#D73A49;--shiki-dark:#FF9492}html pre.shiki code .srMev, html code.shiki .srMev{--shiki-default:#032F62;--shiki-dark:#ADDCFF}html pre.shiki code .sa561, html code.shiki .sa561{--shiki-default:#E36209;--shiki-dark:#FFB757}html pre.shiki code .sP0c6, html code.shiki .sP0c6{--shiki-default:#005CC5;--shiki-dark:#91CBFF}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 .sSjpA, html code.shiki .sSjpA{--shiki-default:#005CC5;--shiki-dark:#FF9492}",{"title":194,"searchDepth":234,"depth":234,"links":1634},[1635,1636,1637,1638,1639,1640,1641,1642,1643,1644,1645,1646],{"id":178,"depth":234,"text":179},{"id":705,"depth":234,"text":706},{"id":814,"depth":234,"text":815},{"id":837,"depth":234,"text":838},{"id":844,"depth":234,"text":845},{"id":1092,"depth":234,"text":1093},{"id":1107,"depth":234,"text":1108},{"id":1462,"depth":234,"text":1463},{"id":1544,"depth":234,"text":1545},{"id":1556,"depth":234,"text":1557},{"id":1563,"depth":234,"text":1564},{"id":1591,"depth":234,"text":1592},"2026-09-17","Python in Excel runs code inside a cell; openpyxl and pandas write files from a script; xlwings drives the Excel application. Compare where each runs, what it can reach and which jobs it suits.","md",[1651,1653,1655,1657],{"q":1569,"a":1652},"No. Python in Excel runs code inside cells in the cloud; xlwings controls Excel from a local script. xlwings can automate the application, reach local files and networks, and run on a schedule, none of which Python in Excel does.",{"q":1575,"a":1654},"Not directly from disk. Open the generated workbook and reference its tables with xl(), or load it into another workbook through Power Query and reference the query.",{"q":1581,"a":1656},"It is included with eligible Microsoft 365 plans, and Microsoft offers a paid add-on for faster premium compute. Check the current plan list, because availability has widened over time. openpyxl, pandas and xlwings' open-source edition cost nothing but need a Python environment.",{"q":1587,"a":1658},"For analysis of data already in a workbook, Python in Excel has the least setup. For automating a recurring report, start with pandas and openpyxl, which teach skills that transfer to every other kind of automation.","python in excel vs openpyxl and xlwings",null,{"breadcrumb":1662},[1663,1666,1669],{"name":1664,"item":1665},"Home","\u002F",{"name":1667,"item":1668},"Getting Started with Python Excel Automation","\u002Fgetting-started-with-python-excel-automation\u002F",{"name":52,"item":51},"\u002Fgetting-started-with-python-excel-automation\u002Fusing-python-in-excel\u002Fpython-in-excel-vs-openpyxl-and-xlwings",{"title":1672,"description":1673},"Python in Excel vs openpyxl and xlwings: Which to Use","Compare Python in Excel (=PY) with openpyxl, pandas and xlwings: where code runs, data access, scheduling, sharing, packages and cost, with the same report built three ways.","python-in-excel-vs-openpyxl-and-xlwings","getting-started-with-python-excel-automation\u002Fusing-python-in-excel\u002Fpython-in-excel-vs-openpyxl-and-xlwings\u002Findex",[1677,42,1678,1679],"python-in-excel","choosing-libraries","openpyxl","how-to","nGHf5tKknMb-Tyfo9WzO0qJc5LzSIFlPt-SloRKpZSM",[1683,1687],{"title":1684,"path":1685,"stem":1686,"children":-1},"Plot Charts with matplotlib in Python in Excel","\u002Fgetting-started-with-python-excel-automation\u002Fusing-python-in-excel\u002Fplot-charts-with-matplotlib-in-python-in-excel","getting-started-with-python-excel-automation\u002Fusing-python-in-excel\u002Fplot-charts-with-matplotlib-in-python-in-excel\u002Findex",{"title":1627,"path":1688,"stem":1689,"children":-1},"\u002Fgetting-started-with-python-excel-automation\u002Fusing-python-in-excel\u002Freference-cells-ranges-and-tables-with-xl-in-python-in-excel","getting-started-with-python-excel-automation\u002Fusing-python-in-excel\u002Freference-cells-ranges-and-tables-with-xl-in-python-in-excel\u002Findex",[1691,1693],{"path":1692,"title":1667},"\u002Fgetting-started-with-python-excel-automation",{"path":1694,"title":52},"\u002Fgetting-started-with-python-excel-automation\u002Fusing-python-in-excel",[],[1697,1700,1704,1707,1710,1711],{"path":1698,"title":1699,"kind":1680},"\u002Fgetting-started-with-python-excel-automation\u002Fusing-python-in-excel\u002Fclean-data-with-pandas-in-python-in-excel","Clean Data with pandas in Python in Excel",{"path":1701,"title":1702,"kind":1703},"\u002Fgetting-started-with-python-excel-automation\u002Fusing-python-in-excel\u002Ffix-python-in-excel-errors","Fix Python in Excel Errors","fix",{"path":1705,"title":1706,"kind":1680},"\u002Fgetting-started-with-python-excel-automation\u002Fusing-python-in-excel\u002Fforecast-a-time-series-with-python-in-excel","Forecast a Time Series with Python in Excel",{"path":1708,"title":1709,"kind":1680},"\u002Fgetting-started-with-python-excel-automation\u002Fusing-python-in-excel\u002Fget-external-data-into-python-in-excel","Get External Data into Python in Excel with Power Query",{"path":1685,"title":1684,"kind":1680},{"path":1688,"title":1627,"kind":1680},1790972075406]