# Dividir um PDF e tratar a saída

Como executar uma ação de divisão e ler suas várias saídas, cobrindo os formatos ZIP, JSON e multipart e as armadilhas de cada um.

Uma ação de divisão transforma um PDF em vários. Diferentemente de todas as
outras ações, a resposta é um conjunto de documentos em vez de um único PDF, e
você escolhe o empacotamento com o cabeçalho de requisição `Accept`: um arquivo
ZIP (o padrão), um envelope JSON de documentos codificados em base64 ou um corpo
`multipart/mixed`. Este guia escolhe uma ação de divisão, pede cada formato e
desempacota as partes no código.

## Escolher uma ação de divisão

Quatro ações dividem um documento de maneiras diferentes. Elas compartilham o
mesmo contrato de saída, então o código de desempacotamento abaixo funciona para
todas.

| Ação | Divide por | Campo principal |
| --- | --- | --- |
| [Dividir por número de páginas](/docs/api/split-pdf-by-page-count) (`split_by_page_count`) | um número fixo de páginas por parte | `page_count` |
| [Dividir em uma página](/docs/api/split-pdf-at-page) (`split_at_page`) | um ponto de corte, gerando duas partes | `page` |
| [Dividir por tamanho de arquivo](/docs/api/split-pdf-by-file-size) (`split_by_size`) | um tamanho máximo em bytes por parte | `maximum_bytes` |
| [Dividir em grupos de páginas](/docs/api/split-pdf-into-page-groups) (`split_by_groups`) | grupos explícitos que você define | `groups` |

Os exemplos usam `split_by_page_count` com `page_count=10`. Troque a rota e o
campo para usar qualquer outra ação de divisão.

## Escolher um formato de saída

Defina o cabeçalho `Accept` para pedir um formato. Os documentos de saída são
sempre nomeados `00001.pdf`, `00002.pdf` e assim por diante, em ordem.

| `Accept` | Corpo da resposta | Como ler |
| --- | --- | --- |
| `application/zip` *(padrão)* | Um arquivo ZIP, uma entrada por documento | Descompacte o arquivo |
| `application/json` | Um envelope JSON com uma matriz `documents[]` em base64 | Decodifique cada `content` |
| `multipart/mixed` | Uma parte `application/pdf` por documento | Leia as partes em ordem |

Omita `Accept` por completo e você recebe o ZIP. Um cabeçalho `Accept` que não
corresponda a nenhum desses três recebe como resposta um `406 Not Acceptable`.
Consulte [Formatos de resposta](/docs/api/response-formats) para ver o contrato
completo.

## Obter um ZIP (o padrão)

Sem o cabeçalho `Accept`, a resposta é um arquivo ZIP. Salve-o e depois percorra
suas entradas.

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

## Obter JSON

Defina `Accept: application/json` para receber um envelope em vez disso. Cada
documento traz seu `name`, seu `content` codificado em base64 e seu
`content_type`:

```json
{
  "documents": [
    { "name": "00001.pdf", "content": "JVBERi0xLjcK…", "content_type": "application/pdf" },
    { "name": "00002.pdf", "content": "JVBERi0xLjcK…", "content_type": "application/pdf" }
  ]
}
```

O JSON é conveniente quando quem chama quer os nomes dos documentos junto com os
bytes, ou quando um transporte é mais fácil de tratar como texto do que como um
arquivo binário. Decodifique cada `content` de base64 para recuperar o 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>

## Obter multipart/mixed

Defina `Accept: multipart/mixed` para receber em fluxo uma parte
`application/pdf` por documento, cada uma com um `Content-Disposition` que a
nomeia `00001.pdf`, `00002.pdf` e assim por diante. Prefira este formato quando
quiser tratar cada parte à medida que ela chega, em vez de manter um arquivo
inteiro na memória. A maioria das linguagens tem um analisador multipart. Em
Python, `requests-toolbelt` decodifica a resposta diretamente:

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

## Armadilhas

- **Um `406` significa que seu `Accept` não correspondeu.** Envie exatamente
  `application/zip`, `application/json` ou `multipart/mixed` (ou nenhum `Accept`).
  Um `application/pdf` ou `*/*` perdido, vindo dos padrões de um cliente HTTP, é
  uma causa comum: defina o cabeçalho explicitamente.
- **Divisões grandes produzem respostas grandes.** Um documento grande dividido
  em muitas partes pode gerar um arquivo volumoso. Escreva a resposta em fluxo no
  disco em vez de mantê-la na memória, ou use `multipart/mixed` para processar
  cada parte à medida que ela chega. Consulte [Trabalhar com arquivos
  grandes](/docs/api/working-with-large-files).
- **Uma única página acima do tamanho.** Com [Dividir por tamanho de
  arquivo](/docs/api/split-pdf-by-file-size), uma página que sozinha já é maior
  que `maximum_bytes` é retornada como uma parte própria que excede o limite:
  não é possível dividi-la mais. Espere que, de vez em quando, uma parte seja
  maior que o teto.

## Veja também

<CardGroup cols={2}>

<Card title="Formatos de resposta" href="/docs/api/response-formats">
  O contrato completo de ZIP, JSON e multipart.
</Card>

<Card title="Dividir por número de páginas" href="/docs/api/split-pdf-by-page-count">
  Divida um PDF em blocos de tamanho fixo.
</Card>

<Card title="Dividir em grupos de páginas" href="/docs/api/split-pdf-into-page-groups">
  Defina exatamente quais páginas vão em cada saída.
</Card>

<Card title="Trabalhar com arquivos grandes" href="/docs/api/working-with-large-files">
  Processe em fluxo grandes arquivos ZIP de divisão sem usar buffer.
</Card>

</CardGroup>
