Skip to content

Latest commit

 

History

History
455 lines (350 loc) · 11.2 KB

File metadata and controls

455 lines (350 loc) · 11.2 KB

API Quick Reference

A condensed view of every public function in exis_pdfeditor (v4.5.8+). For full parameter docs see the PyPI page or the package README.


Initialization

import exis_pdfeditor

# Trial (14 days, no key required)
exis_pdfeditor.initialize()

# Licensed
exis_pdfeditor.initialize("XXXX-XXXX-XXXX-XXXX")

# Or via environment variable
# export EXIS_PDF_LICENSE_KEY=XXXX-XXXX-XXXX-XXXX

Inspect / triage — license-free

info = exis_pdfeditor.inspect("file.pdf")
# -> info.version, info.pageCount, info.title, info.author, info.producer,
#    info.isEncrypted, info.hasFormFields, info.formFieldCount,
#    info.fontsUsed, info.pages[]

dump = exis_pdfeditor.dump_structure("file.pdf")
# -> dump.totalObjects, dump.streamObjectCount, dump.isEncrypted, ...

pages = exis_pdfeditor.analyze_pages("file.pdf")
# -> pages[].pageNumber, .kind (Digital|Scanned|AlreadyOcrd|Empty),
#    .textCharCount, .textCoverageRatio, .imageCoverageRatio,
#    .hasInvisibleTextLayer

Text extraction

result = exis_pdfeditor.extract_text("file.pdf")
# -> result.fullText, result.pages[].text

result = exis_pdfeditor.extract_text("file.pdf", pages=[1, 3])

structured = exis_pdfeditor.extract_text_structured("file.pdf")
# -> structured.pages[].textBlocks[].x, .y, .fontName, .fontSize, .text

Find & Replace (digital / embedded text)

# Single
exis_pdfeditor.find_replace("in.pdf", "out.pdf", "old", "new")

# Multiple pairs
exis_pdfeditor.find_replace("in.pdf", "out.pdf", pairs=[
    {"search": "{{NAME}}", "replace": "John"},
    {"search": "{{DATE}}", "replace": "2026-04-07"},
])

# Regex
exis_pdfeditor.find_replace("in.pdf", "out.pdf", pairs=[
    {"search": r"\d{3}-\d{2}-\d{4}", "replace": "[SSN]", "isRegex": True},
])

# Multi-line wrap (\\n in replace string when wrap="explicit")
exis_pdfeditor.find_replace(
    "in.pdf", "out.pdf",
    "Short label", "Longer label that\nwraps to two lines",
    wrap="explicit",          # auto | explicit | off
    max_lines=3,
    line_spacing=1.2,
)

# All options
exis_pdfeditor.find_replace(
    "in.pdf", "out.pdf",
    "find", "replace",
    case_sensitive=False,
    whole_word=True,
    use_regex=False,
    page_range=[1, 2, 3],
    text_fitting="adaptive",   # none | preserve_width | fit_to_page | adaptive
    min_horizontal_scale=70,
    max_font_size_reduction=1.5,
    replacement_text_color={"r": 1, "g": 0, "b": 0},
    replacement_highlight_color={"r": 1, "g": 1, "b": 0},
    replacement_bold=True,
    replacement_underline=False,
    replacement_strikethrough=False,
    preserve_form_fields=True,
    use_incremental_update=True,
    wrap="auto",
    max_lines=None,
    line_spacing=None,
)

Merge / Split / Bookmarks / Extract

exis_pdfeditor.merge(["a.pdf", "b.pdf", "c.pdf"], "merged.pdf")

# One file per page
result = exis_pdfeditor.split("doc.pdf", "out_dir/")
# -> result.pageCount, result.files[]

# Split by outline / TOC
result = exis_pdfeditor.split(
    "book.pdf", "chapters/",
    by_bookmarks=True,
    prefix="ch_",
    max_depth=1,
    number_names=False,
)
# -> result.sectionCount, result.sections[].title, .startPage, .endPage, .file

toc = exis_pdfeditor.bookmarks("doc.pdf")
# -> toc.count, toc.bookmarks[].title, .level, .startPage

exis_pdfeditor.extract_pages("doc.pdf", "subset.pdf", pages=[1, 3, 5])

Forms

fields = exis_pdfeditor.list_fields("form.pdf")
# -> field.name, .displayName, .type, .value, .options,
#    .isReadOnly, .hasDuplicateWidgets

