pdfdol.bundle#
Bundle several PDFs into one, with a contents page, per-document headers and bookmarks.
concat_pdfs just joins documents. bundle_pdf_bytes keeps track of which
page each document starts on while joining, which is what makes these possible:
toc: a contents page (several pages if needed) whose lines link to the documents’ first pages;doc_header: a band naming the document, added above its first page, so no content is covered;outline: one bookmark per document.
Rendering text uses reportlab, imported lazily: without toc and
doc_header, only pypdf is used.
>>> import io, pypdf
>>> def blank(n, w=200, h=300):
... writer = pypdf.PdfWriter()
... for _ in range(n):
... _ = writer.add_blank_page(width=w, height=h)
... buf = io.BytesIO(); _ = writer.write(buf); return buf.getvalue()
>>> out = bundle_pdf_bytes({'a.pdf': blank(2), 'b.pdf': blank(1)}, outline=True)
>>> reader = pypdf.PdfReader(io.BytesIO(out))
>>> len(reader.pages), [o.title for o in reader.outline]
(3, ['a.pdf', 'b.pdf'])
Module Attributes
Page sizes in points (1/72 inch), portrait. |
|
A contents renderer maps |
Functions
|
Extend |
|
Join PDFs, optionally adding a contents page, document headers and bookmarks. |
|
Put each page of |
|
Default |
|
Name (case-insensitive, see |
Classes
|
One document in a bundle. |
- class pdfdol.bundle.Entry(key, start_page, n_pages)[source]#
Bases:
NamedTupleOne document in a bundle.
start_pageis 1-based, in the final PDF.
- pdfdol.bundle.PAGE_SIZES = {'A3': (841.89, 1190.55), 'A4': (595.28, 841.89), 'A5': (419.53, 595.28), 'legal': (612.0, 1008.0), 'letter': (612.0, 792.0)}#
Page sizes in points (1/72 inch), portrait.
- pdfdol.bundle.TocRenderer#
A contents renderer maps
(entries, title)to the contents PDF bytes, or to(pdf_bytes, link_rects)wherelink_rects[i]is(toc_page_index, (x0, y0, x1, y1))for entryi, making that region a link to the entry’s first page.
- pdfdol.bundle.add_header_band(page, text, *, height=30, margin=36, font='Helvetica-Bold', font_size=9, gray=0.92)[source]#
Extend
pageupward byheightand drawtextin the new band (in place).- Return type:
- pdfdol.bundle.bundle_pdf_bytes(items, *, toc=False, doc_header=None, outline=False, title=None, toc_title='Contents', header_height=30)[source]#
Join PDFs, optionally adding a contents page, document headers and bookmarks.
- Parameters:
items (
Mapping|Iterable) –{key: pdf_bytes}or an iterable of(key, pdf_bytes), in order.toc (
bool|Callable[[list,str],Union[bytes,tuple]]) –Truefor the default contents page (render_contents_pdf), or aTocRenderercallable(entries, title) -> bytes | (bytes, link_rects).doc_header (
None|bool|str|Callable[[str],str]) – Text of the band added above each document’s first page.True-> the key; a format string using{key},{start_page},{n_pages}; or a callablekey -> str.outline (
bool) – Add one bookmark per document.title (
str|None) – PDF title metadata; also the contents page title iftoc_titleis left at its default.toc_title (
str) – Title of the contents page.header_height (
float) – Height in points of the header band.
- Return type:
>>> import io, pypdf >>> w = pypdf.PdfWriter(); _ = w.add_blank_page(width=200, height=300) >>> buf = io.BytesIO(); _ = w.write(buf); one = buf.getvalue() >>> out = bundle_pdf_bytes({'a.pdf': one, 'b.pdf': one}, toc=True, doc_header='{key}') >>> reader = pypdf.PdfReader(io.BytesIO(out)) >>> len(reader.pages) # 1 contents page + 2 documents 3 >>> float(reader.pages[1].mediabox.height) # 300 + header band 330.0
- pdfdol.bundle.fit_pdf_to_page(pdf_bytes, page_size='A4', *, margin=36, landscape_if_wider=True)[source]#
Put each page of
pdf_byteson apage_sizepage, scaled to fit and centered.A page wider than tall gets a landscape page when
landscape_if_wider.- Return type:
>>> import io, pypdf >>> w = pypdf.PdfWriter(); _ = w.add_blank_page(width=1000, height=500) >>> buf = io.BytesIO(); _ = w.write(buf) >>> out = fit_pdf_to_page(buf.getvalue(), 'A4') >>> [round(float(v)) for v in pypdf.PdfReader(io.BytesIO(out)).pages[0].mediabox[2:]] [842, 595]
- pdfdol.bundle.render_contents_pdf(entries, title='Contents', *, page_size='A4', margin=36, line_height=18, font='Helvetica', title_font='Helvetica-Bold', font_size=10, title_size=16)[source]#
Default
TocRenderer: a title, then one line per entry with its page range at right.Returns
(pdf_bytes, link_rects).- Return type: