[Web]flask-excel實現excel文件下載的前后端實現


之前同事寫了前端表格導出的功能, 前后端邏輯沒有梳理, 導致后端代碼十分臃腫.

接手之后, 重新選擇了前端table插件, 從jqxGrid變更為bootstrapTable.

本來想依賴集成的tableExport.js在前端自己實現文件下載的, 然而這個插件存在着諸多不理想的地方.

首先導出的文件格式, excel會提示文件格式損壞報錯; 其次長串數字會被截斷, 並且以科學計數顯示. 在bootstrapTable中將值toString依然無效.

搜索了一下前端的解決方案, 最后還是決定在后端做實現.

第一個方案是打算做一個緩存機制. 前端查詢一次后, 在后端緩存結果, 接口返回數據和cacheId. 當要導出文件時, 前端通過cacheId去請求緩存數據的下載.

然而這種方案雖然合理, 但緩存機制的細節處理較為繁瑣, 糾結了一下, 暫時放棄.

如果不做緩存的話, 每次導出都需要重新去做查詢, 不但耗時較長, 機制也比較蠢.

最后在前同事的方案上做了些許改進. 前端首先向服務器post自己的table數據, 后端處理成excel之后再返回. 這種方案不適合大量數據導出. 數據量大的話, 網絡傳輸也會成為問題.

代碼主要有三部分, 前端業務邏輯, 前端抽象函數, 后端抽象接口.

業務邏輯:

$('#table-export').click(function(){
    var currentPage = window.location.pathname; // 文件命名參數
    var tableData = $('#table').bootstrapTable('getData'); // table數據
    var colnames = [
        {'field':'a', 'title': '國家'},
        {'field':'b', 'title':'代碼'},
        {'field':'c', 'title':'抽象'},
        {'field':'d', 'title': '初音'},
        {'field':'e', 'title': '日期'},
    ]
    if (tableData.length == 0) {
        makeAlert('danger', '沒有可導出數據!', $('#query-alert')); // 錯誤提示
        return false;
    }
    exportExcel(tableData, colnames, currentPage);
})

前端抽象函數:

// 通過form提交實現. 用ajax post也可以, 但實現方式另有不同, 沒有選擇. 
// 參數含data, 列名, 調用頁面的名稱
function exportExcel(data, colnames, page) {
    var targetUrl = $SCRIPT_ROOT + '/api/v1.0/export_excel/';

    var temp = document.createElement("form");
    temp.action = targetUrl;
    temp.method = "post";
    temp.style.display = "none";
    
    var tableData = document.createElement("textarea");
    tableData.name = "table_data";
    tableData.value = JSON.stringify(data);
    temp.appendChild(tableData);

    var columnName = document.createElement("textarea");
    columnName.name = "colnames";
    columnName.value = JSON.stringify(colnames);
    temp.appendChild(columnName);

    var pageName = document.createElement("textarea");
    pageName.name = "pageName";
    pageName.value = JSON.stringify(page);
    temp.appendChild(pageName);

    document.body.appendChild(temp);
    temp.submit();
    return false;
}

后端接口:

# 依賴flask-excel make response 實現xls文件返回
# flask-excel存在很多坑, 耐心點踩

from flask import request
from . import api
from app.utils import format_datetime
import flask_excel as excel
import json
import datetime

@api.route('/export_excel/', methods=['POST'])
def export_excel():
    if request.method == 'POST':
        table_data = json.loads(request.form['table_data'])
        colnames = json.loads(request.form['colnames'])
        page_name = request.form['pageName'].split('/')[-1]
        file_name = '{}_{}'.format(page_name,
            format_datetime(datetime.datetime.now(),'%Y%m%d%H%M%S'))
        excel_resp = make_excel_list(table_data, colnames)
        return excel.make_response_from_array(excel_resp, 'xlsx',
                                sheet_name = page_name,
                                file_name= file_name)
    else:
        return False

def make_excel_list(data, fields):
    list_data = []
    field = [x['field'] for x in fields]
    name = [x['title'] for x in fields]
    
    list_data.append(name)
    for item in data:
        tmp = []
        for fi in field:
            if fi in item.keys():
                tmp.append(item[fi])
            else:
                tmp.append('')
        list_data.append(tmp)
    return list_data


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM