Skip to content

Turn a Report Table into Checkable Documentary Research

Film

Turn a Report Table into Checkable Documentary Research

A table in a public report is one of the cheapest pieces of evidence a documentary pitch can carry. It is also one of the easiest things to break. Paste the cells into your notes and they stop looking like the page. A site identifier loses its leading zeros. A printed dash becomes nothing, or becomes a zero. The footnote that said what the dash meant stays behind, on page two, where nobody is looking.

The job here is narrow. Take one bounded table out of a text-based PDF, keep its headers, units, and notes attached to the numbers, and be able to hand a colleague the page and the exact cell behind every figure you quote. That is the whole deliverable. A tidy CSV is not proof that your extraction was accurate — and an accurate extraction is not proof that the publisher's numbers are right. Those are two different claims, and your pitch only needs the first one. Keeping them separate is most of what makes the work trustworthy.

Establish the source and stop at the text-table boundary

Before you open a tool, write down what you are extracting from. Publisher, report title, version, date, the pages the table sits on, and the table number and title as printed. If there is a v1.2 and an earlier v1.1, one of them is your source, and you should be able to say which without thinking about it.

Then look at the page itself. Is the table text, or is it a picture of text? Put your cursor on a cell and try to highlight a value. If you can select "Ashfield" as characters, you have a text layer and a text-extraction route is available. If the selection drags across the whole page as one block, or grabs nothing at all, you are holding a scan.

That distinction decides your method, because the route documented by the Tabula project is limited to text-based PDFs. Its "How to Use" page walks through uploading a PDF, selecting a table region, previewing the extraction, adjusting the selection, and exporting structured data — and it says plainly that scanned, image-only PDFs are out of scope (checked September 2026). That is the documented sequence and its stated boundary. It is not a promise about your installation, and it is not a claim that the extraction will come back correct. Nothing on the page says that.

If your table is a scan, you are now doing optical recognition, which has its own error modes, its own confidence problems, and a different story to tell about how you know a number. Do not drift into it because the text route didn't work. Two methods that produce two differently uncertain numbers are not interchangeable, and "the page is a scan and I haven't built that pipeline yet" is a better sentence than a figure you can't defend.

Last thing before you touch anything: keep the source. Save an unchanged copy, and note the exact region you're about to process — page number plus the four edges, or a captured image of the selected area. Everything downstream is a derivative, and a derivative needs somewhere to point back to.

Preview the selected region before accepting its columns

Extraction by region works like this. You draw a box around the table. The tool looks for the vertical and horizontal rules and the gaps between cells, guesses where the rows and columns are, and shows you what it thinks it found. You adjust the box. You look again. Only then do you export.

That preview is the whole game. Exporting before you've studied the preview means you've decided the columns are right without checking, which is exactly the thing you were trying to avoid.

Two shapes of trouble are worth hunting for specifically.

A wide header. A top header row where one label — FY2024, say — spans two columns can pull a detected boundary toward the middle of the span. The result looks like a normal table with normal numbers in it.

A wrapped label. A site name that runs onto a second line inside a narrow column can be read as a new row, or can shove the values beside it one column over. This is the one that survives export and gets quoted.

When the preview shows a number sitting under the wrong heading, redraw the region before exporting. Sometimes a small adjustment fixes it cleanly: move one vertical edge, tighten the box, or split the table into two regions and process each. Sometimes no adjustment fixes it. When that happens, keep the messy version and repair it by hand, and write down that you did. A rectangle that looks tidy because it quietly merged two columns is worse than a lopsided export you're going to fix — at least the lopsided one is honest about what happened.

If the table runs across a page break, treat the two pages as two jobs. Check the repeated header and the continuation boundary independently. A region drawn on page one does not transfer to page two; the columns may sit at different widths, and the repeated header is often compressed to a single line.

Restore the meaning above and below the numbers

A good preview gives you strings in a grid. Numbers in a report carry meaning in the words around them, and those words do not extract alongside the digits. Put them back before you do any arithmetic.

Header hierarchy. A two-row header, with FY2024 spanning Preventive and Corrective, means the year is part of the number. "80" is not a fact. "80 preventive work orders in FY2024" is. Flatten the hierarchy so that every column carries its full label.

Period labels. Tables run several years side by side, and the year is not always in the column header. Sometimes it's in a row.

Units. Work orders, dollars, days, square feet. A count of 131 is not a claim until you have said what it counts.

Identifiers. "004" is a site identifier, not the number four. Let a spreadsheet see it as a number and the leading zeros go, along with the row's identity. Force the column to text.

Footnotes and source symbols. A printed dash with a footnote reading "— = not reported" is a third state. It is not zero, which is a measurement — the site did none — and it is not an unexplained gap. "Not reported" is an absence of measurement, and a claim built on it collapses the moment someone asks why the number isn't there.

