mit ReportLab versuche ich, ein PDF-Dokument mit Bookmarks und Seitenzahlen zu erzeugen, leider bekomme ich es nicht zum Laufen. Entweder die Bookmarks funktionieren oder die Seitenzahlen, beides jedoch nicht in Kombination. Hier mein aktueller Code als einfaches lauffähiges Beispiel:
Code: Alles auswählen
from reportlab.pdfgen import canvas
from reportlab.lib.pagesizes import A4
from reportlab.platypus import SimpleDocTemplate, Paragraph, Spacer, PageBreak, Flowable
from reportlab.lib.styles import getSampleStyleSheet
from reportlab.lib.units import inch
from reportlab.lib.pagesizes import letter
from reportlab.lib import colors
from reportlab.lib.units import mm
class NumberedBookmarkCanvas(canvas.Canvas):
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
self._saved_page_states = []
self._bookmarks = []
self._current_page = 0
def showPage(self):
# Speichern des aktuellen Seitenstatus und wechseln zur neuen Seite
self._saved_page_states.append(dict(self.__dict__))
self._current_page += 1
self._startPage()
def save(self):
num_pages = len(self._saved_page_states)
for state in self._saved_page_states:
self.__dict__.update(state)
self.draw_page_number(num_pages)
canvas.Canvas.showPage(self)
self.add_bookmarks()
canvas.Canvas.save(self)
def draw_page_number(self, page_count):
self.setFont("Helvetica", 8)
self.drawRightString(190*mm, 10*mm, f"Page {self._pageNumber} / {page_count}")
def add_bookmarks(self):
for title, name in self._bookmarks:
self.addOutlineEntry(title, name, level=0, closed=False)
def add_bookmark(self, title, name):
self._bookmarks.append((title, name))
class LinkFlowable(Flowable):
def __init__(self, text, target):
super().__init__()
self.text = text
self.target = target
self.width = 0
self.height = 0
def wrap(self, availWidth, availHeight):
from reportlab.pdfbase.pdfmetrics import stringWidth
self.width = stringWidth(self.text, "Helvetica", 10)
self.height = 10
return self.width, self.height
def draw(self):
self.canv.setFont("Helvetica", 10)
self.canv.drawString(100, 0, self.text)
self.canv.linkRect(
"",
self.target,
(100, 0, 100 + self.width, 10),
relative=1
)
class BookmarkFlowable(Flowable):
def __init__(self, name, title, level=0):
super().__init__()
self.name = name
self.title = title
self.level = level
def wrap(self, availWidth, availHeight):
return 0, 0
def draw(self):
self.canv.bookmarkPage(self.name)
self.canv.add_bookmark(self.title, self.name)
def create_pdf_with_multibuild(filename):
doc = SimpleDocTemplate(filename, pagesize=A4)
story = []
styles = getSampleStyleSheet()
def prepare_story():
# Titelseite
story.append(Paragraph("Titelseite:", styles["Normal"]))
story.append(Spacer(1, 12))
story.append(PageBreak())
# Kapitel 1
story.append(Paragraph("Kapitel 1: Einleitung", styles["Heading1"]))
story.append(BookmarkFlowable("chapter1", "Kapitel 1: Einleitung"))
story.append(LinkFlowable("Gehe zu Kapitel 2", "chapter2"))
story.append(Spacer(1, 12))
story.append(LinkFlowable("Gehe zu Kapitel 3", "chapter3"))
story.append(Spacer(1, 12))
# Kapitel 2
story.append(PageBreak())
story.append(BookmarkFlowable("chapter2", "Kapitel 2: Details"))
story.append(Paragraph("Kapitel 2: Details", styles["Heading1"]))
story.append(Spacer(1, 12))
story.append(Paragraph("Hier ist der Inhalt von Kapitel 2.", styles["Normal"]))
# Kapitel 3
story.append(PageBreak())
story.append(BookmarkFlowable("chapter3", "Kapitel 3: Weitere Details"))
story.append(Paragraph("Kapitel 3: Weitere Details", styles["Heading1"]))
story.append(Spacer(1, 12))
story.append(Paragraph("Hier ist der Inhalt von Kapitel 3.", styles["Normal"]))
prepare_story()
doc.multiBuild(story, canvasmaker=NumberedBookmarkCanvas)
create_pdf_with_multibuild("interactive_links_and_bookmarks_with_numbered_canvas.pdf")
Bitte helft mir

Vielen Dank schonmal,
Dominik