PyMuPDF
| Language | Python 3.11+ |
|---|---|
| License | AGPL-3.0 or commercial license from Artifex |
| Repository | github.com/pymupdf/PyMuPDF |
| Documentation | pymupdf.readthedocs.io, Document |
| Depends on | MuPDF (included in the wheels) |
| Read / write | yes / no (XPS and OpenXPS; writes PDF) |
PyMuPDF is the Python binding of MuPDF. It opens XPS (.xps) and OpenXPS (.oxps) with the same Document and Page classes as PDF, so code written for PDF works on XPS: page.get_text(), page.get_pixmap(), doc.get_toc(). Non-PDF documents are read-only, but doc.convert_to_pdf() turns them into a PDF you can edit and save.
Wheels for Windows, macOS and Linux include MuPDF, so there’s nothing else to install. License: AGPL-3.0; closed-source or network use needs a commercial license from Artifex.
Installation#
pip install pymupdf
Basic usage: convert XPS to PDF#
import pymupdf
with pymupdf.open("in.oxps") as doc: # .xps or .oxps
print(doc.metadata["format"], doc.page_count, "pages")
pdf_bytes = doc.convert_to_pdf()
with pymupdf.open("pdf", pdf_bytes) as pdf:
pdf.save("out.pdf", garbage=3, deflate=True)
Text, vector graphics and fonts stay as they are; links and the outline are copied as far as PDF supports them.
How to render XPS pages to PNG#
import pymupdf
with pymupdf.open("in.xps") as doc:
for page in doc:
pix = page.get_pixmap(dpi=150)
pix.save(f"page-{page.number + 1:03d}.png")
How to extract text from an XPS file#
import pymupdf
with pymupdf.open("in.xps") as doc:
for page in doc:
print(page.get_text()) # plain text in reading order
For positions, page.get_text("words") returns (x0, y0, x1, y1, word, block, line, word_no) tuples in points (1/72 inch).
How to read the outline (bookmarks)#
import pymupdf
with pymupdf.open("in.xps") as doc:
for level, title, page_no in doc.get_toc():
print(" " * (level - 1) + f"{title} (page {page_no})")
The outline comes from the XPS DocStructure part; files from “Print to XPS” usually have none.
How to get page sizes#
with pymupdf.open("in.xps") as doc:
for page in doc:
r = page.rect # points
print(page.number + 1, r.width, r.height, "pt =",
r.width * 96 / 72, r.height * 96 / 72, "XPS units")
Tips#
- Open XPS data from memory with
pymupdf.open(stream=data, filetype="xps"). doc.metadatahas only the format for XPS files; readdocProps/core.xmlfrom the ZIP withzipfilefor the title and author.- The older import name
fitzstill works, butimport pymupdfis the current one.