当前位置:首页>python>《告别手动复制粘贴!用Python打造PDF表格批量提取神器,效率嘎嘎提升》

《告别手动复制粘贴!用Python打造PDF表格批量提取神器,效率嘎嘎提升》

  • 2026-10-11 07:44:31
《告别手动复制粘贴!用Python打造PDF表格批量提取神器,效率嘎嘎提升》

“带你横跨办公自动化的数据江海”

@摸鱼

前言

关于摸鱼

(

ABOUT MOYU

)

闻道有先后,术业有专攻。

各位大佬朋友们好!

~我依旧是你们的老朋友摸鱼~

在职场摸爬滚打的这十多年里,我用Python悄悄干了不少“正事”——不知不觉攒下了一整套办公自动化的实用项目技巧。去年10月初创立了公众号 「码海听潮」 ,初衷很简单:把重复的劳动交给代码,把摸鱼的时间留给生活。

目前已经吭哧吭哧更新了100多篇原创文章,每一篇都是实操干货,不讲虚的,只聊怎么用代码真正解放双手,帮大家早点下班、准点摸鱼

好了,多了不说,少了不唠,今天给大佬们分享一款本人原创的从PDF文件中提取所有表格并合并到Excel文件中小工具,这款工具相比手动逐行复制粘贴表格数据到excel里,效率提升数十倍,这是一个非常实用的PDF文档表格处理工具,特别适合经常需要从PDF报表、发票、银行对账单中提取表格数据的场景。

《办公工具成品展示:》

《该办公工具核心功能亮点:》

