Como Trabalhar com Documentos PDF em C++
Aspose.PDF FOSS para C++ é uma biblioteca C++20 licenciada sob MIT, sem dependências, construída e vinculada com CMake — não há importação de gerenciador de pacotes a ser adicionada. Este guia percorre o fluxo de trabalho centralizado em Document: abrir um PDF existente, inspecionar suas páginas e metadados, extrair texto e renderizar uma página para uma imagem raster.
Guia Passo a Passo
Passo 1: Instalar o Pacote
Clone o repositório e adicione-o ao seu projeto CMake como um subdiretório:
git clone https://github.com/aspose-pdf-foss/Aspose.PDF-FOSS-for-Cpp.gitadd_subdirectory(Aspose.PDF-FOSS-for-Cpp)
target_link_libraries(your_app PRIVATE aspose_pdf_foss)Ou configure e compile-o de forma independente:
cmake -S . -B build -DCMAKE_BUILD_TYPE=Release
cmake --build buildVerifique se a cadeia de ferramentas resolve compilando um programa mínimo contra os cabeçalhos:
#include <aspose/pdf/document.hpp>
#include <iostream>
int main() {
Aspose::Pdf::Document doc;
std::cout << "Linked OK - pages: " << doc.Pages().Count() << "\n";
}Uma compilação bem-sucedida que imprime pages: 0 para o Document recém-construído e vazio confirma que a biblioteca está vinculada corretamente.
Etapa 2: Importar Classes Necessárias
#include <aspose/pdf/document.hpp>
#include <aspose/pdf/document_info.hpp>
#include <aspose/pdf/page.hpp>
#include <aspose/pdf/page_collection.hpp>
#include <aspose/pdf/text_absorber.hpp>
#include <aspose/pdf/bmp_device.hpp>
#include <aspose/pdf/resolution.hpp>
#include <fstream>
#include <iostream>Etapa 3: Abrir um Documento PDF e Contar Suas Páginas
Construa um Document a partir de um caminho de arquivo para abrir um PDF existente. Document::Pages() devolve o PageCollection, e Count() informa quantas páginas ele contém:
Aspose::Pdf::Document doc("input.pdf");
std::cout << "Page count: " << doc.Pages().Count() << "\n";Etapa 4: Ler Metadados do Documento
Document::Info() devolve um objeto DocumentInfo com acessores de leitura/escrita tipados para as entradas padrão do dicionário /Info:
auto& info = doc.Info();
std::cout << "Title: " << info.Title() << "\n";
std::cout << "Author: " << info.Author() << "\n";
std::cout << "Producer: " << info.Producer() << "\n";Etapa 5: Extrair Texto de uma Página
Aspose::Pdf::Text::TextAbsorber percorre um Document ou um único Page e acumula o texto encontrado; Text() devolve o resultado posteriormente. PageCollection é indexado a partir de 1, então Pages()[1] é a primeira página:
auto page = doc.Pages()[1];
Aspose::Pdf::Text::TextAbsorber absorber;
absorber.Visit(page);
std::cout << absorber.Text() << "\n";Visit() também aceita o Document completo diretamente (absorber.Visit(doc)) quando você deseja que o texto de todas as páginas seja concatenado em vez de uma única página.
Etapa 6: Renderizar a página para uma imagem raster
BmpDevice renderiza um Page para uma imagem BMP descompactada. Seu construtor recebe um Resolution que controla o DPI de saída, e Process() grava os bytes renderizados em qualquer std::ostream:
Aspose::Pdf::Devices::BmpDevice device(Aspose::Pdf::Devices::Resolution(150));
std::ofstream imageOut("page1.bmp", std::ios::binary);
device.Process(page, imageOut);Etapa 7: Atualizar metadados e salvar o documento
Os setters em DocumentInfo preparam alterações que são descarregadas na próxima vez que Save() for executado no Document proprietário:
doc.Info().Title("Processed by Aspose.PDF FOSS for C++");
doc.Save("output.pdf");Problemas comuns e correções
Accessing Pages()[0] throws std::out_of_range
PageCollection é indexado a partir de 1, correspondendo à semântica canônica de Aspose.PDF — a primeira página é Pages()[1]. Um índice abaixo de 1 ou acima de Count() gera erro.
TextAbsorber::Text() retorna uma string vazia
Text() retorna o que foi acumulado pela chamada mais recente de Visit(). Confirme que Visit() foi realmente chamada antes de ler Text(), e que a página ou documento que você visitou contém texto extraível em vez de apenas imagens escaneadas.
O arquivo BMP renderizado está inesperadamente pequeno ou parece em branco
Um valor baixo de Resolution produz uma imagem raster pequena. Aumente o DPI passado para Resolution — por exemplo, Resolution(300) para saída de qualidade de impressão — e confirme que o índice de página passado para Process() é o que você pretendia.
DocumentInfo campos lidos de volta como strings vazias
Nem todo produtor de PDF grava entradas padrão de /Info. Verifique Producer() e Creator() em busca de valores em branco antes de assumir que a extração de metadados falhou — uma string vazia é o resultado definido para uma chave ausente.
Alterações feitas com Info().Title(...) não aparecem no arquivo salvo
As mutações de DocumentInfo são armazenadas em memória e só são persistidas na próxima vez que Save() for executado na mesma instância de Document. Certifique-se de que a edição de metadados ocorra antes de Save(), não depois.
Perguntas Frequentes
A indexação de páginas é baseada em zero ou em um no Aspose.PDF FOSS para C++?
Baseada em um. doc.Pages()[1] é sempre a primeira página.
O TextAbsorber pode extrair texto de uma única página em vez de todo o documento?
Sim. O Visit() está sobrecarregado para aceitar ou um Document — que extrai o texto de todas as páginas — ou um único Page, que extrai apenas o texto daquela página.
Preciso chamar Save() se eu apenas ler dados do documento?
Não. Save() só é necessário após alterações que precisam ser gravadas de volta em um arquivo, como editar campos DocumentInfo. Ler a contagem de páginas, extrair texto ou renderizar uma página não modifica o documento.
Como controlo a resolução de uma página renderizada?
Passe um valor Resolution para o construtor do dispositivo — por exemplo, Resolution(150) para 150 DPI. Valores mais altos produzem imagens raster maiores e de maior fidelidade.
Qual formato BmpDevice produz?
Uma imagem BMP não compactada escrita diretamente no std::ostream passado para Process().