Django : python pandas generating blank excel - django

I am using pandas tool to create downloadable excel file.Excel will get it data from SQL table , which in turn will get populated depending on values entered by user.I have attached one download button in my web page to download the excel.
On clicking download button it's generating a blank excel file with sheet name and file name as Consistency Report. Can anyone point out what I am doing wrong here.
Thanks in advance
views.py
def export_excel(request):
response = HttpResponse(content_type="application/vnd.ms-excel")
response['Content-Disposition'] = 'attachment; filename=Consistency Report.xls'
fname = 'Consistency Report.xls'
cnxn = pyodbc.connect('DRIVER={SQL Server Native Client 10.0};SERVER=******;DATABASE=testing;UID=***;PWD=******')
cursor = cnxn.cursor()
cursor.execute("select * from dhm_consis_report_tbl")
columns = [column[0] for column in cursor.description]
data=cursor.fetchall()
cursor.commit()
print(columns)
for i in range(0,len(data)):
data[i]=tuple(data[i])
df = ps.DataFrame(data=data,columns=columns)
writer = ps.ExcelWriter('Consistency Report.xls',engine='xlwt')
df.to_excel(writer,sheet_name='Report')
writer.save()
return response
So, I edited my views.py and am able to generate and download excel file but the problem is that the file is now downloading at two locations; one at my project folder and one at my download folder.Also the file at download folder is empty while the one at my project folder contains data.Can anybody explain why this is happening?
Modified views.py
def export_excel(request):
response = HttpResponse(content_type="application/vnd.ms-excel;charset=utf-8")
response['Content-Disposition'] = 'attachment; filename=Consistency Report.xls'
df = ps.DataFrame.from_records(DHM_Consis_Report.objects.values('conquery_source','conquery_name','conquery_count','conquery_desc','criticality','sp_status','con_rundate','instance_id'))
print(df)
writer = ps.ExcelWriter('Consistency Report.xls',encoding='utf-8')
df.to_excel(writer,sheet_name='Report')
writer.save()
return response

Finally, I was able to generate required excel.Earlier I was creating and writing the excel with data but my HttpResponse was not getting the required data.I put the logic regarding generating excel in separate function and logic regarding downloading the generated file in separate function.This is what I did.
I know it's crude and inefficient but this works for me.If anyone has better way to do this please share.
views.py
#login_required
def consisreports(request):
cust= customername
username=None
if request.user.is_authenticated():
username=request.user.username
print(username)
table=ConsisReport(DHM_Consis_Report.objects.all())
RequestConfig(request,paginate={"per_page": 25}).configure(table)
todays=date.today()
todays=todays.strftime("%d-%m-%y")
filename="Consistency Report %s as on %s %s.xls"%(cust,str(todays),username)
colname=['Customer','Query ','Count','Desc','Criticality','Status','Rundate','Instance ID']
df = ps.DataFrame.from_records(DHM_Consis_Report.objects.values('conquery_source','conquery_name','conquery_count','conquery_desc','criticality','sp_status','con_rundate','instance_id'))
df=df[['conquery_source','conquery_name','conquery_count','conquery_desc','criticality','sp_status','con_rundate','instance_id']]
print(df)
#df.save('C:/Users/P1097/Desktop')
writer = ps.ExcelWriter(filename)
df.to_excel(writer,sheet_name='Report',index=False,engine='xlsxwriter',header=colname)
writer.save()
return render(request, 'consistency/consresult.html', {'table': table,'customername':cust})
#login_required
def export_excel(request):
custname=customername
username=None
if request.user.is_authenticated():
username=request.user.username
todays=date.today()
todays=todays.strftime("%d-%m-%y")
filename="Consistency Report %s as on %s %s.xls"%(custname,str(todays),username)
wrapper=open(filename,"rb")
cont=wrapper.read()
response = HttpResponse(cont,content_type="application/vnd.ms-excel;charset=utf-8")
response['Content-Length']=os.path.getsize(filename)
size=os.path.getsize(filename)
print(size)
wrapper.close()
response['Content-Disposition'] = 'attachment; filename= %s'%filename
return response

Related

Django - Create and add multiple xml to zip, and download as attachment

I am learner, and trying to build code to in which user has option to download the zip file that contains multiple .xlm files, which are created on the bases of database.
I have been able to create below code to download single xml file. But struggling to get multiple files packed in zipped format(for each row of database).
import xml.etree.ElementTree as ET
def export_to_xml(request):
listings = mydatabase.objects.all()
root = ET.Element('listings')
for item in listings:
price = ET.Element('price')
price.text = str(item.Name)
offer = ET.Element('offer', attrib={'id': str(item.pk)})
offer.append(price)
root.append(offer)
tree = ET.ElementTree(root)
response = HttpResponse(ET.tostring(tree.getroot()), content_type='application/xhtml+xml')
response['Content-Disposition'] = 'attachment; filename="data.xml"'
return response
Hi Got the solution by using following approach
byteStream = io.BytesIO()
with zipfile.ZipFile(byteStream, mode='w',) as zf:
# your code
zf.writestr()
response = HttpResponse(byteStream.getvalue(), content_type='application/x-zip-compressed')
response['Content-Disposition'] = "attachment; filename=finename.zip"

Django output csv file, filename is not setting as the value of Content-Disposition

