pip install pywin32
import os
import win32com.client
import pythoncom # 新增:用于處理COM線程
import sysdef docx_to_pdf(docx_path, pdf_path=None):"""將Word文檔轉換為PDF格式,修復退出時的COM錯誤"""if not os.path.exists(docx_path):raise FileNotFoundError(f"文件不存在: {docx_path}")if pdf_path is None:pdf_path = os.path.splitext(docx_path)[0] + ".pdf"# 初始化COM線程(避免線程相關的錯誤)pythoncom.CoInitialize()word = Nonedoc = Nonetry:# 創建Word應用對象word = win32com.client.Dispatch("Word.Application")word.Visible = False# 打開文檔(添加只讀參數,避免鎖定文件)doc = word.Documents.Open(docx_path, ReadOnly=True)# 保存為PDFdoc.SaveAs2(pdf_path, FileFormat=17)print(f"轉換成功: {pdf_path}")except Exception as e:print(f"轉換失敗: {str(e)}")finally:# 先關閉文檔(確保文檔先釋放)if doc is not None:doc.Close(SaveChanges=0) # 0表示不保存更改doc = None # 顯式釋放對象# 再退出Word(確保文檔關閉后再退出)if word is not None:try:word.Quit()except Exception as e:# 忽略退出時的錯誤(因為轉換已成功)print(f"關閉Word時警告: {str(e)}")word = None # 顯式釋放對象# 釋放COM資源pythoncom.CoUninitialize()if __name__ == "__main__":# 檢查命令行參數if len(sys.argv) < 2:print("單文件Word轉PDF轉換器")print("用法: python docx_to_pdf.py <Word文件路徑> [輸出PDF路徑]")print("示例1: python docx_to_pdf.py D:\\d\\a.docx")print("示例2: python docx_to_pdf.py D:\\d\\a.docx D:\\d\\output.pdf")sys.exit(1)# 獲取輸入文件路徑input_file = sys.argv[1]# 獲取輸出文件路徑(如果提供了)output_file = sys.argv[2] if len(sys.argv) > 2 else None# 檢查輸入文件是否存在if not os.path.exists(input_file):print(f"錯誤: 輸入文件不存在: {input_file}")sys.exit(1)# 檢查輸入文件是否為Word文檔if not input_file.lower().endswith(('.doc', '.docx')):print(f"錯誤: 輸入文件不是Word文檔: {input_file}")sys.exit(1)# 執行轉換try:docx_to_pdf(input_file, output_file)print("轉換完成!")except Exception as e:print(f"轉換過程中發生錯誤: {str(e)}")sys.exit(1)
然后在java里面調用這個腳本
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;public class PythonScriptCaller {/*** 調用Python腳本實現Word轉PDF* @param scriptPath Python腳本的絕對路徑* @param docxPath 需要轉換的Word文檔路徑* @return 轉換結果(成功/失敗信息)*/public static String callDocxToPdfScript(String scriptPath, String docxPath) {// 構建命令:python 腳本路徑 文檔路徑(通過參數傳遞docx路徑,增強靈活性)String[] command = {"python", scriptPath, docxPath};ProcessBuilder processBuilder = new ProcessBuilder(command);// 合并錯誤流到輸出流,方便統一處理processBuilder.redirectErrorStream(true);Process process = null;StringBuilder result = new StringBuilder();try {// 啟動進程執行命令process = processBuilder.start();// 讀取腳本輸出InputStream inputStream = process.getInputStream();BufferedReader reader = new BufferedReader(new InputStreamReader(inputStream, "GBK")); // 適配中文輸出String line;while ((line = reader.readLine()) != null) {result.append(line).append("\n");}// 等待進程執行完成int exitCode = process.waitFor();if (exitCode == 0) {result.append("腳本執行成功,退出碼:").append(exitCode);} else {result.append("腳本執行失敗,退出碼:").append(exitCode);}} catch (IOException e) {result.append("執行腳本時發生IO錯誤:").append(e.getMessage());} catch (InterruptedException e) {result.append("腳本執行被中斷:").append(e.getMessage());Thread.currentThread().interrupt(); // 恢復中斷狀態} finally {if (process != null) {process.destroy(); // 確保進程銷毀}}return result.toString();}// 測試方法public static void main(String[] args) {// 替換為實際的腳本路徑和Word文檔路徑String scriptPath = "D:\\git\\docx_to_pdf\\docx_to_pdf.py";String docxPath = "D:\\d\\a.docx";String result = callDocxToPdfScript(scriptPath, docxPath);System.out.println("轉換結果:\n" + result);}
}
批量遞歸
import os
import win32com.client
import pythoncom
import shutil
import sysdef convert_all_docs_to_pdf(source_dir, target_dir):"""遞歸遍歷源目錄,將所有Word文檔轉換為PDF并保存到目標目錄Args:source_dir: 源目錄路徑target_dir: 目標目錄路徑"""# 確保目標目錄存在if not os.path.exists(target_dir):os.makedirs(target_dir)# 遍歷源目錄for root, dirs, files in os.walk(source_dir):# 計算相對路徑relative_path = os.path.relpath(root, source_dir)if relative_path == '.':relative_path = ''# 創建對應的目標目錄target_subdir = os.path.join(target_dir, relative_path)if not os.path.exists(target_subdir):os.makedirs(target_subdir)# 處理當前目錄下的文件for file in files:if file.endswith(('.doc', '.docx')):# 源文件路徑source_file_path = os.path.join(root, file)# 目標PDF文件路徑(保持相同文件名但擴展名為.pdf)pdf_filename = os.path.splitext(file)[0] + '.pdf'target_file_path = os.path.join(target_subdir, pdf_filename)# 轉換文件print(f"正在轉換: {source_file_path}")docx_to_pdf(source_file_path, target_file_path)print("所有文件轉換完成!")def docx_to_pdf(docx_path, pdf_path=None):"""將Word文檔轉換為PDF格式,修復退出時的COM錯誤"""if not os.path.exists(docx_path):raise FileNotFoundError(f"文件不存在: {docx_path}")if pdf_path is None:pdf_path = os.path.splitext(docx_path)[0] + ".pdf"# 初始化COM線程(避免線程相關的錯誤)pythoncom.CoInitialize()word = Nonedoc = Nonetry:# 創建Word應用對象word = win32com.client.Dispatch("Word.Application")word.Visible = False# 打開文檔(添加只讀參數,避免鎖定文件)doc = word.Documents.Open(docx_path, ReadOnly=True)# 保存為PDFdoc.SaveAs2(pdf_path, FileFormat=17)print(f"轉換成功: {pdf_path}")except Exception as e:print(f"轉換失敗: {str(e)}")finally:# 先關閉文檔(確保文檔先釋放)if doc is not None:doc.Close(SaveChanges=0) # 0表示不保存更改doc = None # 顯式釋放對象# 再退出Word(確保文檔關閉后再退出)if word is not None:try:word.Quit()except Exception as e:# 忽略退出時的錯誤(因為轉換已成功)print(f"關閉Word時警告: {str(e)}")word = None # 顯式釋放對象# 釋放COM資源pythoncom.CoUninitialize()if __name__ == "__main__":# 檢查命令行參數if len(sys.argv) < 3:print("批量轉換Word文檔到PDF")print("用法: python batch_doc_to_pdf.py <源目錄> <目標目錄>")print("示例: python batch_doc_to_pdf.py D:\\d1 D:\\d2")sys.exit(1)source_directory = sys.argv[1]target_directory = sys.argv[2]# 檢查源目錄是否存在if not os.path.exists(source_directory):print(f"錯誤: 源目錄不存在: {source_directory}")sys.exit(1)# 檢查源目錄和目標目錄是否相同(防止誤操作)if os.path.abspath(source_directory) == os.path.abspath(target_directory):print("錯誤: 源目錄和目標目錄不能相同")sys.exit(1)print(f"開始轉換: {source_directory} -> {target_directory}")# 執行轉換convert_all_docs_to_pdf(source_directory, target_directory)
java調用python 批量腳本:
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;public class PythonBatchConverter {/*** 調用Python批量轉換腳本實現Word轉PDF* @param scriptPath Python腳本的絕對路徑* @param sourceDir 源目錄路徑* @param targetDir 目標目錄路徑* @return 轉換結果(成功/失敗信息)*/public static String callBatchConversionScript(String scriptPath, String sourceDir, String targetDir) {// 構建命令:python 腳本路徑 源目錄 目標目錄String[] command = {"python", scriptPath, sourceDir, targetDir};ProcessBuilder processBuilder = new ProcessBuilder(command);// 合并錯誤流到輸出流,方便統一處理processBuilder.redirectErrorStream(true);Process process = null;StringBuilder result = new StringBuilder();try {// 啟動進程執行命令process = processBuilder.start();// 讀取腳本輸出InputStream inputStream = process.getInputStream();BufferedReader reader = new BufferedReader(new InputStreamReader(inputStream, "GBK")); // 適配中文輸出String line;while ((line = reader.readLine()) != null) {result.append(line).append("\n");}// 等待進程執行完成int exitCode = process.waitFor();if (exitCode == 0) {result.append("批量轉換執行成功,退出碼:").append(exitCode);} else {result.append("批量轉換執行失敗,退出碼:").append(exitCode);}} catch (IOException e) {result.append("執行腳本時發生IO錯誤:").append(e.getMessage());} catch (InterruptedException e) {result.append("腳本執行被中斷:").append(e.getMessage());Thread.currentThread().interrupt(); // 恢復中斷狀態} finally {if (process != null) {process.destroy(); // 確保進程銷毀}}return result.toString();}/*** 調用單個文件轉換腳本實現Word轉PDF* @param scriptPath Python腳本的絕對路徑* @param docxPath 需要轉換的Word文檔路徑* @return 轉換結果(成功/失敗信息)*/public static String callSingleFileScript(String scriptPath, String docxPath) {// 構建命令:python 腳本路徑 文檔路徑String[] command = {"python", scriptPath, docxPath};ProcessBuilder processBuilder = new ProcessBuilder(command);// 合并錯誤流到輸出流,方便統一處理processBuilder.redirectErrorStream(true);Process process = null;StringBuilder result = new StringBuilder();try {// 啟動進程執行命令process = processBuilder.start();// 讀取腳本輸出InputStream inputStream = process.getInputStream();BufferedReader reader = new BufferedReader(new InputStreamReader(inputStream, "GBK")); // 適配中文輸出String line;while ((line = reader.readLine()) != null) {result.append(line).append("\n");}// 等待進程執行完成int exitCode = process.waitFor();if (exitCode == 0) {result.append("單文件轉換執行成功,退出碼:").append(exitCode);} else {result.append("單文件轉換執行失敗,退出碼:").append(exitCode);}} catch (IOException e) {result.append("執行腳本時發生IO錯誤:").append(e.getMessage());} catch (InterruptedException e) {result.append("腳本執行被中斷:").append(e.getMessage());Thread.currentThread().interrupt(); // 恢復中斷狀態} finally {if (process != null) {process.destroy(); // 確保進程銷毀}}return result.toString();}// 測試方法 - 批量轉換public static void main(String[] args) {// 替換為實際的腳本路徑和目錄路徑String scriptPath = "D:\\git\\docx_to_pdf\\batch_doc_to_pdf.py";String sourceDir = "D:\\d1";String targetDir = "D:\\d2";String result = callBatchConversionScript(scriptPath, sourceDir, targetDir);System.out.println("批量轉換結果:\n" + result);// 測試單文件轉換String singleFileScriptPath = "D:\\git\\docx_to_pdf\\docx_to_pdf.py";String docxPath = "D:\\d1\\a.docx";String singleResult = callSingleFileScript(singleFileScriptPath, docxPath);System.out.println("單文件轉換結果:\n" + singleResult);}
}