Django文档翻译应用中Docx转换器返回NoneType的问题
Django文档翻译应用输出文件无法打开问题排查与解决
问题现象
- 输出的翻译文档无法打开,修改扩展名为docx后可被Word读取,但PDF阅读器无法识别
- 代码分析显示输出文件类型为
NoneType,内容为None - 本地生成的PDF文件可用,但通过reConverter函数返回给浏览器的文件无效
- 尝试用win32com手动转换时出现CoInitialization错误
核心问题定位
reConverter函数中使用的docx2pdf.convert()方法无返回值,导致函数返回None,最终传递给HttpResponse的内容为空,生成无效文件。
代码修复方案
1. 修复reConverter函数,返回PDF文件内容
修改reConverter,不再返回convert的结果,而是读取生成的PDF文件的二进制内容:
def reConverter(inputDocxPath): # 将docx转为pdf print('reConverter: '+str(inputDocxPath)) outputPdfPath = inputDocxPath.replace('.docx', '.pdf') # convert函数无返回值,执行即可生成文件 convert(inputDocxPath, outputPdfPath) # 读取生成的PDF文件内容 with open(outputPdfPath, 'rb') as f: pdf_content = f.read() return pdf_content
2. 修复视图中的文件名问题
视图中返回的文件名需改为生成的PDF文件名,避免和原上传文件混淆:
@csrf_protect def translateFile(request) : if request.method == 'POST': form = UploadFileForm(request.POST, request.FILES) if form.is_valid(): uploaded_file = request.FILES['file'] fs = FileSystemStorage() filename = fs.save(uploaded_file.name, uploaded_file) uploaded_file_path = fs.path(filename) file_content = converter(uploaded_file_path) # 生成带翻译标记的PDF文件名 pdf_filename = filename.replace('.pdf', '_translated.pdf') response = HttpResponse(file_content, content_type='application/pdf') response['Content-Disposition'] = f'attachment; filename="{pdf_filename}"' return response else: form = UploadFileForm() return render(request, 'translator_upload/upload.html', {'form': form})
3. 处理win32com的CoInitialization错误(若改用该方案)
如果需要使用win32com进行转换,需在调用前初始化COM环境,并处理线程问题:
import pythoncom import win32com.client def reConverter(inputDocxPath): outputPdfPath = inputDocxPath.replace('.docx', '.pdf') # 初始化COM环境 pythoncom.CoInitialize() try: wordObj = win32com.client.Dispatch('Word.Application') docObj = wordObj.Documents.Open(inputDocxPath) # 直接使用wdFormatPDF对应的常量值17 docObj.SaveAs(outputPdfPath, FileFormat=17) docObj.Close() wordObj.Quit() finally: # 释放COM环境 pythoncom.CoUninitialize() # 读取文件内容返回 with open(outputPdfPath, 'rb') as f: return f.read()
4. 清理临时文件(可选)
转换完成后删除临时生成的docx文件,避免占用存储空间:
import os def converter(inputPdfPath): pdf_file = inputPdfPath docx_file = inputPdfPath.replace('.pdf', '.docx') print('file types saved: '+docx_file+'. Converting to docx') parse(pdf_file, docx_file) myDoc = docx.Document(docx_file) print('converter '+str(myDoc)) pdf_content = translateDocx(myDoc, docx_file) # 删除临时docx文件 os.remove(docx_file) return pdf_content
关键说明
docx2pdf.convert()仅负责生成文件,无返回值,不能直接返回其调用结果- Django的
HttpResponse需要传入文件的二进制内容,才能生成有效的下载文件 - 使用win32com时,必须在每个线程中初始化和释放COM环境,Django默认多线程,需在函数内部处理
内容的提问来源于stack exchange,提问作者tthheemmaannii
相关产品推荐
相关产品推荐

