vue通用匯出元件的實現匯出 excel csv pdf
後臺管理專案中經常使用檔案匯入匯出,故封裝了一個通用匯出元件的實現

通用匯出
思路 使用 Dropdown 控制元件選擇匯出型別 觸發匯出
匯出的table 資料型別
tableColumns: [ { title: '序號', key: 'Ordinal', align: 'center' }, { title: '產品編號', key: 'ProductNo', align: 'left' } ] tableData: [{Ordinal:1,ProductNo:'1234',ProductDesc:'1232222'}]
匯出檔案大部分情況下是後端處理,有時候我們只需要js處理 該怎麼做呢?
1.匯出CSV
首先實現匯出CSV格式
拼接 csv格式其實就是個純文字檔案,中間使用逗號或者換行符進行拼接
這裡使用 json2cvs這個包 需要npm 安裝 npm install json2csv -s
下載方式
對於微軟系瀏覽器(IE和Edge)和非微軟系列瀏覽器採用兩種不同的方式進行下載
IE和Edge 採用了 navigator.msSaveBlob 方法 此方法為IE10及以上特有,IE10以下勿採用
非微軟瀏覽器 使用a標籤的click事件進行下載
關鍵程式碼
try { const result = json2csv.parse(rows, { fields: fields, excelStrings: true }); if (this.MyBrowserIsIE()) { // IE10以及Edge瀏覽器 var BOM = "\uFEFF"; // 檔案轉Blob格式 var csvData = new Blob([BOM + result], { type: "text/csv" }); navigator.msSaveBlob(csvData, `${fileName}.csv`); } else { let csvContent = "data:text/csv;charset=utf-8,\uFEFF" + result; // 非ie 瀏覽器 this.createDownLoadClick(csvContent, `${fileName}.csv`); } } catch (err) { alert(err); }
//建立a標籤下載 createDownLoadClick(content, fileName) { const link = document.createElement("a"); link.href = encodeURI(content); link.download = fileName; document.body.appendChild(link); link.click(); document.body.removeChild(link); },
// 判斷是否IE瀏覽器 MyBrowserIsIE() { let isIE = false; if ( navigator.userAgent.indexOf("compatible") > -1 && navigator.userAgent.indexOf("MSIE") > -1 ) { // ie瀏覽器 isIE = true; } if (navigator.userAgent.indexOf("Trident") > -1) { // edge 瀏覽器 isIE = true; } return isIE; },
2.匯出Excel型別檔案
匯出excel借鑑了iview-admin 自帶的excel操作js(需要npm安裝 xlsx)npm install xlsx -s
需要匯出的地方呼叫excel.export_array_to_excel函式即可
const param = { title: titles, key: keys, data: this.exportData, autoWidth: true, filename: this.exportFileName }; excel.export_array_to_excel(param);
完整excel操作js程式碼如果 excel.js
參考博文
https://www.cnblogs.com/muyangw/p/10306152.html
3.匯出pdf
最開始使用jspdf 包 把 需要匯出的table使用 canvas生成圖片,然後把圖片插入pdf內,但是這種方式不容易控制,並且生成的pdf清晰度不高,如果直接寫pdf又會產生對中文支援的不友好,後採用前後端配合生成pdf檔案並匯出
使用blob的方式 後端返回檔案流前端 接收並下載
主要程式碼如下
//思路 webapi返回二進位制的檔案流 js 通過Blob接收並轉換成pdf檔案下載 this.$axios({ method: "post", Prefix: "", data: { ExCode: "IRAP_RPT_DownLoadFile", fileName: this.exportFileName, access_token: this.$cookies.get("access_token"), valueKeys: valueKeys, //"Product,Version,Description", labeNames: labeNames, // "產品,版本,描述", tableData: tableData } // responseType:'blob' }) .then(response => { // base64字串轉 byte[] var bstr = atob(response.data.FileInfo), n = bstr.length, u8arr = new Uint8Array(n); while (n--) { u8arr[n] = bstr.charCodeAt(n); } // 轉blob var blob = new Blob([u8arr], { type: `application/pdf;charset-UTF-8` }) if (this.MyBrowserIsIE()) { // IE10以及Edge瀏覽器 var BOM = "\uFEFF"; // 傳入 Blob 物件 navigator.msSaveBlob(blob, `${this.exportFileName}.pdf`); } else { // 非ie 瀏覽器 let content = window.URL.createObjectURL(blob); this.createDownLoadClick(content, `${this.exportFileName}.pdf`); } }) .catch(err => { console.log(err); });
因為公司介面通用規範我這裡返回的是檔案的base64字串
如果後臺直接返回了二進位制的檔案流 就不用再次進行轉換 並且需要加上responseType:'blob'這句
後臺介面採用C# webapi 的方式主要程式碼如下
public string DownLoadFile(string clientID, string msgFormat, string inParam) { dynamic res = new System.Dynamic.ExpandoObject(); try { dynamic dn = inParam.GetSimpleObjectFromJson(); string token = dn.access_token.ToString(); // 解析Json 字串中的陣列然後 轉實體物件 string fileName = dn.fileName; string lbelObj = dn.labeNames; string valueKeyObj = dn.valueKeys; object[] tableObj = dn.tableData; string tableJson = JsonConvert.SerializeObject(tableObj); string[] valueKeys = valueKeyObj.Split(','); string[] labeNames = lbelObj.Split(','); //string[] valueKeys = new string[] { "Product", "Version","Description" }; ; //string[] labeNames = new string[] { "產品", "版本", "描述" }; ; DataTable tblDatas = new DataTable("Datas"); //string jsonStr ="[{\"Product\":\"1\",\"Version\":\"1\",\"Description\":\"1\"}]"; tblDatas = ToDataTableTwo(tableJson); PDFHelper pdfHelper = new PDFHelper(); byte[] array = pdfHelper.ExportPDF(fileName, labeNames, tblDatas,valueKeys); // 檔案byte陣列轉base64字串 string str = Convert.ToBase64String(array);; byte[] bt = array.ToArray(); res.ErrCode = 0; res.ErrText = "檔案生成成功"; res.FileInfo = str; return JsonConvert.SerializeObject(res); } catch (Exception ex) { //throw new Exception(ex.Message); res.ErrCode = 9999; res.ErrText = "Excel匯入異常:" + ex.Message; return JsonConvert.SerializeObject(res); } }
C# pdf生成 使用itextsharp
父元件呼叫程式碼
<MyExportType :exportFileName='`test`' v-on:myHandleRepeatExprot="myRepeatExprot" :isPagination="isPagination" :exportData="exportData" :exportColumns="exportColumns" ref="MyExportType"></MyExportType>
如果父元件分頁的需要匯出所有未分頁的資料 需要再次呼叫查詢table資料的介面並且給exportData賦值
async myRepeatExprot(name) { // 查詢所有 await this.geBTtResult(1) // 呼叫子元件的匯出事件 await this.$refs.MyExportType.exportFile(name) },
否則 未分頁或者匯出當前頁 直接匯出即可 不需要通過父元件呼叫子元件事件