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.添加runrun = 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 = Trueif textbox_flag: # True则进行文本框的替换if new_word_path == '': # 新路径为空,则覆盖原文件new_word_path = word_pathdoc.save(new_word_path)return textbox_flag