PDF Blocks
PrezziSupporto
Iniziare gratis
Aprire la pagina

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.

cURLbash
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 …
Pythonpython
# 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')
Gogo
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.

cURLbash
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
Pythonpython
# 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.jsjavascript
// 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:

cURLbash
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
Pythonpython
# 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 406 significa che l’Accept inviato non corrispondeva. Inviare esattamente application/zip, application/json o multipart/mixed (oppure nessun Accept). Una causa frequente è un application/pdf o */* 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/mixed per 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_bytes viene 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