1,背景来源
使用python-docx对word进行处理的时候,插入BytesIO对象的image后,导出的word中出现白框问题。
2,涉及使用方法
- io.BytesIO方法读取image文件:作用【读取image文件后将图片插入到word中】
- deepcopy深复制:作用【读取模板,因为我有多条记录,会遍历多次模板数据表格】
- new_paragraph = doc.add_paragraph():作用【word文件中创建一个段落】
- paragraph.add_run():作用【在段落中创建一个运行】
- run.add_picture(image_data) :作用【在运行中插入图片,也可以是文本各种】
3,两种情况
1,【方案1】首先,在单独的数据表格对象中,插入图片,然后将数据表格插入到word中,最后将word导出。【导出结果:word中图片显示白框】
2,【方案2】首先,获取模板文件中的数据表格,然后遍历所有数据记录,每个数据记录都要对应一个数据表格,将其中的值替换进去,然后将数据表格导入word文件中,最后一步,读取word文件刚刚导入的最后一个数据表格,把image添加进去。【导出结果:图片正常显示】
def gbmc_Image_Output_Word(self):
resultData = 【自己写,调自己数据库的数据,或者写死数据】
unit_resultData = 【自己写,调自己数据库的数据,或者写死数据】
# 打开word文档
doc = Document(r"C:\Users\Desktop\word导出.docx")
# 获取模板文件中的第一个表格【这个就是模板数据表格】
template_table = doc.tables[0]
fields = ['name', '***', '***']
result = []
for item in resultData:
result.append(
{
"code": item.code,
"***": item.***,
"***": item.***,
}
)
for dw_item in unit_resultData:
# 添加一个标题段落
title = doc.add_paragraph(dw_item.dwmc)
# 设置标题样式为一级标题(通常是Heading 1)
title.style = doc.styles['Heading 1']
# 设置段落居中对齐
title.paragraph_format.alignment = WD_PARAGRAPH_ALIGNMENT.CENTER
# 设置段前分页
title.paragraph_format.page_break_before = True
for i, item in enumerate(result):
print(f'姓名:{item.get("name")},工号:{item.get("code")}')
# 复制模板表格(深复制)
new_table = deepcopy(template_table)
image_data = None
# 替换表格中的内容
for row in new_table.rows:
for cell in row.cells:
for key in fields:
value = item.get(key)
if '{{' + key + '}}' in cell.text and value is not None:
if key == "image":
try:
image_data = io.BytesIO(response.content) # 这里是image对象,接口获取的图片
except Exception as e:
print(f'获取图片失败,失败原因:{str(e)}')
else:
# cell.text = cell.text.replace('{{' + key + '}}', image_data)
# 清空单元格原有文本
cell.text = ''
# 添加文本并设置属性
paragraph = cell.paragraphs[0] # 获取单元格的第一个段落
paragraph.alignment = WD_PARAGRAPH_ALIGNMENT.CENTER # 段落居中对齐
run = paragraph.add_run(str(value))
run.bold = True
run.font.size = Pt(12)
run.alignment = WD_PARAGRAPH_ALIGNMENT.CENTER # 文本居中对齐
# 去除模板中{{data}}类型的占位符
for row in new_table.rows:
for cell in row.cells:
if '{{' in cell.text and '}}' in cell.text and cell.text != "{{image}}":
cell.text = ""
# 在文件中创建一个段落
new_paragraph = doc.add_paragraph()
# 在段落中插入数据表格
new_paragraph._element.getparent().insert(new_paragraph._element.getparent().index(new_paragraph._element) + 1, new_table._element)
if image_data: # 【对已经导入word后的数据表格对图片进行处理,重点代码!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!】
table = doc.tables[-1]
for row in table.rows:
for cell in row.cells:
if "{{image}}" in cell.text:
cell.text = ""
if not cell.paragraphs:
cell.add_paragraph()
# 获取单元格的第一个段落
run = cell.paragraphs[0].add_run()
run.add_picture(image_data, width=Inches(1.0)) # 同时指定宽度和高度
# 设置段落格式,确保段落不被拆分到不同的页面
paragraph_format = new_paragraph.paragraph_format
paragraph_format.keep_together = True # 设置段落保持在一起
# 在文件中添加两个段落,不放任何内容
doc.add_paragraph()
doc.add_paragraph()
print("数据已导入")
# 删除读取的模板表格
template_table._element.getparent().remove(template_table._element)
# # 生成目录
# table_of_contents = generate_table_of_contents(doc)
# 保存文档到内存中
output_file = io.BytesIO()
doc.save(output_file)
output_file.seek(0)
doc_path = "测试版.docx"
# 发送文档作为附件
return send_file(output_file, as_attachment=True, download_name=doc_path)