
Um único número inteiro — o total de páginas de um PDF — está por trás de um número surpreendente de decisões do mundo real: limites de upload, estimativa de papel para impressão, operações de divisão, barras de progresso. A maioria das bibliotecas de renderização de PDF apenas desenha páginas e não expõe uma contagem simples, e enviar o arquivo para um backend só para ler a contagem de páginas adiciona latência e preocupações com privacidade.
O Spire.PDF for JavaScript carrega e analisa documentos PDF diretamente no navegador por meio de WebAssembly, de modo que o arquivo nunca sai do cliente. A contagem de páginas está disponível como uma única propriedade — sem loops, sem idas e voltas ao servidor, sem soluções alternativas de renderização. Este artigo aborda como obter essa contagem e três preocupações práticas: distinguir a contagem física de páginas dos rótulos exibidos, lidar com arquivos protegidos por senha e evitar erros de off-by-one ao iterar pelas páginas.
Para instalação e configuração do projeto, consulte Integrar o Spire.PDF for JavaScript em um Projeto React. Os exemplos abaixo pressupõem que o Spire.PDF está instalado e que o módulo WebAssembly foi inicializado.
Obter a Contagem de Páginas de um Documento PDF
Depois que um objeto PdfDocument carrega um arquivo, sua propriedade Pages expõe a coleção de páginas, e a propriedade Count dessa coleção retorna o número total de páginas. Não é necessário iterar pelas páginas individualmente — a contagem fica disponível imediatamente após o carregamento.
O componente React a seguir demonstra o fluxo de trabalho completo: buscar o PDF para o sistema de arquivos virtual, criar um PdfDocument, carregar o arquivo, ler Pages.Count e gravar o resultado em um arquivo de texto para download.
function App() {
const getPageCount = async () => {
// Get the Spire.PDF WASM module
const pdfModule = window.wasmModule?.spirepdf;
// Check whether the module is ready
if (!pdfModule) {
alert('Spire.PDF is not ready yet');
return;
}
// Load the PDF file to be counted into the VFS
const inputFileName = 'Multipage_Document.pdf';
await window.spire.FetchFileToVFS(inputFileName, '', `${process.env.PUBLIC_URL}/data/`);
// Create a PdfDocument object and load the PDF document
const doc = new pdfModule.PdfDocument();
doc.LoadFromFile(inputFileName);
// Pages is the document's page collection; Count is the total page count
const pageCount = doc.Pages.Count;
// Write the result to the VFS
const outputFileName = 'PageCountResult.txt';
const report = `Document: ${inputFileName}\r\nTotal pages: ${pageCount}`;
window.dotnetRuntime.Module.FS.writeFile(outputFileName, report);
doc.Close();
// Read the generated file from the VFS and trigger the download
const fileArray = window.dotnetRuntime.Module.FS.readFile(outputFileName);
const blob = new Blob([fileArray], { type: 'text/plain' });
const url = URL.createObjectURL(blob);
const a = document.createElement('a');
a.href = url;
a.download = outputFileName;
a.click();
URL.revokeObjectURL(url);
};
return (
<div style={{ textAlign: 'center', height: '300px' }}>
<h1>Get PDF Page Count</h1>
<button onClick={getPageCount}>
Count Pages
</button>
</div>
);
}
export default App;
O resultado é gravado em um arquivo de texto que registra o número total de páginas do documento:

