在工程Word文档的大量表格中自动插入图片的python程序

  • 一、问题描述
  • 在word的表格中插入图片代码
  • 图形界面GUI设计
  • 程序打包

一、问题描述

我的姐姐是一个工程技术公司的资料员,经常需要在word文档的表格中插入图片(就是那种类似修路的每100米插入几张照片这种简单重复的工作,其中每100米都有一个单独的表格,一项工程通常几十公里,手动插入图片,还要调整图片大小,工作量还是有的),有一次拜托我帮她完成这样工作,我就想到了写个程序来做这件事,不是一劳永逸的事吗?于是便开始了程序编写工作,语言选择方面,我选择了Python,毕竟“人生苦短,我用python”不是盖的。

在word的表格中插入图片代码

这部分代码主要应用了docx包,有个小坑就是,不要直接装docx。

pip install docx

如果直接装这个docx包,会有些小问题,因为这个包比较老(也有可能是我的pycharm比较新)。我是直接装的python-docx包,和docx包的用法一样,不过不会报错。

pip install python-docx

我一开始装的是docx,会报错,然后找到以下链接解决的:
链接: link

以下是在word的表格中插入图片的代码:

def insert_pictures_to_word(word_in_path,word_out_path,pictures_in_path,row,column,width,height):origin_word_directory=word_in_pathresult_directory=word_out_pathorigin_pictures_directory=pictures_in_pathword_insert_row=int(row)-1word_insert_column=int(column)-1picture_width=int(width)picture_height=int(height)print(origin_word_directory)print(result_directory)print(origin_pictures_directory)print("word_insert_row: ",word_insert_row)print("word_insert_column: ",word_insert_column)print("picture_width: ",picture_width)print("picture_height: ",picture_height)# 获取输入目录下的所有word文件import osword_files_list=[]for files in os.walk(origin_word_directory,topdown=False):for file in files[2]:word_files_list.append(file)print("len(word_files_list) = ",len(word_files_list))# 获取输入图片目录下的所有图片名称picture_file_list=[]for files in os.walk(origin_pictures_directory,topdown=False):for file in files[2]:picture_file_list.append(file)print("len(picture_file_list) = ",len(picture_file_list))# 挨个向目录中的word文件表格中插入图片for origin_name in word_files_list:# 临时文件跳过if '~' == origin_name[0]:continueorigin_doc=origin_word_directory+'/'+origin_name# 打开模板文件document = Document(origin_doc)print("打开文件 ",origin_doc," 成功")tables=document.tablesprint(len(tables)) # len(tables)表示word文档中表格的总个数import osfiles = os.listdir(origin_pictures_directory)  # 读入文件夹num_jpg = len(files)  # 统计文件夹中的文件个数print(num_jpg)  # 打印文件个数# 图片预处理from PIL import Imagefor i in range(len(tables)):tb = tables[i]  # 现在遍历到第i个表格# 获取表格的行tb_rows = tb.rows# 读取每一个表格第六行的内容row_data = []row_cells = tb_rows[5].cellsrun = tb.cell(word_insert_row, word_insert_column).paragraphs[1].add_run()# 产生文件夹内图片数量范围内的两个随机数var=1# rand_num1={'rand_num1':0}# rand_num2={'rand_num1':0}rand_num1=0rand_num2=0while var==1:rand_num1=np.random.randint(1,num_jpg+1)rand_num2=np.random.randint(1,num_jpg+1)if rand_num2!=rand_num1:break# 利用生成的两个随机数重新生成两个随机图片的路径rand_path1=origin_pictures_directory+'/'+picture_file_list[rand_num1-1]rand_path2=origin_pictures_directory+'/'+picture_file_list[rand_num2-1]f1 = Image.open(rand_path1)  # 你的图片文件f1.save(rand_path1)  # 替换掉你的图片文件f1.close()f2 = Image.open(rand_path2)  # 你的图片文件f2.save(rand_path2)  # 替换掉你的图片文件f2.close()# 图片居中设置# paragraph = document.add_paragraph()# paragraph.alignment = WD_PARAGRAPH_ALIGNMENT.CENTER# 插入两张随机序号图片picture1 = run.add_picture(rand_path1)picture2 = run.add_picture(rand_path2)picture1.height = Cm(picture_height) # 设置图片高度picture1.width = Cm(picture_width) # 设置图片宽度picture2.height = Cm(picture_height) # 设置图片高度picture2.width = Cm(picture_width) # 设置图片宽度print("插入第 ",i," 张表成功!")print("插入图片到 ",origin_doc, " 成功")# 组织输出word的pathresult_file_name=result_directory+'/'+'result_'+origin_namedocument.save(result_file_name)print("###################################################################")print('\n')print("#######插入图片完成#######")

