---
title: "pdfplumber in Python: Extract text and tables"
canonical_url: "https://www.nutrient.io/blog/pdfplumber-python-guide/"
md_url: "https://www.nutrient.io/blog/pdfplumber-python-guide.md"
last_updated: "2026-10-13T17:58:08.396Z"
description: "Extract text and tables from PDFs in Python with pdfplumber: the line and text table strategies, word coordinates, cropping, MIT licensing, and where it stops."
---

**TL;DR**

pdfplumber extracts text, tables, and coordinates from PDFs with an existing text layer. Start with its default line strategy for bordered tables, and try text-based boundaries for unruled tables. Inspect the visual debugger when results are wrong. It can render page images but doesn’t perform optical character recognition (OCR) or write PDFs. For varied documents and scans, Nutrient’s Data Extraction API is an option that combines parsing and OCR.

A table can look clear on a PDF page and still extract as an empty list. The visible columns may be aligned words, with no drawn borders for the default table finder to follow. This guide shows how to choose a strategy, inspect the detected cells, and extract text or coordinates when a table isn’t the right representation.

## What is pdfplumber?

pdfplumber is a pure-Python library for reading structured information from a PDF’s content streams: characters with coordinates and font attributes, lines, rectangles, curves, and images. It adds higher-level helpers on top of those primitives for text and table extraction. It’s one of several options in Python — the [Python PDF library comparison](https://www.nutrient.io/blog/best-python-pdf-libraries/) covers where each one fits.

It’s built on [pdfminer.six](https://pdfminersix.readthedocs.io/en/latest/) and released under the MIT license. It can rasterize pages through `page.to_image()`, using `pypdfium2`, but doesn’t perform OCR or write PDFs. Without a text layer, text extraction returns an empty string; image and vector objects can still be inspected.

## Prerequisites

- Python 3.12 for the examples tested here

- A PDF with extractable text, such as a digitally generated document or a scan with an OCR text layer

## Installation

Install the version used for these examples:

```bash

python -m pip install pdfplumber==0.11.10

```

The installer pulls in `pdfminer.six` for parsing and `pypdfium2` for the optional page-image rendering used by the visual debugging helpers. Standard wheels bundle the rendering dependencies on supported platforms; no OCR model is included.

## Extracting text from a PDF

`pdfplumber.open()` returns a PDF object. Accessing `pages` builds the page list, while pdfplumber computes page layout data when needed and caches it. For large files, `page.close()` can release a processed page’s caches. The following example extracts the text of the first page:

```python

import pdfplumber

with pdfplumber.open("document.pdf") as pdf:
    first_page = pdf.pages[0]
    print(first_page.extract_text())

```

The [Python text-extraction guide](https://www.nutrient.io/blog/extract-text-from-pdf-using-python.md) covers the same task across other libraries.

To collect the whole document, iterate the pages and guard against the empty result. `extract_text()` returns an empty string on a page with no extractable characters, so `if text` skips it. Testing `text is not None` would accept the empty string:

```python

import pdfplumber

def extract_document_text(path: str) -> str:
    pages = []
    with pdfplumber.open(path) as pdf:
        for page in pdf.pages:
            text = page.extract_text()
            if text:
                pages.append(text)
    return "\n\n".join(pages)

print(extract_document_text("document.pdf"))

```

Empty text is a reason to inspect the PDF, not proof that it’s a scan. A page may be blank, contain image-only content, use outlined text, or have encoding problems. OCR can help when visible text isn’t extractable.

## Extracting tables

Table extraction is a core pdfplumber feature, and it’s configuration-driven. The [PDF data extraction guide](https://www.nutrient.io/blog/pdf-data-extraction-developer-guide.md) covers the layered alternative: parsing, OCR, layout analysis, and schema-shaped JSON. It suits cases where the goal is the extracted data rather than the parsing stack. `extract_tables()` returns a list of tables, each containing rows of cell strings or `None` values. It returns `[]` when no tables are found. `extract_table()` returns the largest table, or `None` if none is found.

```python

import pdfplumber

with pdfplumber.open("statement.pdf") as pdf:
    page = pdf.pages[0]
    for table in page.extract_tables():
        for row in table:
            print(row)

```

### Bordered tables — The default line strategy

The defaults are `vertical_strategy: "lines"` and `horizontal_strategy: "lines"`, meaning pdfplumber takes cell boundaries from the ruling lines and rectangle edges drawn on the page. This is a useful starting point for bordered tables, although broken lines or closely spaced edges can require tuning.

### Unruled tables — Switching to the text strategy

For a table without drawn cell boundaries, try deriving boundaries from aligned words. The following settings are a starting point for an unruled table. Word alignment and minimum-word thresholds still affect detection:

```python

table_settings = {
    "vertical_strategy": "text",
    "horizontal_strategy": "text",
}

with pdfplumber.open("report.pdf") as pdf:
    table = pdf.pages[0].extract_table(table_settings)

```

For a table with vertical column rules but no horizontal row rules, try mixing `"lines"` vertically with `"text"` horizontally:

```python

table_settings = {
    "vertical_strategy": "lines",
    "horizontal_strategy": "text",
    "snap_y_tolerance": 5,
    "intersection_x_tolerance": 15,
}

```

The tolerance families do different jobs. `snap_*` aligns nearby parallel edges, `join_*` joins collinear segments, and `intersection_*` controls how close orthogonal edges must be to form a cell corner. The settings above are illustrative, not defaults for every document.

An empty result can come from a strategy mismatch, missing text, broken borders, or unsuitable tolerances. `page.debug_tablefinder()` returns a `TableFinder` object for inspecting edges, intersections, cells, and tables. For a visual overlay, use the method on a page image instead:

```python

import pdfplumber

with pdfplumber.open("statement.pdf") as pdf:
    page = pdf.pages[0]
    image = page.to_image(resolution=150)
    image.debug_tablefinder(table_settings={})
    image.save("table-debug.png")

```

This uses the default strategies. Pass the settings you’re testing in place of `{}` to see their effect. The [pdfplumber table extraction reference](https://github.com/jsvine/pdfplumber#extracting-tables) also documents `"lines_strict"` and `"explicit"` strategies.

### Try a bordered-table example

Download the [sample statement](https://www.nutrient.io/downloads/pdfplumber/statement.pdf) and save it as `statement.pdf` beside your script. It contains a bordered table with three made-up transactions. Run the table-extraction and visual-debugging examples from that directory using the default settings.

With Python 3.12 and pdfplumber 0.11.10, the extraction returned one table: a header row and all three transaction rows. The amounts were strings: `1000.00`, `-42.18`, and `250.00`. Download the [extracted rows as CSV](https://www.nutrient.io/downloads/pdfplumber/extracted-rows.csv) to compare the values with your result.![pdfplumber debug overlay showing the bordered sample table, detected cell boundaries, and intersections](@/assets/images/blog/2026/pdfplumber-python-guide/table-debug.png)

This overlay came from the visual-debugging example above. The sample demonstrates the default line strategy on a simple table; test your own layouts separately.

## Working with words and coordinates

Beyond text and tables, pdfplumber exposes the positional data the page is assembled from. `extract_words()` returns each word with its bounding box. `extra_attrs` restricts words to characters that share the same font attributes, which helps isolate headings, totals, or a specific typeface:

```python

with pdfplumber.open("document.pdf") as pdf:
    words = pdf.pages[0].extract_words(extra_attrs=["fontname", "size"])

for word in words[:5]:
    print(word["text"], word["x0"], word["top"], word["fontname"], word["size"])

```

Coordinates make region-based extraction possible. `crop()` takes an `(x0, top, x1, bottom)` bounding box and returns a page restricted to it, so you can read a known layout positionally:

```python

with pdfplumber.open("invoice.pdf") as pdf:
    page = pdf.pages[0]
    header = page.crop((0, 0, page.width, 120))
    print(header.extract_text())

```

For fields at known positions, crop to the region containing the value and extract text from that crop. Fixed coordinates may need adjustment when the layout changes.

## pdfplumber vs. PyMuPDF

Both libraries expose text, tables, and layout data. Compare the specific operations your application needs rather than assuming only one supports a feature.

| Capability                | pdfplumber                                                 | PyMuPDF                                                          |
| ------------------------- | ---------------------------------------------------------- | ---------------------------------------------------------------- |
| License                   | MIT                                                        | AGPL v3 or commercial                                            |
| Parsing implementation    | Python, using `pdfminer.six`                               | MuPDF engine with Python bindings                                |
| Table extraction          | `extract_tables()` with line, text, or explicit strategies | `Page.find_tables()` with configurable strategies and tolerances |
| Character and layout data | Character dictionaries and drawn objects                   | `get_text("rawdict")` and drawing APIs                           |
| Visual inspection         | `to_image().debug_tablefinder()` overlay                   | Page rendering and drawing APIs                                  |
| Page rasterization        | `to_image()`, using `pypdfium2`                            | `Page.get_pixmap()`                                              |
| Writing PDFs              | Not supported                                              | Supported                                                        |
| OCR                       | Not built in                                               | Tesseract integration; requires Tesseract installed separately   |

Choose pdfplumber when its table settings, object dictionaries, and visual debugging fit your extraction task. Evaluate PyMuPDF if you also need PDF editing or its rendering and extraction APIs. Benchmark both on your own files if throughput is a deciding factor. See the [PyMuPDF text extraction guide](https://www.nutrient.io/blog/extract-text-from-pdf-pymupdf/) for examples.

For scanned pages, pdfplumber needs an OCR text layer supplied by another tool. PyMuPDF provides [integrated OCR methods](https://pymupdf.readthedocs.io/en/latest/recipes-ocr.html), including `Page.get_textpage_ocr()`, through a separately installed Tesseract engine.

## Where pdfplumber fits, and where it stops

pdfplumber suits projects that work from digitally generated PDFs with known layouts. In those projects, teams can tune the extraction logic per document type, and per-page speed isn’t the binding constraint.![PDF extraction stages: pdfplumber parses and assembles content; application code handles OCR routing, interpretation, configuration, and throughput.](@/assets/images/blog/2026/pdfplumber-python-guide/where-pdfplumber-stops.png)

The limits show up as document variety increases:

- **OCR** — Image-only text needs recognition before pdfplumber can extract it. Mixed documents may need routing by page.

- **Layout changes** — A table configuration that works on one template may need adjustment on another. Keep representative files for regression checks.

- **Throughput** — Measure text and table extraction separately, with runtime and peak memory limits that match your workload.

- **Field meaning** — Coordinates and cell strings don’t identify business fields by themselves. Your application still maps values and validates them.

These are the tasks between parsing a table and delivering validated records to another system. The [intelligent document processing guide](https://www.nutrient.io/blog/what-is-intelligent-document-processing.md) explains how a broader document workflow handles them.

## Reaching the same outcome with Nutrient

For projects that need extraction across varied layouts and scanned documents, consider [Nutrient’s Data Extraction API](https://www.nutrient.io/api/data-extraction-api/). It combines parsing with OCR and can reduce the amount of extraction infrastructure and layout tuning your team maintains.

The following request uses `/extraction/parse` in `understand` mode and asks for spatial document elements. It doesn’t return Markdown at the same time. Install `requests` with `python -m pip install requests` and replace the placeholder with your Nutrient API key before running it:

```python

import requests

with open("statement.pdf", "rb") as document:
    response = requests.post(
        "https://api.nutrient.io/extraction/parse",
        headers={"Authorization": "Bearer your_api_key_goes_here"},
        files={"file": document},
        data={
            "instructions": '{"mode":"understand","output":{"format":"spatial"}}'
        },
        timeout=120,
    )
    response.raise_for_status()

print(response.json())

```

Use the [document element parsing guide](https://www.nutrient.io/guides/dws-data-extraction/parsing/extract-document-elements.md) to select an output format. The [table extraction API](https://www.nutrient.io/api/table-extraction-api/) page covers the tabular use case. Your application still needs to validate results, map them to its data model, and handle request failures.

For named fields, use schema extraction through `/extraction/extract`. Its citations can include page regions and match labels where available. Not every element returned by the parsing request above carries those labels. See [confidence scores and source grounding](https://www.nutrient.io/blog/document-extraction-confidence-scores.md) and the [extraction case studies](https://www.nutrient.io/blog/pdf-extraction-document-case-studies.md) for how to use evidence during validation.

If documents must stay in your own environment, evaluate the [Python SDK](https://www.nutrient.io/sdk/python/) against your required operations. Check the SDK’s supported operations and output formats separately from the hosted API.

[Extract PDF tables with Nutrient](https://dashboard.nutrient.io/sign_up/?product=data-extraction)

## Conclusion

pdfplumber is a useful choice for text and table extraction when you can test and tune against known layouts. Start with the examples above, inspect failed table detections, and measure performance on the files you’ll process.

Teams that handle varied layouts and scans may want less extraction infrastructure to maintain. Run Nutrient’s Data Extraction API against the same documents and validation criteria.

**Call to Action**

Try Nutrient Data Extraction on your PDFs

[Learn More](https://www.nutrient.io/api/data-extraction-api/)

## FAQ

#### Is pdfplumber free for commercial use?

Yes. Its [MIT license](https://github.com/jsvine/pdfplumber/blob/stable/LICENSE.txt) permits commercial use, subject to retaining the required copyright and permission notice. Check the license text when distributing software that includes it.

#### Which is better, pdfplumber or PyMuPDF?

Use pdfplumber for its table extraction settings and visual debugger. PyMuPDF also extracts tables and character data, and it adds PDF editing and Tesseract-based OCR integration. Compare extraction quality, runtime, and licensing on your own files.

#### Can pdfplumber read scanned PDFs?

It can extract an existing OCR text layer from a scanned PDF, but it can’t recognize text in images itself. For image-only pages, add OCR first or use [Nutrient’s Data Extraction API](https://www.nutrient.io/api/data-extraction-api/), which supports scanned documents.

#### Why does <code>extract_tables()</code> return an empty list on a visible table?

The table finder may lack usable boundaries or text, or its tolerances may not fit the layout. Try text strategies for unruled tables and inspect an overlay with `page.to_image().debug_tablefinder()`. When no tables are found, `extract_tables()` returns `[]`; `extract_table()` returns `None`.

#### When is a document API a better fit than a pdfplumber pipeline?

An API is a better fit when handling scans, layout variation, and extraction infrastructure takes more effort than your team wants to maintain. Test Nutrient’s parsing or schema extraction on representative documents, and check the output against your accuracy and validation requirements.

#### Is pdfplumber fast enough for large documents?

That depends on document complexity, the extraction operations, and your processing window. Benchmark representative files and record both runtime and peak memory. Calling `page.close()` after processing a page can release its cached layout data.

## Related reading

- [Python PDF library comparison](https://www.nutrient.io/blog/best-python-pdf-libraries/)

- [Extract text from a PDF using Python](https://www.nutrient.io/blog/extract-text-from-pdf-using-python.md)

- [PDF data extraction: A developer guide](https://www.nutrient.io/blog/pdf-data-extraction-developer-guide.md)

- [What is intelligent document processing?](https://www.nutrient.io/blog/what-is-intelligent-document-processing.md)

- [Confidence scores and source grounding](https://www.nutrient.io/blog/document-extraction-confidence-scores.md)

- [PDF extraction case studies](https://www.nutrient.io/blog/pdf-extraction-document-case-studies.md)
---

## Related pages

- [The business case for accessibility: Five ways it drives enterprise value](/blog/5-ways-accessibility-drives-enterprise-value.md)
- [Accessibility Untangled Why It Matters Guide](/blog/accessibility-untangled-why-it-matters-guide.md)
- [Advanced Techniques For React Native Ui Components](/blog/advanced-techniques-for-react-native-ui-components.md)
- [`vector_store` holds your indexed documents (see the multimodal RAG post](/blog/agentic-rag.md)
- [Ai Assistant Agent Governance](/blog/ai-assistant-agent-governance.md)
- [How to build an AI agent for contract redlining against a compliance playbook](/blog/ai-contract-redlining-compliance-playbook.md)
- [Ai Document Automation Extraction To Action](/blog/ai-document-automation-extraction-to-action.md)
- [Ai Document Workflows Ocr Compliance Heavy Teams](/blog/ai-document-workflows-ocr-compliance-heavy-teams.md)
- [Ai Legal Assistant Document Authoring](/blog/ai-legal-assistant-document-authoring.md)
- [Ai Schema Generator Document Extraction](/blog/ai-schema-generator-document-extraction.md)
- [Amazon Textract Alternatives](/blog/amazon-textract-alternatives.md)
- [Start (clears any prior buffer), navigate the document, then stop into a file.](/blog/android-faster-pdf-rendering.md)
- [Android Pdf Out Of Memory Handling](/blog/android-pdf-out-of-memory-handling.md)
- [Angular File Viewer Pdf Image Office Files](/blog/angular-file-viewer-pdf-image-office-files.md)
- [Approval Workflow Software](/blog/approval-workflow-software.md)
- [Approvals Matrix](/blog/approvals-matrix.md)
- [Apryse To Nutrient Migration](/blog/apryse-to-nutrient-migration.md)
- [Auto Tagging And Document Accessibility In Dotnet Sdk](/blog/auto-tagging-and-document-accessibility-in-dotnet-sdk.md)
- [Simple PII redaction.](/blog/automated-pii-removal.md)
- [Azure Document Intelligence Alternatives](/blog/azure-document-intelligence-alternatives.md)
- [Best Ai Document Workflow Platforms](/blog/best-ai-document-workflow-platforms.md)
- [Best Document Ai Platforms](/blog/best-document-ai-platforms.md)
- [Best Document Classification Platforms](/blog/best-document-classification-platforms.md)
- [Best document parser for RAG: LlamaParse vs. Unstructured vs. Reducto vs. Nutrient](/blog/best-document-parser-llamaparse-unstructured-reducto.md)
- [Best Document Parsing Apis](/blog/best-document-parsing-apis.md)
- [Best Document Viewers](/blog/best-document-viewers.md)
- [Best Llm Document Understanding Platforms](/blog/best-llm-document-understanding-platforms.md)
- [Best Multilingual Ocr Software](/blog/best-multilingual-ocr-software.md)
- [Best Pdf Parsers For Rag](/blog/best-pdf-parsers-for-rag.md)
- [Best Salesforce Document Generation Apps](/blog/best-salesforce-document-generation-apps.md)
- [Best Secure Document Collaboration Platforms](/blog/best-secure-document-collaboration-platforms.md)
- [Bpm Guide](/blog/bpm-guide.md)
- [Bpm Tools](/blog/bpm-tools.md)
- [Build Vs Buy Document Extraction](/blog/build-vs-buy-document-extraction.md)
- [Business Automation](/blog/business-automation.md)
- [Capex Vs Opex](/blog/capex-vs-opex.md)
- [The CEO’s AI playbook: Why decision architecture beats model selection](/blog/ceo-ai-playbook-decision-architecture.md)
- [1. Extract and chunk the PDF.](/blog/chat-with-pdf.md)
- [Complete Guide To Pdfjs](/blog/complete-guide-to-pdfjs.md)
- [Construction Document Data Extraction](/blog/construction-document-data-extraction.md)
- [Convert One Drive Files To Pdf In Sharepoint](/blog/convert-one-drive-files-to-pdf-in-sharepoint.md)
- [Create And Edit Pdfs In Flutter](/blog/create-and-edit-pdfs-in-flutter.md)
- [Create Pdfs With React](/blog/create-pdfs-with-react.md)
- [Creating A Document Scanner With Ocr In Python](/blog/creating-a-document-scanner-with-ocr-in-python.md)
- [Creating And Filling Pdf Forms Programmatically In Javascript](/blog/creating-and-filling-pdf-forms-programmatically-in-javascript.md)
- [The CTO’s AI playbook: Why accountability architecture beats orchestration](/blog/cto-ai-playbook-accountability-architecture.md)
- [Digital Signatures](/blog/digital-signatures.md)
- [Digital Workflow Automation](/blog/digital-workflow-automation.md)
- [Docling Alternatives](/blog/docling-alternatives.md)
- [Document Ai Vs Ocr](/blog/document-ai-vs-ocr.md)
- [Document Authoring Audit Trail](/blog/document-authoring-audit-trail.md)
- [Document Extraction Confidence Scores](/blog/document-extraction-confidence-scores.md)
- [Document Extraction For Underwriting](/blog/document-extraction-for-underwriting.md)
- [Document Viewer](/blog/document-viewer.md)
- [Document Watermarking](/blog/document-watermarking.md)
- [Electronic signature API: How to sign PDFs programmatically](/blog/electronic-signature-api.md)
- [Emerging threats: Your logging system may be an agentic threat vector](/blog/emerging-threats-your-logging-system.md)
- [Extend Alternatives](/blog/extend-alternatives.md)
- [Extract Patient Data On Premises](/blog/extract-patient-data-on-premises.md)
- [app.py](/blog/extract-text-from-pdf-using-python.md)
- [Fillable Pdf](/blog/fillable-pdf.md)
- [Google Document Ai Alternatives](/blog/google-document-ai-alternatives.md)
- [How To Add Digital Signature To Pdf Using React](/blog/how-to-add-digital-signature-to-pdf-using-react.md)
- [How To Build A Dotnet Maui Pdf Viewer](/blog/how-to-build-a-dotnet-maui-pdf-viewer.md)
- [How To Build A Flutter Pdf Viewer](/blog/how-to-build-a-flutter-pdf-viewer.md)
- [or](/blog/how-to-build-a-javascript-pdf-viewer-with-pdfjs.md)
- [or](/blog/how-to-build-a-javascript-pdf-viewer.md)
- [How To Build A Nextjs Pdf Viewer](/blog/how-to-build-a-nextjs-pdf-viewer.md)
- [How To Build A Powerpoint Viewer Using Javascript](/blog/how-to-build-a-powerpoint-viewer-using-javascript.md)
- [Using Yarn](/blog/how-to-build-a-react-excel-viewer.md)
- [How To Build A React Native Pdf Viewer](/blog/how-to-build-a-react-native-pdf-viewer.md)
- [How To Build A React Powerpoint Viewer](/blog/how-to-build-a-react-powerpoint-viewer.md)
- [How To Build A Reactjs File Viewer](/blog/how-to-build-a-reactjs-file-viewer.md)
- [or](/blog/how-to-build-a-reactjs-pdf-viewer-with-react-pdf.md)
- [or](/blog/how-to-build-a-reactjs-pdf-viewer.md)
- [How To Build A Reactjs Viewer With Pdfjs](/blog/how-to-build-a-reactjs-viewer-with-pdfjs.md)
- [How To Build A Vuejs Pdf Viewer With Pdfjs](/blog/how-to-build-a-vuejs-pdf-viewer-with-pdfjs.md)
- [How To Build A Vuejs Pdf Viewer](/blog/how-to-build-a-vuejs-pdf-viewer.md)
- [How To Build An Android Pdf Viewer](/blog/how-to-build-an-android-pdf-viewer.md)
- [How To Build An Angular Pdf Viewer With Ng2 Pdf Viewer](/blog/how-to-build-an-angular-pdf-viewer-with-ng2-pdf-viewer.md)
- [How To Build An Angular Pdf Viewer With Pdfjs](/blog/how-to-build-an-angular-pdf-viewer-with-pdfjs.md)
- [How To Convert Docx To Pdf Using Javascript](/blog/how-to-convert-docx-to-pdf-using-javascript.md)
- [How To Convert Docx To Pdf Using Python](/blog/how-to-convert-docx-to-pdf-using-python.md)
- [How To Convert Html To Pdf Using Html2pdf](/blog/how-to-convert-html-to-pdf-using-html2pdf.md)
- [How To Convert Html To Pdf Using React](/blog/how-to-convert-html-to-pdf-using-react.md)
- [How To Convert Html To Pdf Using Wkhtmltopdf And Csharp](/blog/how-to-convert-html-to-pdf-using-wkhtmltopdf-and-csharp.md)
- [or](/blog/how-to-convert-html-to-pdf-using-wkhtmltopdf-and-python.md)
- [How To Convert Html To Pptx](/blog/how-to-convert-html-to-pptx.md)
- [Quarterly report](/blog/how-to-convert-pdf-to-markdown-using-python.md)
- [How To Convert Word To Pdf In Nodejs](/blog/how-to-convert-word-to-pdf-in-nodejs.md)
- [or](/blog/how-to-create-a-react-js-signature-pad.md)
- [How To Create Pdfs With React To Pdf](/blog/how-to-create-pdfs-with-react-to-pdf.md)
- [How To Edit Pdfs Using Ios Pdf Library](/blog/how-to-edit-pdfs-using-ios-pdf-library.md)
- [How To Embed A Pdf Viewer In Your Website](/blog/how-to-embed-a-pdf-viewer-in-your-website.md)
- [How To Extract Tables From Pdf And Images](/blog/how-to-extract-tables-from-pdf-and-images.md)
- [How To Generate Pdf From Html With Nodejs](/blog/how-to-generate-pdf-from-html-with-nodejs.md)
- [How to generate PDFs in C# with Nutrient .NET SDK](/blog/how-to-generate-pdf-in-csharp.md)
- [base_url tells WeasyPrint where to resolve relative asset paths](/blog/how-to-generate-pdf-reports-from-html-in-python.md)
- [How To Merge Pdfs Using Javascript](/blog/how-to-merge-pdfs-using-javascript.md)
- [How To Ocr Pdfs In Linux](/blog/how-to-ocr-pdfs-in-linux.md)
- [How To Print Pdf In Csharp](/blog/how-to-print-pdf-in-csharp.md)
- [How To Programmatically Create And Fill Pdf Form In Angular](/blog/how-to-programmatically-create-and-fill-pdf-form-in-angular.md)
- [C# barcode scanner: How to scan and read 1D barcodes and QR codes](/blog/how-to-scan-barcodes-in-csharp.md)
- [Open an image.](/blog/how-to-use-tesseract-ocr-in-python.md)
- [From an HTML string.](/blog/html-in-pdf-format.md)
- [Html To Pdf In Javascript](/blog/html-to-pdf-in-javascript.md)
- [Intelligent Data Extraction](/blog/intelligent-data-extraction.md)
- [Invoice Approval Software](/blog/invoice-approval-software.md)
- [Javascript Document Editor](/blog/javascript-document-editor.md)
- [Javascript Pdf Editors](/blog/javascript-pdf-editors.md)
- [Javascript Pdf Libraries](/blog/javascript-pdf-libraries.md)
- [Landing Ai Alternatives](/blog/landing-ai-alternatives.md)
- [Langextract Vs Llamaindex Extraction Comparison](/blog/langextract-vs-llamaindex-extraction-comparison.md)
- [Linearized Pdf](/blog/linearized-pdf.md)
- [Uses OpenAI by default — set OPENAI_API_KEY.](/blog/llamaindex-vs-langchain-rag.md)
- [Llamaindex Vs Langchain Vs Haystack](/blog/llamaindex-vs-langchain-vs-haystack.md)
- [Llamaindex Workflows Vs Langgraph](/blog/llamaindex-workflows-vs-langgraph.md)
- [Llamaparse Alternatives](/blog/llamaparse-alternatives.md)
- [Low Code No Code Document Integrations](/blog/low-code-no-code-document-integrations.md)
- [Material Requisition](/blog/material-requisition.md)
- [or](/blog/merge-pdfs.md)
- [Migrating Observability Hyperdx To Dash0](/blog/migrating-observability-hyperdx-to-dash0.md)
- [Swift Package Manager](/blog/mobile-pdf-sdk.md)
- [`elements` come from your document parser — each has a type and content.](/blog/multimodal-rag.md)
- [Multipage Extraction Page Boundaries](/blog/multipage-extraction-page-boundaries.md)
- [Nutrient Flutter 6 Bindings Api](/blog/nutrient-flutter-6-bindings-api.md)
- [Nutrient Flutter Bindings Architecture](/blog/nutrient-flutter-bindings-architecture.md)
- [Nutrient Vs Conga Composer](/blog/nutrient-vs-conga-composer.md)
- [Ocr Api Comparison](/blog/ocr-api-comparison.md)
- [Online Document Viewer](/blog/online-document-viewer.md)
- [Open Pdf In Your Web App](/blog/open-pdf-in-your-web-app.md)
- [CPU](/blog/paddleocr-python-guide.md)
- [PDF accessibility for developers: Meeting WCAG 2.2, Section 508, and PDF/UA with an SDK](/blog/pdf-accessibility.md)
- [Extract data from PDF files: A developer guide to structured data from PDFs and scans](/blog/pdf-data-extraction-developer-guide.md)
- [Pdf Extraction Benchmark Opendataloader Bench](/blog/pdf-extraction-benchmark-opendataloader-bench.md)
- [Pdf Extraction Document Case Studies](/blog/pdf-extraction-document-case-studies.md)
- [Pdf Page Labels](/blog/pdf-page-labels.md)
- [Pdf Sdk Compliance Security Checklist](/blog/pdf-sdk-compliance-security-checklist.md)
- [Pdf Sdk Performance Benchmark](/blog/pdf-sdk-performance-benchmark.md)
- [Pdf Ua Compliance Guide](/blog/pdf-ua-compliance-guide.md)
- [Pdf Ua Validation](/blog/pdf-ua-validation.md)
- [Pdfjs Accessibility Structtree Printing](/blog/pdfjs-accessibility-structtree-printing.md)
- [Pdfjs Advanced Loading Streaming Workers](/blog/pdfjs-advanced-loading-streaming-workers.md)
- [Pdfjs Annotation Editor Layer](/blog/pdfjs-annotation-editor-layer.md)
- [Pdfjs Area Annotations Canvas Capture](/blog/pdfjs-area-annotations-canvas-capture.md)
- [Pdfjs Coordinate Systems Pdf To Screen](/blog/pdfjs-coordinate-systems-pdf-to-screen.md)
- [Pdfjs Document Outline Bookmarks Metadata](/blog/pdfjs-document-outline-bookmarks-metadata.md)
- [Pdfjs Eventbus Guide](/blog/pdfjs-eventbus-guide.md)
- [macOS](/blog/pdfjs-file-format-conversion-to-pdf.md)
- [macOS](/blog/pdfjs-generating-pdf-thumbnails-pdf2pic.md)
- [Pdfjs Limitations Commercial Upgrade](/blog/pdfjs-limitations-commercial-upgrade.md)
- [Pdfjs Native Annotation Layer Forms](/blog/pdfjs-native-annotation-layer-forms.md)
- [Pdfjs Navigation Zoom Rotation](/blog/pdfjs-navigation-zoom-rotation.md)
- [Pdfjs Pdf Page Manipulation Pdf Lib](/blog/pdfjs-pdf-page-manipulation-pdf-lib.md)
- [Pdfjs React Viewer Setup](/blog/pdfjs-react-viewer-setup.md)
- [Pdfjs Rendering Overlays React Portals](/blog/pdfjs-rendering-overlays-react-portals.md)
- [Pdfjs Server Side Text Extraction](/blog/pdfjs-server-side-text-extraction.md)
- [Pdfjs Sticky Note Annotations](/blog/pdfjs-sticky-note-annotations.md)
- [Pdfjs Text Highlight Annotations](/blog/pdfjs-text-highlight-annotations.md)
- [Pdfjs Text Search Pdffindcontroller](/blog/pdfjs-text-search-pdffindcontroller.md)
- [Pdfjs Thumbnail Sidebar](/blog/pdfjs-thumbnail-sidebar.md)
- [People Process Tools](/blog/people-process-tools.md)
- [Process Flows](/blog/process-flows.md)
- [React Native Pdf Annotation](/blog/react-native-pdf-annotation.md)
- [React Pdf Annotation Layer Forms](/blog/react-pdf-annotation-layer-forms.md)
- [React Pdf Custom Rendering Hooks](/blog/react-pdf-custom-rendering-hooks.md)
- [Using Yarn](/blog/react-pdf-editor.md)
- [React Pdf Loading States Errors Passwords](/blog/react-pdf-loading-states-errors-passwords.md)
- [React Pdf Non Latin Fonts Special Pdfs](/blog/react-pdf-non-latin-fonts-special-pdfs.md)
- [React Pdf Outline Table Of Contents](/blog/react-pdf-outline-table-of-contents.md)
- [React Pdf Performance Optimization](/blog/react-pdf-performance-optimization.md)
- [React Pdf Setup Basic Rendering](/blog/react-pdf-setup-basic-rendering.md)
- [React Pdf Text Layer Custom Renderer](/blog/react-pdf-text-layer-custom-renderer.md)
- [React Pdf Thumbnails Page Navigation](/blog/react-pdf-thumbnails-page-navigation.md)
- [Reducto Alternatives](/blog/reducto-alternatives.md)
- [Requisition System](/blog/requisition-system.md)
- [labels.py](/blog/route-documents-automatically-classify-api.md)
- [or](/blog/sample-blog-updated.md)
- [Sdk Product Updates Q2 2026](/blog/sdk-product-updates-q2-2026.md)
- [System Of Record Vs Source Of Truth](/blog/system-of-record-vs-source-of-truth.md)
- [Add DWS MCP Server to your Claude Code project.](/blog/teaching-llms-to-read-pdfs.md)
- [Open an image file.](/blog/tesseract-python-guide.md)
- [The Six Best Pdf Generator Apis](/blog/the-six-best-pdf-generator-apis.md)
- [Define the HTML part of the document.](/blog/top-10-ways-to-generate-pdfs-in-python.md)
- [Top 5 Javascript Pdf Viewers](/blog/top-5-javascript-pdf-viewers.md)
- [or](/blog/top-js-pdf-libraries.md)
- [Top Ten Ways To Convert Html To Pdf](/blog/top-ten-ways-to-convert-html-to-pdf.md)
- [Unstructured Alternatives](/blog/unstructured-alternatives.md)
- [Using Javascript In Pdf Form Fields](/blog/using-javascript-in-pdf-form-fields.md)
- [Vector Pdf](/blog/vector-pdf.md)
- [Wcag2 Accessibility Requirements Documents](/blog/wcag2-accessibility-requirements-documents.md)
- [Web Sdk Is Now Headless](/blog/web-sdk-is-now-headless.md)
- [What Are Annotations](/blog/what-are-annotations.md)
- [What Is A Vpat](/blog/what-is-a-vpat.md)
- [What Is Business Logic](/blog/what-is-business-logic.md)
- [What Is Document Processing](/blog/what-is-document-processing.md)
- [What Is Intelligent Document Processing](/blog/what-is-intelligent-document-processing.md)
- [What Is Ocr Invoice Processing](/blog/what-is-ocr-invoice-processing.md)
- [What Is Pdf Ua](/blog/what-is-pdf-ua.md)
- [Why Pdfium Is A Trusted Platform For Pdf Rendering](/blog/why-pdfium-is-a-trusted-platform-for-pdf-rendering.md)
- [Why Your Ai Agent Hallucinates Pdf Table Data](/blog/why-your-ai-agent-hallucinates-pdf-table-data.md)

