"Se um trabalhador quiser fazer bem o seu trabalho, ele deve primeiro afiar suas ferramentas." - Confúcio, "Os Analectos de Confúcio. Lu Linggong"
Primeira página > Programação > Divida e renomeie facilmente PDFs para Skyward

Divida e renomeie facilmente PDFs para Skyward

Publicado em 31/07/2024
Navegar:361

Easily Split and Rename PDFs for Skyward

Por que construí-lo e o que ele faz

Há algumas semanas, meu supervisor me desafiou para ver se eu conseguiria criar um fluxo de trabalho para um problema específico que estávamos enfrentando. Queríamos receber cartas Pré/ACT em nosso SMS (Student Management System), que no nosso caso era o Skyward. O problema que encontramos é que as cartas Pré/ACT estão em um PDF em massa ou em PDF individual e, para entrar no Skyward, precisaríamos ter um PDF para o nome de cada aluno como seu número de identificação. Para conseguir isso decidi escrever um programa em Python, usando Streamlit para a UI.

Vejamos os problemas que precisamos resolver, começando com o PDF. Fazia mais sentido apenas capturar a exportação em massa de PDF único das cartas, isso significava que precisávamos dividir a exportação em massa em PDFs individuais. Embora cada letra tenha normalmente 2 páginas, isso nem sempre é o caso, portanto, uma simples quebra em todas as outras páginas provavelmente estará sujeita a erros.

A segunda questão foi ler o PDF de cada aluno e renomeá-lo com o número de identificação correspondente. Isso dependia principalmente de um padrão Regex que extraía o que eu precisava.

Como esse também era um desafio de tempo, trabalhei com IA para ajudar a gerar o código. NOTA: Isso não substitui o conhecimento da lógica e da linguagem que você está usando. Ao escrever isso com AI/LLM, usei a abordagem de cadeia de pensamento, fornecendo pedaços pequenos do que eu queria e, em seguida, depurando e testando cada pedaço antes de adicionar mais. O código abaixo é o código final que foi usado. Vou dividir cada seção por seção. Se você deseja implementar isso como uma solução em seu distrito, consulte o TLDR no final desta postagem.

Requisitos e importações

Esta parte é bastante simples e é a base sobre a qual o programa é executado.

    Streamlit para nossa IU
  • pypdf2, pymupdf e fitz para manipulação de PDF
Conteúdo de requisitos.txt


streamlit pypdf2 fitz pymupdf
streamlit
pypdf2
fitz
pymupdf
As importações app.py


importar PyPDF2 importar fitz # PyMuPDF importar re do caminho de importação pathlib importar concurrent.futures importar streamlit como st importar Shutil importar arquivo zip importar sistema operacional
streamlit
pypdf2
fitz
pymupdf
Encontrando IDs

Este próximo trecho trata de encontrar os IDs no PDF em massa e criar uma lista de páginas a serem usadas para dividi-los. Esta é a parte que depende do regex e pode precisar ser alterada para sua situação.


def find_id_pages(input_pdf): doc=fitz.open(input_pdf) id_pages = [] id_pattern = re.compile(r'\(ID#:\s*(\d )\)') para i, página em enumerar (doc): texto = página.get_text() se id_pattern.search(texto): id_pages.append(i) retornar id_pages
streamlit
pypdf2
fitz
pymupdf
Dividindo os PDFs

Como o título diz, isso é usado para dividir os PDFs. Isso usará uma função para extrair os nomes de cada PDF individual. Você também notará que isso os divide em paralelo, até 10 por vez, para melhorar o desempenho.


def split_pdf(input_pdf, pasta_de_saída, progress_callback): input_path = Caminho(entrada_pdf) pasta_saída = Caminho(pasta_saída) output_folder.mkdir(parents=True, exist_ok=True) # Encontre páginas com IDs id_pages = find_id_pages(input_pdf) se não for id_pages: st.error("Nenhuma página de ID encontrada no PDF.") retornar pdf_reader = PyPDF2.PdfReader(str(caminho_de_entrada)) total_pages = len(pdf_reader.pages) temp_pdfs = [] para i no intervalo (len (id_pages)): página_inicial = id_páginas[i] end_page = id_pages[i 1] if i 1 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, pasta_de_saída): doc=fitz.open(caminho_pdf) text_first_page = doc[0].get_text() # Extraia o ID usando um padrão regex para o formato (ID#: 01234) match_first_page = re.search(r'\(ID#:\s*(\d )\)', text_first_page) se match_first_page: id_value = match_first_page.group(1) novo_pdf_path = pasta_de_saída / f'{id_value}.pdf' caminho_pdf.renomear(novo_caminho_pdf) outro: novo_pdf_path = pasta_de_saída / f'unknown_{pdf_path.stem}.pdf' caminho_pdf.renomear(novo_caminho_pdf)
streamlit
pypdf2
fitz
pymupdf
Quase lá

