# Dividere un PDF in gruppi di pagine

Dividere un PDF in gruppi di pagine definiti dall’utente, dove ogni gruppo diventa un documento di output.

Dividere un documento PDF in gruppi di pagine definiti dall’utente: ogni gruppo
diventa un PDF di output, nell’ordine in cui è scritto. All’interno di un
gruppo, pagine e intervalli seguono la [sintassi ordinata delle
pagine](/docs/api/selecting-pages), quindi escono esattamente come sono
elencati. Questa azione restituisce più documenti, impacchettati in un’unica
risposta in base all’intestazione `Accept`. L’API è *stateless*: il documento
viene elaborato nella sua regione e non viene mai memorizzato.

## Endpoint

<Endpoint method="POST" path="/v1/split_by_groups" />

Disponibile in tutte le regioni. Vedere [Regioni e residenza dei
dati](/docs/api/regions-and-data-residency) per il routing e la residenza dei
dati.

| Regione            | URL                                                  |
| ------------------ | ---------------------------------------------------- |
| Globale            | `https://api.pdfblocks.com/v1/split_by_groups`       |
| Stati Uniti        | `https://us.api.pdfblocks.com/v1/split_by_groups`    |
| HIPAA Stati Uniti  | `https://hipaa.api.pdfblocks.com/v1/split_by_groups` |
| Unione europea     | `https://eu.api.pdfblocks.com/v1/split_by_groups`    |
| Regno Unito        | `https://uk.api.pdfblocks.com/v1/split_by_groups`    |
| Canada             | `https://ca.api.pdfblocks.com/v1/split_by_groups`    |
| Australia          | `https://au.api.pdfblocks.com/v1/split_by_groups`    |
| Giappone           | `https://jp.api.pdfblocks.com/v1/split_by_groups`    |
| India              | `https://in.api.pdfblocks.com/v1/split_by_groups`    |
| Brasile            | `https://br.api.pdfblocks.com/v1/split_by_groups`    |

## Autenticazione

