Leitfaden zur PDF-Verarbeitung
Überblick
Dieser Leitfaden behandelt grundlegende PDF-Verarbeitungsvorgänge mit Python-Bibliotheken.
Verwenden Sie das Werkzeug execute_code, um den unten gezeigten Python-Code auszuführen.
Alle generierten Dateien sollten im Verzeichnis artifacts/ gespeichert werden.
Schriftarteinstellung für Koreanisch (Erforderlich – in allen PDF-Erzeugungscodes enthalten)
Beim Erstellen von PDFs mit koreanischem Text muss zwingend eine koreanische Schriftart registriert werden. Fügen Sie den folgenden Schriftart-Registrierungscode ganz am Anfang jedes PDF-Erzeugungscodes ein.
Wichtig: Die Schriftart AppleSDGothicNeo.ttc unter macOS verwendet PostScript-Outlines und ist daher mit reportlab nicht kompatibel.
Schriftart-Priorität:
assets/NanumGothic-Regular.ttf(TTF-Datei – am zuverlässigsten)- CID-Schriftart
HYGothic-Medium(in reportlab enthalten – keine separate Datei erforderlich, zuverlässiger Fallback)
import os
from reportlab.pdfbase import pdfmetrics
from reportlab.pdfbase.ttfonts import TTFont
from reportlab.pdfbase.cidfonts import UnicodeCIDFont
def register_korean_font():
"""Registriert eine koreanische Schriftart und gibt den Schriftartnamen zurück. Muss vor der PDF-Erstellung aufgerufen werden."""
# 1. Priorität: NanumGothic TTF
ttf_paths = [
os.path.join("assets", "NanumGothic-Regular.ttf"),
"/usr/share/fonts/truetype/nanum/NanumGothic.ttf",
"/usr/share/fonts/nanum/NanumGothic.ttf",
"/Library/Fonts/NanumGothic.ttf",
]
for path in ttf_paths:
if os.path.exists(path):
try:
pdfmetrics.registerFont(TTFont("KoreanFont", path))
return "KoreanFont"
except Exception:
continue
# 2. Priorität: CID-Schriftart (in reportlab enthalten, keine separate Datei erforderlich)
try:
pdfmetrics.registerFont(UnicodeCIDFont("HYGothic-Medium"))
return "HYGothic-Medium"
except Exception:
pass
return "Helvetica" # Letzter Fallback (Koreanisch nicht unterstützt)
font_name = register_korean_font()
Erstellen neuer PDFs (reportlab)
Einfache PDF-Erstellung (nur Englisch)
from reportlab.lib.pagesizes import A4
from reportlab.pdfgen import canvas
import os
os.makedirs("artifacts", exist_ok=True)
c = canvas.Canvas("artifacts/hello.pdf", pagesize=A4)
width, height = A4
c.drawString(100, height - 100, "Hello World!")
c.save()
Koreanische PDF-Erstellung (empfohlenes Muster)
import os
from reportlab.lib.pagesizes import A4
from reportlab.lib.units import inch
from reportlab.lib import colors
from reportlab.platypus import SimpleDocTemplate, Paragraph, Spacer, PageBreak
from reportlab.lib.styles import getSampleStyleSheet, ParagraphStyle
from reportlab.pdfbase import pdfmetrics
from reportlab.pdfbase.ttfonts import TTFont
from reportlab.pdfbase.cidfonts import UnicodeCIDFont
# 1) Koreanische Schriftart registrieren
font_name = "Helvetica"
for path in [os.path.join("assets", "NamumGothic-Regular.ttf"),
"/usr/share/fonts/truetype/nanum/NanumGothic.ttf"]:
if os.path.exists(path):
try:
pdfmetrics.registerFont(TTFont("KoreanFont", path))
font_name = "KoreanFont"
break
except Exception:
continue
if font_name == "Helvetica":
try:
pdfmetrics.registerFont(UnicodeCIDFont("HYGothic-Medium"))
font_name = "HYGothic-Medium"
except Exception:
pass
# 2) Koreanische Stile definieren
styles = getSampleStyleSheet()
styles.add(ParagraphStyle("Title_KO", parent=styles["Title"], fontName=font_name, fontSize=20, spaceAfter=20, textColor=colors.HexColor("#1a1a2e")))
styles.add(ParagraphStyle("H1_KO", parent=styles["Heading1"], fontName=font_name, fontSize=16, spaceAfter=14, textColor=colors.HexColor("#16213e")))
styles.add(ParagraphStyle("H2_KO", parent=styles["Heading2"], fontName=font_name, fontSize=14, spaceAfter=12, textColor=colors.HexColor("#0f3460")))
styles.add(ParagraphStyle("Normal_KO", parent=styles["Normal"], fontName=font_name, fontSize=10, leading=14, spaceAfter=8))
styles.add(ParagraphStyle("Bullet_KO", parent=styles["Normal"], fontName=font_name, fontSize=10, leading=14, leftIndent=20, bulletIndent=10))
# 3) PDF erstellen
os.makedirs("artifacts", exist_ok=True)
doc = SimpleDocTemplate("artifacts/report.pdf", pagesize=A4,
topMargin=0.8*inch, bottomMargin=0.8*inch, leftMargin=0.75*inch, rightMargin=0.75*inch)
story = []
story.append(Paragraph("Berichtstitel", styles["Title_KO"]))
story.append(Spacer(1, 16))
story.append(Paragraph("1. Einleitung", styles["H1_KO"]))
story.append(Paragraph("Dieser Bericht enthält Beispielinhalte.", styles["Normal_KO"]))
story.append(Spacer(1, 8))
story.append(Paragraph("2. Detaillierte Inhalte", styles["H1_KO"]))
story.append(Paragraph("• Erster Punkt", styles["Bullet_KO"]))
story.append(Paragraph("• Zweiter Punkt", styles["Bullet_KO"]))
story.append(PageBreak())
story.append(Paragraph("3. Anhang", styles["H1_KO"]))
story.append(Paragraph("Dies sind zusätzliche Inhalte.", styles["Normal_KO"]))
doc.build(story)
print("PDF erstellt: artifacts/report.pdf")
Koreanische Tabelle in PDF
import os
from reportlab.lib.pagesizes import A4
from reportlab.platypus import SimpleDocTemplate, Table, TableStyle, Paragraph, Spacer
from reportlab.lib.styles import getSampleStyleSheet, ParagraphStyle
from reportlab.lib import colors
from reportlab.pdfbase import pdfmetrics
from reportlab.pdfbase.ttfonts import TTFont
from reportlab.pdfbase.cidfonts import UnicodeCIDFont
# Schriftart registrieren
font_name = "Helvetica"
for path in [os.path.join("assets", "NamumGothic-Regular.ttf"),
"/usr/share/fonts/truetype/nanum/NanumGothic.ttf"]:
if os.path.exists(path):
try:
pdfmetrics.registerFont(TTFont("KoreanFont", path))
font_name = "KoreanFont"
break
except Exception:
continue
if font_name == "Helvetica":
try:
pdfmetrics.registerFont(UnicodeCIDFont("HYGothic-Medium"))
font_name = "HYGothic-Medium"
except Exception:
pass
styles = getSampleStyleSheet()
styles.add(ParagraphStyle("Title_KO", parent=styles["Title"], fontName=font_name, fontSize=18, textColor=colors.HexColor("#1a1a2e")))
styles.add(ParagraphStyle("Normal_KO", parent=styles["Normal"], fontName=font_name, fontSize=10))
os.makedirs("artifacts", exist_ok=True)
doc = SimpleDocTemplate("artifacts/table_report.pdf", pagesize=A4)
data = [
["Posten", "Beschreibung", "Kosten"],
["Server", "EC2-Instanz", "$120"],
["Speicher", "S3-Bucket", "$45"],
["Datenbank", "RDS PostgreSQL", "$89"],
]
table = Table(data, colWidths=[120, 200, 80])
table.setStyle(TableStyle([
("BACKGROUND", (0, 0), (-1, 0), colors.HexColor("#e8eaf6")),
("TEXTCOLOR", (0, 0), (-1, 0), colors.HexColor("#1a1a2e")),
("FONTNAME", (0, 0), (-1, -1), font_name),
("FONTSIZE", (0, 0), (-1, -1), 10),
("GRID", (0, 0), (-1, -1), 0.5, colors.HexColor("#bdbdbd")),
("VALIGN", (0, 0), (-1, -1), "MIDDLE"),
("TOPPADDING", (0, 0), (-1, -1), 6),
("BOTTOMPADDING", (0, 0), (-1, -1), 6),
]))
doc.build([
Paragraph("Kostenanalyse-Bericht", styles["Title_KO"]),
Spacer(1, 16),
table
])
print("PDF erstellt: artifacts/table_report.pdf")
Wichtige Hinweise für reportlab
- Bei Verwendung koreanischen Texts muss der obige Schriftart-Registrierungscode unbedingt eingefügt werden.
- Die Schriftart
AppleSDGothicNeo.ttcunter macOS verwendet PostScript-Outlines und ist daher mit reportlab nicht kompatibel. Verwenden Sie sie auf keinen Fall. - Falls die TTF-Schriftart (
assets/NanumGothic-Regular.ttf) nicht verfügbar ist, verwenden Sie die CID-SchriftartHYGothic-Medium. - Ohne Schriftart-Registrierung wird koreanischer Text verstümmelt oder als leere Quadrate (□) dargestellt.
- Verwenden Sie NIE Unicode-Tief- oder Hochstellungszeichen (₀₁₂₃₄₅₆₇₈₉) in ReportLab-PDFs – verwenden Sie stattdessen die Tags
<sub>und<sup>.
Lesen von PDFs (pypdf)
Text extrahieren
from pypdf import PdfReader
reader = PdfReader("input.pdf")
text = ""
for page in reader.pages:
text += page.extract_text()
print(text)
PDFs zusammenführen
from pypdf import PdfWriter, PdfReader
writer = PdfWriter()
for pdf_file in ["doc1.pdf", "doc2.pdf"]:
reader = PdfReader(pdf_file)
for page in reader.pages:
writer.add_page(page)
with open("artifacts/merged.pdf", "wb") as output:
writer.write(output)
PDF aufteilen
from pypdf import PdfReader, PdfWriter
reader = PdfReader("input.pdf")
for i, page in enumerate(reader.pages):
writer = PdfWriter()
writer.add_page(page)
with open(f"artifacts/page_{i+1}.pdf", "wb") as output:
writer.write(output)
Seiten drehen
from pypdf import PdfReader, PdfWriter
reader = PdfReader("input.pdf")
writer = PdfWriter()
page = reader.pages[0]
page.rotate(90)
writer.add_page(page)
with open("artifacts/rotated.pdf", "wb") as output:
writer.write(output)
Passwortschutz
from pypdf import PdfReader, PdfWriter
reader = PdfReader("input.pdf")
writer = PdfWriter()
for page in reader.pages:
writer.add_page(page)
writer.encrypt("userpassword", "ownerpassword")
with open("artifacts/encrypted.pdf", "wb") as output:
writer.write(output)
Tabellenextraktion (pdfplumber)
import pdfplumber
with pdfplumber.open("input.pdf") as pdf:
for page in pdf.pages:
text = page.extract_text()
tables = page.extract_tables()
for table in tables:
for row in table:
print(row)
Kurzreferenz
| Aufgabe | Bibliothek | Wichtige Funktion |
|---|---|---|
| PDF erstellen | reportlab | SimpleDocTemplate / canvas |
| PDF lesen/zusammenführen/teilen | pypdf | PdfReader / PdfWriter |
| Tabellen extrahieren | pdfplumber | page.extract_tables() |
| Passwortschutz | pypdf | writer.encrypt() |
| Seiten drehen | pypdf | page.rotate() |