[{"data":1,"prerenderedAt":2175},["ShallowReactive",2],{"doc:\u002Fformatting-and-charting-excel-reports-with-python\u002Fapplying-number-and-date-formats-in-excel\u002Fformat-numbers-in-lakhs-and-crores-in-excel":3,"surround:\u002Fformatting-and-charting-excel-reports-with-python\u002Fapplying-number-and-date-formats-in-excel\u002Fformat-numbers-in-lakhs-and-crores-in-excel":2141,"ancestors:\u002Fformatting-and-charting-excel-reports-with-python\u002Fapplying-number-and-date-formats-in-excel\u002Fformat-numbers-in-lakhs-and-crores-in-excel":2150,"children:\u002Fformatting-and-charting-excel-reports-with-python\u002Fapplying-number-and-date-formats-in-excel\u002Fformat-numbers-in-lakhs-and-crores-in-excel":2155,"related:\u002Fformatting-and-charting-excel-reports-with-python\u002Fapplying-number-and-date-formats-in-excel\u002Fformat-numbers-in-lakhs-and-crores-in-excel":2156},{"id":4,"title":5,"body":6,"dateModified":2108,"datePublished":2108,"description":2109,"extension":2110,"faq":2111,"keyword":2120,"kind":2121,"meta":2122,"navigation":672,"path":2131,"seo":2132,"slug":2135,"stem":2136,"topics":2137,"type":2139,"__hash__":2140},"docs\u002Fformatting-and-charting-excel-reports-with-python\u002Fapplying-number-and-date-formats-in-excel\u002Fformat-numbers-in-lakhs-and-crores-in-excel\u002Findex.md","Format Numbers in Lakhs and Crores in Excel",{"type":7,"value":8,"toc":2097},"minimark",[9,24,29,54,61,65,68,166,190,396,400,407,815,841,845,1263,1282,1424,1428,1434,1827,1838,1977,1981,2021,2025,2032,2036,2042,2048,2054,2060,2064,2093],[10,11,12,13,17,18,23],"p",{},"In India, large numbers are grouped differently from the international style: the first group has three digits and every group after that has two, so one crore is written 1,00,00,000 rather than 10,000,000, and 12,34,56,789 is twelve crore, thirty-four lakh and so on. Readers in India expect reports in that form, and a finance report showing 123,456,789 makes them stop and count digits. Excel can display Indian grouping, but the usual ",[14,15,16],"code",{},"#,##0"," format takes its grouping from the regional settings of whichever computer opens the file — Indian on a machine set to English (India), international everywhere else. A report generated by Python and opened on many machines needs grouping built into the format itself. This page builds that format, handles negative numbers (which the obvious version gets silently wrong), adds the rupee symbol and decimals, checks every case against a Python formatter, and covers reporting in lakhs or crores as units. It belongs to ",[19,20,22],"a",{"href":21},"\u002Fformatting-and-charting-excel-reports-with-python\u002Fapplying-number-and-date-formats-in-excel\u002F","Applying Number and Date Formats in Excel",".",[25,26,28],"h2",{"id":27},"prerequisites","Prerequisites",[30,31,36],"pre",{"className":32,"code":33,"language":34,"meta":35,"style":35},"language-bash shiki shiki-themes github-light github-dark-high-contrast","pip install openpyxl\n","bash","",[14,37,38],{"__ignoreMap":35},[39,40,43,47,51],"span",{"class":41,"line":42},"line",1,[39,44,46],{"class":45},"sMTad","pip",[39,48,50],{"class":49},"srMev"," install",[39,52,53],{"class":49}," openpyxl\n",[10,55,56,57,60],{},"LibreOffice (",[14,58,59],{},"soffice",") is used to export each cell as displayed, so the formats can be checked without Excel.",[25,62,64],{"id":63},"step-1-a-grouping-that-does-not-depend-on-the-computer","Step 1 — A grouping that does not depend on the computer",[10,66,67],{},"A number format can have two conditions in square brackets, followed by a default section. Use them to pick a different layout of separators for numbers of a crore or more, a lakh or more, and smaller numbers:",[30,69,73],{"className":70,"code":71,"language":72,"meta":35,"style":35},"language-python shiki shiki-themes github-light github-dark-high-contrast","LAKH_CRORE = r'[>=10000000]##\\,##\\,##\\,##0.00;[>=100000]##\\,##\\,##0.00;##,##0.00'\nprint(LAKH_CRORE)\n","python",[14,74,75,151],{"__ignoreMap":35},[39,76,77,81,85,88,91,94,98,101,104,108,110,112,114,116,119,121,124,126,129,131,133,135,137,139,141,143,146,148],{"class":41,"line":42},[39,78,80],{"class":79},"sP0c6","LAKH_CRORE",[39,82,84],{"class":83},"s-kum"," =",[39,86,87],{"class":83}," r",[39,89,90],{"class":49},"'",[39,92,93],{"class":79},"[",[39,95,97],{"class":96},"sSjpA",">=10000000",[39,99,100],{"class":79},"]",[39,102,103],{"class":49},"##",[39,105,107],{"class":106},"s_b0D","\\,",[39,109,103],{"class":49},[39,111,107],{"class":106},[39,113,103],{"class":49},[39,115,107],{"class":106},[39,117,118],{"class":49},"##0",[39,120,23],{"class":79},[39,122,123],{"class":49},"00;",[39,125,93],{"class":79},[39,127,128],{"class":96},">=100000",[39,130,100],{"class":79},[39,132,103],{"class":49},[39,134,107],{"class":106},[39,136,103],{"class":49},[39,138,107],{"class":106},[39,140,118],{"class":49},[39,142,23],{"class":79},[39,144,145],{"class":49},"00;##,##0",[39,147,23],{"class":79},[39,149,150],{"class":49},"00'\n",[39,152,154,157,161,163],{"class":41,"line":153},2,[39,155,156],{"class":79},"print",[39,158,160],{"class":159},"skGVy","(",[39,162,80],{"class":79},[39,164,165],{"class":159},")\n",[10,167,168,169,173,174,177,178,181,182,185,186,23],{},"In a number format an unescaped comma between digit placeholders means \"use the thousands separator\", which would put back international grouping. The backslash makes each comma a ",[170,171,172],"em",{},"literal"," character instead, placed exactly where it is written: ",[14,175,176],{},"##\\,##\\,##0"," puts commas after the third and fifth digits from the right, ",[14,179,180],{},"##\\,##\\,##\\,##0"," after the third, fifth and seventh. Numbers below one lakh use ordinary ",[14,183,184],{},"##,##0",", which is the same in both systems — 99,999 is written identically. Testing for the crore case first matters, because conditions are checked in order and every crore value is also at least a lakh. Because the separators are literal, the result looks the same on every computer, whatever its regional settings; the flip side is that it always shows commas and a dot, even in locales that use other characters. The general syntax of conditions and sections is covered in ",[19,187,189],{"href":188},"\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",[191,192,200,201,200,205,200,209,200,217,200,226,200,230,200,237,200,241,200,246,200,248,200,252,200,255,200,259,200,261,200,265,200,268,200,272,200,274,200,277,200,280,200,284,200,286,200,289,200,292,200,296,200,298,200,301,200,304,200,308,200,311,200,313,200,316,200,318,200,321,200,323,200,325,200,327,200,329,200,331,200,333,200,338,200,342,200,344,200,346,200,348,200,351,200,353,200,355,200,357,200,360,200,366,200,370,200,377,200,382,200,390],"svg",{"viewBox":193,"role":194,"ariaLabelledBy":195,"xmlns":198,"style":199},"124 0 512 220","img",[196,197],"lc-group-t","lc-group-d","http:\u002F\u002Fwww.w3.org\u002F2000\u002Fsvg","width:100%;max-width:512px;height:auto;display:block;margin:1.5rem auto;font-family:Inter,ui-sans-serif,system-ui,sans-serif","\n  ",[202,203,204],"title",{"id":196},"International and Indian grouping of the same numbers",[206,207,208],"desc",{"id":197},"One lakh is 100,000 internationally and 1,00,000 in Indian grouping. 1,234,567.89 becomes 12,34,567.89 and 123,456,789 becomes 12,34,56,789. Below one lakh the two systems agree.",[210,211],"rect",{"x":212,"y":213,"width":214,"height":215,"fill":216},"124","0","512","220","#ffffff",[210,218],{"x":219,"y":220,"width":221,"height":222,"rx":213,"fill":223,"stroke":224,"style":225},"140.1","40.0","32.0","24.0","#e7ebef","var(--line,#cdd5e6)","stroke-width:1px",[210,227],{"x":228,"y":220,"width":229,"height":222,"rx":213,"fill":223,"stroke":224,"style":225},"172.1","123.4",[231,232,236],"text",{"x":233,"y":234,"style":235},"233.7","57.0","font-size:11px;font-weight:600;fill:var(--muted,#5b6780);text-anchor:middle","A",[210,238],{"x":219,"y":239,"width":221,"height":240,"rx":213,"fill":223,"stroke":224,"style":225},"64.0","28.0",[231,242,245],{"x":243,"y":244,"style":235},"156.1","83.0","1",[210,247],{"x":228,"y":239,"width":229,"height":240,"rx":213,"fill":216,"stroke":224,"style":225},[231,249,251],{"x":233,"y":244,"style":250},"font-size:12px;font-weight:700;fill:var(--text,#172033);text-anchor:middle","International",[210,253],{"x":219,"y":254,"width":221,"height":240,"rx":213,"fill":223,"stroke":224,"style":225},"92.0",[231,256,258],{"x":243,"y":257,"style":235},"111.0","2",[210,260],{"x":228,"y":254,"width":229,"height":240,"rx":213,"fill":216,"stroke":224,"style":225},[231,262,264],{"x":233,"y":257,"style":263},"font-size:12px;font-weight:400;fill:var(--text,#172033);text-anchor:middle","99,999.50",[210,266],{"x":219,"y":267,"width":221,"height":240,"rx":213,"fill":223,"stroke":224,"style":225},"120.0",[231,269,271],{"x":243,"y":270,"style":235},"139.0","3",[210,273],{"x":228,"y":267,"width":229,"height":240,"rx":213,"fill":216,"stroke":224,"style":225},[231,275,276],{"x":233,"y":270,"style":263},"100,000.00",[210,278],{"x":219,"y":279,"width":221,"height":240,"rx":213,"fill":223,"stroke":224,"style":225},"148.0",[231,281,283],{"x":243,"y":282,"style":235},"167.0","4",[210,285],{"x":228,"y":279,"width":229,"height":240,"rx":213,"fill":216,"stroke":224,"style":225},[231,287,288],{"x":233,"y":282,"style":263},"1,234,567.89",[210,290],{"x":219,"y":291,"width":221,"height":240,"rx":213,"fill":223,"stroke":224,"style":225},"176.0",[231,293,295],{"x":243,"y":294,"style":235},"195.0","5",[210,297],{"x":228,"y":291,"width":229,"height":240,"rx":213,"fill":216,"stroke":224,"style":225},[231,299,300],{"x":233,"y":294,"style":263},"123,456,789.00",[210,302],{"x":303,"y":220,"width":221,"height":222,"rx":213,"fill":223,"stroke":224,"style":225},"460.4",[210,305],{"x":306,"y":220,"width":307,"height":222,"rx":213,"fill":223,"stroke":224,"style":225},"492.4","127.6",[231,309,236],{"x":310,"y":234,"style":235},"556.2",[210,312],{"x":303,"y":239,"width":221,"height":240,"rx":213,"fill":223,"stroke":224,"style":225},[231,314,245],{"x":315,"y":244,"style":235},"476.4",[210,317],{"x":306,"y":239,"width":307,"height":240,"rx":213,"fill":216,"stroke":224,"style":225},[231,319,320],{"x":310,"y":244,"style":250},"Indian",[210,322],{"x":303,"y":254,"width":221,"height":240,"rx":213,"fill":223,"stroke":224,"style":225},[231,324,258],{"x":315,"y":257,"style":235},[210,326],{"x":306,"y":254,"width":307,"height":240,"rx":213,"fill":216,"stroke":224,"style":225},[231,328,264],{"x":310,"y":257,"style":263},[210,330],{"x":303,"y":267,"width":221,"height":240,"rx":213,"fill":223,"stroke":224,"style":225},[231,332,271],{"x":315,"y":270,"style":235},[210,334],{"x":306,"y":267,"width":307,"height":240,"rx":213,"fill":335,"stroke":336,"style":337},"#d9f4f1","var(--teal,#0f9488)","stroke-width:1.5px",[231,339,341],{"x":310,"y":270,"style":340},"font-size:12px;font-weight:700;fill:var(--teal-ink,#0b6157);text-anchor:middle","1,00,000.00",[210,343],{"x":303,"y":279,"width":221,"height":240,"rx":213,"fill":223,"stroke":224,"style":225},[231,345,283],{"x":315,"y":282,"style":235},[210,347],{"x":306,"y":279,"width":307,"height":240,"rx":213,"fill":335,"stroke":336,"style":337},[231,349,350],{"x":310,"y":282,"style":340},"12,34,567.89",[210,352],{"x":303,"y":291,"width":221,"height":240,"rx":213,"fill":223,"stroke":224,"style":225},[231,354,295],{"x":315,"y":294,"style":235},[210,356],{"x":306,"y":291,"width":307,"height":240,"rx":213,"fill":335,"stroke":336,"style":337},[231,358,359],{"x":310,"y":294,"style":340},"12,34,56,789.00",[231,361,365],{"x":362,"y":363,"style":364},"217.7","29.0","font-size:12.5px;font-weight:700;fill:var(--muted,#5b6780);text-anchor:middle","before",[231,367,369],{"x":368,"y":363,"style":364},"540.2","after",[41,371],{"x1":372,"y1":373,"x2":374,"y2":373,"stroke":375,"style":376},"305.4","122.0","446.4","var(--brand,#5b5cf0)","stroke-width:2px",[378,379],"polygon",{"points":380,"fill":381},"450.4,122.0 441.4,127.0 441.4,117.0","#5b5cf0",[210,383],{"x":384,"y":385,"width":386,"height":387,"rx":388,"fill":216,"stroke":224,"style":389},"327.9","89.0","100.0","22.0","11","stroke-width:1.2px",[231,391,395],{"x":392,"y":393,"style":394},"377.9","104.0","font-size:11.5px;font-weight:400;fill:var(--brand-strong,#4338ca);text-anchor:middle;font-family:ui-monospace,SFMono-Regular,Menlo,Consolas,monospace","lakh format",[25,397,399],{"id":398},"step-2-negative-numbers-need-their-own-format","Step 2 — Negative numbers need their own format",[10,401,402,403,406],{},"Both conditions in that format test for large ",[170,404,405],{},"positive"," numbers, so every negative value falls into the default section. Check what that does with a Python formatter to compare against:",[30,408,410],{"className":70,"code":409,"language":72,"meta":35,"style":35},"def indian(x, decimals=2):\n    sign, x = (\"-\" if x \u003C 0 else \"\"), abs(x)\n    whole, frac = f\"{x:.{decimals}f}\".split(\".\")\n    head, tail = whole[:-3], whole[-3:]\n    groups = []\n    while len(head) > 2:\n        groups.insert(0, head[-2:])\n        head = head[:-2]\n    if head:\n        groups.insert(0, head)\n    return sign + \",\".join(groups + [tail]) + \".\" + frac\n\ndef negative_format(v):\n    \"\"\"A single-section format sized for this value; Excel adds the minus sign itself.\"\"\"\n    if abs(v) >= 10_000_000:\n        return r\"##\\,##\\,##\\,##0.00\"\n    if abs(v) >= 100_000:\n        return r\"##\\,##\\,##0.00\"\n    return \"##,##0.00\"\n\nprint(indian(123456789), indian(-1234567), indian(999))\n",[14,411,412,432,472,520,546,557,578,596,614,623,633,667,674,685,691,710,738,754,775,783,788],{"__ignoreMap":35},[39,413,414,417,421,424,427,429],{"class":41,"line":42},[39,415,416],{"class":83},"def",[39,418,420],{"class":419},"s_Opv"," indian",[39,422,423],{"class":159},"(x, decimals",[39,425,426],{"class":83},"=",[39,428,258],{"class":79},[39,430,431],{"class":159},"):\n",[39,433,434,437,439,442,445,448,451,454,457,460,463,466,469],{"class":41,"line":153},[39,435,436],{"class":159},"    sign, x ",[39,438,426],{"class":83},[39,440,441],{"class":159}," (",[39,443,444],{"class":49},"\"-\"",[39,446,447],{"class":83}," if",[39,449,450],{"class":159}," x ",[39,452,453],{"class":83},"\u003C",[39,455,456],{"class":79}," 0",[39,458,459],{"class":83}," else",[39,461,462],{"class":49}," \"\"",[39,464,465],{"class":159},"), ",[39,467,468],{"class":79},"abs",[39,470,471],{"class":159},"(x)\n",[39,473,475,478,480,483,486,489,492,495,497,499,502,505,508,510,512,515,518],{"class":41,"line":474},3,[39,476,477],{"class":159},"    whole, frac ",[39,479,426],{"class":83},[39,481,482],{"class":83}," f",[39,484,485],{"class":49},"\"",[39,487,488],{"class":96},"{",[39,490,491],{"class":159},"x",[39,493,494],{"class":83},":",[39,496,23],{"class":159},[39,498,488],{"class":96},[39,500,501],{"class":159},"decimals",[39,503,504],{"class":96},"}",[39,506,507],{"class":83},"f",[39,509,504],{"class":96},[39,511,485],{"class":49},[39,513,514],{"class":159},".split(",[39,516,517],{"class":49},"\".\"",[39,519,165],{"class":159},[39,521,523,526,528,531,534,536,539,541,543],{"class":41,"line":522},4,[39,524,525],{"class":159},"    head, tail ",[39,527,426],{"class":83},[39,529,530],{"class":159}," whole[:",[39,532,533],{"class":83},"-",[39,535,271],{"class":79},[39,537,538],{"class":159},"], whole[",[39,540,533],{"class":83},[39,542,271],{"class":79},[39,544,545],{"class":159},":]\n",[39,547,549,552,554],{"class":41,"line":548},5,[39,550,551],{"class":159},"    groups ",[39,553,426],{"class":83},[39,555,556],{"class":159}," []\n",[39,558,560,563,566,569,572,575],{"class":41,"line":559},6,[39,561,562],{"class":83},"    while",[39,564,565],{"class":79}," len",[39,567,568],{"class":159},"(head) ",[39,570,571],{"class":83},">",[39,573,574],{"class":79}," 2",[39,576,577],{"class":159},":\n",[39,579,581,584,586,589,591,593],{"class":41,"line":580},7,[39,582,583],{"class":159},"        groups.insert(",[39,585,213],{"class":79},[39,587,588],{"class":159},", head[",[39,590,533],{"class":83},[39,592,258],{"class":79},[39,594,595],{"class":159},":])\n",[39,597,599,602,604,607,609,611],{"class":41,"line":598},8,[39,600,601],{"class":159},"        head ",[39,603,426],{"class":83},[39,605,606],{"class":159}," head[:",[39,608,533],{"class":83},[39,610,258],{"class":79},[39,612,613],{"class":159},"]\n",[39,615,617,620],{"class":41,"line":616},9,[39,618,619],{"class":83},"    if",[39,621,622],{"class":159}," head:\n",[39,624,626,628,630],{"class":41,"line":625},10,[39,627,583],{"class":159},[39,629,213],{"class":79},[39,631,632],{"class":159},", head)\n",[39,634,636,639,642,645,648,651,653,656,658,661,664],{"class":41,"line":635},11,[39,637,638],{"class":83},"    return",[39,640,641],{"class":159}," sign ",[39,643,644],{"class":83},"+",[39,646,647],{"class":49}," \",\"",[39,649,650],{"class":159},".join(groups ",[39,652,644],{"class":83},[39,654,655],{"class":159}," [tail]) ",[39,657,644],{"class":83},[39,659,660],{"class":49}," \".\"",[39,662,663],{"class":83}," +",[39,665,666],{"class":159}," frac\n",[39,668,670],{"class":41,"line":669},12,[39,671,673],{"emptyLinePlaceholder":672},true,"\n",[39,675,677,679,682],{"class":41,"line":676},13,[39,678,416],{"class":83},[39,680,681],{"class":419}," negative_format",[39,683,684],{"class":159},"(v):\n",[39,686,688],{"class":41,"line":687},14,[39,689,690],{"class":49},"    \"\"\"A single-section format sized for this value; Excel adds the minus sign itself.\"\"\"\n",[39,692,694,696,699,702,705,708],{"class":41,"line":693},15,[39,695,619],{"class":83},[39,697,698],{"class":79}," abs",[39,700,701],{"class":159},"(v) ",[39,703,704],{"class":83},">=",[39,706,707],{"class":79}," 10_000_000",[39,709,577],{"class":159},[39,711,713,716,718,721,723,725,727,729,731,733,735],{"class":41,"line":712},16,[39,714,715],{"class":83},"        return",[39,717,87],{"class":83},[39,719,720],{"class":49},"\"##",[39,722,107],{"class":106},[39,724,103],{"class":49},[39,726,107],{"class":106},[39,728,103],{"class":49},[39,730,107],{"class":106},[39,732,118],{"class":49},[39,734,23],{"class":79},[39,736,737],{"class":49},"00\"\n",[39,739,741,743,745,747,749,752],{"class":41,"line":740},17,[39,742,619],{"class":83},[39,744,698],{"class":79},[39,746,701],{"class":159},[39,748,704],{"class":83},[39,750,751],{"class":79}," 100_000",[39,753,577],{"class":159},[39,755,757,759,761,763,765,767,769,771,773],{"class":41,"line":756},18,[39,758,715],{"class":83},[39,760,87],{"class":83},[39,762,720],{"class":49},[39,764,107],{"class":106},[39,766,103],{"class":49},[39,768,107],{"class":106},[39,770,118],{"class":49},[39,772,23],{"class":79},[39,774,737],{"class":49},[39,776,778,780],{"class":41,"line":777},19,[39,779,638],{"class":83},[39,781,782],{"class":49}," \"##,##0.00\"\n",[39,784,786],{"class":41,"line":785},20,[39,787,673],{"emptyLinePlaceholder":672},[39,789,791,793,796,799,802,804,807,809,812],{"class":41,"line":790},21,[39,792,156],{"class":79},[39,794,795],{"class":159},"(indian(",[39,797,798],{"class":79},"123456789",[39,800,801],{"class":159},"), indian(",[39,803,533],{"class":83},[39,805,806],{"class":79},"1234567",[39,808,801],{"class":159},[39,810,811],{"class":79},"999",[39,813,814],{"class":159},"))\n",[10,816,817,818,821,822,825,826,441,829,832,833,836,837,840],{},"The default section of a conditional format does not add a minus sign of its own, and in LibreOffice the number is shown as its absolute value — ",[14,819,820],{},"-1234567"," appears as ",[14,823,824],{},"1,234,567.00",", positive and with international grouping, which is about the worst possible outcome for a finance report. Excel allows only two conditions per format, so one format cannot cover large positives, large negatives and everything in between. Adding negative conditions with a literal minus sign is no cure either: in LibreOffice the first conditional section then shows the sign ",[170,827,828],{},"twice",[14,830,831],{},"--12,34,56,789.00",") while the others show it once. The dependable answer is the oldest rule in number formats: a format with a single section shows negative numbers with a minus sign automatically. Since Python knows each value as it writes it, ",[14,834,835],{},"negative_format()"," picks a single-section format with the right number of literal commas for that value's size. The ",[14,838,839],{},"indian()"," function is the reference everything is checked against below.",[25,842,844],{"id":843},"step-3-apply-the-formats-and-check-every-case","Step 3 — Apply the formats and check every case",[30,846,848],{"className":70,"code":847,"language":72,"meta":35,"style":35},"import csv, subprocess\nfrom openpyxl import Workbook\n\nvalues = [0, 999, 1000, 99999.5, 100000, 1234567.891, 9999999, 10000000, 123456789, 999999999, 1234567890, -50, -1234567, -123456789]\nwb = Workbook()\nws = wb.active\nws.append([\"Value\", \"Indian\"])\nfor v in values:\n    ws.append([v, v])\n    ws.cell(ws.max_row, 2).number_format = negative_format(v) if v \u003C 0 else LAKH_CRORE\nwb.save(\"lakhs.xlsx\")\n\nAS_SHOWN = \"csv:Text - txt - csv (StarCalc):44,34,76,1,,0,false,true,true\"\nsubprocess.run([\"soffice\", \"--headless\", \"--convert-to\", AS_SHOWN, \"--outdir\", \"calc\", \"lakhs.xlsx\"], check=True, capture_output=True)\nwith open(\"calc\u002Flakhs.csv\", encoding=\"utf-8\") as f:\n    rows = list(csv.reader(f))[1:]\nfor (raw, shown), v in zip(rows, values):\n    expected = indian(v)\n    print(f\"{v:>16,.3f}  {shown:>18}  {'ok' if shown == expected else 'differs: expected ' + expected}\")\n",[14,849,850,858,871,875,957,967,977,993,1007,1012,1041,1051,1055,1065,1124,1156,1173,1188,1198],{"__ignoreMap":35},[39,851,852,855],{"class":41,"line":42},[39,853,854],{"class":83},"import",[39,856,857],{"class":159}," csv, subprocess\n",[39,859,860,863,866,868],{"class":41,"line":153},[39,861,862],{"class":83},"from",[39,864,865],{"class":159}," openpyxl ",[39,867,854],{"class":83},[39,869,870],{"class":159}," Workbook\n",[39,872,873],{"class":41,"line":474},[39,874,673],{"emptyLinePlaceholder":672},[39,876,877,880,882,885,887,890,892,894,897,899,902,904,907,909,912,914,917,919,922,924,926,928,931,933,936,938,940,943,945,947,949,951,953,955],{"class":41,"line":522},[39,878,879],{"class":159},"values ",[39,881,426],{"class":83},[39,883,884],{"class":159}," [",[39,886,213],{"class":79},[39,888,889],{"class":159},", ",[39,891,811],{"class":79},[39,893,889],{"class":159},[39,895,896],{"class":79},"1000",[39,898,889],{"class":159},[39,900,901],{"class":79},"99999.5",[39,903,889],{"class":159},[39,905,906],{"class":79},"100000",[39,908,889],{"class":159},[39,910,911],{"class":79},"1234567.891",[39,913,889],{"class":159},[39,915,916],{"class":79},"9999999",[39,918,889],{"class":159},[39,920,921],{"class":79},"10000000",[39,923,889],{"class":159},[39,925,798],{"class":79},[39,927,889],{"class":159},[39,929,930],{"class":79},"999999999",[39,932,889],{"class":159},[39,934,935],{"class":79},"1234567890",[39,937,889],{"class":159},[39,939,533],{"class":83},[39,941,942],{"class":79},"50",[39,944,889],{"class":159},[39,946,533],{"class":83},[39,948,806],{"class":79},[39,950,889],{"class":159},[39,952,533],{"class":83},[39,954,798],{"class":79},[39,956,613],{"class":159},[39,958,959,962,964],{"class":41,"line":548},[39,960,961],{"class":159},"wb ",[39,963,426],{"class":83},[39,965,966],{"class":159}," Workbook()\n",[39,968,969,972,974],{"class":41,"line":559},[39,970,971],{"class":159},"ws ",[39,973,426],{"class":83},[39,975,976],{"class":159}," wb.active\n",[39,978,979,982,985,987,990],{"class":41,"line":580},[39,980,981],{"class":159},"ws.append([",[39,983,984],{"class":49},"\"Value\"",[39,986,889],{"class":159},[39,988,989],{"class":49},"\"Indian\"",[39,991,992],{"class":159},"])\n",[39,994,995,998,1001,1004],{"class":41,"line":598},[39,996,997],{"class":83},"for",[39,999,1000],{"class":159}," v ",[39,1002,1003],{"class":83},"in",[39,1005,1006],{"class":159}," values:\n",[39,1008,1009],{"class":41,"line":616},[39,1010,1011],{"class":159},"    ws.append([v, v])\n",[39,1013,1014,1017,1019,1022,1024,1027,1030,1032,1034,1036,1038],{"class":41,"line":625},[39,1015,1016],{"class":159},"    ws.cell(ws.max_row, ",[39,1018,258],{"class":79},[39,1020,1021],{"class":159},").number_format ",[39,1023,426],{"class":83},[39,1025,1026],{"class":159}," negative_format(v) ",[39,1028,1029],{"class":83},"if",[39,1031,1000],{"class":159},[39,1033,453],{"class":83},[39,1035,456],{"class":79},[39,1037,459],{"class":83},[39,1039,1040],{"class":79}," LAKH_CRORE\n",[39,1042,1043,1046,1049],{"class":41,"line":635},[39,1044,1045],{"class":159},"wb.save(",[39,1047,1048],{"class":49},"\"lakhs.xlsx\"",[39,1050,165],{"class":159},[39,1052,1053],{"class":41,"line":669},[39,1054,673],{"emptyLinePlaceholder":672},[39,1056,1057,1060,1062],{"class":41,"line":676},[39,1058,1059],{"class":79},"AS_SHOWN",[39,1061,84],{"class":83},[39,1063,1064],{"class":49}," \"csv:Text - txt - csv (StarCalc):44,34,76,1,,0,false,true,true\"\n",[39,1066,1067,1070,1073,1075,1078,1080,1083,1085,1087,1089,1092,1094,1097,1099,1101,1104,1108,1110,1113,1115,1118,1120,1122],{"class":41,"line":687},[39,1068,1069],{"class":159},"subprocess.run([",[39,1071,1072],{"class":49},"\"soffice\"",[39,1074,889],{"class":159},[39,1076,1077],{"class":49},"\"--headless\"",[39,1079,889],{"class":159},[39,1081,1082],{"class":49},"\"--convert-to\"",[39,1084,889],{"class":159},[39,1086,1059],{"class":79},[39,1088,889],{"class":159},[39,1090,1091],{"class":49},"\"--outdir\"",[39,1093,889],{"class":159},[39,1095,1096],{"class":49},"\"calc\"",[39,1098,889],{"class":159},[39,1100,1048],{"class":49},[39,1102,1103],{"class":159},"], ",[39,1105,1107],{"class":1106},"sa561","check",[39,1109,426],{"class":83},[39,1111,1112],{"class":79},"True",[39,1114,889],{"class":159},[39,1116,1117],{"class":1106},"capture_output",[39,1119,426],{"class":83},[39,1121,1112],{"class":79},[39,1123,165],{"class":159},[39,1125,1126,1129,1132,1134,1137,1139,1142,1144,1147,1150,1153],{"class":41,"line":693},[39,1127,1128],{"class":83},"with",[39,1130,1131],{"class":79}," open",[39,1133,160],{"class":159},[39,1135,1136],{"class":49},"\"calc\u002Flakhs.csv\"",[39,1138,889],{"class":159},[39,1140,1141],{"class":1106},"encoding",[39,1143,426],{"class":83},[39,1145,1146],{"class":49},"\"utf-8\"",[39,1148,1149],{"class":159},") ",[39,1151,1152],{"class":83},"as",[39,1154,1155],{"class":159}," f:\n",[39,1157,1158,1161,1163,1166,1169,1171],{"class":41,"line":712},[39,1159,1160],{"class":159},"    rows ",[39,1162,426],{"class":83},[39,1164,1165],{"class":79}," list",[39,1167,1168],{"class":159},"(csv.reader(f))[",[39,1170,245],{"class":79},[39,1172,545],{"class":159},[39,1174,1175,1177,1180,1182,1185],{"class":41,"line":740},[39,1176,997],{"class":83},[39,1178,1179],{"class":159}," (raw, shown), v ",[39,1181,1003],{"class":83},[39,1183,1184],{"class":79}," zip",[39,1186,1187],{"class":159},"(rows, values):\n",[39,1189,1190,1193,1195],{"class":41,"line":756},[39,1191,1192],{"class":159},"    expected ",[39,1194,426],{"class":83},[39,1196,1197],{"class":159}," indian(v)\n",[39,1199,1200,1203,1205,1207,1209,1211,1214,1217,1219,1222,1225,1228,1230,1232,1235,1237,1240,1243,1246,1249,1252,1254,1257,1259,1261],{"class":41,"line":777},[39,1201,1202],{"class":79},"    print",[39,1204,160],{"class":159},[39,1206,507],{"class":83},[39,1208,485],{"class":49},[39,1210,488],{"class":96},[39,1212,1213],{"class":159},"v",[39,1215,1216],{"class":83},":>16,.3f",[39,1218,504],{"class":96},[39,1220,1221],{"class":96},"  {",[39,1223,1224],{"class":159},"shown",[39,1226,1227],{"class":83},":>18",[39,1229,504],{"class":96},[39,1231,1221],{"class":96},[39,1233,1234],{"class":49},"'ok'",[39,1236,447],{"class":83},[39,1238,1239],{"class":159}," shown ",[39,1241,1242],{"class":83},"==",[39,1244,1245],{"class":159}," expected ",[39,1247,1248],{"class":83},"else",[39,1250,1251],{"class":49}," 'differs: expected '",[39,1253,663],{"class":83},[39,1255,1256],{"class":159}," expected",[39,1258,504],{"class":96},[39,1260,485],{"class":49},[39,1262,165],{"class":159},[10,1264,1265,1266,1269,1270,1273,1274,1277,1278,1281],{},"Every value matches the reference except one: 1,234,567,890 — 123 crore — displays as ",[14,1267,1268],{},"123,45,67,890.00",", where Indian grouping would be ",[14,1271,1272],{},"1,23,45,67,890.00",". The crore format has a fixed number of literal commas, and with only two conditions available there is no way to add a third tier for a hundred crore. For most reports — invoices, departmental budgets, sales by region — values stay well below 100 crore and the format is exact. For company-level totals that can exceed it, report in crores instead, as in Step 4. Negative values show their sign and Indian grouping, ",[14,1275,1276],{},"-12,34,567.00"," and ",[14,1279,1280],{},"-12,34,56,789.00",". Python picking the format per cell has one limitation worth stating: the negative formats are sized for the value written, and if someone later types a different number into the cell in Excel, the cell keeps the old format, so apply this to report output, not to input sheets.",[191,1283,200,1289,200,1292,200,1295,200,1299,200,1304,200,1309,200,1315,200,1318,200,1322,200,1325,200,1329,200,1333,200,1338,200,1340,200,1344,200,1346,200,1348,200,1350,200,1360,200,1363,200,1367,200,1369,200,1371,200,1373,200,1375,200,1377,200,1382,200,1385,200,1389,200,1391,200,1394,200,1396,200,1398,200,1400,200,1403,200,1406,200,1410,200,1412,200,1415,200,1417,200,1419,200,1421],{"viewBox":1284,"role":194,"ariaLabelledBy":1285,"xmlns":198,"style":1288},"4 0 752 208",[1286,1287],"lc-check-t","lc-check-d","width:100%;max-width:752px;height:auto;display:block;margin:1.5rem auto;font-family:Inter,ui-sans-serif,system-ui,sans-serif",[202,1290,1291],{"id":1286},"How each range of values displays",[206,1293,1294],{"id":1287},"Values below one lakh display identically in both systems. Values from one lakh to just under 100 crore display exactly in Indian grouping. Values of 100 crore or more show extra digits in the first group. Negative values display correctly only with a single-section format sized for the value.",[210,1296],{"x":283,"y":213,"width":1297,"height":1298,"fill":216},"752","208",[210,1300],{"x":1301,"y":1302,"width":1303,"height":220,"rx":213,"fill":216,"stroke":224,"style":225},"20.0","16.0","130.9",[210,1305],{"x":1306,"y":1302,"width":1307,"height":220,"rx":213,"fill":1308,"stroke":375,"style":389},"150.9","196.4","#f0f4ff",[231,1310,1314],{"x":1311,"y":1312,"style":1313},"249.1","41.0","font-size:13px;font-weight:700;fill:var(--brand-strong,#4338ca);text-anchor:middle","example",[210,1316],{"x":1317,"y":1302,"width":1307,"height":220,"rx":213,"fill":1308,"stroke":375,"style":389},"347.3",[231,1319,1321],{"x":1320,"y":1312,"style":1313},"445.5","displayed",[210,1323],{"x":1324,"y":1302,"width":1307,"height":220,"rx":213,"fill":1308,"stroke":375,"style":389},"543.6",[231,1326,1328],{"x":1327,"y":1312,"style":1313},"641.8","correct?",[210,1330],{"x":1301,"y":1331,"width":1303,"height":1332,"rx":213,"fill":223,"stroke":224,"style":225},"56.0","34.0",[231,1334,1337],{"x":221,"y":1335,"style":1336},"78.0","font-size:12.5px;font-weight:700;fill:var(--text,#172033);text-anchor:start","\u003C 1 lakh",[210,1339],{"x":1306,"y":1331,"width":1307,"height":1332,"rx":213,"fill":216,"stroke":224,"style":225},[231,1341,264],{"x":1311,"y":1342,"style":1343},"77.0","font-size:11.5px;font-weight:400;fill:var(--text,#172033);text-anchor:middle",[210,1345],{"x":1317,"y":1331,"width":1307,"height":1332,"rx":213,"fill":216,"stroke":224,"style":225},[231,1347,264],{"x":1320,"y":1342,"style":1343},[210,1349],{"x":1324,"y":1331,"width":1307,"height":1332,"rx":213,"fill":216,"stroke":224,"style":225},[1351,1352,1354],"g",{"transform":1353},"translate(632.8,64.0) scale(0.750)",[1355,1356],"path",{"d":1357,"fill":1358,"stroke":336,"style":1359},"M5 12.5l4.5 4.5L19 7","none","stroke-width:2.40px;stroke-linecap:round;stroke-linejoin:round",[210,1361],{"x":1301,"y":1362,"width":1303,"height":1332,"rx":213,"fill":223,"stroke":224,"style":225},"90.0",[231,1364,1366],{"x":221,"y":1365,"style":1336},"112.0","1 lakh – 99 crore",[210,1368],{"x":1306,"y":1362,"width":1307,"height":1332,"rx":213,"fill":216,"stroke":224,"style":225},[231,1370,798],{"x":1311,"y":257,"style":1343},[210,1372],{"x":1317,"y":1362,"width":1307,"height":1332,"rx":213,"fill":216,"stroke":224,"style":225},[231,1374,359],{"x":1320,"y":257,"style":1343},[210,1376],{"x":1324,"y":1362,"width":1307,"height":1332,"rx":213,"fill":216,"stroke":224,"style":225},[1351,1378,1380],{"transform":1379},"translate(632.8,98.0) scale(0.750)",[1355,1381],{"d":1357,"fill":1358,"stroke":336,"style":1359},[210,1383],{"x":1301,"y":1384,"width":1303,"height":1332,"rx":213,"fill":223,"stroke":224,"style":225},"124.0",[231,1386,1388],{"x":221,"y":1387,"style":1336},"146.0","≥ 100 crore",[210,1390],{"x":1306,"y":1384,"width":1307,"height":1332,"rx":213,"fill":216,"stroke":224,"style":225},[231,1392,935],{"x":1311,"y":1393,"style":1343},"145.0",[210,1395],{"x":1317,"y":1384,"width":1307,"height":1332,"rx":213,"fill":216,"stroke":224,"style":225},[231,1397,1268],{"x":1320,"y":1393,"style":1343},[210,1399],{"x":1324,"y":1384,"width":1307,"height":1332,"rx":213,"fill":216,"stroke":224,"style":225},[231,1401,1402],{"x":1327,"y":1393,"style":1343},"no — use crores",[210,1404],{"x":1301,"y":1405,"width":1303,"height":1332,"rx":213,"fill":223,"stroke":224,"style":225},"158.0",[231,1407,1409],{"x":221,"y":1408,"style":1336},"180.0","negative",[210,1411],{"x":1306,"y":1405,"width":1307,"height":1332,"rx":213,"fill":216,"stroke":224,"style":225},[231,1413,820],{"x":1311,"y":1414,"style":1343},"179.0",[210,1416],{"x":1317,"y":1405,"width":1307,"height":1332,"rx":213,"fill":216,"stroke":224,"style":225},[231,1418,1276],{"x":1320,"y":1414,"style":1343},[210,1420],{"x":1324,"y":1405,"width":1307,"height":1332,"rx":213,"fill":216,"stroke":224,"style":225},[231,1422,1423],{"x":1327,"y":1414,"style":1343},"with a sized format",[25,1425,1427],{"id":1426},"step-4-the-rupee-symbol-and-reporting-in-lakhs-or-crores","Step 4 — The rupee symbol, and reporting in lakhs or crores",[10,1429,1430,1431,1433],{},"The rupee symbol goes in as a literal in each section, and for large totals it is usually clearer to show amounts ",[170,1432,1003],{}," lakhs or crores rather than with all their digits:",[30,1435,1437],{"className":70,"code":1436,"language":72,"meta":35,"style":35},"from openpyxl.styles import Font\n\nRUPEE = r'[>=10000000]\"₹\"##\\,##\\,##\\,##0;[>=100000]\"₹\"##\\,##\\,##0;\"₹\"##,##0'\nIN_CRORE = r'\"₹\"#,##0.00\" Cr\";\"-₹\"#,##0.00\" Cr\"'\n\ntotals = wb.create_sheet(\"Totals\")\ntotals.append([\"Region\", \"Revenue\", \"Revenue (₹ crore)\"])\nfor name, amount in [(\"North\", 412_385_000), (\"South\", 1_865_240_500), (\"West\", 96_500_250)]:\n    r = totals.max_row + 1\n    totals.append([name, amount, f\"=B{r}\u002F10^7\"])\n    totals[f\"B{r}\"].number_format = RUPEE\n    totals[f\"C{r}\"].number_format = IN_CRORE\nfor c in totals[1]:\n    c.font = Font(bold=True)\nwb.save(\"lakhs.xlsx\")\nsubprocess.run([\"soffice\", \"--headless\", \"--convert-to\", \"csv:Text - txt - csv (StarCalc):44,34,76,1,,0,false,true,true,false,false,-1\",\n                \"--outdir\", \"calc\", \"lakhs.xlsx\"], check=True, capture_output=True)\nfrom pathlib import Path\nprint(Path(\"calc\u002Flakhs-Totals.csv\").read_text(encoding=\"utf-8\"))\n",[14,1438,1439,1451,1455,1505,1527,1531,1546,1566,1610,1625,1647,1673,1697,1714,1733,1741,1763,1794,1806],{"__ignoreMap":35},[39,1440,1441,1443,1446,1448],{"class":41,"line":42},[39,1442,862],{"class":83},[39,1444,1445],{"class":159}," openpyxl.styles ",[39,1447,854],{"class":83},[39,1449,1450],{"class":159}," Font\n",[39,1452,1453],{"class":41,"line":153},[39,1454,673],{"emptyLinePlaceholder":672},[39,1456,1457,1460,1462,1464,1466,1468,1470,1472,1475,1477,1479,1481,1483,1485,1488,1490,1492,1494,1496,1498,1500,1502],{"class":41,"line":474},[39,1458,1459],{"class":79},"RUPEE",[39,1461,84],{"class":83},[39,1463,87],{"class":83},[39,1465,90],{"class":49},[39,1467,93],{"class":79},[39,1469,97],{"class":96},[39,1471,100],{"class":79},[39,1473,1474],{"class":49},"\"₹\"##",[39,1476,107],{"class":106},[39,1478,103],{"class":49},[39,1480,107],{"class":106},[39,1482,103],{"class":49},[39,1484,107],{"class":106},[39,1486,1487],{"class":49},"##0;",[39,1489,93],{"class":79},[39,1491,128],{"class":96},[39,1493,100],{"class":79},[39,1495,1474],{"class":49},[39,1497,107],{"class":106},[39,1499,103],{"class":49},[39,1501,107],{"class":106},[39,1503,1504],{"class":49},"##0;\"₹\"##,##0'\n",[39,1506,1507,1510,1512,1514,1517,1519,1522,1524],{"class":41,"line":522},[39,1508,1509],{"class":79},"IN_CRORE",[39,1511,84],{"class":83},[39,1513,87],{"class":83},[39,1515,1516],{"class":49},"'\"₹\"#,##0",[39,1518,23],{"class":79},[39,1520,1521],{"class":49},"00\" Cr\";\"-₹\"#,##0",[39,1523,23],{"class":79},[39,1525,1526],{"class":49},"00\" Cr\"'\n",[39,1528,1529],{"class":41,"line":548},[39,1530,673],{"emptyLinePlaceholder":672},[39,1532,1533,1536,1538,1541,1544],{"class":41,"line":559},[39,1534,1535],{"class":159},"totals ",[39,1537,426],{"class":83},[39,1539,1540],{"class":159}," wb.create_sheet(",[39,1542,1543],{"class":49},"\"Totals\"",[39,1545,165],{"class":159},[39,1547,1548,1551,1554,1556,1559,1561,1564],{"class":41,"line":580},[39,1549,1550],{"class":159},"totals.append([",[39,1552,1553],{"class":49},"\"Region\"",[39,1555,889],{"class":159},[39,1557,1558],{"class":49},"\"Revenue\"",[39,1560,889],{"class":159},[39,1562,1563],{"class":49},"\"Revenue (₹ crore)\"",[39,1565,992],{"class":159},[39,1567,1568,1570,1573,1575,1578,1581,1583,1586,1589,1592,1594,1597,1599,1602,1604,1607],{"class":41,"line":598},[39,1569,997],{"class":83},[39,1571,1572],{"class":159}," name, amount ",[39,1574,1003],{"class":83},[39,1576,1577],{"class":159}," [(",[39,1579,1580],{"class":49},"\"North\"",[39,1582,889],{"class":159},[39,1584,1585],{"class":79},"412_385_000",[39,1587,1588],{"class":159},"), (",[39,1590,1591],{"class":49},"\"South\"",[39,1593,889],{"class":159},[39,1595,1596],{"class":79},"1_865_240_500",[39,1598,1588],{"class":159},[39,1600,1601],{"class":49},"\"West\"",[39,1603,889],{"class":159},[39,1605,1606],{"class":79},"96_500_250",[39,1608,1609],{"class":159},")]:\n",[39,1611,1612,1615,1617,1620,1622],{"class":41,"line":616},[39,1613,1614],{"class":159},"    r ",[39,1616,426],{"class":83},[39,1618,1619],{"class":159}," totals.max_row ",[39,1621,644],{"class":83},[39,1623,1624],{"class":79}," 1\n",[39,1626,1627,1630,1632,1635,1637,1640,1642,1645],{"class":41,"line":625},[39,1628,1629],{"class":159},"    totals.append([name, amount, ",[39,1631,507],{"class":83},[39,1633,1634],{"class":49},"\"=B",[39,1636,488],{"class":96},[39,1638,1639],{"class":159},"r",[39,1641,504],{"class":96},[39,1643,1644],{"class":49},"\u002F10^7\"",[39,1646,992],{"class":159},[39,1648,1649,1652,1654,1657,1659,1661,1663,1665,1668,1670],{"class":41,"line":635},[39,1650,1651],{"class":159},"    totals[",[39,1653,507],{"class":83},[39,1655,1656],{"class":49},"\"B",[39,1658,488],{"class":96},[39,1660,1639],{"class":159},[39,1662,504],{"class":96},[39,1664,485],{"class":49},[39,1666,1667],{"class":159},"].number_format ",[39,1669,426],{"class":83},[39,1671,1672],{"class":79}," RUPEE\n",[39,1674,1675,1677,1679,1682,1684,1686,1688,1690,1692,1694],{"class":41,"line":669},[39,1676,1651],{"class":159},[39,1678,507],{"class":83},[39,1680,1681],{"class":49},"\"C",[39,1683,488],{"class":96},[39,1685,1639],{"class":159},[39,1687,504],{"class":96},[39,1689,485],{"class":49},[39,1691,1667],{"class":159},[39,1693,426],{"class":83},[39,1695,1696],{"class":79}," IN_CRORE\n",[39,1698,1699,1701,1704,1706,1709,1711],{"class":41,"line":676},[39,1700,997],{"class":83},[39,1702,1703],{"class":159}," c ",[39,1705,1003],{"class":83},[39,1707,1708],{"class":159}," totals[",[39,1710,245],{"class":79},[39,1712,1713],{"class":159},"]:\n",[39,1715,1716,1719,1721,1724,1727,1729,1731],{"class":41,"line":687},[39,1717,1718],{"class":159},"    c.font ",[39,1720,426],{"class":83},[39,1722,1723],{"class":159}," Font(",[39,1725,1726],{"class":1106},"bold",[39,1728,426],{"class":83},[39,1730,1112],{"class":79},[39,1732,165],{"class":159},[39,1734,1735,1737,1739],{"class":41,"line":693},[39,1736,1045],{"class":159},[39,1738,1048],{"class":49},[39,1740,165],{"class":159},[39,1742,1743,1745,1747,1749,1751,1753,1755,1757,1760],{"class":41,"line":712},[39,1744,1069],{"class":159},[39,1746,1072],{"class":49},[39,1748,889],{"class":159},[39,1750,1077],{"class":49},[39,1752,889],{"class":159},[39,1754,1082],{"class":49},[39,1756,889],{"class":159},[39,1758,1759],{"class":49},"\"csv:Text - txt - csv (StarCalc):44,34,76,1,,0,false,true,true,false,false,-1\"",[39,1761,1762],{"class":159},",\n",[39,1764,1765,1768,1770,1772,1774,1776,1778,1780,1782,1784,1786,1788,1790,1792],{"class":41,"line":740},[39,1766,1767],{"class":49},"                \"--outdir\"",[39,1769,889],{"class":159},[39,1771,1096],{"class":49},[39,1773,889],{"class":159},[39,1775,1048],{"class":49},[39,1777,1103],{"class":159},[39,1779,1107],{"class":1106},[39,1781,426],{"class":83},[39,1783,1112],{"class":79},[39,1785,889],{"class":159},[39,1787,1117],{"class":1106},[39,1789,426],{"class":83},[39,1791,1112],{"class":79},[39,1793,165],{"class":159},[39,1795,1796,1798,1801,1803],{"class":41,"line":756},[39,1797,862],{"class":83},[39,1799,1800],{"class":159}," pathlib ",[39,1802,854],{"class":83},[39,1804,1805],{"class":159}," Path\n",[39,1807,1808,1810,1813,1816,1819,1821,1823,1825],{"class":41,"line":777},[39,1809,156],{"class":79},[39,1811,1812],{"class":159},"(Path(",[39,1814,1815],{"class":49},"\"calc\u002Flakhs-Totals.csv\"",[39,1817,1818],{"class":159},").read_text(",[39,1820,1141],{"class":1106},[39,1822,426],{"class":83},[39,1824,1146],{"class":49},[39,1826,814],{"class":159},[10,1828,1829,1830,1833,1834,23],{},"Number formats can scale by thousands — each trailing comma divides by 1,000 — but not by a lakh (100,000) or a crore (10,000,000), so the division is done with a formula, ",[14,1831,1832],{},"=B2\u002F10^7",", and the format adds the \"Cr\" label. The South total of ₹186.5 crore shows the full-digit format's limit from Step 3 — its 1,865,240,500 is over 100 crore, so the full figure has an extra digit in its first group — while the crore column reads cleanly as ₹186.52 Cr. A formula column also keeps the full-precision value available for anyone who needs it. For other localisation needs — month names, decimal commas, currency placement — see ",[19,1835,1837],{"href":1836},"\u002Fformatting-and-charting-excel-reports-with-python\u002Fapplying-number-and-date-formats-in-excel\u002Flocalise-an-excel-report-for-other-languages-and-locales\u002F","Localise an Excel Report for Other Languages and Locales",[191,1839,200,1844,200,1847,200,1850,200,1853,200,1859,200,1867,200,1872,200,1876,200,1880,200,1883,200,1886,200,1893,200,1898,200,1903,200,1910,200,1915,200,1919,200,1921,200,1924,200,1928,200,1931,200,1934,200,1940,200,1943,200,1946,200,1948,200,1951,200,1955,200,1958,200,1963,200,1970,200,1974],{"viewBox":1840,"role":194,"ariaLabelledBy":1841,"xmlns":198,"style":1288},"4 0 752 272",[1842,1843],"lc-choose-t","lc-choose-d",[202,1845,1846],{"id":1842},"Which format for which figure",[206,1848,1849],{"id":1843},"Line-level amounts under 100 crore use the lakh and crore grouping format, with a single-section format sized for each negative value. Large totals are better shown in crores with a formula dividing by ten million and a Cr label. Input cells that people type into should keep a plain format.",[210,1851],{"x":283,"y":213,"width":1297,"height":1852,"fill":216},"272",[210,1854],{"x":1855,"y":1302,"width":1856,"height":1857,"rx":1858,"fill":1308,"stroke":375,"style":376},"240.0","280.0","75.5","12",[1351,1860,1862],{"transform":1861},"translate(368.0,29.0) scale(1.000)",[1355,1863],{"d":1864,"fill":1358,"stroke":1865,"style":1866},"M5 9h14 M4 15h14 M10 4l-2 16 M16 4l-2 16","var(--brand-strong,#4338ca)","stroke-width:1.80px;stroke-linecap:round;stroke-linejoin:round",[231,1868,1871],{"x":1869,"y":1857,"style":1870},"380.0","font-size:13.5px;font-weight:700;fill:var(--brand-strong,#4338ca);text-anchor:middle","What is being shown?",[41,1873],{"x1":1869,"y1":1874,"x2":1869,"y2":1875,"stroke":375,"style":376},"91.5","111.5",[41,1877],{"x1":1878,"y1":1875,"x2":1879,"y2":1875,"stroke":375,"style":376},"134.7","625.3",[41,1881],{"x1":1878,"y1":1875,"x2":1878,"y2":1882,"stroke":375,"style":376},"157.5",[378,1884],{"points":1885,"fill":381},"134.7,161.5 129.7,152.5 139.7,152.5",[210,1887],{"x":1888,"y":1889,"width":1890,"height":1891,"rx":1892,"fill":216,"stroke":224,"style":389},"64.9","121.5","139.5","21.0","10",[231,1894,1897],{"x":1878,"y":1895,"style":1896},"136.0","font-size:11.5px;font-weight:700;fill:var(--muted,#5b6780);text-anchor:middle","amounts \u003C 100 crore",[210,1899],{"x":1301,"y":1900,"width":1901,"height":1902,"rx":1858,"fill":335,"stroke":336,"style":376},"163.5","229.3","93.0",[1351,1904,1906],{"transform":1905},"translate(122.7,176.5) scale(1.000)",[1355,1907],{"d":1908,"fill":1358,"stroke":1909,"style":1866},"M3 5h18v14H3z M3 10h18 M3 15h18 M9 5v14","var(--teal-ink,#0b6157)",[231,1911,1914],{"x":1878,"y":1912,"style":1913},"223.0","font-size:13.5px;font-weight:700;fill:var(--teal-ink,#0b6157);text-anchor:middle","lakh-crore format",[231,1916,1918],{"x":1878,"y":1917,"style":1343},"242.5","sized format for \u003C 0",[41,1920],{"x1":1869,"y1":1875,"x2":1869,"y2":1882,"stroke":375,"style":376},[378,1922],{"points":1923,"fill":381},"380.0,161.5 375.0,152.5 385.0,152.5",[210,1925],{"x":1926,"y":1889,"width":1927,"height":1891,"rx":1892,"fill":216,"stroke":224,"style":389},"337.9","84.2",[231,1929,1930],{"x":1869,"y":1895,"style":1896},"large totals",[210,1932],{"x":1933,"y":1900,"width":1901,"height":1902,"rx":1858,"fill":1308,"stroke":375,"style":376},"265.3",[1351,1935,1937],{"transform":1936},"translate(368.0,176.5) scale(1.000)",[1355,1938],{"d":1939,"fill":1358,"stroke":1865,"style":1866},"M4 20h16 M7 17v-5 M12 17V7 M17 17v-8",[231,1941,1942],{"x":1869,"y":1912,"style":1870},"in crores: =B2\u002F10^7",[231,1944,1945],{"x":1869,"y":1917,"style":1343},"\"₹\"#,##0.00\" Cr\"",[41,1947],{"x1":1879,"y1":1875,"x2":1879,"y2":1882,"stroke":375,"style":376},[378,1949],{"points":1950,"fill":381},"625.3,161.5 620.3,152.5 630.3,152.5",[210,1952],{"x":1953,"y":1889,"width":1954,"height":1891,"rx":1892,"fill":216,"stroke":224,"style":389},"585.9","78.8",[231,1956,1957],{"x":1879,"y":1895,"style":1896},"input cells",[210,1959],{"x":1960,"y":1900,"width":1901,"height":1902,"rx":1858,"fill":1961,"stroke":1962,"style":376},"510.7","#fdefd8","var(--gold,#b4740a)",[1351,1964,1966],{"transform":1965},"translate(613.3,176.5) scale(1.000)",[1355,1967],{"d":1968,"fill":1358,"stroke":1969,"style":1866},"M12 12a4 4 0 1 0 0-8 4 4 0 0 0 0 8z M4 21c0-4 3.6-7 8-7s8 3 8 7","var(--gold-ink,#7a4e06)",[231,1971,1973],{"x":1879,"y":1912,"style":1972},"font-size:13.5px;font-weight:700;fill:var(--gold-ink,#7a4e06);text-anchor:middle","plain #,##0",[231,1975,1976],{"x":1879,"y":1917,"style":1343},"users may change sign",[25,1978,1980],{"id":1979},"common-pitfalls","Common pitfalls",[1982,1983,1984,1994,2003,2009,2015],"ul",{},[1985,1986,1987,1993],"li",{},[1988,1989,1990,1991,23],"strong",{},"Relying on ",[14,1992,16],{}," Its grouping comes from the reader's regional settings.",[1985,1995,1996,1999,2000,2002],{},[1988,1997,1998],{},"Unescaped commas."," Write ",[14,2001,107],{}," so commas are literal, not thousands separators.",[1985,2004,2005,2008],{},[1988,2006,2007],{},"Negatives in a conditional format."," They lose their sign or gain two; give them a single-section format.",[1985,2010,2011,2014],{},[1988,2012,2013],{},"Values of 100 crore or more."," The grouping breaks; show them in crores.",[1985,2016,2017,2020],{},[1988,2018,2019],{},"Scaling with commas."," Commas divide by 1,000 only; divide by 10^5 or 10^7 with a formula.",[25,2022,2024],{"id":2023},"conclusion","Conclusion",[10,2026,2027,2028,2031],{},"To show Indian digit grouping in a generated workbook, use a conditional number format with literal commas — one layout for a crore or more, one for a lakh or more, and ",[14,2029,2030],{},"##,##0.00"," for the rest — and, for negative values, a single-section format with the right number of literal commas, chosen per cell in Python so the minus sign is added automatically. Check the display against a Python formatter with a LibreOffice CSV export, and show totals of 100 crore or more in crores with a formula and a \"Cr\" label.",[25,2033,2035],{"id":2034},"frequently-asked-questions","Frequently asked questions",[10,2037,2038,2041],{},[1988,2039,2040],{},"How do I format numbers in lakhs and crores in Excel?","\nUse a custom number format with two conditions — one for a crore or more, one for a lakh or more — and literal commas written as backslash-comma, with ordinary ##,##0 as the third section; the exact code is shown in Step 1.",[10,2043,2044,2047],{},[1988,2045,2046],{},"Why does #,##0 show Indian grouping on some computers but not others?","\nExcel takes the digit grouping for the thousands separator from the operating system's regional settings, so it depends on the computer that opens the file.",[10,2049,2050,2053],{},[1988,2051,2052],{},"Why do negative numbers lose their minus sign with the lakh format?","\nNegative values fall into the default section of a conditional format, which does not add a minus sign; give negative cells a single-section format such as ##,##,##0.00, which shows the minus sign automatically.",[10,2055,2056,2059],{},[1988,2057,2058],{},"How do I show values in crores in Excel?","\nDivide by 10^7 in a formula and apply a format such as \"₹\"#,##0.00\" Cr\", because number formats can only scale by thousands.",[25,2061,2063],{"id":2062},"related","Related",[1982,2065,2066,2072,2079,2086],{},[1985,2067,2068,2069,2071],{},"Up one level: ",[19,2070,22],{"href":21}," — number formats from Python.",[1985,2073,2074,2078],{},[19,2075,2077],{"href":2076},"\u002Fformatting-and-charting-excel-reports-with-python\u002Fapplying-number-and-date-formats-in-excel\u002Fformat-numbers-in-thousands-and-millions-in-excel\u002F","Format Numbers in Thousands and Millions in Excel"," — scaling with commas.",[1985,2080,2081,2085],{},[19,2082,2084],{"href":2083},"\u002Fformatting-and-charting-excel-reports-with-python\u002Fapplying-number-and-date-formats-in-excel\u002Fformat-excel-cells-as-currency-with-python\u002F","Format Excel Cells as Currency with Python"," — currency symbols.",[1985,2087,2088,2092],{},[19,2089,2091],{"href":2090},"\u002Fformatting-and-charting-excel-reports-with-python\u002Fapplying-number-and-date-formats-in-excel\u002Fshow-zeros-as-dashes-or-hide-them-in-excel\u002F","Show Zeros as Dashes or Hide Them in Excel"," — the zero section.",[2094,2095,2096],"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 .sP0c6, html code.shiki .sP0c6{--shiki-default:#005CC5;--shiki-dark:#91CBFF}html pre.shiki code .s-kum, html code.shiki .s-kum{--shiki-default:#D73A49;--shiki-dark:#FF9492}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 .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 .sa561, html code.shiki .sa561{--shiki-default:#E36209;--shiki-dark:#FFB757}",{"title":35,"searchDepth":153,"depth":153,"links":2098},[2099,2100,2101,2102,2103,2104,2105,2106,2107],{"id":27,"depth":153,"text":28},{"id":63,"depth":153,"text":64},{"id":398,"depth":153,"text":399},{"id":843,"depth":153,"text":844},{"id":1426,"depth":153,"text":1427},{"id":1979,"depth":153,"text":1980},{"id":2023,"depth":153,"text":2024},{"id":2034,"depth":153,"text":2035},{"id":2062,"depth":153,"text":2063},"2026-10-02","Show amounts with Indian digit grouping — 12,34,56,789 instead of 123,456,789 — in Excel files generated with Python: a conditional number format that groups by lakh and crore on any computer, a matching format for negative numbers, the ₹ symbol and decimals, the limits of the approach above 100 crore, a Python formatter to check every case, and when to report in lakhs or crores instead.","md",[2112,2114,2116,2118],{"q":2040,"a":2113},"Use a custom number format with two conditions — one for a crore or more, one for a lakh or more — and literal commas written as backslash-comma, with ordinary ##,##0 as the third section; the exact code is shown in Step 1.",{"q":2046,"a":2115},"Excel takes the digit grouping for the thousands separator from the operating system's regional settings, so it depends on the computer that opens the file.",{"q":2052,"a":2117},"Negative values fall into the default section of a conditional format, which does not add a minus sign; give negative cells a single-section format such as ##\\,##\\,##0.00, which shows the minus sign automatically.",{"q":2058,"a":2119},"Divide by 10^7 in a formula and apply a format such as \"₹\"#,##0.00\" Cr\", because number formats can only scale by thousands.","format numbers in lakhs and crores in excel",null,{"breadcrumb":2123},[2124,2127,2130],{"name":2125,"item":2126},"Home","\u002F",{"name":2128,"item":2129},"Formatting and Charting Excel Reports with Python","\u002Fformatting-and-charting-excel-reports-with-python\u002F",{"name":22,"item":21},"\u002Fformatting-and-charting-excel-reports-with-python\u002Fapplying-number-and-date-formats-in-excel\u002Fformat-numbers-in-lakhs-and-crores-in-excel",{"title":2133,"description":2134},"Format Numbers in Lakhs and Crores in Excel with Python","Indian number formatting in openpyxl: conditional number formats for lakh and crore grouping, negatives, ₹ and decimals, checking with LibreOffice against a Python formatter, and showing values in lakhs or crores.","format-numbers-in-lakhs-and-crores-in-excel","formatting-and-charting-excel-reports-with-python\u002Fapplying-number-and-date-formats-in-excel\u002Fformat-numbers-in-lakhs-and-crores-in-excel\u002Findex",[2138],"number-formats","how-to","egePzMBlZZZR0fszRAK-F9_U_J7PSIDQYKnIJQQRXLI",[2142,2146],{"title":2143,"path":2144,"stem":2145,"children":-1},"Format Numbers as Percentages in Excel with Python","\u002Fformatting-and-charting-excel-reports-with-python\u002Fapplying-number-and-date-formats-in-excel\u002Fformat-numbers-as-percentages-in-excel-with-python","formatting-and-charting-excel-reports-with-python\u002Fapplying-number-and-date-formats-in-excel\u002Fformat-numbers-as-percentages-in-excel-with-python\u002Findex",{"title":2147,"path":2148,"stem":2149,"children":-1},"Format Numbers in Thousands and Millions in Excel with Python","\u002Fformatting-and-charting-excel-reports-with-python\u002Fapplying-number-and-date-formats-in-excel\u002Fformat-numbers-in-thousands-and-millions-in-excel","formatting-and-charting-excel-reports-with-python\u002Fapplying-number-and-date-formats-in-excel\u002Fformat-numbers-in-thousands-and-millions-in-excel\u002Findex",[2151,2153],{"path":2152,"title":22},"\u002Fformatting-and-charting-excel-reports-with-python\u002Fapplying-number-and-date-formats-in-excel",{"path":2154,"title":2128},"\u002Fformatting-and-charting-excel-reports-with-python",[],[2157,2160,2163,2166,2169,2172],{"path":2158,"title":2159,"kind":2139},"\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":2161,"title":2162,"kind":2139},"\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":2164,"title":2165,"kind":2139},"\u002Fadvanced-data-transformation-and-cleaning\u002Fexcel-formula-equivalents-in-pandas\u002Fexcel-text-function-equivalent-in-pandas","Excel TEXT Function Equivalent in pandas",{"path":2167,"title":2168,"kind":2139},"\u002Fadvanced-data-transformation-and-cleaning\u002Fexcel-formula-equivalents-in-pandas\u002Fmatch-excel-rounding-in-pandas","Match Excel Rounding in pandas",{"path":2170,"title":2171,"kind":2139},"\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":2173,"title":2174,"kind":2139},"\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",1790972107067]