每到年终时,公司都要举办年会,总结当年的得失。还有就是组织个晚会,表演些节目,抽奖......当然,还有,赏大餐一顿。人事部的妹子这时就发愁了,忙碌地进行各种准备不说,还要给供应商,政府部门发邀请函。这个邀请函其实除了受邀者的名字不同外,其它信息完全一样,纯粹的体力活。这种脏累活儿,就交给Python来干吧。 首先,我们需要将所有受邀者的公司名和代表姓名填入一个Excel表格。然后做好邀请函的模板,在需要填字的地方打上小星星“****”,然后就让Python来玩填字游戏啦。话不多说,直入主题,代码走一波......
#1.从Excel文件获取受邀人单位和名字 from openpyxl import load_workbook wb=load_workbook('data/name_list.xlsx') ws=wb['name'] names=[] for row in range(2,ws.max_row+1): company=ws['A'+str(row)].value name=ws['B'+str(row)].value names.append(' {} {} '.format(company,name)) names >>[' 供应商1 王波 ', ' 供应商2 刘海洋 ', ' 供应商3 少和光 ', ' 供应商4 真凡巧 ', ' 供应商5 鲁鸿运 ', ' 政府1 乐清霁 ', ' 政府2 郎绮琴 ', ' 政府3 贝芳懿 ', ' 政府4 哈彦君 ']
我们首先导入openpyxl 模块中的load_workbook 模块。openpyxl 是一个可读取Excel的第三方库。load_workbook() 可打开一个现有的Excel文件(或叫工作簿)。我们使用load_workbook(path) 读取文件,并存在变量wb 里面。我们可以想象变量就是容器,用来储存各种数据,这里的wb 就是这个容器的名字。wb 存储的是整个工作簿的内容,我们知道一个Excel有几个工作表“Sheet”,接下来我们需要选取我们所需要的“Sheet”,也就是名字叫'name'的那张表。当然你可以给这个工作表起自己喜欢的名字,在写代码的时候把wb['name'] 中的'name'字样替换成你的个性化名字即可。 然后定义一个空列表names 来存储受邀人单位和名字信息。随后我们遍历工作表,将所有信息提取出来存入列表names 。因为工作表第一行是标题,所以我们从第2行开始,最大一行+1结束range(2,ws.max_row+1) 。之所以要加1,是因为range(1,5)只能取到“1,2,3,4”四个值,5是取不到的。ws.max_row 指工作表的总行数。然后我们开始提取公司名称,company=ws['A'+str(row)].value ,当row取2时,就相当于将工作表中A2(即A列2行单元格的值)单元格的值传给了company变量。获取姓名也是类似的操作方式。
然后将公司名称和姓名排一下版,再加入names列表。' {} {} '.format(company,name) 这个格式化字符串函数就完成了这个操作。我们在公司名和姓名之间及前后都加入了一个空格,这样在最终的邀请函上看起来就是这样的:“尊敬的 供应商1 王波 先生/女士:”。不留空格的话,就变成这样了:“尊敬的供应商1王波先生/女士:”,似乎有点不和谐。格式化字符串可以理解为,将format(company,name)括号中的值依次填入前面的{}。
# 2.批量填字,存为不同的word文件 import docx #导入处理word的库,无耻地直接使用别人造好的轮子 doc=docx.Document('data/邀请函.docx') for name in names: doc.paragraphs[1].runs[2].text=name doc.save('data/邀请函_{}.docx'.format(name))
受邀人信息获取完成后,我们就可以开始批量生成邀请函了。首先导入处理word的库,无耻地直接使用别人造好的轮子。建立一个容器doc ,来盛装打开的邀请函,docx.Document('data/邀请函.docx') 为固定写法,括号内填写邀请函模板的路径及文件名。doc 可理解为就是这个名为“邀请函”word文件。然后遍历names 列表,将里面的信息逐个写入word文件的第二段的第三个run,即doc.paragraphs[1].runs[2].text=name ,相当于直接用name的值“ 供应商1 王波 ”替换掉**** 。其中的run指的是每一段中的不同的格式,比如一段中有常规的,有加粗的,有斜体的,有不同颜色的字,那么就有好几个run。
那我们怎么知道**** 是第二段第三个run呢?通过我们制作的“邀请函”模板,我们知道**** 位于第二段(即doc.paragraphs[1] ,因为是从0开始计数,所以0表示第一段,1就表示第二段)。请注意word中若有空行,也算一段,比如模板中的'ABC有限公司'开头的那一段已经算是第四段了。我么将第二段的所有run打印出来,就可以找到**** 所在的run了。 doc=docx.Document('data/邀请函.docx') for run in doc.paragraphs[1].runs: print(run.text)
>>尊敬 的 **** 先生 / 女士 :
我们可以看到其中有7个runs,虽然“尊敬的”三个字格式是一样的,但是还是被识别为两个单独的run了,可能这个库主要用来处理英文文档,拿来搞中文有些水土不服。不管它了,让它乱识别吧。通过以上的run打印,我们简单粗暴地数下去,可以知道**** 在第三个run,即run[2] 。 然后逐个保存为单个的文件,并在给新的word文件命名时加上受邀人的信息doc.save('data/邀请函_{}.docx'.format(name)) 。得到的结果如下:
了方便打印,可以使用word自带的合并功能将所有邀请函合并为一个word文件。打开第一个邀请函word文档,然后单击【插入】选项卡下的【对象】菜单中的【文件中的文字】选项,选择剩余的所有邀请函word文件,点插入,搞定!
所有源代码和说明都在Jupyter notebook上完成,所用到的Excel 资料已上传GitHub, 欢迎Fork或下载到本地随意玩。。。转载请注明出处,谢谢。 GitHub链接: https://github.com/weidylan/Office_Automation_by_Using_Python
|