Powershell(7)——批量生成PPT
创作者俱乐部成员
问题来自方盛老师的帖子:当前文件夹里有很多图片,现在要新建一个PPT,然后每张幻灯片上放3张图片,图片采用飞入动画,直到把图片放完为止。
手动操作肯定费时费力不可取
写JS宏可以自动化,但对于不熟悉宏的用户,使用宏代码也不容易
这里用powershell写代码,转为bat批处理执行,用户只需要获得一个批处理文件,放在图片文件夹里,双击运行即可
好处不仅是使用简单,还可以从其他来源获取数据,比如方便的打开wps电子表格,获取表或图,插入PPT等等
下面逐行解释一下批处理脚本:
| 💡 | #&cls&powershell -NoProfile -NoLogo "gc '%~0'|out-string|iex"&pause&exit |
这是一个固定的写法,把powershell脚本当成bat批处理来运行,其中pause等待任意键退出,用来显示有可能出现的报错,方便调试
如果你熟悉其他脚本语言,可以用类似的小技巧,把python、js、bash等脚本改成bat批处理运行方式
| 📌 | $arr = (dir -Recurse *.jpg).FullName $arr = $arr | Get-Random -Count $arr.Count |
dir命令用来列出当前文件夹里的所有jpg文件,-Recurse参数是指包括列出所有子目录里的jpg文件,如果还有其他格式的图片,可以用逗号分隔,写成*.jpg,*.png
括号里面是整体计算的结果,也就是个文件的列表,点号用来取属性,这里取FullName,完整文件路径,因为后面插入PPT时需要图片的完整路径
等号右边的表达式计算结束后,赋值给左边的变量,这里得到的是文件完整路径的一个数组,赋值给$arr,变量以$开头
第二句是因为方盛老师要求,图片要随机取,所以重新赋值变量$arr,右侧表达式里的|是管道符号,意思是把$arr这个数组,传递进管道,然后用Get-Random这个命令,从管道里随机取出$arr.Count这么多个项目重新组成数组,结果就是打乱了$arr数组的顺序,不用这句就是按名称顺序排列的图片
| 🔔 | $ppt = New-Object -ComObject kwpp.application $ppt.Visible = $true |
New-Object -ComObject命令用来新建一个com对象,office、wps、adobe等很多软件,都提供com对象,方便大家用任何你熟悉的语言来写自动化脚本,我前面分享过一个ahk,列出所有本机可用的com对象,有成百上千个,这里新建kwpp.application对象,就是指wps演示
第二句是把wps演示的窗口显示出来,一般用com对象自动化,com对象打开的窗口是隐藏的,这里把$ppt对象的属性Visible赋值为$true
| 👋 | $p = $ppt.Presentations.Add() $n = 0 |
用com对象操作ppt,就需要了解ppt的对象模型,可以去wps开放平台查询旧版的文档(不得不说,这文档不全、有错误、还没更新过,太懒了啊啊啊),也可以去查微软的ppt的对象模型,两者大同小异
这一句是说,$ppt是打开的wps演示这个应用,它的Presentations属性是演示文档的集合,现在在空的集合里新建Add一个演示文档,这里可以把Add改成Open,打开一个pptx文档,然后赋值给$p变量,以后$p就表示我们新建的这个演示文档
$n=0是赋值一个变量$n,值是0,后面用来作为序号,记录已经插入到哪一张图片了
| 💡 | 1..[int]($arr.Count/3) | %{ $s = $p.Slides.Add($_, 12) 1..3 | %{ $i = $s.Shapes.AddPicture($arr[($n++)], 0, 1, ($_ * 200), 250) $i.AnimationSettings.EntryEffect = 3332 } } |
1..5是生成1,2,3,4,5这个序列,其中[int]($arr.Count/3)这一步,是用数组$arr的长度除以3,取整数,也就是放满3张图片的幻灯片一共有x张,生成1到x这个序列
%{}是foreach-object的缩写,意思是,每次取出前面管道里的一个项目,放到大括号里运算,然后循环遍历所有项目,这里是对1到x每个幻灯片序号循环
$_是指代循环的那个项目,这里是序号,$p是指演示文档,它的Slides属性是幻灯片的集合,我们在集合里新建Add一张幻灯片,这里Add方法可以查手册,有两个参数:位置就是序号,模板类型12表示空模板,然后把这个新建的幻灯片赋值给$s
然后1..3 | %{},再次对1到3这个序号循环,意思是循环处理每张幻灯片里的每张图片
$s是指当前这张幻灯片,Shapes是指所有图片图形的集合,AddPicture是插入图片,查询文档可知,它至少要5个参数:
图片文件名就要从$arr数组里取第$n项$arr[$n],之所以写成($n++),意思是取值之后$n序号要增加1;
第二个参数是否连接到图片文件,这里0表示不连接;
第三个参数是说图片是否保存到pptx文件内,1表示保存;然后是图片的插入位置,x设置为($_ * 200)是说,用图片的序号乘以200,也就分别对应着200,400,600;y统一设置为了250
然后后面还可以加上图片的宽和高w和h,如果你需要调整插入图片的尺寸,可以在这里加上两个参数
$i.AnimationSettings.EntryEffect,其中$i是指当前插入的这张图片,它的属性AnimationSettings.EntryEffect是指进入动画,查手册可知从底部飞入是3332,赋值即可
到这里就结束了,因为运行bat后会生成的ppt需要手动再接着处理,不清理com对象在这个脚本问题不大,如果是其他情况,也许需要手动关闭com对象,清理变量
总的代码大概如下:
| 💡 | #&cls&powershell -NoProfile -NoLogo "gc '%~0'|out-string|iex"&pause&exit $arr = (dir -Recurse *.jpg).FullName $arr = $arr | Get-Random -Count $arr.Count $ppt = New-Object -ComObject kwpp.application $ppt.Visible = $true $p = $ppt.Presentations.Add() $n = 0 1..[int]($arr.Count/3) | %{ $s = $p.Slides.Add($_, 12) 1..3 | %{ $i = $s.Shapes.AddPicture($arr[($n++)], 0, 1, ($_ * 200), 250) $i.AnimationSettings.EntryEffect = 3332 } } $ppt = $null |
脚本看起来有点复杂,但实际上,只要学会去查询演示、表格、文档的对象模型文档,实际就是访问对象的属性,调用对象的方法,再加上一些循环、判断即可实现批量处理
不得不说,官方文档不完整、有bug、不更新,让人十分恼火,但就目前可用的部分,通过创建com对象,你可以用熟悉的各种脚本语言来进行批量自动操作,减轻重复劳动
JS宏也还不完善,有时候用powershell写个批处理,用户用起来更爽不是吗😁