智能 Uber 发票 PDF 合并工具

embedded/2024/12/21 21:06:57/

在现代商务出行中,尤其是在跨国出差中,处理和整合大量 Uber 发票已成为一项不小的挑战。手动整理和合并这些发票不仅耗时,还容易出错。作为开发者,为什么不开发一个自动化工具,将这些任务交给代码来完成呢?在这篇博客中,我将带你一步步构建一个结合 PyQt5pdfplumberPyPDF2 的智能 Uber 发票合并工具,不仅能自动提取数据,还能动态显示进度条,给用户带来极佳的使用体验。

项目亮点:

  • PyQt5 GUI 界面:基于 PyQt5 实现的可视化界面,简洁大方。
  • 自动提取发票数据:利用 pdfplumber 自动提取 Uber 发票中的日期、金额、地点等信息,支持多语言(中文、英文、西班牙语)。
  • PDF 合并功能:通过 PyPDF2 实现多份 PDF 发票的自动合并,并且生成一份总结页,显示所有行程的详细信息。
  • 动态进度条:实时显示合并进度,让用户一目了然处理状态。

1. 项目简介

本项目的主要目的是通过图形化用户界面(GUI)和后端的 PDF 处理技术,自动处理 Uber 发票,自动从 PDF 中提取关键信息,并合并成一个包含详细摘要的 PDF 文件。这样的工具对于经常出差、需要整理大量发票的用户来说,是一个非常实用的助手。

2. 使用技术栈

在开发过程中,我们使用了以下的技术栈:

  • PyQt5:用于创建用户界面,让用户可以轻松选择文件夹、选择语言以及合并 PDF 文件。
  • pdfplumber:用于从 Uber 发票 PDF 中提取文本和行程信息,支持多语言。
  • PyPDF2:用于将多个 PDF 文件合并成一个,同时在合并前生成一份包含所有行程数据的总结页。
  • ReportLab:用于生成总结页的 PDF 文件,方便将表格数据导出。

3. 代码实现

3.1 主窗口的设计与初始化

我们通过 QMainWindow 创建了主窗口,并初始化了必要的组件,比如上传文件按钮、合并按钮、进度条等。我们还为窗口添加了一个版权信息,并通过 setWindowIcon 方法设置了应用的图标。

class MainWindow(QMainWindow):def __init__(self):super(MainWindow, self).__init__()self.ui = Ui_MainWindow()  # 创建UI对象self.ui.setupUi(self)  # 调用setupUi方法,构建界面# 初始化进度条self.ui.progressBar.setValue(0)  # 初始化进度条值为 0# 设置窗口的图标(logo)self.setWindowIcon(QIcon('logo.png'))  # 替换为你的 logo 文件路径# 设置窗口标题self.setWindowTitle("Uber Pdf Merge")  # 设置自定义窗口标题# 添加版权信息self.add_copyright_label()# 其他初始化代码...
3.2 自动提取 Uber 发票中的行程数据

在这一部分中,pdfplumber 被用于提取每一张发票中的行程信息,包括日期、金额、起始地点和目的地。我们通过不同的正则表达式来处理不同语言的发票数据(支持中文、英文和西班牙语)。

    def merge_pdfs(self):if self.selected_folder:pdf_files = [os.path.join(self.selected_folder, f) for f in os.listdir(self.selected_folder) if f.endswith('.pdf')]total_files = len(pdf_files)if total_files:all_trips = []self.ui.progressBar.setValue(0)for i, pdf_file in enumerate(pdf_files):# 提取PDF中的行程数据trips = self.extract_trip_data_from_pdf(pdf_file)all_trips.extend(trips)# 更新进度条progress = int(((i + 1) / total_files) * 100)self.ui.progressBar.setValue(progress)# 生成总结页PDFsummary_pdf_path = "summary.pdf"self.generate_summary_page(summary_pdf_path, all_trips)# 合并PDFsave_path, _ = QFileDialog.getSaveFileName(self, "Save Merged PDF", "", "PDF Files (*.pdf)")if save_path:merger = PdfMerger()merger.append(summary_pdf_path)for pdf in pdf_files:merger.append(pdf)merger.write(save_path)merger.close()
3.4 生成包含行程信息的总结页

为了方便整理行程信息,我们在合并多个发票之前,生成了一份总结页,并将其合并到最终的 PDF 文件中。总结页显示了所有行程的详细信息,并通过 ReportLab 将其以表格形式展示。

