Rumah  >  Artikel  >  pembangunan bahagian belakang  >  Pisahkan dan Namakan semula PDF untuk Skyward dengan mudah

Pisahkan dan Namakan semula PDF untuk Skyward dengan mudah

王林
王林asal
2024-07-30 01:14:33771semak imbas

Easily Split and Rename PDFs for Skyward

Mengapa membinanya dan apa yang dilakukannya

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.

Keperluan dan Import

Bahagian ini agak mudah dan merupakan asas program dijalankan.

  • Strim untuk UI kami
  • pypdf2, pymupdf dan fitz untuk manipulasi PDF

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

Mencari ID

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

Membahagikan PDF

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)

hampir sampai

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")

Membina UI

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.")

TLDR untuk bangkit dan berlari

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

Dalam Penutup

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!

Kenyataan:
Kandungan artikel ini disumbangkan secara sukarela oleh netizen, dan hak cipta adalah milik pengarang asal. Laman web ini tidak memikul tanggungjawab undang-undang yang sepadan. Jika anda menemui sebarang kandungan yang disyaki plagiarisme atau pelanggaran, sila hubungi admin@php.cn
Artikel sebelumnya:Memahami alat liputan ujianArtikel seterusnya:Memahami alat liputan ujian