我在写代码过程中遇到的几个问题:

  1. tkinter的button控件中的command参数默认是函数名,不能带参数,找到了以下文章,解决了该问题:
    链接: Python——如何向 Tkinter 按钮命令中传递参数
    2.我想在UI的多行文本控件中展示整体插入图片的过程,就是将控制台标准输出重定向到tkinter的多行文本控件中,参考的是以下博客:
    链接: python利用重定向知识将print输出到tkinter.Text多行文本控件上

图形界面GUI设计

由于我姐基本没接触过编程,因此有必要做个图形界面,方便使用,这部分主要用的python的原生GUI包tkinter。图形界面的代码如下:

if __name__ == '__main__':# main()root = Tk() # 主界面root.geometry("1150x600+100+100")# 设置主界面窗体宽和高,设定窗口位置x=1000,y=1000,单位都是像素pixelroot.wm_title('Insert_pictures_into_Word-Tool')  # 页面名称# anchor = 'w'  # 文本区域左对齐,可填'n','s','e',w',是英文中北,南,东,西的首字母# justify = 'left'  # 多行文本时行左对齐,可填'left','right','center'Label(root,text='请选择目标Word文档所在文件夹的路径:',font=("宋体",12),width=50,anchor = 'w',justify="left").place(x=40,y=20)word_in_path={'word_in_path':""}def choose_word_path():word_directory = tkinter.filedialog.askdirectory()if word_directory != '':word_in_path['word_in_path']=word_directorylb1.config(text="您选择的文件夹是:" + word_directory,font=("宋体", 12),height = 0,width = 0)lb1.place(x=40,y=90)else:lb1.config(text="您没有选择任何文件夹!",font=("宋体", 12), height=0,width=0)lb1.place(x=40, y=90)lb1 = Label(root, text='')lb1.pack()btn1 = Button(root, text="弹出选择文件夹对话框", command=choose_word_path,font=("宋体", 12),height=0, width=0)btn1.pack()btn1.place(x=40, y=50)  # 设置按钮位置,该语句必须放在加载到窗体后才生效# 设置输出Word的保存路径Label(root, text='请选择输出Word的保存路径:',font = ("宋体", 12), width = 50, anchor = 'w', justify = "left").place(x=40, y=130)word_out_path = {'word_out_path':""}def choose_save_path():filename2 = tkinter.filedialog.askdirectory()if filename2 != '':word_out_path['word_out_path']=filename2lb2.config(text="您选择的文件夹是:" + filename2, font=("宋体", 12), height=0, width=0)lb2.place(x=40, y=200)else:lb2.config(text="您没有选择任何文件夹!",font=("宋体", 12), height=0,width=0)lb2.place(x=40, y=200)lb2 = Label(root, text='')lb2.pack()btn2 = Button(root, text="弹出选择文件夹对话框", command=choose_save_path, font=("宋体", 12), height=0, width=0)btn2.place(x=40, y=160)  # 设置按钮位置,该语句必须放在加载到窗体后才生效#设置要插入图片所在文件夹的路径Label(root,text='请选择要插入图片所在文件夹的路径:',font=("宋体",12),width = 50, anchor = 'w', justify = "left").place(x=40, y=250)pictures_in_path ={'pictures_in_path':""}def choose_pictures_path():filename3 = tkinter.filedialog.askdirectory()if filename3 != '':pictures_in_path['pictures_in_path']=filename3lb3.config(text="您选择的文件夹是:" + filename3, font=("宋体", 12), height=0,width=0)lb3.place(x=40, y=320)else:lb3.config(text="您没有选择任何图片文件夹!",font=("宋体", 12), height=0,width=0)lb3.place(x=40, y=320)lb3 = Label(root, text='')lb3.pack()btn3 = Button(root, text="弹出选择文件夹对话框", command=choose_pictures_path, font=("宋体", 12), height=0,width=0)btn3.place(x=40, y=280)  # 设置按钮位置,该语句必须放在加载到窗体后才生效Label(root,text='请输入图片要插入Word文档表格的行数:',font=("宋体",12),width = 50, anchor = 'w', justify = "left").place(x=40, y=370)row=Entry(root,width=30)row.place(x=45,y=400)Label(root,text='请输入图片要插入Word文档表格的列数:',font=("宋体", 12),width=50, anchor='w', justify="left").place(x=350, y=370)column=Entry(root,width=30)column.place(x=355,y=400)Label(root,text='请输入图片在Word文档表格中的宽度:', font=("宋体", 12), width=50, anchor='w', justify="left").place(x=40, y=440)width=Entry(root,width=30)width.place(x=45,y=470)Label(root,text='请输入图片在Word文档表格中的高度:',font=("宋体", 12), width=50, anchor='w', justify="left").place(x=350, y=440)height=Entry(root,width=30)height.place(x=355,y=470)class myStdout():  # 重定向类,将标准输出重定向到多行文本控件def __init__(self):# 将其备份self.stdoutbak = sys.stdoutself.stderrbak = sys.stderr# 重定向sys.stdout = selfsys.stderr = selfdef write(self, info):# info信息即标准输出sys.stdout和sys.stderr接收到的输出信息t.insert('end', info)  # 在多行文本控件最后一行插入print信息t.update()  # 更新显示的文本,不加这句插入的信息无法显示t.see(tkinter.END)  # 始终显示最后一行,不加这句,当文本溢出控件最后一行时,不会自动显示最后一行def restoreStd(self):# 恢复标准输出sys.stdout = self.stdoutbaksys.stderr = self.stderrbakmystd=myStdout()  # 实例化重定向类t=tkinter.Text(root,font=("宋体", 12),width=50, height=30)  # 创建多行文本控件t.pack() # 布局在窗体上t.place(x=700, y=50)# 设置函数入口按钮btn =Button(root,text='开始插入图片',command=lambda:insert_pictures_to_word(word_in_path['word_in_path'],word_out_path['word_out_path'],pictures_in_path['pictures_in_path'],row.get(),column.get(),width.get(), height.get()),font=("宋体", 18), height = 0, width = 20)# 在默认的系统字体中,水平文本单位等于字符 0 的宽度,垂直文本单位等于 0 的高度。btn.pack()#加载到窗体btn.place(x=250,y=520)# 设置按钮位置,放在加载到窗体语句后才可以生效root.mainloop()mystd.restoreStd()  # 恢复标准输出

