[{"data":1,"prerenderedAt":2451},["ShallowReactive",2],{"doc:\u002Fgetting-started-with-python-excel-automation\u002Fhandling-excel-file-formats-and-conversions\u002Fconvert-fixed-width-text-files-to-excel-with-pandas":3,"surround:\u002Fgetting-started-with-python-excel-automation\u002Fhandling-excel-file-formats-and-conversions\u002Fconvert-fixed-width-text-files-to-excel-with-pandas":2415,"ancestors:\u002Fgetting-started-with-python-excel-automation\u002Fhandling-excel-file-formats-and-conversions\u002Fconvert-fixed-width-text-files-to-excel-with-pandas":2424,"children:\u002Fgetting-started-with-python-excel-automation\u002Fhandling-excel-file-formats-and-conversions\u002Fconvert-fixed-width-text-files-to-excel-with-pandas":2429,"related:\u002Fgetting-started-with-python-excel-automation\u002Fhandling-excel-file-formats-and-conversions\u002Fconvert-fixed-width-text-files-to-excel-with-pandas":2430},{"id":4,"title":5,"body":6,"dateModified":2382,"datePublished":2382,"description":2383,"extension":2384,"faq":2385,"keyword":2394,"kind":2395,"meta":2396,"navigation":111,"path":2404,"seo":2405,"slug":2408,"stem":2409,"topics":2410,"type":2413,"__hash__":2414},"docs\u002Fgetting-started-with-python-excel-automation\u002Fhandling-excel-file-formats-and-conversions\u002Fconvert-fixed-width-text-files-to-excel-with-pandas\u002Findex.md","Convert Fixed-Width Text Files to Excel with pandas",{"type":7,"value":8,"toc":2368},"minimark",[9,29,34,62,83,142,428,432,446,612,631,638,642,645,925,931,1082,1086,1103,1226,1237,1241,1244,1453,1461,1465,1468,1841,2135,2139,2153,2206,2216,2220,2269,2273,2289,2293,2303,2307,2313,2319,2325,2331,2335,2364],[10,11,12,13,17,18,22,23,28],"p",{},"Not every export is a CSV. Banks, payroll bureaus, insurers and systems that started life on a mainframe still produce ",[14,15,16],"em",{},"fixed-width"," files, where each field occupies the same character positions on every line: the account number in columns 1–10, the name in 11–40, the amount in 41–52. There are no delimiters, numbers often carry no decimal point, and one file can mix several kinds of record. Excel's text import wizard can split such a file if someone clicks the column breaks in by hand every time; ",[19,20,21],"code",{},"pandas.read_fwf"," does it from a layout written down once. This page is part of ",[24,25,27],"a",{"href":26},"\u002Fgetting-started-with-python-excel-automation\u002Fhandling-excel-file-formats-and-conversions\u002F","Handling Excel File Formats and Conversions",".",[30,31,33],"h2",{"id":32},"prerequisites","Prerequisites",[35,36,41],"pre",{"className":37,"code":38,"language":39,"meta":40,"style":40},"language-bash shiki shiki-themes github-light github-dark-high-contrast","pip install pandas openpyxl\n","bash","",[19,42,43],{"__ignoreMap":40},[44,45,48,52,56,59],"span",{"class":46,"line":47},"line",1,[44,49,51],{"class":50},"sMTad","pip",[44,53,55],{"class":54},"srMev"," install",[44,57,58],{"class":54}," pandas",[44,60,61],{"class":54}," openpyxl\n",[10,63,64,67,68,71,72,75,76,79,80,28],{},[19,65,66],{},"payroll_20260928.txt"," is a payment file from a payroll bureau. The first line is a header record (",[19,69,70],{},"H",") with the date and batch, each payment is a detail record (",[19,73,74],{},"D","), and the last line is a trailer (",[19,77,78],{},"T",") with the record count and the net total. Its layout document gives the start and end column of every field in a detail record; that layout is saved here as ",[19,81,82],{},"layout.csv",[35,84,88],{"className":85,"code":86,"language":87,"meta":40,"style":40},"language-python shiki shiki-themes github-light github-dark-high-contrast","from pathlib import Path\n\nprint(Path(\"payroll_20260928.txt\").read_text(encoding=\"ascii\"))\n","python",[19,89,90,106,113],{"__ignoreMap":40},[44,91,92,96,100,103],{"class":46,"line":47},[44,93,95],{"class":94},"s-kum","from",[44,97,99],{"class":98},"skGVy"," pathlib ",[44,101,102],{"class":94},"import",[44,104,105],{"class":98}," Path\n",[44,107,109],{"class":46,"line":108},2,[44,110,112],{"emptyLinePlaceholder":111},true,"\n",[44,114,116,120,123,126,129,133,136,139],{"class":46,"line":115},3,[44,117,119],{"class":118},"sP0c6","print",[44,121,122],{"class":98},"(Path(",[44,124,125],{"class":54},"\"payroll_20260928.txt\"",[44,127,128],{"class":98},").read_text(",[44,130,132],{"class":131},"sa561","encoding",[44,134,135],{"class":94},"=",[44,137,138],{"class":54},"\"ascii\"",[44,140,141],{"class":98},"))\n",[143,144,152,153,152,157,152,161,152,169,152,179,152,184,152,189,152,195,152,203,152,206,152,232,152,240,152,244,152,248,152,250,152,304,152,308,152,359,152,362,152,366,152,368,152,373,152,380,152,384,152,387,152,392,152,396,152,399,152,402,152,404,152,408,152,411,152,416,152,419,152,421,152,425],"svg",{"viewBox":145,"role":146,"ariaLabelledBy":147,"xmlns":150,"style":151},"4 0 752 226","img",[148,149],"fw-layout-t","fw-layout-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  ",[154,155,156],"title",{"id":148},"One detail record and the positions of its fields",[158,159,160],"desc",{"id":149},"A single fixed-width detail line with numbered callouts for the record type, the account number in columns 2 to 11, the name in 12 to 35, the department in 36 to 39, the amount in cents in 40 to 51, and the credit or debit sign in column 52.",[162,163],"rect",{"x":164,"y":165,"width":166,"height":167,"fill":168},"4","0","752","226","#ffffff",[162,170],{"x":171,"y":172,"width":173,"height":174,"rx":175,"fill":176,"stroke":177,"style":178},"20.0","16.0","720.0","128.0","12","#f0f2f5","var(--line,#cdd5e6)","stroke-width:1.5px",[180,181,66],"text",{"x":182,"y":182,"style":183},"36.0","font-size:11.5px;font-weight:700;fill:var(--muted,#5b6780);text-anchor:start;font-family:ui-monospace,SFMono-Regular,Menlo,Consolas,monospace",[46,185],{"x1":171,"y1":186,"x2":187,"y2":186,"stroke":177,"style":188},"46.0","740.0","stroke-width:1px",[180,190,194],{"x":191,"y":192,"style":193},"60.0","67.0","font-size:11px;font-weight:400;fill:var(--muted,#5b6780);text-anchor:middle;font-family:ui-monospace,SFMono-Regular,Menlo,Consolas,monospace","1",[196,197],"circle",{"cx":182,"cy":198,"r":199,"fill":200,"stroke":201,"style":202},"62.5","11.0","#5b6780","none","stroke-width:0px",[180,204,194],{"x":182,"y":192,"style":205},"font-size:12px;font-weight:700;fill:#ffffff;text-anchor:middle",[180,207,210,215,218,221,223,226,229],{"x":208,"y":192,"style":209},"82.0","font-size:12.5px;text-anchor:start;font-family:ui-monospace,SFMono-Regular,Menlo,Consolas,monospace",[211,212,214],"tspan",{"style":213},"fill:var(--text,#172033);font-weight:400","H20260928PAYROLL",[211,216,217],{"style":213}," ",[211,219,220],{"style":213},"BUREAU",[211,222,217],{"style":213},[211,224,225],{"style":213},"LTD",[211,227,228],{"style":213},"   ",[211,230,231],{"style":213},"BATCH0042",[162,233],{"x":234,"y":235,"width":236,"height":237,"rx":164,"fill":238,"stroke":239,"style":202},"24.0","73.0","712.0","21.0","#f0f4ff","var(--brand,#5b5cf0)",[180,241,243],{"x":191,"y":242,"style":193},"88.0","2",[196,245],{"cx":182,"cy":246,"r":199,"fill":247,"stroke":201,"style":202},"83.5","#4338ca",[180,249,243],{"x":182,"y":242,"style":205},[180,251,252,255,258,260,263,266,268,270,272,274,276,278,280,282,284,286,288,290,293,295,298,301],{"x":208,"y":242,"style":209},[211,253,254],{"style":213},"D0000123456OKAFOR",[211,256,257],{"style":213},",",[211,259,217],{"style":213},[211,261,262],{"style":213},"ADAEZE",[211,264,265],{"style":213},"          ",[211,267,165],{"style":213},[211,269,165],{"style":213},[211,271,165],{"style":213},[211,273,194],{"style":213},[211,275,165],{"style":213},[211,277,165],{"style":213},[211,279,165],{"style":213},[211,281,165],{"style":213},[211,283,165],{"style":213},[211,285,165],{"style":213},[211,287,243],{"style":213},[211,289,164],{"style":213},[211,291,292],{"style":213},"5",[211,294,165],{"style":213},[211,296,297],{"style":213},"6",[211,299,300],{"style":213},"7",[211,302,303],{"style":213},"C",[180,305,307],{"x":191,"y":306,"style":193},"109.0","3",[180,309,310,313,315,317,320,323,325,327,329,331,333,335,337,339,341,343,345,348,351,353,355,357],{"x":208,"y":306,"style":209},[211,311,312],{"style":213},"D0000098231LINDQVIST",[211,314,257],{"style":213},[211,316,217],{"style":213},[211,318,319],{"style":213},"JONAS",[211,321,322],{"style":213},"        ",[211,324,165],{"style":213},[211,326,165],{"style":213},[211,328,165],{"style":213},[211,330,194],{"style":213},[211,332,165],{"style":213},[211,334,165],{"style":213},[211,336,165],{"style":213},[211,338,165],{"style":213},[211,340,165],{"style":213},[211,342,165],{"style":213},[211,344,194],{"style":213},[211,346,347],{"style":213},"9",[211,349,350],{"style":213},"8",[211,352,243],{"style":213},[211,354,292],{"style":213},[211,356,165],{"style":213},[211,358,303],{"style":213},[180,360,164],{"x":191,"y":361,"style":193},"130.0",[196,363],{"cx":182,"cy":364,"r":199,"fill":365,"stroke":201,"style":202},"125.5","#8a5808",[180,367,307],{"x":182,"y":361,"style":205},[180,369,370],{"x":208,"y":361,"style":209},[211,371,372],{"style":213},"T000005000000000975742",[162,374],{"x":171,"y":375,"width":376,"height":377,"rx":378,"fill":379,"stroke":177,"style":178},"158.0","230.7","52.0","10","#e7ebef",[196,381],{"cx":382,"cy":383,"r":199,"fill":200,"stroke":201,"style":202},"40.0","184.0",[180,385,194],{"x":382,"y":386,"style":205},"188.5",[180,388,391],{"x":191,"y":389,"style":390},"180.0","font-size:12px;font-weight:400;fill:var(--text,#172033);text-anchor:start","H: header — date, sender,",[180,393,395],{"x":191,"y":394,"style":390},"197.0","batch",[162,397],{"x":398,"y":375,"width":376,"height":377,"rx":378,"fill":238,"stroke":239,"style":178},"264.7",[196,400],{"cx":401,"cy":383,"r":199,"fill":247,"stroke":201,"style":202},"284.7",[180,403,243],{"x":401,"y":386,"style":205},[180,405,407],{"x":406,"y":389,"style":390},"304.7","D: detail — account in 2–11,",[180,409,410],{"x":406,"y":394,"style":390},"amount in cents in 40–51",[162,412],{"x":413,"y":375,"width":376,"height":377,"rx":378,"fill":414,"stroke":415,"style":178},"509.3","#fdefd8","var(--gold,#b4740a)",[196,417],{"cx":418,"cy":383,"r":199,"fill":365,"stroke":201,"style":202},"529.3",[180,420,307],{"x":418,"y":386,"style":205},[180,422,424],{"x":423,"y":389,"style":390},"549.3","T: trailer — record count and",[180,426,427],{"x":423,"y":394,"style":390},"net total",[30,429,431],{"id":430},"step-1-describe-the-layout-then-read","Step 1 — Describe the layout, then read",[10,433,434,437,438,441,442,445],{},[19,435,436],{},"read_fwf"," takes ",[19,439,440],{},"colspecs",", a list of ",[19,443,444],{},"(start, end)"," pairs in Python slice terms: zero-based, end exclusive. Layout documents almost always number columns from 1 with inclusive ends, so convert once, in code, rather than by hand for each field:",[35,447,449],{"className":85,"code":448,"language":87,"meta":40,"style":40},"import pandas as pd\n\nlayout = pd.read_csv(\"layout.csv\")\ncolspecs = [(s - 1, e) for s, e in zip(layout[\"start\"], layout[\"end\"])]\nprint(colspecs)\n\nraw = pd.read_fwf(\"payroll_20260928.txt\", colspecs=colspecs, names=layout[\"field\"].tolist(),\n                  dtype=str, header=None)\nprint(raw)\n",[19,450,451,464,468,484,531,539,544,581,604],{"__ignoreMap":40},[44,452,453,455,458,461],{"class":46,"line":47},[44,454,102],{"class":94},[44,456,457],{"class":98}," pandas ",[44,459,460],{"class":94},"as",[44,462,463],{"class":98}," pd\n",[44,465,466],{"class":46,"line":108},[44,467,112],{"emptyLinePlaceholder":111},[44,469,470,473,475,478,481],{"class":46,"line":115},[44,471,472],{"class":98},"layout ",[44,474,135],{"class":94},[44,476,477],{"class":98}," pd.read_csv(",[44,479,480],{"class":54},"\"layout.csv\"",[44,482,483],{"class":98},")\n",[44,485,487,490,492,495,498,501,504,507,510,513,516,519,522,525,528],{"class":46,"line":486},4,[44,488,489],{"class":98},"colspecs ",[44,491,135],{"class":94},[44,493,494],{"class":98}," [(s ",[44,496,497],{"class":94},"-",[44,499,500],{"class":118}," 1",[44,502,503],{"class":98},", e) ",[44,505,506],{"class":94},"for",[44,508,509],{"class":98}," s, e ",[44,511,512],{"class":94},"in",[44,514,515],{"class":118}," zip",[44,517,518],{"class":98},"(layout[",[44,520,521],{"class":54},"\"start\"",[44,523,524],{"class":98},"], layout[",[44,526,527],{"class":54},"\"end\"",[44,529,530],{"class":98},"])]\n",[44,532,534,536],{"class":46,"line":533},5,[44,535,119],{"class":118},[44,537,538],{"class":98},"(colspecs)\n",[44,540,542],{"class":46,"line":541},6,[44,543,112],{"emptyLinePlaceholder":111},[44,545,547,550,552,555,557,560,562,564,567,570,572,575,578],{"class":46,"line":546},7,[44,548,549],{"class":98},"raw ",[44,551,135],{"class":94},[44,553,554],{"class":98}," pd.read_fwf(",[44,556,125],{"class":54},[44,558,559],{"class":98},", ",[44,561,440],{"class":131},[44,563,135],{"class":94},[44,565,566],{"class":98},"colspecs, ",[44,568,569],{"class":131},"names",[44,571,135],{"class":94},[44,573,574],{"class":98},"layout[",[44,576,577],{"class":54},"\"field\"",[44,579,580],{"class":98},"].tolist(),\n",[44,582,584,587,589,592,594,597,599,602],{"class":46,"line":583},8,[44,585,586],{"class":131},"                  dtype",[44,588,135],{"class":94},[44,590,591],{"class":118},"str",[44,593,559],{"class":98},[44,595,596],{"class":131},"header",[44,598,135],{"class":94},[44,600,601],{"class":118},"None",[44,603,483],{"class":98},[44,605,607,609],{"class":46,"line":606},9,[44,608,119],{"class":118},[44,610,611],{"class":98},"(raw)\n",[10,613,614,617,618,621,622,625,626,630],{},[19,615,616],{},"dtype=str"," reads every field as text. That is deliberate: account ",[19,619,620],{},"0000123456"," would otherwise become the integer ",[19,623,624],{},"123456",", losing the leading zeros that make it a valid account number (see ",[24,627,629],{"href":628},"\u002Fgetting-started-with-python-excel-automation\u002Freading-excel-files-with-pandas\u002Fkeep-leading-zeros-when-reading-excel-with-pandas\u002F","Keep Leading Zeros When Reading Excel with pandas"," for the same problem in workbooks). Types are applied afterwards, field by field, from the layout.",[10,632,633,634,637],{},"The output also shows the catch with mixed-record files: the header and trailer lines were forced through the detail layout. The header's \"account\" is ",[19,635,636],{},"20260928PA"," — the date run into the start of the sender name — the trailer's is a slice of its record count and total, and both have no amount. Nothing about them raises an error; they just look like two odd rows of data.",[30,639,641],{"id":640},"step-2-split-the-record-types","Step 2 — Split the record types",[10,643,644],{},"Filter on the record-type column and keep only details for the data sheet. Parse the header and trailer separately with their own positions:",[35,646,648],{"className":85,"code":647,"language":87,"meta":40,"style":40},"details = raw[raw[\"record_type\"] == \"D\"].drop(columns=\"record_type\").reset_index(drop=True)\n\ntext = Path(\"payroll_20260928.txt\").read_text(encoding=\"ascii\").splitlines()\nheader_line = next(l for l in text if l.startswith(\"H\"))\ntrailer_line = next(l for l in text if l.startswith(\"T\"))\nheader = {\"date\": pd.to_datetime(header_line[1:9], format=\"%Y%m%d\"),\n          \"sender\": header_line[9:30].strip(), \"batch\": header_line[30:39]}\ntrailer = {\"count\": int(trailer_line[1:7]), \"net_cents\": int(trailer_line[7:22])}\nprint(header)\nprint(trailer)\n",[19,649,650,695,699,722,756,784,828,861,910,917],{"__ignoreMap":40},[44,651,652,655,657,660,663,666,669,672,675,678,680,682,685,688,690,693],{"class":46,"line":47},[44,653,654],{"class":98},"details ",[44,656,135],{"class":94},[44,658,659],{"class":98}," raw[raw[",[44,661,662],{"class":54},"\"record_type\"",[44,664,665],{"class":98},"] ",[44,667,668],{"class":94},"==",[44,670,671],{"class":54}," \"D\"",[44,673,674],{"class":98},"].drop(",[44,676,677],{"class":131},"columns",[44,679,135],{"class":94},[44,681,662],{"class":54},[44,683,684],{"class":98},").reset_index(",[44,686,687],{"class":131},"drop",[44,689,135],{"class":94},[44,691,692],{"class":118},"True",[44,694,483],{"class":98},[44,696,697],{"class":46,"line":108},[44,698,112],{"emptyLinePlaceholder":111},[44,700,701,704,706,709,711,713,715,717,719],{"class":46,"line":115},[44,702,703],{"class":98},"text ",[44,705,135],{"class":94},[44,707,708],{"class":98}," Path(",[44,710,125],{"class":54},[44,712,128],{"class":98},[44,714,132],{"class":131},[44,716,135],{"class":94},[44,718,138],{"class":54},[44,720,721],{"class":98},").splitlines()\n",[44,723,724,727,729,732,735,737,740,742,745,748,751,754],{"class":46,"line":486},[44,725,726],{"class":98},"header_line ",[44,728,135],{"class":94},[44,730,731],{"class":118}," next",[44,733,734],{"class":98},"(l ",[44,736,506],{"class":94},[44,738,739],{"class":98}," l ",[44,741,512],{"class":94},[44,743,744],{"class":98}," text ",[44,746,747],{"class":94},"if",[44,749,750],{"class":98}," l.startswith(",[44,752,753],{"class":54},"\"H\"",[44,755,141],{"class":98},[44,757,758,761,763,765,767,769,771,773,775,777,779,782],{"class":46,"line":533},[44,759,760],{"class":98},"trailer_line ",[44,762,135],{"class":94},[44,764,731],{"class":118},[44,766,734],{"class":98},[44,768,506],{"class":94},[44,770,739],{"class":98},[44,772,512],{"class":94},[44,774,744],{"class":98},[44,776,747],{"class":94},[44,778,750],{"class":98},[44,780,781],{"class":54},"\"T\"",[44,783,141],{"class":98},[44,785,786,789,791,794,797,800,802,805,807,810,813,815,818,822,825],{"class":46,"line":541},[44,787,788],{"class":98},"header ",[44,790,135],{"class":94},[44,792,793],{"class":98}," {",[44,795,796],{"class":54},"\"date\"",[44,798,799],{"class":98},": pd.to_datetime(header_line[",[44,801,194],{"class":118},[44,803,804],{"class":98},":",[44,806,347],{"class":118},[44,808,809],{"class":98},"], ",[44,811,812],{"class":131},"format",[44,814,135],{"class":94},[44,816,817],{"class":54},"\"%Y%m",[44,819,821],{"class":820},"sSjpA","%d",[44,823,824],{"class":54},"\"",[44,826,827],{"class":98},"),\n",[44,829,830,833,836,838,840,843,846,849,851,853,855,858],{"class":46,"line":546},[44,831,832],{"class":54},"          \"sender\"",[44,834,835],{"class":98},": header_line[",[44,837,347],{"class":118},[44,839,804],{"class":98},[44,841,842],{"class":118},"30",[44,844,845],{"class":98},"].strip(), ",[44,847,848],{"class":54},"\"batch\"",[44,850,835],{"class":98},[44,852,842],{"class":118},[44,854,804],{"class":98},[44,856,857],{"class":118},"39",[44,859,860],{"class":98},"]}\n",[44,862,863,866,868,870,873,876,879,882,884,886,888,891,894,896,898,900,902,904,907],{"class":46,"line":583},[44,864,865],{"class":98},"trailer ",[44,867,135],{"class":94},[44,869,793],{"class":98},[44,871,872],{"class":54},"\"count\"",[44,874,875],{"class":98},": ",[44,877,878],{"class":118},"int",[44,880,881],{"class":98},"(trailer_line[",[44,883,194],{"class":118},[44,885,804],{"class":98},[44,887,300],{"class":118},[44,889,890],{"class":98},"]), ",[44,892,893],{"class":54},"\"net_cents\"",[44,895,875],{"class":98},[44,897,878],{"class":118},[44,899,881],{"class":98},[44,901,300],{"class":118},[44,903,804],{"class":98},[44,905,906],{"class":118},"22",[44,908,909],{"class":98},"])}\n",[44,911,912,914],{"class":46,"line":606},[44,913,119],{"class":118},[44,915,916],{"class":98},"(header)\n",[44,918,920,922],{"class":46,"line":919},10,[44,921,119],{"class":118},[44,923,924],{"class":98},"(trailer)\n",[10,926,927,928,930],{},"Header and trailer records are one line each, so plain string slicing is clearer than a second ",[19,929,436],{}," call. Keep their positions next to the detail layout in the same layout file when there are many of them.",[143,932,152,937,152,940,152,943,152,946,152,952,152,962,152,966,152,971,152,976,152,983,152,989,152,994,152,997,152,1002,152,1007,152,1013,152,1018,152,1025,152,1029,152,1033,152,1036,152,1039,152,1044,152,1048,152,1051,152,1058,152,1063,152,1067,152,1070,152,1073,152,1078],{"viewBox":933,"role":146,"ariaLabelledBy":934,"xmlns":150,"style":151},"4 0 752 332",[935,936],"fw-records-t","fw-records-d",[154,938,939],{"id":935},"One file, three record layouts",[158,941,942],{"id":936},"A fixed-width file fans out into a header record with the date and batch, detail records that become rows in the workbook, and a trailer record with the count and total used for checking.",[162,944],{"x":164,"y":165,"width":166,"height":945,"fill":168},"332",[162,947],{"x":171,"y":948,"width":949,"height":950,"rx":175,"fill":379,"stroke":177,"style":951},"119.5","220.0","93.0","stroke-width:2px",[953,954,956],"g",{"transform":955},"translate(118.0,132.5) scale(1.000)",[957,958],"path",{"d":959,"fill":201,"stroke":960,"style":961},"M6 3h9l4 4v14H6z M15 3v4h4","var(--text,#172033)","stroke-width:1.80px;stroke-linecap:round;stroke-linejoin:round",[180,963,66],{"x":361,"y":964,"style":965},"179.0","font-size:13.5px;font-weight:700;fill:var(--text,#172033);text-anchor:middle",[180,967,970],{"x":361,"y":968,"style":969},"198.5","font-size:11.5px;font-weight:400;fill:var(--text,#172033);text-anchor:middle","one line per record",[162,972],{"x":973,"y":172,"width":974,"height":975,"rx":175,"fill":238,"stroke":239,"style":951},"490.0","250.0","92.0",[953,977,979],{"transform":978},"translate(603.0,29.0) scale(1.000)",[957,980],{"d":981,"fill":201,"stroke":982,"style":961},"M4 5h16v15H4z M4 10h16 M8 3v4 M16 3v4","var(--brand-strong,#4338ca)",[180,984,988],{"x":985,"y":986,"style":987},"615.0","75.0","font-size:13px;font-weight:700;fill:var(--brand-strong,#4338ca);text-anchor:middle","H — header",[180,990,993],{"x":985,"y":991,"style":992},"94.0","font-size:11px;font-weight:400;fill:var(--text,#172033);text-anchor:middle","date, sender, batch → report title",[957,995],{"d":996,"fill":201,"stroke":239,"style":951},"M244.0,166.0 C364.0,166.0 364.0,62.0 480.0,62.0",[998,999],"polygon",{"points":1000,"fill":1001},"484.0,62.0 475.0,67.0 475.0,57.0","#5b5cf0",[162,1003],{"x":1004,"y":1005,"width":208,"height":1006,"rx":347,"fill":168,"stroke":177,"style":188},"324.0","104.0","19.0",[180,1008,1012],{"x":1009,"y":1010,"style":1011},"365.0","117.5","font-size:10.5px;font-weight:700;fill:var(--muted,#5b6780);text-anchor:middle","starts with H",[162,1014],{"x":973,"y":1015,"width":974,"height":975,"rx":175,"fill":1016,"stroke":1017,"style":951},"120.0","#d9f4f1","var(--teal,#0f9488)",[953,1019,1021],{"transform":1020},"translate(603.0,133.0) scale(1.000)",[957,1022],{"d":1023,"fill":201,"stroke":1024,"style":961},"M3 5h18v14H3z M3 10h18 M3 15h18 M9 5v14","var(--teal-ink,#0b6157)",[180,1026,1028],{"x":985,"y":964,"style":1027},"font-size:13px;font-weight:700;fill:var(--teal-ink,#0b6157);text-anchor:middle","D — detail",[180,1030,1032],{"x":985,"y":1031,"style":992},"198.0","one payment per line → data rows",[957,1034],{"d":1035,"fill":201,"stroke":239,"style":951},"M244.0,166.0 C364.0,166.0 364.0,166.0 480.0,166.0",[998,1037],{"points":1038,"fill":1001},"484.0,166.0 475.0,171.0 475.0,161.0",[162,1040],{"x":1041,"y":1042,"width":1043,"height":1006,"rx":347,"fill":168,"stroke":177,"style":188},"324.1","156.0","81.8",[180,1045,1047],{"x":1009,"y":1046,"style":1011},"169.5","starts with D",[162,1049],{"x":973,"y":1050,"width":974,"height":975,"rx":175,"fill":414,"stroke":415,"style":951},"224.0",[953,1052,1054],{"transform":1053},"translate(603.0,237.0) scale(1.000)",[957,1055],{"d":1056,"fill":201,"stroke":1057,"style":961},"M5 12.5l4.5 4.5L19 7","var(--gold-ink,#7a4e06)",[180,1059,1062],{"x":985,"y":1060,"style":1061},"283.0","font-size:13px;font-weight:700;fill:var(--gold-ink,#7a4e06);text-anchor:middle","T — trailer",[180,1064,1066],{"x":985,"y":1065,"style":992},"302.0","count and net total → checks",[957,1068],{"d":1069,"fill":201,"stroke":239,"style":951},"M244.0,166.0 C364.0,166.0 364.0,270.0 480.0,270.0",[998,1071],{"points":1072,"fill":1001},"484.0,270.0 475.0,275.0 475.0,265.0",[162,1074],{"x":1075,"y":1076,"width":1077,"height":1006,"rx":347,"fill":168,"stroke":177,"style":188},"324.4","208.0","81.2",[180,1079,1081],{"x":1009,"y":1080,"style":1011},"221.5","starts with T",[30,1083,1085],{"id":1084},"step-3-apply-types-implied-decimals-and-signs","Step 3 — Apply types: implied decimals and signs",[10,1087,1088,1089,1092,1093,1096,1097,1099,1100,1102],{},"The amount field ",[19,1090,1091],{},"000000245067"," means 2,450.67: the layout says it is in cents, with an ",[14,1094,1095],{},"implied"," decimal point two places from the right. The sign is a separate field, ",[19,1098,303],{}," for credit and ",[19,1101,74],{}," for debit. Convert both, and strip the padding from text fields:",[35,1104,1106],{"className":85,"code":1105,"language":87,"meta":40,"style":40},"details[\"name\"] = details[\"name\"].str.strip()\ndetails[\"amount\"] = details[\"amount\"].astype(int) \u002F 100\ndetails[\"amount\"] = details[\"amount\"].where(details[\"sign\"] == \"C\", -details[\"amount\"])\ndetails = details.drop(columns=\"sign\")\nprint(details)\nprint(details.dtypes.to_dict())\n",[19,1107,1108,1128,1157,1195,1212,1219],{"__ignoreMap":40},[44,1109,1110,1113,1116,1118,1120,1123,1125],{"class":46,"line":47},[44,1111,1112],{"class":98},"details[",[44,1114,1115],{"class":54},"\"name\"",[44,1117,665],{"class":98},[44,1119,135],{"class":94},[44,1121,1122],{"class":98}," details[",[44,1124,1115],{"class":54},[44,1126,1127],{"class":98},"].str.strip()\n",[44,1129,1130,1132,1135,1137,1139,1141,1143,1146,1148,1151,1154],{"class":46,"line":108},[44,1131,1112],{"class":98},[44,1133,1134],{"class":54},"\"amount\"",[44,1136,665],{"class":98},[44,1138,135],{"class":94},[44,1140,1122],{"class":98},[44,1142,1134],{"class":54},[44,1144,1145],{"class":98},"].astype(",[44,1147,878],{"class":118},[44,1149,1150],{"class":98},") ",[44,1152,1153],{"class":94},"\u002F",[44,1155,1156],{"class":118}," 100\n",[44,1158,1159,1161,1163,1165,1167,1169,1171,1174,1177,1179,1181,1184,1186,1188,1190,1192],{"class":46,"line":115},[44,1160,1112],{"class":98},[44,1162,1134],{"class":54},[44,1164,665],{"class":98},[44,1166,135],{"class":94},[44,1168,1122],{"class":98},[44,1170,1134],{"class":54},[44,1172,1173],{"class":98},"].where(details[",[44,1175,1176],{"class":54},"\"sign\"",[44,1178,665],{"class":98},[44,1180,668],{"class":94},[44,1182,1183],{"class":54}," \"C\"",[44,1185,559],{"class":98},[44,1187,497],{"class":94},[44,1189,1112],{"class":98},[44,1191,1134],{"class":54},[44,1193,1194],{"class":98},"])\n",[44,1196,1197,1199,1201,1204,1206,1208,1210],{"class":46,"line":486},[44,1198,654],{"class":98},[44,1200,135],{"class":94},[44,1202,1203],{"class":98}," details.drop(",[44,1205,677],{"class":131},[44,1207,135],{"class":94},[44,1209,1176],{"class":54},[44,1211,483],{"class":98},[44,1213,1214,1216],{"class":46,"line":533},[44,1215,119],{"class":118},[44,1217,1218],{"class":98},"(details)\n",[44,1220,1221,1223],{"class":46,"line":541},[44,1222,119],{"class":118},[44,1224,1225],{"class":98},"(details.dtypes.to_dict())\n",[10,1227,1228,1229,1231,1232,1236],{},"Dividing by 100 after converting to an integer avoids floating-point surprises in the parse itself. For money that must add up to the cent in later steps, keep a cents column as integers and do the arithmetic on that, converting to currency only for display — the checks in the next step use cents for exactly that reason. Other layouts put the sign inside the number (a trailing ",[19,1230,497],{},", or the COBOL \"overpunch\" convention where the last digit becomes a letter); those need a small converter, and ",[24,1233,1235],{"href":1234},"\u002Fadvanced-data-transformation-and-cleaning\u002Fcleaning-excel-data-with-pandas\u002Fconvert-trailing-minus-and-cr-dr-amounts-with-pandas\u002F","Convert Trailing Minus and CR\u002FDR Amounts with pandas"," covers the common forms.",[30,1238,1240],{"id":1239},"step-4-check-the-file-against-its-trailer","Step 4 — Check the file against its trailer",[10,1242,1243],{},"The trailer exists so the receiver can prove nothing was lost or altered in transit. Check it before producing anything:",[35,1245,1247],{"className":85,"code":1246,"language":87,"meta":40,"style":40},"cents = (details[\"amount\"] * 100).round().astype(int)\nproblems = []\nif len(details) != trailer[\"count\"]:\n    problems.append(f\"record count {len(details)} != trailer {trailer['count']}\")\nif cents.sum() != trailer[\"net_cents\"]:\n    problems.append(f\"net total {cents.sum()} != trailer {trailer['net_cents']}\")\nif not details[\"account\"].str.fullmatch(r\"\\d{10}\").all():\n    problems.append(\"malformed account numbers\")\nprint(problems or \"file agrees with its trailer\")\n",[19,1248,1249,1276,1286,1307,1350,1365,1398,1429,1438],{"__ignoreMap":40},[44,1250,1251,1254,1256,1259,1261,1263,1266,1269,1272,1274],{"class":46,"line":47},[44,1252,1253],{"class":98},"cents ",[44,1255,135],{"class":94},[44,1257,1258],{"class":98}," (details[",[44,1260,1134],{"class":54},[44,1262,665],{"class":98},[44,1264,1265],{"class":94},"*",[44,1267,1268],{"class":118}," 100",[44,1270,1271],{"class":98},").round().astype(",[44,1273,878],{"class":118},[44,1275,483],{"class":98},[44,1277,1278,1281,1283],{"class":46,"line":108},[44,1279,1280],{"class":98},"problems ",[44,1282,135],{"class":94},[44,1284,1285],{"class":98}," []\n",[44,1287,1288,1290,1293,1296,1299,1302,1304],{"class":46,"line":115},[44,1289,747],{"class":94},[44,1291,1292],{"class":118}," len",[44,1294,1295],{"class":98},"(details) ",[44,1297,1298],{"class":94},"!=",[44,1300,1301],{"class":98}," trailer[",[44,1303,872],{"class":54},[44,1305,1306],{"class":98},"]:\n",[44,1308,1309,1312,1315,1318,1321,1324,1327,1330,1333,1335,1338,1341,1344,1346,1348],{"class":46,"line":486},[44,1310,1311],{"class":98},"    problems.append(",[44,1313,1314],{"class":94},"f",[44,1316,1317],{"class":54},"\"record count ",[44,1319,1320],{"class":820},"{",[44,1322,1323],{"class":118},"len",[44,1325,1326],{"class":98},"(details)",[44,1328,1329],{"class":820},"}",[44,1331,1332],{"class":54}," != trailer ",[44,1334,1320],{"class":820},[44,1336,1337],{"class":98},"trailer[",[44,1339,1340],{"class":54},"'count'",[44,1342,1343],{"class":98},"]",[44,1345,1329],{"class":820},[44,1347,824],{"class":54},[44,1349,483],{"class":98},[44,1351,1352,1354,1357,1359,1361,1363],{"class":46,"line":533},[44,1353,747],{"class":94},[44,1355,1356],{"class":98}," cents.sum() ",[44,1358,1298],{"class":94},[44,1360,1301],{"class":98},[44,1362,893],{"class":54},[44,1364,1306],{"class":98},[44,1366,1367,1369,1371,1374,1376,1379,1381,1383,1385,1387,1390,1392,1394,1396],{"class":46,"line":541},[44,1368,1311],{"class":98},[44,1370,1314],{"class":94},[44,1372,1373],{"class":54},"\"net total ",[44,1375,1320],{"class":820},[44,1377,1378],{"class":98},"cents.sum()",[44,1380,1329],{"class":820},[44,1382,1332],{"class":54},[44,1384,1320],{"class":820},[44,1386,1337],{"class":98},[44,1388,1389],{"class":54},"'net_cents'",[44,1391,1343],{"class":98},[44,1393,1329],{"class":820},[44,1395,824],{"class":54},[44,1397,483],{"class":98},[44,1399,1400,1402,1405,1407,1410,1413,1416,1418,1421,1424,1426],{"class":46,"line":546},[44,1401,747],{"class":94},[44,1403,1404],{"class":94}," not",[44,1406,1122],{"class":98},[44,1408,1409],{"class":54},"\"account\"",[44,1411,1412],{"class":98},"].str.fullmatch(",[44,1414,1415],{"class":94},"r",[44,1417,824],{"class":54},[44,1419,1420],{"class":118},"\\d",[44,1422,1423],{"class":94},"{10}",[44,1425,824],{"class":54},[44,1427,1428],{"class":98},").all():\n",[44,1430,1431,1433,1436],{"class":46,"line":583},[44,1432,1311],{"class":98},[44,1434,1435],{"class":54},"\"malformed account numbers\"",[44,1437,483],{"class":98},[44,1439,1440,1442,1445,1448,1451],{"class":46,"line":606},[44,1441,119],{"class":118},[44,1443,1444],{"class":98},"(problems ",[44,1446,1447],{"class":94},"or",[44,1449,1450],{"class":54}," \"file agrees with its trailer\"",[44,1452,483],{"class":98},[10,1454,1455,1456,1460],{},"A mismatch means a truncated transfer, a line with a shifted field, or a file edited by hand — all reasons to stop and alert someone rather than publish a report (see ",[24,1457,1459],{"href":1458},"\u002Fautomating-reporting-workflows\u002Ferror-handling-and-logging-in-excel-automation\u002Fvalidate-an-excel-report-before-sending-it\u002F","Validate an Excel Report Before Sending It","). The account-number pattern check catches the most common corruption in fixed-width files: a line one character too long or too short, which shifts every field after the fault.",[30,1462,1464],{"id":1463},"step-5-write-the-workbook","Step 5 — Write the workbook",[10,1466,1467],{},"Put the header information above the table, keep the account column as text, and format the amounts:",[35,1469,1471],{"className":85,"code":1470,"language":87,"meta":40,"style":40},"title = f\"{header['sender']} — batch {header['batch']} — {header['date']:%d %b %Y}\"\nwith pd.ExcelWriter(\"payroll_20260928.xlsx\", engine=\"xlsxwriter\") as xw:\n    details.to_excel(xw, sheet_name=\"Payments\", index=False, startrow=2)\n    wb, ws = xw.book, xw.sheets[\"Payments\"]\n    ws.write(0, 0, title, wb.add_format({\"bold\": True, \"font_size\": 13}))\n    ws.set_column(\"A:A\", 13, wb.add_format({\"num_format\": \"@\"}))\n    ws.set_column(\"B:B\", 24)\n    ws.set_column(\"D:D\", 13, wb.add_format({\"num_format\": \"#,##0.00;[Red]-#,##0.00\"}))\n    last = len(details) + 3\n    ws.write(last, 2, \"Net total\", wb.add_format({\"bold\": True}))\n    ws.write_formula(last, 3, f\"=SUM(D4:D{last})\", wb.add_format({\"bold\": True, \"num_format\": \"#,##0.00\"}))\nprint(pd.read_excel(\"payroll_20260928.xlsx\", skiprows=2, dtype={\"account\": str}).head(3))\n",[19,1472,1473,1545,1573,1607,1622,1656,1681,1695,1717,1734,1756,1800],{"__ignoreMap":40},[44,1474,1475,1478,1480,1483,1485,1487,1490,1493,1495,1497,1500,1502,1504,1507,1509,1511,1514,1516,1518,1521,1524,1527,1530,1532,1535,1537,1540,1542],{"class":46,"line":47},[44,1476,1477],{"class":98},"title ",[44,1479,135],{"class":94},[44,1481,1482],{"class":94}," f",[44,1484,824],{"class":54},[44,1486,1320],{"class":820},[44,1488,1489],{"class":98},"header[",[44,1491,1492],{"class":54},"'sender'",[44,1494,1343],{"class":98},[44,1496,1329],{"class":820},[44,1498,1499],{"class":54}," — batch ",[44,1501,1320],{"class":820},[44,1503,1489],{"class":98},[44,1505,1506],{"class":54},"'batch'",[44,1508,1343],{"class":98},[44,1510,1329],{"class":820},[44,1512,1513],{"class":54}," — ",[44,1515,1320],{"class":820},[44,1517,1489],{"class":98},[44,1519,1520],{"class":54},"'date'",[44,1522,1523],{"class":98},"]:",[44,1525,1526],{"class":94},"%",[44,1528,1529],{"class":98},"d ",[44,1531,1526],{"class":94},[44,1533,1534],{"class":98},"b ",[44,1536,1526],{"class":94},[44,1538,1539],{"class":98},"Y",[44,1541,1329],{"class":820},[44,1543,1544],{"class":54},"\"\n",[44,1546,1547,1550,1553,1556,1558,1561,1563,1566,1568,1570],{"class":46,"line":108},[44,1548,1549],{"class":94},"with",[44,1551,1552],{"class":98}," pd.ExcelWriter(",[44,1554,1555],{"class":54},"\"payroll_20260928.xlsx\"",[44,1557,559],{"class":98},[44,1559,1560],{"class":131},"engine",[44,1562,135],{"class":94},[44,1564,1565],{"class":54},"\"xlsxwriter\"",[44,1567,1150],{"class":98},[44,1569,460],{"class":94},[44,1571,1572],{"class":98}," xw:\n",[44,1574,1575,1578,1581,1583,1586,1588,1591,1593,1596,1598,1601,1603,1605],{"class":46,"line":115},[44,1576,1577],{"class":98},"    details.to_excel(xw, ",[44,1579,1580],{"class":131},"sheet_name",[44,1582,135],{"class":94},[44,1584,1585],{"class":54},"\"Payments\"",[44,1587,559],{"class":98},[44,1589,1590],{"class":131},"index",[44,1592,135],{"class":94},[44,1594,1595],{"class":118},"False",[44,1597,559],{"class":98},[44,1599,1600],{"class":131},"startrow",[44,1602,135],{"class":94},[44,1604,243],{"class":118},[44,1606,483],{"class":98},[44,1608,1609,1612,1614,1617,1619],{"class":46,"line":486},[44,1610,1611],{"class":98},"    wb, ws ",[44,1613,135],{"class":94},[44,1615,1616],{"class":98}," xw.book, xw.sheets[",[44,1618,1585],{"class":54},[44,1620,1621],{"class":98},"]\n",[44,1623,1624,1627,1629,1631,1633,1636,1639,1641,1643,1645,1648,1650,1653],{"class":46,"line":533},[44,1625,1626],{"class":98},"    ws.write(",[44,1628,165],{"class":118},[44,1630,559],{"class":98},[44,1632,165],{"class":118},[44,1634,1635],{"class":98},", title, wb.add_format({",[44,1637,1638],{"class":54},"\"bold\"",[44,1640,875],{"class":98},[44,1642,692],{"class":118},[44,1644,559],{"class":98},[44,1646,1647],{"class":54},"\"font_size\"",[44,1649,875],{"class":98},[44,1651,1652],{"class":118},"13",[44,1654,1655],{"class":98},"}))\n",[44,1657,1658,1661,1664,1666,1668,1671,1674,1676,1679],{"class":46,"line":541},[44,1659,1660],{"class":98},"    ws.set_column(",[44,1662,1663],{"class":54},"\"A:A\"",[44,1665,559],{"class":98},[44,1667,1652],{"class":118},[44,1669,1670],{"class":98},", wb.add_format({",[44,1672,1673],{"class":54},"\"num_format\"",[44,1675,875],{"class":98},[44,1677,1678],{"class":54},"\"@\"",[44,1680,1655],{"class":98},[44,1682,1683,1685,1688,1690,1693],{"class":46,"line":546},[44,1684,1660],{"class":98},[44,1686,1687],{"class":54},"\"B:B\"",[44,1689,559],{"class":98},[44,1691,1692],{"class":118},"24",[44,1694,483],{"class":98},[44,1696,1697,1699,1702,1704,1706,1708,1710,1712,1715],{"class":46,"line":583},[44,1698,1660],{"class":98},[44,1700,1701],{"class":54},"\"D:D\"",[44,1703,559],{"class":98},[44,1705,1652],{"class":118},[44,1707,1670],{"class":98},[44,1709,1673],{"class":54},[44,1711,875],{"class":98},[44,1713,1714],{"class":54},"\"#,##0.00;[Red]-#,##0.00\"",[44,1716,1655],{"class":98},[44,1718,1719,1722,1724,1726,1728,1731],{"class":46,"line":606},[44,1720,1721],{"class":98},"    last ",[44,1723,135],{"class":94},[44,1725,1292],{"class":118},[44,1727,1295],{"class":98},[44,1729,1730],{"class":94},"+",[44,1732,1733],{"class":118}," 3\n",[44,1735,1736,1739,1741,1743,1746,1748,1750,1752,1754],{"class":46,"line":919},[44,1737,1738],{"class":98},"    ws.write(last, ",[44,1740,243],{"class":118},[44,1742,559],{"class":98},[44,1744,1745],{"class":54},"\"Net total\"",[44,1747,1670],{"class":98},[44,1749,1638],{"class":54},[44,1751,875],{"class":98},[44,1753,692],{"class":118},[44,1755,1655],{"class":98},[44,1757,1759,1762,1764,1766,1768,1771,1773,1776,1778,1781,1783,1785,1787,1789,1791,1793,1795,1798],{"class":46,"line":1758},11,[44,1760,1761],{"class":98},"    ws.write_formula(last, ",[44,1763,307],{"class":118},[44,1765,559],{"class":98},[44,1767,1314],{"class":94},[44,1769,1770],{"class":54},"\"=SUM(D4:D",[44,1772,1320],{"class":820},[44,1774,1775],{"class":98},"last",[44,1777,1329],{"class":820},[44,1779,1780],{"class":54},")\"",[44,1782,1670],{"class":98},[44,1784,1638],{"class":54},[44,1786,875],{"class":98},[44,1788,692],{"class":118},[44,1790,559],{"class":98},[44,1792,1673],{"class":54},[44,1794,875],{"class":98},[44,1796,1797],{"class":54},"\"#,##0.00\"",[44,1799,1655],{"class":98},[44,1801,1803,1805,1808,1810,1812,1815,1817,1819,1821,1824,1826,1828,1830,1832,1834,1837,1839],{"class":46,"line":1802},12,[44,1804,119],{"class":118},[44,1806,1807],{"class":98},"(pd.read_excel(",[44,1809,1555],{"class":54},[44,1811,559],{"class":98},[44,1813,1814],{"class":131},"skiprows",[44,1816,135],{"class":94},[44,1818,243],{"class":118},[44,1820,559],{"class":98},[44,1822,1823],{"class":131},"dtype",[44,1825,135],{"class":94},[44,1827,1320],{"class":98},[44,1829,1409],{"class":54},[44,1831,875],{"class":98},[44,1833,591],{"class":118},[44,1835,1836],{"class":98},"}).head(",[44,1838,307],{"class":118},[44,1840,141],{"class":98},[143,1842,152,1848,152,1851,152,1854,152,1859,152,1864,152,1868,152,1875,152,1879,152,1882,152,1884,152,1890,152,1895,152,1899,152,1902,152,1908,152,1912,152,1916,152,1920,152,1923,152,1927,152,1930,152,1933,152,1937,152,1940,152,1945,152,1948,152,1951,152,1953,152,1955,152,1957,152,1959,152,1962,152,1965,152,1967,152,1971,152,1973,152,1976,152,1978,152,1981,152,1983,152,1986,152,1989,152,1992,152,1994,152,1996,152,1998,152,2001,152,2003,152,2006,152,2008,152,2011,152,2014,152,2017,152,2019,152,2022,152,2024,152,2027,152,2029,152,2031,152,2033,152,2036,152,2039,152,2042,152,2044,152,2047,152,2049,152,2052,152,2054,152,2057,152,2059,152,2062,152,2065,152,2068,152,2070,152,2073,152,2075,152,2078,152,2080,152,2082,152,2084,152,2088,152,2091,152,2094,152,2096,152,2099,152,2101,152,2104,152,2106,152,2109,152,2111,152,2114,152,2117,152,2120,152,2122,152,2124,152,2126,152,2129,152,2131],{"viewBox":1843,"role":146,"ariaLabelledBy":1844,"xmlns":150,"style":1847},"134 0 491 366",[1845,1846],"fw-sheet-t","fw-sheet-d","width:100%;max-width:491px;height:auto;display:block;margin:1.5rem auto;font-family:Inter,ui-sans-serif,system-ui,sans-serif",[154,1849,1850],{"id":1845},"payroll_20260928.xlsx",[158,1852,1853],{"id":1846},"The Payments sheet with a title line, a header row, five payments with account numbers keeping their leading zeros, a negative amount in red and a net total formula underneath.",[162,1855],{"x":1856,"y":165,"width":1857,"height":1858,"fill":168},"134","491","366",[162,1860],{"x":1861,"y":172,"width":1862,"height":1863,"rx":350,"fill":379,"stroke":177,"style":178},"150.5","459.0","30.0",[162,1865],{"x":1861,"y":1866,"width":1862,"height":1867,"rx":165,"fill":379,"stroke":177,"style":202},"38.0","8.0",[953,1869,1871],{"transform":1870},"translate(160.5,23.0) scale(0.667)",[957,1872],{"d":1873,"fill":201,"stroke":1024,"style":1874},"M6 3h9l4 4v14H6z M15 3v4h4 M9.5 11.5l4.5 6 M14 11.5l-4.5 6","stroke-width:2.70px;stroke-linecap:round;stroke-linejoin:round",[180,1876,1850],{"x":1877,"y":182,"style":1878},"182.5","font-size:12px;font-weight:700;fill:var(--text,#172033);text-anchor:start",[162,1880],{"x":1861,"y":186,"width":1862,"height":1881,"rx":165,"fill":168,"stroke":177,"style":188},"28.0",[162,1883],{"x":1861,"y":186,"width":382,"height":1881,"rx":165,"fill":379,"stroke":177,"style":188},[180,1885,1889],{"x":1886,"y":1887,"style":1888},"170.5","65.0","font-size:12px;font-weight:700;fill:var(--muted,#5b6780);text-anchor:middle","fx",[180,1891,1894],{"x":1892,"y":1887,"style":1893},"200.5","font-size:12px;font-weight:400;fill:var(--text,#172033);text-anchor:start;font-family:ui-monospace,SFMono-Regular,Menlo,Consolas,monospace","=SUM(D4:D8)",[162,1896],{"x":1861,"y":1897,"width":1898,"height":234,"rx":165,"fill":379,"stroke":177,"style":188},"74.0","32.0",[162,1900],{"x":1877,"y":1897,"width":1901,"height":234,"rx":165,"fill":379,"stroke":177,"style":188},"106.1",[180,1903,1907],{"x":1904,"y":1905,"style":1906},"235.5","91.0","font-size:11px;font-weight:600;fill:var(--muted,#5b6780);text-anchor:middle","A",[162,1909],{"x":1910,"y":1897,"width":1911,"height":234,"rx":165,"fill":379,"stroke":177,"style":188},"288.6","144.3",[180,1913,1915],{"x":1914,"y":1905,"style":1906},"360.7","B",[162,1917],{"x":1918,"y":1897,"width":1919,"height":234,"rx":165,"fill":379,"stroke":177,"style":188},"432.9","95.9",[180,1921,303],{"x":1922,"y":1905,"style":1906},"480.8",[162,1924],{"x":1925,"y":1897,"width":1926,"height":234,"rx":165,"fill":379,"stroke":177,"style":188},"528.8","80.7",[180,1928,74],{"x":1929,"y":1905,"style":1906},"569.1",[162,1931],{"x":1861,"y":1932,"width":1898,"height":1881,"rx":165,"fill":379,"stroke":177,"style":188},"98.0",[180,1934,194],{"x":1935,"y":1936,"style":1906},"166.5","117.0",[162,1938],{"x":1877,"y":1932,"width":1939,"height":1881,"rx":165,"fill":168,"stroke":177,"style":188},"427.0",[180,1941,1944],{"x":1942,"y":1936,"style":1943},"396.0","font-size:12px;font-weight:400;fill:var(--text,#172033);text-anchor:middle","PAYROLL BUREAU LTD — batch BATCH0042",[162,1946],{"x":1861,"y":1947,"width":1898,"height":1881,"rx":165,"fill":379,"stroke":177,"style":188},"126.0",[180,1949,243],{"x":1935,"y":1950,"style":1906},"145.0",[162,1952],{"x":1877,"y":1947,"width":1901,"height":1881,"rx":165,"fill":168,"stroke":177,"style":188},[162,1954],{"x":1910,"y":1947,"width":1911,"height":1881,"rx":165,"fill":168,"stroke":177,"style":188},[162,1956],{"x":1918,"y":1947,"width":1919,"height":1881,"rx":165,"fill":168,"stroke":177,"style":188},[162,1958],{"x":1925,"y":1947,"width":1926,"height":1881,"rx":165,"fill":168,"stroke":177,"style":188},[162,1960],{"x":1861,"y":1961,"width":1898,"height":1881,"rx":165,"fill":379,"stroke":177,"style":188},"154.0",[180,1963,307],{"x":1935,"y":1964,"style":1906},"173.0",[162,1966],{"x":1877,"y":1961,"width":1901,"height":1881,"rx":165,"fill":238,"stroke":239,"style":178},[180,1968,1970],{"x":1904,"y":1964,"style":1969},"font-size:12px;font-weight:700;fill:var(--brand-strong,#4338ca);text-anchor:middle","account",[162,1972],{"x":1910,"y":1961,"width":1911,"height":1881,"rx":165,"fill":238,"stroke":239,"style":178},[180,1974,1975],{"x":1914,"y":1964,"style":1969},"name",[162,1977],{"x":1918,"y":1961,"width":1919,"height":1881,"rx":165,"fill":238,"stroke":239,"style":178},[180,1979,1980],{"x":1922,"y":1964,"style":1969},"department",[162,1982],{"x":1925,"y":1961,"width":1926,"height":1881,"rx":165,"fill":238,"stroke":239,"style":178},[180,1984,1985],{"x":1929,"y":1964,"style":1969},"amount",[162,1987],{"x":1861,"y":1988,"width":1898,"height":1881,"rx":165,"fill":379,"stroke":177,"style":188},"182.0",[180,1990,164],{"x":1935,"y":1991,"style":1906},"201.0",[162,1993],{"x":1877,"y":1988,"width":1901,"height":1881,"rx":165,"fill":168,"stroke":177,"style":188},[180,1995,620],{"x":1904,"y":1991,"style":1943},[162,1997],{"x":1910,"y":1988,"width":1911,"height":1881,"rx":165,"fill":168,"stroke":177,"style":188},[180,1999,2000],{"x":1914,"y":1991,"style":1943},"OKAFOR, ADAEZE",[162,2002],{"x":1918,"y":1988,"width":1919,"height":1881,"rx":165,"fill":168,"stroke":177,"style":188},[180,2004,2005],{"x":1922,"y":1991,"style":1943},"0001",[162,2007],{"x":1925,"y":1988,"width":1926,"height":1881,"rx":165,"fill":168,"stroke":177,"style":188},[180,2009,2010],{"x":1929,"y":1991,"style":1943},"2,450.67",[162,2012],{"x":1861,"y":2013,"width":1898,"height":1881,"rx":165,"fill":379,"stroke":177,"style":188},"210.0",[180,2015,292],{"x":1935,"y":2016,"style":1906},"229.0",[162,2018],{"x":1877,"y":2013,"width":1901,"height":1881,"rx":165,"fill":168,"stroke":177,"style":188},[180,2020,2021],{"x":1904,"y":2016,"style":1943},"0000098231",[162,2023],{"x":1910,"y":2013,"width":1911,"height":1881,"rx":165,"fill":168,"stroke":177,"style":188},[180,2025,2026],{"x":1914,"y":2016,"style":1943},"LINDQVIST, JONAS",[162,2028],{"x":1918,"y":2013,"width":1919,"height":1881,"rx":165,"fill":168,"stroke":177,"style":188},[180,2030,2005],{"x":1922,"y":2016,"style":1943},[162,2032],{"x":1925,"y":2013,"width":1926,"height":1881,"rx":165,"fill":168,"stroke":177,"style":188},[180,2034,2035],{"x":1929,"y":2016,"style":1943},"1,982.50",[162,2037],{"x":1861,"y":2038,"width":1898,"height":1881,"rx":165,"fill":379,"stroke":177,"style":188},"238.0",[180,2040,297],{"x":1935,"y":2041,"style":1906},"257.0",[162,2043],{"x":1877,"y":2038,"width":1901,"height":1881,"rx":165,"fill":168,"stroke":177,"style":188},[180,2045,2046],{"x":1904,"y":2041,"style":1943},"0000401777",[162,2048],{"x":1910,"y":2038,"width":1911,"height":1881,"rx":165,"fill":168,"stroke":177,"style":188},[180,2050,2051],{"x":1914,"y":2041,"style":1943},"MARTIN, CLAIRE",[162,2053],{"x":1918,"y":2038,"width":1919,"height":1881,"rx":165,"fill":168,"stroke":177,"style":188},[180,2055,2056],{"x":1922,"y":2041,"style":1943},"0002",[162,2058],{"x":1925,"y":2038,"width":1926,"height":1881,"rx":165,"fill":168,"stroke":177,"style":188},[180,2060,2061],{"x":1929,"y":2041,"style":1943},"3,120.00",[162,2063],{"x":1861,"y":2064,"width":1898,"height":1881,"rx":165,"fill":379,"stroke":177,"style":188},"266.0",[180,2066,300],{"x":1935,"y":2067,"style":1906},"285.0",[162,2069],{"x":1877,"y":2064,"width":1901,"height":1881,"rx":165,"fill":168,"stroke":177,"style":188},[180,2071,2072],{"x":1904,"y":2067,"style":1943},"0000077002",[162,2074],{"x":1910,"y":2064,"width":1911,"height":1881,"rx":165,"fill":168,"stroke":177,"style":188},[180,2076,2077],{"x":1914,"y":2067,"style":1943},"NAKAMURA, KEN",[162,2079],{"x":1918,"y":2064,"width":1919,"height":1881,"rx":165,"fill":168,"stroke":177,"style":188},[180,2081,2056],{"x":1922,"y":2067,"style":1943},[162,2083],{"x":1925,"y":2064,"width":1926,"height":1881,"rx":165,"fill":168,"stroke":177,"style":188},[180,2085,2087],{"x":1929,"y":2067,"style":2086},"font-size:12px;font-weight:700;fill:var(--accent-ink,#be185d);text-anchor:middle","-15.50",[162,2089],{"x":1861,"y":2090,"width":1898,"height":1881,"rx":165,"fill":379,"stroke":177,"style":188},"294.0",[180,2092,350],{"x":1935,"y":2093,"style":1906},"313.0",[162,2095],{"x":1877,"y":2090,"width":1901,"height":1881,"rx":165,"fill":168,"stroke":177,"style":188},[180,2097,2098],{"x":1904,"y":2093,"style":1943},"0000123999",[162,2100],{"x":1910,"y":2090,"width":1911,"height":1881,"rx":165,"fill":168,"stroke":177,"style":188},[180,2102,2103],{"x":1914,"y":2093,"style":1943},"O'BRIEN, SEAN",[162,2105],{"x":1918,"y":2090,"width":1919,"height":1881,"rx":165,"fill":168,"stroke":177,"style":188},[180,2107,2108],{"x":1922,"y":2093,"style":1943},"0003",[162,2110],{"x":1925,"y":2090,"width":1926,"height":1881,"rx":165,"fill":168,"stroke":177,"style":188},[180,2112,2113],{"x":1929,"y":2093,"style":1943},"2,219.75",[162,2115],{"x":1861,"y":2116,"width":1898,"height":1881,"rx":165,"fill":379,"stroke":177,"style":188},"322.0",[180,2118,347],{"x":1935,"y":2119,"style":1906},"341.0",[162,2121],{"x":1877,"y":2116,"width":1901,"height":1881,"rx":165,"fill":168,"stroke":177,"style":188},[162,2123],{"x":1910,"y":2116,"width":1911,"height":1881,"rx":165,"fill":168,"stroke":177,"style":188},[162,2125],{"x":1918,"y":2116,"width":1919,"height":1881,"rx":165,"fill":168,"stroke":177,"style":188},[180,2127,2128],{"x":1922,"y":2119,"style":1943},"Net total",[162,2130],{"x":1925,"y":2116,"width":1926,"height":1881,"rx":165,"fill":1016,"stroke":1017,"style":178},[180,2132,2134],{"x":1929,"y":2119,"style":2133},"font-size:12px;font-weight:700;fill:var(--teal-ink,#0b6157);text-anchor:middle","9,757.42",[30,2136,2138],{"id":2137},"letting-pandas-infer-the-columns","Letting pandas infer the columns",[10,2140,2141,2142,2144,2145,2148,2149,2152],{},"When no layout document exists, ",[19,2143,436],{}," can guess. Its default, ",[19,2146,2147],{},"colspecs=\"infer\"",", looks at the first ",[19,2150,2151],{},"infer_nrows"," lines (100 by default) and places a boundary wherever every line has a space in the same column:",[35,2154,2156],{"className":85,"code":2155,"language":87,"meta":40,"style":40},"guess = pd.read_fwf(\"payroll_20260928.txt\", header=None, dtype=str)\nprint(guess.shape)\nprint(guess.head(3).to_string())\n",[19,2157,2158,2187,2194],{"__ignoreMap":40},[44,2159,2160,2163,2165,2167,2169,2171,2173,2175,2177,2179,2181,2183,2185],{"class":46,"line":47},[44,2161,2162],{"class":98},"guess ",[44,2164,135],{"class":94},[44,2166,554],{"class":98},[44,2168,125],{"class":54},[44,2170,559],{"class":98},[44,2172,596],{"class":131},[44,2174,135],{"class":94},[44,2176,601],{"class":118},[44,2178,559],{"class":98},[44,2180,1823],{"class":131},[44,2182,135],{"class":94},[44,2184,591],{"class":118},[44,2186,483],{"class":98},[44,2188,2189,2191],{"class":46,"line":108},[44,2190,119],{"class":118},[44,2192,2193],{"class":98},"(guess.shape)\n",[44,2195,2196,2198,2201,2203],{"class":46,"line":115},[44,2197,119],{"class":118},[44,2199,2200],{"class":98},"(guess.head(",[44,2202,307],{"class":118},[44,2204,2205],{"class":98},").to_string())\n",[10,2207,2208,2209,2212,2213,2215],{},"On this file it finds just two columns: one gap after the padded name and nothing else, because the account runs straight into the name (",[19,2210,2211],{},"0000123456OKAFOR",") and the department, amount and sign touch each other. Inference works for files where every field is separated by at least one space of padding, such as reports formatted for printing, and fails on files designed for machines, like this one. It is also thrown off when the first 100 lines are not representative — a long block of header records, say. Use it to explore an unknown file, then write the real positions down in a layout file and read with explicit ",[19,2214,440],{}," from then on.",[30,2217,2219],{"id":2218},"common-pitfalls","Common pitfalls",[2221,2222,2223,2234,2243,2249,2263],"ul",{},[2224,2225,2226,2230,2231,28],"li",{},[2227,2228,2229],"strong",{},"Off-by-one colspecs."," Layout documents count from 1 with inclusive ends; Python slices count from 0 with exclusive ends. Convert with ",[19,2232,2233],{},"(start - 1, end)",[2224,2235,2236,2239,2240,2242],{},[2227,2237,2238],{},"Losing leading zeros."," Read with ",[19,2241,616],{}," and convert numeric fields explicitly.",[2224,2244,2245,2248],{},[2227,2246,2247],{},"Implied decimals left in."," An amount field without a decimal point is almost never in whole currency units; check the layout.",[2224,2250,2251,2254,2255,2258,2259,2262],{},[2227,2252,2253],{},"Encoding."," Older systems write cp1252, latin-1 or even EBCDIC (",[19,2256,2257],{},"cp500","). Pass ",[19,2260,2261],{},"encoding="," and check a name with accents.",[2224,2264,2265,2268],{},[2227,2266,2267],{},"Tabs."," A tab counts as one character, so a file with tabs is not really fixed-width; replace them first or it will not line up.",[30,2270,2272],{"id":2271},"performance-notes","Performance notes",[10,2274,2275,2277,2278,2281,2282,2284,2285,2288],{},[19,2276,436],{}," does not use the fast C tokenizer that ",[19,2279,2280],{},"read_csv"," has; in a quick test with 300,000 lines it took about two and a half times as long as ",[19,2283,2280],{}," on the same data as a CSV — half a second — so it is still comfortably fast for files of a few hundred thousand lines. For multi-gigabyte files, pass ",[19,2286,2287],{},"chunksize="," and process the details in pieces, accumulating the count and the cents total as you go so the trailer check still covers the whole file. Workbooks hold at most 1,048,576 rows per sheet; a file bigger than that belongs in a database or a Parquet file, with Excel reserved for the summary.",[30,2290,2292],{"id":2291},"conclusion","Conclusion",[10,2294,2295,2296,2298,2299,2302],{},"Keep the record layout in a small table, convert its 1-based inclusive positions to ",[19,2297,440],{},", and read with ",[19,2300,2301],{},"read_fwf(..., dtype=str)",". Split header, detail and trailer records by their type code, apply types field by field — strip padding, divide implied-decimal amounts, apply signs — and check the record count and total against the trailer before writing the workbook with text-formatted IDs and number-formatted amounts.",[30,2304,2306],{"id":2305},"frequently-asked-questions","Frequently asked questions",[10,2308,2309,2312],{},[2227,2310,2311],{},"How do I read a fixed-width file in pandas?","\nUse pandas.read_fwf with colspecs, a list of (start, end) positions with zero-based starts and exclusive ends, or widths, a list of field lengths. Pass names for the columns and dtype=str to keep leading zeros.",[10,2314,2315,2318],{},[2227,2316,2317],{},"What does colspecs=\"infer\" do?","\nIt looks at the first rows of the file and puts a column boundary wherever every row has whitespace at the same position. It works for space-padded reports and fails when fields touch each other without a gap.",[10,2320,2321,2324],{},[2227,2322,2323],{},"How do I handle amounts without a decimal point?","\nMany fixed-width layouts store money in the smallest unit with an implied decimal point, so 000000245067 is 2450.67. Convert the field to an integer and divide by 100, or by the power of ten the layout specifies.",[10,2326,2327,2330],{},[2227,2328,2329],{},"How do I read a file with header and trailer records?","\nRead every line with the detail layout and keep only rows whose record-type field marks a detail, then slice the header and trailer lines separately. Use the trailer's count and total to check the detail rows.",[30,2332,2334],{"id":2333},"related","Related",[2221,2336,2337,2343,2350,2357],{},[2224,2338,2339,2340,2342],{},"Up one level: ",[24,2341,27],{"href":26}," — every format that ends up in a workbook.",[2224,2344,2345,2349],{},[24,2346,2348],{"href":2347},"\u002Fgetting-started-with-python-excel-automation\u002Fhandling-excel-file-formats-and-conversions\u002Fconvert-csv-files-to-excel-with-python\u002F","Convert CSV Files to Excel with Python"," — the delimited cousin of this job.",[2224,2351,2352,2356],{},[24,2353,2355],{"href":2354},"\u002Fadvanced-data-transformation-and-cleaning\u002Fvalidating-excel-data-with-python\u002Freconcile-excel-totals-with-control-totals\u002F","Reconcile Excel Totals with Control Totals"," — the trailer check, generalised.",[2224,2358,2359,2363],{},[24,2360,2362],{"href":2361},"\u002Fformatting-and-charting-excel-reports-with-python\u002Fapplying-number-and-date-formats-in-excel\u002Fformat-zip-codes-and-ids-with-leading-zeros\u002F","Format ZIP Codes and IDs with Leading Zeros"," — keeping account numbers intact in the workbook.",[2365,2366,2367],"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 .sSjpA, html code.shiki .sSjpA{--shiki-default:#005CC5;--shiki-dark:#FF9492}",{"title":40,"searchDepth":108,"depth":108,"links":2369},[2370,2371,2372,2373,2374,2375,2376,2377,2378,2379,2380,2381],{"id":32,"depth":108,"text":33},{"id":430,"depth":108,"text":431},{"id":640,"depth":108,"text":641},{"id":1084,"depth":108,"text":1085},{"id":1239,"depth":108,"text":1240},{"id":1463,"depth":108,"text":1464},{"id":2137,"depth":108,"text":2138},{"id":2218,"depth":108,"text":2219},{"id":2271,"depth":108,"text":2272},{"id":2291,"depth":108,"text":2292},{"id":2305,"depth":108,"text":2306},{"id":2333,"depth":108,"text":2334},"2026-09-29","Read fixed-width exports from banks, payroll and mainframe systems with pandas.read_fwf and write them to Excel: column positions from the layout document, leading zeros kept, implied decimals, header, detail and trailer records in one file, record counts checked against the trailer, and the layout kept in a spreadsheet.","md",[2386,2388,2390,2392],{"q":2311,"a":2387},"Use pandas.read_fwf with colspecs, a list of (start, end) positions with zero-based starts and exclusive ends, or widths, a list of field lengths. Pass names for the columns and dtype=str to keep leading zeros.",{"q":2317,"a":2389},"It looks at the first rows of the file and puts a column boundary wherever every row has whitespace at the same position. It works for space-padded reports and fails when fields touch each other without a gap.",{"q":2323,"a":2391},"Many fixed-width layouts store money in the smallest unit with an implied decimal point, so 000000245067 is 2450.67. Convert the field to an integer and divide by 100, or by the power of ten the layout specifies.",{"q":2329,"a":2393},"Read every line with the detail layout and keep only rows whose record-type field marks a detail, then slice the header and trailer lines separately. Use the trailer's count and total to check the detail rows.","convert fixed width text files to excel with pandas",null,{"breadcrumb":2397},[2398,2400,2403],{"name":2399,"item":1153},"Home",{"name":2401,"item":2402},"Getting Started with Python Excel Automation","\u002Fgetting-started-with-python-excel-automation\u002F",{"name":27,"item":26},"\u002Fgetting-started-with-python-excel-automation\u002Fhandling-excel-file-formats-and-conversions\u002Fconvert-fixed-width-text-files-to-excel-with-pandas",{"title":2406,"description":2407},"Convert Fixed-Width Text Files to Excel with pandas read_fwf","Use pandas.read_fwf with colspecs from a record layout, keep IDs as text, convert implied-decimal amounts, split header\u002Fdetail\u002Ftrailer records, validate counts and totals against the trailer, and write a formatted workbook.","convert-fixed-width-text-files-to-excel-with-pandas","getting-started-with-python-excel-automation\u002Fhandling-excel-file-formats-and-conversions\u002Fconvert-fixed-width-text-files-to-excel-with-pandas\u002Findex",[2411,2412],"file-formats","reading-excel","how-to","jDi_TFntPHi47zTPqRg5QY7wicdwKwG5mLZbAmOCJgc",[2416,2420],{"title":2417,"path":2418,"stem":2419,"children":-1},"Convert Excel Sheets to YAML or TOML Config","\u002Fgetting-started-with-python-excel-automation\u002Fhandling-excel-file-formats-and-conversions\u002Fconvert-excel-sheets-to-yaml-or-toml-config","getting-started-with-python-excel-automation\u002Fhandling-excel-file-formats-and-conversions\u002Fconvert-excel-sheets-to-yaml-or-toml-config\u002Findex",{"title":2421,"path":2422,"stem":2423,"children":-1},"Convert Word Document Tables to Excel with Python","\u002Fgetting-started-with-python-excel-automation\u002Fhandling-excel-file-formats-and-conversions\u002Fconvert-word-document-tables-to-excel-with-python","getting-started-with-python-excel-automation\u002Fhandling-excel-file-formats-and-conversions\u002Fconvert-word-document-tables-to-excel-with-python\u002Findex",[2425,2427],{"path":2426,"title":27},"\u002Fgetting-started-with-python-excel-automation\u002Fhandling-excel-file-formats-and-conversions",{"path":2428,"title":2401},"\u002Fgetting-started-with-python-excel-automation",[],[2431,2434,2437,2441,2444,2448],{"path":2432,"title":2433,"kind":2413},"\u002Fadvanced-data-transformation-and-cleaning\u002Freading-excel-with-polars-and-arrow\u002Fconvert-excel-files-to-parquet-with-python","Convert Excel Files to Parquet with Python",{"path":2435,"title":2436,"kind":2413},"\u002Fadvanced-data-transformation-and-cleaning\u002Fworking-with-large-excel-files-in-python\u002Fconvert-excel-to-csv-with-python","Convert Excel to CSV with Python",{"path":2438,"title":2439,"kind":2440},"\u002Fgetting-started-with-python-excel-automation\u002Fchoosing-a-python-excel-library\u002Fexcel-vs-csv-vs-parquet-for-python-data-pipelines","Excel vs CSV vs Parquet for Python Data Pipelines","compare",{"path":2442,"title":2443,"kind":2440},"\u002Fgetting-started-with-python-excel-automation\u002Fchoosing-a-python-excel-library\u002Fpick-an-excel-engine-for-xlsx-xlsm-xls-xlsb-and-ods","Pick an Excel Engine for .xlsx, .xlsm, .xls, .xlsb and .ods",{"path":2445,"title":2446,"kind":2447},"\u002Fadvanced-data-transformation-and-cleaning\u002Fcleaning-excel-data-with-pandas\u002Ffix-garbled-characters-in-excel-data","Fix Garbled Characters Like \"CafÃ©\" and \"â€™\" in Excel Data","fix",{"path":2449,"title":2450,"kind":2413},"\u002Fgetting-started-with-python-excel-automation\u002Fautomating-excel-with-com-and-pywin32\u002Fextract-vba-macro-code-from-an-excel-file","Extract VBA Macro Code from an Excel File",1790972059160]