Heim  >  Artikel  >  Backend-Entwicklung  >  Einfaches Teilen und Umbenennen von PDFs für Skyward

Einfaches Teilen und Umbenennen von PDFs für Skyward

王林
王林Original
2024-07-30 01:14:33778Durchsuche

Easily Split and Rename PDFs for Skyward

Warum es bauen und was macht es?

Vor ein paar Wochen forderte mich mein Vorgesetzter heraus, ob ich einen Arbeitsablauf für ein bestimmtes Problem entwickeln könnte, das wir hatten. Wir wollten Pre/ACT-Briefe in unser SMS (Student Management System) aufnehmen, in unserem Fall Skyward. Das Problem, auf das wir gestoßen sind, besteht darin, dass Pre/ACT-Briefe entweder in einer Massen-PDF-Datei oder als einzelne PDF-Datei vorliegen und wir für den Zugang zu Skyward eine PDF-Datei mit dem Namen jedes Schülers als ID-Nummer benötigen würden. Um dies zu erreichen, habe ich beschlossen, ein Programm in Python zu schreiben und Streamlit für die Benutzeroberfläche zu verwenden.

Sehen wir uns die Probleme an, die wir angehen müssen, beginnend mit dem PDF. Es war sinnvoller, nur den Massenexport der Briefe als Einzel-PDF zu übernehmen. Das bedeutete, dass wir den Massenexport in einzelne PDFs aufteilen mussten. Während jeder Buchstabe in der Regel zwei Seiten umfasst, ist dies nicht immer der Fall. Daher kann ein einfacher Umbruch auf jeder zweiten Seite wahrscheinlich fehleranfällig sein.

Das zweite Problem bestand darin, das PDF jedes Schülers zu lesen und es in die entsprechende ID-Nummer umzubenennen. Dies hing hauptsächlich von einem Regex-Muster ab, das das lieferte, was ich brauchte.

Da dies auch eine zeitliche Herausforderung war, arbeitete ich mit KI, um bei der Generierung des Codes zu helfen. HINWEIS: Dies ist kein Ersatz für die Kenntnis der von Ihnen verwendeten Logik und Sprache. Als ich dies mit AI/LLM geschrieben habe, habe ich den Ketten-von-Gedanken-Ansatz verwendet, indem ich mundgerechte Stücke von dem gegeben habe, was ich wollte, und dann jedes Stück debuggt und getestet habe, bevor ich weitere hinzugefügt habe. Der folgende Code ist der endgültige Code, der verwendet wurde. Ich werde jeden Abschnitt Abschnitt für Abschnitt aufschlüsseln. Wenn Sie dies als Lösung in Ihrem Distrikt implementieren möchten, sehen Sie sich die TLDR am Ende dieses Beitrags an.

Anforderungen und Importe

Dieser Teil ist ziemlich einfach und bildet die Grundlage, auf der das Programm läuft.

  • Streamlit für unsere Benutzeroberfläche
  • pypdf2, pymupdf und fitz für die PDF-Bearbeitung

Inhalt von „requirements.txt“

streamlit
pypdf2
fitz
pymupdf

Die app.py-Importe

import PyPDF2
import fitz  # PyMuPDF
import re
from pathlib import Path
import concurrent.futures
import streamlit as st
import shutil
import zipfile
import os

Ausweise finden

In diesem nächsten Codeausschnitt geht es darum, die IDs in der Massen-PDF-Datei zu finden und eine Liste von Seiten zu erstellen, die zu deren Aufteilung verwendet werden. Dies ist der Teil, der vom regulären Ausdruck abhängt und möglicherweise für Ihre Situation geändert werden muss.

def find_id_pages(input_pdf):
 doc = fitz.open(input_pdf)
 id_pages = []
 id_pattern = re.compile(r'\(ID#:\s*(\d+)\)')

    for i, page in enumerate(doc):
 text = page.get_text()
        if id_pattern.search(text):
 id_pages.append(i)

    return id_pages

Aufteilen der PDFs

Wie der Titel schon sagt, dient dies der Aufteilung der PDFs. Dabei wird eine Funktion zum Extrahieren der Namen für jedes einzelne PDF verwendet. Sie werden auch feststellen, dass sie dadurch parallel aufgeteilt werden, bis zu 10 gleichzeitig, um die Leistung zu verbessern.

