这里是利用WPS进行转换,要先安装WPS。
安装依赖
pip install pypiwin32
代码
#!/usr/bin/python
# -*- coding: UTF-8 -*-
import os
import win32com.client
def ConvertByWps(sourceFile, targetFile):
if not os.path.exists(sourceFile):
print(sourceFile + "不存在,无法继续!")
return False
typemap = {
'doc': 'word',
'docx': 'word',
'ppt': 'ppt',
'pptx': 'ppt',
'xls': 'excel',
'xlsx': 'excel',
}
name_arr = sourceFile.split(".")
suffix = name_arr[len(name_arr) - 1]
wpstype = typemap.get(suffix)
if (wpstype is None):
return False
os.system('taskkill /im wps.exe')
# 如果文件存在就删除
if os.path.exists(targetFile):
os.remove(targetFile)
if wpstype == 'word':
ConvertDocToPdf(sourceFile, targetFile)
elif wpstype == 'ppt':
ConvertPptToPdf(sourceFile, targetFile)
elif wpstype == 'excel':
ConvertXlsToPdf(sourceFile, targetFile)
if os.path.exists(targetFile):
return True
else:
return False
# 转换 Word文件档到pdf
def ConvertDocToPdf(src, dst):
wps = win32com.client.Dispatch("Kwps.Application")
wps.Visible = False
doc = wps.Documents.Open(src)
doc.ExportAsFixedFormat(dst, 17)
doc.Close()
wps.Quit()
# 转换 PPT文件档到pdf
def ConvertPptToPdf(src, dst):
wps = win32com.client.Dispatch("Kwpp.Application")
wps.Visible = False
ppt = wps.Presentations.Open(src)
ppt.SaveAs(dst, 32)
ppt.Close()
wps.Quit()
# 转换 XLS文件档到pdf
def ConvertXlsToPdf(src, dst):
wps = win32com.client.Dispatch("Ket.Application")
excel = wps.Workbooks.Open(src)
excel.ExportAsFixedFormat(0, dst)
excel.Close()
wps.Quit()
if __name__ == '__main__':
# 当前目录
d = os.path.dirname(__file__)
abspath = os.path.abspath(d)
# 测试用例
src = abspath + r"/Doc/test.docx"
dst = abspath + r"/Doc/test.pdf"
r = ConvertByWps(src, dst)
print(r)
PDF转图片
方式1
fitz
pip install fitz
pip install PyMuPDF
转换
import fitz
import os
import time
# 将PDF转化为图片
# pdfPath pdf文件的路径
# imgPath 图像要保存的文件夹
# zoom_x x方向的缩放系数
# zoom_y y方向的缩放系数
# rotation_angle 旋转角度
def pdf_image(pdfPath, imgPath, zoom_x, zoom_y, rotation_angle):
path_arr = pdfPath.split(os.sep)
path_arr.reverse()
filename = ""
if(len(path_arr) > 0):
filename = path_arr[0].split(".")[0]
start_time = time.perf_counter()
pdf = fitz.open(pdfPath)
# 逐页读取PDF
filename_arr = []
for pg in range(0, pdf.pageCount):
page = pdf[pg]
# 设置缩放和旋转系数
trans = fitz.Matrix(zoom_x, zoom_y).prerotate(rotation_angle)
pm = page.get_pixmap(matrix=trans, alpha=False)
# 开始写图像
filename_all = f'{imgPath}{os.sep}{filename}_{str(pg)}.png'
pm.save(filename_all)
filename_arr.append(filename_all)
pdf.close()
end_time = time.perf_counter()
print(f"时间差:{end_time-start_time}")
print(len(filename_arr))
pdf_image(
r"D:\Tools\DocTest\145页.pdf",
r"D:\Tools\DocTest\pic",
2,
2,
0
)
方式2
安装poppler
Poppler for Windows
添加bin对应目录到环境变量
注意
如果调用方法传入poppler_path参数,则不用设置环境变量。
https://github.com/Belval/pdf2image
安装依赖
pip install pdf2image
转换代码
from pdf2image import convert_from_path, convert_from_bytes
from pdf2image.exceptions import (
PDFInfoNotInstalledError,
PDFPageCountError,
PDFSyntaxError
)
import time
try:
start_time = time.perf_counter()
images = convert_from_path(
r"D:\Tools\DocTest\145页.pdf",
output_folder=r"D:\Tools\DocTest\pic",
poppler_path=r"D:\Tools\poppler-0.67.0\bin",
size=(1024, None),
thread_count=4,
timeout=60,
fmt='jpeg'
)
end_time = time.perf_counter()
print(f"时间差:{end_time-start_time}")
print(images[0])
except PDFInfoNotInstalledError:
print("未安装poppler")
except PDFPageCountError:
print("页面异常")
except PDFSyntaxError:
print("PDF页面异常")
except:
print("其它异常")
转换时间对比
PDF页数 | 是否带水印 | 方式1(s) | 方式2(s) | 方式2-4线程(s) |
---|
1 | 否 | 0.0596313 | 0.1325932 | 0.1315048 | 2 | 是 | 0.2342085 | 0.2125386 | 0.1481465 | 145 | 否 | 23.7634431 | 16.4102064 | 5.3497324 | 448 | 否/纯文字 | 20.5313859 | 30.8443124 | 8.4962063 |
粉丝福利,需要的自取https://docs.qq.com/pdf/DR3dMaE1CSkZ6RlBZ
结论
- 转换速度方式2在页面少的时候时间稍长,但是一旦页码多的时候方式2优势就比较明显。
- 两种都能正常转换带水印的文档。
- 如果文档都是纯文字GBK的时候,方式1转换正常,而方式2乱码。
方式1我切换为多线程依旧作用不大
import fitz
import os
import time
from concurrent import futures
import threading
# 将PDF转化为图片
# pdfPath pdf文件的路径
# imgPath 图像要保存的文件夹
# zoom_x x方向的缩放系数
# zoom_y y方向的缩放系数
# rotation_angle 旋转角度
def pdf_image(pdfPath, imgPath, zoom_x, zoom_y, rotation_angle):
path_arr = pdfPath.split(os.sep)
path_arr.reverse()
filename = ""
if(len(path_arr) > 0):
filename = path_arr[0].split(".")[0]
start_time = time.perf_counter()
pdf = fitz.open(pdfPath)
# 逐页读取PDF
filename_arr = []
pages = []
def savePage(pageobj):
print(threading.current_thread().name)
page = pageobj["page"]
pg = pageobj["pg"]
# 设置缩放和旋转系数
trans = fitz.Matrix(zoom_x, zoom_y).prerotate(rotation_angle)
pm = page.get_pixmap(matrix=trans, alpha=False)
# 开始写图像
filename_all = f'{imgPath}{os.sep}{filename}_{str(pg)}.png'
pm.save(filename_all)
filename_arr.append(filename_all)
for pg in range(0, pdf.pageCount):
page = pdf[pg]
pages.append({
"page": page,
"pg": pg
})
print(len(pages))
with futures.ThreadPoolExecutor(max_workers=8) as executor:
for future in executor.map(savePage, pages):
pass
pdf.close()
end_time = time.perf_counter()
print(f"时间差:{end_time-start_time}")
print(len(filename_arr))
pdf_image(
r"D:\Tools\DocTest\145页.pdf",
r"D:\Tools\DocTest\pic",
2,
2,
0
)
|