Como Trabalhar com Documentos PDF em C++

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.git
add_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 build

Verifique 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().

Ver também

 Português