一、需求目标

        把 Excel 表格中的内容和文件夹中的头像,放入 .pptx 文件中生成员工工牌。

二、实现步骤

2.1 了解PPT的写入方式

        在开始之前,我们需要先学习 PPT 模版里的三个概念:母版、版式和占位符。

        版式:打开一个 PPT,添加一张幻灯片页,就会出现带有虚线框的页面,这就是“版式”。
PPT 中有很多自带的版式,是系统为使用者排版好的页面,只需要往里面填内容就好,十分的方便。

        母版:如果你想要自己设计版式,就需要专门修改这些版式的功能。在母版中有很多版式,排在第一位的版式,也就是新建一页的页面。

        母版与版式的区别:放在“母版”中的任何元素,都会直接出现在每一页PPT中;放在"版式"中的元素,则需要手动调出来才会显示在某页PPT中。

        占位符:占位符,顾名思义,就是一种用来占位置的“符号”,也就是版式中的虚线框。占位符的编辑需要通过母版进行操作。有了占位符,你可以输入文字、插入图片,并且不需要调整格式。

        在简单学习了 PPT 的样式后,接下来我们要编写代码,读取 .pptx 文件并在幻灯片页中添加内容。
        首先,我们要使用 python-pptx 模块,调用 Presentation() 函数,读取 .pptx 文件。

# 使用from...import从pptx模块中导入Presentation
from pptx import Presentation

# .pptx文件路径赋值给变量path
path = r"D:\学习资料\Python\test\工牌.pptx"

# 读取PPT赋值给pptxFile
pptxFile = Presentation(path)

        读取“工牌.pptx”文件后,接下来就要往文件中新增一张幻灯片页。由于我们要添加工牌模版,它是母版中的第一个版式,在这里,我们需要先获取版式,再添加页面。

        获取版式对象,在 Presentation 对象中访问 .slide_layouts 属性可以返回母版中的版式序列。

# 获取母版中第一个版式,赋值给变量layoutOne
layoutOne = pptxFile.slide_layouts[0]

        在 Presentation 对象中访问 .slides 属性,返回幻灯片页序列。

        在幻灯片页对象中,调用 add_slide() 函数,传入幻灯片版式对象,即可在 .pptx 文件中新增指定版式的幻灯片页。

# 访问pptxFile中.slides属性,赋值给变量slideAll
slideAll = pptxFile.slides

# 调用add_slide()函数传入参数layoutOne
# 新建幻灯片页,并赋值给变量newSlide
newSlide = slideAll.add_slide(layoutOne)

# 将文件保存至原路径
pptxFile.save(path)

        代码运行成功后,在“工牌.pptx”文件中新增了一张空白工牌模版 

2.2 在幻灯片内添加文本和图片

        我们要在模版页中添加文本和图片,其实也就是在占位符中添加内容。
        仔细观察,在模版中有 4 个占位符,1个图片占位符,3个正文占位符,我们需要获取占位符及其属性,才能精确的写入对应的信息。

        为了把信息写入指定占位符内,python-pptx 模块给每页中的占位符设置了编号和对应的类型。
        我们可以按照以下层级获取到占位符的编号和类型:占位符对象 -> 占位符属性对象 -> 占位符编号和类型

        访问幻灯片页对象中 .placeholders 属性,可以获得幻灯片页中占位符序列。占位符序列中包含所有占位符对象,可以使用索引定位到单个占位符对象;

        访问单个占位符对象中的 .placeholder_format 属性,可以获得此占位符的属性对象。访问占位符的属性对象中的 .idx (占位符的编号)和 .type (占位符的类型),可以获得占位符的编号和类型。

        在 PPT 中占位符的类型有 18 种,常见的有:TITLE—标题占位符、BODY—正文占位符、PICTURE—图片占位符等。