Undefined blanks. If a cell is empty and nothing on the page says what empty means, it stays undefined. Do not decide for it. Carry it forward marked unresolved.

Repeated headers. The header that reappears at the top of the second page is not a data row. Leave it in and a sum will treat it as a site with no values, and a sort will scatter it through the middle of your data.

The scope of a note. A footnote attached to one column governs that column. It does not quietly become a rule for the table. Two columns can look perfectly parallel and mean different things, and a note that covers one of them is not covering the other.

Here is the test. Can you read a cell out of your working table and say what it means without going back to the PDF? If you have to go back, the meaning isn't in the table yet.

Verify the cells you will rely on

Everything in this section is invented: the report, the library system, the numbers, and the failed export. Nothing below is the output of any real run, and none of it was produced by an installed tool. The point is the check, which works the same way whether your export came back clean or crooked.

The invented source. Meadowbrook Library System — Facilities Maintenance Report, FY2024, a two-page document. Table 2, "Completed maintenance work orders by site," begins on page one under a two-row header and continues onto page two, where the header repeats. Footnote 2 reads: "— = not reported."

Page one carried three sites under the FY2024 / Preventive–Corrective header: 001 Alder Ridge, 96 and 47; 002 Bramble Center, 143 and 88; 003 Ashfield, 131 and 39. Page two carried three more and the district total.

Site ID Site Preventive Corrective
004 Bellwether — ² 22
005 Corwin Branch 80 61
006 Dunmore Depot 0
District preventive total 450

Read the page before you read the export. Four things are visible here. Site 004's preventive cell is a dash, which footnote 2 says means not reported — not zero. Site 006's preventive cell is a reported zero, which is a different thing entirely. Site 006's corrective cell is empty, and nothing on the page explains it. And the district total covers the preventive column only; there is no corrective total anywhere on the page.

The arithmetic checks out too. Add the reported preventive values — 96, 143, 131, 80, and 0 — and you get 450, which is what the report says. The total is consistent with the five sites that reported, and it excludes site 004 for the reason footnote 2 gives.

Now here is the invented export, before any correction. It has two problems.

Site ID Site Preventive Corrective
001 Alder Ridge 96 47
002 Bramble Center 143 88
003 Ashfield 131 39
Site ID Site Preventive Corrective
004 Bellwether 22
005 Corwin Branch 80 61
006 Dunmore Depot 0
District preventive total 450

The first problem is the repeated header, sitting in the middle of the data as though it were a site. It isn't fatal and it's easy to spot, but it will break a sum if it stays.

The second problem is Bellwether. The export has 22 in the Preventive column and nothing in Corrective. The page has it the other way around: a dash in Preventive, and 22 in Corrective. That is a one-column shift on a single row — the kind of thing a boundary that drifted, or a cell whose contents didn't come through, leaves behind. It is also the kind of error that is nearly invisible if you only look at the number you already decided you wanted.

In this case the shift announced itself. Sum the exported Preventive column: 96 + 143 + 131 + 22 + 80 + 0 = 472. The report's own district total says 450. The difference is 22 — exactly the value sitting in the wrong column.

That is what a subtotal is good for. It's a diagnostic. It flagged the row, and the remedy was to open page two and compare the cell against the page. It is not proof of anything on its own, and it's worth being precise about why. A total can be right while a constituent cell is wrong, if two errors cancel. Had Bellwether's value been off by 22 in the other direction and some other cell off by 22 the same way, the total would still read 450 and nothing would look wrong. A reconciled subtotal tells you the column is probably aligned. It does not tell you that every cell is correct.

Here is the corrected working table, with the raw export kept untouched beside it.

Site ID Site Preventive Corrective
001 Alder Ridge 96 47
002 Bramble Center 143 88
003 Ashfield 131 39
004 Bellwether — (not reported) 22
005 Corwin Branch 80 61
006 Dunmore Depot 0 (unresolved)
District preventive total 450

Notice what did not happen. The blank corrective cell for site 006 is still blank. The preventive total reconciles at 450, and site 006's preventive zero is part of that sum, so that row is half-verified. It would be easy to let the half-verification spill sideways and conclude that the corrective cell must also be a zero, or must mean "not reported" like the dash one column over. It doesn't. The report gave no corrective total, defined no symbol for an empty corrective cell, and said nothing about why that cell is empty. A matching total in the next column over is not a definition.

Corrections go in a log, not in the export. One line per change, with four fields: where in the source, what the raw export said, what it should say, and why.

