python-docx 在word中指定位置插入图片或表格

docx库add_picture()方法不支持对图片位置的设置

1、新建一个1行3列的表格,在中间的一列中插入图片

from docx import Document
from docx.shared import Pt
from docx.oxml.shared import OxmlElement
from docx.enum.text import WD_ALIGN_PARAGRAPH

def add_center_picture(self, image_path_or_stream, width=None, height=None):
 
    # run = self.doc.add_paragraph().add_run()
 
    tab = self.doc.add_table(rows=1, cols=3) # 添加一个1行3列的空表
 
    cell = tab.cell(0, 1) # 获取某单元格对象(从0开始索引)
 
    ph =cell.paragraphs[0]
 
    run = ph.add_run()
 
    # run.add_break()
 
    run.add_picture(image_path_or_stream, width=width, height=height)

2、在第一段右边加图片

from docx import Document
from docx.shared import Pt
from docx.oxml.shared import OxmlElement
from docx.enum.text import WD_ALIGN_PARAGRAPH

def add_log_img(doc, log_path):
	# log_path : 图片本地地址
    doc.add_picture(log_path, width=Pt(100), height=Pt(100))
    doc.paragraphs[0].alignment = WD_ALIGN_PARAGRAPH.RIGHT
    return doc

3、指定位置(占位符替换)插入图片

  • 原模板文档(箭头处是占位符)
    在这里插入图片描述

  • 插入图片后
    在这里插入图片描述

from docx import Document
from docx.shared import Inches
from docx.oxml.ns import qn
from docx.enum.text import WD_ALIGN_PARAGRAPH


def center_insert_img(doc, img):
    """插入图片"""
    for paragraph in doc.paragraphs:
        # 根据文档中的占位符定位图片插入的位置
        if '<<img1>>' in paragraph.text:
            # 把占位符去掉
            paragraph.text = paragraph.text.replace('<<img1>>', '')
            # 添加一个文字块
            run = paragraph.add_run('')
            # 添加一个’回车换行效果‘
            run.add_break()
            # 添加图片并指定大小
            run.add_picture(img, width=Inches(6.2))


def save_img_to_doc(img):
    """把图片保存到doc文件中的指定位置"""
    tpl_doc = 'reports/template.docx'
    res_doc = 'reports/res/2022-03-11.docx'
    # 打开模板文件
    document = Document(tpl_doc)
    # 插入图片居中
    center_insert_img(document, img)
    # 保存结果文件
    document.save(res_doc)


def main():
    """主函数"""
    img = 'imgs/chart.png'
    save_img_to_doc(img)


if __name__ == '__main__':
    main()

  • 占位符问题
    <<img1>>这个只是占位符,可以换成其他任何的,只要能唯一识别到,比如ph_img1。有时无法替换是因为程序中读取doc文件时格式问题没把占位符识别成一个,可能识别成了ph_和img1,这个时候你把占位符选中,剪切掉然后再粘贴,粘贴时选择只粘贴文字就行了。

4、在table的一个cell中插入图片


from docx import Document 
from docx.shared import  Cm #引入cm单位,便于设置图片的宽度
from docx.enum.table import WD_TABLE_ALIGNMENT #用于设置单元格的内容居中对齐



def insert_img2table():
	#创建文档
	document = Document()
	# 添加表格
	tab1 =document.add_table(rows=1,cols=1)   #添加一个1行1列的空表
	cell=tab1.cell(0,0)  #获取某单元格对象(从0开始索引)
	# 在单元格中添加段落
	c_p1 =cell.paragraphs[0]
	c_p1.paragraph_format.alignment = WD_TABLE_ALIGNMENT.CENTER #设置单元格内容居中对齐
	# 在单元格中添加区块
	c_run1=c_p1.add_run()
	# 在单元格(区块)中添加图片
	c_run1.add_picture('cat.png',width=Cm(10))
	return document 

5、python使用docx向word文档中表格插入图片并固定缩放

使用python的docx模块对word文档进行编辑时,有时候需要向表格中插入图片,但是插入的图片一般是按照原图片的大小插入的,即使你的word文档一开始就设置好了固定宽高,似乎也是不起作用,这个时候就需要在插入后,用python去调整图片的宽高。

#向word文档中的第二个表格的第3行第3列插入了一个图片。
#然后获取当前图片的高度,将其宽度调整为固定的10.71cm,再然后通过计算宽度变化的比例,调整高度的变化。
# 最后将文档保存为一个新的docx文件即可
from docx import Document
from docx import shared
 