精力有限,就随便做了个稍微能看的界面,具体界面展示如下图:

程序打包

本来我想的是让我姐装个python和Anaconda,但是着实很费劲,而且最后也没装好,索性自己打个包。
程序打包我用的是pyinstaller,这里注意有一个坑:
平时我写代码用的都是默认python的base环境,没有想太多,直接就打包了,结果打个包花了好长时间,最后exe包出来有260M,我一想,不对劲啊,我这代码就几百行,引用了几个包,怎么会这么大,遂必应搜索了一波,发现是因为base环境包含了你在python上装的所有包,即使你的程序里没有使用其他包,在base环境下打包也会将你未使用的包装进你打的程序包里。一般都是自己建一个虚拟环境,只把你程序用到的几个包装上,然后在自建的虚拟环境下打包,这样你的程序包就没有多余的东西。在自建了虚拟环境后,打包就快了很多,而且包由260M,直接缩小到26M左右。下图为base环境和自建环境下打的包的大小对比截图。

【在工程Word文档的大量表格中自动插入图片的python程序】相关推荐

  1. Word文档粘贴的表格中文字有淡灰色背景的去除方法

    直接从excel粘贴过来的表格 特征: 无论怎么改字符的底色还是边框底纹都无法去除: 更改字符底纹,该底纹也没有变化: 更改各种格式样式都无法消除: 各种格式刷都不管用. 光标移到别处不会显示灰色背景 ...

  2. matlab制作的表格引入word文档,在Excel表格中插入Word文档的三种方法

    在Excel文档中,插入或链接Word数据一般有利用复制粘贴插入Word文档内容.直接插入Word文档.将Excel表格的内容链接到Word文档3种方法. 一.利用复制粘贴插入Word文档内容 如果用 ...

  3. Java 导出word文档,遍历表格数据,导出图片

    引用:https://www.cnblogs.com/pxblog/p/13072711.html 1.引入maven依赖: <dependency><groupId>cn.a ...

  4. java读取word文档的复杂表格_poi读取word表格 java POI 如何读取word的表格中的表格...

    poi 操作word 2007 (如何删除word中的某一个表格)小编忘了哪年哪月的哪日小编在哪面墙上刻下张脸张微笑着忧伤着凝望小编的脸. public static void changeTable ...

  5. 如何在微信公众号推文加入Word文档、Excel表格,超实用30秒学会

    大家都知道,当我们订阅了公众号(关注公众号),公众号的运营者就能给我们推送最新发布的公众号文章,我们也能在订阅号栏收到最新的文章.有一些微信公众号推文中会有附件,如word文档.excel表格,比如政 ...

  6. 【教程】微信推文怎么添加附件文档 (如word文档、excel表格、pdf文件)

    对于很多企业单位.中小学校公众号来说,有时在对外发布信息时,需要在公众号文章中插入各种文档附件,如:应聘报名表.健康承诺书.记录统计表.防疫登记表.申报评分.公告通知等,文件类型有:word文档.ex ...

  7. word文档转excel表格

    使用java语言将 word文档转excel表格,首先导入apache的poi依赖 <dependency><groupId>org.apache.poi</groupI ...

  8. 「教程」秀米怎么添加附件(Word文档、Excel表格等)

    [教程]秀米怎么添加附件(Word文档.Excel表格等) 秀米作为一款微信公众号文章编辑器,因为模板众多,操作方便,很受公众号运营者的喜欢.但是很多运营者不知道怎么通过秀米给公众号文章添加附件,秀米 ...

  9. python排版word文档命令方法大全_教你怎么使用Python对word文档进行操作

    使用Python对word文档进行操作 一.安装Python-docx Python-docx是专门针对于word文档的一个模块,只能读取docx 不能读取doc文件.说白了,python就相当于wi ...

