# -*- coding:utf-8 -*-
# -*- coding: utf-8 -*-
# @Time : 2020/9/23 15:42
# @Author : zhihao.zhao
# @Software: PyCharm
# 该方法是综合的来处理同一个文件夹中ppt,excel,word
# 将其转换成pdf
#相关的文件
# 源文件: 处理的文件统一放在 wpe_To_pdf下的files下
# 生成的pdf文件: 统一放在 wpe_To_pdf下的pdfconver下
import os
from win32com.client import Dispatch, constants, gencache, DispatchEx
#class类封装方法,面向对象开发
class PDFConverter:
#每个类中都会有的 __init__()这里是指本类的构造方法
#将一些需要的代码和数据在类对象创建的时候进行处理操作
def __init__(self, pathname, export='.'):
#这里是提供的可以识别的文件,后缀名分别为 doc,docx,ppt,pptx,xls,xlsx
self._handle_postfix = ['doc', 'docx', 'ppt', 'pptx', 'xls', 'xlsx']
#用来保存所有读到的文件名
self._filename_list = list()
#这里是来设置文件的保存路径
self._export_folder = os.path.join(os.path.abspath('.'), 'pdfconver')
#如果保存文件的文件夹中没有要保存的文件则保存,否则需要新建一个文件
if not os.path.exists(self._export_folder):
os.mkdir(self._export_folder)
#读取所有的文件名
self._enumerate_filename(pathname)
#读取文件夹下的文件
def _enumerate_filename(self, pathname):
'''
读取所有文件名
'''
#os下的读取该文件夹下的所有文件,之前在批量读取时使用过
full_pathname = os.path.abspath(pathname)
#以下是对文件的分类处理,判断是否是目录还是文件
if os.path.isfile(full_pathname):
#如果存在我规定的众多文件后缀,那么就将该类文件名进行存储,方便处理
if self._is_legal_postfix(full_pathname):
self._filename_list.append(full_pathname)
else:
raise TypeError('文件 {} 后缀名不合法!仅支持如下文件类型:{}。'.format(pathname, '、'.join(self._handle_postfix)))
elif os.path.isdir(full_pathname):
#如果是目录,则去遍历其内部的文件是否有我需要的相关的文件,然后进行读取
for relpath, _, files in os.walk(full_pathname):
for name in files:
#因为如果读文件夹中的目录下的文件则要去修改其的相对路径,估计后期的处理会按照最初所传路径加上该文件相对路径进行处理
filename = os.path.join(full_pathname, relpath, name)
#可惜这里应该是针对于多层文件结构进行处理但是在这里只看到了层处理,如果要是实现相关的多级目录处理应该使用递归的方式进行处理
if self._is_legal_postfix(filename):
self._filename_list.append(os.path.join(filename))
else:#都不是则为文件目录不合法
raise TypeError('文件/文件夹 {} 不存在或不合法!'.format(pathname))
#分离判断文件后缀名的方法
def _is_legal_postfix(self, filename):
return filename.split('.')[-1].lower() in self._handle_postfix and not os.path.basename(filename).startswith(
'~')
#这个函数基本是主转换函数,用于打印需要转换的文件及文件数,执行转换并提示转换的进度
def run_conver(self):
'''
进行批量处理,根据后缀名调用函数执行转换
'''
#这里是需要打印的文件数:
print('需要转换的文件数:', len(self._filename_list))
#循环遍历处理文件集
for filename in self._filename_list:
#这句应该是以'.'作为分隔条件获取文件的后缀名(小写状态)
postfix = filename.split('.')[-1].lower()
#这里没看太懂,大概是,以上一句所获取的后缀名,作为所调用的函数名
#getattr 经过源码的查看 其方法具体为def getattr(object, name, default=None):
# 先描述一下其的基本作用,去返回第一个参数下的名为第二个参数的属性,我想这里也包括函数和方法
# 基本主要是第一个和第二个参数:
# 第一个参数为 object 一般传入的是一个对象(源码为单词object)
# 第二个参数为 name 一般传入的是这个对象的属性名(源码为单词 attribute)
# 具体的英文解释可以点进去看一下
funcCall = getattr(self, postfix)
print('原文件:', filename)
#调用对应的文件处理函数处理数据
funcCall(filename)
print('转换完成!')
#这里是主要的转换的方法是针对于doc或者是docx文件
def doc(self, filename):
'''
doc 和 docx 文件转换
'''
#这句话是获取文件名,具体是因为需要使用原的文件名作为新生产的文件的名称
name = os.path.basename(filename).split('.')[0] + '.pdf'
#设置保存的文件
exportfile = os.path.join(self._export_folder, name)
#以下就是保存操作吧,具体没看太懂
print('保存 PDF 文件:', exportfile)
gencache.EnsureModule('{00020905-0000-0000-C000-000000000046}', 0, 8, 4)
w = Dispatch("Word.Application")
doc = w.Documents.Open(filename)
doc.ExportAsFixedFormat(exportfile, constants.wdExportFormatPDF,
Item=constants.wdExportDocumentWithMarkup,
CreateBookmarks=constants.wdExportCreateHeadingBookmarks)
w.Quit(constants.wdDoNotSaveChanges)
#这里一样因为doc和docx同为word文档
#self 这里看来好像和this很像,应该是代表本对象本类
def docx(self, filename):
self.doc(filename)
#这是针对于xls的方式的转换
def xls(self, filename):
'''
xls 和 xlsx 文件转换
'''
name = os.path.basename(filename).split('.')[0] + '.pdf'
exportfile = os.path.join(self._export_folder, name)
xlApp = DispatchEx("Excel.Application")
xlApp.Visible = False
xlApp.DisplayAlerts = 0
books = xlApp.Workbooks.Open(filename, False)
books.ExportAsFixedFormat(0, exportfile)
books.Close(False)
print('保存 PDF 文件:', exportfile)
xlApp.Quit()
def xlsx(self, filename):
self.xls(filename)
def ppt(self, filename):
'''
ppt 和 pptx 文件转换
'''
name = os.path.basename(filename).split('.')[0] + '.pdf'
exportfile = os.path.join(self._export_folder, name)
gencache.EnsureModule('{00020905-0000-0000-C000-000000000046}', 0, 8, 4)
p = Dispatch("PowerPoint.Application")
ppt = p.Presentations.Open(filename, False, False, False)
ppt.ExportAsFixedFormat(exportfile, 2, PrintRange=None)
print('保存 PDF 文件:', exportfile)
p.Quit()
def pptx(self, filename):
self.ppt(filename)
if __name__ == "__main__":
# 支持文件夹批量导入
folder = 'tmp'
pathname = os.path.join(os.path.abspath('.'), folder)
# 也支持单个文件的转换
# pathname = 'test.doc'
pdfConverter = PDFConverter('./files')
pdfConverter.run_conver()