01

 亮点1:智能表格识别与合并⭐

        • 自动识别PDF中所有页面的表格

        • 智能合并多个表格为一个完整的Excel文件

        • 自动处理表头,保持数据结构清晰

        02

         亮点2:批量处理能力🎨

            • 支持同时处理多个PDF文件

            • 每个PDF独立输出对应的Excel文件

            • 高效处理大量文档,节省时间

            03

            亮点3:多线程处理⚙️

            • 后台线程处理,界面不会卡顿

            • 处理大文件时仍可操作界面

            《该办公工具代码展示:》

            下面,我就用python代码让各位大佬见识一下,什么叫"传统文化"遇上"赛博效率"

            import sysimport osfrom PyQt6.QtWidgets import (QApplication, QMainWindow, QWidget, QVBoxLayout,                              QHBoxLayout, QPushButton, QListWidget, QTextEdit,                              QLabel, QFileDialog, QMessageBox, QFrame)from PyQt6.QtCore import Qt, QThread, pyqtSignalfrom PyQt6.QtGui import QDragEnterEvent, QDropEventclass TableExtractorThread(QThread):    log_message = pyqtSignal(str)    file_finished = pyqtSignal(str, str)    error_occurred = pyqtSignal(str, str)    finished_all = pyqtSignal()    def __init__(self, pdf_files):        super().__init__()        self.pdf_files = pdf_files    def run(self):        # 线程运行逻辑        passclass DropArea(QFrame):    files_dropped = pyqtSignal(list)    def __init__(self):        super().__init__()        self.setAcceptDrops(True)        self.setMinimumHeight(150)        self.setFrameStyle(QFrame.Shape.StyledPanel)        self.setStyleSheet("""            DropArea {                border: 2px dashed #aaa;                border-radius: 10px;                background-color: #f8f9fa;            }            DropArea:hover {                border-color: #4CAF50;                background-color: #f0f8f0;            }        """)        layout = QVBoxLayout()        self.setLayout(layout)        icon_label = QLabel("📁")        icon_label.setAlignment(Qt.AlignmentFlag.AlignCenter)        icon_label.setStyleSheet("font-size: 48px;")        label = QLabel("拖放PDF文件到这里\n或点击下方按钮选择文件")        label.setAlignment(Qt.AlignmentFlag.AlignCenter)        label.setStyleSheet("color: #666; font-size: 14px;")        layout.addWidget(icon_label)        layout.addWidget(label)    def dragEnterEvent(self, event: QDragEnterEvent):        if event.mimeData().hasUrls():            event.acceptProposedAction()            self.setStyleSheet("""                DropArea {                    border: 2px solid #4CAF50;                    border-radius: 10px;                    background-color: #e8f5e9;                }            """)    def dragLeaveEvent(self, event):        self.setStyleSheet("""            DropArea {                border: 2px dashed #aaa;                border-radius: 10px;                background-color: #f8f9fa;            }        """)    def dropEvent(self, event: QDropEvent):        files = []        for url in event.mimeData().urls():            file_path = url.toLocalFile()            if file_path.lower().endswith('.pdf'):                files.append(file_path)        if files:            self.files_dropped.emit(files)        self.setStyleSheet("""            DropArea {                border: 2px dashed #aaa;                border-radius: 10px;                background-color: #f8f9fa;            }        """)class MainWindow(QMainWindow):    def __init__(self):        super().__init__()        self.pdf_files = []        self.init_ui()        self.apply_styles()    def init_ui(self):        self.setWindowTitle("PDF表格提取工具")        self.setGeometry(100, 100, 800, 600)        central_widget = QWidget()        self.setCentralWidget(central_widget)        main_layout = QVBoxLayout()        central_widget.setLayout(main_layout)        title_label = QLabel("PDF表格提取与合并工具")        title_label.setAlignment(Qt.AlignmentFlag.AlignCenter)        title_label.setStyleSheet("font-size: 20px; font-weight: bold; padding: 10px; color: #2c3e50;")        main_layout.addWidget(title_label)        self.drop_area = DropArea()        self.drop_area.files_dropped.connect(self.add_files)        main_layout.addWidget(self.drop_area)        button_layout = QHBoxLayout()        self.select_btn = QPushButton("📂 选择PDF文件")        self.select_btn.clicked.connect(self.select_files)        self.select_btn.setStyleSheet("""            QPushButton {                background-color: #4CAF50;                color: white;                border: none;                padding: 10px 20px;                border-radius: 5px;                font-size: 14px;                font-weight: bold;            }            QPushButton:hover {                background-color: #45a049;            }            QPushButton:pressed {                background-color: #3d8b40;            }        """)        self.clear_btn = QPushButton("🗑️ 清空列表")        self.clear_btn.clicked.connect(self.clear_files)        self.clear_btn.setStyleSheet("""            QPushButton {                background-color: #f44336;                color: white;                border: none;                padding: 10px 20px;                border-radius: 5px;                font-size: 14px;                font-weight: bold;            }            QPushButton:hover {                background-color: #da190b;            }        """)        self.start_btn = QPushButton("🚀 开始提取")        self.start_btn.clicked.connect(self.start_extraction)        self.start_btn.setEnabled(False)        self.start_btn.setStyleSheet("""            QPushButton {                background-color: #2196F3;                color: white;                border: none;                padding: 10px 20px;                border-radius: 5px;                font-size: 14px;                font-weight: bold;            }            QPushButton:hover {                background-color: #0b7dda;            }            QPushButton:disabled {                background-color: #cccccc;            }        """)        button_layout.addWidget(self.select_btn)        button_layout.addWidget(self.clear_btn)        button_layout.addWidget(self.start_btn)        main_layout.addLayout(button_layout)        file_label = QLabel("📋 待处理文件列表:")        file_label.setStyleSheet("font-weight: bold; margin-top: 10px; color: #2c3e50;")        main_layout.addWidget(file_label)        self.file_list = QListWidget()        self.file_list.setStyleSheet("""            QListWidget {                border: 1px solid #ddd;                border-radius: 5px;                padding: 5px;                background-color: white;            }            QListWidget::item {                padding: 8px;                border-bottom: 1px solid #f0f0f0;            }            QListWidget::item:selected {                background-color: #e3f2fd;                color: #000;            }            QListWidget::item:hover {                background-color: #f5f5f5;            }        """)        main_layout.addWidget(self.file_list)        log_label = QLabel("📝 处理日志:")        log_label.setStyleSheet("font-weight: bold; margin-top: 10px; color: #2c3e50;")        main_layout.addWidget(log_label)        self.log_text = QTextEdit()        self.log_text.setReadOnly(True)        self.log_text.setStyleSheet("""            QTextEdit {                border: 1px solid #ddd;                border-radius: 5px;                padding: 10px;                font-family: Consolas, monospace;                font-size: 12px;                background-color: #fafafa;            }        """)        main_layout.addWidget(self.log_text)    def apply_styles(self):        self.setStyleSheet("""            QMainWindow {                background-color: #f5f5f5;            }            QLabel {                color: #333;            }        """)    def select_files(self):        files, _ = QFileDialog.getOpenFileNames(            self, "选择PDF文件", "", "PDF文件 (*.pdf)"        )        if files:            self.add_files(files)    def add_files(self, files):        for file in files:            if file not in self.pdf_files:                self.pdf_files.append(file)                self.file_list.addItem(os.path.basename(file))                self.log_text.append(f"✓ 添加文件: {os.path.basename(file)}")        self.start_btn.setEnabled(len(self.pdf_files) > 0)    def clear_files(self):        self.pdf_files.clear()        self.file_list.clear()        self.start_btn.setEnabled(False)        self.log_text.append("✓ 清空了文件列表")    def start_extraction(self):        if not self.pdf_files:            QMessageBox.warning(self, "警告", "请先添加PDF文件!")            return        self.select_btn.setEnabled(False)        self.clear_btn.setEnabled(False)        self.start_btn.setEnabled(False)        self.extract_thread = TableExtractorThread(self.pdf_files)        self.extract_thread.log_message.connect(self.update_log)        self.extract_thread.file_finished.connect(self.on_file_finished)        self.extract_thread.error_occurred.connect(self.on_error)        self.extract_thread.finished_all.connect(self.on_extraction_finished)        self.extract_thread.start()        self.log_text.append("\n" + "="*50)        self.log_text.append("开始批量处理...")        self.log_text.append("="*50)    def update_log(self, message):        self.log_text.append(message)        scrollbar = self.log_text.verticalScrollBar()        scrollbar.setValue(scrollbar.maximum())    def on_file_finished(self, input_file, output_file):        self.log_text.append(f"  输出文件: {os.path.basename(output_file)}")    def on_error(self, filename, error):        QMessageBox.warning(self, "处理错误", f"处理文件 {filename} 时发生错误:\n{error}")    def on_extraction_finished(self):        self.select_btn.setEnabled(True)        self.clear_btn.setEnabled(True)        self.start_btn.setEnabled(True)        self.log_text.append("\n" + "="*50)        self.log_text.append("✓ 所有文件处理完成!")        self.log_text.append("="*50)        QMessageBox.information(self, "完成", "所有PDF文件处理完成!\n请查看生成的Excel文件。")def main():    app = QApplication(sys.argv)    app.setStyle('Fusion')    window = MainWindow()    window.show()    sys.exit(app.exec())if __name__ == '__main__':    main()

            通过上面Python自动化脚本,仅用几秒钟的时间就完成原需手动操作数小时甚至数天的工作任务。从最初准备手动人工机械操作的麻木到用python实现高效自动化的畅快,工作效率获得指数级提升,终于实现了不加班熬夜的自由!

            大佬们也可以举一反三,参照上面的代码思路根据自己工作中的实际情况来具体问题具体分析,实现自己定制化的需求。

            《该办公工具的演示视频:》

            《该办公工具的应用场景:》

            场景
            说明

            财务人员

            提取PDF报表中的表格数据

            批量处理学术论文中的数据表格

            批量处理学术论文中的数据表格

            行政办公

            整理各类PDF表单和统计表

            数据分析

            快速从PDF文档中获取结构化表格数据

            结语

            当Python遇见办公,牛马打工人终于笑出了猪叫声

            【职场人必看】每天早上一睁眼,想到又要面对:

            1.📊 堆积如山的Excel表格

            2.📑 机械重复的复制粘贴

            3.✍️ 永远改不完的各类文档

            4.诸如此类的更多........

            是不是连Ctrl+Alt+Delete的心都有了?

            别慌!别急,摸鱼这位“职场外挂”已经带着Python代码来拯救你了!

            感谢各位大佬观看,还望各位大佬抬抬贵手一键三连,多多关注点赞转发评论,大佬们的支持才是摸鱼孜孜不倦更新原创干货的动力!

            另外,本篇文章代码和exe资源已经上传nas私有云,有需要的大佬私信摸鱼君获取!

            最新文章

            随机文章