Gerenciamento de Documentos
Gerenciamento de Documentos
A classe Document é o ponto de entrada para quase todas as operações no Aspose.PDF FOSS para Python: criar um novo PDF, carregar um existente, editar suas páginas e gravar o resultado. Este guia percorre o ciclo de vida do documento, as operações de coleção de páginas, otimização, fluxos de trabalho multi-arquivo, criptografia e as exceções que você deve esperar tratar.
Ciclo de Vida do Documento: Criar, Abrir e Salvar
Document() sem argumentos cria um documento vazio na memória. Passe um caminho de arquivo, bytes cru, ou qualquer fluxo binário legível como primeiro argumento (ou chame load_from() explicitamente) para carregar um PDF existente. save() aceita um caminho ou um fluxo binário gravável, como io.BytesIO.
from aspose_pdf import Document
# Create a new, empty document and add a blank page
doc = Document()
doc.pages.add()
doc.save("hello.pdf")
# Re-open it — a path, bytes, or a binary stream all work
reopened = Document("hello.pdf")
print(reopened.page_count) # 1
# ...or load explicitly onto an existing instance
another = Document()
another.load_from("hello.pdf")
reopened.close()
another.dispose()
doc.dispose()save() gera FileExistsError se o caminho de destino já existir, a menos que você passe overwrite=True. close() é um alias para dispose(); ambos são idempotentes, portanto chamá-los mais de uma vez é seguro.
Somente PDF está implementado como destino de salvamento — esta é a funcionalidade central da biblioteca, totalmente operacional. Passar um valor de exportação como SaveFormat.PPTX ou DocFormat.HTML para save() gera UnsupportedFeatureException em vez de gravar um arquivo rotulado incorretamente, portanto uma exportação falha é sempre evidente, não silenciosa.
Gerenciando a Coleção de Páginas
doc.pages é um PageCollection. Ele suporta len(), iteração e indexação baseada em zero (doc.pages[0]), além de add(), insert(index, page) e delete(index) para edições estruturais. Cada Page expõe index, rect (o MediaBox) e rotation.
from aspose_pdf import Document
doc = Document()
doc.pages.add() # page 0
doc.pages.add() # page 1
doc.pages.insert(1, None) # insert a blank page at index 1
print(doc.page_count) # 3
first_page = doc.pages[0]
print(first_page.rect) # (0, 0, 612, 792)
for page in doc.pages:
print(page.index, page.rotation)
doc.pages.delete(1) # remove the page we inserted
doc.save("pages_demo.pdf", overwrite=True)pages.add(page=None) adiciona uma página em branco quando chamado sem argumento. pages.insert() limita um índice fora do intervalo à posição válida mais próxima em vez de lançar.
Otimização e Compactação de Documentos
Document.optimize executa deduplicação de imagem/fluxo, coleta de lixo de objetos não usados e compressão de fluxo em uma única chamada. Passe uma instância de OptimizationOptions para controlar quais técnicas são executadas; omita-a para usar o perfil de limpeza padrão.
from aspose_pdf import Document, OptimizationOptions
doc = Document("large_report.pdf")
options = OptimizationOptions()
options.remove_unused_objects = True
options.link_duplicate_streams = True
options.image_compression_quality = 60
options.subset_fonts = True
doc.optimize(options)
doc.save("large_report_optimized.pdf", overwrite=True)optimize_resources() é um alias para optimize(). Se você quiser apenas compressão de fluxo sem a etapa de limpeza estrutural, chame doc.compress_streams() diretamente.
Mesclagem, Divisão e Edição de Arquivos
Para documentos que você já tem abertos, Document.merge() adiciona outras instâncias de Document ao documento atual:
from aspose_pdf import Document
base = Document("part1.pdf")
extra = Document("part2.pdf")
base.merge(extra)
base.save("combined.pdf", overwrite=True)Para fluxos de trabalho file-to-file sem abrir um Document por conta própria, os plugins low-code Merger e Splitter recebem um objeto MergeOptions/SplitOptions construído a partir das entradas e saídas de FileDataSource:
from aspose_pdf import Merger, MergeOptions, Splitter, SplitOptions, FileDataSource
# Merge two files into one
merge_options = MergeOptions()
merge_options.add_input(FileDataSource("part1.pdf"))
merge_options.add_input(FileDataSource("part2.pdf"))
merge_options.add_output(FileDataSource("combined.pdf"))
Merger().process(merge_options)
# Split the result into one file per page
split_options = SplitOptions()
split_options.add_input(FileDataSource("combined.pdf"))
split_options.add_output(FileDataSource("combined_page1.pdf"))
split_options.add_output(FileDataSource("combined_page2.pdf"))
Splitter().process(split_options)PdfFileEditor oferece a mesma família de operações como uma fachada que retorna True/False em vez de lançar exceções, o que é conveniente para scripts em lote:
from aspose_pdf import PdfFileEditor
with PdfFileEditor() as editor:
ok = editor.concatenate(["part1.pdf", "part2.pdf"], "combined.pdf")
if not ok:
print("concatenate failed:", editor.last_exception)
editor.extract("combined.pdf", "first_page_only.pdf", page_from=1, page_to=1)PdfFileEditor.extract() and .insert() take baseado em 1 números de página, ao contrário PageCollectionindexação baseada em 0 — veja Problemas comuns abaixo.
Criptografia e Segurança de Documentos
Document.encrypt(user_password, owner_password=None, permissions=-4) criptografa o documento em memória; decrypt(password) e change_passwords(old, new_user, new_owner=None) invertem ou rotacionam senhas. is_encrypted e permissions relatam o estado atual.
from aspose_pdf import Document
from aspose_pdf.exceptions import PdfSecurityException
doc = Document()
doc.pages.add()
doc.encrypt("user-pass", "owner-pass", permissions=-4)
doc.save("secured.pdf", overwrite=True)
try:
Document("secured.pdf", password="wrong-pass")
except PdfSecurityException as exc:
print("could not open:", exc)
reopened = Document("secured.pdf", password="user-pass")
print(reopened.is_encrypted) # True
reopened.decrypt("user-pass")
reopened.save("unsecured.pdf", overwrite=True)Abrir um documento criptografado sem senha, ou com a senha errada, gera PdfSecurityException — capture esta classe (de aspose_pdf.exceptions) em vez de supor que o carregamento sempre terá sucesso.
Metadados, Validação e Tratamento de Exceções
Os metadados do documento residem em doc.info (um simples dict[str, str]), e doc.version / doc.id expõem a versão do cabeçalho PDF e o identificador do arquivo trailer. validate() (apelidado como check()) relata a integridade estrutural; repair() tenta corrigir problemas comuns como uma lista de páginas ausente ou um MediaBox fora do intervalo.
from aspose_pdf import Document, PdfLoadLimits
from aspose_pdf.exceptions import AsposePdfException, PdfIOException
doc = Document()
doc.pages.add()
doc.info["Title"] = "Quarterly Report"
doc.info["Author"] = "Reporting Bot"
doc.save("report.pdf", overwrite=True)
# Load untrusted input under an explicit resource-limit policy
safe_limits = PdfLoadLimits(max_input_bytes=50 * 1024 * 1024, max_pages=1000)
try:
untrusted = Document("incoming.pdf", limits=safe_limits)
if not untrusted.validate():
untrusted.repair()
except (AsposePdfException, PdfIOException) as exc:
print("failed to process incoming.pdf:", exc)PdfLoadLimits limita a memória e a contagem de objetos para arquivos não confiáveis; chame PdfLoadLimits.unlimited() para desativar todos os limites quando você confia totalmente na fonte. AsposePdfException é a classe base para toda a hierarquia de exceções (incluindo PdfIOException e PdfSecurityException), portanto um único except AsposePdfException captura qualquer erro gerado pela biblioteca.
Dicas e Melhores Práticas
- Sempre chame
dispose()(ouclose()) em umDocumentquando terminar com ele, ou use-o como uma variável local de curta duração — o motor mantém o conteúdo da página decodificado e as imagens na memória até a liberação. - Passe
overwrite=Trueparasave()ao reescrever um caminho que você já criou na mesma execução; o padrão éFalsee geraFileExistsError. - Prefira
doc.optimize()antes de distribuir um PDF gerado — é uma chamada única que remove objetos não usados e comprime fluxos, e normalmente reduz o tamanho da saída de forma perceptível. - Defina uma política de
PdfLoadLimitsexplicitamente sempre que carregar PDFs de uma fonte não confiável (envios, anexos de e-mail, raspagens da web); os padrões são generosos, porém limitados, não constituindo uma barreira de segurança na qual você deva confiar cegamente. - Capture
AsposePdfException(ou uma subclasse específica, comoPdfSecurityException) ao redor de chamadas de carga/gravação, em vez deExceptionpuro — ela é a base comum para todos os erros que a biblioteca gera.
Problemas Comuns
| Problema | Causa | Correção |
|---|---|---|
FileExistsError em save() | O caminho de destino já existe e overwrite foi deixado no seu padrão False | Passar save(path, overwrite=True) |
UnsupportedFeatureException em save() | Um save_format não PDF (por exemplo, SaveFormat.PPTX, DocFormat.HTML) foi solicitado | Salvar como PDF — qualquer outro valor de SaveFormat/DocFormat gera UnsupportedFeatureException em vez de gravar a saída |
PdfSecurityException: Password required for encrypted document | Um PDF criptografado foi aberto sem um argumento password | Passe Document(path, password="...") ou chame load_from(path, password="...") |
Números de página fora de um entre PageCollection e PdfFileEditor | doc.pages[i] é baseado em zero; os argumentos de página PdfFileEditor.extract()/.insert() são baseados em um | Adicione ou subtraia 1 ao converter entre as duas APIs |
IndexError: Page index out of range. de pages.delete() | O índice passado para delete() não existe na coleção | Verifique doc.page_count (ou len(doc.pages)) antes de excluir |
FAQ
Preciso de uma licença para usar Aspose.PDF FOSS para Python?
Não. Esta é a edição de código aberto (licenciada sob MIT); não há arquivo de licença nem etapa de ativação para configurar.
Posso exportar um Document para formatos diferentes de PDF?
Não nesta versão. save() implementa apenas saída em PDF — passar outro valor SaveFormat/DocFormat gera UnsupportedFeatureException em vez de produzir um arquivo com rótulo errado.
Qual é a diferença entre Document.merge() e o plugin Merger?
Document.merge() combina instâncias de Document que você já tem abertas na memória. Merger (com MergeOptions e FileDataSource) é um wrapper de conveniência file-to-file que abre, mescla e salva para você em uma única chamada — útil para scripts batch simples que nunca precisam do objeto intermediário Document.
Por que pages.insert() nunca gera um erro para um índice fora do intervalo?
PageCollection.insert() limita o índice ao intervalo válido (valores negativos tornam-se 0, valores além do fim tornam-se len(doc.pages)) em vez de gerar erro, portanto uma inserção nunca falha apenas por causa do valor do índice.
Como faço para carregar um PDF com segurança a partir de uma fonte não confiável?
Construa um PdfLoadLimits com limites explícitos (max_input_bytes, max_pages, max_objects e assim por diante) e passe-o como o argumento limits= para Document(...) ou load_from(). Cada campo já tem um valor finito padrão, mas restringi-los ao tamanho de entrada esperado reduz os recursos que um arquivo malformado pode consumir.
API Reference Resumo
| Classe / Método | Descrição |
|---|---|
Document() / Document.load_from | Crie um documento vazio ou carregue um a partir de um caminho, bytes ou um fluxo binário |
Document.save | Escreva o documento em um caminho ou em um fluxo gravável (apenas PDF) |
Document.dispose() / Document.close() | Libere os recursos do motor; idempotente |
Document.pages | O PageCollection do documento |
Document.info | Metadados do documento como um dict[str, str] |
Document.optimize / Document.optimize_resources / Document.compress_streams() | Remover recursos não utilizados e comprimir fluxos |
Document.merge() | Acrescentar outras instâncias de Document a esta |
Document.encrypt / Document.decrypt / Document.change_passwords | Aplicar, remover ou girar senhas de documento |
Document.validate() / Document.check() / Document.repair() | Verificar e tentar corrigir a integridade estrutural |
PageCollection.add() / .insert() / .delete() / .item() | Edições estruturais da coleção de páginas (base zero) |
Page.rect / Page.rotation / Page.index | Geometria e posição por página |
OptimizationOptions | Flags de granularidade fina consumidas por Document.optimize |
MergeOptions / Merger | Plugin de mesclagem de arquivo para arquivo |
SplitOptions / Splitter | Plugin de divisão de arquivo para arquivo, uma página por saída |
FileDataSource | Entrada/saída baseada em arquivo para as APIs do plugin |
PdfFileEditor | Facade para concatenate(), extract(), insert(), delete(), append() (páginas baseadas em 1) |
PdfLoadLimits | Política imutável de limite de recursos para entrada não confiável |
AsposePdfException | Classe base para todas as exceções que a biblioteca gera |
PdfSecurityException | Gerada para senhas ausentes/incorretas e erros de permissão |
PdfIOException | Gerada para erros de E/S durante o processamento de PDF |
Ver também
- API Reference: Documentação completa de classes e métodos para
aspose_pdf - Base de Conhecimento: Guias práticos orientados a tarefas
- Visão geral do produto: Resumo de recursos e capacidades
- Começando / Instalação: instalar e configurar
- Aspose.PDF for Python — Enterprise Documentation