办公自动化/同学,你被录取了

去社区提问

简介:本节课用生成录取通知书的例子,教你使用Python读取Excel信息,批量生成通知书Word文件,并将通知书快速转换为pdf格式。

同学,你被录取了

通知书的麻烦事儿

又来到了一年一度的小象学院入学季,同学们经过寒窗苦读如愿进入心仪的大学。又有一大波自以为逃脱苦海的同学们即将从一个深渊走入另一个深渊中了~

还没准备好笑容就匆匆按下快门键的毕业照,定格了青春的匆匆岁月。

还记得当时收到录取通知书时激动的心情吗?

学校每年都要招收上千名新生,录取通知书又是如何一封封生成的呢?

想想都要耗费很大的时间和精力吧。

在霍格沃滋学院北京分校——小象学院,这一切就都不同啦~

我们会用Python会给这些重复性工作施魔法,分分钟搞定这些难题。

之前的课程里我们就说过,这类重复性的工作,最适合让Python来帮你解决,今天我就带你一起学习如何快速批量生成录取通知书。

首先来看看录取通知书长什么样子:

需要处理的工作就是:

  1. 根据每位学生的实际情况把学号,姓名,学院,专业的信息填写进Word表格。
  2. 把每位同学的通知书转换为pdf格式。

成千上万的学生,要准确无误地给每位同学制作通知书,万一出错后果可是不堪设想。

这巨大的工作量是不是又一次吓到你了。先来展示效果看看,安抚一下你现在紧张的心情:

上面的操作是不是看得有点眼花缭乱?

马上来为你解读!现在我们就一起揭秘这个案例是如何实现的。

特别提示:如果暂时不理解代码的含义也没有关系~只通过这些案例了解Python用途就达到了目标。12课时开始将进入详细的Python语法学习,要继续加油呀。

生成Word录取通知书

在开始操作之前,先来了解一下我们手里现在有的资源有哪些:

首先我们有一个录取通知书的Word模版,需要替换的部分用占位符(xx01xx,xx02xx等)标识。

新生的信息全部储存在一个Excel表格中:

表格的第一行是Word文档中需要替换的占位符,后面是每位学生的入学信息。

然后就,没了。下面就要靠一己之力完成这浩大的工程。

先来整理一下思路,再继续前进。

现在要把Excel里的信息填入录取通知书模版中,生成每位同学的通知书文档,要进行以下四个步骤。

  1. 先获取Excel和Word的文件名

  2. 读取Excel内数据

  3. 循环读取Word并替换占位符

  4. 保存文件

接下来正式开始表演啦!

获取Word和Excel文件

电脑中存储了很多表格和文本文件,需要时我们直接打开相应文件夹就可以找到,如何让计算机找到我们想要的文件呢?

在获取Excel和Word的文件名时,我们用到Python第三方库os中的listdir()方法。

os.listdir() 方法用于返回指定的文件夹包含的文件或文件夹名字的列表。

查看当前目录是否存在‘录取同学名单’和‘通知书模版’的文件,打印出结果:

代码练习:

编程区

  1. '''
  2. 判断当前目录下是否有‘录取同学名单.xlsx’和‘录取通知书模板.docx’
  3. '''
  4. from os import listdir
  5. xlsx_name=''
  6. docx_name=''
  7. for file in listdir():
  8. if '录取同学名单.xlsx' in file:
  9. xlsx_name = file
  10. print("录取学生信息存放在'"+xlsx_name+"'中")
  11. if '录取通知书模板.docx' in file:
  12. docx_name = file
  13. print("想要修改的模板是'"+docx_name+"'")

终端区

录取信息和模版都get啦,下面就来读取Excel表格中的数据。

读取Excel内数据

在生成通知书的过程中,对于Excel的操作主要是从表格中读取学生的数据信息。

这里我们要用到神奇的Openpyxl库。

Openpyxl是一个读写Excel的Python库,是一款比较综合的工具。

不仅能够读取和修改Excel文档,而且可以对Excel文件内单元格进行详细设置,包括单元格样式等内容,甚至还支持图表插入、打印设置等内容。

使用它也可以处理数据量较大的Excel文件。

夸了那么多,是时候来现实碰一碰了,真的有那么厉害吗?

不过在这里先铺垫一个小小的内容,你需要先掌握三个对象:

  • Workbook(工作簿,一个包含多个Sheet的Excel文件)

  • Worksheet(工作表,一个Workbook有多个Worksheet,如“Sheet1”,“Sheet2”等)

  • Cell(单元格,存储具体的数据对象)