# Per-widget names for duplicate widgets (two-up / carbon copies)
fields = exis_pdfeditor.list_fields("form.pdf", split_duplicate_widgets=True)
# e.g. Address_1, Address_2

exis_pdfeditor.fill_form(
    "form.pdf", "filled.pdf",
    fields={"FirstName": "John", "Email": "j@example.com"},
    flatten=True,                 # optional - lock values into page content
    text_alignment="center",      # auto | left | center | right
    split_duplicate_widgets=False,
)

# Signature *image* fields (not PKCS#7 digital sign — see Signatures below)
sig_fields = exis_pdfeditor.list_signature_fields("contract.pdf")
exis_pdfeditor.fill_signature(
    "contract.pdf", "signed_image.pdf",
    image_path="signature.png",
    field="Signature1",
    scale="fit",                  # fit | stretch
    halign="Center",              # Left | Center | Right
    valign="Middle",              # Bottom | Middle | Top
    padding=2.0,
    flatten=True,
)

Redaction

exis_pdfeditor.redact("doc.pdf", "redacted.pdf", redactions=[
    {"text": "John Doe", "replaceWith": "[NAME]"},
    {"text": r"\d{3}-\d{2}-\d{4}", "isRegex": True, "replaceWith": "[SSN]"},
    {"area": {"x": 100, "y": 700, "width": 200, "height": 20}, "pageNumber": 1},
])

Region erase / replace

Erase content inside a rectangle, or paint an image/text over it.

exis_pdfeditor.erase_region(
    "page.pdf", "erased.pdf",
    page=1,
    rect=(72, 400, 200, 40),      # x, y, w, h  (or dict / "x,y,w,h")
    match="inside",               # inside | intersects
    keep_text=False,
    keep_images=False,
    keep_paths=False,
)

exis_pdfeditor.replace_region(
    "page.pdf", "patched.pdf",
    page=1,
    rect={"x": 72, "y": 400, "width": 200, "height": 40},
    image="logo.png",
    image_scale="fit",            # fit | stretch | natural
    background="#FFFFFF",
    text="ACME Corp",
    font_size=12,
    align="center",               # left | center | right
    valign="middle",              # top | middle | bottom
)

Vector (outlined) text & graphics

Use these when text/logos are drawn as paths (not selectable digital text). find_replace will not match them.

# List outline clusters (blob recognizer — works in the Python wheel)
hits = exis_pdfeditor.find_vector_text("outlined.pdf", ocr="none")
# optional: pages=[1], language="en", render_scale=2.0

# Phrase replace needs a real OCR engine (Tesseract/Windows/Apple).
# The AOT CLI bundled in the wheel only ships ocr="none", which cannot
# match --find text. For production outlined-text replace, call the
# .NET API with Exis.PdfOcr, or expect the CLI to raise.
# exis_pdfeditor.replace_vector_text(
#     "in.pdf", "out.pdf", find="ACME", replace="Contoso",
#     ocr="tesseract", mode="outlines", align="auto",
#     fit="shrink", wrap="auto",
# )

# Vector-drawn logos / icons
graphics = exis_pdfeditor.find_vector_graphics(
    "branded.pdf",
    thumbnails_dir="thumbs/",     # writes graphic-{index}.png
    min_size=8.0,
)
# -> graphics[].index, .pageNumber, bounds, ...

exis_pdfeditor.replace_vector_graphic(
    "branded.pdf", "rebranded.pdf",
    image_path="new-logo.png",
    index=graphics[0].index,      # int or list of indices
    scale="fit",                  # fit | stretch | natural
)

Watermark / Stamp

exis_pdfeditor.watermark("in.pdf", "out.pdf", "DRAFT")

exis_pdfeditor.watermark("in.pdf", "out.pdf", "CONFIDENTIAL",
    position="across",     # top | bottom | center | across
    font_size=72,
    text_color={"r": 1, "g": 0, "b": 0},
    opacity=0.15,
    page_range=[1, 2],
)

exis_pdfeditor.stamp("in.pdf", "out.pdf", "letterhead.pdf",
    mode="overlay",        # overlay | underlay
    opacity=1.0,
    page_range=[1],
)

Bates stamp

exis_pdfeditor.bates_stamp(
    "in.pdf", "out.pdf",
    prefix="ABC",
    digits=6,
    start_number=1,
    # see README for confidentiality line, positions, page_range, etc.
)

Optimize

exis_pdfeditor.optimize("in.pdf", "out.pdf")

