Manajemen Dokumen

Manajemen Dokumen

Kelas Document adalah titik masuk untuk hampir setiap operasi di Aspose.PDF FOSS untuk Python: membuat PDF baru, memuat yang sudah ada, menyunting halamannya, dan menulis hasilnya kembali. Panduan ini membahas siklus hidup dokumen, operasi koleksi halaman, optimasi, alur kerja multi-berkas, enkripsi, dan pengecualian yang harus Anda tangani.


Siklus Hidup Dokumen: Buat, Buka, dan Simpan

Document() tanpa argumen membuat dokumen kosong di memori. Berikan jalur file, bytes mentah, atau aliran biner yang dapat dibaca sebagai argumen pertama (atau panggil load_from() secara eksplisit) untuk memuat PDF yang sudah ada. save() menerima jalur atau aliran biner yang dapat ditulisi seperti 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() menimbulkan FileExistsError jika jalur tujuan sudah ada, kecuali Anda memberikan overwrite=True. close() adalah alias untuk dispose(); keduanya idempotent, sehingga memanggilnya lebih dari satu kali aman.

Hanya PDF yang diimplementasikan sebagai target penyimpanan — ini adalah fungsi inti perpustakaan yang sepenuhnya berfungsi. Mengirimkan nilai ekspor seperti SaveFormat.PPTX atau DocFormat.HTML ke save() menimbulkan UnsupportedFeatureException alih-alih menulis file yang salah label, sehingga ekspor yang gagal selalu menghasilkan pesan yang jelas bukan diam.


Mengelola Koleksi Halaman

doc.pages adalah PageCollection. Ia mendukung len(), iterasi, dan pengindeksan berbasis-0 (doc.pages[0]), serta add(), insert(index, page), dan delete(index) untuk penyuntingan struktural. Setiap Page menampilkan index, rect (yang MediaBox), dan 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) menambahkan halaman kosong ketika dipanggil tanpa argumen. pages.insert() menahan indeks di luar jangkauan ke posisi valid terdekat alih-alih menghasilkan error.


Mengoptimalkan dan Mengompresi Dokumen

Document.optimize menjalankan deduplikasi gambar/stream, pengumpulan sampah objek yang tidak terpakai, dan kompresi stream dalam satu panggilan. Berikan sebuah instance OptimizationOptions untuk mengontrol teknik mana yang dijalankan; hilangkan untuk menggunakan profil pembersihan standar.

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() adalah alias untuk optimize(). Jika Anda hanya menginginkan kompresi stream tanpa langkah pembersihan struktural, panggil doc.compress_streams() secara langsung.


Menggabungkan, Membagi, dan Menyunting File

Untuk dokumen yang sudah Anda buka, Document.merge() menambahkan instance Document lain ke yang saat ini:

from aspose_pdf import Document

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

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

Untuk alur kerja file-ke-file tanpa membuka Document secara manual, plugin Merger dan Splitter berkode rendah mengambil objek MergeOptions/SplitOptions yang dibangun dari masukan dan keluaran 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 menawarkan keluarga operasi yang sama sebagai sebuah facade yang mengembalikan True/False alih-alih melempar pengecualian, yang nyaman untuk skrip 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 berbasis 1 nomor halaman, tidak seperti PageCollectionindeks berbasis 0 — lihat Masalah Umum di bawah.


Enkripsi dan Keamanan Dokumen

Document.encrypt(user_password, owner_password=None, permissions=-4) mengenkripsi dokumen dalam memori; decrypt(password) dan change_passwords(old, new_user, new_owner=None) membalik atau memutar kata sandi. is_encrypted dan permissions melaporkan keadaan saat ini.

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)

Membuka dokumen terenkripsi tanpa kata sandi, atau dengan kata sandi yang salah, akan melempar PdfSecurityException — tangkap kelas ini (dari aspose_pdf.exceptions) alih-alih menganggap pemuatan selalu berhasil.


Metadata, Validasi, dan Penanganan Pengecualian

Metadata dokumen berada pada doc.info (sebuah dict[str, str] biasa), dan doc.version / doc.id menampilkan versi header PDF serta pengidentifikasi file trailer. validate() (dengan alias check()) melaporkan integritas struktural; repair() berusaha memperbaiki masalah umum seperti daftar halaman yang hilang atau MediaBox di luar jangkauan.

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 membatasi memori dan jumlah objek untuk file yang tidak dipercaya; panggil PdfLoadLimits.unlimited() untuk menonaktifkan semua batas ketika Anda sepenuhnya mempercayai sumbernya. AsposePdfException adalah kelas dasar untuk seluruh hierarki pengecualian (termasuk PdfIOException dan PdfSecurityException), sehingga satu except AsposePdfException dapat menangkap semua kesalahan yang diangkat oleh perpustakaan.


Tips dan Praktik Terbaik

  • Selalu panggil dispose() (atau close()) pada sebuah Document ketika Anda selesai menggunakannya, atau gunakan sebagai variabel lokal yang bersifat sementara — mesin menyimpan konten halaman yang telah didekode dan gambar dalam memori hingga dibuang.
  • Serahkan overwrite=True ke save() saat menulis ulang jalur yang sudah Anda buat dalam satu proses; nilai baku adalah False dan memicu FileExistsError.
  • Lebih pilih doc.optimize() sebelum mengirim PDF yang dihasilkan — itu adalah satu panggilan yang menghapus objek yang tidak terpakai dan mengompresi aliran, serta biasanya mengurangi ukuran output secara signifikan.
  • Atur kebijakan PdfLoadLimits secara eksplisit setiap kali Anda memuat PDF dari sumber yang tidak terpercaya (unggahan, lampiran email, penarikan web); nilai baku bersifat murah hati namun terbatas, bukan batas keamanan yang harus Anda percayai begitu saja.
  • Tangkap AsposePdfException (atau subclass spesifik seperti PdfSecurityException) di sekitar panggilan muat/simpan daripada Exception mentah — itu merupakan basis umum untuk setiap kesalahan yang dihasilkan perpustakaan.

