[{"data":1,"prerenderedAt":2032},["ShallowReactive",2],{"doc:\u002Fgetting-started-with-python-excel-automation\u002Ftroubleshooting-common-python-excel-errors\u002Ffix-formulas-showing-as-text-in-excel-output":3,"surround:\u002Fgetting-started-with-python-excel-automation\u002Ftroubleshooting-common-python-excel-errors\u002Ffix-formulas-showing-as-text-in-excel-output":1996,"ancestors:\u002Fgetting-started-with-python-excel-automation\u002Ftroubleshooting-common-python-excel-errors\u002Ffix-formulas-showing-as-text-in-excel-output":2005,"children:\u002Fgetting-started-with-python-excel-automation\u002Ftroubleshooting-common-python-excel-errors\u002Ffix-formulas-showing-as-text-in-excel-output":2010,"related:\u002Fgetting-started-with-python-excel-automation\u002Ftroubleshooting-common-python-excel-errors\u002Ffix-formulas-showing-as-text-in-excel-output":2011},{"id":4,"title":5,"body":6,"dateModified":1962,"datePublished":1962,"description":1963,"extension":1964,"faq":1965,"keyword":1974,"kind":1975,"meta":1976,"navigation":140,"path":1985,"seo":1986,"slug":1989,"stem":1990,"topics":1991,"type":1994,"__hash__":1995},"docs\u002Fgetting-started-with-python-excel-automation\u002Ftroubleshooting-common-python-excel-errors\u002Ffix-formulas-showing-as-text-in-excel-output\u002Findex.md","Fix Formulas Showing as Text in Excel Output from Python",{"type":7,"value":8,"toc":1949},"minimark",[9,13,24,42,47,76,82,86,112,345,368,483,487,496,671,677,681,703,896,903,1084,1091,1198,1204,1208,1215,1342,1345,1482,1486,1489,1755,1766,1770,1773,1811,1815,1854,1858,1879,1883,1889,1898,1904,1910,1914,1945],[10,11,12],"p",{},"The report opens, and instead of a total the cell shows the formula itself:",[14,15,21],"pre",{"className":16,"code":18,"language":19,"meta":20},[17],"language-text","=SUM(B2:B9)\n","text","",[22,23,18],"code",{"__ignoreMap":20},[10,25,26,27,31,32,35,36,41],{},"Excel shows formula text for one of two reasons: the cell was stored as a ",[28,29,30],"em",{},"string"," that happens to start with ",[22,33,34],{},"=",", or the sheet was saved with Excel's \"Show Formulas\" view switched on. Which one is easy to find out, and each has a short list of causes in Python code. This page diagnoses the file first, then fixes each cause for openpyxl, xlsxwriter and pandas. It is part of ",[37,38,40],"a",{"href":39},"\u002Fgetting-started-with-python-excel-automation\u002Ftroubleshooting-common-python-excel-errors\u002F","Troubleshooting Common Python Excel Errors",".",[43,44,46],"h2",{"id":45},"prerequisites","Prerequisites",[14,48,52],{"className":49,"code":50,"language":51,"meta":20,"style":20},"language-bash shiki shiki-themes github-light github-dark-high-contrast","pip install openpyxl xlsxwriter pandas\n","bash",[22,53,54],{"__ignoreMap":20},[55,56,59,63,67,70,73],"span",{"class":57,"line":58},"line",1,[55,60,62],{"class":61},"sMTad","pip",[55,64,66],{"class":65},"srMev"," install",[55,68,69],{"class":65}," openpyxl",[55,71,72],{"class":65}," xlsxwriter",[55,74,75],{"class":65}," pandas\n",[10,77,78,81],{},[22,79,80],{},"report.xlsx"," is a small report whose total row shows formula text: three formula cells, written by a script that built the formula strings from a template.",[43,83,85],{"id":84},"step-1-is-the-cell-a-formula-or-text","Step 1 — Is the cell a formula or text?",[10,87,88,89,92,93,96,97,100,101,104,105,108,109,111],{},"Inside an ",[22,90,91],{},".xlsx"," file a formula cell carries an ",[22,94,95],{},"\u003Cf>"," element; a text cell carries a string. openpyxl reports the difference as the cell's ",[22,98,99],{},"data_type",": ",[22,102,103],{},"f"," for formula, ",[22,106,107],{},"s"," for string. Check every cell whose value starts with ",[22,110,34],{}," after trimming:",[14,113,117],{"className":114,"code":115,"language":116,"meta":20,"style":20},"language-python shiki shiki-themes github-light github-dark-high-contrast","from openpyxl import load_workbook\n\ndef formula_like_text(path):\n    wb = load_workbook(path)\n    for ws in wb.worksheets:\n        for row in ws.iter_rows():\n            for c in row:\n                if isinstance(c.value, str) and c.value.strip().lstrip(\"'\").startswith(\"=\"):\n                    yield ws.title, c.coordinate, c.data_type, repr(c.value)\n\nfor sheet, cell, kind, value in formula_like_text(\"report.xlsx\"):\n    print(f\"{sheet}!{cell:4} type={kind}  {value}\")\n","python",[22,118,119,135,142,155,166,181,195,209,246,261,266,285],{"__ignoreMap":20},[55,120,121,125,129,132],{"class":57,"line":58},[55,122,124],{"class":123},"s-kum","from",[55,126,128],{"class":127},"skGVy"," openpyxl ",[55,130,131],{"class":123},"import",[55,133,134],{"class":127}," load_workbook\n",[55,136,138],{"class":57,"line":137},2,[55,139,141],{"emptyLinePlaceholder":140},true,"\n",[55,143,145,148,152],{"class":57,"line":144},3,[55,146,147],{"class":123},"def",[55,149,151],{"class":150},"s_Opv"," formula_like_text",[55,153,154],{"class":127},"(path):\n",[55,156,158,161,163],{"class":57,"line":157},4,[55,159,160],{"class":127},"    wb ",[55,162,34],{"class":123},[55,164,165],{"class":127}," load_workbook(path)\n",[55,167,169,172,175,178],{"class":57,"line":168},5,[55,170,171],{"class":123},"    for",[55,173,174],{"class":127}," ws ",[55,176,177],{"class":123},"in",[55,179,180],{"class":127}," wb.worksheets:\n",[55,182,184,187,190,192],{"class":57,"line":183},6,[55,185,186],{"class":123},"        for",[55,188,189],{"class":127}," row ",[55,191,177],{"class":123},[55,193,194],{"class":127}," ws.iter_rows():\n",[55,196,198,201,204,206],{"class":57,"line":197},7,[55,199,200],{"class":123},"            for",[55,202,203],{"class":127}," c ",[55,205,177],{"class":123},[55,207,208],{"class":127}," row:\n",[55,210,212,215,219,222,225,228,231,234,237,240,243],{"class":57,"line":211},8,[55,213,214],{"class":123},"                if",[55,216,218],{"class":217},"sP0c6"," isinstance",[55,220,221],{"class":127},"(c.value, ",[55,223,224],{"class":217},"str",[55,226,227],{"class":127},") ",[55,229,230],{"class":123},"and",[55,232,233],{"class":127}," c.value.strip().lstrip(",[55,235,236],{"class":65},"\"'\"",[55,238,239],{"class":127},").startswith(",[55,241,242],{"class":65},"\"=\"",[55,244,245],{"class":127},"):\n",[55,247,249,252,255,258],{"class":57,"line":248},9,[55,250,251],{"class":123},"                    yield",[55,253,254],{"class":127}," ws.title, c.coordinate, c.data_type, ",[55,256,257],{"class":217},"repr",[55,259,260],{"class":127},"(c.value)\n",[55,262,264],{"class":57,"line":263},10,[55,265,141],{"emptyLinePlaceholder":140},[55,267,269,272,275,277,280,283],{"class":57,"line":268},11,[55,270,271],{"class":123},"for",[55,273,274],{"class":127}," sheet, cell, kind, value ",[55,276,177],{"class":123},[55,278,279],{"class":127}," formula_like_text(",[55,281,282],{"class":65},"\"report.xlsx\"",[55,284,245],{"class":127},[55,286,288,291,294,296,299,303,306,309,312,314,317,320,322,325,327,330,332,335,338,340,342],{"class":57,"line":287},12,[55,289,290],{"class":217},"    print",[55,292,293],{"class":127},"(",[55,295,103],{"class":123},[55,297,298],{"class":65},"\"",[55,300,302],{"class":301},"sSjpA","{",[55,304,305],{"class":127},"sheet",[55,307,308],{"class":301},"}",[55,310,311],{"class":65},"!",[55,313,302],{"class":301},[55,315,316],{"class":127},"cell",[55,318,319],{"class":123},":4",[55,321,308],{"class":301},[55,323,324],{"class":65}," type=",[55,326,302],{"class":301},[55,328,329],{"class":127},"kind",[55,331,308],{"class":301},[55,333,334],{"class":301},"  {",[55,336,337],{"class":127},"value",[55,339,308],{"class":301},[55,341,298],{"class":65},[55,343,344],{"class":127},")\n",[10,346,347,350,351,353,354,357,358,361,362,364,365,367],{},[22,348,349],{},"B8"," is a real formula (",[22,352,103],{},"). ",[22,355,356],{},"B6"," and ",[22,359,360],{},"B7"," are strings (",[22,363,107],{},"): one starts with a space, the other with an apostrophe. Excel displays both exactly as stored, text and all. If every cell reports ",[22,366,103],{}," but Excel still shows formulas, skip to Step 4.",[369,370,378,379,378,383,378,387,378,395,378,404,378,410,378,414,378,418,378,422,378,426,378,431,378,435,378,437,378,440,378,444,378,448,378,451,378,454,378,456,378,459,378,461,378,464,378,467,378,470,378,472,378,475,378,479],"svg",{"viewBox":371,"role":372,"ariaLabelledBy":373,"xmlns":376,"style":377},"171 0 417 144","img",[374,375],"ft-cells-t","ft-cells-d","http:\u002F\u002Fwww.w3.org\u002F2000\u002Fsvg","width:100%;max-width:417px;height:auto;display:block;margin:1.5rem auto;font-family:Inter,ui-sans-serif,system-ui,sans-serif","\n  ",[380,381,382],"title",{"id":374},"What the three cells contain",[384,385,386],"desc",{"id":375},"A table of the three total-row cells. B6 holds a string starting with a space and shows as text. B7 holds a string starting with an apostrophe and shows as text including the apostrophe. B8 holds a real formula and shows the result.",[388,389],"rect",{"x":390,"y":391,"width":392,"height":393,"fill":394},"171","0","417","144","#ffffff",[388,396],{"x":397,"y":398,"width":399,"height":400,"rx":391,"fill":401,"stroke":402,"style":403},"187.7","16.0","45.7","28.0","#f0f4ff","var(--brand,#5b5cf0)","stroke-width:1.5px",[19,405,409],{"x":406,"y":407,"style":408},"210.5","35.0","font-size:11px;font-weight:700;fill:var(--brand-strong,#4338ca);text-anchor:middle","Cell",[388,411],{"x":412,"y":398,"width":413,"height":400,"rx":391,"fill":401,"stroke":402,"style":403},"233.4","204.1",[19,415,417],{"x":416,"y":407,"style":408},"335.4","Stored as",[388,419],{"x":420,"y":398,"width":421,"height":400,"rx":391,"fill":401,"stroke":402,"style":403},"437.5","134.9",[19,423,425],{"x":424,"y":407,"style":408},"504.9","Excel shows",[388,427],{"x":397,"y":428,"width":399,"height":400,"rx":391,"fill":394,"stroke":429,"style":430},"44.0","var(--line,#cdd5e6)","stroke-width:1px",[19,432,356],{"x":406,"y":433,"style":434},"63.0","font-size:11px;font-weight:400;fill:var(--text,#172033);text-anchor:middle",[388,436],{"x":412,"y":428,"width":413,"height":400,"rx":391,"fill":394,"stroke":429,"style":430},[19,438,439],{"x":416,"y":433,"style":434},"text starting with a space",[388,441],{"x":420,"y":428,"width":421,"height":400,"rx":391,"fill":442,"stroke":443,"style":403},"#fce9e9","var(--danger,#dc2626)",[19,445,447],{"x":424,"y":433,"style":446},"font-size:11px;font-weight:700;fill:var(--accent-ink,#be185d);text-anchor:middle","formula text",[388,449],{"x":397,"y":450,"width":399,"height":400,"rx":391,"fill":394,"stroke":429,"style":430},"72.0",[19,452,360],{"x":406,"y":453,"style":434},"91.0",[388,455],{"x":412,"y":450,"width":413,"height":400,"rx":391,"fill":394,"stroke":429,"style":430},[19,457,458],{"x":416,"y":453,"style":434},"text starting with an apostrophe",[388,460],{"x":420,"y":450,"width":421,"height":400,"rx":391,"fill":442,"stroke":443,"style":403},[19,462,463],{"x":424,"y":453,"style":446},"'=AVERAGE(B2:B4)",[388,465],{"x":397,"y":466,"width":399,"height":400,"rx":391,"fill":394,"stroke":429,"style":430},"100.0",[19,468,349],{"x":406,"y":469,"style":434},"119.0",[388,471],{"x":412,"y":466,"width":413,"height":400,"rx":391,"fill":394,"stroke":429,"style":430},[19,473,474],{"x":416,"y":469,"style":434},"formula MAX(B2:B4)",[388,476],{"x":420,"y":466,"width":421,"height":400,"rx":391,"fill":477,"stroke":478,"style":403},"#d9f4f1","var(--teal,#0f9488)",[19,480,482],{"x":424,"y":469,"style":481},"font-size:11px;font-weight:700;fill:var(--teal-ink,#0b6157);text-anchor:middle","14,300",[43,484,486],{"id":485},"cause-1-a-character-before-the-equals-sign","Cause 1 — A character before the equals sign",[10,488,489,490,492,493,495],{},"openpyxl treats a string as a formula only if its first character is ",[22,491,34],{},". A leading space, a non-breaking space, or an apostrophe copied from a spreadsheet makes it text. The apostrophe is worse than it looks: in Excel a typed apostrophe is a hidden \"treat as text\" marker, but written from Python it is part of the value, so the cell shows ",[22,494,463],{}," including the quote. Clean formula strings before writing them:",[14,497,499],{"className":114,"code":498,"language":116,"meta":20,"style":20},"def as_formula(text):\n    cleaned = text.replace(\" \", \" \").strip().lstrip(\"'\")\n    if not cleaned.startswith(\"=\"):\n        raise ValueError(f\"not a formula: {text!r}\")\n    return cleaned\n\nwb = load_workbook(\"report.xlsx\")\nws = wb[\"Report\"]\nfor coord in (\"B6\", \"B7\"):\n    ws[coord] = as_formula(ws[coord].value)\n    print(coord, ws[coord].data_type, ws[coord].value)\nwb.save(\"report_fixed.xlsx\")\n",[22,500,501,511,537,552,580,588,592,606,622,644,654,661],{"__ignoreMap":20},[55,502,503,505,508],{"class":57,"line":58},[55,504,147],{"class":123},[55,506,507],{"class":150}," as_formula",[55,509,510],{"class":127},"(text):\n",[55,512,513,516,518,521,524,527,530,533,535],{"class":57,"line":137},[55,514,515],{"class":127},"    cleaned ",[55,517,34],{"class":123},[55,519,520],{"class":127}," text.replace(",[55,522,523],{"class":65},"\" \"",[55,525,526],{"class":127},", ",[55,528,529],{"class":65},"\" \"",[55,531,532],{"class":127},").strip().lstrip(",[55,534,236],{"class":65},[55,536,344],{"class":127},[55,538,539,542,545,548,550],{"class":57,"line":144},[55,540,541],{"class":123},"    if",[55,543,544],{"class":123}," not",[55,546,547],{"class":127}," cleaned.startswith(",[55,549,242],{"class":65},[55,551,245],{"class":127},[55,553,554,557,560,562,564,567,569,571,574,576,578],{"class":57,"line":157},[55,555,556],{"class":123},"        raise",[55,558,559],{"class":217}," ValueError",[55,561,293],{"class":127},[55,563,103],{"class":123},[55,565,566],{"class":65},"\"not a formula: ",[55,568,302],{"class":301},[55,570,19],{"class":127},[55,572,573],{"class":123},"!r",[55,575,308],{"class":301},[55,577,298],{"class":65},[55,579,344],{"class":127},[55,581,582,585],{"class":57,"line":168},[55,583,584],{"class":123},"    return",[55,586,587],{"class":127}," cleaned\n",[55,589,590],{"class":57,"line":183},[55,591,141],{"emptyLinePlaceholder":140},[55,593,594,597,599,602,604],{"class":57,"line":197},[55,595,596],{"class":127},"wb ",[55,598,34],{"class":123},[55,600,601],{"class":127}," load_workbook(",[55,603,282],{"class":65},[55,605,344],{"class":127},[55,607,608,611,613,616,619],{"class":57,"line":211},[55,609,610],{"class":127},"ws ",[55,612,34],{"class":123},[55,614,615],{"class":127}," wb[",[55,617,618],{"class":65},"\"Report\"",[55,620,621],{"class":127},"]\n",[55,623,624,626,629,631,634,637,639,642],{"class":57,"line":248},[55,625,271],{"class":123},[55,627,628],{"class":127}," coord ",[55,630,177],{"class":123},[55,632,633],{"class":127}," (",[55,635,636],{"class":65},"\"B6\"",[55,638,526],{"class":127},[55,640,641],{"class":65},"\"B7\"",[55,643,245],{"class":127},[55,645,646,649,651],{"class":57,"line":263},[55,647,648],{"class":127},"    ws[coord] ",[55,650,34],{"class":123},[55,652,653],{"class":127}," as_formula(ws[coord].value)\n",[55,655,656,658],{"class":57,"line":268},[55,657,290],{"class":217},[55,659,660],{"class":127},"(coord, ws[coord].data_type, ws[coord].value)\n",[55,662,663,666,669],{"class":57,"line":287},[55,664,665],{"class":127},"wb.save(",[55,667,668],{"class":65},"\"report_fixed.xlsx\"",[55,670,344],{"class":127},[10,672,673,674,676],{},"Templates are the usual source: formula strings kept in a config file, a CSV or another sheet pick up spaces and quotes along the way. A formula pasted into a CSV or a YAML file by hand keeps whatever came with it, including a leading space from indentation or a quote character from the editor, and nothing looks wrong until the report opens. Clean them where they are loaded, and raise on anything that does not start with ",[22,675,34],{}," after cleaning, so a broken template stops the run instead of producing a report full of text.",[43,678,680],{"id":679},"cause-2-the-writer-was-told-not-to-make-formulas","Cause 2 — The writer was told not to make formulas",[10,682,683,684,687,688,690,691,693,694,698,699,702],{},"xlsxwriter's ",[22,685,686],{},"write()"," turns strings starting with ",[22,689,34],{}," into formulas by default, and pandas passes DataFrame strings through ",[22,692,686],{},". Code that guards against ",[37,695,697],{"href":696},"\u002Fautomating-reporting-workflows\u002Ferror-handling-and-logging-in-excel-automation\u002Fprevent-formula-injection-in-excel-exports\u002F","formula injection"," often switches that off with the ",[22,700,701],{},"strings_to_formulas"," option, and then the report's own formula columns come out as text too. Compare the stored cell type:",[14,704,706],{"className":114,"code":705,"language":116,"meta":20,"style":20},"import pandas as pd\n\ndf = pd.DataFrame({\"Sales\": [12500, 9800], \"Double\": [\"=A2*2\", \"=A3*2\"]})\ndf.to_excel(\"default.xlsx\", index=False, engine=\"xlsxwriter\")\nwith pd.ExcelWriter(\"no_formulas.xlsx\", engine=\"xlsxwriter\",\n                    engine_kwargs={\"options\": {\"strings_to_formulas\": False}}) as writer:\n    df.to_excel(writer, index=False)\nfor path in (\"default.xlsx\", \"no_formulas.xlsx\"):\n    print(path, load_workbook(path).active[\"B2\"].data_type)\n",[22,707,708,721,725,768,799,821,851,864,883],{"__ignoreMap":20},[55,709,710,712,715,718],{"class":57,"line":58},[55,711,131],{"class":123},[55,713,714],{"class":127}," pandas ",[55,716,717],{"class":123},"as",[55,719,720],{"class":127}," pd\n",[55,722,723],{"class":57,"line":137},[55,724,141],{"emptyLinePlaceholder":140},[55,726,727,730,732,735,738,741,744,746,749,752,755,757,760,762,765],{"class":57,"line":144},[55,728,729],{"class":127},"df ",[55,731,34],{"class":123},[55,733,734],{"class":127}," pd.DataFrame({",[55,736,737],{"class":65},"\"Sales\"",[55,739,740],{"class":127},": [",[55,742,743],{"class":217},"12500",[55,745,526],{"class":127},[55,747,748],{"class":217},"9800",[55,750,751],{"class":127},"], ",[55,753,754],{"class":65},"\"Double\"",[55,756,740],{"class":127},[55,758,759],{"class":65},"\"=A2*2\"",[55,761,526],{"class":127},[55,763,764],{"class":65},"\"=A3*2\"",[55,766,767],{"class":127},"]})\n",[55,769,770,773,776,778,782,784,787,789,792,794,797],{"class":57,"line":157},[55,771,772],{"class":127},"df.to_excel(",[55,774,775],{"class":65},"\"default.xlsx\"",[55,777,526],{"class":127},[55,779,781],{"class":780},"sa561","index",[55,783,34],{"class":123},[55,785,786],{"class":217},"False",[55,788,526],{"class":127},[55,790,791],{"class":780},"engine",[55,793,34],{"class":123},[55,795,796],{"class":65},"\"xlsxwriter\"",[55,798,344],{"class":127},[55,800,801,804,807,810,812,814,816,818],{"class":57,"line":168},[55,802,803],{"class":123},"with",[55,805,806],{"class":127}," pd.ExcelWriter(",[55,808,809],{"class":65},"\"no_formulas.xlsx\"",[55,811,526],{"class":127},[55,813,791],{"class":780},[55,815,34],{"class":123},[55,817,796],{"class":65},[55,819,820],{"class":127},",\n",[55,822,823,826,828,830,833,836,839,841,843,846,848],{"class":57,"line":183},[55,824,825],{"class":780},"                    engine_kwargs",[55,827,34],{"class":123},[55,829,302],{"class":127},[55,831,832],{"class":65},"\"options\"",[55,834,835],{"class":127},": {",[55,837,838],{"class":65},"\"strings_to_formulas\"",[55,840,100],{"class":127},[55,842,786],{"class":217},[55,844,845],{"class":127},"}}) ",[55,847,717],{"class":123},[55,849,850],{"class":127}," writer:\n",[55,852,853,856,858,860,862],{"class":57,"line":197},[55,854,855],{"class":127},"    df.to_excel(writer, ",[55,857,781],{"class":780},[55,859,34],{"class":123},[55,861,786],{"class":217},[55,863,344],{"class":127},[55,865,866,868,871,873,875,877,879,881],{"class":57,"line":211},[55,867,271],{"class":123},[55,869,870],{"class":127}," path ",[55,872,177],{"class":123},[55,874,633],{"class":127},[55,876,775],{"class":65},[55,878,526],{"class":127},[55,880,809],{"class":65},[55,882,245],{"class":127},[55,884,885,887,890,893],{"class":57,"line":248},[55,886,290],{"class":217},[55,888,889],{"class":127},"(path, load_workbook(path).active[",[55,891,892],{"class":65},"\"B2\"",[55,894,895],{"class":127},"].data_type)\n",[10,897,898,899,902],{},"Keep the protection for data and write the formulas you intend explicitly with ",[22,900,901],{},"write_formula",", which ignores the option:",[14,904,906],{"className":114,"code":905,"language":116,"meta":20,"style":20},"with pd.ExcelWriter(\"safe_and_working.xlsx\", engine=\"xlsxwriter\",\n                    engine_kwargs={\"options\": {\"strings_to_formulas\": False}}) as writer:\n    df[[\"Sales\"]].to_excel(writer, index=False)\n    ws = writer.sheets[\"Sheet1\"]\n    ws.write(\"B1\", \"Double\")\n    for row in range(2, len(df) + 2):\n        ws.write_formula(f\"B{row}\", f\"=A{row}*2\")\nprint(load_workbook(\"safe_and_working.xlsx\").active[\"B2\"].data_type)\n",[22,907,908,927,951,969,984,998,1030,1067],{"__ignoreMap":20},[55,909,910,912,914,917,919,921,923,925],{"class":57,"line":58},[55,911,803],{"class":123},[55,913,806],{"class":127},[55,915,916],{"class":65},"\"safe_and_working.xlsx\"",[55,918,526],{"class":127},[55,920,791],{"class":780},[55,922,34],{"class":123},[55,924,796],{"class":65},[55,926,820],{"class":127},[55,928,929,931,933,935,937,939,941,943,945,947,949],{"class":57,"line":137},[55,930,825],{"class":780},[55,932,34],{"class":123},[55,934,302],{"class":127},[55,936,832],{"class":65},[55,938,835],{"class":127},[55,940,838],{"class":65},[55,942,100],{"class":127},[55,944,786],{"class":217},[55,946,845],{"class":127},[55,948,717],{"class":123},[55,950,850],{"class":127},[55,952,953,956,958,961,963,965,967],{"class":57,"line":144},[55,954,955],{"class":127},"    df[[",[55,957,737],{"class":65},[55,959,960],{"class":127},"]].to_excel(writer, ",[55,962,781],{"class":780},[55,964,34],{"class":123},[55,966,786],{"class":217},[55,968,344],{"class":127},[55,970,971,974,976,979,982],{"class":57,"line":157},[55,972,973],{"class":127},"    ws ",[55,975,34],{"class":123},[55,977,978],{"class":127}," writer.sheets[",[55,980,981],{"class":65},"\"Sheet1\"",[55,983,621],{"class":127},[55,985,986,989,992,994,996],{"class":57,"line":168},[55,987,988],{"class":127},"    ws.write(",[55,990,991],{"class":65},"\"B1\"",[55,993,526],{"class":127},[55,995,754],{"class":65},[55,997,344],{"class":127},[55,999,1000,1002,1004,1006,1009,1011,1014,1016,1019,1022,1025,1028],{"class":57,"line":183},[55,1001,171],{"class":123},[55,1003,189],{"class":127},[55,1005,177],{"class":123},[55,1007,1008],{"class":217}," range",[55,1010,293],{"class":127},[55,1012,1013],{"class":217},"2",[55,1015,526],{"class":127},[55,1017,1018],{"class":217},"len",[55,1020,1021],{"class":127},"(df) ",[55,1023,1024],{"class":123},"+",[55,1026,1027],{"class":217}," 2",[55,1029,245],{"class":127},[55,1031,1032,1035,1037,1040,1042,1045,1047,1049,1051,1053,1056,1058,1060,1062,1065],{"class":57,"line":197},[55,1033,1034],{"class":127},"        ws.write_formula(",[55,1036,103],{"class":123},[55,1038,1039],{"class":65},"\"B",[55,1041,302],{"class":301},[55,1043,1044],{"class":127},"row",[55,1046,308],{"class":301},[55,1048,298],{"class":65},[55,1050,526],{"class":127},[55,1052,103],{"class":123},[55,1054,1055],{"class":65},"\"=A",[55,1057,302],{"class":301},[55,1059,1044],{"class":127},[55,1061,308],{"class":301},[55,1063,1064],{"class":65},"*2\"",[55,1066,344],{"class":127},[55,1068,1069,1072,1075,1077,1080,1082],{"class":57,"line":211},[55,1070,1071],{"class":217},"print",[55,1073,1074],{"class":127},"(load_workbook(",[55,1076,916],{"class":65},[55,1078,1079],{"class":127},").active[",[55,1081,892],{"class":65},[55,1083,895],{"class":127},[10,1085,1086,1087,1090],{},"The same applies to ",[22,1088,1089],{},"write_string()",", which always writes text: use it for data, never for formulas.",[369,1092,378,1098,378,1101,378,1104,378,1109,378,1116,378,1127,378,1133,378,1137,378,1142,378,1146,378,1151,378,1158,378,1163,378,1167,378,1170,378,1173,378,1176,378,1183,378,1188,378,1192,378,1195],{"viewBox":1093,"role":372,"ariaLabelledBy":1094,"xmlns":376,"style":1097},"4 0 752 181",[1095,1096],"ft-routes-t","ft-routes-d","width:100%;max-width:752px;height:auto;display:block;margin:1.5rem auto;font-family:Inter,ui-sans-serif,system-ui,sans-serif",[380,1099,1100],{"id":1095},"Which xlsxwriter call writes what",[384,1102,1103],{"id":1096},"Three panels. write() with the default options turns a string starting with an equals sign into a formula. write() with strings_to_formulas False, and write_string() in every case, store it as text. write_formula() always stores a formula, whatever the options.",[388,1105],{"x":1106,"y":391,"width":1107,"height":1108,"fill":394},"4","752","181",[388,1110],{"x":1111,"y":398,"width":1112,"height":1113,"rx":1114,"fill":477,"stroke":478,"style":1115},"20.0","228.0","149.0","14","stroke-width:2px",[1117,1118,1120],"g",{"transform":1119},"translate(121.0,29.0) scale(1.083)",[1121,1122],"path",{"d":1123,"fill":1124,"stroke":1125,"style":1126},"M9 8l-4 4 4 4 M15 8l4 4-4 4","none","var(--teal-ink,#0b6157)","stroke-width:1.66px;stroke-linecap:round;stroke-linejoin:round",[19,1128,1132],{"x":1129,"y":1130,"style":1131},"134.0","78.0","font-size:14px;font-weight:700;fill:var(--teal-ink,#0b6157);text-anchor:middle","write(), default",[57,1134],{"x1":1135,"y1":453,"x2":1136,"y2":453,"stroke":478,"style":430},"36.0","232.0",[19,1138,1141],{"x":1129,"y":1139,"style":1140},"111.0","font-size:12px;font-weight:400;fill:var(--text,#172033);text-anchor:middle","'=A2*2' becomes a formula",[19,1143,1145],{"x":1129,"y":1144,"style":1140},"137.0","also for user data",[388,1147],{"x":1148,"y":398,"width":1112,"height":1113,"rx":1114,"fill":1149,"stroke":1150,"style":1115},"266.0","#fdefd8","var(--gold,#b4740a)",[1117,1152,1154],{"transform":1153},"translate(367.0,29.0) scale(1.083)",[1121,1155],{"d":1156,"fill":1124,"stroke":1157,"style":1126},"M6 3h9l4 4v14H6z M15 3v4h4","var(--gold-ink,#7a4e06)",[19,1159,1162],{"x":1160,"y":1130,"style":1161},"380.0","font-size:14px;font-weight:700;fill:var(--gold-ink,#7a4e06);text-anchor:middle","write_string() \u002F option off",[57,1164],{"x1":1165,"y1":453,"x2":1166,"y2":453,"stroke":1150,"style":430},"282.0","478.0",[19,1168,1169],{"x":1160,"y":1139,"style":1140},"'=A2*2' stays text",[19,1171,1172],{"x":1160,"y":1144,"style":1140},"safe for user data",[388,1174],{"x":1175,"y":398,"width":1112,"height":1113,"rx":1114,"fill":401,"stroke":402,"style":1115},"512.0",[1117,1177,1179],{"transform":1178},"translate(613.0,29.0) scale(1.083)",[1121,1180],{"d":1181,"fill":1124,"stroke":1182,"style":1126},"M5 12.5l4.5 4.5L19 7","var(--brand-strong,#4338ca)",[19,1184,1187],{"x":1185,"y":1130,"style":1186},"626.0","font-size:14px;font-weight:700;fill:var(--brand-strong,#4338ca);text-anchor:middle","write_formula()",[57,1189],{"x1":1190,"y1":453,"x2":1191,"y2":453,"stroke":402,"style":430},"528.0","724.0",[19,1193,1194],{"x":1185,"y":1139,"style":1140},"always a formula",[19,1196,1197],{"x":1185,"y":1144,"style":1140},"use for intended formulas",[10,1199,1200,1201,1203],{},"The combination that works for most reports is the middle and right panels together: every value that came from data goes through a path that cannot create formulas, and every formula the report means to contain is written with ",[22,1202,901],{},", so it is obvious in the code which cells calculate.",[43,1205,1207],{"id":1206},"cause-3-show-formulas-is-switched-on","Cause 3 — Show Formulas is switched on",[10,1209,1210,1211,1214],{},"If every cell is a real formula and Excel still shows formula text everywhere, the sheet was saved with the \"Show Formulas\" view on, the button of that name on Excel's Formulas tab. The setting is stored per sheet, so a template saved in that state passes it to every report built from it. openpyxl exposes it as ",[22,1212,1213],{},"sheet_view.showFormulas",":",[14,1216,1218],{"className":114,"code":1217,"language":116,"meta":20,"style":20},"tpl = load_workbook(\"report_fixed.xlsx\")\ntpl[\"Report\"].sheet_view.showFormulas = True        # what a template saved in this mode contains\ntpl.save(\"template_show_formulas.xlsx\")\n\nwb = load_workbook(\"template_show_formulas.xlsx\")\nfor ws in wb.worksheets:\n    print(ws.title, \"showFormulas:\", ws.sheet_view.showFormulas)\n    ws.sheet_view.showFormulas = False\nwb.save(\"template_fixed.xlsx\")\nprint(\"after:\", load_workbook(\"template_fixed.xlsx\")[\"Report\"].sheet_view.showFormulas)\n",[22,1219,1220,1233,1252,1262,1266,1278,1288,1301,1311,1320],{"__ignoreMap":20},[55,1221,1222,1225,1227,1229,1231],{"class":57,"line":58},[55,1223,1224],{"class":127},"tpl ",[55,1226,34],{"class":123},[55,1228,601],{"class":127},[55,1230,668],{"class":65},[55,1232,344],{"class":127},[55,1234,1235,1238,1240,1243,1245,1248],{"class":57,"line":137},[55,1236,1237],{"class":127},"tpl[",[55,1239,618],{"class":65},[55,1241,1242],{"class":127},"].sheet_view.showFormulas ",[55,1244,34],{"class":123},[55,1246,1247],{"class":217}," True",[55,1249,1251],{"class":1250},"s-wDw","        # what a template saved in this mode contains\n",[55,1253,1254,1257,1260],{"class":57,"line":144},[55,1255,1256],{"class":127},"tpl.save(",[55,1258,1259],{"class":65},"\"template_show_formulas.xlsx\"",[55,1261,344],{"class":127},[55,1263,1264],{"class":57,"line":157},[55,1265,141],{"emptyLinePlaceholder":140},[55,1267,1268,1270,1272,1274,1276],{"class":57,"line":168},[55,1269,596],{"class":127},[55,1271,34],{"class":123},[55,1273,601],{"class":127},[55,1275,1259],{"class":65},[55,1277,344],{"class":127},[55,1279,1280,1282,1284,1286],{"class":57,"line":183},[55,1281,271],{"class":123},[55,1283,174],{"class":127},[55,1285,177],{"class":123},[55,1287,180],{"class":127},[55,1289,1290,1292,1295,1298],{"class":57,"line":197},[55,1291,290],{"class":217},[55,1293,1294],{"class":127},"(ws.title, ",[55,1296,1297],{"class":65},"\"showFormulas:\"",[55,1299,1300],{"class":127},", ws.sheet_view.showFormulas)\n",[55,1302,1303,1306,1308],{"class":57,"line":211},[55,1304,1305],{"class":127},"    ws.sheet_view.showFormulas ",[55,1307,34],{"class":123},[55,1309,1310],{"class":217}," False\n",[55,1312,1313,1315,1318],{"class":57,"line":248},[55,1314,665],{"class":127},[55,1316,1317],{"class":65},"\"template_fixed.xlsx\"",[55,1319,344],{"class":127},[55,1321,1322,1324,1326,1329,1332,1334,1337,1339],{"class":57,"line":263},[55,1323,1071],{"class":217},[55,1325,293],{"class":127},[55,1327,1328],{"class":65},"\"after:\"",[55,1330,1331],{"class":127},", load_workbook(",[55,1333,1317],{"class":65},[55,1335,1336],{"class":127},")[",[55,1338,618],{"class":65},[55,1340,1341],{"class":127},"].sheet_view.showFormulas)\n",[10,1343,1344],{},"This one is also visible in Excel: the columns become wider and every formula in the sheet shows as text, not just the ones your script wrote.",[369,1346,378,1351,378,1354,378,1357,378,1360,378,1366,378,1373,378,1377,378,1381,378,1385,378,1388,378,1393,378,1401,378,1406,378,1411,378,1417,378,1422,378,1427,378,1429,378,1432,378,1436,378,1439,378,1442,378,1448,378,1452,378,1455,378,1457,378,1460,378,1464,378,1467,378,1470,378,1476,378,1479],{"viewBox":1347,"role":372,"ariaLabelledBy":1348,"xmlns":376,"style":1097},"4 0 752 272",[1349,1350],"ft-diagnose-t","ft-diagnose-d",[380,1352,1353],{"id":1349},"Diagnosing formula text",[384,1355,1356],{"id":1350},"A decision diagram. If the cell's data type is string, look for a character before the equals sign or a writer that writes strings as text. If the data type is formula and every formula in the sheet shows as text, the sheet has Show Formulas switched on. If the formula shows",[388,1358],{"x":1106,"y":391,"width":1107,"height":1359,"fill":394},"272",[388,1361],{"x":1362,"y":398,"width":1363,"height":1364,"rx":1365,"fill":401,"stroke":402,"style":1115},"240.0","280.0","75.5","12",[1117,1367,1369],{"transform":1368},"translate(368.0,29.0) scale(1.000)",[1121,1370],{"d":1371,"fill":1124,"stroke":1182,"style":1372},"M11 4a7 7 0 1 0 .01 0z M16 16l5 5","stroke-width:1.80px;stroke-linecap:round;stroke-linejoin:round",[19,1374,1376],{"x":1160,"y":1364,"style":1375},"font-size:13.5px;font-weight:700;fill:var(--brand-strong,#4338ca);text-anchor:middle","What does openpyxl report?",[57,1378],{"x1":1160,"y1":1379,"x2":1160,"y2":1380,"stroke":402,"style":1115},"91.5","111.5",[57,1382],{"x1":1383,"y1":1380,"x2":1384,"y2":1380,"stroke":402,"style":1115},"134.7","625.3",[57,1386],{"x1":1383,"y1":1380,"x2":1383,"y2":1387,"stroke":402,"style":1115},"157.5",[1389,1390],"polygon",{"points":1391,"fill":1392},"134.7,161.5 129.7,152.5 139.7,152.5","#5b5cf0",[388,1394],{"x":1395,"y":1396,"width":1397,"height":1398,"rx":1399,"fill":394,"stroke":429,"style":1400},"87.6","121.5","94.1","21.0","10","stroke-width:1.2px",[19,1402,1405],{"x":1383,"y":1403,"style":1404},"136.0","font-size:11.5px;font-weight:700;fill:var(--muted,#5b6780);text-anchor:middle","data_type 's'",[388,1407],{"x":1111,"y":1408,"width":1409,"height":1410,"rx":1365,"fill":442,"stroke":443,"style":1115},"163.5","229.3","93.0",[1117,1412,1414],{"transform":1413},"translate(122.7,176.5) scale(1.000)",[1121,1415],{"d":1156,"fill":1124,"stroke":1416,"style":1372},"var(--accent-ink,#be185d)",[19,1418,1421],{"x":1383,"y":1419,"style":1420},"223.0","font-size:13.5px;font-weight:700;fill:var(--accent-ink,#be185d);text-anchor:middle","Stored as text",[19,1423,1426],{"x":1383,"y":1424,"style":1425},"242.5","font-size:11.5px;font-weight:400;fill:var(--text,#172033);text-anchor:middle","Causes 1 and 2",[57,1428],{"x1":1160,"y1":1380,"x2":1160,"y2":1387,"stroke":402,"style":1115},[1389,1430],{"points":1431,"fill":1392},"380.0,161.5 375.0,152.5 385.0,152.5",[388,1433],{"x":1434,"y":1396,"width":1435,"height":1398,"rx":1399,"fill":394,"stroke":429,"style":1400},"291.5","177.0",[19,1437,1438],{"x":1160,"y":1403,"style":1404},"'f', whole sheet shows text",[388,1440],{"x":1441,"y":1408,"width":1409,"height":1410,"rx":1365,"fill":1149,"stroke":1150,"style":1115},"265.3",[1117,1443,1445],{"transform":1444},"translate(368.0,176.5) scale(1.000)",[1121,1446],{"d":1447,"fill":1124,"stroke":1157,"style":1372},"M2 12s4-7 10-7 10 7 10 7-4 7-10 7S2 12 2 12z M12 9a3 3 0 1 0 .01 0z",[19,1449,1451],{"x":1160,"y":1419,"style":1450},"font-size:13.5px;font-weight:700;fill:var(--gold-ink,#7a4e06);text-anchor:middle","Show Formulas on",[19,1453,1454],{"x":1160,"y":1424,"style":1425},"Cause 3",[57,1456],{"x1":1384,"y1":1380,"x2":1384,"y2":1387,"stroke":402,"style":1115},[1389,1458],{"points":1459,"fill":1392},"625.3,161.5 620.3,152.5 630.3,152.5",[388,1461],{"x":1462,"y":1396,"width":1463,"height":1398,"rx":1399,"fill":394,"stroke":429,"style":1400},"559.9","130.9",[19,1465,1466],{"x":1384,"y":1403,"style":1404},"'f', shows #NAME?",[388,1468],{"x":1469,"y":1408,"width":1409,"height":1410,"rx":1365,"fill":401,"stroke":402,"style":1115},"510.7",[1117,1471,1473],{"transform":1472},"translate(613.3,176.5) scale(1.000)",[1121,1474],{"d":1475,"fill":1124,"stroke":1182,"style":1372},"M12 3.5l9.5 17h-19z M12 10v5 M12 17.8v.4",[19,1477,1478],{"x":1384,"y":1419,"style":1375},"Wrong function name",[19,1480,1481],{"x":1384,"y":1424,"style":1425},"see below",[43,1483,1485],{"id":1484},"a-check-for-your-tests","A check for your tests",[10,1487,1488],{},"The fixes above are easy once the problem is found; the point is to find it before a recipient does. The diagnostic function from Step 1 turns into a test with one more line: any formula-like text, or any sheet saved in Show Formulas mode, fails the build. Run it on the output of every report in the test suite:",[14,1490,1492],{"className":114,"code":1491,"language":116,"meta":20,"style":20},"def assert_formulas_are_formulas(path):\n    problems = [f\"{s}!{c} stored as text: {v}\" for s, c, kind, v in formula_like_text(path) if kind != \"f\"]\n    wb = load_workbook(path)\n    problems += [f\"{ws.title}: Show Formulas is on\" for ws in wb.worksheets if ws.sheet_view.showFormulas]\n    assert not problems, \"\\n\".join(problems)\n\nfor path in (\"report.xlsx\", \"report_fixed.xlsx\", \"template_show_formulas.xlsx\", \"template_fixed.xlsx\"):\n    try:\n        assert_formulas_are_formulas(path)\n        print(f\"{path:28} ok\")\n    except AssertionError as e:\n        print(f\"{path:28} FAIL: {str(e).splitlines()[0]}\")\n",[22,1493,1494,1503,1569,1577,1614,1634,1638,1664,1672,1677,1702,1716],{"__ignoreMap":20},[55,1495,1496,1498,1501],{"class":57,"line":58},[55,1497,147],{"class":123},[55,1499,1500],{"class":150}," assert_formulas_are_formulas",[55,1502,154],{"class":127},[55,1504,1505,1508,1510,1513,1515,1517,1519,1521,1523,1525,1527,1530,1532,1535,1537,1540,1542,1544,1547,1550,1552,1555,1558,1561,1564,1567],{"class":57,"line":137},[55,1506,1507],{"class":127},"    problems ",[55,1509,34],{"class":123},[55,1511,1512],{"class":127}," [",[55,1514,103],{"class":123},[55,1516,298],{"class":65},[55,1518,302],{"class":301},[55,1520,107],{"class":127},[55,1522,308],{"class":301},[55,1524,311],{"class":65},[55,1526,302],{"class":301},[55,1528,1529],{"class":127},"c",[55,1531,308],{"class":301},[55,1533,1534],{"class":65}," stored as text: ",[55,1536,302],{"class":301},[55,1538,1539],{"class":127},"v",[55,1541,308],{"class":301},[55,1543,298],{"class":65},[55,1545,1546],{"class":123}," for",[55,1548,1549],{"class":127}," s, c, kind, v ",[55,1551,177],{"class":123},[55,1553,1554],{"class":127}," formula_like_text(path) ",[55,1556,1557],{"class":123},"if",[55,1559,1560],{"class":127}," kind ",[55,1562,1563],{"class":123},"!=",[55,1565,1566],{"class":65}," \"f\"",[55,1568,621],{"class":127},[55,1570,1571,1573,1575],{"class":57,"line":144},[55,1572,160],{"class":127},[55,1574,34],{"class":123},[55,1576,165],{"class":127},[55,1578,1579,1581,1584,1586,1588,1590,1592,1595,1597,1600,1602,1604,1606,1609,1611],{"class":57,"line":157},[55,1580,1507],{"class":127},[55,1582,1583],{"class":123},"+=",[55,1585,1512],{"class":127},[55,1587,103],{"class":123},[55,1589,298],{"class":65},[55,1591,302],{"class":301},[55,1593,1594],{"class":127},"ws.title",[55,1596,308],{"class":301},[55,1598,1599],{"class":65},": Show Formulas is on\"",[55,1601,1546],{"class":123},[55,1603,174],{"class":127},[55,1605,177],{"class":123},[55,1607,1608],{"class":127}," wb.worksheets ",[55,1610,1557],{"class":123},[55,1612,1613],{"class":127}," ws.sheet_view.showFormulas]\n",[55,1615,1616,1619,1621,1624,1626,1629,1631],{"class":57,"line":168},[55,1617,1618],{"class":123},"    assert",[55,1620,544],{"class":123},[55,1622,1623],{"class":127}," problems, ",[55,1625,298],{"class":65},[55,1627,1628],{"class":301},"\\n",[55,1630,298],{"class":65},[55,1632,1633],{"class":127},".join(problems)\n",[55,1635,1636],{"class":57,"line":183},[55,1637,141],{"emptyLinePlaceholder":140},[55,1639,1640,1642,1644,1646,1648,1650,1652,1654,1656,1658,1660,1662],{"class":57,"line":197},[55,1641,271],{"class":123},[55,1643,870],{"class":127},[55,1645,177],{"class":123},[55,1647,633],{"class":127},[55,1649,282],{"class":65},[55,1651,526],{"class":127},[55,1653,668],{"class":65},[55,1655,526],{"class":127},[55,1657,1259],{"class":65},[55,1659,526],{"class":127},[55,1661,1317],{"class":65},[55,1663,245],{"class":127},[55,1665,1666,1669],{"class":57,"line":211},[55,1667,1668],{"class":123},"    try",[55,1670,1671],{"class":127},":\n",[55,1673,1674],{"class":57,"line":248},[55,1675,1676],{"class":127},"        assert_formulas_are_formulas(path)\n",[55,1678,1679,1682,1684,1686,1688,1690,1692,1695,1697,1700],{"class":57,"line":263},[55,1680,1681],{"class":217},"        print",[55,1683,293],{"class":127},[55,1685,103],{"class":123},[55,1687,298],{"class":65},[55,1689,302],{"class":301},[55,1691,1121],{"class":127},[55,1693,1694],{"class":123},":28",[55,1696,308],{"class":301},[55,1698,1699],{"class":65}," ok\"",[55,1701,344],{"class":127},[55,1703,1704,1707,1710,1713],{"class":57,"line":268},[55,1705,1706],{"class":123},"    except",[55,1708,1709],{"class":217}," AssertionError",[55,1711,1712],{"class":123}," as",[55,1714,1715],{"class":127}," e:\n",[55,1717,1718,1720,1722,1724,1726,1728,1730,1732,1734,1737,1739,1741,1744,1746,1749,1751,1753],{"class":57,"line":287},[55,1719,1681],{"class":217},[55,1721,293],{"class":127},[55,1723,103],{"class":123},[55,1725,298],{"class":65},[55,1727,302],{"class":301},[55,1729,1121],{"class":127},[55,1731,1694],{"class":123},[55,1733,308],{"class":301},[55,1735,1736],{"class":65}," FAIL: ",[55,1738,302],{"class":301},[55,1740,224],{"class":217},[55,1742,1743],{"class":127},"(e).splitlines()[",[55,1745,391],{"class":217},[55,1747,1748],{"class":127},"]",[55,1750,308],{"class":301},[55,1752,298],{"class":65},[55,1754,344],{"class":127},[10,1756,1757,1758,1760,1761,1765],{},"Deliberate text that starts with ",[22,1759,34],{},", such as a note explaining a formula, will trip the check; keep an allow-list of those cells rather than weakening the test. ",[37,1762,1764],{"href":1763},"\u002Fautomating-reporting-workflows\u002Ftesting-and-packaging-excel-automation-scripts\u002Ftest-excel-output-with-pytest\u002F","Test Excel Output with pytest"," shows how to wire checks like this into a test suite.",[43,1767,1769],{"id":1768},"look-alikes-that-are-not-formula-text","Look-alikes that are not formula text",[10,1771,1772],{},"Two other symptoms get reported as \"my formula doesn't work\" and have different causes:",[1774,1775,1776,1795],"ul",{},[1777,1778,1779,1786,1787,1790,1791,41],"li",{},[1780,1781,1782,1785],"strong",{},[22,1783,1784],{},"#NAME?"," instead of a result."," The cell is a formula, but Excel does not recognise a function in it: a localised name such as ",[22,1788,1789],{},"SUMME",", a newer function Excel wants with a prefix, or a typo. Files always store English function names with comma separators, whatever the language of Excel. See ",[37,1792,1794],{"href":1793},"\u002Fgetting-started-with-python-excel-automation\u002Ftroubleshooting-common-python-excel-errors\u002Ffix-name-error-for-new-excel-functions-written-by-python\u002F","Fix #NAME? in Formulas Written from Python (XLOOKUP, TEXTJOIN, IFS)",[1777,1796,1797,1802,1803,1805,1806,1810],{},[1780,1798,1799,1801],{},[22,1800,391],{}," or an empty cell in a preview."," The formula is fine, but the file has no calculated result stored and the viewer (a mail preview, a web viewer, pandas with openpyxl) does not calculate. xlsxwriter stores ",[22,1804,391],{}," as the cached result. Excel recalculates on open; other tools may not. ",[37,1807,1809],{"href":1808},"\u002Fgetting-started-with-python-excel-automation\u002Fworking-with-excel-formulas-in-python\u002Frecalculate-excel-formulas-without-excel-in-python\u002F","Recalculate Excel Formulas Without Excel in Python"," fills in the results.",[43,1812,1814],{"id":1813},"common-pitfalls","Common pitfalls",[1774,1816,1817,1827,1838,1848],{},[1777,1818,1819,1822,1823,1826],{},[1780,1820,1821],{},"Stripping only spaces."," Non-breaking spaces and apostrophes survive ",[22,1824,1825],{},"strip()","; handle them explicitly.",[1777,1828,1829,1835,1836,41],{},[1780,1830,1831,1832,1834],{},"Turning off ",[22,1833,701],{}," globally."," Protect data columns, then write intended formulas with ",[22,1837,901],{},[1777,1839,1840,1843,1844,1847],{},[1780,1841,1842],{},"Semicolons as separators."," Write ",[22,1845,1846],{},"=SUM(A1,A2)","; separators and function names in files are always the English ones.",[1777,1849,1850,1853],{},[1780,1851,1852],{},"Fixing the report, not the template."," If Show Formulas or text-formatted formula cells come from a template, fix the template once.",[43,1855,1857],{"id":1856},"conclusion","Conclusion",[10,1859,1860,1861,1863,1864,1866,1867,1869,1870,1872,1873,1875,1876,41],{},"Open the file with openpyxl and check each suspicious cell's ",[22,1862,99],{},". A string (",[22,1865,107],{},") means the formula was written as text: strip leading spaces, non-breaking spaces and apostrophes, and write intended formulas with ",[22,1868,901],{}," when ",[22,1871,701],{}," is off. A real formula (",[22,1874,103],{},") that still shows as text means the sheet has Show Formulas enabled; set ",[22,1877,1878],{},"sheet_view.showFormulas = False",[43,1880,1882],{"id":1881},"frequently-asked-questions","Frequently asked questions",[10,1884,1885,1888],{},[1780,1886,1887],{},"Why does my formula show as text in Excel after writing it with Python?","\nUsually the value was written as a string: a space or apostrophe before the equals sign, or a writer configured not to convert strings to formulas. Check the cell's data_type with openpyxl; it should be f for a formula.",[10,1890,1891,1894,1895,1897],{},[1780,1892,1893],{},"How do I write a formula with openpyxl?","\nAssign a string that starts exactly with an equals sign, such as ws",[55,1896,636],{}," = \"=SUM(B2:B4)\". openpyxl stores it as a formula; Excel calculates it when the file is opened.",[10,1899,1900,1903],{},[1780,1901,1902],{},"Why does pandas write my formula strings as text?","\nThe xlsxwriter option strings_to_formulas has been set to False, often to prevent formula injection. Write the formula cells separately with worksheet.write_formula.",[10,1905,1906,1909],{},[1780,1907,1908],{},"How do I turn off Show Formulas in a workbook from Python?","\nSet ws.sheet_view.showFormulas = False on each worksheet with openpyxl and save the file.",[43,1911,1913],{"id":1912},"related","Related",[1774,1915,1916,1922,1927,1933,1938],{},[1777,1917,1918,1919,1921],{},"Up one level: ",[37,1920,40],{"href":39}," — the other common errors.",[1777,1923,1924,1926],{},[37,1925,1794],{"href":1793}," — formulas that calculate to an error.",[1777,1928,1929,1932],{},[37,1930,1931],{"href":696},"Prevent Formula Injection in Excel Exports"," — the other side of strings_to_formulas.",[1777,1934,1935,1937],{},[37,1936,1809],{"href":1808}," — filling in cached results.",[1777,1939,1940,1944],{},[37,1941,1943],{"href":1942},"\u002Fgetting-started-with-python-excel-automation\u002Ftroubleshooting-common-python-excel-errors\u002Ffix-number-stored-as-text-warnings-in-excel-output\u002F","Fix \"Number Stored as Text\" Warnings in Excel Output"," — the numeric version of the same mix-up.",[1946,1947,1948],"style",{},"html pre.shiki code .sMTad, html code.shiki .sMTad{--shiki-default:#6F42C1;--shiki-dark:#FFB757}html pre.shiki code .srMev, html code.shiki .srMev{--shiki-default:#032F62;--shiki-dark:#ADDCFF}html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html.dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html pre.shiki code .s-kum, html code.shiki .s-kum{--shiki-default:#D73A49;--shiki-dark:#FF9492}html pre.shiki code .skGVy, html code.shiki .skGVy{--shiki-default:#24292E;--shiki-dark:#F0F3F6}html pre.shiki code .s_Opv, html code.shiki .s_Opv{--shiki-default:#6F42C1;--shiki-dark:#DBB7FF}html pre.shiki code .sP0c6, html code.shiki .sP0c6{--shiki-default:#005CC5;--shiki-dark:#91CBFF}html pre.shiki code .sSjpA, html code.shiki .sSjpA{--shiki-default:#005CC5;--shiki-dark:#FF9492}html pre.shiki code .sa561, html code.shiki .sa561{--shiki-default:#E36209;--shiki-dark:#FFB757}html pre.shiki code .s-wDw, html code.shiki .s-wDw{--shiki-default:#6A737D;--shiki-dark:#BDC4CC}",{"title":20,"searchDepth":137,"depth":137,"links":1950},[1951,1952,1953,1954,1955,1956,1957,1958,1959,1960,1961],{"id":45,"depth":137,"text":46},{"id":84,"depth":137,"text":85},{"id":485,"depth":137,"text":486},{"id":679,"depth":137,"text":680},{"id":1206,"depth":137,"text":1207},{"id":1484,"depth":137,"text":1485},{"id":1768,"depth":137,"text":1769},{"id":1813,"depth":137,"text":1814},{"id":1856,"depth":137,"text":1857},{"id":1881,"depth":137,"text":1882},{"id":1912,"depth":137,"text":1913},"2026-09-29","A workbook written by Python shows \"=SUM(B2:B9)\" in the cell instead of the result. Check whether the cell was stored as a formula or as text, then fix the cause: a leading space or apostrophe, a writer told not to convert strings to formulas, text written with write_string, or a sheet saved with Show Formulas switched on.","md",[1966,1968,1970,1972],{"q":1887,"a":1967},"Usually the value was written as a string: a space or apostrophe before the equals sign, or a writer configured not to convert strings to formulas. Check the cell's data_type with openpyxl; it should be f for a formula.",{"q":1893,"a":1969},"Assign a string that starts exactly with an equals sign, such as ws[\"B6\"] = \"=SUM(B2:B4)\". openpyxl stores it as a formula; Excel calculates it when the file is opened.",{"q":1902,"a":1971},"The xlsxwriter option strings_to_formulas has been set to False, often to prevent formula injection. Write the formula cells separately with worksheet.write_formula.",{"q":1908,"a":1973},"Set ws.sheet_view.showFormulas = False on each worksheet with openpyxl and save the file.","fix formulas showing as text in excel output",null,{"breadcrumb":1977},[1978,1981,1984],{"name":1979,"item":1980},"Home","\u002F",{"name":1982,"item":1983},"Getting Started with Python Excel Automation","\u002Fgetting-started-with-python-excel-automation\u002F",{"name":40,"item":39},"\u002Fgetting-started-with-python-excel-automation\u002Ftroubleshooting-common-python-excel-errors\u002Ffix-formulas-showing-as-text-in-excel-output",{"title":1987,"description":1988},"Fix Excel Formulas Showing as Text (openpyxl, xlsxwriter)","Why formulas written from Python show as text in Excel: leading spaces and apostrophes, xlsxwriter strings_to_formulas and write_string, pandas engine options, and showFormulas. Diagnose the stored cell type and fix each cause.","fix-formulas-showing-as-text-in-excel-output","getting-started-with-python-excel-automation\u002Ftroubleshooting-common-python-excel-errors\u002Ffix-formulas-showing-as-text-in-excel-output\u002Findex",[1992,1993],"troubleshooting","excel-formulas","how-to","8049gxxDWirDpGxHoG4ilXdOEEk1hjmbxQmbqPGZerY",[1997,2001],{"title":1998,"path":1999,"stem":2000,"children":-1},"Fix Formula Cells Reading as NaN (or 0) in pandas","\u002Fgetting-started-with-python-excel-automation\u002Ftroubleshooting-common-python-excel-errors\u002Ffix-formula-cells-reading-as-nan-in-pandas","getting-started-with-python-excel-automation\u002Ftroubleshooting-common-python-excel-errors\u002Ffix-formula-cells-reading-as-nan-in-pandas\u002Findex",{"title":2002,"path":2003,"stem":2004,"children":-1},"Fix #### Showing Instead of Values in Excel Output","\u002Fgetting-started-with-python-excel-automation\u002Ftroubleshooting-common-python-excel-errors\u002Ffix-hash-marks-showing-instead-of-values-in-excel","getting-started-with-python-excel-automation\u002Ftroubleshooting-common-python-excel-errors\u002Ffix-hash-marks-showing-instead-of-values-in-excel\u002Findex",[2006,2008],{"path":2007,"title":1982},"\u002Fgetting-started-with-python-excel-automation",{"path":2009,"title":40},"\u002Fgetting-started-with-python-excel-automation\u002Ftroubleshooting-common-python-excel-errors",[],[2012,2016,2019,2022,2025,2028],{"path":2013,"title":2014,"kind":2015},"\u002Fautomating-reporting-workflows\u002Ferror-handling-and-logging-in-excel-automation\u002Fhandle-permission-denied-when-writing-excel-in-python","Handle Permission Denied When Writing Excel in Python","fix",{"path":2017,"title":2018,"kind":1994},"\u002Fgetting-started-with-python-excel-automation\u002Fusing-openpyxl-for-excel-file-manipulation\u002Fwhat-openpyxl-loses-when-saving-an-existing-workbook","What openpyxl Loses When You Save an Existing Workbook",{"path":2020,"title":2021,"kind":2015},"\u002Fadvanced-data-transformation-and-cleaning\u002Fworking-with-dates-and-times-in-excel-data\u002Ffix-excel-serial-numbers-showing-instead-of-dates","Fix Excel Serial Numbers Showing Instead of Dates",{"path":2023,"title":2024,"kind":1994},"\u002Fadvanced-data-transformation-and-cleaning\u002Fworking-with-dates-and-times-in-excel-data\u002Fhandle-daylight-saving-time-in-excel-timestamps","Handle Daylight Saving Time in Excel Timestamps",{"path":2026,"title":2027,"kind":1994},"\u002Fautomating-reporting-workflows\u002Fautomating-excel-online-with-microsoft-graph\u002Fhandle-microsoft-graph-throttling-for-excel","Handle Microsoft Graph Throttling in Excel Automation",{"path":2029,"title":2030,"kind":2031},"\u002Fautomating-reporting-workflows\u002Ferror-handling-and-logging-in-excel-automation","Error Handling and Logging in Excel Automation","guide",1790972065775]