Free · Runs in your browser · No sign-up

PDF to Markdown With Tables

Most converters hand a table back as one long line of prose. This one measures where the columns are, writes real Markdown pipe tables, and counts how many cells it left empty — so it can tell you when it did the job badly instead of letting you find out later. Headings, lists and links preserve their formatting on the way through too.

No PDF handy?
  • 2,469 rows from 293 pagesA Chinese annual report, 329 tables. Nothing was uploaded to do it.
  • Where others return zeroThe same fifteen-page paper: 103 rows here, 0 from pdf2md.net and 0 from PDF.ai.
  • It admits a bad tableAbove a quarter of cells empty, the result says so. No converter that guesses can promise more.
  • 1,000 pages a fileNo cap to hit halfway through a 10-K, and no daily quota to run out of.

What has to happen for a table to survive the trip to Markdown

A PDF does not contain a table. It contains characters at coordinates, and — sometimes — lines drawn near them. Every row below is a step this PDF-to-Markdown converter takes to get a table back out of that, and each one exists because a real document broke without it.

  • Nothing in the file says “cell”

    The ruled box you see is a drawing, not a container. A converter that reads the text stream in order gets the cells in whatever sequence the file happens to store them, which is how a four-column table becomes one line of prose.

  • Columns come from horizontal positions

    Characters that start at the same x-coordinate down the page are one column. The row labels down the left often sit outside the ruled box entirely, so they are pulled back in by their geometry rather than dropped for being outside the frame.

  • A row split by line-wrapping is joined back

    One tall cell wraps onto three lines and the whole row arrives as three fragments. They are merged back into one logical row by how the fragments line up, not by how many lines they occupy.

  • A header squashed into one cell is split back out

    Two- and three-line headers land as a single run of text — “Complexity per Layer Sequential Maximum Path Length” is one real example. Where the column boundaries below it are known, the header is divided along them.

  • Cells that were measured but never filled get a second pass

    The engine can find a cell's box and still write nothing into it. Those are re-read against their own bounding box before the table is emitted, and whatever is still empty afterwards is counted rather than hidden.

Six documents, every table counted

These are the table-bearing documents in the test corpus, converted to Markdown by the same code this page runs. The last column is the share of cells that came out empty — the measure the converter uses on your file to decide whether to warn you.

DocumentPagesTablesRowsEmpty cells
Attention Is All You NeedarXiv 1706.03762151010316.1%
Language Models are Few-Shot LearnersarXiv 2005.14165 (GPT-3)75322672.0%
Deep Residual LearningarXiv 1512.03385, two-column122411714.0%
Berkshire Hathaway 2023 annual reportDense financial tables1521571,46827.1%
令和6年版 情報通信白書 データ編Japanese statistical tables3102053.2%
PetroChina 2023 annual reportChinese A-share edition2933292,46914.4%

One row on this table is over the line: at 27.1% the Berkshire report trips the converter's own warning, and anyone who converts it is told so on screen. It is left in rather than dropped, because a corpus that only shows the documents that went well is not evidence of anything.

The source files, their hashes and the commands that reproduce these counts are on the benchmark page.

One table, four PDF-to-Markdown converters

Table 1 of the Attention paper is four columns by four rows with a header that runs over two lines. Every converter below was given the same file. Their output is quoted from the stored results, not retyped.

pdf2md.net returns it as prose

The rows run into one another and the header runs into the first row. The whole fifteen-page file contains no pipe table at all.

pdf2md.net
Layer Type Complexity per Layer Sequential Maximum Path Length Operations Self-Attention O(n 2 · d) O(1) O(1) Recurrent O(n · d 2 ) O(n) O(n) Convolutional O(k · n · d 2 ) O(1) O(logk(n)) Self-Attention (restricted) O(r · n · d) O(1) O(n/r)

0 table rows in the file

pdf2md.me
| Layer Type | Complexity per Layer | Sequential Operations | Maximum Path Length |
|---|---|---|---|
| Self-Attention | O(n2 · d) | O(1) | O(1) |
| Recurrent | O(n · d2 ) | O(n) | O(n) |
| Convolutional | O(k · n · d ) | O(1) | O(logk(n)) |
| Self-Attention (restricted) | O(r · n · d) | O(1) | O(n/r) |

103 table rows across 10 tables

