Dividere un PDF e gestire l’output
Come eseguire un’azione di divisione e leggerne i molti output, con i formati ZIP, JSON e multipart e le insidie di ciascuno.
Un’azione di divisione trasforma un PDF in più documenti. A differenza di ogni
altra azione, la risposta è un insieme di documenti e non un solo PDF, e
l’impacchettamento si sceglie con l’intestazione di richiesta Accept: un
archivio ZIP (il valore predefinito), una busta JSON di documenti codificati in
base64 oppure un corpo multipart/mixed. Questa guida sceglie un’azione di
divisione, richiede ciascun formato e spacchetta le parti nel codice.
Scegliere un’azione di divisione
Quattro azioni dividono un documento in modi diversi. Condividono lo stesso contratto di output, quindi il codice di spacchettamento qui sotto funziona per tutte.
| Azione | Divide per | Campo chiave |
|---|---|---|
Dividere per numero di pagine (split_by_page_count) |
un numero fisso di pagine per parte | page_count |
Dividere a una pagina (split_at_page) |
un punto di taglio, in due parti | page |
Dividere per dimensione del file (split_by_size) |
una dimensione massima in byte per parte | maximum_bytes |
Dividere in gruppi di pagine (split_by_groups) |
i gruppi espliciti che si definiscono | groups |
Gli esempi usano split_by_page_count con page_count=10. Sostituire il
percorso e il campo per usare qualsiasi altra azione di divisione.
Scegliere un formato di output
Impostare l’intestazione Accept per richiedere un formato. I documenti di
output si chiamano sempre 00001.pdf, 00002.pdf e così via, in ordine.
Accept |
Corpo della risposta | Come leggerlo |
|---|---|---|
application/zip (predefinito) |
Un archivio ZIP, una voce per documento | Estrarre l’archivio |
application/json |
Una busta JSON con un array documents[] in base64 |
Decodificare ogni content |
multipart/mixed |
Una parte application/pdf per documento |
Leggere le parti in ordine |
Omettendo del tutto Accept si ottiene lo ZIP. Un’intestazione Accept che non
corrisponde a nessuno di questi tre riceve in risposta un 406 Not Acceptable.
Vedere Formati di risposta per il contratto
completo.
Ottenere uno ZIP (il valore predefinito)
Senza intestazione Accept, la risposta è un archivio ZIP. Salvarlo, poi
scorrerne le voci.
curl https://api.pdfblocks.com/v1/split_by_page_count \
-H 'X-API-Key: your_api_key' \
-F file=@input.pdf \
-F page_count=10 \
-o parts.zip
unzip parts.zip -d parts/
# parts/00001.pdf parts/00002.pdf parts/00003.pdf …# pip install requests
import io
import zipfile
import requests
with open('input.pdf', 'rb') as file:
response = requests.post(
'https://api.pdfblocks.com/v1/split_by_page_count',
headers={'X-API-Key': 'your_api_key'}, # no Accept → ZIP
files={'file': file},
data={'page_count': 10},
)
response.raise_for_status()
with zipfile.ZipFile(io.BytesIO(response.content)) as archive:
print(archive.namelist()) # ['00001.pdf', '00002.pdf', …]
archive.extractall('parts')package main
import (
"archive/zip"
"bytes"
"io"
"mime/multipart"
"net/http"
"os"
"path/filepath"
)
func main() {
var buf bytes.Buffer
form := multipart.NewWriter(&buf)
file, _ := os.Open("input.pdf")
defer file.Close()
part, _ := form.CreateFormFile("file", "input.pdf")
io.Copy(part, file)
form.WriteField("page_count", "10")
form.Close()
req, _ := http.NewRequest("POST",
"https://api.pdfblocks.com/v1/split_by_page_count", &buf)
req.Header.Set("Content-Type", form.FormDataContentType())
req.Header.Set("X-API-Key", "your_api_key")
// No Accept header → ZIP.
res, _ := http.DefaultClient.Do(req)
defer res.Body.Close()
body, _ := io.ReadAll(res.Body)
archive, _ := zip.NewReader(bytes.NewReader(body), int64(len(body)))
os.MkdirAll("parts", 0755)
for _, entry := range archive.File {
in, _ := entry.Open()
out, _ := os.Create(filepath.Join("parts", entry.Name))
io.Copy(out, in)
out.Close()
in.Close()
}
}Ottenere il JSON
Impostare Accept: application/json per ricevere invece una busta. Ogni
documento porta il proprio name, il content codificato in base64 e il
content_type:
{
"documents": [
{ "name": "00001.pdf", "content": "JVBERi0xLjcK…", "content_type": "application/pdf" },
{ "name": "00002.pdf", "content": "JVBERi0xLjcK…", "content_type": "application/pdf" }
]
}Il JSON è comodo quando il chiamante vuole i nomi dei documenti insieme ai byte,
oppure quando un trasporto è più facile da gestire come testo che come archivio
binario. Decodificare da base64 ogni content per recuperare il PDF.
curl https://api.pdfblocks.com/v1/split_by_page_count \
-H 'X-API-Key: your_api_key' \
-H 'Accept: application/json' \
-F file=@input.pdf \
-F page_count=10 \
-o parts.json# pip install requests
import base64
import requests
with open('input.pdf', 'rb') as file:
response = requests.post(
'https://api.pdfblocks.com/v1/split_by_page_count',
headers={'X-API-Key': 'your_api_key', 'Accept': 'application/json'},
files={'file': file},
data={'page_count': 10},
)
response.raise_for_status()
for document in response.json()['documents']:
with open(document['name'], 'wb') as out:
out.write(base64.b64decode(document['content']))// Node.js 18+
import { readFile, writeFile } from 'node:fs/promises';
const body = new FormData();
body.set('file', new Blob([await readFile('input.pdf')]), 'input.pdf');
body.set('page_count', '10');
const response = await fetch('https://api.pdfblocks.com/v1/split_by_page_count', {
method: 'POST',
headers: { 'X-API-Key': 'your_api_key', Accept: 'application/json' },
body,
});
if (!response.ok) throw new Error(`Request failed: ${response.status}`);
const { documents } = await response.json();
for (const document of documents) {
await writeFile(document.name, Buffer.from(document.content, 'base64'));
}Ottenere multipart/mixed
Impostare Accept: multipart/mixed per ricevere in streaming una parte
application/pdf per documento, ciascuna con un Content-Disposition che la
nomina 00001.pdf, 00002.pdf e così via. Da preferire quando si vuole gestire
ogni parte man mano che arriva anziché tenere in memoria un intero archivio. La
maggior parte dei linguaggi dispone di un parser multipart. Per Python,
requests-toolbelt decodifica direttamente la risposta:
curl https://api.pdfblocks.com/v1/split_by_page_count \
-H 'X-API-Key: your_api_key' \
-H 'Accept: multipart/mixed' \
-F file=@input.pdf \
-F page_count=10 \
-o parts.multipart# pip install requests requests-toolbelt
import requests
from requests_toolbelt.multipart.decoder import MultipartDecoder
with open('input.pdf', 'rb') as file:
response = requests.post(
'https://api.pdfblocks.com/v1/split_by_page_count',
headers={'X-API-Key': 'your_api_key', 'Accept': 'multipart/mixed'},
files={'file': file},
data={'page_count': 10},
)
response.raise_for_status()
for index, part in enumerate(MultipartDecoder.from_response(response).parts, start=1):
with open(f'{index:05d}.pdf', 'wb') as out:
out.write(part.content)Insidie
- Un
406significa che l’Acceptinviato non corrispondeva. Inviare esattamenteapplication/zip,application/jsonomultipart/mixed(oppure nessunAccept). Una causa frequente è unapplication/pdfo*/*di troppo arrivato dai valori predefiniti di un client HTTP: impostare l’intestazione in modo esplicito. - Le divisioni grandi producono risposte grandi. Un documento voluminoso
diviso in molte parti può dare un archivio di dimensioni notevoli. Scrivere la
risposta su disco in streaming invece di tenerla in memoria, oppure usare
multipart/mixedper elaborare ogni parte man mano che arriva. Vedere Lavorare con file di grandi dimensioni. - Una singola pagina fuori misura. Con Dividere per dimensione del
file, una pagina che da sola supera
maximum_bytesviene restituita come parte a sé che eccede il limite: non può essere divisa oltre. Aspettarsi che di tanto in tanto una parte sia più grande del limite.
Vedi anche
Il contratto completo di ZIP, JSON e multipart.
Dividere un PDF in blocchi di dimensione fissa.
Definire esattamente quali pagine finiscono in ogni output.
Ricevere in streaming grandi archivi di divisione senza bufferizzarli.