I want to be able to convert some Django model to a Excel file. My view is as follows:
#login_required
def archive_to_excel(request):
calculations_list = Calculations.objects.filter(user=request.user) \
.values_list('make', 'model', 'first_registration', 'body', 'facelift',
'engine', 'transmission', 'purchase_price', 'mileage',
'customer__firstname', 'customer__lastname', 'customer__email') \
.order_by('-id')
columns = [_('Make'), _('Model'), _('First registration'), _('Body'), _('Facelift'), _('Engine'), _('Transmission'),
_('Price'), _('Mileage'), _('Customer first name'), _('Customer last name'), _('Customer email')]
return convert_to_excel("archive", columns, calculations_list)
And convert_to_excel function is as follows:
def convert_to_excel(file_name, columns, values):
response = HttpResponse(content_type='application/ms-excel')
response['Content-Disposition'] = 'attachment; filename="{}.xls"'.format(file_name)
wb = xlwt.Workbook(encoding='utf-8')
ws = wb.add_sheet(file_name.capitalize())
# Sheet header, first row
row_num = 0
font_style = xlwt.XFStyle()
font_style.font.bold = True
for col_num in range(len(columns)):
ws.write(row_num, col_num, columns[col_num], font_style)
# Sheet body, remaining rows
font_style = xlwt.XFStyle()
for row in values:
row_num += 1
for col_num in range(len(row)):
ws.write(row_num, col_num, row[col_num], font_style)
wb.save(response)
return response
That works fine, but the problem that I have is that the purchase_price in Calculations model is stored EXCL VAT and I want to show it in the excel file INCL VAT.
How can I multiply the purchase_price with 1.21 and show it in the excel file?
Any advice?
You can for instance do this:
calculations_list = Calculations.objects.filter(user=request.user) \
.values_list('make', 'model', 'first_registration', 'body', 'facelift',
'engine', 'transmission', 'mileage',
'customer__firstname', 'customer__lastname', 'customer__email') \
.annotate(purchase_price=F('purchase_price')*1.21)
.order_by('-id')
Related
When all set foreign key (sku_id) it's working fine if null foreign key it's showing error
object has no attribute
How to print 'none' instead of error in CSV columns
def seller_report(request):
loginned_user = request.user
if request.method=="POST":
from_date = request.POST.get('from_date')
to_date = request.POST.get('to_date')
new_from = datetime.datetime.strptime(from_date, '%Y-%m-%d').date()
new_to = datetime.datetime.strptime(to_date, '%Y-%m-%d').date()
min_dt = datetime.datetime.combine(new_from, datetime.time.min)
max_dt = datetime.datetime.combine(new_to, datetime.time.max)
space = ' '
to = 'to'
download_name = space + from_date + space + to + space + to_date
daily_en = All_enquiries.objects.filter(enquired_at__range = (min_dt, max_dt))
response = HttpResponse(content_type='text/csv')
response['Content-Disposition'] = 'attachment; filename="Report{}.csv"'.format(download_name)
writer = csv.writer(response, delimiter=',')
writer.writerow(['created_at','product_name','product_category','price','seller_name','seller_mobile','seller state','seller city','seller pincode', 'seller type','customer_name','customer_mobile','state','district','city','pincode','status','remarks','source','username'])
for obj in daily_en:
if obj.sku_id is None:
obj.sku_id is 'None'
writer.writerow([obj.enquired_at,obj.product_name,obj.product_category,obj.price,obj.sku_id.seller_id.seller_name, obj.sku_id.seller_id.mobile_number,obj.sku_id.seller_id.state,obj.sku_id.seller_id.city,obj.sku_id.seller_id.pincode,obj.sku_id.seller_id.get_seller_type_display(), obj.customer_name,obj.customer_mobile,obj.state,obj.district,obj.city,obj.pincode,obj.status,obj.remarks,obj.get_source_display(),obj.user_id])
return response
return render (request,'enquiries/admin/report.html')
You should be able to use values_list to select all the values from the DB while getting None for relationships that cannot be traversed
for row in daily_en.values_list(
'enquired_at',
'product_name',
'product_category',
'price',
'sku_id__seller_id__seller_name',
'sku_id__seller_id__mobile_number',
'sku_id__seller_id__state',
'sku_id__seller_id__city',
'sku_id__seller_id__pincode',
'sku_id__seller_id__seller_type',
'customer_name',
'customer_mobile',
'state',
'district',
'city',
'pincode',
'status',
'remarks',
'source',
'user_id'
):
writer.writerow(row)
I need help with exporting data using a template. I installed django-import-export and added it to admin panel, now I can only export data from the admin panel. I want to know how can i export excel file using template.
This should get you started:
import StringIO
import xlsxwriter
from django.http import HttpResponse
def export_page(request):
# create our spreadsheet. I will create it in memory with a StringIO
output = StringIO.StringIO()
workbook = xlsxwriter.Workbook(output)
worksheet = workbook.add_worksheet()
worksheet.write('A1', 'Some Data')
workbook.close()
# create a response
response = HttpResponse(content_type='application/vnd.ms-excel')
# tell the browser what the file is named
response['Content-Disposition'] = 'attachment;filename="some_file_name.xlsx"'
# put the spreadsheet data into the response
response.write(output.getvalue())
# return the response
return response
I tried the same with newer version of Django and after trial and error found this worked.
import io
import xlsxwriter
def excelreport(request):
buffer = io.BytesIO()
workbook = xlsxwriter.Workbook(buffer)
worksheet = workbook.add_worksheet()
worksheet.write('A1', 'Some Data')
workbook.close()
buffer.seek(0)
return FileResponse(buffer, as_attachment=True, filename='report.xlsx')
You can alos use xlwt if you really need to export to a .xls file. You will be able to add formating as bold font, font size, define column size, etc.
$ pip install xlwt
import xlwt
from django.http import HttpResponse
from django.contrib.auth.models import User
def export_users_xls(request):
response = HttpResponse(content_type='application/ms-excel')
response['Content-Disposition'] = 'attachment; filename="users.xls"'
wb = xlwt.Workbook(encoding='utf-8')
ws = wb.add_sheet('Users')
# Sheet header, first row
row_num = 0
font_style = xlwt.XFStyle()
font_style.font.bold = True
columns = ['Username', 'First name', 'Last name', 'Email address', ]
for col_num in range(len(columns)):
ws.write(row_num, col_num, columns[col_num], font_style)
# Sheet body, remaining rows
font_style = xlwt.XFStyle()
rows = User.objects.all().values_list('username', 'first_name', 'last_name', 'email')
for row in rows:
row_num += 1
for col_num in range(len(row)):
ws.write(row_num, col_num, row[col_num], font_style)
wb.save(response)
return response
If you are using pandas, this is probably the easiest and most concise way:
import pandas as pd
from django.http import HttpResponse
def export_excel_file(request):
df = pd.read_excel("excel_filename.xlsx")
response = HttpResponse(content_type='application/vnd.ms-excel')
response['Content-Disposition'] = f'attachment; filename=excel_filename.xlsx'
df.to_excel(response, index=False)
return response
Am exporting data to excel using xlwt but the problem that am getting user id in the row user instead of username, how to fix this,, here is the view
def export_buy_and_sell_report_csv(request):
today_date = date.today()
response = HttpResponse(content_type='application/ms-excel')
response['Content-Disposition'] = 'attachment; filename="BuyAndSellReports_' + str(today_date) + '.xls"'
wb = xlwt.Workbook(encoding='utf-8')
ws = wb.add_sheet('BuyAndSells')
# Sheet header, first row
row_num = 0
font_style = xlwt.XFStyle()
font_style.font.bold = True
columns = ['المستخدم', ' القيمة', 'البيان', 'الفئة', 'نوع الحركة', 'التاريخ']
for col_num in range(len(columns)):
ws.write(row_num, col_num, columns[col_num], font_style)
# Sheet body, remaining rows
font_style = xlwt.XFStyle()
rows = models.BuyAndSellReport.objects.all().values_list('user', 'amount', 'text', 'move_category', 'move_type',
'date')
rows = [[x.strftime("%Y-%m-%d %H:%M") if isinstance(x, datetime.datetime) else x for x in row] for row in
rows]
for row in rows:
row_num += 1
for col_num in range(len(row)):
ws.write(row_num, col_num, row[col_num], font_style)
wb.save(response)
return response
You probably want to access a specific property of user instead of using a foreign key in values_list.
Try constructing your query like this:
rows = models.BuyAndSellReport.objects.all().values_list('user__username', 'amount', 'text', 'move_category', 'move_type',
'date')
I am using xlwt library to export data in excel format. When i am adding company_created in value_list of my queryset i am getting error -
TypeError at /company/csv/
can't subtract offset-naive andoffset-aware datetimes
company_created is a DateField in Model.
import xlwt
from django.http import HttpResponse
from django.contrib.auth.models import User
def GenerateCompanyCSV(request):
response = HttpResponse(content_type='application/ms-excel')
response['Content-Disposition'] = 'attachment; filename="users.xls"'
wb = xlwt.Workbook(encoding='utf-8')
ws = wb.add_sheet('Users')
# Sheet header, first row
row_num = 0
font_style = xlwt.XFStyle()
font_style.font.bold = True
columns = ['Company Name', 'Company Email', 'Count of people','Created Date', 'Current Monthly Payment', 'Is TABopts Customer', 'Status', ]
for col_num in range(len(columns)):
ws.write(row_num, col_num, columns[col_num], font_style)
# Sheet body, remaining rows
font_style = xlwt.XFStyle()
rows = Company.objects.exclude(id=1).exclude(
company_is_deleted=True
).annotate(
number_of_company_users=Count('userprofile')
).values_list(
'company_name',
'company_email',
'number_of_company_users',
'company_created',
'company_monthly_payment',
'company_tab_opts',
'company_status',
)
for row in rows:
row_num += 1
for col_num in range(len(row)):
ws.write(row_num, col_num, row[col_num], font_style)
wb.save(response)
return response
I found a hack and this is my solution: Change the for loop if you have date field.
date_format = xlwt.XFStyle()
date_format.num_format_str = 'dd/mm/yyyy'
for row in rows:
row_num += 1
print('row_num', row_num)
for col_num in range(len(row)):
if isinstance(row[col_num], datetime.date):
ws.write(row_num, col_num, row[col_num].replace(tzinfo=None), font_style)
else:
ws.write(row_num, col_num, row[col_num], font_style)
How to write not field name but verbose name of field (in column title) in this code (Export to xls) ?
def export_as_xls(modeladmin, request, queryset):
if not request.user.is_staff:
raise PermissionDenied
opts = modeladmin.model._meta
wb = Workbook()
ws0 = wb.add_sheet('0')
col = 0
field_names = []
# write header row
for field in opts.fields:
ws0.write(0, col, field.name)
field_names.append(field.name)
col = col + 1
row = 1
# Write data rows
for obj in queryset:
col = 0
for field in field_names:
val = unicode(getattr(obj, field)).strip()
ws0.write(row, col, val)
col = col + 1
row = row + 1
f = StringIO()
wb.save(f)
f.seek(0)
response = HttpResponse(f.read(), mimetype='application/ms-excel')
response['Content-Disposition'] = 'attachment; filename=%s.xls' % unicode(opts).replace('.', '_')
return response
export_as_xls.short_description = "Export selected objects to XLS"
I see field.name but I don't know how to change it. This code is from django snippet site
I may be misinterpreting the question, but if you want to change field.name:
for field in opts.fields:
field.name = 'Foo'
This would change all the field names to "Foo"