小猪的Python学习之旅 —— 22.安静!吵到我用TNT了(下)

简介: 原理利用Python-pptx库,通过编写模板的方式自动生成批量PPT!

参数传递下,调用这个模板2,查看下生成的效果:



接下来如法炮制剩下的三个模板,主要是难点是控件的位置和宽高设置, 有两种操作:

最简单的操作:


随便填个坐标和宽高,运行后打开生成的PPT,自行调整 位置,然后记录下何时的位置和宽高,然后改代码。


复杂点的操作:


自行计算,比如模板5,三个小标题,先减去左右的间隔, 然后三等分,循环动态计算小标题的起始位置。


3.配置文件读取


接下来编写一个读取文件内容,调用对应方法的函数,代码如下


# 读取配置文件调用模板的方法
def read_rules(prs, filename):
    if os.path.exists(filename):
        with open(filename, 'r+', encoding='utf-8') as f:
            for rule in f:
                word_list = rule.replace('\n', '').split(',')
                if 'png' in rule or 'jpg' in rule:
                    if len(word_list) == 1:
                        model_1(prs, os.path.join(c.res_pictures, word_list[0]))
                    else:
                        model_3(prs, word_list[0], os.path.join(c.res_pictures, word_list[1]))
                else:
                    if len(word_list) == 1:
                        model_2(prs, word_list[0])
                    elif len(word_list) == 2:
                        model_4(prs, word_list[0], word_list[1])
                    elif len(word_list) == 4:
                        model_5(prs, word_list[0], word_list[1], word_list[2], word_list[3])


4.代码执行


调用配置文件读取的函数


if __name__ == '__main__':
    t.is_dir_existed(c.outputs_documents_path)
    ppt_existed(ppt_file_name)
    presentation = Presentation(ppt_file_name)
    read_rules(presentation, rules_path)
    presentation.save(ppt_file_name)


运行结果



4.有些东西要说说


批量生成是挺爽的,不过呢,不支持直接生成动画哦!!! 然后这种简单的PPT,其实粘贴复制修改图片的效率可能比起你一个个 模板编写快一些...不得不说有些鸡肋,哦,对哦,这个还支持生成图表, 怎么整可以自行查阅官方文档。


另外的win32com的库,貌似功能更加强大,可能支持动画吧,但是文档是 真的难啃,就没有深入去研究了,有兴趣可以自己去折腾折腾。附上用win32com这个库时遇到的问题的解决方法:


1.Python3安装win32com


pip install pypiwin32


2.哪里有win32com的文档


微软官网有,不过看到脑壳痛,介绍个工具:oleview,网上一搜一堆 不过这个用的时候会遇到一个问题,这里顺带记录下笔者win10电脑遇到的 一些情况:

IVIEWERS.DLL缺失:


网上搜下这个dll文件,下载完把文件复制到Windows/system32, 然后管理员模式打开命令提示符,键入:regsvr32 iviewers.dll注册这个dll运行库就可以了。不过呢,win10 64位这样的执行是会报错的:


模块iviewers.dll可能与您正在运行的Windows版本不兼容,检查该模块是否与 regsvr.exe的x86或x64版本兼容


你要做的是把dll文件拷贝到Windows/SysWOW64,然后管理员模式打开命令提示符cd到这个目录下,接着执行regsvr32 iviewers.dll即可。


如果出现:对DllRegisterServer的调用失败,错误代码为0x80070005那是UAC的缘故,你没有以管理员模式打开命令提示符


如果解决了,应该能正常打开,左侧招到PowerPoint那项,双击打开, 然后呢,这个工具不支持查找,你可以把内容全选然后复制到如Sublime Text 这样的代码查看工具上,ctrl + f 查找关键字,然后一步步定位出实现某个 功能需要用到的一些函数。



小结


本节讲解了一波利用Python-pptx批量生成N张PPT的套路


参考文献




附:最终代码(都可以在:github.com/coder-pig/R… 找到):


