Dokumenthantering

Dokumenthantering

Klassen Document är startpunkten för nästan varje operation i Aspose.PDF FOSS för Python: skapa en ny PDF, läsa in en befintlig, redigera dess sidor och skriva tillbaka resultatet. Den här guiden går igenom dokumentets livscykel, operationer för sidssamling, optimering, flermodulsarbetsflöden, kryptering och de undantag du bör förvänta dig att hantera.


Dokumentlivscykel: Skapa, Öppna och Spara

Document() utan argument skapar ett tomt dokument i minnet. Skicka en filsökväg, rå bytes eller någon läsbar binär ström som första argument (eller anropa load_from() explicit) för att läsa in en befintlig PDF istället. save() accepterar en sökväg eller en skrivbar binär ström såsom 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() kastar FileExistsError om destinationssökvägen redan finns, såvida du inte skickar overwrite=True. close() är ett alias för dispose(); båda är idempotenta, så att anropa dem mer än en gång är säkert.

Endast PDF är implementerat som en sparmål — detta är bibliotekets kärna, en fullt fungerande funktion. Att skicka ett exportvärde såsom SaveFormat.PPTX eller DocFormat.HTML till save() kastar UnsupportedFeatureException istället för att skriva en felaktigt namngiven fil, så en misslyckad export är alltid tydlig snarare än tyst.


Hantera sidssamlingen

doc.pages är en PageCollection. Det stöder len(), iteration och 0-baserad indexering (doc.pages[0]), samt add(), insert(index, page) och delete(index) för strukturella redigeringar. Varje Page exponerar index, rect (det MediaBox), och 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) lägger till en tom sida när den anropas utan argument. pages.insert() klampar ett index utanför intervallet till närmaste giltiga position istället för att kasta ett fel.


Optimera och komprimera dokument

Document.optimize kör bild/ström-deduplikering, skräpsamling av oanvända objekt och strömkomprimering i ett anrop. Skicka en OptimizationOptions-instans för att styra vilka tekniker som körs; utelämna den för att använda standardprofilen för rensning.

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() är ett alias för optimize(). Om du bara vill ha strömkomprimering utan det strukturella rensningssteget, anropa doc.compress_streams() direkt.


Sammanfoga, dela och redigera filer

För dokument som du redan har öppna, Document.merge() lägger till andra Document-instanser på den aktuella:

from aspose_pdf import Document

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

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

För fil-till-fil-arbetsflöden utan att själv öppna en Document, tar de lågkods-Merger och Splitter-pluggarna ett MergeOptions/SplitOptions-objekt byggt från FileDataSource-inmatningar och -utmatningar:

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 erbjuder samma familj av operationer som en fasad som returnerar True/False istället för att kasta, vilket är bekvämt för batch-skript:

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 1-baserad sidnummer, till skillnad från PageCollection’s 0-baserade indexering — se Vanliga problem nedan.


Kryptering och dokumentsäkerhet

Document.encrypt(user_password, owner_password=None, permissions=-4) krypterar dokumentet i minnet; decrypt(password) och change_passwords(old, new_user, new_owner=None) vänder eller roterar lösenord. is_encrypted och permissions rapporterar det aktuella tillståndet.

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)

Att öppna ett krypterat dokument utan lösenord, eller med fel lösenord, kastar PdfSecurityException — fånga den här klassen (från aspose_pdf.exceptions) istället för att anta att en laddning alltid lyckas.


Metadata, validering och undantagshantering

Dokumentmetadata finns på doc.info (en enkel dict[str, str]), och doc.version / doc.id visar PDF-huvudets version och trailer-filidentifierare. validate() (alias check()) rapporterar strukturell integritet; repair() försöker åtgärda vanliga problem såsom en saknad sidlista eller ett MediaBox utanför intervallet.

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 begränsar minne och objektantal för opålitliga filer; anropa PdfLoadLimits.unlimited() för att inaktivera alla begränsningar när du litar fullt på källan. AsposePdfException är basklassen för hela undantagshierarkin (inklusive PdfIOException och PdfSecurityException), så ett enda except AsposePdfException fångar alla fel som biblioteket kastar.


Tips och bästa praxis

  • Anropa alltid dispose() (eller close()) på en Document när du är klar med den, eller använd den som en kortlivad lokal variabel — motorn håller avkodade sidinnehåll och bilder i minnet tills de kasseras.
  • Skicka overwrite=True till save() när du skriver om en sökväg som du redan har skapat i samma körning; standardvärdet är False och kastar FileExistsError.
  • Föredra doc.optimize() innan du levererar en genererad PDF — det är ett enda anrop som tar bort oanvända objekt och komprimerar strömmar, och minskar vanligtvis utdatafilens storlek märkbart.
  • Ange en PdfLoadLimits-policy explicit varje gång du laddar PDF-filer från en opålitlig källa (uppladdningar, e-postbilagor, webbsökningar); standardinställningarna är generösa men begränsade, och är inte en säkerhetsgräns du bör förlita dig på blint.
  • Fånga AsposePdfException (eller en specifik underklass såsom PdfSecurityException) runt laddnings-/sparningsanrop snarare än enbart Exception — det är den gemensamma basen för varje fel som biblioteket kastar.

