Javascript 如何在Django项目中下载PythonDocx生成的文档?

Javascript 如何在Django项目中下载PythonDocx生成的文档?,javascript,python,django,httpresponse,python-docx,Javascript,Python,Django,Httpresponse,Python Docx,我正在尝试在我还在学习的django应用程序中下载用PythonDocx生成的word文档,这是我第一次使用文档;在ajax的帮助下,我将所有需要的信息发送到视图并调用一个函数,该函数使用这些信息并返回文档,然后我尝试将此文档作为响应发送,以便在下载按钮的帮助下下载它,或在提交数据的同一模板中显示web浏览器下载对话框,但这就是我被困的地方 将此文档作为响应发送,以便在下载按钮的帮助下进行下载,或在提交数据的同一模板中显示web浏览器下载对话框,但我遇到了麻烦 到目前为止,我所拥有的是: 1在j

我正在尝试在我还在学习的django应用程序中下载用PythonDocx生成的word文档,这是我第一次使用文档;在ajax的帮助下,我将所有需要的信息发送到视图并调用一个函数,该函数使用这些信息并返回文档,然后我尝试将此文档作为响应发送,以便在下载按钮的帮助下下载它,或在提交数据的同一模板中显示web浏览器下载对话框,但这就是我被困的地方

将此文档作为响应发送,以便在下载按钮的帮助下进行下载,或在提交数据的同一模板中显示web浏览器下载对话框,但我遇到了麻烦

到目前为止,我所拥有的是:

1在javascript中,我发送的信息如下:

2在我的Django看来:

3我创建文档的功能如下所示:

如果您有任何想法或建议,我将不胜感激,谢谢

注:我已经复习了这些答案和其他答案,但都不走运

,

更新:感谢收到的反馈,我终于找到了如何生成文档并显示下载对话框:

正如我们所建议的,使用视图而不是ajax实现its的最佳方法,因此代码中的最终更新是:

更新视图以在反馈中显示的方式工作

b JavaScript-POST方法的Ajax控件被删除,现在所有的控件都直接用python处理,不需要额外的代码

1.观点:

def Reporte(request):
    if request.method == "GET":
        context={}
        context['form'] = catForm
        return render(request, 'reportes/reporte_base.html', context)

    if request.method == 'POST':
        #Getting data needed after submit the form in the page
        GcasID = request.POST.get('GCASS')
        FI = request.POST.get('dp1')
        FF = request.POST.get('dp2')
        Grafica = request.POST.get('options')

        #Function to obtain complete code from GcasID 
        Gcas =  GcasNumber(GcasID)

        #Report creation
        Reporte = ReporteWord(Gcas, FI, FF, Grafica)

        #PART UPDATED TO SHOW DOWNLOAD REPORT DIALOG
        bio = io.BytesIO()
        Reporte.save(bio)  # save to memory stream
        bio.seek(0)  # rewind the stream
        response = HttpResponse(
        bio.getvalue(),  # use the stream's contents
        content_type="application/vnd.openxmlformats-officedocument.wordprocessingml.document",
    )

        response["Content-Disposition"] = 'attachment; filename = "Reporte.docx"'
        response["Content-Encoding"] = "UTF-8"
        return response
现在,当我按下表单的CreateReportSubmit按钮时,所有的工作都按预期进行,而且不需要更多的库。最后,正如您所建议的那样,用这种方式比使用ajax更容易

非常感谢大家的帮助。

Python docx的方法接受流而不是文件名。因此,您可以初始化io.BytesIO对象以将文档保存到其中,然后将其转储给用户

Reporte = ReporteWord(Gcas, FI, FF, grafica)
bio = io.BytesIO()
Reporte.save(bio)  # save to memory stream
bio.seek(0)  # rewind the stream
response = HttpResponse(
    bio.getvalue(),  # use the stream's contents
    content_type="application/vnd.openxmlformats-officedocument.wordprocessingml.document",
)
response["Content-Disposition"] = 'attachment; filename = "Reporte.docx"'
response["Content-Encoding"] = "UTF-8"
return response

如果您使用常规链接或表单来提交请求,这将起作用,但是由于您使用的是$.ajax,因此您可能需要在浏览器端执行额外的工作,以便客户端下载文件。不使用$.ajax会更容易。

您可以发布错误消息,或者描述哪些有效,哪些无效吗?谢谢您的回复;我在控制台中没有收到任何错误消息,基本上我发布的所有部分都是:来自AJAX post的数据传递到视图,我用来生成文档点3的函数返回一个“docx.document.document”对象,Django视图的响应是一个“Django.http.response.HttpResponse”,如果我在javascript上设置了“console.logresponse”,我会收到“string”,在这里我不知道如何从模板中的按钮或直接从下载对话框下载docx文件。您是否验证了视图是否正确打开了文件?在JS的这一部分,我没有你那么多的经验,但是你好。当我使用行文档直接保存报告时,视图似乎工作正常。saver'C:\tests\new\u demo.docx'该文档是在该路径中生成的。我已经开始使用TKinter查看替代方案,同时继续查找javascript信息以显示“另存为”对话框,并将文件名和所选路由传递到视图,此选项起作用,但有时我会随机收到错误:RuntimeError:主线程不在主循环中
def ReporteWord( gcas, FI, FF, Chart):
    #Cargamos el template
    template = finders.find('otros/Template_reporte.docx')
    document = Document(template) 

    #Header
    logo = finders.find('otros/logo.png')
    header = document.sections[0].header
    paragraph = header.paragraphs[0]
    r = paragraph.add_run()
    r.add_picture(logo)

    #Adding title
    titulo = document.add_heading('', 0)
    titulo.add_run('Mi reporte').bold = True
    titulo.style.font.size=Pt(13)
    .
    Many other steps to add more content    
    .
    .
    #IF I SAVE THE FILE NORMALLY ALL WORKS FINE
    #document.save(r'C:\tests\new_demo.docx')

    return document
def Reporte(request):
    if request.method == "GET":
        context={}
        context['form'] = catForm
        return render(request, 'reportes/reporte_base.html', context)

    if request.method == 'POST':
        #Getting data needed after submit the form in the page
        GcasID = request.POST.get('GCASS')
        FI = request.POST.get('dp1')
        FF = request.POST.get('dp2')
        Grafica = request.POST.get('options')

        #Function to obtain complete code from GcasID 
        Gcas =  GcasNumber(GcasID)

        #Report creation
        Reporte = ReporteWord(Gcas, FI, FF, Grafica)

        #PART UPDATED TO SHOW DOWNLOAD REPORT DIALOG
        bio = io.BytesIO()
        Reporte.save(bio)  # save to memory stream
        bio.seek(0)  # rewind the stream
        response = HttpResponse(
        bio.getvalue(),  # use the stream's contents
        content_type="application/vnd.openxmlformats-officedocument.wordprocessingml.document",
    )

        response["Content-Disposition"] = 'attachment; filename = "Reporte.docx"'
        response["Content-Encoding"] = "UTF-8"
        return response
Reporte = ReporteWord(Gcas, FI, FF, grafica)
bio = io.BytesIO()
Reporte.save(bio)  # save to memory stream
bio.seek(0)  # rewind the stream
response = HttpResponse(
    bio.getvalue(),  # use the stream's contents
    content_type="application/vnd.openxmlformats-officedocument.wordprocessingml.document",
)
response["Content-Disposition"] = 'attachment; filename = "Reporte.docx"'
response["Content-Encoding"] = "UTF-8"
return response