”工欲善其事,必先利其器。“—孔子《论语.录灵公》
首页 > 编程 > 轻松拆分和重命名 Skyward 的 PDF

轻松拆分和重命名 Skyward 的 PDF

发布于2024-07-31
浏览:814

Easily Split and Rename PDFs for Skyward

为什么要建造它以及它有什么作用

几周前,我的主管给了我一个挑战,看看我是否可以针对我们遇到的特定问题提出一个工作流程。我们希望将 Pre/ACT 信件放入我们的 SMS(学生管理系统)中,在我们的例子中是 Skyward。我们遇到的问题是,Pre/ACT 信件要么是批量 PDF,要么是单独的 PDF,要进入 Skyward,我们需要每个学生的姓名作为 ID 号的 PDF。为了实现这一目标,我决定用 Python 编写一个程序,使用 Streamlit 作为 UI。

让我们从 PDF 开始看看我们需要解决的问题。获取信件的批量单个 PDF 导出更有意义,这意味着我们需要将批量导出拆分为单独的 PDF。虽然每个字母通常有 2 页,但情况并非总是如此,因此每隔一页进行简单的分隔可能很容易出错。

第二个问题是读取每个学生的PDF并将其重命名为相应的ID Number。这主要取决于满足我需要的正则表达式模式。

由于这也是一个时间挑战,我与人工智能一起帮助生成代码。注意:这并不能替代了解您正在使用的逻辑和语言。当使用 AI/LLM 编写本文时,我使用了思维链方法,给出了我想要的小块,然后在添加更多块之前调试和测试每个块。下面的代码是最终使用的代码,我将逐节分解每个代码。如果您希望将此作为您所在地区的解决方案实施,请参阅本文末尾的 TLDR。

要求和进口

这部分相当简单,是程序运行的基础。

  • 我们的 UI 的 Streamlit
  • 用于 PDF 操作的 pypdf2、pymupdf 和 fitz

requirements.txt内容

streamlit
pypdf2
fitz
pymupdf

app.py 导入

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

寻找ID

下一个代码片段涉及在批量 PDF 中查找 ID 并创建用于拆分它们的页面列表,这是取决于正则表达式的部分,可能需要根据您的情况进行更改。

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

分割 PDF

正如标题所说,这是用来分割PDF的。这将使用一个函数来提取每个 PDF 的名称。您还会注意到,这会将它们并行拆分(一次最多 10 个),以提高性能。

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 





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)

差不多了

接下来是几个简短的函数,一个用于压缩所有拆分的 PDF(如果您想在内部服务器上运行它),另一个用于清理任何临时文件,这样就不会出现 PII 学生信息了它不需要生存。

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

构建用户界面

最后一段代码是针对 UI 的。 Streamlit 是一个多功能的 WebUI(是的,您可以单独运行它)。经过几次尝试并考虑可用性。为了简单起见,我将其简化为上传按钮、操作按钮(即拆分)和下载按钮以获取压缩的 PDF。

# 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 启动并运行

要启动并运行,只需使用以下命令(假设是 Linux、WSL 和 MacOS)。您可以通过访问 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

结束语

如果您就读于 K12 学校,我希望这对您有所帮助。如果是这样,请鼓掌或考虑给我买杯咖啡。下次再见,顺风顺水。

