Python調用Win32com實現Office批量轉PDF
需求
- 一直以來有將諸如Word之類的Office文檔轉為PDF的需求,此前的方法是挨個打開文檔,手動另存為PDF,此方法費時費力,尤其在電腦配置不高、同時運行很多程序的情況下會造成卡頓,因此需要通過Python將此類文檔自動轉為PDF,如果能夠批量轉換最好。
調研
-
在網上搜索調研后,決定選擇Win32com組件,因為它是微軟的原生API,功能強大,手動操作Office能做到的通過調用Win32com一樣能實現。缺陷是僅限於Win+Office環境。
-
在原先需求的基礎上增加PDF轉PNG圖片,經調研后選擇使用PyMuPDF。
代碼實現
- Office轉PDF
from win32com.client import Dispatch
from os import walk
import sys
def doc2pdf(input_file):
word = Dispatch('Word.Application') # WPS改為Kwps.Application
# word = DispatchEx('Word.Application') # 啟動獨立進程
output_file = input_file.split(".")
try:
doc = word.Documents.Open(input_file)
doc.SaveAs(output_file[0] + ".pdf", FileFormat=17) # Word另存為PDF為17
doc.Close()
except:
print("Unexpected error:", sys.exc_info())
word.Quit()
def ppt2pdf(input_file):
powerpoint = Dispatch('Powerpoint.Application') # WPS改為Kwpp.Application
output_file = input_file.split(".")
try:
ppt = powerpoint.Presentations.Open(input_file)
ppt.SaveAs(output_file[0] + ".pdf", FileFormat=32) # PPT另存為PDF為32
ppt.Close()
except:
print("Unexpected error:", sys.exc_info())
powerpoint.Quit()
def xls2pdf(input_file):
excel = Dispatch('Excel.Application') # WPS改為Ket.Application
output_file = input_file.split(".")
try:
xls = excel.Workbooks.Open(input_file)
xls.SaveAs(output_file[0] + ".pdf", FileFormat=57) # Excel另存為PDF為57
xls.Close()
except:
print("Unexpected error:", sys.exc_info())
excel.Quit()
if __name__ == "__main__":
doc_files = []
directory = "C:\\Users\\Administrator\\Desktop"
# 對directory目錄里的所有文件進行遍歷
for root, dirs, filenames in walk(directory):
for file in filenames:
# 忽略~$開頭的臨時文件,並根據后綴名判斷文件類型
if file.find("~$") == -1:
if file.endswith(".doc") or file.endswith(".docx") or file.endswith(".DOC"):
doc2pdf(str(root + "\\" + file))
elif file.endswith(".ppt") or file.endswith(".pptx") or file.endswith(".PPT"):
ppt2pdf(str(root + "\\" + file))
elif file.endswith(".xls") or file.endswith(".xlsx") or file.endswith(".XLS"):
xls2pdf(str(root + "\\" + file))
- PDF轉png
from os import walk
import sys
import fitz
'''
# 將PDF轉化為圖片
input_file pdf文件的路徑
zoom_x x方向的縮放系數
zoom_y y方向的縮放系數
rotation_angle 旋轉角度
'''
def pdftoimage(input_file,zoom_x,zoom_y,rotation_angle):
try:
# 打開PDF文件
pdf = fitz.open(input_file)
# 逐頁讀取PDF
for pg in range(0, pdf.pageCount):
page = pdf[pg]
# 設置縮放和旋轉系數
trans = fitz.Matrix(zoom_x, zoom_y).preRotate(rotation_angle)
pm = page.getPixmap(matrix=trans, alpha=False)
# 開始寫圖像
pm.writePNG(input_file.replace(".pdf","")+str(pg+1)+".png")
pdf.close()
except:
print("Unexpected error:", sys.exc_info())
if __name__ == "__main__":
doc_files = []
directory = "C:\\Users\\Administrator\\Desktop"
for root, dirs, filenames in walk(directory):
for file in filenames:
if file.endswith(".pdf"):
pdftoimage(str(root + "\\" + file),2,2,0)
注意事項
-
調用Win32com對Office文檔進行操作與人工手動打開Office文檔無異,優點在不用手動點擊鼠標
-
此代碼根據對應目錄下的文件挨個轉換,未支持異步多線程轉換
-
使用DispatchEx可啟動獨立進程進行轉換,優點在於不影響正在編輯的文檔,缺點在於如果轉換出錯會造成進程殘留
-
代碼運行中可能看到Word/Excel/PowerPoint窗口顯示或錯誤警告,可添加
word.Visible = 0
隱藏窗口,添加word.DisplayAlerts = 0
忽略錯誤警告 -
加入try/except是為了防止轉換異常導致進程未關閉,從而造成Office無法打開的情況發生
-
Word、Excel、PowerPoint另存為PDF的FileFormat不同,Word為17、Excel為57、PowerPoint為32
-
如果轉換的同時有對應的Word/Excel/PowerPoint實例在運行,轉換完畢后的.Quit()方法會將這些實例一並關閉,請提前做好保存,或使用DispatchEx啟動獨立進程,建議不要在運行代碼的同時打開實例
-
PDF轉PNG時一定要先安裝fitz,再安裝PyMuPDF,否則會報錯