import pptx
import config as c
import tools as t
from pptx import Presentation
from pptx.dml.color import RGBColor
from pptx.util import Inches, Pt
from pptx.enum.text import MSO_VERTICAL_ANCHOR, PP_PARAGRAPH_ALIGNMENT
import os
rules_path = os.path.join(c.res_documents, 'ppt_rules.txt')
ppt_bg_path = os.path.join(c.res_pictures, 'ppt_bg.png')
laoluo_bg_path = os.path.join(c.res_pictures, 'laoluo.jpg')
last_bg_path = os.path.join(c.res_pictures, 'last.png')
story_bg_path = os.path.join(c.res_pictures, 'story.png')
ppt_file_name = os.path.join(c.outputs_documents_path, 'result.pptx')
# 厘米转英寸
def cm_to_in(cm):
    return Inches(cm / 2.54)
# 判断课件是否存在,不存在的新建一个空白
def ppt_existed(ppt_name):
    if not os.path.exists(ppt_name):
        prs = Presentation()
        prs.slide_height = cm_to_in(14.35)
        prs.slide_width = cm_to_in(25.5)
        prs.save(ppt_name)
# 模板1:只有一张图片
def model_1(prs, pic_path):
    slide = prs.slides.add_slide(prs.slide_layouts[6])
    slide.shapes.add_picture(pic_path, cm_to_in(0), cm_to_in(0), cm_to_in(25.4), cm_to_in(14.288))
# 模板2:只有一个标题
def model_2(prs, title):
    slide = prs.slides.add_slide(prs.slide_layouts[6])
    slide.shapes.add_picture(ppt_bg_path, cm_to_in(0), cm_to_in(0), cm_to_in(25.4), cm_to_in(14.288))
    title_box = slide.shapes.add_textbox(cm_to_in(3.89), cm_to_in(5.35), cm_to_in(17.61), cm_to_in(3.59))
    paragraph = title_box.text_frame.add_paragraph()
    paragraph.text = title
    paragraph.vertical_anchor = MSO_VERTICAL_ANCHOR.MIDDLE
    paragraph.alignment = PP_PARAGRAPH_ALIGNMENT.CENTER
    paragraph.font.size = Pt(60)
    paragraph.font.name = '微软雅黑'
    paragraph.font.color.rgb = RGBColor(255, 255, 255)
#  模板3:有字,有图片
def model_3(prs, title, pic_path):
    slide = prs.slides.add_slide(prs.slide_layouts[6])
    slide.shapes.add_picture(ppt_bg_path, cm_to_in(0), cm_to_in(0), cm_to_in(25.4), cm_to_in(14.288))
    img = slide.shapes.add_picture(pic_path, cm_to_in(0), cm_to_in(0), height=cm_to_in(11.72))
    img.left = int(prs.slide_width / 2 + (prs.slide_width / 2 - img.width) / 2)
    img.top = int((prs.slide_height - img.height) / 2)
    title_box = slide.shapes.add_textbox(cm_to_in(2), cm_to_in(5.35), int(prs.slide_width / 3), cm_to_in(3.59))
    paragraph = title_box.text_frame.add_paragraph()
    paragraph.text = title
    paragraph.font.size = Pt(44)
    paragraph.font.name = '微软雅黑'
    paragraph.font.color.rgb = RGBColor(255, 255, 255)
