python实现docx转pptx(word文档转幻灯片)
以前都是手工将word内容复制粘贴到ppt中,实在受够了。
文心一言真是大忽悠,给的转换方案是用docx2pptx库,然而根本没有这个库,倒是可以用我下面的代码生成这个库:-)
网上很多方案是转成图片形式插入ppt,导致无法正常编辑ppt.
于是研究出以下方案:
1.先将word文档的页面设置改为自定义大小,使每一页文字可容纳于一张幻灯片
2.去掉word文档页码(否则后面读取时会把页码作为正文的一部分,还要处理),然后转换为pdf格式(以便于按页读取,因为用代码读取word文档的一页比较困难,参看我的上一篇文章:python 获取word页数 https://www.cnblogs.com/pu369/p/17757633.html)
3.读取pdf每一页的文字,粘贴到ppt中。(注意在代码中设置好文本框大小及字号,保证ppt的文本框比pdf页要大。否则会因段落的换行符而影响显示效果)
4.打开ppt选择设计模板。然后可以按正常的PPT进行编辑。
主要用到三个库:1.用docx2pdf将word转pdf 2.用 PyPDF2读取pdf 3.用pptx生成幻灯片
代码:
from pptx import Presentation from pptx.enum.text import PP_PARAGRAPH_ALIGNMENT,MSO_ANCHOR from pptx.util import Pt from docx2pdf import convert import PyPDF2 wordfile = "1.docx" pdffile = "{}{}".format(wordfile[:-4],"pdf") # 将Word文档转换为pdf convert(wordfile, pdffile) # 创建一个Presentation对象 prs = Presentation() #打开pdf文件 with open(pdffile, 'rb') as file: # 创建一个PDF Reader对象 pdf_reader = PyPDF2.PdfFileReader(file) # 获取PDF文件中页面的数量 num_pages = pdf_reader.numPages # 读取一页的内容 for i in range(0,num_pages): page = pdf_reader.getPage(i) pdftext = page.extractText()#如有页码,则读出的第一个字符为页码 # 在演示文稿中添加幻灯片 slide_layout = prs.slide_layouts[5] # 5是标题幻灯片的布局 slide = prs.slides.add_slide(slide_layout) # 在幻灯片上添加一个shapge,并设置高度和宽度 shapes0 = slide.shapes[0] shapes0.height = Pt(450) shapes0.width = Pt(660) #左右边距 shapes0.top = Pt(100) shapes0.left = Pt(100) #在shape里面添加文本 txt_frame = slide.shapes[0].text_frame txt_frame.text = pdftext #段落左对齐 for p in txt_frame.paragraphs: p.alignment = 1 p.font.size = Pt(25) #文本框顶端对齐 txt_frame.vertical_anchor = MSO_ANCHOR.TOP # 保存演示文稿 prs.save('1.pptx')
注意:代码主要适用于文字 ,表格也会变成文字形式,图片我没有试。
补充:上述代码直接双击运行不了,但在IDLE中正常,原因是:
collections.Container自 3.3 起已弃用并在 3.10 中删除,因此请检查您的 python 版本,检查该模块的更新版本是否可用
解决方法是导入模块集合和集合。导入pptx前的abc,例:
import collections
import collections.abc
好像IDLE会自动导入,所以运行时不会出错。
而且,还有个问题是pdf的一页显示文字是对齐的,但将文字转回ppt,就变得不整齐了。
所以还不如不绕弯子,直接读取word的段落,保存到列表中,并将字数太长的段落拆分开。
然后,将列表中的文字分别放到每一张幻灯片上:
代码:
from docx import Document from pptx import Presentation from pptx.enum.text import PP_PARAGRAPH_ALIGNMENT,MSO_ANCHOR from pptx.util import Pt file_path = '1.docx' # 替换为实际word文件路径 #每页ppt允许的最多字数 NUM_PERPAGE = 200 #打开word doc = Document(file_path) # 创建一个Presentation对象,由于pptx无法设置主题及母版, #所以我们先准备一个带主题的template.pptx作为模板,内容可以为空。 prs = Presentation("template.pptx") #按段落读取word,并准备一个列表wordtexts保存所有段落内容,每个元素容纳一张ppt的文字 wordtexts = [] for paragraph in doc.paragraphs: paratext = paragraph.text #空行就不要了 if paratext.strip() != '': #若一张ppt超过规定字数perpage,则拆分开 if len(paratext)> NUM_PERPAGE: splitparas = [paratext[i:i+NUM_PERPAGE] for i in range(0, len(paratext), NUM_PERPAGE)] wordtexts.extend(splitparas) else: wordtexts.append(paratext) ''' #如果两张ppt的文字加起来还不够半张ppt,则合并,结合存入wordtexts2 wordtexts2=[] if len(wordtexts) % 2 == 0: #偶数 numpage = len(wordtexts) else: numpage = len(wordtexts) - 1 for i in range(0,numpage,2): nexti = i + 1 if((len(wordtexts[i]) + len(wordtexts[nexti])) < NUM_PERPAGE ): #整除 wordtexts2.append(wordtexts[i] + wordtexts[nexti]) else:#字数够了,不用合并,直接追加两张ppt wordtexts2.append(wordtexts[i]) wordtexts2.append(wordtexts[nexti]) if len(wordtexts) % 2 == 1: #奇数张的最后一张ppt wordtexts2.append(wordtexts[len(wordtexts) - 1]) ''' for ppttext in wordtexts: # 在演示文稿中添加幻灯片 slide_layout = prs.slide_layouts[5] # 5是标题幻灯片的布局 slide = prs.slides.add_slide(slide_layout) # 在幻灯片上添加一个shapge,并设置高度和宽度 shapes0 = slide.shapes[0] shapes0.height = Pt(450) shapes0.width = Pt(600) #左右边距 shapes0.top = Pt(60) shapes0.left = Pt(60) #在shape里面添加文本 txt_frame = slide.shapes[0].text_frame new_para = txt_frame.add_paragraph() # 添加段落 new_para.text = ppttext new_para.line_spacing = 1.5 # 1.5 倍的行距 #段落左对齐 for p in txt_frame.paragraphs: p.alignment = 1 p.font.size = Pt(25) #文本框顶端对齐 txt_frame.vertical_anchor = MSO_ANCHOR.TOP ''' #删除所有空shape。从最后面往前删,以避免循环过程中的顺序变化(这段代码在这个位置其实不起作用) for i in range(len(prs.slides),0,-1): for j in range(len(prs.slides[i-1].shapes),0, -1): shapej = prs.slides[i-1].shapes[j-1] if not shapej.has_text_frame: prs.slides[i-1].shapes._spTree.remove(shapej._element) ''' # 保存演示文稿 prs.save('1.pptx')
https://baijiahao.baidu.com/s?id=1664903484937508104&wfr=spider&for=pc
https://blog.csdn.net/naer_chongya/article/details/131429885
https://blog.csdn.net/programmerbug/article/details/127872706