日本不卡不码高清免费观看,久久国产精品久久w女人spa,黄色aa久久,三上悠亚国产精品一区二区三区

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

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

瀏覽:147日期: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
相關文章:
日本不卡不码高清免费观看,久久国产精品久久w女人spa,黄色aa久久,三上悠亚国产精品一区二区三区
日韩有码av| 免费看精品久久片| 欧美成人精品午夜一区二区| 欧美亚洲三级| 国产视频网站一区二区三区| 91精品福利观看| 欧美一级网址| 亚洲美女久久| 日韩高清不卡在线| 久久99精品久久久野外观看| 国产乱论精品| 福利一区二区三区视频在线观看| 精品欧美日韩精品| 国产传媒在线| 欧美不卡在线| 亚洲午夜国产成人| 国产精品自在| 日韩在线观看| 亚洲在线成人| 国产调教一区二区三区| 美腿丝袜亚洲一区| 日韩一区三区| 国产综合精品| 亚洲制服一区| 欧美精品第一区| 丁香六月综合| 99re国产精品| 黑丝一区二区| 日韩精品免费一区二区夜夜嗨 | 国产精品欧美大片| 成人精品高清在线视频| 久久蜜桃精品| 一本综合精品| 欧美黄色一区二区| 国产99亚洲| 奇米777国产一区国产二区| 精品免费av| 欧美~级网站不卡| 日本91福利区| 丝袜诱惑一区二区| 蜜桃久久av一区| 久久精品五月| 久久午夜视频| 久久亚洲人体| 国产手机视频一区二区| 国产乱人伦精品一区| а√天堂8资源在线| 三级欧美在线一区| 国产精品www.| 99在线精品免费视频九九视 | 亚洲毛片一区| 国产一区二区三区天码| 亚洲一区二区成人| 精品精品国产三级a∨在线| 99riav国产精品| 久久亚洲黄色| 亚洲制服少妇| 成人台湾亚洲精品一区二区 | 日产欧产美韩系列久久99| 在线看片福利| 日韩国产一区二| 蜜桃国内精品久久久久软件9| 欧美在线精品一区| 米奇777超碰欧美日韩亚洲| 国产精品久久久久久久久久久久久久久| 久久一区二区三区喷水| 欧美国产极品| 日韩专区一卡二卡| 日韩国产欧美一区二区| 国产亚洲电影| 最新国产拍偷乱拍精品| 麻豆久久一区| 四虎国产精品免费久久| 久久久亚洲一区| 欧美激情91| 日韩一区二区三区精品视频第3页| 亚洲1234区| 开心激情综合| 日韩国产91| 久久亚洲影院| 国产专区一区| 91亚洲一区| 国产精品chinese| 视频精品一区| 亚洲欧美日韩综合国产aⅴ| 国产精选在线| 国产精品观看| 日本欧美大码aⅴ在线播放| 亚洲欧洲一区二区天堂久久| 高清不卡亚洲| 九九久久国产| 国产日韩亚洲欧美精品| 亚洲精品高潮| 夜夜嗨一区二区三区| 成人日韩在线| caoporn视频在线| 久久亚洲精精品中文字幕| 日韩av午夜在线观看| 亚洲精选成人| 免费美女久久99| 美女被久久久| 亚洲高清成人| 亚洲va中文在线播放免费| 国产中文欧美日韩在线| 国产精品欧美一区二区三区不卡| 日本一不卡视频| 在线精品一区二区| 国产视频一区三区| 黄色国产精品| 激情欧美一区| 香蕉久久99| 国产精品7m凸凹视频分类| 精品三级久久| 人人精品亚洲| 久久久精品网| 久久夜色精品| 蜜桃免费网站一区二区三区| 国产h片在线观看| 国产成人精品一区二区免费看京| 国产情侣一区| 国产欧美一区二区三区精品观看| 日韩精品午夜视频| 日韩成人精品一区二区三区| 日本国产亚洲| 99久久精品费精品国产| 都市激情国产精品| 国产成人精选| 激情久久99| 激情黄产视频在线免费观看| 成人午夜亚洲| 日韩伦理在线一区| 久久99国产精品视频| 久久久国产精品入口麻豆| 美腿丝袜亚洲一区| 精品视频一区二区三区四区五区| 麻豆视频一区二区| 91中文字幕精品永久在线| 亚洲欧洲高清| 久久香蕉国产| 99热精品在线观看| 亚洲精品大片| 国产精品对白久久久久粗| 麻豆精品国产91久久久久久| 国产精品毛片久久| 久久久精品午夜少妇| 日韩一级网站| 玖玖精品视频| 欧美一区自拍| 红杏一区二区三区| 亚洲www啪成人一区二区| 蜜桃国内精品久久久久软件9| 男人天堂欧美日韩| 97成人超碰| 国产欧洲在线| 国产视频一区三区| 欧美日韩视频免费看| 精品国产91| 在线日韩一区| 亚洲丝袜啪啪| 欧美1区2区3| 欧美freesex黑人又粗又大| 久久理论电影| 一区二区三区四区在线观看国产日韩| 国产欧美日韩| 日韩欧美二区| 一区二区亚洲视频| 精品亚洲精品| 亚洲大全视频| 青青草国产成人99久久| 丰满少妇一区| 国产精品腿扒开做爽爽爽挤奶网站| 日韩高清在线一区| 天堂8中文在线最新版在线| 视频在线在亚洲| 精品视频91| 亚洲欧美日韩国产一区二区| 欧美日韩精品一区二区三区视频| 成人三级高清视频在线看| 久久国产精品久久w女人spa| 麻豆精品蜜桃视频网站| 婷婷综合在线| 国产精品亚洲四区在线观看| 激情久久中文字幕| 久久国内精品视频| 免费精品国产| 国产高清精品二区| 亚洲视频www| 欧美日中文字幕| 国产精品试看| 日本在线精品| 狠狠久久伊人| 亚洲精品成人一区| 在线午夜精品| 亚洲天堂免费电影| 国产日韩欧美一区在线| 蜜臀av国产精品久久久久| 日韩精品久久理论片| 国产亚洲一区二区手机在线观看 | 久久免费大视频| 国产乱人伦精品一区|