A seguir estão algumas funções curtas, uma para compactar todos os PDFs divididos (caso você queira executar isso em um servidor interno) e outra para limpar todos os arquivos temporários para que não haja informações PII dos alunos por aí. não precisa viver.


def zip_output_folder(output_folder, zip_name): shutil.make_archive(zip_name, 'zip', pasta_de_saída)
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 clean_up(pasta_de_saída, nome_zip):
 shutil.rmtree(pasta_de_saída)
 os.remove(f"{zip_name}.zip")
streamlit
pypdf2
fitz
pymupdf
Construindo a IU

O último pedaço de código é para a IU. Streamlit é uma WebUI versátil (sim, você pode executá-lo sozinho). Depois de algumas tentativas e considerando a usabilidade. Mantendo a simplicidade, reduzi-o a um botão de upload, um botão de ação (ou seja, divisão) e um botão de download para obter os PDFs compactados.


# Parte do aplicativo Streamlit st.title("Divisor e renomeador de PDF") uploaded_file = st.file_uploader("Escolha um arquivo PDF", type="pdf") pasta_saída = "pasta_saída" if st.button("Dividir e renomear PDF"): se upload_file e output_folder: tentar: # Salva o arquivo enviado temporariamente com open("temp_input.pdf", "wb") como f: f.write(uploaded_file.getbuffer()) barra_progresso = st.progress(0) def update_progress(progresso): progress_bar.progress(progresso) split_pdf("temp_input.pdf", pasta_de_saída, update_progress) zip_name = "saída_pdfs" zip_output_folder(pasta_de_saída, zip_name) st.success("PDF dividido e renomeado com sucesso!") com open(f"{zip_name}.zip", "rb") como f: st.download_button( label="Baixar ZIP", dados=f, nome_do_arquivo=f"{nome_zip}.zip", mime="aplicativo/zip" ) #Remove arquivo temporário Caminho("temp_input.pdf").unlink() clean_up(pasta_de_saída, nome_zip) exceto Exceção como e: st.error(f"Ocorreu um erro: {e}") outro: st.error("Por favor, carregue um arquivo PDF e especifique uma pasta de saída.")
streamlit
pypdf2
fitz
pymupdf
TLDR para começar a funcionar

Para colocar tudo em funcionamento, basta usar os seguintes comandos (isso pressupõe Linux, WSL e MacOS). e você poderá acessar o aplicativo acessando http://localhost:8501.


clone do git https://github.com/Blacknight318/act-to-sms.git cd ato-para-sms python3 -m venv venv origem venv/bin/ativar pip instalar -r requisitos.txt streamlit execute app.py
streamlit
pypdf2
fitz
pymupdf
No encerramento

Se você estiver em uma escola de ensino fundamental e médio, espero que isso seja útil. Se sim, bata palmas ou considere me pagar um café. Até a próxima, ventos favoráveis ​​e mar agitado.

Declaração de lançamento Este artigo foi reproduzido em: https://dev.to/blacknight318/easily-split-and-rename-pdfs-for-skyward-17ha?1 Se houver alguma violação, entre em contato com [email protected] para excluí-la
Tutorial mais recente Mais>

Isenção de responsabilidade: Todos os recursos fornecidos são parcialmente provenientes da Internet. Se houver qualquer violação de seus direitos autorais ou outros direitos e interesses, explique os motivos detalhados e forneça prova de direitos autorais ou direitos e interesses e envie-a para o e-mail: [email protected]. Nós cuidaremos disso para você o mais rápido possível.

Copyright© 2022 湘ICP备2022001581号-3