Durchnummerieren konkatenierter PDFs

Wenn du dir nicht sicher bist, in welchem der anderen Foren du die Frage stellen sollst, dann bist du hier im Forum für allgemeine Fragen sicher richtig.
Antworten
tobias.billen
User
Beiträge: 5
Registriert: Montag 30. Juli 2018, 14:47

Hallo zusammen,

mir ist bewusst, dass man Code Snippets klein halten sollte, allerdings ist dieser Code durch diverses googlen und auch nutzen von ChatGPT zustanden gekommen. Ich möchte gerne diverse PDF-Files von einem FTP-Server laden, diese dann miteinander kontaktieren und dann mit einem Deckblatt voran wieder als neue PDF auf den FTP-Server hochladen. Dies funktioniert auch ohne Probleme.

Nun möchte ich dieses konkatenierte PDF durchnummerieren. Dazu soll im Fuß der PDF der Text "Seite x von y" ausgegeben werden, ob x die aktuelle Seitenanzahl repräsentiert und y die maximale Seitenanzahl.

Hierzu habe ich mir diese Snippet genommen. Dies wird korrekt getriggert (Daher habe ich diesen Print Befehl), allerdings fehlt das Drucken des Footers auf die PDF:

Code: Alles auswählen

text_object = _canvas.beginText(page_width - 50, 50)  # Anpassen der Koordinaten
text_object.setFont(font_name, font_size)  # Schriftart und -größe festlegen
text_object.textLine(f"Seite {page_number} von {total_pages}")
_canvas.drawText(text_object)
print("Count should be printed")

Ich habe hier das Script (gekürzt) gepostet, damit man das Vorgehen nachvollziehen kann. Ich weiß selbst, dass ich noch kommentieren muss. Die deutschen Kommentare sind aus ChatGPT, die englischen sind meine Kommentierungen. Ich habe bewusst meine Imports stehen gelassen, da dies bereits zu Missverständnissen mit ChatGPT geführt hat.

Ich hoffe, ihr könnt mir einen Tipp geben, wo mein Fehler ist. Wichtig ist, dass die PDFs, die ich durchnummeriere, bereits vorhanden sind und, dass sie "unten" (Das untere Vietel) komplett weiß sind.

Viele Grüße und Glückauf aus dem Pott

Tobias

Code: Alles auswählen

import base64
import io

import PyPDF2
# import canvas
from PIL.Image import Image
from PyPDF2 import PdfWriter
from PyPDF2 import PdfReader
from reportlab.lib import colors, pagesizes
from reportlab.lib.enums import TA_LEFT
from reportlab.lib.pagesizes import letter, portrait
from reportlab.lib.styles import ParagraphStyle, getSampleStyleSheet
from reportlab.lib.units import inch
from reportlab.pdfbase import pdfmetrics
from reportlab.pdfbase.ttfonts import TTFont
from reportlab.pdfgen import canvas
from reportlab.platypus import SimpleDocTemplate, Paragraph, KeepTogether, Spacer, Image, Table, TableStyle
from six import BytesIO

import Query as query
from CreateDocument import wrap_text
from DB import DB
from FTP import FTP
from pdf import letterhead, arial, arial_bold
from send_mail import send_mail


def set_footer_content(image_base64, name, items):
  [...]


def get_page_number_canvas():
    """
    
    :return: 
    """
    packet = io.BytesIO()
    pdf_canvas = canvas.Canvas(packet, pagesize=letter)  # Use the renamed variable
    return packet, pdf_canvas


def add_page_number(page, page_number, total_pages, _canvas):
    """
    
    :param page: 
    :param page_number: 
    :param total_pages: 
    :param _canvas: 
    :return: 
    """
    page_width, page_height = portrait(letter)  # Ändern Sie portrait(letter) für Hochformat

    # Schriftart und -größe für die Seitenzahl festlegen
    pdfmetrics.registerFont(TTFont("Arial", arial))  # Pfade anpassen
    font_name = "Arial"
    font_size = 12

    text_object = _canvas.beginText(page_width - 50, 50)  # Anpassen der Koordinaten
    text_object.setFont(font_name, font_size)  # Schriftart und -größe festlegen
    text_object.textLine(f"Seite {page_number} von {total_pages}")
    _canvas.drawText(text_object)
    print("Count should be printed")




