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