PDF Table Extractor
Estrae dati da PDF nativi con tabelle. Riconosce automaticamente computi metrici, elenchi prezzi PriMus e dispone di una modalità tabella generica basata sulle coordinate del PDF.
API
Usa il tool dai tuoi script: carica un PDF, ricevi il risultato JSON e convertilo in CSV o Excel. L'estrazione è sincrona: la risposta arriva al termine dell'elaborazione. Il servizio non richiede una chiave API; eventuali controlli di accesso dipendono dal deployment.
Negli esempi imposta API_BASE_URL con l'indirizzo del servizio. In locale, la porta predefinita è 3000.
API_BASE_URL='http://localhost:3000'
1. Estrai un PDF
POST /api/extract — invia un corpo multipart/form-data con:
pdf(obbligatorio): un file PDF con testo nativo. I PDF scansionati senza testo non sono supportati.mode(facoltativo):auto,computo,elenco_prezziogeneric_table. Se omesso o non riconosciuto, viene usatoauto.
curl --fail-with-body "$API_BASE_URL/api/extract" \
-F 'pdf=@documento.pdf;type=application/pdf' \
-F 'mode=auto' \
-o risultato.json
La risposta 200 application/json contiene filename, pages, modeRequested, type, label, records e warnings. Per computi ed elenchi prezzi, columns associa le chiavi alle intestazioni. Le tabelle generiche includono tables con page e rows, e record con tabella, pagina, riga e cells.
Esempio ridotto di risposta per un computo (i campi disponibili dipendono dal tipo di documento):
{
"filename": "documento.pdf",
"pages": 1,
"modeRequested": "auto",
"type": "computo",
"label": "Computo metrico",
"columns": [["descrizione", "Descrizione"], ["controllo", "Check"]],
"records": [{"descrizione": "Voce senza importo", "controllo": "INCOMPLETO"}],
"totaleEstratto": 0,
"warnings": ["1 voci incomplete: verificare il documento."]
}
Nei computi, controllo può essere OK, VERIFICARE o INCOMPLETO. Gli avvisi in warnings segnalano risultati da controllare anche quando la richiesta riesce.
2. Esporta il risultato
Invia l'intera risposta dell'estrazione come application/json. Gli endpoint restituiscono direttamente il file: CSV UTF-8 con BOM e separatore ;, oppure Excel .xlsx.
curl --fail-with-body "$API_BASE_URL/api/export/csv" \
-H 'Content-Type: application/json' \
--data-binary @risultato.json \
-o estrazione.csv
curl --fail-with-body "$API_BASE_URL/api/export/xlsx" \
-H 'Content-Type: application/json' \
--data-binary @risultato.json \
-o estrazione.xlsx
Esempio JavaScript (browser)
Questo esempio usa il file selezionato nella pagina e l'API sullo stesso dominio. FormData imposta automaticamente il Content-Type con il boundary necessario.
async function estraiPdf(file) {
if (!file) throw new Error('Seleziona un PDF.');
const form = new FormData();
form.append('pdf', file);
form.append('mode', 'auto');
const response = await fetch('/api/extract', {
method: 'POST',
body: form
});
const result = await response.json();
if (!response.ok) throw new Error(result.error || 'Estrazione fallita');
return result;
}
try {
const result = await estraiPdf(document.getElementById('file').files[0]);
const incompleti = (result.records || []).filter(r => r.controllo === 'INCOMPLETO');
console.log(result, incompleti);
} catch (error) {
console.error(error.message);
}
Limiti ed errori
Il limite predefinito del PDF è 50 MB (configurabile con MAX_UPLOAD_MB); il limite del corpo JSON per gli export è 30 MB (configurabile con JSON_BODY_LIMIT_MB). Gli errori applicativi restituiscono JSON con error e code, ad esempio {"error":"Carica un PDF.","code":"invalid_input"}.
| HTTP | Code | Significato |
|---|---|---|
| 400 | invalid_input | File assente o contenuto non valido come PDF. |
| 413 | file_too_large | PDF oltre il limite di upload configurato. |
| 422 | no_native_text | PDF senza testo nativo estraibile. |
| 500 | internal_error | Errore di elaborazione. Anche JSON malformato o oltre il limite viene attualmente gestito con questo stato. |
Stato del servizio
GET /healthz restituisce stato, servizio, ambiente, versione e data. GET /readyz restituisce stato, limite upload attivo (maxUploadMb), versione e data.
curl --fail-with-body "$API_BASE_URL/healthz"
curl --fail-with-body "$API_BASE_URL/readyz"