电脑知识|欧美黑人一区二区三区|软件|欧美黑人一级爽快片淫片高清|系统|欧美黑人狂野猛交老妇|数据库|服务器|编程开发|网络运营|知识问答|技术教程文章 - 好吧啦网

您的位置:首頁技術文章
文章詳情頁

在django項目中導出數據到excel文件并實現下載的功能

瀏覽:108日期:2022-07-06 16:05:46

依賴模塊

xlwt下載:pip install xlwt

后臺模塊

view.py

# 導出Excel文件def export_excel(request): city = request.POST.get(’city’) print(city) list_obj=place.objects.filter(city=city) # 設置HTTPResponse的類型 response = HttpResponse(content_type=’application/vnd.ms-excel’) response[’Content-Disposition’] = ’attachment;filename=’+city+’.xls’ '''導出excel表''' if list_obj: # 創建工作簿 ws = xlwt.Workbook(encoding=’utf-8’) # 添加第一頁數據表 w = ws.add_sheet(’sheet1’) # 新建sheet(sheet的名稱為'sheet1') # 寫入表頭 w.write(0, 0, u’地名’) w.write(0, 1, u’次數’) w.write(0, 2, u’經度’) w.write(0, 3, u’緯度’) # 寫入數據 excel_row = 1 for obj in list_obj: name = obj.place sum = obj.sum lng = obj.lng lat = obj.lat # 寫入每一行對應的數據 w.write(excel_row, 0, name) w.write(excel_row, 1, sum) w.write(excel_row, 2, lng) w.write(excel_row, 3, lat) excel_row += 1 # 寫出到IO output = BytesIO() ws.save(output) # 重新定位到開始 output.seek(0) response.write(output.getvalue()) return response

前端模塊

<button type='button' >導出excel</button>

