Gestion de documents

Gestion de documents

Gestion des documents

La classe Document est le point d’entrée pour presque toutes les opérations dans Aspose.PDF FOSS pour Python: créer un nouveau PDF, charger un PDF existant, modifier ses pages et écrire le résultat. Ce guide parcourt le cycle de vie du document, les opérations sur la collection de pages, l’optimisation, les flux de travail multi-fichiers, le chiffrement et les exceptions que vous devez vous attendre à gérer.


Cycle de vie du document: créer, ouvrir et enregistrer

Document() sans arguments crée un document vide en mémoire. Passez un chemin de fichier, le bytes brut, ou tout flux binaire lisible comme premier argument (ou appelez load_from() explicitement) pour charger un PDF existant à la place. save() accepte un chemin ou un flux binaire writable tel que 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() lève FileExistsError si le chemin de destination existe déjà, sauf si vous passez overwrite=True. close() est un alias de dispose(); les deux sont idempotents, donc les appeler plus d’une fois est sûr.

Seul le PDF est implémenté comme cible d’enregistrement — c’est le cœur de la bibliothèque, une fonction entièrement fonctionnelle. Passer une valeur d’exportation telle que SaveFormat.PPTX ou DocFormat.HTML à save() lève UnsupportedFeatureException au lieu d’écrire un fichier mal étiqueté, de sorte qu’un export échoué est toujours signalé de manière audible plutôt que silencieuse.


Gestion de la collection de pages

doc.pages est un PageCollection. Il prend en charge len(), l’itération et l’indexation à base zéro (doc.pages[0]), ainsi que add(), insert(index, page) et delete(index) pour les modifications structurelles. Chaque Page expose index, rect (le MediaBox), et 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) ajoute une page blanche lorsqu’il est appelé sans argument. pages.insert() limite un indice hors de portée à la position valide la plus proche au lieu de lever une exception.


Optimisation et compression des documents

Document.optimize exécute la déduplication d’images/flux, la collecte des objets inutilisés et la compression de flux en un seul appel. Fournissez une instance OptimizationOptions pour contrôler les techniques exécutées; omettez-la pour utiliser le profil de nettoyage standard.

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() est un alias de optimize(). Si vous ne souhaitez que la compression de flux sans le passage de nettoyage structurel, appelez directement doc.compress_streams().


Fusion, division et édition de fichiers

Pour les documents déjà ouverts, Document.merge() ajoute d’autres instances Document au document actuel:

from aspose_pdf import Document

base = Document("part1.pdf")
extra = Document("part2.pdf")

base.merge(extra)
base.save("combined.pdf", overwrite=True)

Pour les flux de travail fichier-à-fichier sans ouvrir vous-même un Document, les plugins low-code Merger et Splitter acceptent un objet MergeOptions/SplitOptions construit à partir des entrées et sorties 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 propose la même famille d’opérations qu’une façade qui renvoie True/False au lieu de lever une exception, ce qui est pratique pour les scripts batch :

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 indexé à 1 numéros de page, contrairement à PageCollectionindexation à base 0 — voir Problèmes courants ci-dessous.


Chiffrement et sécurité des documents

Document.encrypt(user_password, owner_password=None, permissions=-4) chiffre le document en mémoire; decrypt(password) et change_passwords(old, new_user, new_owner=None) inversent ou font pivoter les mots de passe. is_encrypted et permissions indiquent l’état actuel.

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)

L’ouverture d’un document chiffré sans mot de passe, ou avec un mauvais mot de passe, lève PdfSecurityException — attrapez cette classe (provenant de aspose_pdf.exceptions) plutôt que de supposer qu’un chargement réussit toujours.


Métadonnées, validation et gestion des exceptions

Les métadonnées du document résident sur doc.info (un simple dict[str, str]), et doc.version / doc.id exposent la version de l’en-tête PDF ainsi que l’identifiant de fichier du trailer. validate() (alias check()) indique l’intégrité structurelle; repair() tente de corriger les problèmes courants tels qu’une liste de pages manquante ou un MediaBox hors limites.

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 limite la mémoire et le nombre d’objets pour les fichiers non fiables; appelez PdfLoadLimits.unlimited() pour désactiver toutes les limites lorsque vous faites totalement confiance à la source. AsposePdfException est la classe de base de toute la hiérarchie d’exceptions (y compris PdfIOException et PdfSecurityException), ainsi un seul except AsposePdfException intercepte toute erreur levée par la bibliothèque.


Conseils et meilleures pratiques

  • Appelez toujours dispose() (ou close()) sur un Document lorsque vous avez fini de l’utiliser, ou utilisez-le comme une variable locale à courte durée de vie — le moteur conserve le contenu des pages décodées et les images en mémoire jusqu’à leur élimination.
  • Passez overwrite=True à save() lors de la réécriture d’un chemin que vous avez déjà créé dans la même exécution; la valeur par défaut est False et déclenche FileExistsError.
  • Privilégiez doc.optimize() avant de livrer un PDF généré — c’est un appel unique qui supprime les objets inutilisés et compresse les flux, et réduit généralement la taille du résultat de façon notable.
  • Définissez explicitement une politique PdfLoadLimits chaque fois que vous chargez des PDF provenant d’une source non fiable (téléversements, pièces jointes d’e-mail, extractions web); les valeurs par défaut sont généreuses mais limitées, ce n’est pas une frontière de sécurité sur laquelle vous devez compter aveuglément.
  • Interceptez AsposePdfException (ou une sous-classe spécifique comme PdfSecurityException) autour des appels de chargement/enregistrement plutôt que le simple Exception — c’est la base commune de toutes les erreurs levées par la bibliothèque.