I want to download a csv file with custom filename in a django project, but somehow the downloaded filename just display as "download.csv" instead of using the value of filename in Content-Disposition. I also tried to print csv_response['Content-Disposition'] out, but I'm getting a very strange string =?utf-8?b?YXR0YWNobWVudDsgZmlsZW5hbWU9Iuivvueoi+aKpeWQjeaDheWGtV8yMDE5MTEyODA3NDI0Ny5jc3Yi?=
the code snippet is :
#action(detail=False, methods=['GET'])
def download(self, request):
registrations = self.filter_queryset(self.get_queryset())
csv_response = HttpResponse(content_type='text/csv')
csv_response['Content-Disposition'] = 'attachment; filename="some_custom_name_{time}.csv"'.format(
time=time.strftime("%Y%m%d%H%M%S", time.localtime())
)
writer = csv.writer(csv_response)
writer.writerow([
some content,
])
for registration in registrations:
term_title = '{order} th'.format(order=registration.term.order)
course_title = registration.course.title
writer.writerow([
registration.user.email,
course_title,
term_title,
str(registration.confirmation_code),
str(registration.payment_due),
str(registration.payment_paid),
str(registration.source),
str(registration.created_at),
str(registration.updated_at),
str(registration.payment_source),
])
return csv_response
the django I am using is 2.2
any ideas why this is happening? I am a newb.
Thx in advance
The response header in chrome Dev tools:
I resolved the problem, by following the answer in the below post:
HttpResponse Django does not change file name
I guess that it is that because the string of Content-Disposition needs to be encoded, and if no, then somehow cannot operate on that, by using urlquote, it is solved.
Explanation about urlquote is here
UPDATE:
Also, a simpler way to resolve this without importing urlquote is to add encode(), like below:
csv_response['Content-Disposition'] = 'attachment; filename="some_custom_name_{time}.csv"'.format(
time=time.strftime("%Y%m%d%H%M%S", time.localtime())
).encode()
Change to this:
csv_response['Content-Disposition'] = 'attachment; filename="some_custom_name_{}.csv"'.format(
time.strftime("%Y%m%d%H%M%S", time.localtime())
)

csv download doesn't occur without error in Django

I am implementing csv donwloand function referring to this page.
Even though I don't get any error message, cannot get csv file downloaded.
Does anyone know what is the problem for this implementation?
Below is the code to download csv file from database.
class timeCSVexport(View):
def get(self,request,pk,keyword):
key=keyword.replace("_"," ")
queryset=timeseries.objects.filter(html__pk=pk).filter(keyword=key)
bio = BytesIO()
data=json.loads(list(queryset)[0].df)
df=pd.DataFrame.from_dict(data,orient='index').T
df.index=pd.to_datetime(df.index)
df1=df.sort_index()
sheet=key[:31] if len(key)>31 else key
print (sheet)
writer=pd.ExcelWriter(bio,engine='xlsxwriter')
df1.to_excel(writer,sheet_name=sheet)
writer.save()
bio.seek(0)
workbook=bio.getvalue()
response = StreamingHttpResponse(workbook,content_type='application/vnd.openxmlformats-officedocument.spreadsheetml.sheet')
response['Content-Disposition'] = 'attachment; filename=%s' % pk
return response

Return Excel file from django view to html for downloading at client

I have a django app in which excel file is generated at server side and I want that to be downloaded at client.
I am sending​ request through Ajax call in JavaScript that goes to server generates excel which needs to be downloaded.
The view should generate http response that sends excel file to html that could be downloaded to a file at client
It's not as complicated as you may think. In fact, as I understand, you have a Django model and you need to export some instances' data in an .xlsx file for example.
I'd suggest the following simple solution:
import openpyxl
from openpyxl.utils import get_column_letter
from django.http.response import HttpResponse
def method(request, **kwargs):
queryset = ModelName.objects.filter() # adjust accordingly
response = HttpResponse(content_type='application/vnd.openxmlformats-officedocument.spreadsheetml.sheet')
response['Content-Disposition'] = 'attachment; filename=this-is-your-filename.xlsx'
wb = openpyxl.Workbook()
ws = wb.get_active_sheet()
ws.title = "Your Title"
row_num = 0
columns = [
("ID", 5),
(u'Name', 20),
]
for col_num in range(len(columns)):
c = ws.cell(row=row_num + 1, column=col_num + 1)
c.value = columns[col_num][0]
ws.column_dimensions[get_column_letter(col_num + 1)].width = columns[col_num][1]
for obj in queryset:
row_num += 1
row = [
obj.pk,
obj.name,
]
for col_num in range(len(row)):
c = ws.cell(row=row_num + 1, column=col_num + 1)
c.value = row[col_num]
wb.save(response)
return response
Please keep in mind that you need to install with pip install openpyxl the openpyxl lib first.
I had to complete this exact task and ended up using the following method. Instead of using an AJAX call, I just do
window.location.pathname = "/relative/path/to/url/"
within Javascript click handler for the button.
Within Django, I am using the following code (I am using XlsxWriter but you could use whatever you wish for creating XLSX file):
excel_file = BytesIO()
workbook = xlsxwriter.Workbook(excel_file)
# Code to populate the workbook
# Here comes the magic
workbook.close()
excel_file.seek(0)
response = HttpResponse(excel_file.read(),
content_type='application/vnd.openxmlformats-officedocument.spreadsheetml.sheet')
response['Content-Disposition'] = 'attachment; filename=somename.xlsx'
return response
When called this way, the created Excel file is downloaded and the user remains on the calling page, which is the exact behavior I wanted.

How to download data in a blob field from database in django?

I have a table in which I have a blob column containing some data, how can i download the blob content in django?
I tried the solution mentioned here but it didn't work for me
def download_blob(request, id):
contents = BlobModel.objects.get(id=id).blob_field
response = HttpResponse(contents)
response['Content-Disposition'] = 'attachment; filename=blob.bin'
return response