# for循环遍历newSlide中的.placeholders属性
# 赋值给变量single_plh
for single_plh in newSlide.placeholders:
    # 访问占位符对象中的.placeholder_format属性
    # 赋值给变量phf
    phf = single_plh.placeholder_format
    # 访问phf中的.idx和.type属性
    # 格式化字符串以"-"连接并输出
    print(f"{phf.idx}-{phf.type}")

        执行后,发现图片占位符的编号是1,正文占位符的编号分别是2、10、11。

        获取到了占位符的编号,接下来就可写入对应的内容啦,访问指定正文占位符对象中的 .text 属性,可以写入文本内容,写入的文本内容需要是字符串的格式,否则就会报错。

        在图片占位符对象中,调用 insert_picture() 函数,传入图片路径,即可在图片占位符中插入指定的图片。

# 访问newSlide中的.placeholders,赋值给变量all_plh
all_plh = newSlide.placeholders
# 将"白涵"、"运营"、"35"写入对应的正文占位符
all_plh[2].text = "张小凡"
all_plh[10].text = "副宗主"
all_plh[11].text = "003"
all_plh[1].insert_picture("D:/学习资料/Python/test/批量制作工牌/二维码/张小凡.png")

        代码运行成功后,在工牌模版里,姓名、岗位、工号以及对应的头像二维码已经写入页面中

 2.3 从Excel中提取工牌信息

        由于 PPT 模版中,需要写入的内容有:姓名、岗位、工号与头像二维码,而前三个信息都在 Excel 文件中。在这里,我们需要导入相关模块,读取指定工作表,把姓名、岗位和工号提取出来。

        导入 openpyxl 模块,调用 openpyxl.load_workbook() 函数,读取 Excel 文件;接着从工作簿对象中获取工作表,赋值给变量。

# 导入openpyxl模块
import openpyxl
# 将Excel文件夹路径D:\学习资料\Python\test\批量制作工牌\资料.xlsx,赋值给变量path
path = "D:\学习资料\Python\stest\批量制作工牌\资料.xlsx"
# 读取path的工作簿并赋值给变量wb
wb = openpyxl.load_workbook(path, data_only=True)
# 获取wb工作簿的"信息"工作表赋值给变量sheet
sheet = wb["信息"]

        在读取了 Excel 文件中指定的工作表后,接下来我们要提取姓名、岗位和工号。提取的方法有很多,在这里,我们可以按行读取工作表数据。

        我们可以通过读取工作表的 rows 属性获得行列表,使用 for 循环逐行读取行内容,并筛选2到5行,然后通过row[列数].value来获得列的值。

# for循环遍历sheet工作表的所有行,赋值给变量row
for row in sheet.rows:
    # 获取第row行数据列表,
    # 索引第1、2、5个元素
    # 分别赋值给job_num、name、post
    if row[0].value == "工号":
        continue
    else:
        job_num = row[0].value
        name = row[1].value
        post = row[4].value
    
        # 格式化字符串输出,以"-"连接job_num、name、post
        print(f"{job_num}-{name}-{post}")

        代码运行成功后,我们就从 Excel 文件中提取出想要的数据,完成工牌信息的提取。

2.4 查找头像二维码对应的信息

        接下来查找头像二维码对应的信息,可以分为以下两个子步骤:

1. 获取文件夹中的文件名;

        导入 os 模块,使用 os.listdir() 函数获取文件夹內所有文件名

# 导入os模块
import os
# 将文件夹路径"D:\学习资料\Python\stest\批量制作工牌\二维码",赋值给pathFile
pathFile = "D:\学习资料\Python\stest\批量制作工牌\二维码"
# 使用os.listdir()函数获取该路径下所有文件名,并赋值给变量allItems
allItems = os.listdir(pathFile)
# print()输出allItems
print(allItems)

2. 分割文件名获取文件名称;

        使用for 循环遍历存储文件名的列表;调用内置函数 split() 分割文件名,获取第一个元素

    # for循环遍历allItems,赋值给变量item
    for item in allItems:
        # 调用split()分割item,获取第一个元素赋值给变量file_name
        file_name = item.split(".")[0]
        # print()输出file_name
        print(file_name)