exis_pdfeditor.optimize("in.pdf", "out.pdf",
    downsample_images=True,
    max_image_dpi=150,
    remove_metadata=True,
)

Encrypt / Decrypt

exis_pdfeditor.encrypt("in.pdf", "out.pdf",
    user_password="openme",
    owner_password="secret",
    permissions=["Print", "CopyText"],
    # Available: Print, ModifyContents, CopyText, AddAnnotations,
    #            FillForms, PrintHighQuality, All
)

exis_pdfeditor.decrypt("in.pdf", "out.pdf", password="openme")

Page editing

exis_pdfeditor.rotate("in.pdf", "out.pdf", angle=90)
exis_pdfeditor.rotate("in.pdf", "out.pdf", angle=180, pages=[2, 4])

exis_pdfeditor.crop("in.pdf", "out.pdf",
    rect={"x": 50, "y": 50, "width": 500, "height": 700},
)

exis_pdfeditor.reorder("in.pdf", "out.pdf", order=[3, 1, 2])

exis_pdfeditor.delete_pages("in.pdf", "out.pdf", pages=[2, 4])

exis_pdfeditor.insert_blank_pages(
    "in.pdf", "out.pdf",
    insertions=[{"afterPage": 1, "count": 2}],
)

Images

result = exis_pdfeditor.find_images("doc.pdf")
# -> result.totalImages, result.images[].index, .pixelWidth, .pixelHeight,
#    .colorSpace, .format, .pageNumbers

# Save extracted images to disk
exis_pdfeditor.find_images("doc.pdf", output_dir="extracted/")

# Replace all images
exis_pdfeditor.replace_image("doc.pdf", "out.pdf", "new_logo.png")

# Replace specific images by index, scoped to a page
exis_pdfeditor.replace_image("doc.pdf", "out.pdf", "new_logo.jpg",
    image_indices=[0, 2],
    page_range=[1],
    scale_mode="scale_to_fit",
    # match_original_size | preserve_aspect_ratio | scale_to_fit
)

Digital signatures (PKCS#7 / PFX)

exis_pdfeditor.sign("in.pdf", "out.pdf",
    cert_path="cert.pfx",
    cert_password="certpass",
    reason="Approved",
    location="New York, NY",
    signer_name="John Doe",
)

# Visible signature box
exis_pdfeditor.sign("in.pdf", "out.pdf",
    cert_path="cert.pfx",
    cert_password="certpass",
    visible=True,
    page=1,
    rect={"x": 50, "y": 50, "width": 200, "height": 60},
)

# Verify
sig = exis_pdfeditor.verify("signed.pdf")
# -> sig.isSigned, sig.signerName, sig.isValid, sig.reason, sig.signDate

# Multi-signature
all_sigs = exis_pdfeditor.verify("signed.pdf", all_signatures=True)

PDF/A

result = exis_pdfeditor.pdfa_validate("doc.pdf", level="2b")
# Levels: 1b | 2b | 2u | 3b | 3u
# -> result.isCompliant, result.violations[].code, .message, .canAutoFix

exis_pdfeditor.pdfa_convert("doc.pdf", "archive.pdf", level="2b")

Metadata (XMP + /Info)

meta = exis_pdfeditor.get_metadata("doc.pdf")

exis_pdfeditor.set_xmp("in.pdf", "out.pdf", xmp_path="meta.xmp")
exis_pdfeditor.set_info("in.pdf", "out.pdf", info={
    "title": "Report",
    "author": "Exis",
})

exis_pdfeditor.remove_xmp("in.pdf", "out.pdf")
exis_pdfeditor.remove_info("in.pdf", "out.pdf")
exis_pdfeditor.remove_metadata("in.pdf", "out.pdf")  # both

OCR — Windows only

Raises OcrNotSupportedError on Linux/macOS wheels.

exis_pdfeditor.make_searchable_pdf(
    "scan.pdf", "searchable.pdf",
    languages=["eng"],
    dpi=300,
)

exis_pdfeditor.redact_scanned_pdf(
    "scan.pdf", "redacted.pdf",
    terms=["John Doe", "SSN"],
    visible_replacement="[REDACTED]",
)

Licensing summary

Tier Behavior
Free (no init) inspect(), analyze_pages(), pdfa_validate(), dump_structure()
Trial (init with no key) All features, 14 days
Licensed (init with key) All features, no expiry
Evaluation (after trial) All features but limited to 3 pages per document

Purchase: pdfbatcheditor.com/developers — $499 / developer / year.