Vanliga problem

ProblemOrsakÅtgärd
FileExistsError på save()Målsökvägen finns redan och overwrite lämnades på sitt standard-FalsePassa save(path, overwrite=True)
UnsupportedFeatureException på save()En icke-PDF save_format (t.ex. SaveFormat.PPTX, DocFormat.HTML) begärdesSpara som PDF — vilket som helst annat SaveFormat/DocFormat-värde utlöser UnsupportedFeatureException istället för att skriva utdata
PdfSecurityException: Password required for encrypted documentÖppnade en krypterad PDF utan ett password-argumentSkicka Document(path, password="...") eller anropa load_from(path, password="...")
Off-by-one-sidnummer mellan PageCollection och PdfFileEditordoc.pages[i] är 0-baserad; PdfFileEditor.extract()/.insert() sidargument är 1-baseradeLägg till eller dra bort 1 när du konverterar mellan de två API:erna
IndexError: Page index out of range. från pages.delete()Index som skickas till delete() finns inte i samlingenKontrollera doc.page_count (eller len(doc.pages)) innan du tar bort

FAQ

Behöver jag en licens för att använda Aspose.PDF FOSS för Python?

Nej. Detta är den öppna källkod (MIT-licensierade) utgåvan; det finns ingen licensfil eller aktiveringssteg att konfigurera.

Kan jag exportera en Document till andra format än PDF?

Inte i den här versionen. save() implementerar endast PDF-utmatning — att skicka ett annat SaveFormat/DocFormat-värde kastar UnsupportedFeatureException istället för att producera en felaktigt namngiven fil.

Vad är skillnaden mellan Document.merge() och Merger-pluginet?

Document.merge() kombinerar Document-instanser som du redan har öppna i minnet. Merger (med MergeOptions och FileDataSource) är ett fil-till-fil-bekvämlighets-wrapper som öppnar, slår ihop och sparar åt dig i ett anrop — användbart för enkla batch-skript som aldrig behöver det mellansteg Document-objektet.

Varför ger pages.insert() aldrig ett fel för ett index som ligger utanför intervallet?

PageCollection.insert() klämmer indexet till det giltiga intervallet (negativa värden blir 0, värden som ligger efter slutet blir len(doc.pages)) istället för att kasta ett fel, så en insättning misslyckas aldrig enbart på grund av indexvärdet.

Hur laddar jag säkert en PDF från en opålitlig källa?

Konstruera en PdfLoadLimits med explicita gränser (max_input_bytes, max_pages, max_objects och så vidare) och skicka den som limits=-argumentet till Document(...) eller load_from(). Varje fält har redan ett ändligt standardvärde, men genom att strama åt dem till den förväntade indatastorleken minskar de resurser som en felaktig fil kan förbruka.


API Reference Sammanfattning

Klass / MetodBeskrivning
Document() / Document.load_fromSkapa ett tomt dokument eller ladda ett från en sökväg, bytes eller en binär ström
Document.saveSkriv dokumentet till en sökväg eller en skrivbar ström (PDF endast)
Document.dispose() / Document.close()Frigör motorresurser; idempotent
Document.pagesDokumentets PageCollection
Document.infoDokumentmetadata som en dict[str, str]
Document.optimize / Document.optimize_resources / Document.compress_streams()Ta bort oanvända resurser och komprimera strömmar
Document.merge()Lägg till andra Document-instanser på den här
Document.encrypt / Document.decrypt / Document.change_passwordsTillämpa, ta bort eller rotera dokumentlösenord
Document.validate() / Document.check() / Document.repair()Kontrollera och försök åtgärda strukturell integritet
PageCollection.add() / .insert() / .delete() / .item()Strukturella sidinsamlingredigeringar (0-baserade)
Page.rect / Page.rotation / Page.indexGeometri och position per sida
OptimizationOptionsFinmaskiga flaggor som konsumeras av Document.optimize
MergeOptions / MergerFil-till-fil-sammanfognings-plugin
SplitOptions / SplitterFil-till-fil en-sida-per-utdata split-plugin
FileDataSourceFilstödd input/output för plugin-API:erna
PdfFileEditorFacade för concatenate(), extract(), insert(), delete(), append() (1-baserade sidor)
PdfLoadLimitsOföränderlig resursgränspolicy för opålitlig indata
AsposePdfExceptionBas-klass för varje undantag som biblioteket kastar
PdfSecurityExceptionUtlöst för saknade/felaktiga lösenord och behörighetsfel
PdfIOExceptionUtlöst för I/O-fel under PDF-behandling

Se även

 Svenska