# 本脚本用于测试word文件的表格写入
 
document = Document("test.docx")
 
#向word文档中的第二个表格的第3行第3列插入了一个图片。
pic = document.tables[1].cell(2,2).paragraphs[0].add_run().add_picture("Output_1.png")
#获取原图片的宽度
source_width = pic.width
#设置图片插入后的固定宽度
pic.width = shared.Cm(10.71)
#按图片宽度的缩放比例配置图片的高度
pic.height = int(pic.height * (pic.width / source_width))
 
document.save("1.docx")

6、通过python-docx给word文档中的指定位置添加表格

1.读取一个已有的word文档。docx格式。
2.在该word文档中,通过一个给定的文字。找到该位置。在该位置的下方添加一个表格。例如在图中“BUG情况表”的下方插入一个表格

6.1 需求

1.读取一个已有的word文档。docx格式。
2.在该word文档中,通过一个给定的文字。找到该位置。在该位置的下方添加一个表格。例如在图中“BUG情况表”的下方插入一个表格
在这里插入图片描述
3.表格内容如下。要求添加完该表格后,如果表格内容发生变更。还能再次通过该程序,修改表格里的数据。
在这里插入图片描述

6.2 设计
  • 通过python-docx读取word文档。通过document.paragraphs定位指定文字的位置。
  • 通过xlwings读取excel的内容,存成list[list[]]。
  • 通过docx的add_table增加一个表格,并且更改表头颜色,合并表格等操作
  • 通过识别表头的第一行,判断是否是已经存在这个表格,来决定是否要删除原表格
# -*- coding: UTF-8 -*-
import sys
from copy import deepcopy
import xlwings
from docx import Document
from docx.oxml.ns import nsdecls
from docx.oxml import parse_xml
def copy_table_after(table, paragraph):
    tbl, p = table._tbl, paragraph._p
    new_tbl = deepcopy(tbl)
    p.addnext(new_tbl)
def move_table_after(table, paragraph):
    tbl, p = table._tbl, paragraph._p
    p.addnext(tbl)
def get_excel_date(filename):
    '''
    获得excel里的所有内容,返回list
    :param filename:  excel路径
    :return: list[list[]]
    '''
    app = xlwings.App(visible=False, add_book=True)
    app.display_alerts = False
    app.screen_updating = False
    wb = app.books.open(filename)
    sht = wb.sheets[0]
    rng = sht.range('A1')
    # 把excel里的数据读取成 年-月-日 时:分:秒的格式
    my_date_handler = lambda year, month, day, hour, minute, second, **kwargs: "%04i-%02i-%02i %02i:%02i:%02i" % (
        year, month, day, hour, minute, second)
    # 取出所有内容,这里用ig这个变量,是为了庆祝I.G获得LOL S8赛季总冠军
    ig = rng.current_region.options(index=False, numbers=int, empty='N/A', dates=my_date_handler)
    result = ig.value
    wb.close()
    app.quit()
    return result
def delete_table_with_title(document,expect_text):
    allTables = document.tables
    for activeTable in allTables:
        if activeTable.cell(0, 0).paragraphs[0].text == expect_text:
            print('删除成功')
            activeTable._element.getparent().remove(activeTable._element)
def insert_table_after_text(file_name,excel_name,expect_text):
    document = Document(file_name)
    # 因为docx读出来的都是unicode类型的,所以我们要用unicode类型的进行查找
    expect_text=expect_text.decode('utf-8')
    delete_table_with_title(document,expect_text)
    target = None
    for paragraph in document.paragraphs:
        paragraph_text = paragraph.text
        if paragraph_text.endswith(expect_text):
            target = paragraph
            break
    if target is not None:
        records = get_excel_date(excel_name)
        # 获得excel数据的栏数,初始化一个空的table
        col = len(records[0])
        table = document.add_table(rows=1, cols=col)
        table.style = 'Table Grid'
        # 给table加一个表头,并且合并第一栏
        shading_elm_1 = parse_xml(r'<w:shd {} w:fill="D9E2F3"/>'.format(nsdecls('w')))
        table.rows[0].cells[0]._tc.get_or_add_tcPr().append(shading_elm_1)
        table.rows[0].cells[0].text=expect_text
        table_row=table.rows[0]
        first=table_row.cells[0]
        end=table_row.cells[-1]
        first.merge(end)
        # 合并结束,开始把excel里的内容添加到table里
        for tr_list in records:
            row_cells = table.add_row().cells
            index = 0
            for td_list in tr_list:
                row_cells[index].text = td_list
                index = index + 1
        # 把添加的table移动到指定的位置
        move_table_after(table, target)
        # 保存
    document.save(file_name)
