[英]How to download a document generated with python-docx in Django project?
我試圖弄清楚如何在我的 django 應用程序中下載使用 python-docx 生成的 word 文檔(我還在學習,這是我第一次使用文檔); 在 ajax 的幫助下,我將所需的所有信息發送到視圖並調用使用該信息並返回文檔的函數,然后我嘗試將此文檔作為響應發送,以便在“下載”的幫助下下載它" 按鈕(或顯示 Web 瀏覽器下載對話框)在我提交數據的同一模板中,但這是我卡住的地方。
將此文檔作為響應發送,以便在我提交數據的同一模板中的“下載”按鈕(或顯示 Web 瀏覽器下載對話框)的幫助下下載它,但這是我卡住的地方。
到目前為止,我所擁有的是:
1)在javascript中,我發送的信息如下:
data = { categoria: cat, familia: fam, Gcas: gcas, FI: FI, FF: FF, Test: test, Grafica: grafica }, $.ajax({ type: 'post', headers: { "X-CSRFToken": csrftoken }, url: url, data: { json_data: JSON.stringify(data) }, success: function (response) { $('#instrucciones').hide(); //Hide a div with a message $('#btndesc').show(); //Show the button to download the file generated } }); return false; }
2)在我的Django視圖中:
def Documento(request): if request.method == "GET": context={} context['form'] = catForm return render(request, 'report/report_base.html', context) if request.method == 'POST': #Data from ajax datos = request.POST.get('json_data') jsondata = json.loads(datos) Gcas = jsondata['Gcas'] FI = jsondata['FI'] FF = jsondata['FF'] grafica = jsondata['Grafica'] #Using function to create the report Reporte = ReporteWord(Gcas, FI, FF, grafica) #Response response = HttpResponse(content_type='application/vnd.openxmlformats- officedocument.wordprocessingml.document') response['Content-Disposition'] = 'attachment; filename = "Reporte.docx"' response['Content-Encoding'] = 'UTF-8' Reporte.save(response) return response
3)我創建文檔的功能如下:
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
我將非常感謝任何想法或建議,非常感謝提前。
注意:我沒有運氣就查看了這些答案(和其他答案)。
更新:感謝收到的反饋,我終於找到了如何生成文檔並顯示下載對話框:
正如建議的那樣,使用視圖而不是 ajax 來實現它的最佳方法,所以代碼中的最終更新是:
a) 更新視圖以在反饋中顯示
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
現在,當我按下“創建報告”(表單的提交按鈕)時,所有這些更改都按預期工作(因為不需要更多的庫)。 最后,正如您所建議的那樣,以這種方式比使用 ajax 更容易。
非常感謝大家的幫助。
Python-docx 的Document.save()
方法接受流而不是文件名。 因此,您可以初始化一個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
會更容易。
是的,正如 wardk 所說,更簡潔的選擇是使用https://python-docx.readthedocs.org/ :
from docx import Document
from django.http import HttpResponse
def download_docx(request):
document = Document()
document.add_heading('Document Title', 0)
response = HttpResponse(content_type='application/vnd.openxmlformats-officedocument.wordprocessingml.document')
response['Content-Disposition'] = 'attachment; filename=download.docx'
document.save(response)
return response
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.