J'avais besoin d'un fichier PDF avec différentes tailles de page pour mon travail (1ère page est A4, 2ème page est B5, etc.).
À première vue, je n'avais pas d'outil capable de créer un fichier PDF avec une taille différente pour chaque page, alors je l'ai fait moi-même avec Python.
L'environnement utilisé est Windows 10 Home 1903 Ver.
PyPDF2 peut créer des pages PDF vides. Cependant, vous ne pouvez écrire aucun objet tel que du texte ou une image sur la page créée **.
ReportLab peut créer un PDF avec des caractères et des chiffres écrits directement à partir du code du programme. Cependant, ** (pour autant que je sache) vous ne pouvez pas créer de PDF avec des tailles de page différentes pour chaque page **.
Donc à peu près
Suivez la procédure. C'est un peu ennuyeux.
Cette fois, je veux insérer des pages de toutes tailles uniformément de A0 à C10 (je sais qu'il y a C, je sais pour la première fois), alors obtenez toutes les tailles de page définies dans reportlab.lib.pagesizes
Vu.
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
#Créer un PDF avec du texte
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)
Dans ReportLab, vous pouvez créer un fichier PDF en utilisant la classe Canvas
.
Cependant, dans le canevas qui peut être obtenu ici, ** le coin inférieur gauche est l'origine (X: 0 Y: 0) **, donc soyez prudent lorsque vous dessinez la figure.
Si vous n'aimez pas cela, ajoutez bottomup = False
au constructeur de la classe Canvas
.
La méthode objet Canvas
rect ()` prend quelques arguments après les coordonnées X, Y, la hauteur et la largeur, comme suit:
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."
Cependant, les valeurs telles que storke
et fill
de cet argument n'indiquent pas de valeurs telles que la largeur de ligne et la couleur, mais sont des types booléens de peinture ou non **.
Il y a la description suivante à la ligne 44 de reportlab / pdfgen / canvas.py
.
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
La méthode rect
fait référence à cette variable appelée PATH_OPS
, et les deux arguments stroke
et fill
semblent correspondre aux deux valeurs de ce tableau.
mergeScalePage
of PyPDF2.PageObject
Pour créer une nouvelle page au format PDF avec PyPDF2.PdfFileWriter
, utilisez la méthode PdfFileWriter # addBlankPage ()
.
Si vous voulez coller un autre objet de page ici, utilisez PageObject # merge *** Page ()
.
À première vue, il semble que vous puissiez contourner mergeScaledPage ()
simplement en changeant l'échelle, mais comme scale
de cette méthode n'accepte qu'une seule valeur, elle ne peut pas être utilisée lorsque les échelles verticale et horizontale sont différentes.
Si les échelles verticale et horizontale sont différentes, vous pouvez utiliser mergeTransformedPage ()
. C'est parce que mergeScaledPage ()
appelle simplement mergeTransformedPage ()
avec les mêmes agrandissements vertical et horizontal.
Si vous souhaitez définir la verticale sur 1,5x et l'horizontale sur 2x, vous pouvez procéder comme suit.
page.mergeTransformedPage('PageObject que vous souhaitez ajouter', [2, 0, 0 , 1.5, 0, 0] , True)
Dans reportlab / lib / pagesizes.py
, le tuple qui définit les valeurs de toutes les tailles de page est décrit, donc ceci est obtenu par la fonction dir
.
Cependant, ce fichier définit également des fonctions telles que portlait
et landscape
qui inversent la hauteur et la largeur de la page, supprimez-les donc avec la fonction filter
.
list(filter(lambda n: type(eval(f'reportlab.lib.pagesizes.{n}')) == tuple, dir(reportlab.lib.pagesizes)))
Recommended Posts