if __name__ == '__main__':
    insert_table_after_text('demo2.docx', 'demo.xlsx',"BUG情况表")

最终效果:

在这里插入图片描述


参考

官方文档
github/python-docx
python-docx生成word,插入图片居中显示问题解决办法
python-docx替换字符串【保存原有样式
Python在word的指定位置插入图片
feature: _Cell.add_picture() #10
python使用docx向word文档中表格插入图片并固定缩放
python如何在docx的指定位置插入图片?
通过python-docx给word文档中的指定位置添加表格
python-docx中文

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/648665.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

Jenkins安装 :Aws EC2下Docker镜像安装

1 安装docker # 安装docker $ sudo yum install -y docker# 启动docker daemon $ sudo systemctl start docker# 用户加入docker组 $ sudo usermod -aG docker username 2 docker安装jenkins $ docker pull jenkins/jenkins:lts# 安装成功 $ docker images REPOSITORY …

动手学深度学习22 池化层

动手学深度学习22 池化层 1. 池化层2. 实现3. QA 课本&#xff1a; https://zh-v2.d2l.ai/chapter_convolutional-neural-networks/pooling.html 视频&#xff1a; https://www.bilibili.com/video/BV1EV411j7nX/?spm_id_fromautoNext&vd_sourceeb04c9a33e87ceba9c9a2e5f0…

第三方软件测试机构进行代码审计需要哪些专业的知识?

代码审计 进行代码审计需要专业的知识&#xff0c;包括编程语言、操作系统、数据库、网络知识以及安全知识等。 1.编程语言知识是进行代码审计的基础&#xff0c;因为你需要理解代码的语法和结构。对于不同的应用程序&#xff0c;你需要了解其所使用的编程语言的特点和语法规…

IO多路复用模型原理

在linux没有实现epoll事件驱动机制之前,常规的手段是选择select和poll等IO多路复用的方法来实现并发服务程序。但是在大数据、高并发、集群情况下,select和poll的性能瓶颈就出现了,于是epoll就诞生了 Select select函数监视的文件描述符分三类:writefds、readfds和exceptf…

Windows64位操作系统安装汇编语言环境

1、下载好MASM工具, 并存放在指定路径 2、再安装一个DOSBox 3、打开DOSBox, 并使用 mount 将刚刚存放MASM的路径挂在到C盘&#xff0c;然后进入C盘就可以使用 MASM的命令工具了。 例如&#xff1a; mount c G:\install\study\MASM C:但是DOSBox默认打开的窗口是很小的&…

openwrt 官方版 安装配置 AdGuard Home + smartdns 告别广告烦扰 教程 软路由实测 系列五

1 安装 adguard home opkg update opkg install adguardhome #启动 /etc/init.d/adguardhome start /etc/init.d/adguardhome enable #查看 rootOpenWrt:~# ps| grep AdGuardHome5101 root 1233m S /usr/bin/AdGuardHome -c /etc/adguardhome.yaml -w /var/adguardhom…

深入解读力扣154题:寻找旋转排序数组中的最小值 II(多种方法及详细ASCII图解)

❤️❤️❤️ 欢迎来到我的博客。希望您能在这里找到既有价值又有趣的内容&#xff0c;和我一起探索、学习和成长。欢迎评论区畅所欲言、享受知识的乐趣&#xff01; 推荐&#xff1a;数据分析螺丝钉的首页 格物致知 终身学习 期待您的关注 导航&#xff1a; LeetCode解锁100…

深入了解Nginx(一):Nginx核心原理

一、Nginx核心原理 本节为大家介绍Nginx的核心原理,包含Reactor模型、Nginx的模块化设计、Nginx的请求处理阶段. &#xff08;本文源自微博客,且已获得授权&#xff09; 1.1、Reactor模型 Nginx对高并发IO的处理使用了Reactor事件驱动模型。Reactor模型的基本组件包含时间收集…

vue实现页面渲染时候执行某需求

