Fußzeilen in PDFs per Batch-Verarbeitung erstellen

Zusätz­li­che PDF-Tools machen es mög­lich, PDFs auch ohne Ado­be Acro­bat Pro zu bear­bei­ten. Die­ser Arti­kel stellt eine wei­te­re Lösung vor, über die sich Text in PDF-Datei­en ein­bau­en lässt, bei­spiels­wei­se für eine Fuß­zei­le.

Es gibt eini­ge Open-Source-Tools, mit denen sich PDFs bear­bei­ten las­sen. Eins davon ist die Biblio­thek pypdf (https://pypdf.readthedocs.io/en/latest/). Sie ermög­licht, PDF-Datei­en auf­zu­tei­len, zusam­men­zu­fü­gen oder umzu­wan­deln. Ein wei­te­res ist PyPDF­Form (https://chinapandaman.github.io/PyPDFForm/), mit dem sich PDF-For­mu­la­re aus­fül­len und For­mu­lar­fel­der ein­fü­gen las­sen. Mit bei­den zusam­men kann man Fuß­zei­len bezie­hungs­wei­se Text oder Bil­der an belie­bi­gen Posi­tio­nen in PDF-Datei­en ein­bau­en, was wir mit dem Kom­man­do­zei­len­tool pdf_text_inserter rea­li­siert haben. Das Python-Tool habe ich für Win­dows kom­pi­liert um die Ver­wen­dung so ein­fach wie mög­lich zu machen. Der Quell­text ist unten zu sehen. Dazu gibt es noch das gra­fi­sche Front­end pdf­Insert­Text, über das sich das Tool steu­ern lässt. Alter­na­tiv ver­wen­den Sie pdf_text_inserter unter Win­dows in einer Batch­da­tei.

Eine alter­na­ti­ve Lösung für Besit­zer von Ado­be Acro­bat Pro habe ich im Arti­kel „Ado­be Acro­bat Pro: Fuß­zei­len mit Java­script-Akti­on erstel­len“ vor­ge­stellt. Wer Fuß­zei­len über den kos­ten­lo­sen Acro­bat Rea­der in ein­zel­ne PDF-Datei­en ein­set­zen will, liest den Arti­kel „Ado­be Rea­der: Datei­na­men in PDF-Doku­men­ten auf jede Sei­te dru­cken“.

Down­load zu die­sem Arti­kel:
pdf­Insert­Text 1.1
Lizenz: GNU Les­ser Gene­ral Public Licen­se
86 Down­loads
Down­load zu die­sem Arti­kel:
pdf­Insert­Text Linux-Ver­si­on 1.1
Lizenz: GNU Les­ser Gene­ral Public Licen­se
Wenn nicht vor­han­den, bit­te unter Ubuntu/Linux Mint mit sudo apt install libgtk2.0–0 das feh­len­de Paket instal­lie­ren.
35 Down­loads

pdfInsertText konfigurieren und nutzen

Ent­pa­cken Sie das Archiv und star­ten Sie pdfInsertText.exe. In das Feld links oben kön­nen Sie PDF-Datei­en per Drag & Drop vom Datei­ma­na­ger aus hin­ein­zie­hen. Oder Sie ver­wen­den die Schalt­flä­che „Datei­en hin­zu­fü­gen“. Mit „Ord­ner hin­zu­fü­gen“ geben Sie einen Ord­ner an, aus dem alle PDF-Datei­en hin­zu­ge­fügt wer­den.

Kon­fi­gu­rie­ren Sie hin­ter „Aus­ga­be­ord­ner“ eine Ziel­ord­ner, in dem Sie die bear­bei­te­ten PDF-Datei spei­chern wol­len. Der Ord­ner soll­te leer sein. Alle ent­hal­te­nen PDF-Datei­en mit dem glei­chen Name wer­den ohne Rück­fra­ge über­schrie­ben, wenn ein Häk­chen vor „Datei­en im Aus­ga­be­ver­zeich­nis über­schrei­ben (Vor­sicht!)“ gesetzt ist. Andern­falls wer­den die Datei­en über­sprun­gen.

Hin­ter „Text für Fuß­zei­le“ geben Sie Tex­te ein, der in der Fuß­zei­le ent­hal­ten sein soll. Dar­un­ter kön­nen Sie Platz­hal­ter wäh­len, um bei­spiels­wei­se das Datum, den Datei­na­men oder Sei­ten­zah­len in den Fuß­zeil­en­text ein­zu­bau­en.

Mit den Ein­stel­lun­gen unter „Optio­nen“ ändern Sie das Ver­hal­ten des Tools. Ist „Nur ers­te Sei­te“ aktiv, wird die Fuß­zei­le nur ein die ers­te Sei­te ein­ge­setzt. Die ande­ren Optio­nen bestim­men das Aus­se­hen der Fuß­zei­le, bei­spiels­wei­se Schrift­grö­ße und Schrift­far­be (in Hex).

Intern las­sen sich die PDF-Stan­dard­fonts Font Hel­ve­ti­ca und Cou­rier ver­wen­den. Hel­ve­ti­ca ist der Stan­dard, Cou­rier kön­nen Sie hin­ter „Schrift­na­me“ ein­tra­gen. Für ande­re Schrift­ar­ten erwar­tet „Schrift­na­me“ den Datei­na­men einer ttf-Datei, die im Ord­ner „Tools\Fonts“ lie­gen muss.

Da PyPDF­Form kei­ne Opti­on für zen­trier­ten Text besitzt, muss die Brei­te des Tex­tes in der Fuß­zei­le berech­net wer­den. Der Stan­dard für „Lauf­wei­te“ ist „0.2“, was für den Font Hel­ve­ti­ca meist pas­sen soll­te. Wenn ande­re Fonts zu weit links oder rechts erschei­nen, ver­wen­den Sie einen ande­ren Wert, was Sie aus­pro­bie­ren müs­sen.

„Y‑Versatz“ und „X‑Versatz“ bestim­men die Posi­ti­on des Tex­tes auf der Sei­te. Das Koor­di­na­ten­sys­tem auf einer ein­zel­nen Sei­te einer PDF-Datei beginnt am lin­ken unte­ren Rand der Sei­te als Ursprung. Die Ein­heit der Koor­di­na­ten wird „Punk­te“ genannt und es gibt 72 Punkte/Zoll. PyPDF­Form nutzt die­ses Koor­di­na­ten­sys­tem in eini­gen sei­ner APIs, so dass Wid­gets, Tex­te oder Bil­der in einem PDF erstellt wer­den kön­nen. Der Stan­dard von pdf_text_inserter ist jeweils 30 Punk­te, wobei „X‑Versatz“ nur berück­sich­tigt wird, wenn bei „Aus­rich­tung“ etwas ande­res als „cen­ter“ (zen­triert) ein­ge­stellt ist. Über den Para­me­ter „Y‑Versatz“ lässt sich der Text auch am obe­ren Sei­ten­rand für eine Kopf­zei­le posi­tio­nie­ren.

Nach­dem alles kon­fi­gu­riert ist, kli­cken Sie auf „Start“. Die Datei­en mit den ein­ge­füg­ten Fuß­zei­len lie­gen danach im Aus­ga­be­ord­ner.

pdf_text_inserter für die Batch-Verarbeitung nutzen

Wenn Sie die Ver­ar­bei­tung von PDF-Datei­en auto­ma­ti­sie­ren wol­len, ver­wen­den Sie pdf_text_inserter.exe in einer Batch-Datei. Die mög­li­chen Para­me­ter sind die­se:

usa­ge: pdf_text_inserter.exe [-h] [-f FILENAME] [-o OUTFILENAME] [-t TEXT] [-s FONT_SIZE] [-c FONT_SCALE]
[-n FONT_NAME] [-l FONTCOLOR] [-y MARGIN_Y] [-x MARGIN_X] [-a {center,left,right}] [-p]
[-b]

opti­ons:
-h, –help show this help mes­sa­ge and exit
-f FILENAME PDF-Datei­na­me (erfor­der­lich)
-o OUTFILENAME Name der Aus­ga­be­da­tei (erfor­der­lich)
-t TEXT Fuß­zeil­en­text (erfor­der­lich)
-s FONT_SIZE Optio­nal: Schrift­grö­ße in pt
-c FONT_SCALE Optio­nal: Fak­tor für Font-Lauf­wei­te
-n FONT_NAME Optio­nal: Name der Font-Datei
-l FONTCOLOR Optio­nal: Schrift­far­be in Hex
-y MARGIN_Y Optio­nal: Y‑Versatz
-x MARGIN_X Optio­nal: X‑Versatz (not cen­te­red)
-a {center,left,right} Optio­nal: Text­aus­rich­tung
-p Optio­nal: Fuß­zei­le nur auf der ers­ten Sei­te
-b Kei­ne Far­ben im Ter­mi­nal

Eine Batch­da­tei kann so aus­se­hen (im Down­load-Archiv ent­hal­ten):

@echo off
setlocal enabledelayedexpansion
chcp 1252>nul
REM Verzeichnis mit Quelldateien
set SOURCE=In
REM Zielverzeichnis
set TARGET=OUT
REM Zieldateien überschreiben OVERWRITE=True
REM set OVERWRITE=False
set OVERWRITE=True
REM Datum
set dt=%DATE:~6,4%-%DATE:~3,2%-%DATE:~0,2%
REM Datum und Uhrzeit
REM dt=%DATE:~6,4%-%DATE:~3,2%-%DATE:~0,2%--%TIME:~0,2%-%TIME:~3,2%-%TIME:~6,2%
set dt=%dt: =0%

for %%a in (%SOURCE%\*.pdf) do (
REM Nur Dateiname
set TEXT=%%~nxa
REM Datum und Dateiname
REM set TEXT=%dt%-%%~nxa
REM Pfad und Dateiname der Quelldatei
REM set TEXT=%%~dpa%%~nxa
REM  echo %%~nxa

if %OVERWRITE%==False (
  if exist %TARGET%\%%~nxa (
   echo Zieldatei !TARGET!\%%~nxa bereits vorhanden
   ) else (
    REM call with source path and file name
    call :insert "%%~nxa"
   )
  ) else (
 REM Überschreiben
 REM call with file name
 call :insert "%%~nxa"
  )
REM end for
) 
goto :eof

:insert
echo Füge ein Fußzeile: %TEXT%
TOOLS\pdf_text_inserter.exe -b -f %SOURCE%\%~1 -o %TARGET%\%~1 -t %TEXT%
goto :eof

Python-Quellcode von pdf_text_inserter

import argparse
import sys
import os.path
from PyPDFForm import PdfWrapper
from pypdf import PdfReader

parser = argparse.ArgumentParser()
parser.add_argument("-f", dest="filename", help = "PDF-Dateiname (erforderlich)")
parser.add_argument("-o", dest="outfilename", help = "Name der Ausgabedatei (erforderlich)")
parser.add_argument("-t", dest="text", type=str, help = "Fußzeilentext (erforderlich)")
parser.add_argument("-s", dest="font_size", type=int, default=12, help = "Optional: Schriftgröße in pt")
parser.add_argument("-c", dest="font_scale", type=float, default=0.2, help = "Optional: Faktor für Font-Laufweite")
parser.add_argument("-n", dest="font_name", default="Helvetica", help = "Optional: Name der Font-Datei")
parser.add_argument("-l", dest="FontColor", default="000000", help = "Optional: Schriftfarbe in Hex")
parser.add_argument("-y", dest="margin_y", type=int, default=30, help = "Optional: Y-Versatz")
parser.add_argument("-x", dest="margin_x", type=int, default=30, help = "Optional: X-Versatz (not centered)")
parser.add_argument("-a", choices=["center","left","right"], default="center", dest="align", help = "Optional: Textausrichtung")
parser.add_argument("-p", dest="FirstPageOnly", action="store_true", default=False, help = "Optional: Fußzeile nur auf der ersten Seite")
parser.add_argument("-b", dest="NoColors", action="store_false", default=True, help = "Keine Farben im Terminal")
args=parser.parse_args()


if sys.platform == 'win32':
    os.system('color')

class bcolors:
    OKGREEN = "\033[92m"
    FAIL = "\033[91m"
    ENDC = "\033[0m"

if not (args.filename):
    print("")
    if args.NoColors:
        print ("Fehler: Name der PDF-Datei fehlt.")
    else:
        print (f"{bcolors.FAIL}Fehler: Name der PDF-Datei fehlt.{bcolors.ENDC}")

    print("")
    parser.print_help()
    sys.exit()

if not (args.outfilename):
    print("")
    if args.NoColors:
        print ("Fehler: Name der Ausgabedatei fehlt.")
    else:
        print (f"{bcolors.FAIL}Fehler: Name der Ausgabedatei fehlt.{bcolors.ENDC}")
    print("")
    parser.print_help()
    sys.exit()


if not (args.text):
    print("")
    if arg.NoColors:
        print ("Fehler: Text für die Fußzeile fehlt.")
    else:
        print (f"{bcolors.FAIL}Fehler: Text für die Fußzeile fehlt.{bcolors.ENDC}")
    print("")
    parser.print_help()
    sys.exit()


if not os.path.isfile(args.filename):
    if args.NoColors:
        print("Fehler: Datei " +args.filename + " ist nicht vorhanden.")
    else:
        print(f"{bcolors.FAIL}Fehler: Datei " +args.filename + " ist nicht vorhanden."+ f"{bcolors.ENDC}")
    sys.exit(1)

# convert font color hex to RGB
FontColor=tuple(int(args.FontColor[i:i+2], 16) for i in (0, 2, 4))


reader = PdfReader(args.filename)
number_of_pages = reader.get_num_pages()
print("Seitenanzahl: " + str(number_of_pages))
myText=args.text.replace('%%total-pages%%',str(number_of_pages))
if (args.font_name=="Helvetica"):
    myFont="Helvetica"
if (args.font_name=="Courier"):
    myFont="Courier"

if not (args.font_name =="Helvetica" or args.font_name =="Courier"):
    if not os.path.isfile('Tools/fonts/' +args.font_name):
        if args.NoColors:
            print("Fehler: Tools/fonts/" +args.font_name + " ist nicht vorhanden.")
        else:
            print(f"{bcolors.FAIL}Fehler: Tools/fonts/" +args.font_name + " ist nicht vorhanden."+ f"{bcolors.ENDC}")
        sys.exit(1)
    PdfWrapper.register_font("myFont", "Tools/fonts/" + args.font_name)
    pdf = PdfWrapper(args.filename,global_font="myFont")
    myFont="myFont"
else:
    pdf = PdfWrapper(args.filename)
if args.NoColors:
    print ("Verarbeite: " + args.filename)
else:
    print (f"{bcolors.OKGREEN}Verarbeite: " + args.filename +f"{bcolors.ENDC}")
pages=reader.pages
j=1
# Pages loop

for page in pages:
    aRect=page.cropbox
    myText=myText.replace('%%cur-page%%',str(j))
    myText_len=len(myText)
    # calculate text adjustment, factor font_scale depends on the used font
    if (args.align=="center"):
        new_text_pos=((aRect.width-30)/2)-(myText_len*(args.font_size*args.font_scale))
    if (args.align=="left"):
        new_text_pos=(args.margin_x)
    if (args.align=="right"):
        new_text_pos=(args.margin_x)
    
    pdf.draw_text(
        text=myText,
        page_number=j,
        x=new_text_pos,
        y=args.margin_y,
        font_size=args.font_size,
        font=myFont,    # optional
        font_color=FontColor # optional
    )
    print("Verarbeite Seite: " + str(j))


    if (args.FirstPageOnly==True):
        break
    j+=1

with open(args.outfilename, "wb+") as output:
     output.write(pdf.read())
if args.NoColors:
    print ("Fertig: Datei " + args.outfilename + " gespeichert.")
else:
    print (f"{bcolors.OKGREEN}Fertig: Datei " + args.outfilename + " gespeichert."+f"{bcolors.ENDC}")

[amazon_auto_links id="323980"]


Schlagwörter:


Kommentare

Schreibe einen Kommentar

Deine E-Mail-Adresse wird nicht veröffentlicht. Erforderliche Felder sind mit * markiert

This site uses Akismet to reduce spam. Learn how your comment data is processed.

Partner-Links

[amazon_auto_links id="323997"]

Neueste Kommentare

  1. Die digitale Abhängigkeit von Geräten wie dem Smartphone ist nicht mehr von der Hand zu weisen. Man soll am besten…

  2. Vielen herzlichen Dank für die Anleitung. Sie war äußerst hilfreich bei der Einrichtung meiner Fritzbox. Ich kann sie nur bestens…


Die Website durchsuchen