# 模板4:两行文字,一大一小
def model_4(prs, title, content):
    slide = prs.slides.add_slide(prs.slide_layouts[6])
    slide.shapes.add_picture(ppt_bg_path, cm_to_in(0), cm_to_in(0), cm_to_in(25.4), cm_to_in(14.288))
    # 一级标题
    title_box_1 = slide.shapes.add_textbox(cm_to_in(1.27), cm_to_in(2.04), cm_to_in(22.86), cm_to_in(3.18))
    paragraph_1 = title_box_1.text_frame.add_paragraph()
    paragraph_1.text = title
    paragraph_1.vertical_anchor = MSO_VERTICAL_ANCHOR.MIDDLE
    paragraph_1.alignment = PP_PARAGRAPH_ALIGNMENT.CENTER
    paragraph_1.font.size = Pt(44)
    paragraph_1.font.name = '微软雅黑'
    paragraph_1.font.color.rgb = RGBColor(255, 255, 255)
    # 二级标题
    title_box_2 = slide.shapes.add_textbox(cm_to_in(7.46), cm_to_in(6.4), cm_to_in(10.47), cm_to_in(2.39))
    paragraph_2 = title_box_2.text_frame.add_paragraph()
    paragraph_2.text = title
    paragraph_2.vertical_anchor = MSO_VERTICAL_ANCHOR.MIDDLE
    paragraph_2.alignment = PP_PARAGRAPH_ALIGNMENT.CENTER
    paragraph_2.font.size = Pt(32)
    paragraph_2.font.name = '微软雅黑'
    paragraph_2.font.color.rgb = RGBColor(255, 255, 255)
# 模板5:一行文字,多个小标题
def model_5(prs, title, *content):
    slide = prs.slides.add_slide(prs.slide_layouts[6])
    slide.shapes.add_picture(ppt_bg_path, cm_to_in(0), cm_to_in(0), cm_to_in(25.4), cm_to_in(14.288))
    title_box_1 = slide.shapes.add_textbox(cm_to_in(1.27), cm_to_in(2.04), cm_to_in(22.86), cm_to_in(3.18))
    paragraph_1 = title_box_1.text_frame.add_paragraph()
    paragraph_1.text = title
    paragraph_1.vertical_anchor = MSO_VERTICAL_ANCHOR.MIDDLE
    paragraph_1.alignment = PP_PARAGRAPH_ALIGNMENT.CENTER
    paragraph_1.font.size = Pt(44)
    paragraph_1.font.name = '微软雅黑'
    paragraph_1.font.color.rgb = RGBColor(255, 255, 255)
    # 动态构建小标题
    module_width = (prs.slide_width - cm_to_in(1.27) * 2) / len(content)
    for i in range(0, 3):
        title_box = slide.shapes.add_textbox(cm_to_in(1.27) + i * module_width, cm_to_in(6.4), module_width,
                                             cm_to_in(2.39))
        paragraph = title_box.text_frame.add_paragraph()
        paragraph.text = content[i]
        paragraph.vertical_anchor = MSO_VERTICAL_ANCHOR.MIDDLE
        paragraph.alignment = PP_PARAGRAPH_ALIGNMENT.CENTER
        paragraph.font.size = Pt(32)
        paragraph.font.name = '微软雅黑'
        paragraph.font.color.rgb = RGBColor(255, 255, 255)
# 读取配置文件调用模板的方法
def read_rules(prs, filename):
    if os.path.exists(filename):
        with open(filename, 'r+', encoding='utf-8') as f:
            for rule in f:
                word_list = rule.replace('\n', '').split(',')
                if 'png' in rule or 'jpg' in rule:
                    if len(word_list) == 1:
                        model_1(prs, os.path.join(c.res_pictures, word_list[0]))
                    else:
                        model_3(prs, word_list[0], os.path.join(c.res_pictures, word_list[1]))
                else:
                    if len(word_list) == 1:
                        model_2(prs, word_list[0])
                    elif len(word_list) == 2:
                        model_4(prs, word_list[0], word_list[1])
                    elif len(word_list) == 4:
                        model_5(prs, word_list[0], word_list[1], word_list[2], word_list[3])
if __name__ == '__main__':
    t.is_dir_existed(c.outputs_documents_path)
    ppt_existed(ppt_file_name)
    presentation = Presentation(ppt_file_name)
    read_rules(presentation, rules_path)
    presentation.save(ppt_file_name)