def split_pdf(input_pdf, output_folder, progress_callback):
 input_path = Path(input_pdf)
 output_folder = Path(output_folder)
 output_folder.mkdir(parents=True, exist_ok=True)

    # Find pages with IDs
 id_pages = find_id_pages(input_pdf)

    if not id_pages:
 st.error("No ID pages found in the PDF.")
        return

 pdf_reader = PyPDF2.PdfReader(str(input_path))
 total_pages = len(pdf_reader.pages)
 temp_pdfs = []

    for i in range(len(id_pages)):
 start_page = id_pages[i]
 end_page = id_pages[i + 1] if i + 1 < len(id_pages) else total_pages

 pdf_writer = PyPDF2.PdfWriter()
        for j in range(start_page, end_page):
 pdf_writer.add_page(pdf_reader.pages[j])

 temp_pdf_path = output_folder / f'temp_{i}.pdf'
        with open(temp_pdf_path, 'wb') as output_pdf:
 pdf_writer.write(output_pdf)

 temp_pdfs.append(temp_pdf_path)
 progress_callback((i + 1) / len(id_pages))  # Update progress bar

    # Process renaming in parallel
    with concurrent.futures.ThreadPoolExecutor(max_workers=10) as executor:
 executor.map(lambda pdf_path: extract_and_rename_pdf(pdf_path, output_folder), temp_pdfs)
def extract_and_rename_pdf(pdf_path, output_folder):
 doc = fitz.open(pdf_path)
 text_first_page = doc[0].get_text()

    # Extract ID using a regex pattern for the format (ID#: 01234)
 match_first_page = re.search(r'\(ID#:\s*(\d+)\)', text_first_page)

    if match_first_page:
 id_value = match_first_page.group(1)
 new_pdf_path = output_folder / f'{id_value}.pdf'
 pdf_path.rename(new_pdf_path)
    else:
 new_pdf_path = output_folder / f'unknown_{pdf_path.stem}.pdf'
 pdf_path.rename(new_pdf_path)

Fast da

Als nächstes folgen ein paar kurze Funktionen, eine zum Komprimieren aller geteilten PDFs (falls Sie dies auf einem internen Server ausführen möchten) und eine zum Bereinigen aller temporären Dateien, damit keine personenbezogenen Daten von Schülern herumhängen es muss nicht leben.

def zip_output_folder(output_folder, zip_name):
 shutil.make_archive(zip_name, 'zip', output_folder)
def clean_up(output_folder, zip_name):
 shutil.rmtree(output_folder)
 os.remove(f"{zip_name}.zip")

Erstellen der Benutzeroberfläche

Der letzte Code ist für die Benutzeroberfläche. Streamlit ist eine WebUI für Vielseitigkeit (ja, Sie können es alleine ausführen). Nach ein paar Versuchen und unter Berücksichtigung der Benutzerfreundlichkeit. Um es einfach zu halten, habe ich es auf eine Schaltfläche zum Hochladen, eine Aktionsschaltfläche (z. B. Teilen) und eine Schaltfläche zum Herunterladen reduziert, um die komprimierten PDFs zu erhalten.

# Streamlit App Portion
st.title("PDF Splitter and Renamer")

uploaded_file = st.file_uploader("Choose a PDF file", type="pdf")
output_folder = "output_folder"

if st.button("Split and Rename PDF"):
    if uploaded_file and output_folder:
        try:
            # Save uploaded file temporarily
            with open("temp_input.pdf", "wb") as f:
 f.write(uploaded_file.getbuffer())

 progress_bar = st.progress(0)
            def update_progress(progress):
 progress_bar.progress(progress)

 split_pdf("temp_input.pdf", output_folder, update_progress)

 zip_name = "output_pdfs"
 zip_output_folder(output_folder, zip_name)
 st.success("PDF split and renamed successfully!")

            with open(f"{zip_name}.zip", "rb") as f:
 st.download_button(
                    label="Download ZIP",
                    data=f,
                    file_name=f"{zip_name}.zip",
                    mime="application/zip"
 )

            # Remove temporary file
 Path("temp_input.pdf").unlink()
 clean_up(output_folder, zip_name)
        except Exception as e:
 st.error(f"An error occurred: {e}")
    else:
 st.error("Please upload a PDF file and specify an output folder.")

TLDR, um loszulegen

Um alles zum Laufen zu bringen, verwenden Sie einfach die folgenden Befehle (dies setzt Linux, WSL und MacOS voraus). und Sie können die App erreichen, indem Sie zu http://localhost:8501 gehen.

git clone https://github.com/Blacknight318/act-to-sms.git
cd act-to-sms
python3 -m venv venv
source venv/bin/activate
pip install -r requirements.txt
streamlit run app.py

Abschließend

Wenn Sie eine K12-Schule besuchen, hoffe ich, dass Sie dies hilfreich finden. Wenn ja, klatschen Sie oder kaufen Sie mir einen Kaffee. Bis zum nächsten Mal, gute Winde und folgende Seegänge.

Das obige ist der detaillierte Inhalt vonEinfaches Teilen und Umbenennen von PDFs für Skyward. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!

Stellungnahme:
Der Inhalt dieses Artikels wird freiwillig von Internetnutzern beigesteuert und das Urheberrecht liegt beim ursprünglichen Autor. Diese Website übernimmt keine entsprechende rechtliche Verantwortung. Wenn Sie Inhalte finden, bei denen der Verdacht eines Plagiats oder einer Rechtsverletzung besteht, wenden Sie sich bitte an admin@php.cn
Vorheriger Artikel:Testabdeckungstools verstehenNächster Artikel:Testabdeckungstools verstehen