Source location Raw value Revised value Reason
p. 2, Table 2, row Site ID 004, Preventive column 22 — (not reported, footnote 2) Export placed the row's Corrective value in the Preventive column and left Corrective empty. The source page shows "—" with footnote marker 2 in Preventive and 22 in Corrective. Detected when the Preventive column summed to 472 against the report's stated district total of 450.
p. 2, Table 2, row between Site ID 003 and Site ID 004 "Site ID / Site / Preventive / Corrective" row removed Repeated page header on the continuation page, not a data row.

Now trace the figure you actually want. Suppose the pitch is about Bellwether. Two counts are available, and they are not interchangeable.

The 22 belongs to the Corrective column of the row for Site ID 004, on page two of the FY2024 report. Footnote 2 attaches to the Preventive cell in that row, not to this one. The dash belongs to the Preventive cell, and footnote 2 says it means not reported. It is not a zero. Bellwether's preventive figure for the year is unknown from this table.

Which means the sentence the raw export would have supported — "Bellwether completed 22 preventive work orders in FY2024" — is wrong twice over. It reads a not-reported value as a number, and it reads the wrong column. Both errors were in the export, and both were caught by comparing the export against the page rather than against itself.

Carry one bounded figure into the pitch

Only now does a number go into the pitch, and it goes in with its scope attached.

The usable figure here is the district preventive total: 450 completed preventive work orders in FY2024, across the five sites that reported, from Table 2 of the Meadowbrook facilities report. That sentence has to carry "the five sites that reported," because 450 excludes Bellwether for a stated reason — its figure was not reported. Drop that clause and the number quietly claims a district-wide total it isn't.

Alternatively, 22 corrective work orders at Bellwether in FY2024 is usable as a site-level figure, as long as it stays in its column and its year.

The blank is not usable. Site 006's corrective cell goes into the pitch as an explicit unresolved point, or it doesn't go in at all. Filling it by inference — assuming the library did no corrective work, or assuming the preventive total adding up means the row is trustworthy — is how a working table turns back into a guess.

Keep three things, separately. The raw export, exactly as it came out, uncorrected. The corrected working table. The correction log. Do not clean the raw export; its whole value is that it shows what the tool actually produced, and if someone later disputes a figure you've carried into the pitch, the log and the raw export are how you show your work.

And stop at the edge of the table. Joining this table to another one, running a rate, or comparing sites across a district — those are separate operations with their own error modes and their own questions about whether two sources define their terms the same way. Extraction gets you a number you can defend. It does not get you a conclusion.

Finish with one figure you can trace, or finish with a note saying you looked and decided not to use one. Both are results, and the second is often the more useful thing to hand a director who is about to put a number in front of a funder.

What you're after isn't a clean CSV. It's a number you can say out loud — with a page, a column, a year, and a caveat attached — and know that the colleague who checks it will find the same thing you did. The cleanup is never invisible. Write it down. A correction log sitting next to an untouched raw export is a great deal more convincing than a table that happens to look perfect.

Frequently asked questions

What is the first thing to check before extracting a table from a PDF?

Establish the source: publisher, report title, version, date, pages, and the table number and title as printed. Then check whether the table is text or a scan by trying to select a cell value. The documented Tabula route is limited to text-based PDFs and says scanned, image-only PDFs are out of scope. If it is a scan, you are doing optical recognition with different error modes and uncertainty.

Why study the preview before exporting the table?

The preview shows what the tool thinks the rows and columns are. Watch for a wide header that spans columns and can pull a detected boundary toward the middle, and for a wrapped label that can be read as a new row or shove values one column over. Redraw the region, split the table, or treat pages across a page break as separate jobs before exporting.

What meanings must be restored before using the numbers?

Restore header hierarchy so the year is part of the value, period labels, units, and identifiers as text so leading zeros are not lost. Footnotes and source symbols matter: a dash with a note saying not reported is not zero. Undefined blanks stay unresolved. Repeated headers are not data rows, and a footnote attached to one column governs that column, not the whole table.

How can a subtotal help verify an extraction, and what are its limits?

A subtotal can flag misalignment. In the article's invented Meadowbrook example, summing the exported preventive column gave 472 against the report's stated district total of 450; the difference of 22 pointed to Bellwether's value having shifted from corrective to preventive. But a total can be right while a cell is wrong if two errors cancel, so reconciliation is not proof that every cell is correct. Compare against the source page.

How should a table figure enter a documentary pitch?

Carry it with scope. For example, 450 completed preventive work orders in FY2024 across the five sites that reported, from Table 2, is usable because it names the excluded site and the reason. Bellwether's 22 corrective work orders are usable as a site-level figure if kept in its column and year. A blank corrective cell stays unresolved or is omitted. Keep the raw export, corrected working table, and correction log separate; extraction gets a defensible number, not a conclusion.

More in Film Browse all articles