如何使用Python将xlsx文件下载至用户下载文件夹
问题描述
使用Python的xlsxwriter库编写了生成并下载xlsx文件的代码,点击触发后文件可生成,但并未保存到用户的下载文件夹,而是保存在项目代码所在目录。尝试用pathlib库获取下载文件夹路径,但未生效。
相关代码
views.py
def downloadFuelXlsx(request): downloads_path = str(Path.home() / "Downloads") print(downloads_path) workbook = xlsxwriter.Workbook("Fuel.xlsx") print(workbook) worksheet = workbook.add_worksheet() """ Add a format for the header cells. """ header_format = workbook.add_format( { "border": 1, "bg_color": "#C6EFCE", "bold": True, "text_wrap": True, "valign": "vcenter", "indent": 1, } ) """ Create Excel""" #Create Heading and apply formatting heading1 = "Name" heading2 = "Fuel Type" heading3 = "Cost" worksheet.write("A1", heading1, header_format) worksheet.write("B1", heading2, header_format) worksheet.write("C1", heading3, header_format) length = 20 #Set the number as per number of rows required. This will give you 20 rows in data #The list inside source should dynamically come from Database for r in range(1, length, 1): worksheet.data_validation('B'+str(r+1), {'validate': 'list', 'source': ['Petrol', 'Diesel', 'BioFuel'], }) workbook.close() return workbook
urls.py
urlpatterns = [ path('download_fuel_xlsx', views.downloadFuelXlsx, name='download_fuel_xlsx'), ]
HTML点击下载代码
<div class="col-lg-4 text-right"> <i class="fa fa-check" style="font-size:25px;color:green;cursor: pointer;"> <a target="_blank" href="{% url 'shouldcost:download_fuel_xlsx' %}"></a></i> </div>
解决方案
你的代码存在两个核心问题:
- 目前是在服务器端生成文件并保存到项目目录,没有通过HTTP响应把文件传递给用户浏览器,自然不会触发用户本地的下载行为。直接返回
workbook对象也不符合Django视图的要求,视图必须返回HttpResponse或其子类。 - 无需在服务器端获取下载文件夹路径(那是服务器的下载目录,不是用户本地的),正确的做法是生成文件后,通过响应让浏览器触发下载,由用户的浏览器决定保存到本地的下载文件夹。
推荐方案:内存生成文件并返回(无需服务器存储)
使用BytesIO在内存中生成Excel文件,直接通过HttpResponse返回给用户:
from django.http import HttpResponse from io import BytesIO from pathlib import Path import xlsxwriter def downloadFuelXlsx(request): # 用BytesIO在内存中创建文件对象 output = BytesIO() workbook = xlsxwriter.Workbook(output) worksheet = workbook.add_worksheet() # 表头格式设置 header_format = workbook.add_format( { "border": 1, "bg_color": "#C6EFCE", "bold": True, "text_wrap": True, "valign": "vcenter", "indent": 1, } ) # 写入表头 headings = ["Name", "Fuel Type", "Cost"] for col, heading in enumerate(headings): worksheet.write(0, col, heading, header_format) length = 20 for r in range(1, length): worksheet.data_validation(f'B{r+1}', { 'validate': 'list', 'source': ['Petrol', 'Diesel', 'BioFuel'], }) # 关闭工作簿,确保内容写入BytesIO workbook.close() # 将文件指针移到开头 output.seek(0) # 构造HTTP响应,触发下载 response = HttpResponse( output, content_type='application/vnd.openxmlformats-officedocument.spreadsheetml.sheet' ) response['Content-Disposition'] = 'attachment; filename="Fuel.xlsx"' return response
可选方案:保存到服务器后提供下载(不推荐,会占用服务器存储)
如果一定要先把文件保存到服务器的下载目录,再让用户下载:
from django.http import FileResponse from pathlib import Path import xlsxwriter import os def downloadFuelXlsx(request): downloads_path = Path.home() / "Downloads" file_path = downloads_path / "Fuel.xlsx" # 生成文件到服务器指定路径 workbook = xlsxwriter.Workbook(file_path) # ... 后续的表头、数据验证代码和之前一致 ... workbook.close() # 构造文件响应 response = FileResponse(open(file_path, 'rb')) response['Content-Disposition'] = 'attachment; filename="Fuel.xlsx"' return response
HTML代码修正
原HTML中a标签在i标签内部且没有内容,点击区域可能失效,调整为a包裹i:
<div class="col-lg-4 text-right"> <a target="_blank" href="{% url 'shouldcost:download_fuel_xlsx' %}"> <i class="fa fa-check" style="font-size:25px;color:green;cursor: pointer;"></i> </a> </div>
内容的提问来源于stack exchange,提问作者Namita Tare
相关产品推荐
相关产品推荐

