opendataloader-pdf
Libraryopendataloader-project/opendataloader-pdf
PDF parser for AI-ready data extraction and accessibility automation.
Overview
Open-source PDF parser that extracts structured data (Markdown, JSON, HTML) with bounding boxes, reading order, and table support. Automates PDF accessibility by auto-tagging untagged PDFs into Tagged PDFs, with optional enterprise PDF/UA export. Achieves top benchmarks in extraction accuracy.
README Preview
\n\n# OpenDataLoader PDF\n\n**PDF Parser for AI-ready data. Automate PDF accessibility. Open-source.**\n\n[](https://github.com/opendataloader-project/opendataloader-pdf/blob/main/LICENSE)\n[](https://pypi.org/project/opendataloader-pdf/)\n[](https://www.npmjs.com/package/@opendataloader/pdf)\n[](https://search.maven.org/artifact/org.opendataloader/opendataloader-pdf-core)\n[](https://github.com/opendataloader-project/opendataloader-pdf#java)\n\n\n\n🔍 **PDF parser for AI data extraction** — Extract Markdown, JSON (with bounding boxes), and HTML from any PDF. #1 in benchmarks (0.907 overall). Deterministic local mode + AI hybrid mode for complex pages.\n\n- **How accurate is it?** — #1 in benchmarks: 0.907 overall, 0.928 table accuracy across 200 real-world PDFs including multi-column and scientific papers. Deterministic local mode + AI hybrid mode for complex pages ([benchmarks](#extraction-benchmarks))\n- **Scanned PDFs and OCR?** — Yes. Built-in OCR (80+ languages) in hybrid mode. Works with poor-quality scans at 300 DPI+ ([hybrid mode](#hybrid-mode-1-accuracy-for-complex-pdfs))\n- **Tables, formulas, images, charts?** — Yes. Complex/borderless tables, LaTeX formulas, and AI-generated picture/chart descriptions all via hybrid mode ([hybrid mode](#hybrid-mode-1-accuracy-for-complex-pdfs))\n- **How do I use this for RAG?** — `pip install opendataloader-pdf`, convert in 3 lines. Outputs structured Markdown for chunking, JSON with bounding boxes for source citations, and HTML. LangChain integration available. Python, Node.js, Java SDKs ([quick start](#get-started-in-30-seconds) | [LangChain](#langchain-integration))\n\n♿ **PDF accessibility automation** — Auto-tag untagged PDFs into screen-reader-ready Tagged PDFs at scale. First open-source tool to generate Tagged PDFs end-to-end.\n\n- **What's the problem?** — Accessibility regulations are now enforced worldwide. Manual PDF remediation costs $50–200 per document and doesn't scale ([regulations](#pdf-accessibility--
FAQ (5)
TroubleshootingWhy does opendataloader-pdf print output twice when not using the --quiet flag?
A bug causes stdout output to be duplicated when the --quiet option is not set. The fix resolves the promise with an empty string in streaming mode to prevent the CLI from double-writing. Update to the latest version of opendataloader-pdf, or apply the changes from PR #399 manually: in src/index.ts, in the executeJar function, change the resolve call to resolve(streamOutput ? '' : stdout).
TroubleshootingWhy does deleting a PDF after OpenDataLoaderPDF.processFile fail with 'The file cannot be deleted because it is being used by another process'?
In OpenDataLoader 2.2.1, the PDF PDDocument and related resources are not properly closed after processing, leaving an active file lock. To fix this, add a resource cleanup method and wrap the existing processFile logic in a try-finally block. Implement the following in DocumentProcessor.java:
// Add this method
private static void closePdfResources() {
try {
StaticLayoutContainers.closeContrastRatioConsumer();
} catch (Exception e) {
LOGGER.log(Level.WARNING, "Unable to close contrast ratio consumer: " + e.getMessage());
}
PDDocument document = StaticResources.getDocument();
if (document != null) {
try {
document.close();
} catch (Exception e) {
LOGGER.log(Level.WARNING, "Unable to close PDF document: " + e.getMessage());
}
}
}
// Wrap processFile body in try-finally
public static void processFile(String inputPdfName, Config config) throws IOException {
try {
// ... original code ...
} finally {
closePdfResources();
}
}
After applying this fix, files can be deleted immediately after processing.
TroubleshootingWhy do images fail to display in the generated markdown when the original PDF filename has spaces?
The markdown converter produces image links with unescaped spaces, causing renderers to truncate the path at the first space (e.g., ). To fix, wrap the image path in angle brackets: . This is compliant with CommonMark §6.4 and ensures images render correctly in VS Code, GitHub, and most renderers. The fix was included in commit 4b87a30 (PR #468).
TroubleshootingHow to fix "subprocess.CalledProcessError: returned non-zero exit status 1" when using opendataloader_pdf to convert PDF?
This error is caused by a bug in the image extraction logic when processing certain PDFs (e.g., files generated by QuarkXPress). The bug has been fixed in newer releases. Upgrade opendataloader_pdf to the latest version (v2.0.3 or later) using pip: pip install --upgrade opendataloader_pdf.
TroubleshootingWhy do I get an error when using numpy >= 2.0 with docling or hybrid libraries?
The project already supports numpy >= 2.0 natively (verified with numpy 2.2.6/2.4.2 in lockfiles). If you encounter an error, it is likely due to a stale installation of transitive dependencies like docling or easyocr that previously pinned numpy < 2. To fix, reinstall from scratch: pip install --upgrade --force-reinstall docling or pip install --no-cache-dir docling[easyocr]. Ensure all packages are updated. If the issue persists, check your resolved dependency versions with pip list and report the traceback, Python version, and installation method.