Masalah Umum

MasalahPenyebabPerbaikan
FileExistsError pada save()Jalur tujuan sudah ada dan overwrite dibiarkan pada nilai default FalseLewati save(path, overwrite=True)
UnsupportedFeatureException pada save()Sebuah save_format non-PDF (misalnya SaveFormat.PPTX, DocFormat.HTML) dimintaSimpan sebagai PDF — nilai SaveFormat/DocFormat lain akan memicu UnsupportedFeatureException alih-alih menulis output
PdfSecurityException: Password required for encrypted documentMembuka PDF terenkripsi tanpa argumen passwordBerikan Document(path, password="...") atau panggil load_from(path, password="...")
Nomor halaman off-by-one antara PageCollection dan PdfFileEditordoc.pages[i] bersifat 0-based; argumen halaman PdfFileEditor.extract()/.insert() bersifat 1-basedTambah atau kurangi 1 saat mengonversi antara dua API tersebut
IndexError: Page index out of range. dari pages.delete()Indeks yang diberikan ke delete() tidak ada dalam koleksiPeriksa doc.page_count (atau len(doc.pages)) sebelum menghapus

FAQ

Apakah saya perlu lisensi untuk menggunakan Aspose.PDF FOSS untuk Python?

Tidak. Ini adalah edisi sumber terbuka (berlisensi MIT); tidak ada berkas lisensi atau langkah aktivasi yang harus dikonfigurasi.

Apakah saya dapat mengekspor Document ke format selain PDF?

Tidak dalam rilis ini. save() hanya mengimplementasikan output PDF — memberikan nilai SaveFormat/DocFormat lain akan memicu UnsupportedFeatureException alih-alih menghasilkan berkas yang salah label.

Apa perbedaan antara Document.merge() dan plugin Merger?

Document.merge() menggabungkan instance Document yang sudah Anda buka di memori. Merger (dengan MergeOptions dan FileDataSource) adalah pembungkus kenyamanan file-ke-file yang membuka, menggabungkan, dan menyimpan untuk Anda dalam satu panggilan — berguna untuk skrip batch sederhana yang tidak pernah memerlukan objek Document menengah.

Mengapa pages.insert() tidak pernah memunculkan kesalahan untuk indeks di luar jangkauan?

PageCollection.insert() menyesuaikan indeks ke dalam rentang yang valid (nilai negatif menjadi 0, nilai yang melewati akhir menjadi len(doc.pages)) alih-alih memunculkan kesalahan, sehingga penyisipan tidak pernah gagal semata-mata karena nilai indeks.

Bagaimana cara memuat PDF dengan aman dari sumber yang tidak tepercaya?

Buat sebuah PdfLoadLimits dengan batas eksplisit (max_input_bytes, max_pages, max_objects, dan seterusnya) dan berikan sebagai argumen limits= ke Document(...) atau load_from(). Setiap bidang sudah memiliki nilai default yang terbatas, tetapi memperketatnya sesuai ukuran input yang Anda harapkan mengurangi sumber daya yang dapat dikonsumsi oleh file yang rusak.


API Reference Ringkasan

Kelas / MetodeDeskripsi
Document() / Document.load_fromBuat dokumen kosong atau muat satu dari jalur, byte, atau aliran biner
Document.saveTuliskan dokumen ke jalur atau aliran yang dapat ditulis (hanya PDF)
Document.dispose() / Document.close()Lepaskan sumber daya mesin; idempotent
Document.pagesBagian PageCollection dokumen
Document.infoMetadata dokumen sebagai dict[str, str]
Document.optimize / Document.optimize_resources / Document.compress_streams()Hapus sumber daya yang tidak terpakai dan kompres aliran
Document.merge()Tambahkan instance Document lain ke yang ini
Document.encrypt / Document.decrypt / Document.change_passwordsTerapkan, hapus, atau putar kata sandi dokumen
Document.validate() / Document.check() / Document.repair()Periksa dan coba perbaiki integritas struktural
PageCollection.add() / .insert() / .delete() / .item()Edit koleksi halaman struktural (berbasis 0)
Page.rect / Page.rotation / Page.indexGeometri dan posisi per halaman
OptimizationOptionsFlag halus yang digunakan oleh Document.optimize
MergeOptions / MergerPlugin penggabungan file-ke-file
SplitOptions / SplitterPlugin pemisahan file-ke-file satu-halaman-per-output
FileDataSourceInput/output berbasis file untuk API plugin
PdfFileEditorFasad untuk concatenate(), extract(), insert(), delete(), append() (halaman berbasis 1)
PdfLoadLimitsKebijakan batas sumber daya yang tidak dapat diubah untuk input yang tidak tepercaya
AsposePdfExceptionKelas dasar untuk setiap pengecualian yang dilemparkan oleh perpustakaan
PdfSecurityExceptionDilempar untuk kata sandi yang hilang/salah dan kesalahan izin
PdfIOExceptionDilempar untuk kesalahan I/O selama pemrosesan PDF

Lihat Juga

 Bahasa Indonesia