Em uma aplicação de produção, você normalmente usaria o valor de pageCount diretamente em vez de gravá-lo em um arquivo — por exemplo, para validar um upload, definir o limite de um loop ou exibir metadados na interface. A abordagem de gerar um arquivo de saída mostrada aqui é útil para testes e demonstrações.
Contagem Física de Páginas vs. Rótulos de Página
Eis uma situação que pega os desenvolvedores de surpresa: você lê Pages.Count e obtém 12, mas o leitor de PDF na tela do usuário mostra a última página como "página 8". Qual número está correto?
Ambos estão — eles medem coisas diferentes. Pages.Count retorna o número de páginas físicas do documento, simplesmente. Já o número exibido por um leitor vem dos rótulos de página (a entrada /PageLabels na especificação PDF). Os rótulos de página são uma camada de apresentação que os editores usam para controlar como os números de página aparecem para o leitor. Um editor de livros pode excluir a capa da numeração, usar algarismos romanos (i, ii, iii) para o material preliminar e reiniciar o corpo do texto em 1. Depois de tudo isso, a quinta página física pode ser exibida como iii ou 1, dependendo de como os rótulos estão configurados.
Essa distinção importa quando sua aplicação precisa mostrar aos usuários um número de página que corresponda ao que eles veem em seu leitor. Se você exibir Pages.Count como a "página atual", ele não corresponderá à numeração do leitor sempre que houver rótulos de página em uso.
Quando você precisar do rótulo exibido em vez do índice físico, leia a propriedade PageLabel no objeto de página individual:
// What label the 5th physical page displays in a reader
const page = doc.Pages.get_Item(4);
console.log(page.PageLabel);
Observe o índice baseado em zero: get_Item(4) recupera a quinta página física. Quando o documento não tem rótulos de página configurados, PageLabel retorna uma string vazia. Nesse caso comum, o número exibido corresponde à ordem física das páginas, então Count é o valor que você quer.
Uma forma prática de lidar com os dois cenários é verificar PageLabel primeiro e recorrer ao índice físico quando ele estiver vazio. Isso garante que sua aplicação mostre um número de página que sempre corresponde ao que o usuário vê, independentemente de o documento usar rótulos personalizados.
Contar Páginas em um PDF Criptografado
Muitos PDFs em ambientes corporativos são protegidos por uma senha de abertura — uma medida de segurança que impede a leitura do documento sem a credencial correta. Se você tentar carregar esse arquivo com uma chamada simples de LoadFromFile, o runtime do WASM lança um erro antes mesmo de Pages.Count ser alcançado:
Can not open an encrypted document. The password is invalid.
Isso acontece no momento do carregamento, não no ponto em que você lê a contagem de páginas. O conteúdo do documento — incluindo sua estrutura de páginas — está criptografado, então a biblioteca não consegue analisá-lo sem a senha. Não há como contar páginas sem primeiro desbloquear o documento.
A solução é direta: passe a senha de abertura como segundo argumento para LoadFromFile. Depois que o documento é desbloqueado, a contagem de páginas fica disponível exatamente como em um arquivo não criptografado:
// The second argument is the open password
doc.LoadFromFile(inputFileName, 'spire123');
const pageCount = doc.Pages.Count;
Em uma aplicação real, você normalmente coletaria a senha do usuário por meio de um campo de formulário e a passaria dinamicamente, em vez de codificá-la diretamente. Se o usuário digitar a senha errada, o mesmo erro será lançado — por isso, envolver a chamada de LoadFromFile em um bloco try/catch e exibir uma mensagem amigável de "senha incorreta" é uma boa prática.
Mais uma coisa que vale destacar: essa senha é a senha de abertura (também chamada de senha de usuário), que controla quem pode visualizar o documento. Um PDF também pode ter uma senha de permissões (senha de proprietário) que restringe edição, impressão ou cópia sem bloquear a visualização. Para fins de contagem de páginas, apenas a senha de abertura é relevante — uma vez que o documento está aberto, Pages.Count funciona independentemente das restrições de permissão.
Usar a Contagem de Páginas como Limite de Loop
Depois de obter a contagem de páginas, um próximo passo natural é percorrer cada página — para extrair texto, renderizar miniaturas, dividir o documento ou aplicar alguma transformação. É aí que surge um bug sutil, mas comum: usar Count como limite superior inclusivo.
A coleção Pages é baseada em zero, o que significa que os índices válidos vão de 0 a Count - 1. Se a condição do loop for escrita com <= em vez de <, a iteração final tentará acessar a página no índice Count, que não existe. O runtime do WASM encapsula a ArgumentOutOfRangeException subjacente do .NET como um Error do JavaScript com uma mensagem como:
ArgumentOutOfRange_IndexMustBeLess Arg_ParamName_Name, index
Como a propriedade name do erro é apenas o genérico Error, você não consegue distingui-lo apenas pelo nome — é preciso comparar a string da mensagem se quiser tratá-lo especificamente.
O loop correto usa <, de modo que o último índice acessado seja Count - 1:
// The upper bound is Count - 1, so use < rather than <=
for (let i = 0; i < doc.Pages.Count; i++) {
const page = doc.Pages.get_Item(i);
}
Esse padrão de off-by-one é uma das fontes mais frequentes de erros em tempo de execução ao trabalhar com coleções de páginas. É fácil não percebê-lo nos testes se seus documentos de exemplo tiverem apenas uma ou duas páginas — o erro só aparece na iteração final, então um documento de uma única página não o acionará de forma alguma. Teste sempre a lógica do loop com um documento que tenha pelo menos três páginas para garantir que a condição de limite esteja correta.
Veja Também
- Integrar o Spire.PDF for JavaScript em um Projeto React — Guia de configuração para instalar o Spire.PDF e inicializar o módulo WebAssembly em um aplicativo React.
- Página do Produto Spire.PDF for JavaScript — Visão geral dos recursos, operações suportadas e capacidades de processamento de PDF no navegador.
- spire.pdf no npm — Página do pacote para instalar a biblioteca via npm.