2.5 把员工信息批量写入PPT中

        接下来,判断文件名称与姓名是否匹配,如果是匹配的,就新建一页工牌版式,写入对应的信息。就把该员工对应的姓名、岗位、工号和头像二维码全部写入 PPT 中。

            if file_name == name:
                # 获取母版中第一个版式,赋值给变量layoutOne
                layoutOne = pptxFile.slide_layouts[0]

                # 访问pptxFile中.slides属性,赋值给变量slideAll
                slideAll = pptxFile.slides
                # 调用add_slide()函数传入参数layoutOne
                # 新建幻灯片页,并赋值给变量newSlide
                newSlide = slideAll.add_slide(layoutOne)

                # 将名称、职位、工号、照片写入对应的正文占位符
                newSlide.placeholders[2].text = name
                newSlide.placeholders[10].text = post
                newSlide.placeholders[11].text = f"{job_num}号"
                newSlide.placeholders[1].insert_picture(pathFile+"/"+item)

三、实现结果

3.1 完成代码

        以下是优化整理后的完整代码

import collections.abc  # 此模块是为了解决pptx与python3.10的版本问题加入的
# 使用from...import从pptx模块中导入Presentation
from pptx import Presentation
# 导入openpyxl模块
import openpyxl
# 导入os模块
import os

# pptx文件路径赋值给变量pptxpath
pptxpath = "D:\学习资料\Python\stest\批量制作工牌\工牌.pptx"
# 读取PPT赋值给pptxFile
pptxFile = Presentation(pptxpath)

# 将Excel文件夹路径D:\学习资料\Python\test\批量制作工牌\资料.xlsx,赋值给变量path
xlsxpath = "D:\学习资料\Python\stest\批量制作工牌\资料.xlsx"
# 读取path的工作簿并赋值给变量wb
wb = openpyxl.load_workbook(xlsxpath, data_only=True)
# 获取wb工作簿的"信息"工作表赋值给变量sheet
sheet = wb["信息"]

# 将文件夹路径"D:\学习资料\Python\stest\批量制作工牌\二维码",赋值给pathFile
pathFile = r"D:\学习资料\Python\stest\批量制作工牌\二维码"
# 使用os.listdir()函数获取该路径下所有文件名,并赋值给变量allItems
allItems = os.listdir(pathFile)

# for循环遍历sheet工作表的所有行,赋值给变量row
for row in sheet.rows:
    # 获取第row行数据列表,
    # 索引第1、2、5个元素
    # 分别赋值给job_num、name、post
    if row[0].value == "工号":
        continue
    else:
        job_num = row[0].value
        name = row[1].value
        post = row[4].value

        for item in allItems:
            file_name = item.split(".")[0]
                # 如果名称匹配成功
            if file_name == name:
                # 获取母版中第一个版式,赋值给变量layoutOne
                layoutOne = pptxFile.slide_layouts[0]

                # 访问pptxFile中.slides属性,赋值给变量slideAll
                slideAll = pptxFile.slides
                # 调用add_slide()函数传入参数layoutOne
                # 新建幻灯片页,并赋值给变量newSlide
                newSlide = slideAll.add_slide(layoutOne)

                # 将名称、职位、工号、照片写入对应的正文占位符
                newSlide.placeholders[2].text = name
                newSlide.placeholders[10].text = post
                newSlide.placeholders[11].text = f"{job_num}号"
                newSlide.placeholders[1].insert_picture(pathFile+"/"+item)
    
# 将文件保存至原路径
pptxFile.save(pptxpath)

        执行后的结果如图

3.2 总结  

        通过本实例我们制作出一个设计工具,你可以运用这个工具去批量生成名片、奖状、邀请函等,快捷又方便。在实现过程中pptx模块,写入 PPT 涉及一些代码使用,可以参考图片中的内容,在本地练习时,可以对照使用。

Logo

开放原子开发者工作坊旨在鼓励更多人参与开源活动,与志同道合的开发者们相互交流开发经验、分享开发心得、获取前沿技术趋势。工作坊有多种形式的开发者活动,如meetup、训练营等,主打技术交流,干货满满,真诚地邀请各位开发者共同参与!

更多推荐