Python实战:批量处理Word文档转PDF(支持doc/docx,跨平台方案)
1. 为什么需要批量转换Word到PDF在日常办公中我们经常会遇到需要将大量Word文档转换为PDF格式的场景。PDF作为一种通用的文档格式具有跨平台显示一致、不易被修改、体积较小等优点。比如公司需要将历年积累的合同文档统一归档为PDF或者老师需要把几十份学生作业转换为PDF以便批注。手动一个个打开Word文件另存为PDF显然效率太低。我曾经接手过一个项目需要将2000多份技术文档从doc格式转换为pdf如果手动操作至少需要3天时间。而用Python脚本处理不到1小时就全部完成这就是自动化办公的魅力。2. 环境准备与工具选择2.1 跨平台方案对比在Windows和Linux系统下Word转PDF的实现方式有所不同Windows方案核心依赖Microsoft Word应用程序使用win32com库调用Word的COM接口优点转换质量高保留所有格式缺点需要安装Office软件Linux方案核心依赖LibreOffice办公套件使用subprocess调用命令行工具优点开源免费服务器环境友好缺点某些复杂格式可能略有差异2.2 安装必备Python库无论哪种方案我们都需要以下Python库pip install pywin32 # Windows专用 pip install python-docx # 文档处理对于Linux用户还需要安装LibreOfficesudo apt update sudo apt install libreoffice3. Windows系统实现方案3.1 使用win32com调用Word这是最稳定的Windows解决方案原理是通过COM接口控制Word应用程序import os from win32com import client def word_to_pdf(input_path, output_folder): word client.Dispatch(Word.Application) word.Visible False # 后台运行 try: doc word.Documents.Open(input_path) filename os.path.splitext(os.path.basename(input_path))[0] output_path os.path.join(output_folder, f{filename}.pdf) # 参数17表示PDF格式 doc.SaveAs(output_path, FileFormat17) print(f转换成功: {input_path} - {output_path}) except Exception as e: print(f转换失败 {input_path}: {str(e)}) finally: doc.Close() word.Quit()3.2 批量处理技巧处理大量文件时建议添加以下优化错误处理跳过损坏的文件进度显示使用tqdm显示进度条日志记录记录转换失败的文件from tqdm import tqdm def batch_convert(folder_path, output_folder): if not os.path.exists(output_folder): os.makedirs(output_folder) word_files [f for f in os.listdir(folder_path) if f.endswith((.doc, .docx))] for filename in tqdm(word_files, desc转换进度): input_path os.path.join(folder_path, filename) word_to_pdf(input_path, output_folder)4. Linux系统实现方案4.1 使用LibreOffice命令行LibreOffice提供了强大的命令行转换功能import subprocess import os def convert_to_pdf_linux(input_path, output_folder): try: cmd [ libreoffice, --headless, --convert-to, pdf, --outdir, output_folder, input_path ] subprocess.run(cmd, checkTrue) print(f转换成功: {input_path}) except subprocess.CalledProcessError as e: print(f转换失败 {input_path}: {str(e)})4.2 处理权限问题在服务器环境运行时可能会遇到权限问题解决方法指定完整的LibreOffice路径使用www-data用户安装LibreOffice设置正确的文件权限# 通常安装路径为 libreoffice_path /usr/bin/libreoffice5. 高级功能实现5.1 保留目录结构如果需要保持原始文件夹结构可以使用递归处理def process_folder(input_folder, output_folder): for root, _, files in os.walk(input_folder): relative_path os.path.relpath(root, input_folder) current_output os.path.join(output_folder, relative_path) if not os.path.exists(current_output): os.makedirs(current_output) for file in files: if file.endswith((.doc, .docx)): input_path os.path.join(root, file) if os.name nt: # Windows word_to_pdf(input_path, current_output) else: # Linux/Mac convert_to_pdf_linux(input_path, current_output)5.2 添加水印和元数据转换时可以添加额外信息from PyPDF2 import PdfReader, PdfWriter def add_watermark(pdf_path, watermark_text): reader PdfReader(pdf_path) writer PdfWriter() for page in reader.pages: page.compress_content_streams() writer.add_page(page) # 添加水印 writer.add_metadata({ /Title: 转换文档, /Creator: Python自动化工具, /Watermark: watermark_text }) with open(pdf_path, wb) as f: writer.write(f)6. 常见问题解决方案问题1Word进程残留解决方法确保在finally块中调用Quit()问题2中文乱码解决方法检查系统默认编码建议使用UTF-8问题3格式错乱解决方法更新Word/LibreOffice到最新版尝试将文档另存为RTF再转换问题4性能优化对于超大批量处理使用多进程处理分批处理文件关闭杀毒软件实时监控from multiprocessing import Pool def worker(args): input_path, output_folder args if os.name nt: word_to_pdf(input_path, output_folder) else: convert_to_pdf_linux(input_path, output_folder) def parallel_convert(file_list, output_folder, processes4): with Pool(processes) as p: args [(f, output_folder) for f in file_list] list(tqdm(p.imap(worker, args), totallen(args)))7. 完整代码示例以下是跨平台的完整实现import os import sys from tqdm import tqdm def convert_word_to_pdf(input_path, output_folder): 跨平台Word转PDF if os.name nt: # Windows系统 from win32com import client word client.Dispatch(Word.Application) word.Visible False try: doc word.Documents.Open(input_path) filename os.path.splitext(os.path.basename(input_path))[0] output_path os.path.join(output_folder, f{filename}.pdf) doc.SaveAs(output_path, FileFormat17) return True except Exception as e: print(fError converting {input_path}: {str(e)}) return False finally: doc.Close() word.Quit() else: # Linux/Mac系统 try: cmd [ libreoffice, --headless, --convert-to, pdf, --outdir, output_folder, input_path ] subprocess.run(cmd, checkTrue, stdoutsubprocess.PIPE, stderrsubprocess.PIPE) return True except subprocess.CalledProcessError as e: print(fError converting {input_path}: {str(e)}) return False def main(): if len(sys.argv) ! 3: print(Usage: python word_to_pdf.py input_folder output_folder) return input_folder sys.argv[1] output_folder sys.argv[2] if not os.path.exists(output_folder): os.makedirs(output_folder) word_files [] for root, _, files in os.walk(input_folder): for file in files: if file.lower().endswith((.doc, .docx)): word_files.append(os.path.join(root, file)) print(f找到 {len(word_files)} 个Word文档需要转换) success 0 for filepath in tqdm(word_files, desc转换进度): if convert_word_to_pdf(filepath, output_folder): success 1 print(f转换完成成功 {success}/{len(word_files)}) if __name__ __main__: main()这个脚本可以直接通过命令行运行python word_to_pdf.py input_folder output_folder在实际项目中这个脚本帮我处理了数千份文档的批量转换特别是在文档归档和电子合同签署场景下非常实用。建议首次使用时先用少量文件测试确认格式转换符合预期后再处理大批量文件。