PDF.ai breaks it into headings

Not only is there no table — the exponents and the second header line become second-level headings, so the document outline fills up with fragments of a table.

PDF.ai
Layer TypeComplexity per LayerSequentialMaximum Path Length
## Operations
Self-AttentionO(n
## 2
·d)O(1)O(1)
RecurrentO(n·d
## 2
)O(n)O(n)

0 table rows · 310 H2s in the file

pdf2md.me
| Layer Type | Complexity per Layer | Sequential Operations | Maximum Path Length |
|---|---|---|---|
| Self-Attention | O(n2 · d) | O(1) | O(1) |
| Recurrent | O(n · d2 ) | O(n) | O(n) |

103 table rows · a three-level outline

iLovePDF builds a table and loses the header

This one does emit pipe tables — 67 rows across the file — so the failure is subtler and worse: three header lines collapse into one cell, “Operations” drops into the body as if it were data, and two empty columns are invented alongside.

iLovePDF
| Layer Type |   | Complexity per Layer Sequential Maximum Path Length |   |
| --- | --- | --- | --- |
|   |   | Operations |   |
| Self-Attention | O(n2 · d) | O(1) | O(1) |

4 columns, 2 of them empty; header in the body

pdf2md.me
| Layer Type | Complexity per Layer | Sequential Operations | Maximum Path Length |
|---|---|---|---|
| Self-Attention | O(n2 · d) | O(1) | O(1) |

4 columns, header where a header goes

Competitor output was captured in August 2026 on the free tier, signed out. Converters change — if one of these has moved, tell us and it gets re-run.

Where PDF to Markdown still gets tables wrong

Every one of these was measured on a document in the corpus above. A page selling table fidelity that listed none of them would be the kind of claim this site exists to argue against.

  • A two-line header becomes two rows

    Berkshire's 59-year performance table heads two columns with “in Per-Share Market Value of Berkshire” stacked over two lines. The first line becomes the header and the second becomes the first body row. The numbers underneath are all correct; the label above them is in the wrong cell.

  • A currency symbol can be stranded

    Accounting layouts put the $ in its own column so the digits line up. Where that gap is wide enough to read as a column boundary, a row comes out as “Insurance – underwriting $ | 5,428” instead of “$5,428”.

  • A nil dash can read as a bullet

    Inside a financial table an em dash meaning “nothing” sits alone at the start of a cell, which is also what a list item looks like. On the worst document in the corpus that accounted for 12.5% of the list items found.

  • A table that is a picture does not convert to Markdown

    Scanned pages have no text layer to measure, so there are no coordinates and no columns. The converter detects that before producing anything and says so, rather than handing back an empty document.

  • Above a quarter empty, you are told

    The warning fires at 25% empty cells and it is not tuned to flatter: the Berkshire report, the densest document here, is over it. The threshold sits past the honest end of the measured range so that it only fires where the damage is not in question.

FAQ

Questions about tables in Markdown

Rows and columns come through as Markdown pipe tables — 2,469 rows out of a 293-page annual report, 103 out of a fifteen-page paper. What can go wrong is placement rather than loss: on dense financial layouts a value can land in the wrong column. The converter measures the share of empty cells and warns you above 25% instead of leaving you to spot it.

A header split over two or three lines is divided along the column boundaries found below it, which works when those boundaries are unambiguous and puts one header line into the first body row when they are not. There is no rowspan or colspan in Markdown, so a merged cell is written into the first cell it covers and the rest are left empty — which is also why the empty-cell figure is reported rather than buried.

Yes, and they are among the cleanest results in the corpus: a 293-page Chinese annual report gives 329 tables and 2,469 rows, and a page of Japanese statistical tables gives 205 rows with 3.2% of cells empty. Column detection works on positions, which do not care what script fills them.

Up to 1,000 pages in one file, and no size limit — the 293-page report above is 12 MB. Past about 50 MB the page warns you it may take a few seconds. There is no daily quota, because the conversion costs nothing to run: it happens on your machine.

No. The converter is WebAssembly running in a worker in your browser, and your file never becomes a network request. You can disconnect from the network after the page loads and convert anyway — which is the only proof of this claim worth anything.

Try it on the worst table you have

A table you already know the right answer to will tell you more in ten seconds than this page can in a thousand words.