一个Excel文件就是一个工作薄,可以从下面这张图直观看到三者的关系。

下面就要来读取Excel内的数据了。

首先打开Excel文件’录取同学名单.xlsx’。

  1. from openpyxl import load_workbook
  2. wb = load_workbook(xlsx_name)

下面用sheetx0得到Excel文件中的所有工作表(案例中Excel文件只有一个工作表)。

  1. sheetx0 = wb.sheetnames

选择我们所要操作的工作表。

  1. sheetx = wb[sheetx0[0]]

来查看一下Excel表格中共有多少行数据。

代码练习:

编程区

  1. sheetx.max_row

终端区

接下来可以按照行和列读取Excel单元格的数据,来看下第一行第一列的数据吧~

代码练习:

编程区

  1. sheetx.cell(row=1,column=1).value

终端区

想要获取Excel中第一行的所有数据该怎么做呢?只需要一个循环就能轻松实现了。

代码练习:

编程区

  1. for l in range(1,sheetx.max_column+1):
  2. print(sheetx.cell(row=1,column=l).value)

终端区

现在你已经掌握了读取Excel单元格数据的方法,下面的操作中,可以随心所欲地读取任意单元格的数据啦~

处理完Excel的读取任务,接下来研究研究如何把读取到的信息写入Word中。

读取docx文档

按照惯例还是先介绍一下我们即将用到,神通广大的第三方库。

对Word文档操作用到docx库。

docx库中的方法Document可以对Word文档进行读写操作。

首先打开Word文件,读取内容的所有段落。

  1. from docx import Document
  2. #打开Word文档
  3. document = Document(docx_name)
  4. #读取所有的自然段
  5. all_paragraphs = document.paragraphs

读取到文档内容后,我们要想方设法替换原文的内容。

在Python中除了可以直接调用第三方库中的方法,还可以自由定义函数方法,达到我们想要的目的。

简单来说自定义方法就像方便面一样,调料包都配好了,想吃的时候随时拿出来煮就可以~

下面我们自定义一个方法,使它能够实现新旧文本的替换的功能:

  1. def replace_text(old_text, new_text):
  2. #读取所有的自然段
  3. all_paragraphs = document.paragraphs
  4. for paragraph in all_paragraphs:
  5. for run in paragraph.runs:
  6. run_text = run.text.replace(old_text, new_text)
  7. run.text = run_text

完成啦,之后想要替换文本就可以直接调用replace_text这个方法。

生成并保存通知书文件

了解了上面这些功能的实现,我们就可以把Excel表格中每行学生信息和第一行占位符信息替换,匹配到Word文档中了。

表格中的数据共有18行,第一行是占位符,第二行是表头,从第三行开始是每位同学的入学信息。

所以在进行操作时,需要从第三行数据开始读取,把表中内容和Word文本中占位符替换,生成录取通知书文件。后面继续对每行进行相同操作就能得到同学们的录取通知书文档了。

这样的重复性工作计算机做起来”特别擅长并且速度超快“,而不仅仅是”能干活,不抱怨“。

计算机不怕苦不怕累,无聊的事情可以重复上千遍,这恰恰就是编程解放人类劳动的地方~

你再也不用弱小无助地担心大量重复工作堆积着做不完,被老板催进度了。

究其原理,其实是因为代码中的循环语句,可以把一件事情重复操作多次,让计算机能够重复自动地执行指令。

偷偷告诉你,现在添加小助手的微信,帮你解锁更多高效工作技巧和摸鱼技能哦~

上面所说的过程就可以用Python的for循环来实现,不管是十封通知书,还是一千封录取通知,编写代码时只需要改变循环次数就能轻松搞定。

代码练习:

编程区

  1. import os
  2. for row in range(3,sheetx.max_row+1):
  3. document = Document(docx_name)
  4. # openpyxl在使用sheetx.max_column时可能会读取到空的单元格,这里进行剔除
  5. if sheetx.cell(row=row,column=1).value!=None:
  6. # 录取通知书要素Excel中逐行循环
  7. for l in range(1,sheetx.max_column+1):
  8. # 获取Excel第一行的内容
  9. old_text = sheetx.cell(row=1,column=l).value
  10. # 对循环的Excel当前列逐行读取新要素
  11. new_text = sheetx.cell(row=row,column=l).value
  12. # 进行替换
  13. replace_text(str(old_text),str(new_text))
  14. # 定义文件名为当前列第一行的内容
  15. filename = str(sheetx.cell(row=row,column=1).value)
  16. # 按定义的文件名进行保存
  17. document.save(r"存放学生录取通知书Word文档/%s.docx"%(filename))
  18. print('学号{}学生的录取通知书已生成'.format(filename))

