Python/Django 下載Excel2007
一、前提
上一篇,我寫了下載Excel2003的博文,這裏寫下載Excel2007的博文的原因有三:
第一、Excel2003基本已經淘汰了
第二、Excel2003下載文件太大,不利於網絡傳輸
第三、xlwt這個庫有個Bug,就是它不支持單元格字符串長度超過32767【這裏,有興趣的同學可以查看下源碼】
好了,廢話不多說了,我們進入正題。
二、安裝
本文使用的是pandas,引入庫的方式:pip install pandas
三、使用
首先、引入該庫,例如:import pandas
其次、
創建Excel文檔:
out = BytesIO()
excel = pandas.ExcelWriter(out, engine = ‘xlsxwriter‘) 這裏使用xlsxwriter引擎創建, 創建的文件直接關聯到輸出流out,安裝xlsxwriter也很簡單,如: pip install xlsxwriter
創建Sheet:
summary_df = pandas.DataFrame({}) 這裏使用空對象創建,下面代碼生成的sheet會是一個空sheet
summary_df.to_excel(excel, sheet_name = "Summary", index = False, header = False)
獲取sheet:worksheet = excel.sheets["Summary"] 獲取sheet名稱為summary的sheet名
設置列寬:worksheet.set_column(‘D:D‘, 18, long_text_format) 設置第四列寬度為18,使用樣式long_text_format【這個樣式需要自己提前定義】
保存Excel:excel.save()
Excel文件會直接輸出上面創建的輸出流out。
第四、輸出
response = HttpResponse(out.getvalue(), content_type = ‘application/vnd.ms-excel‘) dt = datetime.datetime.now() response[‘Content-Disposition‘] = ‘attachment;filename={} {}.xlsx‘.format(urlquote(domain_name), dt.strftime(‘%Y-%m-%d %H-%M-%S‘)) print("End downloading...") return response
貼下源碼:
def download_report(request, task_id, domain_name = ‘全部‘): print("start downloading xlsx...", task_id) print("start downloading...", domain_name) domains = [{‘domain_name‘: domain_name}] ai_task = AITask.objects.get(id = task_id) if domain_name == ‘全部‘: if 1 == ai_task.type: domains = Classification.objects.values(‘domain_name‘).distinct().filter(type = 1).order_by("domain_name") elif 2 == ai_task.type: domains = Classification.objects.values(‘domain_name‘).distinct().filter(type = 2).order_by("domain_name") out = BytesIO() excel = pandas.ExcelWriter(out, engine = ‘xlsxwriter‘) summary_title = [‘Domain‘, ‘Pass‘, ‘Fail‘] summary_dict = {title: [] for title in summary_title} domain_title = [‘Domain‘, ‘One level‘, ‘Two level‘, ‘Semantic‘, ‘Priority‘, ‘Intent group‘, ‘Intent‘, ‘Result‘, ‘Handle time‘, ‘Response time‘, ‘Server Domain‘, ‘Detail‘] summary_df = pandas.DataFrame({}) summary_df.to_excel(excel, sheet_name = "Summary", index = False, header = False) workbook = excel.book body_format = workbook.add_format(style.body_style) header_format = workbook.add_format(style.head_style) long_text_format = workbook.add_format(style.long_text_style) large_text_format = workbook.add_format(style.large_text_style) sheet_data = {} for domain in domains: dmain_name = domain["domain_name"] sheet_data[dmain_name] = {column_name: [] for column_name in domain_title} reports = ai_task.report.filter(semantic__classification__domain_name__exact = dmain_name) if len(reports): pass_no = fail_no = 0 for report in reports: semantic = report.semantic classification = semantic.classification sheet_data[dmain_name][domain_title[0]].append(classification.domain_name) sheet_data[dmain_name][domain_title[1]].append(classification.first_classification) sheet_data[dmain_name][domain_title[2]].append(classification.second_classification) sheet_data[dmain_name][domain_title[3]].append(semantic.name) sheet_data[dmain_name][domain_title[4]].append(classification.semantic_property) sheet_data[dmain_name][domain_title[5]].append(classification.intent_group) sheet_data[dmain_name][domain_title[6]].append(classification.intent) sheet_data[dmain_name][domain_title[7]].append(report.result) sheet_data[dmain_name][domain_title[8]].append(report.in_handle_time) sheet_data[dmain_name][domain_title[9]].append(report.ex_handle_time) sheet_data[dmain_name][domain_title[10]].append(report.server_domain) sheet_data[dmain_name][domain_title[11]].append(report.description) if "pass" == report.result: pass_no += 1 elif "fail" == report.result: fail_no += 1 sheet_df = pandas.DataFrame(sheet_data[dmain_name]) sheet_df.to_excel(excel, sheet_name = dmain_name, index = False, header = False, startrow = 1) worksheet = excel.sheets[dmain_name] worksheet.set_column(‘A:C‘, None, body_format) worksheet.set_column(‘D:D‘, 18, long_text_format) worksheet.set_column(‘E:E‘, None, body_format) worksheet.set_column(‘F:G‘, 30, long_text_format) worksheet.set_column(‘H:H‘, None, body_format) worksheet.set_column(‘I:K‘, None, body_format) worksheet.set_column(‘L:L‘, 50, large_text_format) for col, title in enumerate(sheet_df.columns.values): worksheet.write(0, col, title, header_format) sheet_data.clear() #回收內存 summary_dict[summary_title[0]].append(dmain_name) summary_dict[summary_title[1]].append(pass_no) summary_dict[summary_title[2]].append(fail_no) summary_df = pandas.DataFrame(summary_dict) summary_df.to_excel(excel, sheet_name = ‘Summary‘, index = False, header = False, startrow = 1) worksheet = excel.sheets[‘Summary‘] for col, title in enumerate(summary_df.columns.values): worksheet.write(0, col, title, header_format) for row in range(len(summary_dict[title])): worksheet.write(row + 1, col, summary_dict[title][row], body_format) excel.save() response = HttpResponse(out.getvalue(), content_type = ‘application/vnd.ms-excel‘) dt = datetime.datetime.now() response[‘Content-Disposition‘] = ‘attachment;filename={} {}.xlsx‘.format(urlquote(domain_name), dt.strftime(‘%Y-%m-%d %H-%M-%S‘)) print("End downloading...") return response
Python/Django 下載Excel2007