版本声明 本文转载于:https://dev.to/blacknight318/easily-split-and-rename-pdfs-for-skyward-17ha?1如有侵犯,请联系[email protected]删除
最新教程 更多>
  • 如何在PDO中使用通配符安全地绑定像参数?
    如何在PDO中使用通配符安全地绑定像参数?
    在pDO In the query below, we're trying to bind the variable $partial% using PDO:select wrd from tablename WHERE wrd LIKE '$partial%'It'...
    编程 发布于2025-03-25
  • 哪种在JavaScript中声明多个变量的方法更可维护?
    哪种在JavaScript中声明多个变量的方法更可维护?
    在JavaScript中声明多个变量:探索两个方法在JavaScript中,开发人员经常遇到需要声明多个变量的需要。对此的两种常见方法是:在单独的行上声明每个变量: 当涉及性能时,这两种方法本质上都是等效的。但是,可维护性可能会有所不同。 第一个方法被认为更易于维护。每个声明都是其自己的语句,使其...
    编程 发布于2025-03-25
  • 如何将熊猫数据框中的逗号分隔字符串分为单独的行?
    如何将熊猫数据框中的逗号分隔字符串分为单独的行?
    在pandas dataframes中将comma-pandas dataframe strings拆分为单独的行使用series.explode()或dataframe.explode():将CSV字符串转换为列表:如果目标完全可以将CSV字符串转换为列表,则可以通过使用str.split()。...
    编程 发布于2025-03-25
  • 我可以将加密从McRypt迁移到OpenSSL,并使用OpenSSL迁移MCRYPT加密数据?
    我可以将加密从McRypt迁移到OpenSSL,并使用OpenSSL迁移MCRYPT加密数据?
    将我的加密库从mcrypt升级到openssl 问题:是否可以将我的加密库从McRypt升级到OpenSSL?如果是这样,如何?答案:是的,可以将您的Encryption库从McRypt升级到OpenSSL。可以使用openssl。附加说明: [openssl_decrypt()函数要求iv参...
    编程 发布于2025-03-25
  • 在使用JavaScript上传之前,如何验证文件大小?
    在使用JavaScript上传之前,如何验证文件大小?
    在使用javascript 解决方案:在上传之前,请访问以下代码:; //验证文件大小 如果(!file){ console.log(“未选择文件。”); } 别的 { console.log(“ file” file.name”是“ file.size”字节大小...
    编程 发布于2025-03-25
  • 在程序退出之前,我需要在C ++中明确删除堆的堆分配吗?
    在程序退出之前,我需要在C ++中明确删除堆的堆分配吗?
    在C中的显式删除 在C中的动态内存分配时,开发人员通常会想知道是否有必要在heap-procal extrable exit exit上进行手动调用“ delete”操作员,但开发人员通常会想知道是否需要手动调用“ delete”操作员。本文深入研究了这个主题。 在C主函数中,使用了动态分配变量(H...
    编程 发布于2025-03-25
  • 如何根据字典自定义大熊猫数据框列进行排序?
    如何根据字典自定义大熊猫数据框列进行排序?
    在pandas dataframes中自定义排序您的pandas dataframe带有包含月份名称的列。您想使用自定义词典进行对本列进行分类,例如: custom_dict = {'3月':0,'April':1,'dec':3} 将月列转换为类...
    编程 发布于2025-03-25
  • QT信号:何时使用DirectConnection与QueuedConnection?
    QT信号:何时使用DirectConnection与QueuedConnection?
    了解DirectConnection和queuedConnection之间的区别至关重要。这些连接类型控制了信号的发射和接收方式,尤其是在处理位于不同线程中的对象时。 DirectConnection 立即立即立即调用连接的插槽。这意味着插槽方法将在发射信号的对象的线程中执行。如果插槽方法不是线程...
    编程 发布于2025-03-25
  • 如何在Java中执行命令提示命令,包括目录更改,包括目录更改?
    如何在Java中执行命令提示命令,包括目录更改,包括目录更改?
    在java 通过Java通过Java运行命令命令可能很具有挑战性。尽管您可能会找到打开命令提示符的代码段,但他们通常缺乏更改目录并执行其他命令的能力。 solution:使用Java使用Java,使用processBuilder。这种方法允许您:启动一个过程,然后将其标准错误重定向到其标准输出。...
    编程 发布于2025-03-25
  • 如何在Java中正确显示“ DD/MM/YYYY HH:MM:SS.SS”格式的当前日期和时间?
    如何在Java中正确显示“ DD/MM/YYYY HH:MM:SS.SS”格式的当前日期和时间?
    如何在“ dd/mm/yyyy hh:mm:mm:ss.ss”格式“ gormat 解决方案: args)抛出异常{ 日历cal = calendar.getInstance(); SimpleDateFormat SDF =新的SimpleDateFormat(“...
    编程 发布于2025-03-25
  • 如何使用Depimal.parse()中的指数表示法中的数字?
    如何使用Depimal.parse()中的指数表示法中的数字?
    在尝试使用Decimal.parse(“ 1.2345e-02”中的指数符号表示法表示的字符串时,您可能会遇到错误。这是因为默认解析方法无法识别指数符号。 成功解析这样的字符串,您需要明确指定它代表浮点数。您可以使用numbersTyles.Float样式进行此操作,如下所示:[&& && && ...
    编程 发布于2025-03-25
  • 如何正确地施放T-SQL中的散装插入的变量?
    如何正确地施放T-SQL中的散装插入的变量?
    在t-sql 问题: 。[tstagingtable] - 来自n't:\ x.csv' - 这一行有效 来自@csvfile-此行失败 和 (( fieldTerminator =',', rowternator ='\ n', firstrow...
    编程 发布于2025-03-25
  • 如何使用Regex在PHP中有效地提取括号内的文本
    如何使用Regex在PHP中有效地提取括号内的文本
    php:在括号内提取文本在处理括号内的文本时,找到最有效的解决方案是必不可少的。一种方法是利用PHP的字符串操作函数,如下所示: 作为替代 $ text ='忽略除此之外的一切(text)'; preg_match('#((。 &&& [Regex使用模式来搜索特...
    编程 发布于2025-03-25
  • 如何配置Pytesseract以使用数字输出的单位数字识别?
    如何配置Pytesseract以使用数字输出的单位数字识别?
    Pytesseract OCR具有单位数字识别和仅数字约束 在pytesseract的上下文中,在配置tesseract以识别单位数字和限制单个数字和限制输出对数字可能会提出质疑。 To address this issue, we delve into the specifics of Te...
    编程 发布于2025-03-25
  • 什么是反应及其运作方式?
    什么是反应及其运作方式?
    React is a Javascript Library for building user interfaces. এখন দুটি জিনিস গুরুত্বপূর্ণ, একটি হলো Javascript Library, আরেকটি হলো user interfaces। Libr...
    编程 发布于2025-03-25

免责声明: 提供的所有资源部分来自互联网,如果有侵犯您的版权或其他权益,请说明详细缘由并提供版权或权益证明然后发到邮箱:[email protected] 我们会第一时间内为您处理。

Copyright© 2022 湘ICP备2022001581号-3