花10分钟写一个 Python 脚本,搞定了初中老师一个下午的工作
有个朋友是一个初中老师。嗯,教学行政两手抓的那种初中老师。
一天晚上突然微信问我,怎么把图片转成PDF。懵了一下,这个直接打印成PDF不就可以了?
遂告诉他,结果感觉两个人不是一个世界的:
好不容易教他把图片放Word里面打印,结果发现他的需求并不止于此:
没辙,送佛送到西呗。继续挖他的需求:
还有需要特殊处理的地方:
提炼了一下他的需求:
- 有两百多张用手机拍的学生XXX档案资料;
- 已经按照每个学生的名字编好了号;
- 需要每个学生按照顺序 + 公共的图片,组合成一个新的PDF文件;
- 生成的文件体积大小需要在20MB以内;
现状是这样的图片文件:
需要按照一定的图片顺序进行排序并转换PDF。
总结起来,也就是处理文件,将图片拼接组合成PDF。这个小需求,用Python实现起来轻轻松松。
梳理一下这个任务的几个关键点:
缩放图片
因为图片使用手机拍摄的,现有的手机动不动就是几千万的像素。拍一张照片,十几兆的大小是逃不了的。而需求最终每一个PDF的大小不超过20MB,缩放图片是必须要做的。
在 Python 中处理图片很经典的第三方模块是 Pillow,通过它可以对图像进行各种操作,当然也不限于缩小图片。
-
# 缩放图片
-
dir_list = os.listdir(dir_path)
-
new_path = r"D:DocumentsTencent Files3280350050FileRecvnew"
-
for f in dir_list:
-
if f.endswith('.jpg'):
-
img =
Image.open(dir_path+'\'+f)
-
new_size = img.resize((1401,1867))
-
new_size.save(new_path +
'\'
+ f)
上述代码就把图片缩小到了1401*1867像素大小。
图片转PDF
在这个任务里面,核心的需求是把图片转成 PDF 格式的文件。Python 中图片转 PDF 的功能有很多模块可以实现,在此州的先生选用的是 img2pdf。
直接调用img2pdf.convert()
方法,将图片路径或图片列表路径作为参数传递进去,就可以得到一个转换好的 PDF 文件对象。
-
# 新建单个PDF文件
-
with open(new_path+'\'+'{}_1.pdf'.format(name),'wb')
as pdf_file:
-
a4inpt =
(img2pdf.mm_to_pt(210), img2pdf.mm_to_pt(297))
# 创建A4纸格式
-
layout_fun = img2pdf.get_layout_fun(a4inpt)
# 设置A4纸格式
-
# PDF写入图片
-
pdf_file.write(
-
img2pdf.convert(
-
img_list,
-
# layout_fun=layout_fun
-
)
-
)
其 PyPI 的链接为:https://pypi.org/project/img2pdf/ ,感兴趣的朋友可以详细地了解其使用方法。
图像排列规则
因为需要按照一定的顺序对照片进行排序,然后还有一个特殊的情况,所以在对原始图片进行遍历的时候,需要进行一番处理,最后生成每一个人的图片的列表。
-
# 生成单个名称的图片列表
-
for name in sorted(name_list,reverse=False):
-
print(name)
-
if name ==
'***':
# 特殊情况学生的名字
-
img_list =
[]
-
for f in dir_list:
-
print(f)
-
file_name, file_suffix = f.split('.')
-
file_sort =
int(file_name[-1])
-
if name == file_name[:-1]:
-
if file_sort ==
3:
-
img_list.insert(4, new_path +
'\'
+ f)
-
else:
-
img_list.insert(int(file_name[-1])
-
1, new_path +
'\'
+ f)
-
img_list.insert(1, new_path +
'\'
+
'公共1.jpg')
-
img_list.insert(3, new_path +
'\'
+
'公共2.jpg')
-
img_list.insert(9, new_path +
'\'
+
'公共4.jpg')
-
img_list.insert(10, new_path +
'\'
+
'公共5.jpg')
-
img_list.insert(11, new_path +
'\'
+
'公共6.jpg')
-
print(img_list)
-
else:
-
img_list =
[]
-
for f in dir_list:
-
print(f)
-
file_name,file_suffix = f.split('.')
-
file_sort =
int(file_name[-1])
-
if name == file_name[:-1]:
-
if file_sort ==
3:
-
img_list.insert(5,new_path+'\'+f)
-
else:
-
img_list.insert(int(file_name[-1])-1,new_path+'\'+f)
-
img_list.insert(1,new_path+'\'+'公共1.jpg')
-
img_list.insert(3, new_path +
'\'
+
'公共2.jpg')
-
img_list.insert(4, new_path +
'\'
+
'公共3.jpg')
-
img_list.insert(9, new_path +
'\'
+
'公共4.jpg')
-
img_list.insert(10, new_path +
'\'
+
'公共5.jpg')
-
img_list.insert(11, new_path +
'\'
+
'公共6.jpg')
-
print(img_list)
完整步骤
在对任务的关键点有了认识之后,我们按照流程,就可以轻松完成这个任务。
- 遍历原始图片文件夹,缩小图片,并将其另存到另一个文件夹;
- 遍历新图片的文件夹,生成除了公共图片之外的所有学生姓名列表;
- 遍历学生姓名列表,按照指定的图片排序规则,生成每个学生的图片列表; 3.1 生成每个学生的图片列表之后,新建一个文件,将图片列表转为PDF;
以上4步,就完成了这个手工操作浪费时间且令人抓狂的任务。运行代码不出一分钟,所有学生的PDF文件都已生成完成:
算上找模块的时间,花在代码上的时间满打满算20分钟。
瞬间把一个快炸毛的老师:
的毛给顺了下去:
如果需要源代码参考,请添加州的先生微信号:taoist_ling
- 第四次工业革命
- 每周.NET前沿技术文章摘要(2017-06-07)
- 再谈Silverlight中的对象序列化/反序列化
- jQuery打造智能提示插件
- 每周.NET前沿技术文章摘要(2017-05-17)
- 每周.NET前沿技术文章摘要(2017-05-24)
- ruby学习笔记(10)-puts,p,print的区别
- Linux下的Mongodb部署应用梳理
- Ocelot API网关的实现剖析
- ruby学习笔记(9)-别名(alias)与方法取消(undef,remove_method)
- Pupet自动化管理环境部署记录
- ruby学习笔记(8)-"静态方法的4种写法"与"单例方法的2种写法"
- Puppet常识梳理
- linux下增加磁盘改变指定文件路径分区挂载点和迁移数据
- JavaScript 教程
- JavaScript 编辑工具
- JavaScript 与HTML
- JavaScript 与Java
- JavaScript 数据结构
- JavaScript 基本数据类型
- JavaScript 特殊数据类型
- JavaScript 运算符
- JavaScript typeof 运算符
- JavaScript 表达式
- JavaScript 类型转换
- JavaScript 基本语法
- JavaScript 注释
- Javascript 基本处理流程
- Javascript 选择结构
- Javascript if 语句
- Javascript if 语句的嵌套
- Javascript switch 语句
- Javascript 循环结构
- Javascript 循环结构实例
- Javascript 跳转语句
- Javascript 控制语句总结
- Javascript 函数介绍
- Javascript 函数的定义
- Javascript 函数调用
- Javascript 几种特殊的函数
- JavaScript 内置函数简介
- Javascript eval() 函数
- Javascript isFinite() 函数
- Javascript isNaN() 函数
- parseInt() 与 parseFloat()
- escape() 与 unescape()
- Javascript 字符串介绍
- Javascript length属性
- javascript 字符串函数
- Javascript 日期对象简介
- Javascript 日期对象用途
- Date 对象属性和方法
- Javascript 数组是什么
- Javascript 创建数组
- Javascript 数组赋值与取值
- Javascript 数组属性和方法
- PyQt5 技术篇-在clipboard.dataChanged.connect()里如何写入剪切板示例演示,pyqt5监听剪切板变动并写入剪切板内容
- 去除WordPress链接中出现的index.php
- MySQL 语法问题:You can‘t specify target table ‘xxx‘ for update in FROM clause. 原因及解决方法
- 配置 prometheus-operator 报警规则
- SQL语句查询出的数据进行字符串拼接,oracle批量删除数据库用户实例演示
- prometheus-operator 监控 k8s 外部集群
- Python+selenium 自动化-操作已启用的chrome浏览器实例演示,chrome启用调试端口方法
- JavaScript 技术篇-js检测原生对象类型实例演示,js的3种对象类型
- Python 技术篇-利用pyqt5库读取剪切板已复制数据的格式类型实例演示,python判断复制文件的文件类型
- 第36期:二叉树的遍历(小白必看)
- Python 技术篇-index()字符串倒叙匹配获取索引,字符串切片反向输出,逆向输出字符串
- JavaScript 技术篇-navigator.permissions读取chrome剪切板权限获取不生效原因:只有在https协议下使用有效。手动设置chrome页面剪切板读取权限方法
- 生产prometheus-operator 监控二进制kubernetes
- Excel 技术篇-跨页签统计某一区域下符合条件值的数量方法,COUNTIF函数、数量统计公式的用法实例演示
- Oracle 数据库用户锁定与解锁,用户锁定最大密码失败次数设置方法,ORA-28000: the account is locked问题解决方法