1. 前言 在之前的项目中&#xff0c;需要实现一个监控token是否过期从而动态刷新token的功能&#xff0c;然而在登录成功后创建的监控器会在浏览器刷新点击或者是通过导航栏输入网址时销毁... 2. 试错 前前后后始过很多方法&#xff0c;在这里就记录一下也许也能为各位读者排…

JWT的生成

引依赖 生成JWT JWT校验 注意

从alpine构建预装vcpkg的docker image用于gitea actions CI

动机 想要构建一个基于vcpkg的交叉编译容器平台用于cpp项目的CI(自动集成),此处仅提供最基础的image,amd64的机子上构建完成后大小为533兆(着实不小😓),各位看官可以在此基础上自行构建需要的版本。 hello world效果展示 corss_compiler.dockerfile FROM alpine:la…

数据结构篇之二叉树(binary tree)的介绍和应用

欢迎光临&#xff1a; 男神 目录 一树的介绍和表示&#xff1a; 二二叉树的介绍及性质&#xff1a; 三堆的介绍及创建&#xff1a; 1堆的创建&#xff1a; 2堆的应用&#xff1a; 四二叉树的创建&#xff1a; ①// 通过前序遍历的数组"ABD##E#H##CF##G##"构建二…

2024年中国电机工程学会杯数学建模思路 - 案例:最短时间生产计划安排

# 前言 2024电工杯(中国电机工程学会杯)数学建模思路解析 最新思路更新(看最新发布的文章即可): https://blog.csdn.net/dc_sinor/article/details/138726153 最短时间生产计划模型 该模型出现在好几个竞赛赛题上&#xff0c;预测2022今年国赛也会与该模型相关。 1 模型描…

Flink常见面试题总结

文章目录 1. 简单介绍一下Flink2. Flink 的运行必须依赖Hadoop组件吗?3. Flink 和 Spark Streaming 的区别&#xff1f;4. Flink集群角色5. Flink核心概念5.1 并行度5.2 算子链&#xff08;Operator Chain&#xff09;5.3 任务槽&#xff08;Task Slots&#xff09;5.4 任务槽…

【PCI】PCIe高级错误上报能力AER(十二)

本文参考PCIe协议 5.0&#xff1a;https://download.csdn.net/download/zz2633105/89204842 本文参考intel IP用户指南&#xff1a;https://www.intel.cn/content/www/cn/zh/docs/programmable/683501/23-2-10-0-0/debugging-data-transfer-and-performance-25123.html 本文参…

技术前沿:三品PLM系统引领工程变更管理新趋势

引言 在当今快速变化的制造行业&#xff0c;产品生命周期管理&#xff08;PLM&#xff09;系统已成为企业不可或缺的工具之一。PLM系统不仅帮助企业优化产品开发流程&#xff0c;还对工程变更管理&#xff08;ECM&#xff09;起着至关重要的作用。本文将探讨PLM系统在工程变更…

机器学习之词袋模型

目录 1 词袋模型基本概念 2 词袋模型的表示方法 2.1 三大方法 1 独热表示法&#xff08;One-Hot&#xff09; 2 词频表示法&#xff08;Term Frequency, TF&#xff09; 3 词频-逆文档频率表示法&#xff08;TF-IDF&#xff09; 2.2 例子 1 词袋模型基本概念 词袋模型&a…

SpringValidation

一、概述&#xff1a; ​ JSR 303中提出了Bean Validation&#xff0c;表示JavaBean的校验&#xff0c;Hibernate Validation是其具体实现&#xff0c;并对其进行了一些扩展&#xff0c;添加了一些实用的自定义校验注解。 ​ Spring中集成了这些内容&#xff0c;你可以在Spri…

【深度学习基础】NumPy数组库的使用

目录 写在开头 一、数组的类型与维度 数组的类型 数组的维度 二、数组的创建 递增数组 同值数组 随机数数组 三、数组的索引 访问/修改单个元素 花式索引 数组的切片 四、数组的变形 数组的转置 数组的翻转 数组的形状改变 数组的拼接 五、数组的运算 数…

Simulate Ring Resonator in INTERCONNECT

Simulate Ring Resonator in INTERCONNECT 正文正文 首先,我们采用 Interconnect 模块的工作流程 一文中介绍的方法添加一个直波导器件。接着,我们需要对它的名称进行更改,此时我们看左侧 Property View - Root Element 中的 General 属性,我们发现 name 属性是灰色的,无…