终端区

OK,Word版本的录取通知书就全部生成啦~并且文件都以学号命名。

批量转换PDF格式

等等,到这儿还没结束。

别忘了我们还有下一项任务:把通知书批量转换为pdf格式。

别担心,我们依然先来看一下运行效果:

完成转换操作需要下面三个步骤:

  1. 启动Word进程

  2. 遍历Word所在目录下的所有Word文件一一转化pdf

  3. 保存pdf

坚持一下,马上就能迎来最后的胜利了。

先来完成单一Word文档的转换方式,后续依然运用循环的方法就可以实现批处理的功能。

这里用到的模块是win32,它不是纯粹的Python模块,是windows功能和Office功能来实现的。

启动独立的进程

  1. import win32com.client
  2. wordApp = win32com.client.Dispatch('word.Application')

控制Word转化pdf过程是否可视化

这里选择不用可视化

  1. wordApp.Visible = False

接着先打开一个学生录取通知书的Word文档:

  1. import os
  2. filepath = os.getcwd()
  3. filepath = filepath+'\\'+'存放学生录取通知书Word文档\\20190601.docx'
  4. myDoc = wordApp.Documents.Open(filepath)
  5. myDoc

打开之后将它转化为pdf格式:

  1. import os
  2. output_file_path = os.getcwd() # PDF储存位置
  3. output_file_path = output_file_path + "\\" + "存放学生录取通知书PDF文档\\20190601.pdf"
  4. myDoc.ExportAsFixedFormat(output_file_path, 17, Item=7, CreateBookmarks=0)

可以看到成功生成了pdf格式的文件,最后关闭word进程:

  1. wordApp.Quit()

接下来我们把上面的转换pdf的步骤整合在一起:

  1. class Word_2_PDF(object):
  2. def __init__(self, filepath, wordVisible=False):
  3. """
  4. :param filepath:
  5. :param Debug: 控制过程是否可视化
  6. """
  7. # 启动独立的进程
  8. self.wordApp = win32com.client.Dispatch('word.Application')
  9. # 控制过程是否可视化
  10. self.wordApp.Visible = wordVisible
  11. # 打开文件夹
  12. self.myDoc = self.wordApp.Documents.Open(filepath)
  13. def export_pdf(self, output_file_path):
  14. """
  15. 将Word文档转化为PDF文件
  16. :param output_file_path:
  17. :return:
  18. """
  19. self.myDoc.ExportAsFixedFormat(output_file_path, 17, Item=7, CreateBookmarks=0)
  20. def close(self):
  21. self.wordApp.Quit()

了解了单个Word转化pdf的操作,接下来就要开始进行批处理操作。

定义生成的pdf文件都存放在“存放学生录取通知书PDF文档”的文件夹下。

  1. import win32com.client
  2. import pythoncom
  3. import os
  4. rootpath = os.getcwd() # 文件夹路径
  5. save_path = os.getcwd() # PDF储存位置
  6. if not os.path.exists('存放学生录取通知书PDF文档'):
  7. os.mkdir('存放学生录取通知书PDF文档')
  8. rootpath = rootpath + "\\" + "存放学生录取通知书Word文档"
  9. save_path = save_path + "\\" + "存放学生录取通知书PDF文档"

遍历目录下所有的Word文件,用同样的方法进行转换就没问题啦。

  1. pythoncom.CoInitialize()
  2. os_dict = {root:[dirs, files] for root, dirs, files in os.walk(rootpath)}
  3. for parent, dirnames, filenames in os.walk(rootpath):
  4. for filename in filenames:
  5. if u'.doc' in filename and u'~$' not in filename:
  6. # 直接保存为PDF文件
  7. #print(rootpath+filename)
  8. a = Word_2_PDF(rootpath +'\\'+ filename, True)
  9. title = filename.split('.')[0] # 删除.docx
  10. a.export_pdf(save_path + '\\' + title+'.pdf')
  11. a.close()
  12. print('转化完成')

大功告成~!这下就完成了所有任务。

今天我们成功把Excel中保存的学生信息填写到Word模版中,生成录取通知书,又批量把它们处理为pdf格式。

是不是成就感满满?

想要继续学习更多Python相关知识,欢迎扫描下方二维码?添加班主任微信,和更多同学一起交流学习,我们下节课不见不散哦。

扫描下方二维码,添加班主任微信

办公自动化 1/3

同学,你被录取了

1.0x

恭喜完成本课时的学习!
坚持学习

行动力超过

累计学习

学习下一课时