[{"data":1,"prerenderedAt":2971},["ShallowReactive",2],{"doc:\u002Fformatting-and-charting-excel-reports-with-python\u002Fapplying-number-and-date-formats-in-excel\u002Fread-cell-values-as-displayed-in-excel":3,"surround:\u002Fformatting-and-charting-excel-reports-with-python\u002Fapplying-number-and-date-formats-in-excel\u002Fread-cell-values-as-displayed-in-excel":2939,"ancestors:\u002Fformatting-and-charting-excel-reports-with-python\u002Fapplying-number-and-date-formats-in-excel\u002Fread-cell-values-as-displayed-in-excel":2947,"children:\u002Fformatting-and-charting-excel-reports-with-python\u002Fapplying-number-and-date-formats-in-excel\u002Fread-cell-values-as-displayed-in-excel":2952,"related:\u002Fformatting-and-charting-excel-reports-with-python\u002Fapplying-number-and-date-formats-in-excel\u002Fread-cell-values-as-displayed-in-excel":2953},{"id":4,"title":5,"body":6,"dateModified":2905,"datePublished":2905,"description":2906,"extension":2907,"faq":2908,"keyword":2917,"kind":2918,"meta":2919,"navigation":232,"path":2927,"seo":2928,"slug":2931,"stem":2932,"topics":2933,"type":2937,"__hash__":2938},"docs\u002Fformatting-and-charting-excel-reports-with-python\u002Fapplying-number-and-date-formats-in-excel\u002Fread-cell-values-as-displayed-in-excel\u002Findex.md","Read Cell Values as Displayed in Excel with Python",{"type":7,"value":8,"toc":2894},"minimark",[9,33,168,173,197,204,579,585,589,592,738,753,757,760,2353,2364,2494,2498,2501,2614,2621,2742,2746,2768,2772,2816,2820,2829,2833,2839,2845,2851,2857,2861,2890],[10,11,12,13,17,18,22,23,26,27,32],"p",{},"Sometimes the value is not what you need. A reconciliation must compare what a report ",[14,15,16],"em",{},"shows"," with what a system printed; a generated email must quote figures exactly as they appear in the attached workbook; a test must check that a column really displays ",[19,20,21],"code",{},"(1,235)"," and not ",[19,24,25],{},"-1234.5",". openpyxl and pandas both return the stored value, because that is what the file contains — the displayed text is created by Excel when it draws the cell, from the value and the number format together. This guide, part of ",[28,29,31],"a",{"href":30},"\u002Fformatting-and-charting-excel-reports-with-python\u002Fapplying-number-and-date-formats-in-excel\u002F","Applying Number and Date Formats in Excel",", shows two ways to get that text and where each one stops being exact.",[34,35,43,44,43,48,43,52,43,60,43,70,43,81,43,88,43,92,43,98,43,103,43,106,43,112,43,116,43,119,43,123,43,126,43,131,43,138,43,143,43,146,43,150,43,153,43,156,43,162,43,166],"svg",{"viewBox":36,"role":37,"ariaLabelledBy":38,"xmlns":41,"style":42},"4 0 752 125","img",[39,40],"rd-flow-t","rd-flow-d","http:\u002F\u002Fwww.w3.org\u002F2000\u002Fsvg","width:100%;max-width:752px;height:auto;display:block;margin:1.5rem auto;font-family:Inter,ui-sans-serif,system-ui,sans-serif","\n  ",[45,46,47],"title",{"id":39},"From stored value to displayed text",[49,50,51],"desc",{"id":40},"The file stores a value and a number format code separately. A spreadsheet application combines them when drawing the cell. To get the same text in Python, either let LibreOffice render the workbook and export the text, or apply the format code to the value with a Python formatter.",[53,54],"rect",{"x":55,"y":56,"width":57,"height":58,"fill":59},"4","0","752","125","#ffffff",[53,61],{"x":62,"y":63,"width":64,"height":65,"rx":66,"fill":67,"stroke":68,"style":69},"20.0","16.0","153.0","93.0","12","#f0f4ff","var(--brand,#5b5cf0)","stroke-width:2px",[71,72,74],"g",{"transform":73},"translate(84.5,29.0) scale(1.000)",[75,76],"path",{"d":77,"fill":78,"stroke":79,"style":80},"M5 9h14 M4 15h14 M10 4l-2 16 M16 4l-2 16","none","var(--brand-strong,#4338ca)","stroke-width:1.80px;stroke-linecap:round;stroke-linejoin:round",[82,83,87],"text",{"x":84,"y":85,"style":86},"96.5","75.5","font-size:13.5px;font-weight:700;fill:var(--brand-strong,#4338ca);text-anchor:middle","Stored value",[82,89,25],{"x":84,"y":90,"style":91},"95.0","font-size:11.5px;font-weight:400;fill:var(--text,#172033);text-anchor:middle",[93,94],"line",{"x1":95,"y1":96,"x2":97,"y2":96,"stroke":68,"style":69},"178.0","62.5","200.0",[99,100],"polygon",{"points":101,"fill":102},"204.0,62.5 195.0,67.5 195.0,57.5","#5b5cf0",[53,104],{"x":105,"y":63,"width":64,"height":65,"rx":66,"fill":67,"stroke":68,"style":69},"209.0",[71,107,109],{"transform":108},"translate(273.5,29.0) scale(1.000)",[75,110],{"d":111,"fill":78,"stroke":79,"style":80},"M9 8l-4 4 4 4 M15 8l4 4-4 4",[82,113,115],{"x":114,"y":85,"style":86},"285.5","Format code",[82,117,118],{"x":114,"y":90,"style":91},"#,##0_);[Red](#,##0)",[93,120],{"x1":121,"y1":96,"x2":122,"y2":96,"stroke":68,"style":69},"367.0","389.0",[99,124],{"points":125,"fill":102},"393.0,62.5 384.0,67.5 384.0,57.5",[53,127],{"x":128,"y":63,"width":64,"height":65,"rx":66,"fill":129,"stroke":130,"style":69},"398.0","#d9f4f1","var(--teal,#0f9488)",[71,132,134],{"transform":133},"translate(462.5,29.0) scale(1.000)",[75,135],{"d":136,"fill":78,"stroke":137,"style":80},"M2 12s4-7 10-7 10 7 10 7-4 7-10 7S2 12 2 12z M12 9a3 3 0 1 0 .01 0z","var(--teal-ink,#0b6157)",[82,139,142],{"x":140,"y":85,"style":141},"474.5","font-size:13.5px;font-weight:700;fill:var(--teal-ink,#0b6157);text-anchor:middle","Renderer",[82,144,145],{"x":140,"y":90,"style":91},"Excel or LibreOffice",[93,147],{"x1":148,"y1":96,"x2":149,"y2":96,"stroke":68,"style":69},"556.0","578.0",[99,151],{"points":152,"fill":102},"582.0,62.5 573.0,67.5 573.0,57.5",[53,154],{"x":155,"y":63,"width":64,"height":65,"rx":66,"fill":67,"stroke":68,"style":69},"587.0",[71,157,159],{"transform":158},"translate(651.5,29.0) scale(1.000)",[75,160],{"d":161,"fill":78,"stroke":79,"style":80},"M5 12.5l4.5 4.5L19 7",[82,163,165],{"x":164,"y":85,"style":86},"663.5","Displayed text",[82,167,21],{"x":164,"y":90,"style":91},[169,170,172],"h2",{"id":171},"prerequisites","Prerequisites",[174,175,180],"pre",{"className":176,"code":177,"language":178,"meta":179,"style":179},"language-bash shiki shiki-themes github-light github-dark-high-contrast","pip install openpyxl\n","bash","",[19,181,182],{"__ignoreMap":179},[183,184,186,190,194],"span",{"class":93,"line":185},1,[183,187,189],{"class":188},"sMTad","pip",[183,191,193],{"class":192},"srMev"," install",[183,195,196],{"class":192}," openpyxl\n",[10,198,199,200,203],{},"LibreOffice (the ",[19,201,202],{},"soffice"," command) is needed for the first approach. A sample workbook with typical report formats:",[174,205,209],{"className":206,"code":207,"language":208,"meta":179,"style":179},"language-python shiki shiki-themes github-light github-dark-high-contrast","import datetime as dt\n\nfrom openpyxl import Workbook, load_workbook\n\nCASES = [\n    (1234.5, \"#,##0\"), (0.1234, \"0.0%\"), (1234567, '#,##0.0,,\"M\"'),\n    (-1234.5, \"#,##0_);[Red](#,##0)\"), (1234.5, '\"€\"#,##0.00'), (42, \"00000\"),\n    (2.675, \"0.00\"), (dt.datetime(2026, 3, 5, 14, 7), \"dd\u002Fmm\u002Fyyyy\"),\n    (dt.datetime(2026, 3, 5, 14, 7), \"d-mmm-yy\"), (dt.datetime(2026, 3, 5, 9, 5, 3), \"h:mm:ss\"),\n]\nwb = Workbook()\nws = wb.active\nfor row, (value, fmt) in enumerate(CASES, start=1):\n    ws.cell(row, 1, value).number_format = fmt\nwb.save(\"formats.xlsx\")\n\ncell = load_workbook(\"formats.xlsx\").active[\"A4\"]\nprint(cell.value, cell.number_format)       # -1234.5 #,##0_);[Red](#,##0)\n","python",[19,210,211,227,234,248,253,266,305,341,388,449,455,467,478,512,528,540,545,566],{"__ignoreMap":179},[183,212,213,217,221,224],{"class":93,"line":185},[183,214,216],{"class":215},"s-kum","import",[183,218,220],{"class":219},"skGVy"," datetime ",[183,222,223],{"class":215},"as",[183,225,226],{"class":219}," dt\n",[183,228,230],{"class":93,"line":229},2,[183,231,233],{"emptyLinePlaceholder":232},true,"\n",[183,235,237,240,243,245],{"class":93,"line":236},3,[183,238,239],{"class":215},"from",[183,241,242],{"class":219}," openpyxl ",[183,244,216],{"class":215},[183,246,247],{"class":219}," Workbook, load_workbook\n",[183,249,251],{"class":93,"line":250},4,[183,252,233],{"emptyLinePlaceholder":232},[183,254,256,260,263],{"class":93,"line":255},5,[183,257,259],{"class":258},"sP0c6","CASES",[183,261,262],{"class":215}," =",[183,264,265],{"class":219}," [\n",[183,267,269,272,275,278,281,284,287,289,292,294,297,299,302],{"class":93,"line":268},6,[183,270,271],{"class":219},"    (",[183,273,274],{"class":258},"1234.5",[183,276,277],{"class":219},", ",[183,279,280],{"class":192},"\"#,##0\"",[183,282,283],{"class":219},"), (",[183,285,286],{"class":258},"0.1234",[183,288,277],{"class":219},[183,290,291],{"class":192},"\"0.0%\"",[183,293,283],{"class":219},[183,295,296],{"class":258},"1234567",[183,298,277],{"class":219},[183,300,301],{"class":192},"'#,##0.0,,\"M\"'",[183,303,304],{"class":219},"),\n",[183,306,308,310,313,315,317,320,322,324,326,329,331,334,336,339],{"class":93,"line":307},7,[183,309,271],{"class":219},[183,311,312],{"class":215},"-",[183,314,274],{"class":258},[183,316,277],{"class":219},[183,318,319],{"class":192},"\"#,##0_);[Red](#,##0)\"",[183,321,283],{"class":219},[183,323,274],{"class":258},[183,325,277],{"class":219},[183,327,328],{"class":192},"'\"€\"#,##0.00'",[183,330,283],{"class":219},[183,332,333],{"class":258},"42",[183,335,277],{"class":219},[183,337,338],{"class":192},"\"00000\"",[183,340,304],{"class":219},[183,342,344,346,349,351,354,357,360,362,365,367,370,372,375,377,380,383,386],{"class":93,"line":343},8,[183,345,271],{"class":219},[183,347,348],{"class":258},"2.675",[183,350,277],{"class":219},[183,352,353],{"class":192},"\"0.00\"",[183,355,356],{"class":219},"), (dt.datetime(",[183,358,359],{"class":258},"2026",[183,361,277],{"class":219},[183,363,364],{"class":258},"3",[183,366,277],{"class":219},[183,368,369],{"class":258},"5",[183,371,277],{"class":219},[183,373,374],{"class":258},"14",[183,376,277],{"class":219},[183,378,379],{"class":258},"7",[183,381,382],{"class":219},"), ",[183,384,385],{"class":192},"\"dd\u002Fmm\u002Fyyyy\"",[183,387,304],{"class":219},[183,389,391,394,396,398,400,402,404,406,408,410,412,414,417,419,421,423,425,427,429,431,434,436,438,440,442,444,447],{"class":93,"line":390},9,[183,392,393],{"class":219},"    (dt.datetime(",[183,395,359],{"class":258},[183,397,277],{"class":219},[183,399,364],{"class":258},[183,401,277],{"class":219},[183,403,369],{"class":258},[183,405,277],{"class":219},[183,407,374],{"class":258},[183,409,277],{"class":219},[183,411,379],{"class":258},[183,413,382],{"class":219},[183,415,416],{"class":192},"\"d-mmm-yy\"",[183,418,356],{"class":219},[183,420,359],{"class":258},[183,422,277],{"class":219},[183,424,364],{"class":258},[183,426,277],{"class":219},[183,428,369],{"class":258},[183,430,277],{"class":219},[183,432,433],{"class":258},"9",[183,435,277],{"class":219},[183,437,369],{"class":258},[183,439,277],{"class":219},[183,441,364],{"class":258},[183,443,382],{"class":219},[183,445,446],{"class":192},"\"h:mm:ss\"",[183,448,304],{"class":219},[183,450,452],{"class":93,"line":451},10,[183,453,454],{"class":219},"]\n",[183,456,458,461,464],{"class":93,"line":457},11,[183,459,460],{"class":219},"wb ",[183,462,463],{"class":215},"=",[183,465,466],{"class":219}," Workbook()\n",[183,468,470,473,475],{"class":93,"line":469},12,[183,471,472],{"class":219},"ws ",[183,474,463],{"class":215},[183,476,477],{"class":219}," wb.active\n",[183,479,481,484,487,490,493,496,498,500,504,506,509],{"class":93,"line":480},13,[183,482,483],{"class":215},"for",[183,485,486],{"class":219}," row, (value, fmt) ",[183,488,489],{"class":215},"in",[183,491,492],{"class":258}," enumerate",[183,494,495],{"class":219},"(",[183,497,259],{"class":258},[183,499,277],{"class":219},[183,501,503],{"class":502},"sa561","start",[183,505,463],{"class":215},[183,507,508],{"class":258},"1",[183,510,511],{"class":219},"):\n",[183,513,515,518,520,523,525],{"class":93,"line":514},14,[183,516,517],{"class":219},"    ws.cell(row, ",[183,519,508],{"class":258},[183,521,522],{"class":219},", value).number_format ",[183,524,463],{"class":215},[183,526,527],{"class":219}," fmt\n",[183,529,531,534,537],{"class":93,"line":530},15,[183,532,533],{"class":219},"wb.save(",[183,535,536],{"class":192},"\"formats.xlsx\"",[183,538,539],{"class":219},")\n",[183,541,543],{"class":93,"line":542},16,[183,544,233],{"emptyLinePlaceholder":232},[183,546,548,551,553,556,558,561,564],{"class":93,"line":547},17,[183,549,550],{"class":219},"cell ",[183,552,463],{"class":215},[183,554,555],{"class":219}," load_workbook(",[183,557,536],{"class":192},[183,559,560],{"class":219},").active[",[183,562,563],{"class":192},"\"A4\"",[183,565,454],{"class":219},[183,567,569,572,575],{"class":93,"line":568},18,[183,570,571],{"class":258},"print",[183,573,574],{"class":219},"(cell.value, cell.number_format)       ",[183,576,578],{"class":577},"s-wDw","# -1234.5 #,##0_);[Red](#,##0)\n",[10,580,581,582,584],{},"That last line is the whole problem: the value and the format, but not ",[19,583,21],{},".",[169,586,588],{"id":587},"approach-1-let-libreoffice-render-it","Approach 1 — Let LibreOffice render it",[10,590,591],{},"LibreOffice can open the workbook headlessly and export each sheet as CSV containing the formatted text. It applies the same number-format engine it uses on screen, so the result is what a reader of the file in LibreOffice sees:",[174,593,595],{"className":206,"code":594,"language":208,"meta":179,"style":179},"import csv\nimport subprocess\n\nsubprocess.run([\"soffice\", \"--headless\", \"--convert-to\",\n                \"csv:Text - txt - csv (StarCalc):44,34,76,1,,0,false,true,true\",\n                \"formats.xlsx\"], check=True, capture_output=True, timeout=120)\nshown = [row[0] for row in csv.reader(open(\"formats.csv\", encoding=\"utf-8\"))]\nprint(shown)\n# ['1,235', '12.3%', '1.2M', '(1,235)', '€1,234.50', '00042', '2.68', '05\u002F03\u002F2026', '5-Mar-26', '9:05:03']\n",[19,596,597,604,611,615,636,643,680,726,733],{"__ignoreMap":179},[183,598,599,601],{"class":93,"line":185},[183,600,216],{"class":215},[183,602,603],{"class":219}," csv\n",[183,605,606,608],{"class":93,"line":229},[183,607,216],{"class":215},[183,609,610],{"class":219}," subprocess\n",[183,612,613],{"class":93,"line":236},[183,614,233],{"emptyLinePlaceholder":232},[183,616,617,620,623,625,628,630,633],{"class":93,"line":250},[183,618,619],{"class":219},"subprocess.run([",[183,621,622],{"class":192},"\"soffice\"",[183,624,277],{"class":219},[183,626,627],{"class":192},"\"--headless\"",[183,629,277],{"class":219},[183,631,632],{"class":192},"\"--convert-to\"",[183,634,635],{"class":219},",\n",[183,637,638,641],{"class":93,"line":255},[183,639,640],{"class":192},"                \"csv:Text - txt - csv (StarCalc):44,34,76,1,,0,false,true,true\"",[183,642,635],{"class":219},[183,644,645,648,651,654,656,659,661,664,666,668,670,673,675,678],{"class":93,"line":268},[183,646,647],{"class":192},"                \"formats.xlsx\"",[183,649,650],{"class":219},"], ",[183,652,653],{"class":502},"check",[183,655,463],{"class":215},[183,657,658],{"class":258},"True",[183,660,277],{"class":219},[183,662,663],{"class":502},"capture_output",[183,665,463],{"class":215},[183,667,658],{"class":258},[183,669,277],{"class":219},[183,671,672],{"class":502},"timeout",[183,674,463],{"class":215},[183,676,677],{"class":258},"120",[183,679,539],{"class":219},[183,681,682,685,687,690,692,695,697,700,702,705,708,710,713,715,718,720,723],{"class":93,"line":307},[183,683,684],{"class":219},"shown ",[183,686,463],{"class":215},[183,688,689],{"class":219}," [row[",[183,691,56],{"class":258},[183,693,694],{"class":219},"] ",[183,696,483],{"class":215},[183,698,699],{"class":219}," row ",[183,701,489],{"class":215},[183,703,704],{"class":219}," csv.reader(",[183,706,707],{"class":258},"open",[183,709,495],{"class":219},[183,711,712],{"class":192},"\"formats.csv\"",[183,714,277],{"class":219},[183,716,717],{"class":502},"encoding",[183,719,463],{"class":215},[183,721,722],{"class":192},"\"utf-8\"",[183,724,725],{"class":219},"))]\n",[183,727,728,730],{"class":93,"line":343},[183,729,571],{"class":258},[183,731,732],{"class":219},"(shown)\n",[183,734,735],{"class":93,"line":390},[183,736,737],{"class":577},"# ['1,235', '12.3%', '1.2M', '(1,235)', '€1,234.50', '00042', '2.68', '05\u002F03\u002F2026', '5-Mar-26', '9:05:03']\n",[10,739,740,741,744,745,748,749,752],{},"The filter string requests comma-separated UTF-8 output of the formatted text (the ",[19,742,743],{},"true"," in the eighth position); add ",[19,746,747],{},",false,false,-1"," to get one CSV per sheet instead of only the first. This is the most faithful option without Excel, and it handles every format LibreOffice understands. Its costs are a LibreOffice installation, a second or two per file, and the fact that it shows LibreOffice's rendering — identical to Excel's for the common codes above, but not guaranteed for every exotic one. Colours such as ",[19,750,751],{},"[Red]"," are not part of the text.",[169,754,756],{"id":755},"approach-2-format-in-python","Approach 2 — Format in Python",[10,758,759],{},"For a known set of formats, a Python function is faster, needs no external program and is easy to test. The one below handles the codes that make up most reports: thousands separators, fixed decimals, leading zeros, percent, scaling commas, literal text, the positive; negative; zero sections, and date and time tokens. It rounds like Excel — halves away from zero, on the value's 15-digit representation — which is essential: Python's own formatting would show 2.675 as 2.67 and 1,234.5 as 1,234.",[174,761,763],{"className":206,"code":762,"language":208,"meta":179,"style":179},"import re\nfrom decimal import ROUND_HALF_UP, Decimal\n\nDATE_TOKEN = re.compile(r'yyyy|yy|mmmm|mmm|mm|m|dddd|ddd|dd|d|hh|h|ss|s|\"[^\"]*\"|\\\\.|.', re.I)\n\ndef _date_text(value, fmt):\n    fmt = re.sub(r\"\\[[^\\]]*\\]\", \"\", fmt.split(\";\")[0])\n    tokens, out, prev = DATE_TOKEN.findall(fmt), [], \"\"\n    for i, tok in enumerate(tokens):\n        low = tok.lower()\n        nxt = next((t.lower() for t in tokens[i + 1:] if t.strip(\":. \")), \"\")\n        if low in (\"mm\", \"m\") and (prev in (\"h\", \"hh\") or nxt in (\"s\", \"ss\")):\n            out.append(f\"{value.minute:02d}\" if low == \"mm\" else str(value.minute))\n        else:\n            out.append({\n                \"yyyy\": f\"{value.year:04d}\", \"yy\": f\"{value.year % 100:02d}\",\n                \"mmmm\": value.strftime(\"%B\"), \"mmm\": value.strftime(\"%b\"),\n                \"mm\": f\"{value.month:02d}\", \"m\": str(value.month),\n                \"dddd\": value.strftime(\"%A\"), \"ddd\": value.strftime(\"%a\"),\n                \"dd\": f\"{value.day:02d}\", \"d\": str(value.day),\n                \"hh\": f\"{value.hour:02d}\", \"h\": str(value.hour),\n                \"ss\": f\"{value.second:02d}\", \"s\": str(value.second),\n            }.get(low, tok.strip('\"').lstrip(\"\\\\\") if len(tok) > 1 else tok))\n        if low.strip(\":. \"):\n            prev = low\n    return \"\".join(out)\n\ndef _number_text(value, fmt):\n    sections = fmt.split(\";\")\n    if value \u003C 0 and len(sections) > 1:\n        fmt, value = sections[1], -value\n    elif value == 0 and len(sections) > 2:\n        fmt = sections[2]\n    else:\n        fmt = sections[0]\n    fmt = re.sub(r\"_.\", \" \", re.sub(r\"\\[[^\\]]*\\]\", \"\", fmt)).replace(\"*\", \"\")\n    m = re.search(r\"[#0][#0,.]*\", fmt)\n    if not m:\n        return fmt.replace('\"', \"\")\n    code, prefix, suffix = m.group(0), fmt[:m.start()], fmt[m.end():]\n    scale = len(code) - len(code.rstrip(\",\"))\n    int_part, _, dec_part = code.rstrip(\",\").partition(\".\")\n    value = value \u002F 1000 ** scale * (100 if \"%\" in suffix else 1)\n    number = Decimal(format(value, \".15g\")).quantize(Decimal(1).scaleb(-len(dec_part)), ROUND_HALF_UP)\n    whole, _, frac = f\"{number:{',' if ',' in int_part else ''}f}\".partition(\".\")\n    if len(whole.replace(\",\", \"\")) \u003C int_part.count(\"0\"):\n        whole = whole.replace(\",\", \"\").zfill(int_part.count(\"0\"))\n    return (prefix + whole + (\".\" + frac if frac else \"\") + suffix).replace('\"', \"\").replace(\"\\\\\", \"\")\n\ndef displayed(value, fmt):\n    if value is None:\n        return \"\"\n    if isinstance(value, dt.time):                     # a time-only cell\n        value = dt.datetime.combine(dt.date(1899, 12, 31), value)\n    elif isinstance(value, dt.date) and not isinstance(value, dt.datetime):\n        value = dt.datetime.combine(value, dt.time())\n    if isinstance(value, dt.datetime):\n        return _date_text(value, fmt)\n    if isinstance(value, (int, float)) and fmt not in (None, \"General\"):\n        return _number_text(value, fmt)\n    return format(value, \".10g\") if isinstance(value, float) else str(value)\n\nws = load_workbook(\"formats.xlsx\").active\nprint([displayed(c.value, c.number_format) for (c,) in ws.iter_rows(max_col=1)])\n# ['1,235', '12.3%', '1.2M', '(1,235)', '€1,234.50', '00042', '2.68', '05\u002F03\u002F2026', '5-Mar-26', '9:05:03']\n",[19,764,765,772,787,791,913,917,929,980,996,1011,1021,1069,1134,1178,1186,1191,1245,1272,1306,1333,1368,1402,1436,1474,1486,1497,1509,1514,1524,1539,1568,1588,1613,1628,1636,1649,1711,1746,1757,1774,1790,1816,1837,1884,1925,1981,2010,2034,2095,2100,2110,2125,2133,2147,2173,2192,2202,2211,2219,2261,2269,2301,2306,2320,2348],{"__ignoreMap":179},[183,766,767,769],{"class":93,"line":185},[183,768,216],{"class":215},[183,770,771],{"class":219}," re\n",[183,773,774,776,779,781,784],{"class":93,"line":229},[183,775,239],{"class":215},[183,777,778],{"class":219}," decimal ",[183,780,216],{"class":215},[183,782,783],{"class":258}," ROUND_HALF_UP",[183,785,786],{"class":219},", Decimal\n",[183,788,789],{"class":93,"line":236},[183,790,233],{"emptyLinePlaceholder":232},[183,792,793,796,798,801,804,807,810,813,815,818,820,823,825,828,830,833,835,838,840,843,845,848,850,853,855,858,860,863,865,868,870,873,875,878,881,884,887,890,893,895,897,901,903,905,907,910],{"class":93,"line":250},[183,794,795],{"class":258},"DATE_TOKEN",[183,797,262],{"class":215},[183,799,800],{"class":219}," re.compile(",[183,802,803],{"class":215},"r",[183,805,806],{"class":192},"'yyyy",[183,808,809],{"class":215},"|",[183,811,812],{"class":192},"yy",[183,814,809],{"class":215},[183,816,817],{"class":192},"mmmm",[183,819,809],{"class":215},[183,821,822],{"class":192},"mmm",[183,824,809],{"class":215},[183,826,827],{"class":192},"mm",[183,829,809],{"class":215},[183,831,832],{"class":192},"m",[183,834,809],{"class":215},[183,836,837],{"class":192},"dddd",[183,839,809],{"class":215},[183,841,842],{"class":192},"ddd",[183,844,809],{"class":215},[183,846,847],{"class":192},"dd",[183,849,809],{"class":215},[183,851,852],{"class":192},"d",[183,854,809],{"class":215},[183,856,857],{"class":192},"hh",[183,859,809],{"class":215},[183,861,862],{"class":192},"h",[183,864,809],{"class":215},[183,866,867],{"class":192},"ss",[183,869,809],{"class":215},[183,871,872],{"class":192},"s",[183,874,809],{"class":215},[183,876,877],{"class":192},"\"",[183,879,880],{"class":258},"[",[183,882,883],{"class":215},"^",[183,885,877],{"class":886},"sSjpA",[183,888,889],{"class":258},"]",[183,891,892],{"class":215},"*",[183,894,877],{"class":192},[183,896,809],{"class":215},[183,898,900],{"class":899},"s_b0D","\\\\",[183,902,584],{"class":258},[183,904,809],{"class":215},[183,906,584],{"class":258},[183,908,909],{"class":192},"'",[183,911,912],{"class":219},", re.I)\n",[183,914,915],{"class":93,"line":255},[183,916,233],{"emptyLinePlaceholder":232},[183,918,919,922,926],{"class":93,"line":268},[183,920,921],{"class":215},"def",[183,923,925],{"class":924},"s_Opv"," _date_text",[183,927,928],{"class":219},"(value, fmt):\n",[183,930,931,934,936,939,941,943,946,948,950,953,955,957,959,961,963,966,969,972,975,977],{"class":93,"line":307},[183,932,933],{"class":219},"    fmt ",[183,935,463],{"class":215},[183,937,938],{"class":219}," re.sub(",[183,940,803],{"class":215},[183,942,877],{"class":192},[183,944,945],{"class":899},"\\[",[183,947,880],{"class":258},[183,949,883],{"class":215},[183,951,952],{"class":899},"\\]",[183,954,889],{"class":258},[183,956,892],{"class":215},[183,958,952],{"class":899},[183,960,877],{"class":192},[183,962,277],{"class":219},[183,964,965],{"class":192},"\"\"",[183,967,968],{"class":219},", fmt.split(",[183,970,971],{"class":192},"\";\"",[183,973,974],{"class":219},")[",[183,976,56],{"class":258},[183,978,979],{"class":219},"])\n",[183,981,982,985,987,990,993],{"class":93,"line":343},[183,983,984],{"class":219},"    tokens, out, prev ",[183,986,463],{"class":215},[183,988,989],{"class":258}," DATE_TOKEN",[183,991,992],{"class":219},".findall(fmt), [], ",[183,994,995],{"class":192},"\"\"\n",[183,997,998,1001,1004,1006,1008],{"class":93,"line":390},[183,999,1000],{"class":215},"    for",[183,1002,1003],{"class":219}," i, tok ",[183,1005,489],{"class":215},[183,1007,492],{"class":258},[183,1009,1010],{"class":219},"(tokens):\n",[183,1012,1013,1016,1018],{"class":93,"line":451},[183,1014,1015],{"class":219},"        low ",[183,1017,463],{"class":215},[183,1019,1020],{"class":219}," tok.lower()\n",[183,1022,1023,1026,1028,1031,1034,1036,1039,1041,1044,1047,1050,1053,1056,1059,1062,1065,1067],{"class":93,"line":457},[183,1024,1025],{"class":219},"        nxt ",[183,1027,463],{"class":215},[183,1029,1030],{"class":258}," next",[183,1032,1033],{"class":219},"((t.lower() ",[183,1035,483],{"class":215},[183,1037,1038],{"class":219}," t ",[183,1040,489],{"class":215},[183,1042,1043],{"class":219}," tokens[i ",[183,1045,1046],{"class":215},"+",[183,1048,1049],{"class":258}," 1",[183,1051,1052],{"class":219},":] ",[183,1054,1055],{"class":215},"if",[183,1057,1058],{"class":219}," t.strip(",[183,1060,1061],{"class":192},"\":. \"",[183,1063,1064],{"class":219},")), ",[183,1066,965],{"class":192},[183,1068,539],{"class":219},[183,1070,1071,1074,1077,1079,1082,1085,1087,1090,1093,1096,1099,1101,1103,1106,1108,1111,1113,1116,1119,1121,1123,1126,1128,1131],{"class":93,"line":469},[183,1072,1073],{"class":215},"        if",[183,1075,1076],{"class":219}," low ",[183,1078,489],{"class":215},[183,1080,1081],{"class":219}," (",[183,1083,1084],{"class":192},"\"mm\"",[183,1086,277],{"class":219},[183,1088,1089],{"class":192},"\"m\"",[183,1091,1092],{"class":219},") ",[183,1094,1095],{"class":215},"and",[183,1097,1098],{"class":219}," (prev ",[183,1100,489],{"class":215},[183,1102,1081],{"class":219},[183,1104,1105],{"class":192},"\"h\"",[183,1107,277],{"class":219},[183,1109,1110],{"class":192},"\"hh\"",[183,1112,1092],{"class":219},[183,1114,1115],{"class":215},"or",[183,1117,1118],{"class":219}," nxt ",[183,1120,489],{"class":215},[183,1122,1081],{"class":219},[183,1124,1125],{"class":192},"\"s\"",[183,1127,277],{"class":219},[183,1129,1130],{"class":192},"\"ss\"",[183,1132,1133],{"class":219},")):\n",[183,1135,1136,1139,1142,1144,1147,1150,1153,1156,1158,1161,1163,1166,1169,1172,1175],{"class":93,"line":480},[183,1137,1138],{"class":219},"            out.append(",[183,1140,1141],{"class":215},"f",[183,1143,877],{"class":192},[183,1145,1146],{"class":886},"{",[183,1148,1149],{"class":219},"value.minute",[183,1151,1152],{"class":215},":02d",[183,1154,1155],{"class":886},"}",[183,1157,877],{"class":192},[183,1159,1160],{"class":215}," if",[183,1162,1076],{"class":219},[183,1164,1165],{"class":215},"==",[183,1167,1168],{"class":192}," \"mm\"",[183,1170,1171],{"class":215}," else",[183,1173,1174],{"class":258}," str",[183,1176,1177],{"class":219},"(value.minute))\n",[183,1179,1180,1183],{"class":93,"line":514},[183,1181,1182],{"class":215},"        else",[183,1184,1185],{"class":219},":\n",[183,1187,1188],{"class":93,"line":530},[183,1189,1190],{"class":219},"            out.append({\n",[183,1192,1193,1196,1199,1201,1203,1205,1208,1211,1213,1215,1217,1220,1222,1224,1226,1228,1231,1234,1237,1239,1241,1243],{"class":93,"line":542},[183,1194,1195],{"class":192},"                \"yyyy\"",[183,1197,1198],{"class":219},": ",[183,1200,1141],{"class":215},[183,1202,877],{"class":192},[183,1204,1146],{"class":886},[183,1206,1207],{"class":219},"value.year",[183,1209,1210],{"class":215},":04d",[183,1212,1155],{"class":886},[183,1214,877],{"class":192},[183,1216,277],{"class":219},[183,1218,1219],{"class":192},"\"yy\"",[183,1221,1198],{"class":219},[183,1223,1141],{"class":215},[183,1225,877],{"class":192},[183,1227,1146],{"class":886},[183,1229,1230],{"class":219},"value.year ",[183,1232,1233],{"class":215},"%",[183,1235,1236],{"class":258}," 100",[183,1238,1152],{"class":215},[183,1240,1155],{"class":886},[183,1242,877],{"class":192},[183,1244,635],{"class":219},[183,1246,1247,1250,1253,1256,1258,1261,1263,1265,1268,1270],{"class":93,"line":547},[183,1248,1249],{"class":192},"                \"mmmm\"",[183,1251,1252],{"class":219},": value.strftime(",[183,1254,1255],{"class":192},"\"%B\"",[183,1257,382],{"class":219},[183,1259,1260],{"class":192},"\"mmm\"",[183,1262,1252],{"class":219},[183,1264,877],{"class":192},[183,1266,1267],{"class":886},"%b",[183,1269,877],{"class":192},[183,1271,304],{"class":219},[183,1273,1274,1277,1279,1281,1283,1285,1288,1290,1292,1294,1296,1298,1300,1303],{"class":93,"line":568},[183,1275,1276],{"class":192},"                \"mm\"",[183,1278,1198],{"class":219},[183,1280,1141],{"class":215},[183,1282,877],{"class":192},[183,1284,1146],{"class":886},[183,1286,1287],{"class":219},"value.month",[183,1289,1152],{"class":215},[183,1291,1155],{"class":886},[183,1293,877],{"class":192},[183,1295,277],{"class":219},[183,1297,1089],{"class":192},[183,1299,1198],{"class":219},[183,1301,1302],{"class":258},"str",[183,1304,1305],{"class":219},"(value.month),\n",[183,1307,1309,1312,1314,1317,1319,1322,1324,1326,1329,1331],{"class":93,"line":1308},19,[183,1310,1311],{"class":192},"                \"dddd\"",[183,1313,1252],{"class":219},[183,1315,1316],{"class":192},"\"%A\"",[183,1318,382],{"class":219},[183,1320,1321],{"class":192},"\"ddd\"",[183,1323,1252],{"class":219},[183,1325,877],{"class":192},[183,1327,1328],{"class":886},"%a",[183,1330,877],{"class":192},[183,1332,304],{"class":219},[183,1334,1336,1339,1341,1343,1345,1347,1350,1352,1354,1356,1358,1361,1363,1365],{"class":93,"line":1335},20,[183,1337,1338],{"class":192},"                \"dd\"",[183,1340,1198],{"class":219},[183,1342,1141],{"class":215},[183,1344,877],{"class":192},[183,1346,1146],{"class":886},[183,1348,1349],{"class":219},"value.day",[183,1351,1152],{"class":215},[183,1353,1155],{"class":886},[183,1355,877],{"class":192},[183,1357,277],{"class":219},[183,1359,1360],{"class":192},"\"d\"",[183,1362,1198],{"class":219},[183,1364,1302],{"class":258},[183,1366,1367],{"class":219},"(value.day),\n",[183,1369,1371,1374,1376,1378,1380,1382,1385,1387,1389,1391,1393,1395,1397,1399],{"class":93,"line":1370},21,[183,1372,1373],{"class":192},"                \"hh\"",[183,1375,1198],{"class":219},[183,1377,1141],{"class":215},[183,1379,877],{"class":192},[183,1381,1146],{"class":886},[183,1383,1384],{"class":219},"value.hour",[183,1386,1152],{"class":215},[183,1388,1155],{"class":886},[183,1390,877],{"class":192},[183,1392,277],{"class":219},[183,1394,1105],{"class":192},[183,1396,1198],{"class":219},[183,1398,1302],{"class":258},[183,1400,1401],{"class":219},"(value.hour),\n",[183,1403,1405,1408,1410,1412,1414,1416,1419,1421,1423,1425,1427,1429,1431,1433],{"class":93,"line":1404},22,[183,1406,1407],{"class":192},"                \"ss\"",[183,1409,1198],{"class":219},[183,1411,1141],{"class":215},[183,1413,877],{"class":192},[183,1415,1146],{"class":886},[183,1417,1418],{"class":219},"value.second",[183,1420,1152],{"class":215},[183,1422,1155],{"class":886},[183,1424,877],{"class":192},[183,1426,277],{"class":219},[183,1428,1125],{"class":192},[183,1430,1198],{"class":219},[183,1432,1302],{"class":258},[183,1434,1435],{"class":219},"(value.second),\n",[183,1437,1439,1442,1445,1448,1450,1452,1454,1456,1458,1461,1464,1467,1469,1471],{"class":93,"line":1438},23,[183,1440,1441],{"class":219},"            }.get(low, tok.strip(",[183,1443,1444],{"class":192},"'\"'",[183,1446,1447],{"class":219},").lstrip(",[183,1449,877],{"class":192},[183,1451,900],{"class":886},[183,1453,877],{"class":192},[183,1455,1092],{"class":219},[183,1457,1055],{"class":215},[183,1459,1460],{"class":258}," len",[183,1462,1463],{"class":219},"(tok) ",[183,1465,1466],{"class":215},">",[183,1468,1049],{"class":258},[183,1470,1171],{"class":215},[183,1472,1473],{"class":219}," tok))\n",[183,1475,1477,1479,1482,1484],{"class":93,"line":1476},24,[183,1478,1073],{"class":215},[183,1480,1481],{"class":219}," low.strip(",[183,1483,1061],{"class":192},[183,1485,511],{"class":219},[183,1487,1489,1492,1494],{"class":93,"line":1488},25,[183,1490,1491],{"class":219},"            prev ",[183,1493,463],{"class":215},[183,1495,1496],{"class":219}," low\n",[183,1498,1500,1503,1506],{"class":93,"line":1499},26,[183,1501,1502],{"class":215},"    return",[183,1504,1505],{"class":192}," \"\"",[183,1507,1508],{"class":219},".join(out)\n",[183,1510,1512],{"class":93,"line":1511},27,[183,1513,233],{"emptyLinePlaceholder":232},[183,1515,1517,1519,1522],{"class":93,"line":1516},28,[183,1518,921],{"class":215},[183,1520,1521],{"class":924}," _number_text",[183,1523,928],{"class":219},[183,1525,1527,1530,1532,1535,1537],{"class":93,"line":1526},29,[183,1528,1529],{"class":219},"    sections ",[183,1531,463],{"class":215},[183,1533,1534],{"class":219}," fmt.split(",[183,1536,971],{"class":192},[183,1538,539],{"class":219},[183,1540,1542,1545,1548,1551,1554,1557,1559,1562,1564,1566],{"class":93,"line":1541},30,[183,1543,1544],{"class":215},"    if",[183,1546,1547],{"class":219}," value ",[183,1549,1550],{"class":215},"\u003C",[183,1552,1553],{"class":258}," 0",[183,1555,1556],{"class":215}," and",[183,1558,1460],{"class":258},[183,1560,1561],{"class":219},"(sections) ",[183,1563,1466],{"class":215},[183,1565,1049],{"class":258},[183,1567,1185],{"class":219},[183,1569,1571,1574,1576,1579,1581,1583,1585],{"class":93,"line":1570},31,[183,1572,1573],{"class":219},"        fmt, value ",[183,1575,463],{"class":215},[183,1577,1578],{"class":219}," sections[",[183,1580,508],{"class":258},[183,1582,650],{"class":219},[183,1584,312],{"class":215},[183,1586,1587],{"class":219},"value\n",[183,1589,1591,1594,1596,1598,1600,1602,1604,1606,1608,1611],{"class":93,"line":1590},32,[183,1592,1593],{"class":215},"    elif",[183,1595,1547],{"class":219},[183,1597,1165],{"class":215},[183,1599,1553],{"class":258},[183,1601,1556],{"class":215},[183,1603,1460],{"class":258},[183,1605,1561],{"class":219},[183,1607,1466],{"class":215},[183,1609,1610],{"class":258}," 2",[183,1612,1185],{"class":219},[183,1614,1616,1619,1621,1623,1626],{"class":93,"line":1615},33,[183,1617,1618],{"class":219},"        fmt ",[183,1620,463],{"class":215},[183,1622,1578],{"class":219},[183,1624,1625],{"class":258},"2",[183,1627,454],{"class":219},[183,1629,1631,1634],{"class":93,"line":1630},34,[183,1632,1633],{"class":215},"    else",[183,1635,1185],{"class":219},[183,1637,1639,1641,1643,1645,1647],{"class":93,"line":1638},35,[183,1640,1618],{"class":219},[183,1642,463],{"class":215},[183,1644,1578],{"class":219},[183,1646,56],{"class":258},[183,1648,454],{"class":219},[183,1650,1652,1654,1656,1658,1660,1663,1665,1667,1669,1672,1675,1677,1679,1681,1683,1685,1687,1689,1691,1693,1695,1697,1699,1702,1705,1707,1709],{"class":93,"line":1651},36,[183,1653,933],{"class":219},[183,1655,463],{"class":215},[183,1657,938],{"class":219},[183,1659,803],{"class":215},[183,1661,1662],{"class":192},"\"_",[183,1664,584],{"class":258},[183,1666,877],{"class":192},[183,1668,277],{"class":219},[183,1670,1671],{"class":192},"\" \"",[183,1673,1674],{"class":219},", re.sub(",[183,1676,803],{"class":215},[183,1678,877],{"class":192},[183,1680,945],{"class":899},[183,1682,880],{"class":258},[183,1684,883],{"class":215},[183,1686,952],{"class":899},[183,1688,889],{"class":258},[183,1690,892],{"class":215},[183,1692,952],{"class":899},[183,1694,877],{"class":192},[183,1696,277],{"class":219},[183,1698,965],{"class":192},[183,1700,1701],{"class":219},", fmt)).replace(",[183,1703,1704],{"class":192},"\"*\"",[183,1706,277],{"class":219},[183,1708,965],{"class":192},[183,1710,539],{"class":219},[183,1712,1714,1717,1719,1722,1724,1726,1728,1731,1734,1737,1739,1741,1743],{"class":93,"line":1713},37,[183,1715,1716],{"class":219},"    m ",[183,1718,463],{"class":215},[183,1720,1721],{"class":219}," re.search(",[183,1723,803],{"class":215},[183,1725,877],{"class":192},[183,1727,880],{"class":258},[183,1729,1730],{"class":886},"#0",[183,1732,1733],{"class":258},"][",[183,1735,1736],{"class":886},"#0,.",[183,1738,889],{"class":258},[183,1740,892],{"class":215},[183,1742,877],{"class":192},[183,1744,1745],{"class":219},", fmt)\n",[183,1747,1749,1751,1754],{"class":93,"line":1748},38,[183,1750,1544],{"class":215},[183,1752,1753],{"class":215}," not",[183,1755,1756],{"class":219}," m:\n",[183,1758,1760,1763,1766,1768,1770,1772],{"class":93,"line":1759},39,[183,1761,1762],{"class":215},"        return",[183,1764,1765],{"class":219}," fmt.replace(",[183,1767,1444],{"class":192},[183,1769,277],{"class":219},[183,1771,965],{"class":192},[183,1773,539],{"class":219},[183,1775,1777,1780,1782,1785,1787],{"class":93,"line":1776},40,[183,1778,1779],{"class":219},"    code, prefix, suffix ",[183,1781,463],{"class":215},[183,1783,1784],{"class":219}," m.group(",[183,1786,56],{"class":258},[183,1788,1789],{"class":219},"), fmt[:m.start()], fmt[m.end():]\n",[183,1791,1793,1796,1798,1800,1803,1805,1807,1810,1813],{"class":93,"line":1792},41,[183,1794,1795],{"class":219},"    scale ",[183,1797,463],{"class":215},[183,1799,1460],{"class":258},[183,1801,1802],{"class":219},"(code) ",[183,1804,312],{"class":215},[183,1806,1460],{"class":258},[183,1808,1809],{"class":219},"(code.rstrip(",[183,1811,1812],{"class":192},"\",\"",[183,1814,1815],{"class":219},"))\n",[183,1817,1819,1822,1824,1827,1829,1832,1835],{"class":93,"line":1818},42,[183,1820,1821],{"class":219},"    int_part, _, dec_part ",[183,1823,463],{"class":215},[183,1825,1826],{"class":219}," code.rstrip(",[183,1828,1812],{"class":192},[183,1830,1831],{"class":219},").partition(",[183,1833,1834],{"class":192},"\".\"",[183,1836,539],{"class":219},[183,1838,1840,1843,1845,1847,1850,1853,1856,1859,1861,1863,1866,1868,1871,1874,1877,1880,1882],{"class":93,"line":1839},43,[183,1841,1842],{"class":219},"    value ",[183,1844,463],{"class":215},[183,1846,1547],{"class":219},[183,1848,1849],{"class":215},"\u002F",[183,1851,1852],{"class":258}," 1000",[183,1854,1855],{"class":215}," **",[183,1857,1858],{"class":219}," scale ",[183,1860,892],{"class":215},[183,1862,1081],{"class":219},[183,1864,1865],{"class":258},"100",[183,1867,1160],{"class":215},[183,1869,1870],{"class":192}," \"%\"",[183,1872,1873],{"class":215}," in",[183,1875,1876],{"class":219}," suffix ",[183,1878,1879],{"class":215},"else",[183,1881,1049],{"class":258},[183,1883,539],{"class":219},[183,1885,1887,1890,1892,1895,1898,1901,1904,1907,1909,1912,1914,1917,1920,1923],{"class":93,"line":1886},44,[183,1888,1889],{"class":219},"    number ",[183,1891,463],{"class":215},[183,1893,1894],{"class":219}," Decimal(",[183,1896,1897],{"class":258},"format",[183,1899,1900],{"class":219},"(value, ",[183,1902,1903],{"class":192},"\".15g\"",[183,1905,1906],{"class":219},")).quantize(Decimal(",[183,1908,508],{"class":258},[183,1910,1911],{"class":219},").scaleb(",[183,1913,312],{"class":215},[183,1915,1916],{"class":258},"len",[183,1918,1919],{"class":219},"(dec_part)), ",[183,1921,1922],{"class":258},"ROUND_HALF_UP",[183,1924,539],{"class":219},[183,1926,1928,1931,1933,1936,1938,1940,1943,1946,1948,1951,1953,1956,1958,1961,1963,1966,1968,1970,1972,1974,1977,1979],{"class":93,"line":1927},45,[183,1929,1930],{"class":219},"    whole, _, frac ",[183,1932,463],{"class":215},[183,1934,1935],{"class":215}," f",[183,1937,877],{"class":192},[183,1939,1146],{"class":886},[183,1941,1942],{"class":219},"number",[183,1944,1945],{"class":215},":",[183,1947,1146],{"class":886},[183,1949,1950],{"class":192},"','",[183,1952,1160],{"class":215},[183,1954,1955],{"class":192}," ','",[183,1957,1873],{"class":215},[183,1959,1960],{"class":219}," int_part ",[183,1962,1879],{"class":215},[183,1964,1965],{"class":192}," ''",[183,1967,1155],{"class":886},[183,1969,1141],{"class":215},[183,1971,1155],{"class":886},[183,1973,877],{"class":192},[183,1975,1976],{"class":219},".partition(",[183,1978,1834],{"class":192},[183,1980,539],{"class":219},[183,1982,1984,1986,1988,1991,1993,1995,1997,2000,2002,2005,2008],{"class":93,"line":1983},46,[183,1985,1544],{"class":215},[183,1987,1460],{"class":258},[183,1989,1990],{"class":219},"(whole.replace(",[183,1992,1812],{"class":192},[183,1994,277],{"class":219},[183,1996,965],{"class":192},[183,1998,1999],{"class":219},")) ",[183,2001,1550],{"class":215},[183,2003,2004],{"class":219}," int_part.count(",[183,2006,2007],{"class":192},"\"0\"",[183,2009,511],{"class":219},[183,2011,2013,2016,2018,2021,2023,2025,2027,2030,2032],{"class":93,"line":2012},47,[183,2014,2015],{"class":219},"        whole ",[183,2017,463],{"class":215},[183,2019,2020],{"class":219}," whole.replace(",[183,2022,1812],{"class":192},[183,2024,277],{"class":219},[183,2026,965],{"class":192},[183,2028,2029],{"class":219},").zfill(int_part.count(",[183,2031,2007],{"class":192},[183,2033,1815],{"class":219},[183,2035,2037,2039,2042,2044,2047,2049,2051,2053,2056,2059,2061,2063,2065,2067,2069,2071,2074,2076,2078,2080,2083,2085,2087,2089,2091,2093],{"class":93,"line":2036},48,[183,2038,1502],{"class":215},[183,2040,2041],{"class":219}," (prefix ",[183,2043,1046],{"class":215},[183,2045,2046],{"class":219}," whole ",[183,2048,1046],{"class":215},[183,2050,1081],{"class":219},[183,2052,1834],{"class":192},[183,2054,2055],{"class":215}," +",[183,2057,2058],{"class":219}," frac ",[183,2060,1055],{"class":215},[183,2062,2058],{"class":219},[183,2064,1879],{"class":215},[183,2066,1505],{"class":192},[183,2068,1092],{"class":219},[183,2070,1046],{"class":215},[183,2072,2073],{"class":219}," suffix).replace(",[183,2075,1444],{"class":192},[183,2077,277],{"class":219},[183,2079,965],{"class":192},[183,2081,2082],{"class":219},").replace(",[183,2084,877],{"class":192},[183,2086,900],{"class":886},[183,2088,877],{"class":192},[183,2090,277],{"class":219},[183,2092,965],{"class":192},[183,2094,539],{"class":219},[183,2096,2098],{"class":93,"line":2097},49,[183,2099,233],{"emptyLinePlaceholder":232},[183,2101,2103,2105,2108],{"class":93,"line":2102},50,[183,2104,921],{"class":215},[183,2106,2107],{"class":924}," displayed",[183,2109,928],{"class":219},[183,2111,2113,2115,2117,2120,2123],{"class":93,"line":2112},51,[183,2114,1544],{"class":215},[183,2116,1547],{"class":219},[183,2118,2119],{"class":215},"is",[183,2121,2122],{"class":258}," None",[183,2124,1185],{"class":219},[183,2126,2128,2130],{"class":93,"line":2127},52,[183,2129,1762],{"class":215},[183,2131,2132],{"class":192}," \"\"\n",[183,2134,2136,2138,2141,2144],{"class":93,"line":2135},53,[183,2137,1544],{"class":215},[183,2139,2140],{"class":258}," isinstance",[183,2142,2143],{"class":219},"(value, dt.time):                     ",[183,2145,2146],{"class":577},"# a time-only cell\n",[183,2148,2150,2153,2155,2158,2161,2163,2165,2167,2170],{"class":93,"line":2149},54,[183,2151,2152],{"class":219},"        value ",[183,2154,463],{"class":215},[183,2156,2157],{"class":219}," dt.datetime.combine(dt.date(",[183,2159,2160],{"class":258},"1899",[183,2162,277],{"class":219},[183,2164,66],{"class":258},[183,2166,277],{"class":219},[183,2168,2169],{"class":258},"31",[183,2171,2172],{"class":219},"), value)\n",[183,2174,2176,2178,2180,2183,2185,2187,2189],{"class":93,"line":2175},55,[183,2177,1593],{"class":215},[183,2179,2140],{"class":258},[183,2181,2182],{"class":219},"(value, dt.date) ",[183,2184,1095],{"class":215},[183,2186,1753],{"class":215},[183,2188,2140],{"class":258},[183,2190,2191],{"class":219},"(value, dt.datetime):\n",[183,2193,2195,2197,2199],{"class":93,"line":2194},56,[183,2196,2152],{"class":219},[183,2198,463],{"class":215},[183,2200,2201],{"class":219}," dt.datetime.combine(value, dt.time())\n",[183,2203,2205,2207,2209],{"class":93,"line":2204},57,[183,2206,1544],{"class":215},[183,2208,2140],{"class":258},[183,2210,2191],{"class":219},[183,2212,2214,2216],{"class":93,"line":2213},58,[183,2215,1762],{"class":215},[183,2217,2218],{"class":219}," _date_text(value, fmt)\n",[183,2220,2222,2224,2226,2229,2232,2234,2237,2239,2241,2244,2247,2249,2251,2254,2256,2259],{"class":93,"line":2221},59,[183,2223,1544],{"class":215},[183,2225,2140],{"class":258},[183,2227,2228],{"class":219},"(value, (",[183,2230,2231],{"class":258},"int",[183,2233,277],{"class":219},[183,2235,2236],{"class":258},"float",[183,2238,1999],{"class":219},[183,2240,1095],{"class":215},[183,2242,2243],{"class":219}," fmt ",[183,2245,2246],{"class":215},"not",[183,2248,1873],{"class":215},[183,2250,1081],{"class":219},[183,2252,2253],{"class":258},"None",[183,2255,277],{"class":219},[183,2257,2258],{"class":192},"\"General\"",[183,2260,511],{"class":219},[183,2262,2264,2266],{"class":93,"line":2263},60,[183,2265,1762],{"class":215},[183,2267,2268],{"class":219}," _number_text(value, fmt)\n",[183,2270,2272,2274,2277,2279,2282,2284,2286,2288,2290,2292,2294,2296,2298],{"class":93,"line":2271},61,[183,2273,1502],{"class":215},[183,2275,2276],{"class":258}," format",[183,2278,1900],{"class":219},[183,2280,2281],{"class":192},"\".10g\"",[183,2283,1092],{"class":219},[183,2285,1055],{"class":215},[183,2287,2140],{"class":258},[183,2289,1900],{"class":219},[183,2291,2236],{"class":258},[183,2293,1092],{"class":219},[183,2295,1879],{"class":215},[183,2297,1174],{"class":258},[183,2299,2300],{"class":219},"(value)\n",[183,2302,2304],{"class":93,"line":2303},62,[183,2305,233],{"emptyLinePlaceholder":232},[183,2307,2309,2311,2313,2315,2317],{"class":93,"line":2308},63,[183,2310,472],{"class":219},[183,2312,463],{"class":215},[183,2314,555],{"class":219},[183,2316,536],{"class":192},[183,2318,2319],{"class":219},").active\n",[183,2321,2323,2325,2328,2330,2333,2335,2338,2341,2343,2345],{"class":93,"line":2322},64,[183,2324,571],{"class":258},[183,2326,2327],{"class":219},"([displayed(c.value, c.number_format) ",[183,2329,483],{"class":215},[183,2331,2332],{"class":219}," (c,) ",[183,2334,489],{"class":215},[183,2336,2337],{"class":219}," ws.iter_rows(",[183,2339,2340],{"class":502},"max_col",[183,2342,463],{"class":215},[183,2344,508],{"class":258},[183,2346,2347],{"class":219},")])\n",[183,2349,2351],{"class":93,"line":2350},65,[183,2352,737],{"class":577},[10,2354,2355,2356,2359,2360,2363],{},"Both approaches produce the same ten strings. The function reads ",[19,2357,2358],{},"cell.value"," and ",[19,2361,2362],{},"cell.number_format"," straight from openpyxl, so it works anywhere Python runs.",[34,2365,43,2370,43,2373,43,2376,43,2379,43,2383,43,2389,43,2395,43,2401,43,2407,43,2413,43,2417,43,2422,43,2426,43,2433,43,2437,43,2444,43,2446,43,2452,43,2457,43,2461,43,2465,43,2470,43,2473,43,2478,43,2481,43,2486,43,2489],{"viewBox":2366,"role":37,"ariaLabelledBy":2367,"xmlns":41,"style":42},"4 0 752 233",[2368,2369],"rd-approaches-t","rd-approaches-d",[45,2371,2372],{"id":2368},"LibreOffice export or a Python formatter",[49,2374,2375],{"id":2369},"Exporting with LibreOffice handles every format LibreOffice supports and needs no format-specific code, but requires LibreOffice and takes a second or more per file. A Python formatter is fast, portable and testable, but only covers the codes it implements and approximates the General format.",[53,2377],{"x":55,"y":56,"width":57,"height":2378,"fill":59},"233",[53,2380],{"x":62,"y":63,"width":2381,"height":2382,"rx":374,"fill":129,"stroke":130,"style":69},"351.0","201.0",[71,2384,2386],{"transform":2385},"translate(182.5,29.0) scale(1.083)",[75,2387],{"d":136,"fill":78,"stroke":137,"style":2388},"stroke-width:1.66px;stroke-linecap:round;stroke-linejoin:round",[82,2390,2394],{"x":2391,"y":2392,"style":2393},"195.5","78.0","font-size:14px;font-weight:700;fill:var(--teal-ink,#0b6157);text-anchor:middle","LibreOffice CSV export",[93,2396],{"x1":2397,"y1":2398,"x2":2399,"y2":2398,"stroke":130,"style":2400},"36.0","91.0","355.0","stroke-width:1px",[82,2402,2406],{"x":2403,"y":2404,"style":2405},"60.0","111.0","font-size:12px;font-weight:400;fill:var(--text,#172033);text-anchor:start","any format LibreOffice supports",[71,2408,2410],{"transform":2409},"translate(38.5,99.5) scale(0.625)",[75,2411],{"d":161,"fill":78,"stroke":130,"style":2412},"stroke-width:2.88px;stroke-linecap:round;stroke-linejoin:round",[82,2414,2416],{"x":2403,"y":2415,"style":2405},"137.0","no format-specific code",[71,2418,2420],{"transform":2419},"translate(38.5,125.5) scale(0.625)",[75,2421],{"d":161,"fill":78,"stroke":130,"style":2412},[82,2423,2425],{"x":2403,"y":2424,"style":2405},"163.0","needs LibreOffice installed",[71,2427,2429],{"transform":2428},"translate(38.5,151.5) scale(0.625)",[75,2430],{"d":2431,"fill":78,"stroke":2432,"style":2412},"M6 6l12 12 M18 6L6 18","var(--accent,#f43f8f)",[82,2434,2436],{"x":2403,"y":2435,"style":2405},"189.0","seconds per file",[71,2438,2440],{"transform":2439},"translate(38.5,177.5) scale(0.625)",[75,2441],{"d":2442,"fill":78,"stroke":2443,"style":2412},"M12 3.5l9.5 17h-19z M12 10v5 M12 17.8v.4","var(--gold,#b4740a)",[53,2445],{"x":122,"y":63,"width":2381,"height":2382,"rx":374,"fill":67,"stroke":68,"style":69},[71,2447,2449],{"transform":2448},"translate(551.5,29.0) scale(1.083)",[75,2450],{"d":2451,"fill":78,"stroke":79,"style":2388},"M12 3c-4 0-4 1.6-4 3v2h4.2v1H6c-2 0-3 1.4-3 4s1 4 3 4h2v-2.6c0-1.6 1.3-2.9 2.9-2.9h4.2c1.3 0 2.4-1.1 2.4-2.4V6c0-1.6-1.8-3-5.5-3z M10 5.5h.01 M12 21c4 0 4-1.6 4-3v-2h-4.2v-1H18c2 0 3-1.4 3-4s-1-4-3-4h-2v2.6c0 1.6-1.3 2.9-2.9 2.9H8.9c-1.3 0-2.4 1.1-2.4 2.4V18c0 1.6 1.8 3 5.5 3z M14 18.5h.01",[82,2453,2456],{"x":2454,"y":2392,"style":2455},"564.5","font-size:14px;font-weight:700;fill:var(--brand-strong,#4338ca);text-anchor:middle","Python formatter",[93,2458],{"x1":2459,"y1":2398,"x2":2460,"y2":2398,"stroke":68,"style":2400},"405.0","724.0",[82,2462,2464],{"x":2463,"y":2404,"style":2405},"429.0","fast and dependency-free",[71,2466,2468],{"transform":2467},"translate(407.5,99.5) scale(0.625)",[75,2469],{"d":161,"fill":78,"stroke":130,"style":2412},[82,2471,2472],{"x":2463,"y":2415,"style":2405},"easy to unit test",[71,2474,2476],{"transform":2475},"translate(407.5,125.5) scale(0.625)",[75,2477],{"d":161,"fill":78,"stroke":130,"style":2412},[82,2479,2480],{"x":2463,"y":2424,"style":2405},"only the codes it implements",[71,2482,2484],{"transform":2483},"translate(407.5,151.5) scale(0.625)",[75,2485],{"d":2431,"fill":78,"stroke":2432,"style":2412},[82,2487,2488],{"x":2463,"y":2435,"style":2405},"General is approximated",[71,2490,2492],{"transform":2491},"translate(407.5,177.5) scale(0.625)",[75,2493],{"d":2442,"fill":78,"stroke":2443,"style":2412},[169,2495,2497],{"id":2496},"step-3-test-the-formatter-against-the-renderer","Step 3 — Test the formatter against the renderer",[10,2499,2500],{},"A hand-written formatter is only trustworthy if it is checked. Keep a list of the formats your reports use, write them to a workbook with awkward values — halves, negatives, zeros, small numbers — and compare the function's output with LibreOffice's export in a test:",[174,2502,2504],{"className":206,"code":2503,"language":208,"meta":179,"style":179},"def mismatches(path, rendered):\n    ws = load_workbook(path).active\n    ours = [displayed(c.value, c.number_format) for (c,) in ws.iter_rows(max_col=1)]\n    return [(i + 1, a, b) for i, (a, b) in enumerate(zip(ours, rendered)) if a != b]\n\nprint(mismatches(\"formats.xlsx\", shown))       # []\n",[19,2505,2506,2516,2526,2553,2595,2599],{"__ignoreMap":179},[183,2507,2508,2510,2513],{"class":93,"line":185},[183,2509,921],{"class":215},[183,2511,2512],{"class":924}," mismatches",[183,2514,2515],{"class":219},"(path, rendered):\n",[183,2517,2518,2521,2523],{"class":93,"line":229},[183,2519,2520],{"class":219},"    ws ",[183,2522,463],{"class":215},[183,2524,2525],{"class":219}," load_workbook(path).active\n",[183,2527,2528,2531,2533,2536,2538,2540,2542,2544,2546,2548,2550],{"class":93,"line":236},[183,2529,2530],{"class":219},"    ours ",[183,2532,463],{"class":215},[183,2534,2535],{"class":219}," [displayed(c.value, c.number_format) ",[183,2537,483],{"class":215},[183,2539,2332],{"class":219},[183,2541,489],{"class":215},[183,2543,2337],{"class":219},[183,2545,2340],{"class":502},[183,2547,463],{"class":215},[183,2549,508],{"class":258},[183,2551,2552],{"class":219},")]\n",[183,2554,2555,2557,2560,2562,2564,2567,2569,2572,2574,2576,2578,2581,2584,2586,2589,2592],{"class":93,"line":250},[183,2556,1502],{"class":215},[183,2558,2559],{"class":219}," [(i ",[183,2561,1046],{"class":215},[183,2563,1049],{"class":258},[183,2565,2566],{"class":219},", a, b) ",[183,2568,483],{"class":215},[183,2570,2571],{"class":219}," i, (a, b) ",[183,2573,489],{"class":215},[183,2575,492],{"class":258},[183,2577,495],{"class":219},[183,2579,2580],{"class":258},"zip",[183,2582,2583],{"class":219},"(ours, rendered)) ",[183,2585,1055],{"class":215},[183,2587,2588],{"class":219}," a ",[183,2590,2591],{"class":215},"!=",[183,2593,2594],{"class":219}," b]\n",[183,2596,2597],{"class":93,"line":255},[183,2598,233],{"emptyLinePlaceholder":232},[183,2600,2601,2603,2606,2608,2611],{"class":93,"line":268},[183,2602,571],{"class":258},[183,2604,2605],{"class":219},"(mismatches(",[183,2607,536],{"class":192},[183,2609,2610],{"class":219},", shown))       ",[183,2612,2613],{"class":577},"# []\n",[10,2615,2616,2617,2620],{},"The formatter in this guide was checked this way against 25 value-and-format pairs, including 0.125 and 1.005 at two decimals, −0.4 showing as ",[19,2618,2619],{},"(0)",", zero sections, scaled millions and times, with no differences. When a report adopts a new format, add it to the list first; a mismatch then fails the test rather than a figure in a sent report.",[34,2622,43,2627,43,2630,43,2633,43,2636,43,2641,43,2646,43,2652,43,2657,43,2662,43,2664,43,2670,43,2673,43,2677,43,2679,43,2684,43,2687,43,2691,43,2693,43,2698,43,2701,43,2705,43,2707,43,2712,43,2715,43,2719,43,2721,43,2727,43,2730,43,2734,43,2736],{"viewBox":2623,"role":37,"ariaLabelledBy":2624,"xmlns":41,"style":42},"4 0 752 276",[2625,2626],"rd-support-t","rd-support-d",[45,2628,2629],{"id":2625},"Which parts of a format code the Python function handles",[49,2631,2632],{"id":2626},"The function handles digit placeholders with thousands separators and decimals, leading zeros, percent, scaling commas, quoted literal text, positive negative and zero sections, padding characters, and common date and time tokens. It ignores colours and conditions, and does not implement fractions, scientific notation, elapsed time in brackets or locale-specific codes.",[53,2634],{"x":55,"y":56,"width":57,"height":2635,"fill":59},"276",[53,2637],{"x":62,"y":63,"width":2638,"height":2639,"rx":56,"fill":59,"stroke":2640,"style":2400},"216.8","40.0","var(--line,#cdd5e6)",[53,2642],{"x":2643,"y":63,"width":2644,"height":2639,"rx":56,"fill":67,"stroke":68,"style":2645},"236.8","503.2","stroke-width:1.2px",[82,2647,2651],{"x":2648,"y":2649,"style":2650},"488.4","41.0","font-size:13px;font-weight:700;fill:var(--brand-strong,#4338ca);text-anchor:middle","Handled",[53,2653],{"x":62,"y":2654,"width":2638,"height":2655,"rx":56,"fill":2656,"stroke":2640,"style":2400},"56.0","34.0","#e7ebef",[82,2658,2661],{"x":2659,"y":2392,"style":2660},"32.0","font-size:12.5px;font-weight:700;fill:var(--text,#172033);text-anchor:start","#,##0.00 and 00000",[53,2663],{"x":2643,"y":2654,"width":2644,"height":2655,"rx":56,"fill":59,"stroke":2640,"style":2400},[71,2665,2667],{"transform":2666},"translate(479.4,64.0) scale(0.750)",[75,2668],{"d":161,"fill":78,"stroke":130,"style":2669},"stroke-width:2.40px;stroke-linecap:round;stroke-linejoin:round",[53,2671],{"x":62,"y":2672,"width":2638,"height":2655,"rx":56,"fill":2656,"stroke":2640,"style":2400},"90.0",[82,2674,2676],{"x":2659,"y":2675,"style":2660},"112.0","% and trailing commas",[53,2678],{"x":2643,"y":2672,"width":2644,"height":2655,"rx":56,"fill":59,"stroke":2640,"style":2400},[71,2680,2682],{"transform":2681},"translate(479.4,98.0) scale(0.750)",[75,2683],{"d":161,"fill":78,"stroke":130,"style":2669},[53,2685],{"x":62,"y":2686,"width":2638,"height":2655,"rx":56,"fill":2656,"stroke":2640,"style":2400},"124.0",[82,2688,2690],{"x":2659,"y":2689,"style":2660},"146.0","\"text\", sections, _) padding",[53,2692],{"x":2643,"y":2686,"width":2644,"height":2655,"rx":56,"fill":59,"stroke":2640,"style":2400},[71,2694,2696],{"transform":2695},"translate(479.4,132.0) scale(0.750)",[75,2697],{"d":161,"fill":78,"stroke":130,"style":2669},[53,2699],{"x":62,"y":2700,"width":2638,"height":2655,"rx":56,"fill":2656,"stroke":2640,"style":2400},"158.0",[82,2702,2704],{"x":2659,"y":2703,"style":2660},"180.0","dd\u002Fmm\u002Fyyyy, mmm, h:mm:ss",[53,2706],{"x":2643,"y":2700,"width":2644,"height":2655,"rx":56,"fill":59,"stroke":2640,"style":2400},[71,2708,2710],{"transform":2709},"translate(479.4,166.0) scale(0.750)",[75,2711],{"d":161,"fill":78,"stroke":130,"style":2669},[53,2713],{"x":62,"y":2714,"width":2638,"height":2655,"rx":56,"fill":2656,"stroke":2640,"style":2400},"192.0",[82,2716,2718],{"x":2659,"y":2717,"style":2660},"214.0","[Red], [>=1000] conditions",[53,2720],{"x":2643,"y":2714,"width":2644,"height":2655,"rx":56,"fill":59,"stroke":2640,"style":2400},[71,2722,2724],{"transform":2723},"translate(479.9,200.5) scale(0.708)",[75,2725],{"d":2442,"fill":78,"stroke":2443,"style":2726},"stroke-width:2.54px;stroke-linecap:round;stroke-linejoin:round",[53,2728],{"x":62,"y":2729,"width":2638,"height":2655,"rx":56,"fill":2656,"stroke":2640,"style":2400},"226.0",[82,2731,2733],{"x":2659,"y":2732,"style":2660},"248.0","# ?\u002F?, 0.00E+00, [h]:mm",[53,2735],{"x":2643,"y":2729,"width":2644,"height":2655,"rx":56,"fill":59,"stroke":2640,"style":2400},[71,2737,2739],{"transform":2738},"translate(480.4,235.0) scale(0.667)",[75,2740],{"d":2431,"fill":78,"stroke":2432,"style":2741},"stroke-width:2.70px;stroke-linecap:round;stroke-linejoin:round",[169,2743,2745],{"id":2744},"where-the-displayed-text-is-not-enough","Where the displayed text is not enough",[10,2747,2748,2749,2752,2753,2755,2756,2758,2759,2762,2763,2767],{},"The text a cell displays also depends on things outside the file. Excel shows ",[19,2750,2751],{},"####"," when a number is too wide for its column, and the General format switches to scientific notation in narrow cells; neither shows up in a CSV export or a Python formatter. Month and day names follow the reader's language — ",[19,2754,822],{}," is \"Mar\" for an English reader but a different abbreviation for a German or French one — and decimal and thousands separators follow their regional settings, so 1,234.50 reads as 1.234,50 in much of Europe. And colours from ",[19,2757,751],{}," sections or conditional formatting are not text at all. If you need to reproduce exactly what one person sees on one screen, only that application can tell you; on Windows with Excel installed, the ",[19,2760,2761],{},"Text"," property of a cell through COM returns it — see ",[28,2764,2766],{"href":2765},"\u002Fgetting-started-with-python-excel-automation\u002Fautomating-excel-with-com-and-pywin32\u002Fsave-a-workbook-in-another-format-with-win32com\u002F","Save a Workbook in Another Format with win32com"," for driving Excel from Python.",[169,2769,2771],{"id":2770},"common-pitfalls","Common pitfalls",[2773,2774,2775,2796,2806],"ul",{},[2776,2777,2778,2782,2783,2786,2787,2790,2791,2359,2794,584],"li",{},[2779,2780,2781],"strong",{},"Formatting with f-strings."," ",[19,2784,2785],{},"f\"{2.675:.2f}\""," gives 2.67 and ",[19,2788,2789],{},"f\"{1234.5:,.0f}\""," gives 1,234 — banker's rounding on the binary value. Round with ",[19,2792,2793],{},"Decimal",[19,2795,1922],{},[2776,2797,2798,2801,2802,2805],{},[2779,2799,2800],{},"Numbers stored as text."," A cell holding the string \"1234.5\" displays as typed, whatever its format says. Check ",[19,2803,2804],{},"cell.data_type"," first.",[2776,2807,2808,2811,2812,2815],{},[2779,2809,2810],{},"Assuming every date cell is a datetime."," openpyxl returns ",[19,2813,2814],{},"datetime"," only when the format is a date format; a date typed as text stays a string.",[169,2817,2819],{"id":2818},"conclusion","Conclusion",[10,2821,2822,2823,2825,2826,2828],{},"The displayed text of a cell is the stored value run through its number format by the application that draws it. Without Excel, get it by exporting the formatted text with LibreOffice, or by formatting ",[19,2824,2358],{}," with ",[19,2827,2362],{}," in Python using Excel's rounding. Test any Python formatter against LibreOffice's output for the formats your reports use, and remember that column width, locale and colour are outside what either approach can capture.",[169,2830,2832],{"id":2831},"frequently-asked-questions","Frequently asked questions",[10,2834,2835,2838],{},[2779,2836,2837],{},"Why does openpyxl return 1234.5 when Excel shows $1,234.50?","\nAn .xlsx file stores the value and the number format separately; the displayed text is produced by the application when it draws the cell. openpyxl gives you both parts — cell.value and cell.number_format — but not the combined text.",[10,2840,2841,2844],{},[2779,2842,2843],{},"Is there a way to read the exact text Excel displays?","\nNot from the file alone. The most faithful option without Excel is to let LibreOffice render the workbook and export the formatted text as CSV. With Excel installed on Windows, cell.Text through COM returns exactly what Excel shows.",[10,2846,2847,2850],{},[2779,2848,2849],{},"Can I format the values myself in Python?","\nFor common codes, yes. A small function that handles thousands separators, decimals, percent, scaling commas, sign sections, literal text and date tokens covers most report formats, provided it rounds halves away from zero like Excel.",[10,2852,2853,2856],{},[2779,2854,2855],{},"Why does Python round my displayed values differently?","\nPython's formatting rounds halves to even and works on the binary value, so 2.675 formats as 2.67. Excel shows 2.68. Round with Decimal and ROUND_HALF_UP on the value's 15-digit representation to match.",[169,2858,2860],{"id":2859},"related","Related",[2773,2862,2863,2869,2876,2883],{},[2776,2864,2865,2866,2868],{},"Up one level: ",[28,2867,31],{"href":30}," — number and date formatting.",[2776,2870,2871,2875],{},[28,2872,2874],{"href":2873},"\u002Fformatting-and-charting-excel-reports-with-python\u002Fapplying-number-and-date-formats-in-excel\u002Fwrite-custom-number-format-codes-in-excel-with-python\u002F","Write Custom Number Format Codes in Excel with Python"," — the code syntax the formatter reads.",[2776,2877,2878,2882],{},[28,2879,2881],{"href":2880},"\u002Fformatting-and-charting-excel-reports-with-python\u002Fapplying-number-and-date-formats-in-excel\u002Fshow-negative-numbers-in-red-with-parentheses\u002F","Show Negative Numbers in Red with Parentheses in Excel"," — the sign sections in practice.",[2776,2884,2885,2889],{},[28,2886,2888],{"href":2887},"\u002Fadvanced-data-transformation-and-cleaning\u002Fexcel-formula-equivalents-in-pandas\u002Fmatch-excel-rounding-in-pandas\u002F","Match Excel Rounding in pandas"," — the rounding rule behind the formatter.",[2891,2892,2893],"style",{},"html pre.shiki code .sMTad, html code.shiki .sMTad{--shiki-default:#6F42C1;--shiki-dark:#FFB757}html pre.shiki code .srMev, html code.shiki .srMev{--shiki-default:#032F62;--shiki-dark:#ADDCFF}html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html.dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html pre.shiki code .s-kum, html code.shiki .s-kum{--shiki-default:#D73A49;--shiki-dark:#FF9492}html pre.shiki code .skGVy, html code.shiki .skGVy{--shiki-default:#24292E;--shiki-dark:#F0F3F6}html pre.shiki code .sP0c6, html code.shiki .sP0c6{--shiki-default:#005CC5;--shiki-dark:#91CBFF}html pre.shiki code .sa561, html code.shiki .sa561{--shiki-default:#E36209;--shiki-dark:#FFB757}html pre.shiki code .s-wDw, html code.shiki .s-wDw{--shiki-default:#6A737D;--shiki-dark:#BDC4CC}html pre.shiki code .sSjpA, html code.shiki .sSjpA{--shiki-default:#005CC5;--shiki-dark:#FF9492}html pre.shiki code .s_b0D, html code.shiki .s_b0D{--shiki-default:#22863A;--shiki-default-font-weight:bold;--shiki-dark:#72F088;--shiki-dark-font-weight:bold}html pre.shiki code .s_Opv, html code.shiki .s_Opv{--shiki-default:#6F42C1;--shiki-dark:#DBB7FF}",{"title":179,"searchDepth":229,"depth":229,"links":2895},[2896,2897,2898,2899,2900,2901,2902,2903,2904],{"id":171,"depth":229,"text":172},{"id":587,"depth":229,"text":588},{"id":755,"depth":229,"text":756},{"id":2496,"depth":229,"text":2497},{"id":2744,"depth":229,"text":2745},{"id":2770,"depth":229,"text":2771},{"id":2818,"depth":229,"text":2819},{"id":2831,"depth":229,"text":2832},{"id":2859,"depth":229,"text":2860},"2026-09-23","openpyxl and pandas return the stored value — 1234.5 — not the text Excel shows, such as (1,235) or 05\u002F03\u002F2026. Get the displayed text two ways — exported by LibreOffice, or formatted in Python by a small function that handles common number and date codes — and check them against each other.","md",[2909,2911,2913,2915],{"q":2837,"a":2910},"An .xlsx file stores the value and the number format separately; the displayed text is produced by the application when it draws the cell. openpyxl gives you both parts — cell.value and cell.number_format — but not the combined text.",{"q":2843,"a":2912},"Not from the file alone. The most faithful option without Excel is to let LibreOffice render the workbook and export the formatted text as CSV. With Excel installed on Windows, cell.Text through COM returns exactly what Excel shows.",{"q":2849,"a":2914},"For common codes, yes. A small function that handles thousands separators, decimals, percent, scaling commas, sign sections, literal text and date tokens covers most report formats, provided it rounds halves away from zero like Excel.",{"q":2855,"a":2916},"Python's formatting rounds halves to even and works on the binary value, so 2.675 formats as 2.67. Excel shows 2.68. Round with Decimal and ROUND_HALF_UP on the value's 15-digit representation to match.","read cell values as displayed in excel with python",null,{"breadcrumb":2920},[2921,2923,2926],{"name":2922,"item":1849},"Home",{"name":2924,"item":2925},"Formatting and Charting Excel Reports with Python","\u002Fformatting-and-charting-excel-reports-with-python\u002F",{"name":31,"item":30},"\u002Fformatting-and-charting-excel-reports-with-python\u002Fapplying-number-and-date-formats-in-excel\u002Fread-cell-values-as-displayed-in-excel",{"title":2929,"description":2930},"Read Excel Cell Values as Displayed (Formatted Text) in Python","Get the formatted text of Excel cells in Python — why openpyxl returns raw values, exporting displayed text with LibreOffice, a tested Python formatter for number, currency, percent, scaled and date formats, and where each approach falls short.","read-cell-values-as-displayed-in-excel","formatting-and-charting-excel-reports-with-python\u002Fapplying-number-and-date-formats-in-excel\u002Fread-cell-values-as-displayed-in-excel\u002Findex",[2934,2935,2936],"number-formats","reading-excel","openpyxl","how-to","6JaTqrjhD7OPFGch7WpSIVFTdimI9gBzLqOlvhn4hJM",[2940,2944],{"title":2941,"path":2942,"stem":2943,"children":-1},"Localise an Excel Report for Other Languages and Locales","\u002Fformatting-and-charting-excel-reports-with-python\u002Fapplying-number-and-date-formats-in-excel\u002Flocalise-an-excel-report-for-other-languages-and-locales","formatting-and-charting-excel-reports-with-python\u002Fapplying-number-and-date-formats-in-excel\u002Flocalise-an-excel-report-for-other-languages-and-locales\u002Findex",{"title":2881,"path":2945,"stem":2946,"children":-1},"\u002Fformatting-and-charting-excel-reports-with-python\u002Fapplying-number-and-date-formats-in-excel\u002Fshow-negative-numbers-in-red-with-parentheses","formatting-and-charting-excel-reports-with-python\u002Fapplying-number-and-date-formats-in-excel\u002Fshow-negative-numbers-in-red-with-parentheses\u002Findex",[2948,2950],{"path":2949,"title":31},"\u002Fformatting-and-charting-excel-reports-with-python\u002Fapplying-number-and-date-formats-in-excel",{"path":2951,"title":2924},"\u002Fformatting-and-charting-excel-reports-with-python",[],[2954,2957,2960,2963,2965,2968],{"path":2955,"title":2956,"kind":2937},"\u002Fadvanced-data-transformation-and-cleaning\u002Fcleaning-excel-data-with-pandas\u002Fconvert-currency-strings-to-numbers-with-pandas","Convert Currency Strings Like \"$1,234.56\" and \"(500)\" to Numbers with pandas",{"path":2958,"title":2959,"kind":2937},"\u002Fadvanced-data-transformation-and-cleaning\u002Fcleaning-excel-data-with-pandas\u002Fconvert-percentage-strings-to-numbers-with-pandas","Convert Percentage Strings Like \"12.5%\" to Numbers with pandas",{"path":2961,"title":2962,"kind":2937},"\u002Fadvanced-data-transformation-and-cleaning\u002Fexcel-formula-equivalents-in-pandas\u002Fexcel-text-function-equivalent-in-pandas","Excel TEXT Function Equivalent in pandas",{"path":2964,"title":2888,"kind":2937},"\u002Fadvanced-data-transformation-and-cleaning\u002Fexcel-formula-equivalents-in-pandas\u002Fmatch-excel-rounding-in-pandas",{"path":2966,"title":2967,"kind":2937},"\u002Fadvanced-data-transformation-and-cleaning\u002Fworking-with-dates-and-times-in-excel-data\u002Fconvert-excel-time-values-and-durations","Convert Excel Time Values and Durations in Python",{"path":2969,"title":2970,"kind":2937},"\u002Fautomating-reporting-workflows\u002Fbuilding-multi-sheet-excel-dashboards\u002Fadd-variance-arrows-and-trend-indicators-to-a-dashboard","Add Variance Arrows and Trend Indicators to a Dashboard",1790972107182]