最新文章

  1. POJ1523 SPF tanjar割点求块数
  2. 用于制图、写电子邮件、创建条形码控件Aspose.Total
  3. 51..分治算法练习:  4378 【Laoguo】循环比赛
  4. eclipse 面包屑开关 / 查看class再哪个jar中
  5. Bootstrap CustomBox 弹层
  6. 使用自己的数据集训练MobileNet、ResNet实现图像分类(TensorFlow)
  7. CentOS 7 install Zabbix3.4
  8. 19、java中枚举
  9. qpsk的matlab平方根升余,【求助】求助:【QPSK功率谱密度的matlab的代码】 - 仿真模拟 - 小木虫 - 学术 科研 互动社区...
  10. CUDA程序kernel函数的运行时间限制
  11. mysql中不能update与safe update mode 有关
  12. 什么是pytorch_什么是Pytorch?
  13. 通用权限管理系统组件 (GPM - General Permissions Manager) 中实现系统参数配置保存,附源码...
  14. Hbase记录-client访问zookeeper大量断开以及参数调优分析(转载)
  15. python爬虫怎么翻页_python爬虫怎么实现翻页
  16. oracle数据库报01033,oracle数据库报ORA-01033错误
  17. C语言统计1到100素数的个数,统计1到100素数的个数
  18. 自强不息系列之Java 实例 - 线程优先级设置
  19. Google analytics如何统计网站信息?
  20. 解压压缩包的时候要求输入密码

热门文章

  1. 难得和你相遇,用来生气多可惜
  2. 交换机如何配置SNMP(简单网络管理协议)
  3. NAT地址转换(又称为网络地址转换,用于实现私有网络和共有网络之间的互相访问)
  4. Kubernetes 资源清单与Pod生命周期
  5. 线上展会之桥批与金融历史文化3D线上展厅
  6. 你必须要学会的动态代理
  7. 关于——GitHub注册问题详细解决步骤
  8. 如何做一个基于JAVA多用户B2C商城系统毕业设计毕设作品(springboot框架)
  9. 将PPT文件内容转换为图片放在Email邮件正文中发送
  10. 51单片机调时电子钟