【Python Docx】批量获取江财学生综测信息登记表脚本实战教程

概述

Python脚本旨在自动化处理学生信息的提取和整理,最终将信息汇总到一个Excel文件中。脚本利用了openpyxlpython-docx库来操作Excel和Word文档,以及正则表达式来提取特定格式的信息。希望对综测评价有所帮助。

脚本功能详解

1. 读取Word文档中的表格信息

word表格格式大致形式

  • 脚本首先定义了read_word_table函数,该函数负责打开指定路径的Word文档,并读取其中的第一个表格。
  • 通过遍历表格的行和列,脚本记录了每个单元格的位置,并构建了一个索引列表,用于后续提取特定单元格中的文本内容。
  • 解决由于合并单元格导致元素重复输出问题。参考python docx处理word文档中表格合并问题
  • def read_word_table(path):
        # 打开Word文档
        file = Document(path)
        # 文档内容已经以字符串形式存储在变量content中
        content = ""
        # 假设我们只处理第一个表格
        table = file.tables[0]
    
        # 初始化变量
        row_cells, column_cells = [], []
        index = []
        width, length = len(table.columns), len(table.rows)
        k = 0
    
        # 遍历行和列,记录单元格的位置
        for row in table.rows:
            for cell in row.cells:
                if cell not in row_cells:
                    index.append([k // width, k % width])
                    row_cells.append(cell)
                k += 1
    
        k = 0
        for column in table.columns:
            for cell in column.cells:
                if cell not in column_cells:
                    column_cells.append(cell)
                elif [k % length, k // length] in index:
                    index.remove([k % length, k // length])
                k += 1
        # 打印找到的单元格索引对应的文本
        for i in index:
            # print(table.rows[i[0]].cells[i[1]].text)
            content += table.rows[i[0]].cells[i[1]].text + "\n"
    
        # print(content)
        # 使用正则表达式替换连续的换行符
        filtered_text = re.sub(r'\n+', '\n', content)
        # print(filtered_text)
        return filtered_text
    

    2. 信息提取

  • extract_information函数使用正则表达式来匹配和提取学生信息,包括姓名、学号以及德育、智育、体育、美育和劳育的各项分数。
  • 正则表达式被设计为能够识别和提取包含换行符的多行文本,确保即使在表格跨越多行的情况下也能准确提取信息。
  •     # 使用正则表达式匹配所需的信息
        name_pattern = r"姓名\n(.*?)\n"
        student_id_pattern = r"学号\n(.*?)\n"
        德育_pattern = r"德育基础分\n(.*?)\n德育民主评议分\n(.*?)\n加、减分项目:(.*?)德育附加分数合计:(.*?)\n合计\n(.*?)\n"
        智育_pattern = r"学年加权\n(.*?)\n是否有挂科\n(.*?)\n加、减分项目:(.*?)智育附加分数合计:(.*?)\n合计\n(.*?)\n"
        体育_pattern = r"体测成绩\n(.*?)\n加、减分项目:(.*?)体育附加分数合计:(.*?)\n合计\n(.*?)\n"
        美育_pattern = r"美育基础分\n(.*?)\n美育民主评议分\n(.*?)\n加、减分项目:(.*?)美育附加分数合计:(.*?)\n合计\n(.*?)\n"
        劳育_pattern = r"劳育基础分\n(.*?)\n劳育民主评议分\n(.*?)\n加、减分项目:(.*?)劳育附加分数合计:(.*?)\n合计\n(.*?)\n"
    

    3. 信息整理

  • 提取的信息被组织成一个字典,其中包含了学生的各项分数和评价信息。
  • 4. 生成Excel文件

  • 脚本遍历指定文件夹中的所有Word文档,对每个文档调用上述函数来提取和整理信息。
  • 然后,脚本创建一个新的Excel工作簿,并在其中添加标题行和从Word文档中提取的学生信息。
  • 最后,脚本将整理好的信息保存到一个Excel文件中。
    输出结果
  • 技术实现细节

  • 库的使用

  • openpyxl库用于创建和操作Excel文件。
  • python-docx库用于读取Word文档中的表格信息。
  • re模块用于执行正则表达式匹配,以提取特定格式的文本。
  • 正则表达式的运用

  • 脚本中的正则表达式被设计为能够处理复杂的文本模式,包括跨行的文本和包含特殊字符的文本。
  • 文件操作

  • 脚本通过os模块遍历指定文件夹中的文件,并根据文件扩展名(.docx)来确定要处理的文档。
  • 注意事项

  • 确保脚本运行前已安装openpyxlpython-docx库。
  • 脚本假设所有Word文档中的表格格式是一致的,如果格式有差异,可能需要调整正则表达式或表格处理逻辑。
  • 脚本目前只处理每个Word文档中的第一个表格,如果需要处理多个表格,需要进一步扩展脚本功能。
  • 完整代码

    import os
    from openpyxl import Workbook
    from docx import Document
    import re
    
    
    def read_word_table(path):
        # 打开Word文档
        file = Document(path)
        # 文档内容已经以字符串形式存储在变量content中
        content = ""
        # 假设我们只处理第一个表格
        table = file.tables[0]
    
        # 初始化变量
        row_cells, column_cells = [], []
        index = []
        width, length = len(table.columns), len(table.rows)
        k = 0
    
        # 遍历行和列,记录单元格的位置
        for row in table.rows:
            for cell in row.cells:
                if cell not in row_cells:
                    index.append([k // width, k % width])
                    row_cells.append(cell)
                k += 1
    
        k = 0
        for column in table.columns:
            for cell in column.cells:
                if cell not in column_cells:
                    column_cells.append(cell)
                elif [k % length, k // length] in index:
                    index.remove([k % length, k // length])
                k += 1
        # 打印找到的单元格索引对应的文本
        for i in index:
            # print(table.rows[i[0]].cells[i[1]].text)
            content += table.rows[i[0]].cells[i[1]].text + "\n"
    
        # print(content)
        # 使用正则表达式替换连续的换行符
        filtered_text = re.sub(r'\n+', '\n', content)
        # print(filtered_text)
        return filtered_text
    
    
    # 定义一个函数来提取信息
    def extract_information(content):
        # 使用正则表达式匹配所需的信息
        name_pattern = r"姓名\n(.*?)\n"
        student_id_pattern = r"学号\n(.*?)\n"
        德育_pattern = r"德育基础分\n(.*?)\n德育民主评议分\n(.*?)\n加、减分项目:(.*?)德育附加分数合计:(.*?)\n合计\n(.*?)\n"
        智育_pattern = r"学年加权\n(.*?)\n是否有挂科\n(.*?)\n加、减分项目:(.*?)智育附加分数合计:(.*?)\n合计\n(.*?)\n"
        体育_pattern = r"体测成绩\n(.*?)\n加、减分项目:(.*?)体育附加分数合计:(.*?)\n合计\n(.*?)\n"
        美育_pattern = r"美育基础分\n(.*?)\n美育民主评议分\n(.*?)\n加、减分项目:(.*?)美育附加分数合计:(.*?)\n合计\n(.*?)\n"
        劳育_pattern = r"劳育基础分\n(.*?)\n劳育民主评议分\n(.*?)\n加、减分项目:(.*?)劳育附加分数合计:(.*?)\n合计\n(.*?)\n"
    
        # 搜索匹配的信息
        name = re.search(name_pattern, content)
        student_id = re.search(student_id_pattern, content)
        德育 = re.search(德育_pattern, content, re.DOTALL)
        智育 = re.search(智育_pattern, content, re.DOTALL)
        体育 = re.search(体育_pattern, content, re.DOTALL)
        美育 = re.search(美育_pattern, content, re.DOTALL)
        劳育 = re.search(劳育_pattern, content, re.DOTALL)
    
        # 将匹配的信息组织成字典
        student_info = {
            "姓名": name.group(1) if name else "未找到",
            "学号": student_id.group(1) if student_id else "未找到",
            # "德育"
            "德育基础分": 德育.group(1) if 德育 else "未找到",
            "德育民主评议分": 德育.group(2) if 德育 else "未找到",
            "德育加、减分项目": 德育.group(3) if 德育 else "未找到",
            "德育附加分数合计": 德育.group(4) if 德育 else "未找到",
            "德育合计": 德育.group(5) if 德育 else "未找到",
            
            # "智育"
            "学年加权": 智育.group(1) if 智育 else "未找到",
            "是否有挂科": 智育.group(2) if 智育 else "未找到",
            "智育加、减分项目": 智育.group(3) if 智育 else "未找到",
            "智育附加分数合计": 智育.group(4) if 智育 else "未找到",
            "智育合计": 智育.group(5) if 智育 else "未找到",
    
            # "体育"
            "体测成绩": 体育.group(1) if 体育 else "未找到",
            "体育加、减分项目": 体育.group(2) if 体育 else "未找到",
            "体育附加分数合计": 体育.group(3) if 体育 else "未找到",
            "体育合计": 体育.group(4) if 体育 else "未找到",
    
            # "美育"
            "美育基础分": 美育.group(1) if 美育 else "未找到",
            "美育民主评议分": 美育.group(2) if 美育 else "未找到",
            "美育加、减分项目": 美育.group(3) if 美育 else "未找到",
            "美育附加分数合计": 美育.group(4) if 美育 else "未找到",
            "美育合计": 美育.group(5) if 美育 else "未找到",
    
            # "劳育"
            "劳育基础分": 劳育.group(1) if 劳育 else "未找到",
            "劳育民主评议分": 劳育.group(2) if 劳育 else "未找到",
            "劳育加、减分项目": 劳育.group(3) if 劳育 else "未找到",
            "劳育附加分数合计": 劳育.group(4) if 劳育 else "未找到",
            "劳育合计": 劳育.group(5) if 劳育 else "未找到"
    
        }
        return student_info
    
    
    # 指定res文件夹的路径
    folderPath = './res'
    
    # 创建一个新的Excel工作簿
    wb = Workbook()
    ws = wb.active
    ws.title = "学生信息"
    
    # 添加标题行
    headers = ["姓名", "学号",
               "德育基础分", "德育民主评议分", "德育加、减分项目", "德育附加分数合计",
               "学年加权", "是否有挂科", "智育加、减分项目", "智育附加分数合计",
               "体测成绩", "体育加、减分项目", "体育附加分数合计",
               "美育基础分", "美育民主评议分", "美育加、减分项目", "美育附加分数合计",
               "劳育基础分", "劳育民主评议分", "劳育加、减分项目", "劳育附加分数合计"]
    ws.append(headers)
    
    # 遍历文件夹中的所有文件
    for filename in os.listdir(folderPath):
        if filename.endswith('.docx'):
            wordPath = os.path.join(folderPath, filename)
            wordContent = read_word_table(wordPath)
            student_info = extract_information(wordContent)
            row_data = [student_info.get(header, "") for header in headers]
            ws.append(row_data)
    
    # 保存Excel文件
    excel_path = './students_info.xlsx'
    wb.save(excel_path)
    print(f"信息已保存到 {excel_path}")
    
    

    作者:jiunuan_

    物联沃分享整理
    物联沃-IOTWORD物联网 » 【Python Docx】批量获取江财学生综测信息登记表脚本实战教程

    发表回复