PDF 轉純文字或 Markdown:3 個免費指令實測及其限制
PDF to Clean Text or Markdown: 3 Free Commands I Tested (and Where Each Breaks)
作者實測 pdftotext、pymupdf4llm 和 ocrmypdf,整理 PDF 轉純文字或 Markdown 的適用情況與限制。測試檔中,pdftotext -layout 保留表格行列;pymupdf4llm 輸出帶標題的 Markdown,但表格被壓成一行,結果會因 PDF 表格繪製方式而異。掃描 PDF 須先用 ocrmypdf 加入文字層,再抽取文字。
Full disclosure: I make PDF Insight, a web app that does PDF → text/summary. This post is mostly about the free command-line options, because for a lot of jobs they're all you need. I'll say where each one breaks, including mine.
The short version
-
Plain text, fast:
pdftotext -layout file.pdf out.txt(Poppler). Keep-layouton or table rows fall apart. -
Markdown with headings, in Python:
pymupdf4llm.to_markdown("file.pdf"). Good headings, but check your tables. -
Scanned PDFs (images, no text layer): none of the above work. You need OCR first (
ocrmypdf in.pdf out.pdf, then extract). - Don't want to script it / need a summary: a hosted tool (mine is linked at the end, there are others).
The test file
I didn't want to hand-wave, so I made a tiny PDF with a heading, a paragraph, a 3-row table and a second heading, and ran each tool on it. You can rebuild the same file:
# pip install pymupdf
import pymupdf
html = """<h1>Quarterly Report</h1>
<p>Revenue grew in the second quarter while costs stayed flat.
The table below lists results by region.</p>
<table border="1"><tr><th>Region</th><th>Q1</th><th>Q2</th></tr>
<tr><td>North</td><td>120</td><td>140</td></tr>
<tr><td>South</td><td>90</td><td>95</td></tr>
<tr><td>West</td><td>60</td><td>81</td></tr></table>
<h2>Notes</h2><p>West grew fastest because of a new partner. South was flat.</p>"""
story = pymupdf.Story(html=html)
w = pymupdf.DocumentWriter("sample.pdf")
page = pymupdf.paper_rect("a4")
more = 1
while more:
dev = w.begin_page(page)
more, _ = story.place(page + (36, 36, -36, -36))
story.draw(dev)
w.end_page()
w.close()
Versions used: Poppler pdftotext 25.03.0, PyMuPDF / pymupdf4llm 1.28.2, Linux, October 2026.
1. pdftotext (Poppler): the default you probably already have
pdftotext sample.pdf - # print to stdout
pdftotext -layout sample.pdf - # keep the visual layout
Without -layout, the table came out like this — every cell on its own line, so you can't tell which number belongs to which region:
Region Q1 Q2
North
120 140
South
...
With -layout the rows stay together:
Region Q1 Q2
North 120 140
South 90 95
West 60 81
Watch out for: ligatures. "flat" came out as "flat" (one fl character), which breaks grep flat. Normalise it:
import unicodedata
text = unicodedata.normalize("NFKC", text) # 'fl' -> 'fl'
Best for: grepping, quick copy-paste, shell pipelines. What it won't do: headings or Markdown structure.
2. pymupdf4llm: Markdown with real headings
pip install pymupdf4llm
import pymupdf4llm
md = pymupdf4llm.to_markdown("sample.pdf")
print(md)
Output on the test file:
# **Quarterly Report**
Revenue grew in the second quarter while costs stayed flat. ...
**Region Q1 Q2** North 120 140 South 90 95 West 60 81
## **Notes**
Headings became # / ## and the ligature was already fixed. But on this file the table was flattened into one line. Results vary by how the table was drawn in the PDF, so check tables by eye before you feed the output to an LLM or a search index.
Best for: chunking documents for RAG / LLM prompts, where headings matter. What it won't do: guarantee table structure.
3. Scanned PDFs: OCR first
If pdftotext prints nothing (or garbage), the PDF is probably images. Add a text layer, then extract:
# apt install ocrmypdf (or brew install ocrmypdf)
ocrmypdf scanned.pdf searchable.pdf
pdftotext -layout searchable.pdf out.txt
OCR quality depends on the scan; tables from scans are the hardest case for every tool.
4. Hosted tools
If you don't want to script it, or you want a summary rather than raw text, a hosted tool saves time. Options include ChatPDF (chat-first), NotebookLM (free, good across several sources at once) and PDF Insight (mine).
What PDF Insight does: upload a PDF, get clean Markdown text you can copy or download, plus a short, medium or long AI summary with key points; on Pro you can ask questions and get answers cited from the document. The site says its parser is built for complex layouts, tables and multi-column pages, but I didn't include it in the test above, so try it on your own file. Free is 1 PDF; Pro is $15/mo billed yearly. Link: PDF Insight
What I'd do today
- Run
pdftotext -layoutfirst. If the output looks right, stop there. - If you need headings (for chunking/RAG), try
pymupdf4llmand eyeball every table. - If you get nothing back, OCR with
ocrmypdfand extract again. - If you need a summary or Q&A rather than raw text, use a hosted tool and spot-check its answers against the page.
FAQ
Why does my extracted table have one cell per line? You ran pdftotext without -layout. Add it.
Why can't I grep a word I can see in the PDF? Often a ligature (fi, fl) or a hyphenated line break. NFKC-normalise and join hyphenated lines.
Which is best for feeding an LLM? Markdown with headings (e.g. pymupdf4llm), checked for tables. Headings make chunking much better.
Does any of this work on scanned PDFs? Not without OCR. Run ocrmypdf first.
Is it safe to upload confidential PDFs to a hosted tool? Read the tool's privacy policy first; for sensitive files the local commands above keep everything on your machine.
Disclosure: I'm the developer of PDF Insight. This post was drafted with an AI assistant; the commands and outputs above were run on a real file.
來源:DEV Community · dev.to