i have implemented csv in my current Python Django project.
writer = csv.writer(open('custom_data/abc.csv', 'w+'))
print "abc"
headers = []
for i in data_desc:
headers.append((i[0].replace('_', ' ')).upper())
j = j+1
j=1
writer.writerow(headers)
"""
fill data into csv cells
"""
for value in data.fetchall():
k=0
no_record_check=1
row = []
for val in value:
row.append(val)
k = k+1
j=j+1
writer.writerow(row)
except:
print "Exception here after printing"
#pass
response = HttpResponse(mimetype='text/csv')
now = datetime.datetime.now().strftime('%m-%d-%Y_%H:%M:%S')
response['Content-Disposition'] = 'attachment; filename= custom_data/abc.csv'
code is working fine. and file with name abc.csv created successfully . but download option come with wrong name .
i have created file with name : abc.csv under custom_report and custom_report folder reside in my project folder. (e.g. projectname/custom_report/abc.csv). i found file under this location. ::
my project structure are:
projectname / app / app_name/ forms.py, views.py...
projetname / custom_report /abc.csv
** my issue issue :**
file come with new name custom_data_abc.csv. with blank data. while abc.csv file under the custom_report is availabe with correct data.
can you help me ?
Try this:
Sorry for the wrong reply .The tutorial says that:
response = HttpResponse(mimetype='text/csv')
response['Content-Disposition'] = 'attachment; filename=unruly.csv'
writer = csv.writer(response)
First create a response and then write the content
Related
I'm quite new on Django and i'm looking for a way to dwonload a zip file from my django site but i have some issue when i'm running this piece of code:
def download(self):
dirName = settings.DEBUG_FOLDER
name = 'test.zip'
with ZipFile(name, 'w') as zipObj:
# Iterate over all the files in directory
for folderName, subfolders, filenames in os.walk(dirName):
for filename in filenames:
# create complete filepath of file in directory
filePath = os.path.join(folderName, filename)
# Add file to zip
zipObj.write(filePath, basename(filePath))
path_to_file = 'http://' + sys.argv[-1] + '/' + name
resp= {}
# Grab ZIP file from in-memory, make response with correct MIME-type
resp = HttpResponse(content_type='application/zip')
# ..and correct content-disposition
resp['Content-Disposition'] = 'attachment; filename=%s' % smart_str(name)
resp['X-Sendfile'] = smart_str(path_to_file)
return resp
I get:
Exception Value:
<HttpResponse status_code=200, "application/zip"> is not JSON serializable
I tried to change the content_type to octet-stream but it doesn't work
And to use a wrapper as followw:
wrapper = FileWrapper(open('test.zip', 'rb'))
content_type = 'application/zip'
content_disposition = 'attachment; filename=name'
# Grab ZIP file from in-memory, make response with correct MIME-type
resp = HttpResponse(wrapper, content_type=content_type)
# ..and correct content-disposition
resp['Content-Disposition'] = content_disposition
I didn't find useful answer so far but maybe I didn't search well, so if it seems my problem had been already traited, feel free to notify me
Thank you very much for any help
You have to send the zip file as byte
response = HttpResponse(zipObj.read(), content_type="application/zip")
response['Content-Disposition'] = 'attachment; filename=%s' % smart_str(name)
return response
I would do like this:
(Caveat I use wsl so the python function will make use of cmd lines)
In view:
import os
def zipdownfun(request):
""" Please establish in settings.py where media file should be downloaded from.
In my case is media with a series of other folders inside. Media folder is at the same level of project root folder, where settings.py is"""
file_name = os.path.join(MEDIA_URL,'folder_where_your_file_is','file_name.zip')
"""let us put the case that you have zip folder in media folder"""
file_folder_path = os.path.join(MEDIA_URL,'saving_folder')
"""The command line takes as first variable the name of the
future zip file and as second variable the destination folder"""
cmd = f'zip {file_name} {file_folder_path}'
"""With os I open a process in the background so that some magic
happens"""
os.system(cmd)
"""I don't know what you want to do with this, but I placed the
URL of the file in a button for the download, so you will need
the string of the URL to place in href of an <a> element"""
return render(request,'your_html_file.html', {'url':file_name})
The db I have created, will be updated very often. I used a slightly different version of this function with -r clause since I had to zip, each time, a folder. Why I did this? The database I have created has to allow the download of this zipped folder. This folder will be updated daily. So this function basically overwrites the file each time that is downloaded. It will be so fresh of new data each time.
Please refer to this page to understand how to create a button for the download of the generated file.
Take as reference approach 2. The URL variable that you are passing to the Django template should be used at the place of the file (screenshot attached)
I hope it can help!
I created a function to create multiple PDFs with Weasyprint, zip them together and download the zip file. When trying to extract the folder on Windows 10 with the in-house zip program i get this error:
"An unexpected error is keeping you from copying the file. [...] Error 0x80070057" <
I can skip the error and the files get extracted. However in the best case scenario I'd like to prevent this error.
def get_all_shareholder_reports(request):
current_shareholders = list(models.objects.all())
zip_buffer = io.BytesIO()
with zipfile.ZipFile(zip_buffer, "a") as zip_file:
for shareholder in current_shareholders:
pdf_file_handle = io.BytesIO()
context_dict = get_report_details(pk=shareholder.shareholder_id)
html_string = render_to_string('template.html',
context_dict)
html_handler = HTML(string=html_string, base_url=request.build_absolute_uri())
html_handler.write_pdf(target=pdf_file_handle)
pdf_file_handle.seek(0)
pdf_string = pdf_file_handle.getvalue()
pdf_file_name ='Shareholder_Report_{}_{}_{}.pdf'.format(context_dict['shareholder'].forename,
context_dict['shareholder'].surname,
datetime.datetime.now().strftime(
"%d_%m_%Y_%H:%M:%S"))
zip_file.writestr(zinfo_or_arcname=pdf_file_name, data=pdf_string)
zip_buffer.seek(0)
response = HttpResponse(zip_buffer.getvalue(), content_type="application/x-zip-compressed")
response['Content-Disposition'] = 'attachment; filename=%s' % 'myzip.zip'
return response
I figured it out: The zip file didn't like the ":" in the filename. Removing them fixed the issue.
pdf_file_name ='Shareholder_Report_{}_{}_{}.pdf'.format(context_dict['shareholder'].forename,
context_dict['shareholder'].surname,
datetime.datetime.now().strftime(
"%d_%m_%Y_%H_%M_%S"))
You basically need to clean the filename for all reserved characters in Windows: https://learn.microsoft.com/en-us/windows/win32/fileio/naming-a-file#naming-conventions
So the following should do it "filename".replaceAll("[<>:\"/\\\\|?*]", "")
I am trying to save some .csv files into folder using Python and Django but it's throwing the below error.
Error:
Exception Type: NameError
Exception Value:
global name 'filename' is not defined
I am providing my code below.
report = Reactor.objects.all()
response = HttpResponse(content_type='text/csv')
response['Content-Disposition'] = 'attachment; filename='+str(uuid.uuid4())+'.csv'
writer = csv.writer(response)
writer.writerow(['Name', 'Status', 'Date'])
for rec in report:
if rec.status == 1:
status = 'Start'
if rec.status == 0:
status = 'Stop'
if rec.status == 2:
status = 'Suspend'
writer.writerow([rec.rname, status, rec.date])
open(settings.FILE_PATH+filename,'w')
return response
settings.py:
FILE_PATH = os.path.join(BASE_DIR, '/upload/')
Here I wring the DB value into .CSV file and downloading it. In the same time I need to save that downloaded file into upload folder but getting those error.
It's exactly what the error is telling you. You haven't defined filename anywhere, but are calling it in open(settings.FILE_PATH+filename,'w')
Try:
filename = str(uuid.uuid4()) + '.csv'
response['Content-Disposition'] = 'attachment; filename=' + filename
Related, but not the problem that you're seeing, what's the point of opening the file for writing, but never writing anything to it?
I'm trying create and serve excel files using Django. I have a jar file which gets parameters and produces an excel file according to parameters and it works with no problem. But when i'm trying to get the produced file and serve it to the user for download the file comes out broken. It has 0kb size. This is the code piece I'm using for excel generation and serving.
def generateExcel(request,id):
if os.path.exists('./%s_Report.xlsx' % id):
excel = open("%s_Report.xlsx" % id, "r")
output = StringIO.StringIO(excel.read())
out_content = output.getvalue()
output.close()
response = HttpResponse(out_content,content_type='application/vnd.openxmlformats-officedocument.spreadsheetml.sheet')
response['Content-Disposition'] = 'attachment; filename=%s_Report.xlsx' % id
return response
else:
args = ['ServerExcel.jar', id]
result = jarWrapper(*args) # this creates the excel file with no problem
if result:
excel = open("%s_Report.xlsx" % id, "r")
output = StringIO.StringIO(excel.read())
out_content = output.getvalue()
output.close()
response = HttpResponse(out_content,content_type='application/vnd.openxmlformats-officedocument.spreadsheetml.sheet')
response['Content-Disposition'] = 'attachment; filename=%s_Report.xlsx' % id
return response
else:
return HttpResponse(json.dumps({"no":"excel","no one": "cries"}))
I have searched for possible solutions and tried to use File Wrapper also but the result did not changed. I assume i have problem with reading the xlsx file into StringIO object. But dont have any idea about how to fix it
Why on earth are you passing your file's content to a StringIO just to assign StringIO.get_value() to a local variable ? What's wrong with assigning file.read() to your variable directly ?
def generateExcel(request,id):
path = './%s_Report.xlsx' % id # this should live elsewhere, definitely
if os.path.exists(path):
with open(path, "r") as excel:
data = excel.read()
response = HttpResponse(data,content_type='application/vnd.openxmlformats-officedocument.spreadsheetml.sheet')
response['Content-Disposition'] = 'attachment; filename=%s_Report.xlsx' % id
return response
else:
# quite some duplication to fix down there
Now you may want to check weither you actually had any content in your file - the fact that the file exists doesn't mean it has anything in it. Remember that you're in a concurrent context, you can have one thread or process trying to read the file while another (=>another request) is trying to write it.
In addition to what Bruno says, you probably need to open the file in binary mode:
excel = open("%s_Report.xlsx" % id, "rb")
You can use this library to create excel sheets on the fly.
http://xlsxwriter.readthedocs.io/
For more information see this page. Thanks to #alexcxe
XlsxWriter object save as http response to create download in Django
my answer is:
def generateExcel(request,id):
if os.path.exists('./%s_Report.xlsx' % id):
with open('./%s_Report.xlsx' % id, "rb") as file:
response = HttpResponse(file.read(),content_type='application/vnd.openxmlformats-officedocument.spreadsheetml.sheet')
response['Content-Disposition'] = 'attachment; filename=%s_Report.xlsx' % id
return response
else:
# quite some duplication to fix down there
why using "rb"? because HttpResponse class init parameters is (self, content=b'', *args, **kwargs), so we should using "rb" and using .read() to get the bytes.
I have a view that takes data from my site and then makes it into a zip compressed csv file. Here is my working code sans zip:
def backup_to_csv(request):
response = HttpResponse(mimetype='text/csv')
response['Content-Disposition'] = 'attachment; filename=backup.csv'
writer = csv.writer(response, dialect='excel')
#code for writing csv file go here...
return response
and it works great. Now I want that file to be compressed before it gets sent out. This is where I get stuck.
def backup_to_csv(request):
output = StringIO.StringIO() ## temp output file
writer = csv.writer(output, dialect='excel')
#code for writing csv file go here...
response = HttpResponse(mimetype='application/zip')
response['Content-Disposition'] = 'attachment; filename=backup.csv.zip'
z = zipfile.ZipFile(response,'w') ## write zip to response
z.writestr("filename.csv", output) ## write csv file to zip
return response
But thats not it and I have no idea how to do this.
OK I got it. Here is my new function:
def backup_to_csv(request):
output = StringIO.StringIO() ## temp output file
writer = csv.writer(output, dialect='excel')
#code for writing csv file go here...
response = HttpResponse(mimetype='application/zip')
response['Content-Disposition'] = 'attachment; filename=backup.csv.zip'
z = zipfile.ZipFile(response,'w') ## write zip to response
z.writestr("filename.csv", output.getvalue()) ## write csv file to zip
return response
Note how, in the working case, you return response... and in the NON-working case you return z, which is NOT an HttpResponse of course (while it should be!).
So: use your csv_writer NOT on response but on a temporary file; zip the temporary file; and write THAT zipped bytestream into the response!
zipfile.ZipFile(response,'w')
doesn't seem to work in python 2.7.9. The response is a django.HttpResponse object (which is said to be file-like) but it gives an error "HttpResponse object does not have an attribute 'seek'. When the same code is run in python 2.7.0 or 2.7.6 (I haven't tested it in other versions) it is OK... So you'd better test it with python 2.7.9 and see if you get the same behaviour.