话不多说,先贴代码
代码1:Excel转PDF
# -*- coding:utf-8 -*-
import os
from win32com.client import DispatchEx
from ig.documents.ig_pdf_watermark import Add_watermark # 另外写的添加水印的代码位置
class PDFConverter(object):
def __init__(self, pathname, export='.'):
self._handle_postfix = ['xls', 'xlsx']
self._filename_list = list()
self._export_folder = os.path.join("C:\\cdb", 'pdfconver')
if not os.path.exists(self._export_folder):
os.mkdir(self._export_folder)
self._enumerate_filename(pathname)
def _enumerate_filename(self, pathname):
'''读取所有文件名'''
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()
funcCall = getattr(self, postfix)
print('原文件:', filename)
funcCall(filename)
print('转换完成!')
def xls(self, filename):
'''xls 和 xlsx 文件转换'''
name = os.path.basename(filename).split('.')[0] + '.pdf'
exportfile = os.path.join(self._export_folder, name)
if os.path.exists(exportfile): # 如果存在转换后的PDF,删除重新生成
os.remove(exportfile)
xlApp = DispatchEx("Excel.Application")
xlApp.Visible = False
xlApp.DisplayAlerts = 0
books = xlApp.Workbooks.Open(filename, False)
sheet = books.Worksheets(1) # 获取excel的sheet页
sheet.PageSetup.Orientation = 2 # 设置excel转换方向为横向
books.ExportAsFixedFormat(0, exportfile)
books.Close(False)
xlApp.Quit() # 切记,一定要写在添加水印的后面面,不然会报错,太恐怖了
# 给转换后的PDF添加水印
pdf_path = Add_watermark().add_pdf_watermark(exportfile) # 给PDF添加水印
self.pdf_path = pdf_path
def xlsx(self, filename):
self.xls(filename)
if __name__ == "__main__":
# 支持文件夹批量导入
# folder = 'test'
# pathname = os.path.join("C:\\", folder)
# 也支持单个文件的转换
pathname = r'C:\cdb\intron_prd\ig.plm\ig\templates'+u'\ACL替代物料通知书模板.xlsx'
pdfConverter = PDFConverter(pathname)
pdfConverter.run_conver()
代码2:给PDF添加水印
# -*- coding:utf-8 -*-
# 添加水印
import os
from PyPDF2 import PdfFileReader, PdfFileWriter
from copy import copy
# from cdb import cdbtime
import datetime
class Add_watermark():
def add_pdf_watermark(self, path1):
sy = PdfFileReader(r"C:\cdb\intron_prd\ig.plm\ig\templates\watermark.pdf")
mark_page = sy.getPage(0) # 水印所在的页数
# 读取添加水印的文件
file_reader = PdfFileReader(path1)
file_writer = PdfFileWriter()
for page in range(file_reader.getNumPages()):
# 读取需要添加水印每一页pdf
source_page = file_reader.getPage(page)
new_page = copy(mark_page) #
new_page.mergePage(source_page) # new_page(水印)在下面,source_page原文在上面
file_writer.addPage(new_page)
# file_name = u"ACL替代物料通知书" + cdbtime.now('__%Y_%m_%d_%H_%M_%S') + '.pdf'
file_name = u"ACL替代物料通知书" + datetime.datetime.now().strftime("%Y-%m-%d %H-%M-%S")
+ '.pdf'
pdf_path = os.path.join("C:\\cdb\\pdfconver\\", file_name)
if os.path.exists(pdf_path): # 如果存在添加水印后的PDF,删除重新生成
os.remove(pdf_path)
with open(pdf_path, 'wb') as out:
file_writer.write(out)
return pdf_path
3.特别的,需要注意这里
books.Close(False)
xlApp.Quit()
因为我想着转完PDF再关闭,结果系统一直报错,报的我头都大了,报错如下:大家可千万别犯这个错误。
9月份我又遇到这个问题了,经过无数次的修改,还是有问题,最终发现了他真正的报错原因:excel没激活!!!!!!!!
4. 因为excel直接转PDF,当excel列比较多时会将PDF调整为好几页转换,所以需要将excel打印方向设置为横向打印,这样转出来的PDF列就在同一页面了。
sheet = books.Worksheets(1) # 获取excel的sheet页
sheet.PageSetup.Orientation = 2 # 设置excel转换方向为横向