You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.11 17:23:21