05】基於 "xlsxwriter + BytesIO"(Python3)生成 Excel 報表 ||| Python2 StringIO.StringIO()
阿新 • • 發佈:2018-12-16
Django Series(Django2.1.2 + Anaconda3)
說明:本系列教程根據最近實踐過程進行整理、總結和分享。由於時間和精力有限,發表時內容分析部分可能不是很完整,後續有時間會慢慢補充。同時!!也希望感興趣的同學可以提出一些細節問題和建議,我會根據這些問題進一步整理和完善哈。
更新日誌:
20181019:發表第一版,主要以程式碼分享為主;知識點分析較為粗略。
知識點分析:
實現程式碼:
Python3 + Django2.1.2
views.py
## 匯出excel報表 @csrf_exempt def Cur_ProjectsReport(request): try: import xlsxwriter output = BytesIO() workbook = xlsxwriter.Workbook(output) target_sheet1 = workbook.add_worksheet(u"XXXX現有專案情況") target_sheet1.merge_range(0, 0, 0, 0+10, u"XXXX現有專案情況報表") ## title target_sheet1.write(1, 0, u"工作令號") target_sheet1.write(1, 1, u"專案名稱") target_sheet1.write(1, 2, u"是否結項") target_sheet1.write(1, 3, u"合同日期") target_sheet1.write(1, 4, u"合同金額") ## table projects_list = Cur_Projects.objects.all() i = 2 for project in projects_list: target_sheet1.write(i, 0, u"{}".format(project.proj_id)) target_sheet1.write(i, 1, u"{}".format(project.proj_name)) target_sheet1.write(i, 2, u"{}".format(project.progress)) target_sheet1.write(i, 3, u"{}".format(project.contract_date.strftime("%Y%m%d"))) target_sheet1.write(i, 4, u"{}".format(project.contract_cost)) i += 1 date_day = datetime.datetime.now().strftime('%Y%m%d') file_name = "ProjectReport{}_{}.xlsx".format(date_day, request.session.get("UserName")) workbook.close() xlsx_data = output.getvalue() response = HttpResponse(content_type='application/ms-excel') response['Content-Disposition'] = 'attachment; filename=%s' % file_name response.write(xlsx_data) hcq_write(request.session.get('log_file_path'), True, True, "[{}({})]【成功】匯出現有專案報表:{}".format( request.session.get('UserName'), request.session.get('RoleTypeID'), file_name)) return response except Exception as e: hcq_write(request.session.get('log_file_path'), True, True, "[{}({})]【異常】匯出現有專案報表:{}".format( request.session.get('UserName'), request.session.get('RoleTypeID'), e)) response = HttpResponse() response.write("failure") return response
xxx.html
<a class="btn btn-default" type="button" href="{% url 'app_ManageSystem:Cur_ProjectsReport' %}">生成報表</a>
Python2 + Django1.6.11
Python2 直接 imort StringIO 模組,呼叫 StringIO.StringIO()。但 Python3 已經對 StringIO 模型進行修改,如下方法在Python2能夠成功匯出excel報表,但在Python3環境下會報錯。
## 專案出貨:匯出excel報表 @csrf_exempt def ProjectSaleReport(request, proj_id): import xlwt import StringIO print("proj_id = {}".format(proj_id)) try: ## 獲取內容 if Proj_info.objects.filter(proj_id = proj_id).exists(): proj_name = Proj_info.objects.get(proj_id = proj_id).proj_name else: proj_name = "沒有獲取到專案名稱" ProjectSale_list = ProjectSale_info.objects.filter(proj_id = proj_id).order_by("-sale_goods_type") date_day = datetime.datetime.now().strftime('%Y%m%d') ## 寫入 excel ws = xlwt.Workbook(encoding='utf-8') target_sheet = ws.add_sheet(u"{}專案出貨報表".format(proj_name)) ''' - 合併單元格 write_merge(x, x + h, y, w + y, string, sytle) x表示行,y表示列,w表示跨列個數,h表示跨行個數,string表示要寫入的單元格內容,style表示單元格樣式 注意,x,y,w,h,都是以0開始計算的 ''' target_sheet.write_merge(0, 0, 0, 0+4, u"工程名稱:{}".format(proj_name)) target_sheet.write_merge(0, 0, 7, 7+2, u"出貨編號:{}".format(proj_id)) target_sheet.write_merge(1, 1+0, 7, 7+2, u"匯出日期:{}".format(date_day)) ## title target_sheet.write(2, 0, u"序號") target_sheet.write(2, 1, u"收費專案") target_sheet.write(2, 2, u"品名") target_sheet.write(2, 3, u"單位") target_sheet.write(2, 4, u"數量") target_sheet.write(2, 5, u"人工費單價") target_sheet.write(2, 6, u"人工費總價") target_sheet.write(2, 7, u"報價") target_sheet.write(2, 8, u"收入金額(元)") target_sheet.write(2, 9, u"備註") ## write content index = 1 i = 3 for ProjectSale in ProjectSale_list: target_sheet.write(i, 0, u"{}".format(index)) target_sheet.write(i, 1, u"{}".format(ProjectSale.sale_goods_type)) target_sheet.write(i, 2, u"{}".format(ProjectSale.sale_goods_name)) target_sheet.write(i, 3, u"{}".format(ProjectSale.sale_unit)) target_sheet.write(i, 4, u"{}".format(ProjectSale.sale_number)) target_sheet.write(i, 5, u"{}".format(ProjectSale.staff_unit_price)) target_sheet.write(i, 6, u"{}".format(ProjectSale.staff_cost)) target_sheet.write(i, 7, u"{}".format(ProjectSale.sale_unit_price)) target_sheet.write(i, 8, u"{}".format(ProjectSale.sale_income)) target_sheet.write(i, 9, u"{}".format(ProjectSale.note)) i += 1 index += 1 file_name = proj_name + "_" + date_day + ".xls" file_path = "./report/" + file_name print(file_path) if os.path.exists(file_path): os.remove(file_path) ws.save(file_path) sio = StringIO.StringIO() ws.save(sio) sio.seek(0) response = HttpResponse(sio.getvalue(), content_type='text/html') response['Content-Disposition'] = 'attachment; filename=' + file_name.encode('GBK') response.write(sio.getvalue()) print("[successful]: ProjectSaleReport") return response except Exception as e: print("[failure]: ProjectSaleReport - {}".format(e)) response = HttpResponse() response.write("failure") return response