python + word文本框中文字识别并替换【真替换,不只是识别】

1. 简单描述

在一些转换场景下,文本框不会被转换,需要先识别成文字内容。
【识别的文字段落可能会和实际看到的效果有些差异,后续还需校对,如下图】。
在这里插入图片描述
不足:除了上面说的那个情况(上图说的问题,有大神解决了可发评论区,不胜感激。),还有就是如果文本框要是还有一些特殊字体样式,或者图片什么的未作处理,读者可自行优化。

2.废话少说,直接上干货

def docx_handle_textbox(word_path, new_word_path=''):
    doc = docx.Document(word_path)
    textbox_flag = False  # 默认不存在
    for para in doc.paragraphs:
        text_box_list = []
        if para._element.xml.find('textbox') != -1:  # 表示文本框
            textbox_flag = True
            # print(para._element.xml)
            # print('该文档存在文本框,需核实替换内容是否正确(主要是文本的顺序)')
            # print( para._element.xml) # /v:group/v:group/v:rect/v:textbox
            # for textbox in para._element.xpath('.//w:r/w:pict/v:group/v:group/v:rect/v:textbox/w:txbxContent/w:p'): # 类型需要相同w, 否则需要指定 namespace

            # ============================================不保留文本框文字样式==================================================
            # for p in para._element.xpath('.//w:p'):
            #     tmp_run_list = []
            #     for run in p.xpath('.//w:t'):
            #         tmp_run_list.append(run.text)
            #     if len(tmp_run_list) > 0:
            #         text_box_list.append(''.join(tmp_run_list))
            #
            # para._element.clear()  # 清除原来的文本框
            #
            # # 【方法一】将一个大文本框作为一整段,不推荐
            # # text_box_content = '\n'.join(text_box_list)
            # # print(text_box_content)
            # # para.text = text_box_content
            #
            # # 【方法二】推荐做法根据文本框里的段进行分段
            # for tbc in text_box_list:
            #     para.insert_paragraph_before(tbc)  # 文本框所在段前插入段落【由于文本框被清除,即在完成了原文本框内容的替换】
            # ==============================================================================================================

            # 保留一些简单样式
            for p in para._element.xpath('.//w:p'):
                tmp_run_list = []
                for run in p.xpath('.//w:r'):  # 一个run的内容
                    tmp_run_list.append(run)
                if len(tmp_run_list) > 0:
                    text_box_list.append(tmp_run_list)

            para._element.clear()  # 清除原来的文本框

            # 【方法一】将一个大文本框作为一整段,不推荐
            # text_box_content = '\n'.join(text_box_list)
            # print(text_box_content)
            # para.text = text_box_content

            # 【方法二】推荐做法根据文本框里的段进行分段
            for tbc in text_box_list:  # tbc可以认为是一个段落

                # 文本框所在段前插入段落【由于文本框被清除,即在完成了原文本框内容的替换】
                insert_para = para.insert_paragraph_before('')  # 插入空字符段落,表示创建一个空段落
                for run_ct in tbc:
                    # 1.添加run
                    run = insert_para.add_run(run_ct.text)

                    # 2.对run进行样式添加
                    # 2.1检查斜体样式
                    if run_ct.xml.find('<w:i/>') != -1:
                        # print(f"文本 '{run_ct.text}' 是斜体。")
                        run.font.italic = True
                    # 2.2检查是否加粗
                    if run_ct.xml.find('<w:b/>') != -1:
                        # print(f"文本 '{run_ct.text}' 是加粗。")
                        run.font.bold = True
                    # 2.3检查文本颜色(如果已设置)
                    colors = re.findall('<w:color w:val="(.*?)"/>', run_ct.xml)
                    if colors:  # 非空
                        run.font.color.rgb = RGBColor.from_string(colors[0])
                    # 2.4一些特殊样式处理;Todo 需要根据word中具体内容去调整
                    if run_ct.style == '0Char':  # 非None word中的双下划线,此处只能使用单下划线操作【要先原样式比较麻烦】
                        run.underline = True

    if textbox_flag:  # True则进行文本框的替换
        if new_word_path == '':  # 新路径为空,则覆盖原文件
            new_word_path = word_path
        doc.save(new_word_path)

    return textbox_flag
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值