def is_page_blank(page) -> bool:
    [...]


class JoinPDF:
    def __init__(self, equipment, con_db, con_ftp):
        [...]

    def create_pdf(self, item_per_page=4):
       [...]

    def set_footer(self):
       [...]

    def set_text(self, msg, font_size=12, font_name="Arial", alignment=1, space_before=0, space_after=10,
                 text_color="black", bold=False):
    [...]

    def set_header(self, data, coloring=True):
        [...]

    def convert_header(self) -> []:
       [...]

    def set_foreword(self):
      [...]

    # Create the PDF by adding header, anlage-pdf and footer
    def get_pdfs(self):
        total_pages = 0  # Initialize a counter for total pages

        """Header"""
        self.set_foreword()
        buffer = io.BytesIO()
        self.output.write(buffer)
        pdf_bytes = buffer.getvalue()
        self.pdf_list.append(pdf_bytes)

        # Increment the total pages by the number of pages in the header PDF
        total_pages += len(PdfReader(io.BytesIO(pdf_bytes)).pages)

        """PDFs for concatenating"""
        for pdf in self.db.select(query=query.get_anlage_pdf_by_equipment(self.equipment)):
            res = base64.b64decode(self.ftp.get_pdf_by_path(pdf[2])["pdf"])
            self.pdf_list.append(res)

            # Increment the total pages by the number of pages in each Anlage PDF
            total_pages += len(PdfReader(io.BytesIO(res)).pages)

        """Footer"""
        self.elems.clear()
        self.output = PdfWriter()

        for pdf_bytes in self.pdf_list:
            pdf_reader = PdfReader(io.BytesIO(pdf_bytes))
            for page_number, page in enumerate(pdf_reader.pages):
                packet, page_canvas = get_page_number_canvas()
                add_page_number(page_canvas, page_number + 1, total_pages, page_canvas)
                new_page = page_canvas.showPage()  # Create a new page with the page number
                if new_page is not None:
                    page.add_transformation(new_page)

    def create_new_pdf(self):
        """

        :return:
        """
        pdf_writer = PdfWriter()
        err = 0
        for pdf_bytes in self.pdf_list:
            try:
                pdf_reader = PyPDF2.PdfReader(io.BytesIO(pdf_bytes))
                for page_number, page in enumerate(pdf_reader.pages):
                    if not is_page_blank(page):
                        pdf_writer.add_page(page)
            [...]
        pdf_writer.write(self.output_b64)

    def get_b64(self) -> str:
        """Create pdf as base64"""
        self.output_b64.seek(0)
        return base64.b64encode(self.output_b64.read()).decode()

Sirius3
User
Beiträge: 18272
Registriert: Sonntag 21. Oktober 2012, 17:20

Es ist immer schwierig, hier maschinell erzeugten Code zu redigieren, den die Auftraggeber selbst nicht verstehen.
JoinPDF ist keine Klasse, auch wenn sie in dieses Konstrukt gepresst worden ist.
create_new_pdf benutzt aus der Klasse nur pdf_list, get_b64 nur output_b64, zwei Funktionen, die nichts miteinander zu tun haben, die Klasse ist nur eine Lagerstätte für globale Variablen, um den Input und Output der Funktionen zu verschleiern.
In `get_pdfs` liest Du ständig PDF-Dateien nur im die Anzahl der Seiten zu ermitteln.
Das Aufteilen in Funktionen ist auch seltsam und macht es schwierig, die Teile einzeln zu testen.

Als erstes mußt Du die einzelnen Funktionen sauber identifizieren; eine Funktion hat klaren Input und Output und eine Aufgabe.

Eine Funktion, die ein Deckblatt erzeugt und ein Pdf-Objekt zurückgibt.
Eine Funktionen, die ein Pdf mit den Seitennummern erzeugt und ein Pdf-Objekt zurückgibt.
Eine Funktion, die die viele Pdf-Objekte nimmt und ein gemergtes Pdf-Objekt zurückgibt.
Eine Funktion, die ein Pdf mit dem Seitennummernpdf zusammenbringt.
Antworten