To turn a PDF into an HTML table, first get the table's rows out as clean cells, in a spreadsheet or CSV. Then write them as table markup: a caption, a header row of th cells with scope set, and td cells for the data. Right-align the amounts. The result can be pasted into any page, read aloud and searched.
Getting rows out of the PDF before writing the HTML table
Extract the table into a spreadsheet or CSV first, because a PDF stores positioned text, not cells. Copying straight from the PDF into an editor usually gives you values in the wrong order or run together. A spreadsheet lets you check every row and column before any markup exists.
A short preparation pass pays off:
- Convert or copy the table into a sheet with one value per cell.
- Delete page headers, footers and repeated column titles from later pages.
- Join descriptions that wrapped onto a second line.
- Check the row count and one total against the PDF.
On a Mac, the routes for that first step differ from Windows, and converting a PDF to Excel on a Mac goes through them. If the table is going into a database rather than a page, loading PDF rows into SQL is the better next stop.
Once the cells are clean, a CSV export is the easiest input for writing HTML by hand or by script. To look at that CSV without a spreadsheet reformatting the dates, see viewing a CSV file without Excel changing it.
Which tags does an HTML table from a PDF need?
A table taken from a PDF needs five things: a table element, a caption naming it, a thead with the column titles in th cells, a tbody holding the data rows in td cells, and scope="col" on each header. The caption and header cells are what make the table readable without seeing it.
The W3C's Web Accessibility Initiative tables tutorial says header cells must be marked up with th and data cells with td, and that scope sets whether a header applies to a column or a row. Its page on captions and summaries says a caption "functions like a heading for a table" and is placed directly inside the table element.
A complete example
Here is an example table with made-up values, ready to paste:
<table class="statement">
<caption>Example checking account, first week of June 2026</caption>
<thead>
<tr>
<th scope="col">Date</th>
<th scope="col">Description</th>
<th scope="col">Amount</th>
<th scope="col">Balance</th>
</tr>
</thead>
<tbody>
<tr><td>2026-06-01</td><td>Opening balance</td><td></td><td>2,400.00</td></tr>
<tr><td>2026-06-03</td><td>Hardware store</td><td>-86.15</td><td>2,313.85</td></tr>
<tr><td>2026-06-05</td><td>Client payment</td><td>950.00</td><td>3,263.85</td></tr>
</tbody>
</table>
<style>
.statement td:nth-child(n+3),
.statement th:nth-child(n+3) {
text-align: right;
font-variant-numeric: tabular-nums;
}
</style>
Every part has a job. The caption tells a screen reader user which table this is before they enter it. The scope="col" attributes tie each value to its column title, so a reader hears "Amount, -86.15" instead of a bare number. The empty amount cell on the opening line is left empty, not filled with a dash, so it reads as no value.
Lining up amounts in an HTML table converted from a PDF
Right-align the amount and balance columns and switch on tabular figures. With both in place, the decimal points of two-decimal amounts sit in one vertical line, just as they did in the PDF. Leave dates and descriptions left-aligned so the eye can scan them.
Tabular figures matter because many fonts give digits different widths. A 1 is often narrower than an 8, so right-aligned numbers still wobble. MDN's reference for the CSS font-variant-numeric property says tabular-nums switches to figures that are all the same size, so they line up like a table.
Keep the number format consistent too. If one row shows 950.00 and another shows 950, alignment cannot hide the difference. Format every amount with the same number of decimals before you write the markup, and choose whether negatives show a minus sign or brackets.
Why is a picture of a PDF table worse than an HTML table?
An image of a table is a set of pixels, so nobody can select, copy, search or resize its numbers. A screen reader gets only the alt text, which cannot hold every row. On a phone the picture shrinks until the figures are unreadable, while an HTML table can scroll or reflow.
What each version gives the reader:
| Need | Picture of the table | HTML table |
|---|---|---|
| Copy one value | No | Yes |
| Find a payee with the browser's search | No | Yes |
| Hear each cell with its column name | No | Yes, with th and scope |
| Zoom without blur | No | Yes |
| Update one figure | Remake the image | Edit one cell |
A picture is only reasonable for a table you are showing as a document, such as a scan you are discussing. Even then, put the key numbers in the text beside it.
Merged headings and wrapped rows in a PDF to HTML table
Irregular tables need more markup than a single header row. When a PDF table has a heading that spans two columns, or a label that covers several rows, use colspan or rowspan on that cell and scope="colgroup" or scope="rowgroup" on its header. The WAI tutorial covers these as irregular tables.
Before you reach for spans, ask whether the merged cell is decoration. Many PDF tables merge a section title like "Deposits" across the full width. That reads better as two separate HTML tables with their own captions than as one table with a spanning row in the middle.
Wrapped rows need the opposite treatment. A description printed on two lines in the PDF is still one cell. Join the text into a single td and let the browser wrap it to fit the screen.
For bank statements, FastBankConvert is built to turn the PDF into Excel or CSV rows, which would be the clean input the first section asks for. It is getting ready to open; the FastBankConvert homepage explains what it does.