Django中如何将字符串格式图片在python-docx中正确显示
问题解决:Django生成图片插入Word文档显示为字符串的修复
核心问题
你的代码存在两个关键问题:
- 变量名不匹配:
create_image函数将图片存入results['image'],但create_doc里调用的是results['score_image'],导致传入内容不对应。 document.add_picture()不支持直接传入base64编码字符串,它需要文件对象或本地文件路径。直接传base64字符串会被Word识别为普通文本。
修复步骤
1. 修正变量名一致性
在create_image函数中,将存储图片的键改为score_image,与create_doc的调用保持一致:
def create_image(): results = {} plot, axes = plt.subplots(num_plots, 1,figsize=(6, 4)) # code to create figure here fig = plot.get_figure() img_in_memory = BytesIO() fig.savefig(img_in_memory, format='png') image = base64.b64encode(img_in_memory.getvalue()) image = image.decode(settings.DEFAULT_CHARSET) plot.get_figure().clf() results['score_image'] = image # 修改键名与create_doc对应 results['results_intro'] = 'Report introduction' return results
2. 将base64字符串转换为文件对象
在create_doc函数中,先把base64编码的字符串解码为字节数据,再用BytesIO包装成可读取的文件对象,传给add_picture:
def create_doc(results): docx_title = "report.docx" document = Document() section = document.sections[0] header = section.header paragraph = header.paragraphs[0] document.add_paragraph() paragraph = document.add_paragraph("%s" % date.today().strftime('%B %d, %Y')) paragraph.alignment = WD_ALIGN_PARAGRAPH.RIGHT document.add_paragraph() document.add_paragraph('Start Report,') run = document.add_paragraph().add_run('RE: Name DD/MMM/YYYY') run.font.bold = True run.font.underline = True document.add_paragraph(results['results_intro']) document.add_paragraph() # 替换原有的add_picture调用 import base64 from io import BytesIO img_bytes = base64.b64decode(results['score_image']) img_file = BytesIO(img_bytes) document.add_picture(img_file) f = BytesIO() document.save(f) length = f.tell() f.seek(0) response = HttpResponse( f.getvalue(), content_type='application/vnd.openxmlformats-officedocument.wordprocessingml.document' ) response['Content-Disposition'] = 'attachment; filename=' + docx_title response['Content-Length'] = length return response
可选优化:释放Matplotlib资源
在create_image函数中,添加plt.close(fig)彻底释放图形资源,避免内存泄漏:
def create_image(): # ... 原有代码 ... plot.get_figure().clf() plt.close(fig) # 新增:关闭图形释放资源 results['score_image'] = image # ...
修改后,生成的Word文档会正确解码并显示图片,而非base64字符串。
内容的提问来源于stack exchange,提问作者RobMcC
相关产品推荐
相关产品推荐

