word文档复杂表格格式一键转换

项目来源

 最近,有个做管线检测的朋友在进行内业工作的时候,需要将原始检测报告里的表格信息转换到标准模版下(转换前后的表格样式不同,且只需要转换有用的信息,其中还包含了图片)。
 转换前一个表格就是一个片区的检测内容,一段时间累积下来,要转换的表格少则几千,多则上万。之前他们内业就是,人工将需要的内容从原始报告中,复制到标准模版中,过程费时费力,一般都是一个小组进行十几天的内业工作才能完成。由此产生了这次项目需求,具体要求如下:
  原始报告样式:
在这里插入图片描述
  需要转换成的标准样式:
在这里插入图片描述

设计思路与核心代码

 可以简单的理解就是把原始报告中需要的信息转换到标准模版中,并对应的插入图片。鉴于原始报告中单元格的排列横纵交叉,并且伴有不定个数的图片,所以可以对思路进行拆解

  1. 横向单元格标题与内容提取 ,对于横向单元格来说,可以看到奇数列为标题,偶数列为对应的内容,也由此容易想到可以用字典来存储数据;
data_dict = {}  # 用于存储标题与值的字典
    for row in table1.rows[start_index:end_index]:
        cells = [cell.text.strip() for cell in row.cells] 
        for i in range(0, len(cells) - 1, 2):  # 遍历奇数索引的标题
            title = cells[i]
            value = cells[i + 1]  # 偶数索引的值
            if title == value:
                value = cells[i + 2]
            # 将值添加到标题对应的列表中
            data_dict.setdefault(title, value)
  1. 纵向单元格标题与内容提取 ,对于纵向来说,第九行为标题,接下来几行都是标题对应的值(几张图片就有几行值);
def extract_more_data(table2, start_number, end_number):
    headers = []  # 存储表头
    data = []  # 存储数据

    for cell in table2.rows[7].cells:
        headers.append(cell.text.strip())

    for row in table2.rows[start_number:end_number]:
        row_data = {}
        for i, cell in enumerate(row.cells):
            header = headers[i]
            value = cell.text.strip()

            # 如果值为空,则忽略此列
            if value != "":
                row_data[header] = value
            else:
                row_data[header] = "/"

        # 只添加非空行数据
        if len(row_data) > 0:
            data.append(row_data)

    return headers, data
  1. 图片提取 ,对于图片的转换也是模拟word文档中的复制粘贴功能。由于本项目涉及到的复制粘贴操作量较大,而且频繁打开word,容易引发读写错误,所以决定对图片采取缓存的形式;
def extract_images(document, output_folder):
    # 确保输出文件夹存在
    if not os.path.exists(output_folder):
        os.makedirs(output_folder)
    image_count = 1
    # 遍历文档中的所有内联形状并提取图片
    for inline_shape in document.inline_shapes:
        blip = inline_shape._inline.graphic.graphicData.pic.blipFill.blip
        rel_id = blip.embed
        pic_rel = document.part.related_parts[rel_id]
        # 构造按顺序编号的图片文件名并保存
        image_name = os.path.join(output_folder, f'image_{image_count}.png')
        with open(image_name, 'wb') as f:
            f.write(pic_rel.blob)
        image_count += 1
    return image_count
  1. 表格内容写入,为了将提取的文字内容插入到新的标准模版中,需要对原始报告的标题和标准模版的标题做个映射。然后通过键值对取值写入,例:
    for g in range(len(sum_tables_data)):
        con_dict = sum_tables_data[g]
        # 管段编号
        cell1 = table_after[g].cell(0, 1)
        paragraph1 = cell1.paragraphs[0]
        content1 = con_dict.get('起始井号') + "-" + con_dict.get('终止井号')
        run1 = paragraph1.add_run(content1)
  1. 对应图片插入 ,根据缓存中的图片的文件名进行读取插入
def insert_image_into_cell(document, insert_path):
    tables = document.tables
    x = len(tables)
    for i in range(len(tables)):
        # 假设我们要在第row行第column列插入图片
        target_cell = tables[i].cell(row, column)  

        # 图片路径
        image_path = r'./picture/image_{}.png'.format(i + 1)

        # 在指定单元格插入图片并设置水平居中
        paragraph = target_cell.add_paragraph()
        run = paragraph.add_run()
        run.add_picture(image_path, width=Inches(2.9), height=Inches(2))
        paragraph.alignment = WD_ALIGN_PARAGRAPH.CENTER
    # 保存文档
    document.save(insert_path)
  1. 项目打包 ,开发完成后,将其打包成.exe可执行文件,方便执行任务
pyinstaller --onefile --icon=icon.ico main.py
#icon.ico为图标路径,可以作为软件的展现形式,main.py替换成你自己的主函数名称

效果展示

 小编最后将项目打包成.exe文件,双击即可运行,对于参数进行了封装,自己填入需要处理的原始报告的文件绝对路径
在这里插入图片描述
 填入文件路径,直接回车便可执行,执行结束后窗口自动关闭

一点思考

 小编在自己的程序中加入了任务耗时计算的代码,测试了98个原始报告表格,转换共耗时5秒,这样来说一万个表格大概需要十分钟的时间。当然代码还有可以优化的地方,达到耗时更短的效果,也可以自己做个GUI,更方便操作。
 有任何疑问或者指教,欢迎评论或者私信交流。

  • 19
    点赞
  • 20
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值