相关文章
|
2月前
|
Python 容器
Python学习的自我理解和想法(9)
这是我在B站跟随千锋教育学习Python的第9天,主要学习了赋值、浅拷贝和深拷贝的概念及其底层逻辑。由于开学时间紧张,内容较为简略,但希望能帮助理解这些重要概念。赋值是创建引用,浅拷贝创建新容器但元素仍引用原对象,深拷贝则创建完全独立的新对象。希望对大家有所帮助,欢迎讨论。
|
2月前
|
Python
Python学习的自我理解和想法(10)
这是我在千锋教育B站课程学习Python的第10天笔记,主要学习了函数的相关知识。内容包括函数的定义、组成、命名、参数分类(必须参数、关键字参数、默认参数、不定长参数)及调用注意事项。由于开学时间有限,记录较为简略,望谅解。通过学习,我理解了函数可以封装常用功能,简化代码并便于维护。若有不当之处,欢迎指正。
|
1月前
|
数据可视化 数据挖掘 大数据
1.1 学习Python操作Excel的必要性
学习Python操作Excel在当今数据驱动的商业环境中至关重要。Python能处理大规模数据集,突破Excel行数限制;提供丰富的库实现复杂数据分析和自动化任务,显著提高效率。掌握这项技能不仅能提升个人能力,还能为企业带来价值,减少人为错误,提高决策效率。推荐从基础语法、Excel操作库开始学习,逐步进阶到数据可视化和自动化报表系统。通过实际项目巩固知识,关注新技术,为职业发展奠定坚实基础。
|
2月前
|
存储 索引 Python
Python学习的自我理解和想法(6)
这是我在B站千锋教育学习Python的第6天笔记,主要学习了字典的使用方法,包括字典的基本概念、访问、修改、添加、删除元素,以及获取字典信息、遍历字典和合并字典等内容。开学后时间有限,内容较为简略,敬请谅解。
|
2月前
|
存储 程序员 Python
Python学习的自我理解和想法(2)
今日学习Python第二天,重点掌握字符串操作。内容涵盖字符串介绍、切片、长度统计、子串计数、大小写转换及查找位置等。通过B站黑马程序员课程跟随老师实践,非原创代码,旨在巩固基础知识与技能。
|
2月前
|
程序员 Python
Python学习的自我理解和想法(3)
这是学习Python第三天的内容总结,主要围绕字符串操作展开,包括字符串的提取、分割、合并、替换、判断、编码及格式化输出等,通过B站黑马程序员课程跟随老师实践,非原创代码。
|
2月前
|
Python
Python学习的自我理解和想法(7)
学的是b站的课程(千锋教育),跟老师写程序,不是自创的代码! 今天是学Python的第七天,学的内容是集合。开学了,时间不多,写得不多,见谅。
|
2月前
|
存储 安全 索引
Python学习的自我理解和想法(8)
这是我在B站千锋教育学习Python的第8天,主要内容是元组。元组是一种不可变的序列数据类型,用于存储一组有序的元素。本文介绍了元组的基本操作,包括创建、访问、合并、切片、遍历等,并总结了元组的主要特点,如不可变性、有序性和可作为字典的键。由于开学时间紧张,内容较为简略,望见谅。
|
2月前
|
存储 索引 Python
Python学习的自我理解和想法(4)
今天是学习Python的第四天,主要学习了列表。列表是一种可变序列类型,可以存储任意类型的元素,支持索引和切片操作,并且有丰富的内置方法。主要内容包括列表的入门、关键要点、遍历、合并、判断元素是否存在、切片、添加和删除元素等。通过这些知识点,可以更好地理解和应用列表这一强大的数据结构。
|
2月前
|
索引 Python
Python学习的自我理解和想法(5)
这是我在B站千锋教育学习Python的第五天笔记,主要内容包括列表的操作,如排序(`sort()`、``sorted()``)、翻转(`reverse()`)、获取长度(`len()`)、最大最小值(`max()`、``min()``)、索引(`index()`)、嵌套列表和列表生成(`range`、列表生成式)。通过这些操作,可以更高效地处理数据。希望对大家有所帮助!

热门文章

最新文章