python使用python-docx库处理图片白框问题

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)

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

缱绻命运

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值
>