# 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](/docs/api/split-pdf-by-page-count) (`split_by_page_count`) | un numero fisso di pagine per parte | `page_count` |
| [Dividere a una pagina](/docs/api/split-pdf-at-page) (`split_at_page`) | un punto di taglio, in due parti | `page` |
| [Dividere per dimensione del file](/docs/api/split-pdf-by-file-size) (`split_by_size`) | una dimensione massima in byte per parte | `maximum_bytes` |
| [Dividere in gruppi di pagine](/docs/api/split-pdf-into-page-groups) (`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](/docs/api/response-formats) per il contratto
completo.

## Ottenere uno ZIP (il valore predefinito)

Senza intestazione `Accept`, la risposta è un archivio ZIP. Salvarlo, poi
scorrerne le voci.

<CodeGroup>

```bash title="cURL"
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 …
```

```python title="Python"
# 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')
```

```go title="Go"
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()
	}
}
```

</CodeGroup>

## 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`:

```json
{
  "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.

<CodeGroup>

```bash title="cURL"
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
```

```python title="Python"
# 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']))
```

```javascript title="Node.js"
// 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'));
}
```

</CodeGroup>

## 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:

<CodeGroup>

```bash title="cURL"
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
```

```python title="Python"
# 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)
```

</CodeGroup>

## 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](/docs/api/working-with-large-files).
- **Una singola pagina fuori misura.** Con [Dividere per dimensione del
  file](/docs/api/split-pdf-by-file-size), 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

<CardGroup cols={2}>

<Card title="Formati di risposta" href="/docs/api/response-formats">
  Il contratto completo di ZIP, JSON e multipart.
</Card>

<Card title="Dividere per numero di pagine" href="/docs/api/split-pdf-by-page-count">
  Dividere un PDF in blocchi di dimensione fissa.
</Card>

<Card title="Dividere in gruppi di pagine" href="/docs/api/split-pdf-into-page-groups">
  Definire esattamente quali pagine finiscono in ogni output.
</Card>

<Card title="Lavorare con file di grandi dimensioni" href="/docs/api/working-with-large-files">
  Ricevere in streaming grandi archivi di divisione senza bufferizzarli.
</Card>

</CardGroup>
