当前位置:首页>python>《告别手动复制!Python智能提取Word表格:自动识别表格标题,一键批量单独保存,效率翻倍~》

《告别手动复制!Python智能提取Word表格:自动识别表格标题,一键批量单独保存,效率翻倍~》

  • 2026-10-11 18:32:10
《告别手动复制!Python智能提取Word表格:自动识别表格标题,一键批量单独保存,效率翻倍~》

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

@摸鱼

前言

关于摸鱼

(

ABOUT MOYU

)

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

各位大佬朋友们好!

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

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

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

好了,多了不说,少了不唠,今天给大佬们分享一款自动识别并提取Word文档中的表格,将每个表格(连同其标题)保存为独立的Word文档小工具

《办公工具成品展示:》

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

01

 亮点1:智能识别表格标题

        • 自动识别以"表"开头的标题(如:表1、表2-1、表3.1等)

        • 向上搜索5个段落范围内查找表格标题

        • 未找到标题时自动命名为"表_X"

        02

         亮点2:批量处理能力

          • 支持 .docx 和 .doc 格式

          • 递归处理子文件夹中的所有Word文档

          • 可同时处理多个Word文件

          03

          亮点3:表格提取方式

          • 将表格标题和表格内容一起提取

          • 保留源格式粘贴到新文档

          • 每个表格保存为独立的Word文件

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

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

          import sysimport osfrom datetime import datetimefrom PyQt6.QtWidgets import (    QApplication, QMainWindow, QWidget, QVBoxLayout, QHBoxLayout,    QPushButton, QTextEdit, QLabel, QFileDialog, QGroupBox,    QMessageBox)from PyQt6.QtCore import Qt, QThread, pyqtSignalfrom PyQt6.QtGui import QTextCursor, QColorclass ExtractionThread(QThread):    """提取线程基类,实际使用时需要继承并实现具体逻辑"""    log_message = pyqtSignal(str)    extraction_finished = pyqtSignal(int, int)    def __init__(self, folder_path):        super().__init__()        self.folder_path = folder_path        self.is_running = True    def stop(self):        self.is_running = False    def run(self):        # 这是一个示例实现,实际使用时需要替换为真正的提取逻辑        self.log_message.emit(f"开始处理文件夹: {self.folder_path}")        # 模拟处理过程        import time        for i in range(10):            if not self.is_running:                break            time.sleep(0.5)            self.log_message.emit(f"处理进度: {i+1}/10")        self.extraction_finished.emit(5, 10)class MainWindow(QMainWindow):    def __init__(self):        super().__init__()        self.worker_thread = None        self.init_ui()    def append_log(self, text, color=None):        """添加日志到文本框"""        cursor = self.log_text.textCursor()        cursor.movePosition(QTextCursor.MoveOperation.End)        # 设置颜色        if color:            self.log_text.setTextColor(QColor(color))        else:            # 根据内容自动判断颜色            if "✓" in text or "成功" in text or "保存成功" in text:                self.log_text.setTextColor(QColor("#4CAF50"))  # 绿色            elif "✗" in text or "失败" in text or "错误" in text or "出错" in text:                self.log_text.setTextColor(QColor("#F44336"))  # 红色            elif "⚠" in text or "警告" in text:                self.log_text.setTextColor(QColor("#FF9800"))  # 橙色            elif "===" in text or "###" in text or "处理文件" in text or "开始处理" in text:                self.log_text.setTextColor(QColor("#2196F3"))  # 蓝色            elif "生成表格" in text or "创建文件夹" in text:                self.log_text.setTextColor(QColor("#9C27B0"))  # 紫色            else:                self.log_text.setTextColor(QColor("#333333"))  # 深灰色        self.log_text.setTextCursor(cursor)        self.log_text.insertPlainText(text + "\n")        self.log_text.ensureCursorVisible()    def init_ui(self):        self.setWindowTitle("Word表格批量提取工具(欢迎关注微信公众号:码海听潮)")        self.setGeometry(100, 100, 700, 600)        # 设置应用样式        self.setStyleSheet("""            QMainWindow {                background-color: #f5f5f5;            }            QGroupBox {                font-weight: bold;                border: 2px solid #cccccc;                border-radius: 8px;                margin-top: 1ex;                padding-top: 10px;                background-color: white;            }            QGroupBox::title {                subcontrol-origin: margin;                left: 10px;                padding: 0 5px 0 5px;                color: #2196F3;            }            QPushButton {                background-color: #2196F3;                color: white;                border: none;                border-radius: 5px;                padding: 8px 16px;                font-weight: bold;                min-width: 100px;            }            QPushButton:hover {                background-color: #1976D2;            }            QPushButton:pressed {                background-color: #0D47A1;            }            QPushButton:disabled {                background-color: #BDBDBD;            }            QPushButton#stopButton {                background-color: #F44336;            }            QPushButton#stopButton:hover {                background-color: #D32F2F;            }            QLabel {                color: #333333;            }            QTextEdit {                border: 1px solid #cccccc;                border-radius: 5px;                background-color: #fafafa;                font-family: 'Consolas', 'Courier New', monospace;                font-size: 12px;                line-height: 1.5;            }        """)        # 创建中央部件        central_widget = QWidget()        self.setCentralWidget(central_widget)        main_layout = QVBoxLayout(central_widget)        main_layout.setSpacing(15)        main_layout.setContentsMargins(20, 20, 20, 20)        # 文件夹选择区域        folder_group = QGroupBox("📁 文件夹设置")        folder_layout = QVBoxLayout(folder_group)        path_layout = QHBoxLayout()        self.folder_path_label = QLabel("未选择文件夹")        self.folder_path_label.setStyleSheet("""            background-color: #FFF3E0;            border: 1px solid #FFB74D;            border-radius: 3px;            padding: 8px;            color: #E65100;        """)        self.folder_path_label.setWordWrap(True)        path_layout.addWidget(self.folder_path_label, 1)        self.browse_button = QPushButton("📂 选择文件夹")        self.browse_button.clicked.connect(self.browse_folder)        path_layout.addWidget(self.browse_button)        folder_layout.addLayout(path_layout)        main_layout.addWidget(folder_group)        # 日志显示区域        log_group = QGroupBox("📝 处理日志")        log_layout = QVBoxLayout(log_group)        self.log_text = QTextEdit()        self.log_text.setReadOnly(True)        log_layout.addWidget(self.log_text)        main_layout.addWidget(log_group, 1)        # 按钮区域        button_layout = QHBoxLayout()        self.start_button = QPushButton("▶ 开始提取")        self.start_button.clicked.connect(self.start_extraction)        self.start_button.setMinimumHeight(40)        button_layout.addWidget(self.start_button)        self.stop_button = QPushButton("⏹ 停止")        self.stop_button.setObjectName("stopButton")        self.stop_button.clicked.connect(self.stop_extraction)        self.stop_button.setEnabled(False)        self.stop_button.setMinimumHeight(40)        button_layout.addWidget(self.stop_button)        self.clear_button = QPushButton("🗑 清空日志")        self.clear_button.clicked.connect(self.clear_log)        self.clear_button.setStyleSheet("""            QPushButton {                background-color: #607D8B;            }            QPushButton:hover {                background-color: #455A64;            }        """)        self.clear_button.setMinimumHeight(40)        button_layout.addWidget(self.clear_button)        main_layout.addLayout(button_layout)        # 显示启动信息        self.append_log("📌 功能说明:")        self.append_log("   1. 自动识别以'表'开头的表格标题(如:表1、表2-1等)")        self.append_log("   2. 将标题和表格一起提取并保存为独立的Word文档")    def browse_folder(self):        folder_path = QFileDialog.getExistingDirectory(            self,             "选择包含Word文档的文件夹",            os.path.expanduser("~"),            QFileDialog.Option.ShowDirsOnly        )        if folder_path:            self.folder_path_label.setText(folder_path)            self.folder_path_label.setStyleSheet("""                background-color: #E8F5E9;                border: 1px solid #81C784;                border-radius: 3px;                padding: 8px;                color: #2E7D32;            """)            self.append_log(f"\n✅ 已选择文件夹: {folder_path}")            # 扫描并显示文件夹内容            word_extensions = ['.docx', '.doc']            word_files = []            for root, dirs, files in os.walk(folder_path):                for file in files:                    if any(file.lower().endswith(ext) for ext in word_extensions):                        if not file.startswith('~$'):                            word_files.append(os.path.join(root, file))            if word_files:                self.append_log(f"📊 发现 {len(word_files)} 个Word文档")                self.append_log("📄 文档列表:")                for i, file in enumerate(word_files[:10], 1):                    rel_path = os.path.relpath(file, folder_path)                    self.append_log(f"   {i}. {rel_path}")                if len(word_files) > 10:                    self.append_log(f"   ... 还有 {len(word_files) - 10} 个文档")                self.append_log("")            else:                self.append_log("⚠ 该文件夹中没有找到Word文档")                self.append_log("")    def start_extraction(self):        folder_path = self.folder_path_label.text()        if folder_path == "未选择文件夹":            QMessageBox.warning(self, "警告", "请先选择文件夹!")            return        if not os.path.exists(folder_path):            QMessageBox.critical(self, "错误", "选择的文件夹不存在!")            return        # 确认开始处理        reply = QMessageBox.question(            self,             "确认",             "开始提取表格?\n\n"            "注意:\n"            "1. 处理过程中会打开Word应用\n"            "2. 请确保Word文档未被其他程序占用\n"            "3. 提取的表格将保存在原文档所在目录\n"            "4. 默认包含子文件夹,标题查找范围为5段",            QMessageBox.StandardButton.Yes | QMessageBox.StandardButton.No        )        if reply != QMessageBox.StandardButton.Yes:            return        # 清空日志        self.log_text.clear()        # 更新UI状态        self.start_button.setEnabled(False)        self.stop_button.setEnabled(True)        self.browse_button.setEnabled(False)        # 创建并启动工作线程        # 注意:这里需要使用实际的提取线程类替换ExtractionThread        self.worker_thread = ExtractionThread(folder_path)        self.worker_thread.extraction_finished.connect(self.on_extraction_finished)        self.worker_thread.log_message.connect(self.on_log_message)        self.worker_thread.start()        self.append_log(f"\n{'='*80}")        self.append_log(f"🚀 开始处理任务")        self.append_log(f"📁 目标文件夹: {folder_path}")        self.append_log(f"{'='*80}\n")    def stop_extraction(self):        if self.worker_thread and self.worker_thread.isRunning():            reply = QMessageBox.question(                self,                "确认停止",                "确定要停止处理吗?\n已处理的文件将保留。",                QMessageBox.StandardButton.Yes | QMessageBox.StandardButton.No            )            if reply == QMessageBox.StandardButton.Yes:                self.worker_thread.stop()                self.stop_button.setEnabled(False)                self.append_log("\n⏸ 用户已请求停止处理...")    def on_extraction_finished(self, success_count, total_files):        self.start_button.setEnabled(True)        self.stop_button.setEnabled(False)        self.browse_button.setEnabled(True)        # 显示完成消息        if total_files > 0:            QMessageBox.information(                self,                "处理完成",                f"表格提取完成!\n\n"                f"处理文件数: {total_files}\n"                f"提取表格数: {success_count}"            )    def on_log_message(self, message):        """接收线程发送的日志消息"""        # 添加时间戳        timestamp = datetime.now().strftime('%H:%M:%S')        formatted_message = f"[{timestamp}] {message}"        self.append_log(formatted_message)    def clear_log(self):        self.log_text.clear()        self.append_log("🗑 日志已清空")        self.append_log("")    def closeEvent(self, event):        if self.worker_thread and self.worker_thread.isRunning():            reply = QMessageBox.question(                self,                "确认退出",                "处理正在进行中,确定要退出吗?",                QMessageBox.StandardButton.Yes | QMessageBox.StandardButton.No            )            if reply == QMessageBox.StandardButton.Yes:                self.worker_thread.stop()                self.worker_thread.wait(3000)                event.accept()            else:                event.ignore()        else:            event.accept()if __name__ == "__main__":    app = QApplication(sys.argv)    app.setStyle('Fusion')    window = MainWindow()    window.show()    sys.exit(app.exec())

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

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

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

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

            这套工具特别适合:

            结语

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

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

            1.📊 堆积如山的Excel表格

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

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

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

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

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

            另外,此工具已上传绿联nas私有云,有需要的大佬私信摸鱼君获取!

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

            最新文章

            随机文章