Ich benötigte für meine Arbeit eine PDF-Datei mit unterschiedlichen Seitengrößen (1. Seite ist A4, 2. Seite ist B5 usw.).
Auf den ersten Blick hatte ich kein Tool, mit dem ich für jede Seite eine PDF-Datei mit einer anderen Größe erstellen konnte, also habe ich es selbst mit Python gemacht.
Die verwendete Umgebung ist Windows 10 Home 1903 Ver.
PyPDF2 kann leere PDF-Seiten erstellen. Sie können jedoch kein Objekt wie Text oder Bild auf die erstellte Seite schreiben **.
ReportLab kann ein PDF mit Zeichen und Zahlen erstellen, die direkt aus dem Programmcode geschrieben wurden. ** (soweit ich sehen kann) Sie können jedoch nicht für jede Seite PDFs mit unterschiedlichen Seitengrößen erstellen **.
So grob
Nehmen Sie das Verfahren. Es ist ein bisschen nervig.
Dieses Mal möchte ich Seiten aller Größen gleichmäßig von A0 bis C10 einfügen (ich weiß, dass es C gibt, ich weiß es zum ersten Mal), also alle in "reportlab.lib.pagesizes" definierten Seitengrößen erhalten Sah.
testpdf_creator.py
import random
import os
from pathlib import Path
from tqdm import tqdm
from PyPDF2 import PdfFileReader, PdfFileWriter
from reportlab.pdfgen import canvas
from reportlab.pdfbase import pdfmetrics
from reportlab.pdfbase.ttfonts import TTFont
import reportlab.lib.pagesizes
YU_GOTHIC = Path(filter(lambda n: (Path(n) / "Fonts" / "YuGothB.ttc").exists(), os.environ.get("PATH").split(";")).__next__()) / "Fonts" / "YuGothB.ttc"
def makepage(writer, size, name):
A4 = reportlab.lib.pagesizes.A4
#Erstellen Sie ein PDF mit Text
c = canvas.Canvas("base.pdf", pagesize=A4)
pdfmetrics.registerFont(TTFont("YU", YU_GOTHIC))
c.setFont('YU', 20)
c.drawString(12, 12, f"This is {name} page.")
c.drawString(12, A4[1] - 50, f"This is {name} page.")
c.rect(0, 0, A4[0], A4[1])
c.showPage()
c.save()
# Create Page
with open("base.pdf", mode="rb") as f:
r = PdfFileReader(f)
p = writer.addBlankPage(size[0], size[1])
scale = [a / b for a, b in zip(size, A4)]
p.mergeTransformedPage(r.getPage(0), [scale[0], 0, 0 , scale[1], 0, 0] , True)
if __name__ == "__main__":
writer = PdfFileWriter()
sizes = list(filter(lambda n: type(eval(f'reportlab.lib.pagesizes.{n}')) == tuple, dir(reportlab.lib.pagesizes)))
s = random.sample(sizes, 10)
for n in tqdm(s):
makepage(writer, eval(f"reportlab.lib.pagesizes.{n}"), n)
with open("multisize.pdf", mode="wb") as f:
writer.write(f)
In ReportLab können Sie mithilfe der Klasse "Canvas" eine PDF-Datei erstellen. In der Leinwand, die hier erhältlich ist, ** ist unten links der Ursprung (X: 0 Y: 0) **. Seien Sie also beim Zeichnen der Figur vorsichtig.
Wenn Ihnen das nicht gefällt, fügen Sie dem Konstruktor der Canvas-Klasse bottomup = False
hinzu.
Die "Canvas" -Objektmethode "rect ()" verwendet einige Argumente nach den X-, Y-Koordinaten, der Höhe und der Breite wie folgt:
reportlab/pdfgen/canvas.py
def rect(self, x, y, width, height, stroke=1, fill=0):
"draws a rectangle with lower left corner at (x,y) and width and height as given."
Die Werte wie "storke" und "fill" dieses Arguments geben jedoch keine Werte wie Linienbreite und Farbe an, sondern sind boolesche Typen, ob gemalt werden soll oder nicht **.
Dies wird in Zeile 44 von reportlab / pdfgen / canvas.py
wie folgt beschrieben.
reportlab/pdfgen/canvas.py
PATH_OPS = {(0, 0, FILL_EVEN_ODD) : 'n', #no op
(0, 0, FILL_NON_ZERO) : 'n', #no op
(1, 0, FILL_EVEN_ODD) : 'S', #stroke only
(1, 0, FILL_NON_ZERO) : 'S', #stroke only
(0, 1, FILL_EVEN_ODD) : 'f*', #Fill only
(0, 1, FILL_NON_ZERO) : 'f', #Fill only
(1, 1, FILL_EVEN_ODD) : 'B*', #Stroke and Fill
(1, 1, FILL_NON_ZERO) : 'B', #Stroke and Fill
Die Methode "rect" bezieht sich auf diese Variable mit dem Namen "PATH_OPS", und die beiden Argumente "Stroke" und "Fill" scheinen den beiden Werten in diesem Array zu entsprechen.
mergeScalePage
von PyPDF2.PageObject
Verwenden Sie die Methode "PdfFileWriter # addBlankPage ()", um eine neue PDF-Seite mit "PyPDF2.PdfFileWriter" zu erstellen.
Wenn Sie hier ein anderes Seitenobjekt einfügen möchten, verwenden Sie "PageObject # merge *** Page ()".
Auf den ersten Blick scheint es so, als könnten Sie "mergeScaledPage ()" umgehen, indem Sie einfach die Skalierung ändern. Da "scale" dieser Methode jedoch nur einen Wert akzeptiert, kann sie nicht verwendet werden, wenn die vertikale und die horizontale Skalierung unterschiedlich sind.
Wenn die vertikale und horizontale Skalierung unterschiedlich sind, können Sie "mergeTransformedPage ()" verwenden. Das liegt daran, dass mergeScaledPage () nur mergeTransformedPage () mit der gleichen vertikalen und horizontalen Vergrößerung aufruft.
Wenn Sie die Vertikale auf 1,5x und die Horizontale auf 2x einstellen möchten, können Sie wie folgt vorgehen.
page.mergeTransformedPage('PageObject, das Sie hinzufügen möchten', [2, 0, 0 , 1.5, 0, 0] , True)
In reportlab / lib / pagesizes.py
wird das Tupel beschrieben, das die Werte aller Seitengrößen definiert, sodass dies durch die Funktion dir
erhalten wird.
Diese Datei definiert jedoch auch Funktionen wie "Portlait" und "Querformat", die die Höhe und Breite der Seite umkehren. Entfernen Sie sie daher mit der Funktion "Filter".
list(filter(lambda n: type(eval(f'reportlab.lib.pagesizes.{n}')) == tuple, dir(reportlab.lib.pagesizes)))
Recommended Posts