$('#export_excel').click(function () { var csrf=$(’input[name='csrfmiddlewaretoken']’).val(); const req = new XMLHttpRequest(); req.open(’POST’, ’/export_excel/’, true); req.responseType = ’blob’; req.setRequestHeader(’Content-Type’, ’application/x-www-form-urlencoded’); //設置請求頭 req.send(’city=’+$(’#city’).val()+'&&csrfmiddlewaretoken='+csrf); //輸入參數 req.onload = function() { const data = req.response; const a = document.createElement(’a’); const blob = new Blob([data]); const blobUrl = window.URL.createObjectURL(blob); download(blobUrl) ; }; });

function download(blobUrl) { var city = $('input[name=’city’]').val(); const a = document.createElement(’a’); a.style.display = ’none’; a.download = ’<文件命名>’; a.href = blobUrl; a.click(); document.body.removeChild(a);}

補充知識:Python Django實現MySQL百萬、千萬級的數據量下載:解決memoryerror、nginx time out

前文

在用Django寫項目的時候時常需要提供文件下載的功能,而Django也是貼心提供了幾種方法:FileResponse、StreamingHttpResponse、HttpResponse,其中FileResponse和StreamingHttpResponse都是使用迭代器迭代生成數據的方法,所以適合傳輸文件比較大的情況;而HttpResponse則是直接取得數據返回給用戶,所以容易造成memoryerror和nginx time out(一次性取得數據和返回的數據過多,導致nginx超時或者內存不足),關于這三者,DJango的官網也是寫的非常清楚,連接如下:https://docs.djangoproject.com/en/1.11/ref/request-response/

那正常我們使用的是FileResponse和StreamingHttpResponse,因為它們流式傳輸(迭代器)的特點,可以使得數據一條條的返回給客戶端,文件隨時中斷和復傳,并且保持文件的一致性。

FileResponse和StreamingHttpResponse

FileResponse顧名思義,就是打開文件然后進行傳輸,并且可以指定一次能夠傳輸的數據chunk。所以適用場景:從服務端返回大文件。缺點是無法實時獲取數據庫的內容并傳輸給客戶端。舉例如下:

def download(request): file=open(’path/demo.py’,’rb’) response =FileResponse(file) response[’Content-Type’]=’application/octet-stream’ response[’Content-Disposition’]=’attachment;filename='demo.py'’ return response

從上可以發現,文件打開后作為參數傳入FileResponse,隨后指定傳輸頭即可,但是很明顯用這個來傳輸數據庫就不太方便了,所以這邊推介用StreamingHttpResponse的方式來傳輸。

這里就用PyMysql來取得數據,然后指定為csv的格式返回,具體代碼如下:

# 通過pymysql取得數據import pymysqlfield_types = { 1: ’tinyint’, 2: ’smallint’, 3: ’int’} #用于后面的字段名匹配,這里省略了大多數conn = pymysql.connect(host=’127.0.0.1’,port=3306,database=’demo’,user=’root’,password=’root’)cursor = conn.cursor(cursor=pymysql.cursors.DictCursor)cursor.execute(sql)#獲取所有數據data = cursor.fetchall()cols = {}#獲取所有字段for i,row in enumerate(self.cursor.description): if row[0] in cols: cols[str(i)+row[0]] = field_types.get(row[1], str(row[1])) #這里的field_type是類型和數字的匹配 cols[row[0]] = field_types.get(row[1], str(row[1]))cursor.close()conn.close()#通過StreamingHttpResponse指定返回格式為csvresponse = StreamingHttpResponse(get_result_fromat(data, cols))response[’Content-Type’] = ’application/octet-stream’response[’Content-Disposition’] = ’attachment;filename='{0}'’.format(out_file_name)return response#循環所有數據,然后加到字段上返回,注意的是要用迭代器來控制def get_result_fromat(data, cols): tmp_str = '' # 返回文件的每一列列名 for col in cols: tmp_str += ’'%s',’ % (col) yield tmp_str.strip(',') + 'n' for row in data: tmp_str = '' for col in cols: tmp_str += ’'%s',’ % (str(row[col])) yield tmp_str.strip(’,’) + 'n'

整個代碼如上,大致分為三部分:從mysql取數據,格式化成我們想要的格式:excel、csv、txt等等,這邊指定的是csv,如果對其他格式也有興趣的可以留言,最后就是用StreamingHttpResponse指定返回的格式返回。

實現百萬級數據量下載

上面的代碼下載可以支持幾萬行甚至十幾萬行的數據,但是如果超過20萬行以上的數據,那就比較困難了,我這邊的剩余內存大概是1G的樣子,當超過15萬行數據(大概)的時候,就報memoryerror了,問題就是因為fetchall,雖然我們StreamingHttpResponse是一條條的返回,但是我們的數據時一次性批量的取得!

如何解決?以下是我的解決方法和思路:

用fetchone來代替fetchall,迭代生成fetchone

發現還是memoryerror,因為execute是一次性執行,后來發現可以用流式游標來代替原來的普通游標,即SSDictCursor代替DictCursor

于是整個代碼需要修改的地方如下:

cursor = conn.cursor(cursor=pymysql.cursors.DictCursor) ===>cursor = conn.cursor(cursor=pymysql.cursors.SSDictCursor)

data = cursor.fetchall() ===>row = cursor.fetchone()

def get_result_fromat(data, cols): tmp_str = '' # 返回文件的每一列列名 for col in cols: tmp_str += ’'%s',’ % (col) yield tmp_str.strip(',') + 'n' for row in data: tmp_str = '' for col in cols: tmp_str += ’'%s',’ % (str(row[col])) yield tmp_str.strip(’,’) + 'n' =====> def get_result_fromat(data, cols): tmp_str = '' for col in cols: tmp_str += ’'%s',’ % (col) yield tmp_str.strip(',') + 'n' while True: tmp_str = '' for col in cols: tmp_str += ’'%s',’ % (str(row[col])) yield tmp_str.strip(’,’) + 'n' row = db.cursor.fetchone() if row is None: break

可以看到就是通過while True來實現不斷地取數據下載,有效避免一次性從MySQL取出內存不足報錯,又或者取得過久導致nginx超時!

總結

關于下載就分享到這了,還是比較簡單的,謝謝觀看~希望能給大家一個參考,也希望大家多多支持好吧啦網。

標簽: excel
相關文章:
主站蜘蛛池模板: 土壤水分自动监测站-SM150便携式土壤水分仪-铭奥仪器 | PU树脂_水性聚氨酯树脂_聚氨酯固化剂_聚氨酯树脂厂家_宝景化工 | 济南画室培训-美术高考培训-山东艺霖艺术培训画室 | 企典软件一站式企业管理平台,可私有、本地化部署!在线CRM客户关系管理系统|移动办公OA管理系统|HR人事管理系统|人力 | FAG轴承,苏州FAG轴承,德国FAG轴承-恩梯必传动设备(苏州)有限公司 | Dataforth隔离信号调理模块-信号放大模块-加速度振动传感器-北京康泰电子有限公司 | 深圳激光打标机_激光打标机_激光焊接机_激光切割机_同体激光打标机-深圳市创想激光科技有限公司 深圳快餐店设计-餐饮设计公司-餐饮空间品牌全案设计-深圳市勤蜂装饰工程 | 游动电流仪-流通式浊度分析仪-杰普仪器(上海)有限公司 | 智慧农业|农业物联网|现代农业物联网-托普云农物联网官方网站 | 道康宁消泡剂-瓦克-大川进口消泡剂供应商 | 郑州爱婴幼师学校_专业幼师培训_托育师培训_幼儿教育培训学校 | 除湿机|工业除湿机|抽湿器|大型地下室车间仓库吊顶防爆除湿机|抽湿烘干房|新风除湿机|调温/降温除湿机|恒温恒湿机|加湿机-杭州川田电器有限公司 | 电渗析,废酸回收,双极膜-山东天维膜技术有限公司 | 活性氧化铝|无烟煤滤料|活性氧化铝厂家|锰砂滤料厂家-河南新泰净水材料有限公司 | elisa试剂盒-PCR试剂盒「上海谷研实业有限公司」 | 哈尔滨京科脑康神经内科医院-哈尔滨治疗头痛医院-哈尔滨治疗癫痫康复医院 | TPM咨询,精益生产管理,5S,6S现场管理培训_华谋咨询公司 | 鼓风干燥箱_真空烘箱_高温干燥箱_恒温培养箱-上海笃特科学仪器 | 油罐车_加油机_加油卷盘_加油机卷盘_罐车人孔盖_各类球阀_海底阀等车用配件厂家-湖北华特专用设备有限公司 | 数控专用机床,专用机床,自动线,组合机床,动力头,自动化加工生产线,江苏海鑫机床有限公司 | 波纹补偿器_不锈钢波纹补偿器_巩义市润达管道设备制造有限公司 | 高速龙门架厂家_监控杆_多功能灯杆_信号灯杆_锂电池太阳能路灯-鑫世源照明 | 福建自考_福建自学考试网| 硬质合金模具_硬质合金非标定制_硬面加工「生产厂家」-西迪技术股份有限公司 | sus630/303cu不锈钢棒,440C/430F/17-4ph不锈钢研磨棒-江苏德镍金属科技有限公司 | 微信小程序定制,广州app公众号商城网站开发公司-广东锋火 | 粘弹体防腐胶带,聚丙烯防腐胶带-全民塑胶| 软启动器-上海能曼电气有限公司| 余姚生活网_余姚论坛_余姚市综合门户网站 | 环氧铁红防锈漆_环氧漆_无溶剂环氧涂料_环氧防腐漆-华川涂料 | 老城街小面官网_正宗重庆小面加盟技术培训_特色面馆加盟|牛肉拉面|招商加盟代理费用多少钱 | 浙江筋膜枪-按摩仪厂家-制造商-肩颈按摩仪哪家好-温州市合喜电子科技有限公司 | 电位器_轻触开关_USB连接器_广东精密龙电子科技有限公司 | 环氧乙烷灭菌器_压力蒸汽灭菌器_低温等离子过氧化氢灭菌器 _低温蒸汽甲醛灭菌器_清洗工作站_医用干燥柜_灭菌耗材-环氧乙烷灭菌器_脉动真空压力蒸汽灭菌器_低温等离子灭菌设备_河南省三强医疗器械有限责任公司 | 锂辉石检测仪器,水泥成分快速分析仪-湘潭宇科分析仪器有限公司 | 定坤静电科技静电消除器厂家-除静电设备 | 哈尔滨发电机,黑龙江柴油发电机组-北方星光 | 无锡门窗-系统门窗-阳光房-封阳台-断桥铝门窗厂[窗致美] | 炒货机-炒菜机-炒酱机-炒米机@霍氏机械 | 贝朗斯动力商城(BRCPOWER.COM) - 买叉车蓄电池上贝朗斯商城,价格更超值,品质有保障! | 超声波清洗机_大型超声波清洗机_工业超声波清洗设备-洁盟清洗设备 |