NativePort
← All use cases

Move PDF tables into Excel

Extract table rows from a PDF and write them into an Excel workbook.

The problem

A table printed inside a PDF is not an Excel table. Copy-and-paste may split rows or merge columns, and a regular text agent cannot create dependable spreadsheet data from an unread scan without extraction and file-writing tools.

How NativePort helps

NativePort handles the document-reading step and returns the table rows in a consistent structure. A short script then puts those rows into an Excel workbook. Your agent can use the resulting spreadsheet without retyping the original table.

Technical implementation

Use Python 3 with requests installed (python -m pip install requests). Set NATIVEPORT_API_KEY in your environment to your NativePort key. Run the snippets on your server, where your key stays private.

Set DOCUMENT_URL to an HTTPS URL the document service can fetch, such as a time-limited file link. The example reads page 0 (the first page). Select only pages you need, up to 100 per request; split longer documents into batches. Send the URL, not inline file bytes.

Also install openpyxl (python -m pip install openpyxl) to write the workbook locally. Adapt this line-item schema to your table.

python
import os
import requests

BASE = "https://api.nativeport.ai"
HEADERS = {"Authorization": f"Bearer {os.environ['NATIVEPORT_API_KEY']}"}

payload = {
    "document": {"type": "document_url", "document_url": os.environ["DOCUMENT_URL"]},
    "pages": [0],
}
schema = {'type': 'object',
 'properties': {'rows': {'type': 'array',
                         'items': {'type': 'object',
                                   'properties': {'description': {'type': ['string',
                                                                           'null']},
                                                  'quantity': {'type': ['string',
                                                                        'null']},
                                                  'amount': {'type': ['string',
                                                                      'null']}},
                                   'required': ['description',
                                                'quantity',
                                                'amount'],
                                   'additionalProperties': False}}},
 'required': ['rows'],
 'additionalProperties': False}
payload["document_annotation_format"] = {
    "type": "json_schema",
    "json_schema": {"name": "extraction", "strict": True, "schema": schema},
}
payload["document_annotation_prompt"] = (
    'Extract only what is visible. Use null for missing or unreadable values.'
)
response = requests.post(BASE + "/mistral/v1/ocr", headers=HEADERS,
                         json=payload, timeout=120)
response.raise_for_status()
result = response.json()
import json
fields = result.get("document_annotation")
if isinstance(fields, str):
    fields = json.loads(fields)
if fields is None:
    raise ValueError("No document annotation returned; inspect the OCR response")
from openpyxl import Workbook

workbook = Workbook()
sheet = workbook.active
sheet.title = "Extracted rows"
columns = ["description", "quantity", "amount"]
sheet.append(columns)
for row in fields["rows"]:
    sheet.append([row.get(column) for column in columns])
    # Keep extracted strings as text, including values starting with '='.
    for cell in sheet[sheet.max_row]:
        if isinstance(cell.value, str):
            cell.data_type = "s"
workbook.save("extracted-table.xlsx")

NativePort returns structured data; your script creates extracted-table.xlsx. This preserves recognized amounts as text. Check rows against the PDF, then convert quantities and amounts to numbers using the correct locale. An annotation request uses the Document AI rate. See the Mistral request policy for document URLs, page selection, and accepted options. OCR returns recognized content; check unclear scans against the source.

Tool costs

Tool used in the examplePrice per call
Mistral — structured extraction $0.005275 / call (1 page)

Prices in USD. Usage-based tools have no fixed per-call price. View pricing.

Let your agent build it

You don’t need to write this code yourself. Copy this page’s link and paste it into your agent. Ask it to follow the guide and implement the feature for you.