Problèmes courants

ProblèmeCauseCorrection
FileExistsError sur save()Le chemin de destination existe déjà et overwrite a été laissé à son False par défautPasser save(path, overwrite=True)
UnsupportedFeatureException sur save()Un save_format non-PDF (par ex. SaveFormat.PPTX, DocFormat.HTML) a été demandéEnregistrer en PDF — toute autre valeur SaveFormat/DocFormat déclenche UnsupportedFeatureException au lieu d’écrire la sortie
PdfSecurityException: Password required for encrypted documentPDF chiffré ouvert sans argument passwordPassez Document(path, password="...") ou appelez load_from(path, password="...")
Décalage d’une page entre PageCollection et PdfFileEditordoc.pages[i] est basé sur 0 ; les arguments de page PdfFileEditor.extract()/.insert() sont basés sur 1Ajoutez ou soustrayez 1 lors de la conversion entre les deux API
IndexError: Page index out of range. de pages.delete()L’index passé à delete() n’existe pas dans la collectionVérifiez doc.page_count (ou len(doc.pages)) avant de supprimer

FAQ

Ai-je besoin d’une licence pour utiliser Aspose.PDF FOSS pour Python?

Non. Il s’agit de l’édition open source (sous licence MIT); il n’existe aucun fichier de licence ni aucune étape d’activation à configurer.

Puis-je exporter un Document vers des formats autres que le PDF?

Pas dans cette version. save() ne prend en charge que la sortie PDF — fournir une autre valeur SaveFormat/DocFormat déclenche UnsupportedFeatureException plutôt que de produire un fichier mal nommé.

Quelle est la différence entre Document.merge() et le plugin Merger?

Document.merge() combine les instances Document que vous avez déjà ouvertes en mémoire. Merger (avec MergeOptions et FileDataSource) est un wrapper de commodité file-to-file qui ouvre, fusionne et enregistre pour vous en un seul appel — utile pour les scripts batch simples qui n’ont jamais besoin de l’objet intermédiaire Document.

Pourquoi pages.insert() ne soulève-t-il jamais d’exception pour un index hors limites?

PageCollection.insert() limite l’index à la plage valide (les valeurs négatives deviennent 0, les valeurs dépassant la fin deviennent len(doc.pages)) au lieu de lever une exception, ainsi un insert n’échoue jamais uniquement à cause de la valeur de l’index.

Comment charger en toute sécurité un PDF provenant d’une source non fiable ?

Construisez un PdfLoadLimits avec des limites explicites (max_input_bytes, max_pages, max_objects, etc.) et transmettez-le en tant qu’argument limits= à Document(...) ou load_from(). Chaque champ possède déjà une valeur finie par défaut, mais les resserrer à la taille d’entrée attendue réduit les ressources qu’un fichier mal formé peut consommer.


API Reference Résumé

Classe / MéthodeDescription
Document() / Document.load_fromCréez un document vide ou chargez-en un depuis un chemin, des octets ou un flux binaire
Document.saveÉcrivez le document vers un chemin ou un flux pouvant être écrit (PDF uniquement)
Document.dispose() / Document.close()Libérez les ressources du moteur ; idempotent
Document.pagesLe PageCollection du document
Document.infoMétadonnées du document en tant que dict[str, str]
Document.optimize / Document.optimize_resources / Document.compress_streams()Supprimer les ressources inutilisées et compresser les flux
Document.merge()Ajouter d’autres instances de Document à celle-ci
Document.encrypt / Document.decrypt / Document.change_passwordsAppliquer, supprimer ou faire pivoter les mots de passe du document
Document.validate() / Document.check() / Document.repair()Vérifier et tenter de réparer l’intégrité structurelle
PageCollection.add() / .insert() / .delete() / .item()Modifications de la collection de pages structurales (indexation à partir de 0)
Page.rect / Page.rotation / Page.indexGéométrie et position par page
OptimizationOptionsDrapeaux fins consommés par Document.optimize
MergeOptions / MergerPlugin de fusion de fichier à fichier
SplitOptions / SplitterPlugin de division fichier à fichier une page par sortie
FileDataSourceEntrée/sortie basée sur fichier pour les API du plugin
PdfFileEditorFaçade pour concatenate(), extract(), insert(), delete(), append() (pages indexées à partir de 1)
PdfLoadLimitsPolitique immuable de limitation des ressources pour les entrées non fiables
AsposePdfExceptionClasse de base pour chaque exception que la bibliothèque lève
PdfSecurityExceptionLevée pour les mots de passe manquants/incorrects et les erreurs d’autorisation
PdfIOExceptionLevée pour les erreurs d’E/S lors du traitement de PDF

Voir aussi

 Français