---
title: "Versão para impressão - PKI Express"
description: "Como gerar uma versão para impressão de um arquivo assinado com o PKI Express: PdfMarker e PdfHelper marcam os signatários e um código de verificação em todas as páginas e acrescentam uma página de manifesto com QR code."
canonical: "https://docs.lacunasoftware.com/articles/pki-express/printer-friendly-version"
locale: "pt-BR"
product: "PKI Express"
last_updated: "2026-10-13"
---

# Versão para impressão - PKI Express

Uma cópia impressa de um PDF assinado perde as assinaturas digitais. A versão para impressão diz ao leitor quem assinou o documento e como
obter de volta o arquivo assinado: o [PKI Express](https://docs.lacunasoftware.com/articles/pki-express) valida as assinaturas, marca em todas as páginas os nomes dos signatários e um
código de verificação e acrescenta uma página de manifesto com um QR code. O seu site, depois, localiza o documento por esse código. 
O PKI Express acrescentou a edição de PDFs (o comando `edit-pdf`) na 1.3.0, justamente para gerar versões para impressão. 

O código é Node.js, dos [samples do PKI Suite](https://github.com/LacunaSoftware/PkiSuiteSamples), com o `pki-express` (1.16.2); o sample em
Python faz o mesmo. 

## Fluxo

1. Gere um código de verificação para o PDF assinado e guarde-o junto com o arquivo.
1. Abra e valide as assinaturas do PDF com o `PadesSignatureExplorer`.
1. Monte as marcas com o `PdfHelper`: os signatários em todas as páginas e um manifesto em uma página nova.
1. Chame `PdfMarker.apply()`, que executa o comando `edit-pdf` do PKI Express e grava o PDF marcado.
1. Quando alguém digitar o código no seu site, localize o arquivo e mostre-o ou ofereça o download.

## 1. O código de verificação

O sample gera um código de 16 caracteres a partir de bytes aleatórios criptograficamente fortes e guarda, na sessão web, o código e o id do
arquivo nos dois sentidos. Guarde-os no seu banco de dados. 

```js
let verificationCode = StorageMock.getVerificationCode(req.session, fileId);
if (!verificationCode) {
	verificationCode = Util.generateVerificationCode();
	StorageMock.setVerificationCode(req.session, fileId, verificationCode);
}
```

O código protege o acesso aos seus documentos: a biblioteca Java tem a classe `AlphaCode` para gerá-lo, descrita em
[Gerando códigos alfanuméricos em Java](https://docs.lacunasoftware.com/articles/pki-express/java/alpha-codes). 

## 2. Abrir as assinaturas

```js
const sigExplorer = new PadesSignatureExplorer();
Util.setPkiDefaults(sigExplorer);
sigExplorer.validate = true;
sigExplorer.setSignatureFileFromPathSync(pdfPath);
sigExplorer.open().then((signature) => { /* build the marks from signature.signers */ });
```

Cada signatário tem `certificate`, `signingTime` e `validationResults`; veja [Validar assinaturas](https://docs.lacunasoftware.com/articles/pki-express/validate-signatures#ler-os-resultados). 

## 3. Marcar todas as páginas

O `PdfHelper` é uma API fluente que monta marcas, containers e elementos (texto, imagem, QR code); o `PdfMarker` guarda a lista de marcas. O
sample põe o logotipo da ICP-Brasil no canto inferior direito e a mensagem ao longo da borda inferior e da borda direita de todas as
páginas: 

```js
const pdfMarker = new PdfMarker();
Util.setPkiDefaults(pdfMarker);
pdfMarker.setFileFromPathSync(pdfPath);
const pdf = new PdfHelper();
pdfMarker.marks.push(
	pdf.mark()
		.onAllPages()
		.onContainer(pdf.container().width(1).anchorRight(1).height(1)
			.anchorBottom(1))
		.addElement(
			pdf.imageElement()
				.withOpacity(75)
				.withImageContent(Util.getIcpBrasilLogoContent(), 'image/png'),
		),
);
pdfMarker.marks.push(
	pdf.mark()
		.onAllPages()
		.onContainer(pdf.container().height(2).anchorBottom().varWidth()
			.margins(1.5, 3.5))
		.addElement(pdf.textElement().withOpacity(75).addSectionFromText(allPagesMessage)),
);
```

* `allPagesMessage` cita os signatários e informa o site de verificação e o código. 
* Tamanhos e posições ficam em centímetros por padrão (`measurementUnits`). 
* Um elemento de texto pode ser girado com `rotate90CounterClockwise()`, como o sample faz na borda direita. 

## 4. Acrescentar a página de manifesto

Uma marca com `onNewPage()` acrescenta uma página. O sample a preenche de cima para baixo: o logotipo, um QR code com o link de verificação,
o título, o código, uma linha por signatário com um ícone de válido ou inválido e o link de verificação. 

```js
const manifestMark = pdf.mark()
	.onNewPage()
	.onContainer(pdf.container().varWidthAndHeight().margins(2.54, 2.54));
manifestMark.addElement(
	pdf.qrCodeElement()
		.onContainer(pdf.container().height(elementHeight).anchorTop(verticalOffset)
			.width(elementHeight)
			.anchorRight())
		.withQRCodeData(verificationLink),
);
// ... more elements
pdfMarker.marks.push(manifestMark);
outputFile = `${uuidv4()}.pdf`;
pdfMarker.outputFile = path.join(APP_ROOT, 'app-data', outputFile);
return pdfMarker.apply();
```

* `apply()` grava o PDF marcado em `outputFile`, ou sobre o original com `overwriteOriginalFile`. 
* TODO(docs): se a cópia marcada mantém as assinaturas originais (o `PdfMarker` do PKI SDK as remove; veja a [página do PKI SDK](https://docs.lacunasoftware.com/articles/pki-sdk/printer-friendly-version)).

## 5. Verificar um código

A página de verificação interpreta o código, encontra o arquivo e abre de novo as assinaturas para mostrá-las: 

```js
const verificationCode = Util.parseVerificationCode(req.query.code);
const fileId = StorageMock.lookupVerificationCode(req.session, verificationCode);
const sigExplorer = new PadesSignatureExplorer();
Util.setPkiDefaults(sigExplorer);
sigExplorer.setSignatureFileFromPathSync(StorageMock.getDataPath(fileId));
sigExplorer.validate = true;
sigExplorer.open().then((signature) => { /* render the signers and a link to the file */ });
```

## Para um arquivo CAdES

Para um `.p7s`, o sample em Node.js o abre com o `CadesSignatureExplorer` e marca um PDF vazio que vem com o sample; o resultado é um
manifesto que lista os signatários, com o código de verificação e um QR code. 

## Em cada linguagem

| Biblioteca | `PdfMarker` | `PdfHelper` (API fluente) |
|---|---|---|
| Node.js | sim; `setFileFromPath`, `outputFile`, `marks`, `apply()` | sim |
| Java | sim | sim |
| PHP | sim; `setFile`, `setOutputFile`, `apply()` | não: monte objetos `PdfMark` |
| Python | sim; `set_file_from_path`, `output_file`, `marks`, `apply()` | sim |
| Ruby | não | não |

## Veja também

* [Validar assinaturas](https://docs.lacunasoftware.com/articles/pki-express/validate-signatures)
* [Assinar um PDF (PAdES)](https://docs.lacunasoftware.com/articles/pki-express/pades-signature)
* [Versão para impressão com o PKI SDK](https://docs.lacunasoftware.com/articles/pki-sdk/printer-friendly-version)
* [Referência rápida do PKI Express](https://docs.lacunasoftware.com/articles/pki-express/quick-reference)

**Demonstrações e exemplos**

- Demonstração: [Gerar uma versão para impressão](https://try.lacunasoftware.com/pt/pki-suite/printer-friendly-version)
- Gerar a versão para impressão de um PDF assinado com o PKI Express: [Node.js](https://github.com/LacunaSoftware/PkiSuiteSamples/blob/master/nodejs/expressmvc/routes/printer-version-pades-express.js) · [Python](https://github.com/LacunaSoftware/PkiSuiteSamples/blob/master/python/flask/sample/views/printer_version_pades_express.py)
- Gerar a versão para impressão de uma assinatura CMS/CAdES com o PKI Express: [Node.js](https://github.com/LacunaSoftware/PkiSuiteSamples/blob/master/nodejs/expressmvc/routes/printer-version-cades-express.js)
