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

轻松拆分和重命名 Skyward 的 PDF

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

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]删除
最新教程 更多>
  • Python元类工作原理及类创建与定制
    Python元类工作原理及类创建与定制
    python中的metaclasses是什么? Metaclasses负责在Python中创建类对象。就像类创建实例一样,元类也创建类。他们提供了对类创建过程的控制层,允许自定义类行为和属性。在Python中理解类作为对象的概念,类是描述用于创建新实例或对象的蓝图的对象。这意味着类本身是使用类关...
    编程 发布于2025-04-18
  • 如何在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 解决方案:的,请访问量很大,并应为procectiquiestate的,并在整个代码上正确格式不多: java.text.simpledateformat; 导入java.util.calendar; 导入java...
    编程 发布于2025-04-18
  • 如何使用不同数量列的联合数据库表?
    如何使用不同数量列的联合数据库表?
    合并列数不同的表 当尝试合并列数不同的数据库表时,可能会遇到挑战。一种直接的方法是在列数较少的表中,为缺失的列追加空值。 例如,考虑两个表,表 A 和表 B,其中表 A 的列数多于表 B。为了合并这些表,同时处理表 B 中缺失的列,请按照以下步骤操作: 确定表 B 中缺失的列,并将它们添加到表的末...
    编程 发布于2025-04-18
  • Java中Lambda表达式为何需要“final”或“有效final”变量?
    Java中Lambda表达式为何需要“final”或“有效final”变量?
    Lambda Expressions Require "Final" or "Effectively Final" VariablesThe error message "Variable used in lambda expression shou...
    编程 发布于2025-04-18
  • Python读取CSV文件UnicodeDecodeError终极解决方法
    Python读取CSV文件UnicodeDecodeError终极解决方法
    在试图使用已内置的CSV模块读取Python中时,CSV文件中的Unicode Decode Decode Decode Decode decode Error读取,您可能会遇到错误的错误:无法解码字节 在位置2-3中:截断\ uxxxxxxxx逃脱当CSV文件包含特殊字符或Unicode的路径逃...
    编程 发布于2025-04-18
  • 如何简化PHP中的JSON解析以获取多维阵列?
    如何简化PHP中的JSON解析以获取多维阵列?
    php 试图在PHP中解析JSON数据的JSON可能具有挑战性,尤其是在处理多维数组时。 To simplify the process, it's recommended to parse the JSON as an array rather than an object.To do...
    编程 发布于2025-04-18
  • 为什么不````''{margin:0; }`始终删除CSS中的最高边距?
    为什么不````''{margin:0; }`始终删除CSS中的最高边距?
    在CSS 问题:不正确的代码: 全球范围将所有余量重置为零,如提供的代码所建议的,可能会导致意外的副作用。解决特定的保证金问题是更建议的。 例如,在提供的示例中,将以下代码添加到CSS中,将解决余量问题: body H1 { 保证金顶:-40px; } 此方法更精确,避免了由全局保证金重置引...
    编程 发布于2025-04-18
  • Python中何时用"try"而非"if"检测变量值?
    Python中何时用"try"而非"if"检测变量值?
    使用“ try“ vs.” if”来测试python 在python中的变量值,在某些情况下,您可能需要在处理之前检查变量是否具有值。在使用“如果”或“ try”构建体之间决定。“ if” constructs result = function() 如果结果: 对于结果: ...
    编程 发布于2025-04-18
  • Python中如何轻松将数据格式化为表格?
    Python中如何轻松将数据格式化为表格?
    在Python中为表格输出的格式化数据问题, [0,1,0], [2,4,2]]))所需的输出是一个表格名称为列的表,矩阵值为行: hotspur 012teams_list = ["Man Utd", &...
    编程 发布于2025-04-18
  • 哪种方法更有效地用于点 - 填点检测:射线跟踪或matplotlib \的路径contains_points?
    哪种方法更有效地用于点 - 填点检测:射线跟踪或matplotlib \的路径contains_points?
    在Python Matplotlib's path.contains_points FunctionMatplotlib's path.contains_points function employs a path object to represent the polygon.它...
    编程 发布于2025-04-18
  • 在Ubuntu/linux上安装mysql-python时,如何修复\“ mysql_config \”错误?
    在Ubuntu/linux上安装mysql-python时,如何修复\“ mysql_config \”错误?
    mysql-python安装错误:“ mysql_config找不到”“ 由于缺少MySQL开发库而出现此错误。解决此问题,建议在Ubuntu上使用该分发的存储库。使用以下命令安装Python-MysqldB: sudo apt-get安装python-mysqldb sudo pip in...
    编程 发布于2025-04-18
  • 如何使用“ JSON”软件包解析JSON阵列?
    如何使用“ JSON”软件包解析JSON阵列?
    parsing JSON与JSON软件包 QUALDALS:考虑以下go代码:字符串 } func main(){ datajson:=`[“ 1”,“ 2”,“ 3”]`` arr:= jsontype {} 摘要:= = json.unmarshal([] byte(...
    编程 发布于2025-04-18
  • 表单刷新后如何防止重复提交?
    表单刷新后如何防止重复提交?
    在Web开发中预防重复提交 在表格提交后刷新页面时,遇到重复提交的问题是常见的。要解决这个问题,请考虑以下方法: 想象一下具有这样的代码段,看起来像这样的代码段:)){ //数据库操作... 回声“操作完成”; 死(); } ?> ...
    编程 发布于2025-04-18
  • 为什么PHP的DateTime :: Modify('+1个月')会产生意外的结果?
    为什么PHP的DateTime :: Modify('+1个月')会产生意外的结果?
    使用php dateTime修改月份:发现预期的行为在使用PHP的DateTime类时,添加或减去几个月可能并不总是会产生预期的结果。正如文档所警告的那样,“当心”这些操作的“不像看起来那样直观。 ; $ date->修改('1个月'); //前进1个月 echo $ date->...
    编程 发布于2025-04-18
  • jQuery获取单选按钮组的值
    jQuery获取单选按钮组的值
    [2 本文提供了有关操纵单个按钮组的简洁jQuery代码段和答案。 [2 获取所选广播按钮值的最简单方法是: $('输入:无线​​电[名称=主题]:checked')。val(); 另外,如果您在选择时需要值: $('输入:无线​​电[name = theme]'...
    编程 发布于2025-04-18

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

Copyright© 2022 湘ICP备2022001581号-3