Beberapa minggu lalu penyelia saya memberi saya cabaran untuk melihat sama ada saya boleh menghasilkan aliran kerja untuk masalah tertentu yang kami hadapi. Kami ingin memasukkan surat Pra/ACT ke dalam SMS (Sistem Pengurusan Pelajar), yang dalam kes kami ialah Skyward. Masalah yang kami hadapi ialah huruf Pra/ACT adalah sama ada dalam PDF pukal atau setiap PDF individu, dan untuk masuk ke Skyward, kami perlu mempunyai PDF untuk setiap nama pelajar sebagai nombor ID mereka. Untuk mencapainya, saya memutuskan untuk menulis program dalam Python, menggunakan Streamlit untuk UI.
Mari kita lihat masalah yang perlu kita tangani, bermula dengan PDF. Lebih masuk akal hanya untuk merebut eksport PDF tunggal pukal surat, ini bermakna kami perlu membahagikan eksport pukal kepada PDF individu. Walaupun setiap huruf biasanya 2 halaman yang tidak selalu berlaku, jadi pemecahan mudah setiap halaman lain mungkin terdedah kepada ralat.
Isu kedua ialah membaca PDF setiap pelajar dan menamakannya kepada Nombor ID yang sepadan. Ini kebanyakannya bergantung pada corak Regex yang menarik apa yang saya perlukan.
Memandangkan ini juga merupakan cabaran masa, saya bekerja dengan AI untuk membantu menjana kod. NOTA: Ini bukan pengganti untuk mengetahui logik dan bahasa yang anda gunakan. Semasa menulis ini dengan AI/LLM, saya menggunakan pendekatan rantaian pemikiran, memberikan potongan bersaiz gigitan daripada apa yang saya mahukan, dan kemudian menyahpepijat dan menguji setiap bahagian sebelum menambah lagi. Kod di bawah adalah kod akhir yang digunakan, saya akan memecahkan setiap bahagian mengikut bahagian. Jika anda ingin melaksanakan ini sebagai penyelesaian di daerah anda lihat TLDR adalah penghujung siaran ini.
Bahagian ini agak mudah dan merupakan asas program dijalankan.
Kandungan keperluan.txt
streamlit pypdf2 fitz pymupdf
App.py mengimport
import PyPDF2 import fitz # PyMuPDF import re from pathlib import Path import concurrent.futures import streamlit as st import shutil import zipfile import os
Coretan seterusnya ini berurusan dengan mencari ID dalam PDF pukal dan membuat senarai halaman untuk digunakan untuk memisahkannya, ini adalah bahagian yang bergantung pada regex dan mungkin perlu diubah untuk situasi anda.
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
Seperti tajuknya, ini digunakan untuk memisahkan PDF. Ini akan menggunakan fungsi untuk mengekstrak nama untuk setiap PDF individu. Anda juga akan melihat bahawa ini membahagikannya secara selari, sehingga 10 pada satu masa, untuk meningkatkan prestasi.
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)
Seterusnya ialah beberapa fungsi pendek, satu untuk mengezip semua PDF yang dipecahkan (sekiranya anda ingin menjalankan ini pada pelayan dalaman), dan satu untuk membersihkan mana-mana fail temp supaya tiada maklumat pelajar PII tergantung di mana-mana ia tidak perlu hidup.
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")
Bit terakhir kod adalah untuk UI. Streamlit ialah WebUI untuk serba boleh (ya anda boleh menjalankannya secara solo). Selepas beberapa percubaan dan mempertimbangkan kebolehgunaan. Untuk memastikannya mudah, saya menyaringnya kepada butang muat naik, butang tindakan (iaitu pemisahan) dan butang muat turun untuk mendapatkan PDF yang dizipkan.
# 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.")
Untuk menyiapkan dan menjalankannya, hanya gunakan arahan berikut (ini mengandaikan Linux, WSL dan MacOS). dan anda akan dapat mencapai apl itu dengan pergi ke http://localhost:8501.
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
Jika anda berada di sekolah K12, saya harap anda akan mendapati ini berguna. Jika begitu bertepuk tangan atau pertimbangkan untuk membeli saya kopi. Sehingga lain kali, angin kencang dan laut mengikuti.
Atas ialah kandungan terperinci Pisahkan dan Namakan semula PDF untuk Skyward dengan mudah. Untuk maklumat lanjut, sila ikut artikel berkaitan lain di laman web China PHP!