def generate_summary_page(self, output_path, trips_data):pdfmetrics.registerFont(UnicodeCIDFont('STSong-Light'))  # 使用 STSong-Light 字体doc = SimpleDocTemplate(output_path, pagesize=A4)table_data = [["日期", "起始时间", "启程地", "结束时间", "目的地", "金额", "单位"]]# 循环将行程数据添加到表格for trip in trips_data:table_data.append([trip["日期"], trip["起始时间"], trip["启程地"], trip["结束时间"], trip["目的地"], trip["金额"], trip["单位"]])table = Table(table_data, colWidths=[3 * cm, 2 * cm, 5 * cm, 2 * cm, 5 * cm, 2 * cm, 2 * cm])style = TableStyle([...])table.setStyle(style)elements = [table]doc.build(elements)

4. 运行效果展示

当用户运行该程序时,可以选择一个包含多个 Uber 发票的文件夹,点击 "Merge PDF NOW" 按钮后,程序会自动提取每一张发票中的行程数据,并动态更新进度条。处理完成后,用户可以保存最终合并的 PDF 文件,并查看生成的总结页。


5. 总结

通过这篇博客,你学会了如何使用 PyQt5 构建一个图形化的发票合并工具,并结合 pdfplumberPyPDF2ReportLab 实现发票的自动处理、数据提取以及文件合并。这种工具能够极大地提高发票处理的效率,并为用户带来便捷的体验。

如果你对 PDF 处理有需求或希望进一步优化用户界面,这将是一个非常好的入门项目。希望这篇文章对你有所帮助!


http://www.ppmy.cn/embedded/114565.html

相关文章

springBoot整合easyexcel实现导入、导出功能

本次使用的框架是springboot&#xff0c;使用mybatisplus操作表&#xff0c;使用easyexcel实现表格的导入与导出。 操作步骤 1、导入依赖&#xff1a;&#xff08;pom.xml&#xff09; <!-- 查看excel的maven仓库 https://mvnrepository.com/artifact/com.alibaba/easyex…

WEB攻防-JS项目Node.js框架安全识别审计验证绕过

知识点&#xff1a; 1、原生JS&开发框架-安全条件 2、常见安全问题-前端验证&未授权 详细点&#xff1a; 1、什么是JS渗透测试&#xff1f; 在JavaScript中也存在变量和函数&#xff0c;当存在可控变量及函数调用即可参数漏洞 2、流行的Js框架有哪些&#xff1f; …

SpringMVC1~~~

快速入门 spring容器文件 在src下就是applicationContext-mvc.xml&#xff0c;需要在web.xml指定<init-param>&#xff0c;给DispatcherServlet指定要去操作的spring容器文件 在WEB-INF下就是xxx-servlet.xml&#xff0c;不需要在web.xml指定<init-param>,如果我们…

Java中的`String`、`StringBuffer` 和 `StringBuilder`:深入理解与应用场景

在Java中&#xff0c;String、StringBuffer 和 StringBuilder 是用于处理字符串的三种常用类。虽然它们都可以用于创建和操作字符串&#xff0c;但它们的实现、特性、性能以及使用场景各不相同。理解这三者的区别以及它们各自的应用场景&#xff0c;对于编写高效的Java程序至关…

如何学习JAIN-SLEE

要系统地学习 JAIN-SLEE (Java API for Integrated Networks – Service Logic Execution Environment)&#xff0c;你需要从基础概念到高级应用逐步深入学习。以下是详细的入门学习路径和顺序&#xff0c;涵盖必要的知识点、学习顺序和步骤&#xff0c;帮助你快速掌握 JAIN-SL…

如何在webots中搭建一个履带机器人

前期准备 下载webotswebots基本知识 a. 官方文档:Webots documentation: Track b. B站教程:webots-超详细入门教程(2020)_哔哩哔哩_bilibili搭建流程 搭建履带机器人主要使用到了webots中的track节点,这个节点是专门用来定义履带的相关属性,模拟履带运动的 首先,创建一个…

Unity3D入门(二) :Unity3D实现视角的丝滑过渡切换

1. 前言 上篇文章&#xff0c;我们已经初步了解了Unity3D&#xff0c;并新建并运行起来了一个项目&#xff0c;使相机视角自动围绕着立方体旋转。 这篇文章&#xff0c;我们来讲一下Unity3D怎么过渡地切换视角。 我们继续是我上篇文章中的项目&#xff0c;但是需要向把Camera…

深入理解时间复杂度与空间复杂度

在软件开发领域&#xff0c;特别是算法设计与优化中&#xff0c;理解并准确计算算法的时间复杂度和空间复杂度是至关重要的。这不仅能帮助我们评估算法的性能&#xff0c;还能指导我们在面对不同问题时选择合适的算法。本文将深入探讨JavaScript环境下如何详细分析和计算这两种…