Heim >Backend-Entwicklung >Python-Tutorial >Einfaches Teilen und Umbenennen von PDFs für Skyward
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.
Dieser Teil ist ziemlich einfach und bildet die Grundlage, auf der das Programm läuft.
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
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
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)
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")
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.")
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
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!