Django使用docx2pdf转上传Word为PDF时出现CoInitialize未调用错误
报错原因
CoInitialize has not been called 是Windows COM组件的初始化错误,docx2pdf底层依赖Microsoft Word的COM接口完成格式转换,Django的请求处理线程默认没有初始化COM环境,所以调用转换接口时会抛出该错误。
解决步骤
- 引入COM操作依赖模块
pythoncom,该模块属于pywin32依赖包,安装docx2pdf时已默认附带,缺失可执行pip install pywin32安装。 - 在调用
convert函数前手动初始化COM环境,转换完成后释放COM环境。 - 修正原有代码中的语法错误和逻辑错误:
- 原代码中
file_type == ".docx":缺少if关键字,属于语法错误,不会触发docx转换逻辑 convert执行完成后会在docx同目录生成对应PDF文件,原有代码直接用上传的docx文件对象保存PDF,属于逻辑错误,需要读取生成的PDF文件再写入数据库- 路径拼接建议使用
os.path.join避免路径分隔符兼容问题
- 原代码中
修改后的参考代码
import os import pythoncom from django.conf import settings def post(self, request): files = request.FILES.getlist("files") for f in files: file_type = getFileType(f)[-1] if file_type == ".docx": new_file = File() fs = FileSystemStorage() # 保存上传的docx文件 docx_name = fs.save(f.name, f) docx_full_path = os.path.join(settings.MEDIA_ROOT, docx_name) # 初始化COM环境 pythoncom.CoInitialize() try: # 调用转换接口 convert(docx_full_path) # 拼接生成的PDF路径 pdf_name = os.path.splitext(docx_name)[0] + ".pdf" pdf_full_path = os.path.join(settings.MEDIA_ROOT, pdf_name) # 读取生成的PDF文件保存到数据库 with open(pdf_full_path, 'rb') as pdf_f: new_file.file.save(pdf_name, pdf_f, save=False) new_file.save() finally: # 释放COM环境 pythoncom.CoUninitialize() resp = {"message": "Files Uploaded"} return Response(resp, status=status.HTTP_200_OK)
额外注意事项
- 部署该服务的Windows环境必须安装Microsoft Word,否则docx2pdf无法正常工作
- 转换完成后如果不需要保留源docx和临时生成的PDF文件,可以自行添加删除逻辑
内容的提问来源于stack exchange,提问作者Hrishikesh Lamdade
相关产品推荐
相关产品推荐