Autenticare ogni richiesta con la chiave API segreta nell’intestazione
`X-API-Key`, tramite HTTPS. Le chiavi si creano e si gestiscono dalla
[dashboard](https://dashboard.pdfblocks.com). Vedere
[Autenticazione](/docs/api/authentication) per i dettagli.

## Richiesta

L’endpoint accetta un corpo della richiesta `multipart/form-data`.

<ParamField name="file" type="file" required>
  Il documento PDF di input.
</ParamField>

<ParamField name="groups" type="string" required>
  I gruppi di pagine da produrre, secondo [la sintassi dei gruppi di
  pagine](#gruppi-di-pagine). I gruppi sono separati da `;`; all’interno di un
  gruppo, pagine e intervalli sono separati da `,` e seguono le regole
  ordinate. Ogni gruppo diventa un PDF di output, nell’ordine in cui è scritto.
  Ad esempio, `2..8,29;1` produce due PDF: le pagine da 2 a 8 e poi la 29, e la
  pagina 1.
</ParamField>

### Gruppi di pagine

I gruppi sono separati da `;`. All’interno di ogni gruppo, pagine e intervalli
seguono la sintassi ordinata: l’ordine e le ripetizioni contano, una pagina
indicata due volte viene emessa due volte e un intervallo può procedere a
ritroso. Ogni gruppo diventa un PDF di output, emesso nell’ordine in cui i
gruppi sono scritti.

Ad esempio, `2..8,29;1` produce due documenti:

| Gruppo     | PDF di output | Pagine                                    |
| ---------- | ------------- | ----------------------------------------- |
| `2..8,29`  | `00001.pdf`   | Le pagine 2, 3, 4, 5, 6, 7, 8 e poi la 29 |
| `1`        | `00002.pdf`   | La pagina 1                               |

All’interno di un gruppo, `groups` condivide la semantica ordinata di
`page_order`. Vedere [Selezionare le pagine](/docs/api/selecting-pages) per il
riferimento completo.

## Esempi

Dividere un documento in due PDF: le pagine da 2 a 8 e poi la 29, e la pagina 1:

<CodeGroup>

```bash title="cURL"
curl https://api.pdfblocks.com/v1/split_by_groups \
  -H 'X-API-Key: your_api_key' \
  -F file=@input.pdf \
  -F groups='2..8,29;1' \
  -o parts.zip
```

```python title="Python"
# pip install requests
import requests

with open('input.pdf', 'rb') as file:
    response = requests.post(
        'https://api.pdfblocks.com/v1/split_by_groups',
        headers={'X-API-Key': 'your_api_key'},
        files={'file': file},
        data={'groups': '2..8,29;1'},
    )

response.raise_for_status()
with open('parts.zip', 'wb') as output:
    output.write(response.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('groups', '2..8,29;1');

const response = await fetch('https://api.pdfblocks.com/v1/split_by_groups', {
  method: 'POST',
  headers: { 'X-API-Key': 'your_api_key' },
  body,
});

if (!response.ok) throw new Error(`Request failed: ${response.status}`);
await writeFile('parts.zip', Buffer.from(await response.arrayBuffer()));
```

```php title="PHP"
<?php
$ch = curl_init('https://api.pdfblocks.com/v1/split_by_groups');
curl_setopt_array($ch, [
    CURLOPT_RETURNTRANSFER => true,
    CURLOPT_HTTPHEADER => ['X-API-Key: your_api_key'],
    CURLOPT_POST => true,
    CURLOPT_POSTFIELDS => [
        'file' => new CURLFile('input.pdf', 'application/pdf'),
        'groups' => '2..8,29;1',
    ],
]);

$zip = curl_exec($ch);
if (curl_getinfo($ch, CURLINFO_HTTP_CODE) === 200) {
    file_put_contents('parts.zip', $zip);
}
```

```ruby title="Ruby"
# gem install http
require 'http'

response = HTTP
  .headers('X-API-Key' => 'your_api_key')
  .post('https://api.pdfblocks.com/v1/split_by_groups', form: {
    file: HTTP::FormData::File.new('input.pdf'),
    groups: '2..8,29;1',
  })

File.write('parts.zip', response.body) if response.status.success?
```

```go title="Go"
package main

import (
	"bytes"
	"io"
	"mime/multipart"
	"net/http"
	"os"
)

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("groups", "2..8,29;1")
	form.Close()

	req, _ := http.NewRequest("POST", "https://api.pdfblocks.com/v1/split_by_groups", &buf)
	req.Header.Set("Content-Type", form.FormDataContentType())
	req.Header.Set("X-API-Key", "your_api_key")

	res, _ := http.DefaultClient.Do(req)
	defer res.Body.Close()

	out, _ := os.Create("parts.zip")
	defer out.Close()
	io.Copy(out, res.Body)
}
```

```csharp title="C#"
using var client = new HttpClient();
client.DefaultRequestHeaders.Add("X-API-Key", "your_api_key");

using var form = new MultipartFormDataContent
{
    { new ByteArrayContent(File.ReadAllBytes("input.pdf")), "file", "input.pdf" },
    { new StringContent("2..8,29;1"), "groups" },
};

var response = await client.PostAsync(
    "https://api.pdfblocks.com/v1/split_by_groups", form);
response.EnsureSuccessStatusCode();
await File.WriteAllBytesAsync(
    "parts.zip", await response.Content.ReadAsByteArrayAsync());
```

</CodeGroup>

## Risposta

Questa azione restituisce più documenti, impacchettati in un’unica risposta
secondo l’intestazione di richiesta `Accept`. Vedere [Formati di risposta e
negoziazione del contenuto](/docs/api/response-formats) per il riferimento
completo sulla negoziazione. Senza intestazione `Accept`, il valore predefinito
è un archivio ZIP:

```http
HTTP/1.1 200 OK
Content-Type: application/zip
```

Selezionare l’impacchettamento con l’intestazione `Accept`:

| Intestazione `Accept`  | Risposta                                                     |
| ---------------------- | ------------------------------------------------------------ |
| *(nessuna inviata)*    | `application/zip`: il valore predefinito                     |
| `application/zip`      | Un archivio ZIP dei PDF di output                            |
| `application/json`     | Una busta JSON di documenti codificati in base64             |
| `multipart/mixed`      | Un PDF per ogni parte                                        |
| qualsiasi altro valore | `406 Not Acceptable`                                          |

L’API produce un documento di output per ogni gruppo, nell’ordine in cui i
gruppi sono scritti, con i nomi `00001.pdf`, `00002.pdf` e così via.

<Tip>
  Per codice end-to-end che chiama un’azione di divisione e spacchetta ogni
  formato (estraendo lo ZIP, decodificando la busta JSON o leggendo le parti
  multipart), vedere la guida [Dividere un
  PDF](/docs/api/splitting-a-pdf).
</Tip>

## Errori

Le richieste non riuscite restituiscono un corpo `application/problem+json`.
L’errore più frequente su questo endpoint è un `400`, restituito quando
`groups` è assente o malformato, oppure quando fa riferimento a una pagina che
non esiste nel documento: l’oggetto `errors` nomina ogni campo:

```json
{
  "type": "https://www.pdfblocks.com/docs/api/v1/error/400",
  "title": "One or more validation errors occurred.",
  "status": 400,
  "errors": {
    "groups": ["The groups field references a page that does not exist in the document."]
  }
}
```

Se l’intestazione `Accept` non corrisponde a nessuno tra `application/zip`,
`application/json` e `multipart/mixed`, ad esempio `Accept: application/pdf`,
l’API risponde con `406 Not Acceptable`. Omettere `Accept` per prendere lo ZIP
predefinito, oppure richiedere uno dei tipi di media supportati. Una
`X-API-Key` assente o non valida restituisce un `401`. Vedere
[Errori](/docs/api/errors) per tutti i codici di stato e la forma completa
della risposta.

## Ricette

Una variante comune. Espanderla per vedere il codice in tutti i linguaggi.

<AccordionGroup>

<Accordion title="Ricevere le parti come busta JSON">

Inviare `Accept: application/json` per ottenere tutte le parti in linea in
un’unica risposta, quindi decodificare da base64 il `content` di ogni voce in un
file con il nome indicato dal suo `name`:

<CodeGroup>

```bash title="cURL"
curl https://api.pdfblocks.com/v1/split_by_groups \
  -H 'X-API-Key: your_api_key' \
  -H 'Accept: application/json' \
  -F file=@input.pdf \
  -F groups='2..8,29;1' \
  | jq -r '.documents[] | .name + " " + .content' \
  | while read -r name content; do
      echo "$content" | base64 --decode > "$name"
    done
```

```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_groups',
        headers={
            'X-API-Key': 'your_api_key',
            'Accept': 'application/json',
        },
        files={'file': file},
        data={'groups': '2..8,29;1'},
    )

response.raise_for_status()
for document in response.json()['documents']:
    with open(document['name'], 'wb') as output:
        output.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('groups', '2..8,29;1');

const response = await fetch('https://api.pdfblocks.com/v1/split_by_groups', {
  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 doc of documents) {
  await writeFile(doc.name, Buffer.from(doc.content, 'base64'));
}
```

```php title="PHP"
<?php
$ch = curl_init('https://api.pdfblocks.com/v1/split_by_groups');
curl_setopt_array($ch, [
    CURLOPT_RETURNTRANSFER => true,
    CURLOPT_HTTPHEADER => [
        'X-API-Key: your_api_key',
        'Accept: application/json',
    ],
    CURLOPT_POST => true,
    CURLOPT_POSTFIELDS => [
        'file' => new CURLFile('input.pdf', 'application/pdf'),
        'groups' => '2..8,29;1',
    ],
]);

$body = curl_exec($ch);
if (curl_getinfo($ch, CURLINFO_HTTP_CODE) === 200) {
    foreach (json_decode($body, true)['documents'] as $document) {
        file_put_contents($document['name'], base64_decode($document['content']));
    }
}
```

```ruby title="Ruby"
# gem install http
require 'base64'
require 'http'
require 'json'

response = HTTP
  .headers('X-API-Key' => 'your_api_key', 'Accept' => 'application/json')
  .post('https://api.pdfblocks.com/v1/split_by_groups', form: {
    file: HTTP::FormData::File.new('input.pdf'),
    groups: '2..8,29;1',
  })

if response.status.success?
  JSON.parse(response.body)['documents'].each do |document|
    File.write(document['name'], Base64.decode64(document['content']))
  end
end
```

```go title="Go"
package main

import (
	"bytes"
	"encoding/base64"
	"encoding/json"
	"io"
	"mime/multipart"
	"net/http"
	"os"
)

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("groups", "2..8,29;1")
	form.Close()

	req, _ := http.NewRequest("POST", "https://api.pdfblocks.com/v1/split_by_groups", &buf)
	req.Header.Set("Content-Type", form.FormDataContentType())
	req.Header.Set("X-API-Key", "your_api_key")
	req.Header.Set("Accept", "application/json")

	res, _ := http.DefaultClient.Do(req)
	defer res.Body.Close()

	var result struct {
		Documents []struct {
			Name    string `json:"name"`
			Content string `json:"content"`
		} `json:"documents"`
	}
	json.NewDecoder(res.Body).Decode(&result)

	for _, doc := range result.Documents {
		data, _ := base64.StdEncoding.DecodeString(doc.Content)
		os.WriteFile(doc.Name, data, 0644)
	}
}
```

```csharp title="C#"
using System.Text.Json;

using var client = new HttpClient();
client.DefaultRequestHeaders.Add("X-API-Key", "your_api_key");
client.DefaultRequestHeaders.Add("Accept", "application/json");

using var form = new MultipartFormDataContent
{
    { new ByteArrayContent(File.ReadAllBytes("input.pdf")), "file", "input.pdf" },
    { new StringContent("2..8,29;1"), "groups" },
};

var response = await client.PostAsync(
    "https://api.pdfblocks.com/v1/split_by_groups", form);
response.EnsureSuccessStatusCode();

using var json = JsonDocument.Parse(
    await response.Content.ReadAsStringAsync());
foreach (var document in json.RootElement.GetProperty("documents").EnumerateArray())
{
    var name = document.GetProperty("name").GetString()!;
    var content = document.GetProperty("content").GetString()!;
    await File.WriteAllBytesAsync(name, Convert.FromBase64String(content));
}
```

</CodeGroup>

</Accordion>

</AccordionGroup>

## Azioni correlate

<CardGroup cols={2}>

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

<Card title="Dividere a una pagina" href="/docs/api/split-pdf-at-page">
  Dividere in due documenti in un punto di taglio.
</Card>

<Card title="Riordinare le pagine" href="/docs/api/reorder-pages-of-pdf">
  Riordinare le pagine all’interno di un unico output.
</Card>

<Card title="Estrarre pagine" href="/docs/api/extract-pages-from-pdf">
  Conservare un solo intervallo di pagine.
</Card>

</CardGroup>
