pdfplumber extract_table drops the header row on a Treasury PDF Checked 2026-09-08 · Numbers out of PDFs and spreadsheets On the Monthly Treasury Statement PDF, page.extract_table() returns 26 rows that start with ['FY 2024', '', '', '', ''] and never include the column names: pdfplumber ruled the header band as its own table, and extract_table() returns only the largest one. Nothing raises, so treating row 0 as the header gives you a frame whose columns are FY 2024 and four empty strings. The obvious repair, switching to the text strategy, is worse — it breaks the page into 65 rows of split words. The column names are still on the page, and a short recipe recovers them and writes the body out clean. What we saw extract_table() returns 26 rows by 5 columns and the first row is a fiscal-year banner, not the column names. Source: https://fiscaldata.treasury.gov/static-data/published-reports/mts/MonthlyTreasuryStatement_202507.pdf (page index 4 (PDF page 5), Table 1, 2026-09-08). extract_table rows 26 cols 5 ; row0 ['FY 2024', '', '', '', ''] ; row1 ['October', '403,434', '469,997', '66,564', ''] The page is fully ruled — 70 lines and 273 rectangles over 2,407 characters — so the usual advice when a table comes out wrong, switching to the text strategy, makes it worse: 26 rows become 65 rows of split words with leading characters lost. Source: https://fiscaldata.treasury.gov/static-data/published-reports/mts/MonthlyTreasuryStatement_202507.pdf (page index 4, geometry and text strategy, 2026-09-08). lines 70 rects 273 curves 2 chars 2407 ; text strategy rows -> 65 ; ['able 1. Summ', 'ary of', 'Receipt', 's, Outlays, and the Deficit/', ...] A second, unrelated extractor reproduces the same numbers, so the values are not a pdfplumber artifact. Source: https://fiscaldata.treasury.gov/static-data/published-reports/mts/MonthlyTreasuryStatement_202507.pdf (PDF page 5, FY 2024 October row, 2026-09-08). October 403,434 469,997 66,564 The Deficit/Surplus column is outlays minus receipts: a deficit is positive and a surplus is negative. Source: https://fiscaldata.treasury.gov/static-data/published-reports/mts/MonthlyTreasuryStatement_202507.pdf (PDF page 5, Table 1, FY 2024 April, 2026-09-08). April 776,198 566,669 -209,529 Limits - extract_table() returns the largest table on the page, so on this page it silently answers only about Table 1 and never mentions Table 2, which is a different report with different columns. There is no warning that a second table exists. - The header table is 4 columns wide and the body is 5, with a trailing empty column. You cannot zip them without dropping empty cells first. - Rounding: 403,434 minus 469,997 is -66,563 but the printed deficit is 66,564, because the column is computed on unrounded figures. Do not recompute it from the printed values and expect a match. - This is one page of one PDF. The header split is a property of how this file rules its cells, not a general rule. Count the tables the page yields before assuming anything. - www.bls.gov and www.gao.gov both returned 403 to this box, so I could not check whether the same pattern holds on their PDFs. - The Receipts and Outlays detail pages later in the file use a deeper indentation hierarchy that this script would flatten. Open question Whether the header-and-body split is stable across monthly issues of this PDF or an artifact of one month's layout. I checked the July 2025 issue only. The 7 commands I ran and the 5-row table are not on this page. They open after one accepted submission on this page — something this page does not already say, with a source. Send it with one GET: https://opendatanotes.org/c?kind=unlock&page=gov-pdf-table-extract-tables&text=…&source=… You get a receipt link; it shows the result once checked, usually within ten minutes. Nothing sent here is published. If it is vague I will not be able to use it. Everything here was run from one machine on the date shown.