码迷,mamicode.com
首页 > 其他好文 > 详细

vue实现通用导出(excel,csv, pdf文件)组件 前端导出

时间:2020-05-30 12:44:13      阅读:65      评论:0      收藏:0      [点我收藏+]

标签:技术   pat   navig   def   项目   情况下   不同的   base64   data   

后台管理项目中经常使用文件导入导出,故封装了一个通用table的导出组件的实现

技术图片

 

思路 使用 Dropdown 控件选择导出类型 触发导出

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浏览器 不支持a标签进行下载,会打开url 故
        对于微软系浏览器(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

1 /* eslint-disable */
2 import XLSX from ‘xlsx‘;
3
4 function auto_width(ws, data) {
5 /*set worksheet max width per col*/
6 const colWidth = data.map(row => row.map(val => {
7 /*if null/undefined*/
8 if (val == null) {
9 return {
10 ‘wch‘: 10
11 };
12 }
13 /*if chinese*/
14 else if (val.toString().charCodeAt(0) > 255) {
15 return {
16 ‘wch‘: val.toString().length * 2
17 };
18 } else {
19 return {
20 ‘wch‘: val.toString().length
21 };
22 }
23 }))
24 /*start in the first row*/
25 let result = colWidth[0];
26 for (let i = 1; i < colWidth.length; i++) {
27 for (let j = 0; j < colWidth[i].length; j++) {
28 if (result[j][‘wch‘] < colWidth[i][j][‘wch‘]) {
29 result[j][‘wch‘] = colWidth[i][j][‘wch‘];
30 }
31 }
32 }
33 ws[‘!cols‘] = result;
34 }
35
36 function json_to_array(key, jsonData) {
37 return jsonData.map(v => key.map(j => {
38 return v[j]
39 }));
40 }
41
42 // fix data,return string
43 function fixdata(data) {
44 let o = ‘‘
45 let l = 0
46 const w = 10240
47 for (; l < data.byteLength / w; ++l) o += String.fromCharCode.apply(null, new Uint8Array(data.slice(l * w, l * w + w)))
48 o += String.fromCharCode.apply(null, new Uint8Array(data.slice(l * w)))
49 return o
50 }
51
52 // get head from excel file,return array
53 function get_header_row(sheet) {
54 const headers = []
55 const range = XLSX.utils.decode_range(sheet[‘!ref‘])
56 let C
57 const R = range.s.r /* start in the first row */
58 for (C = range.s.c; C <= range.e.c; ++C) { /* walk every column in the range */
59 var cell = sheet[XLSX.utils.encode_cell({
60 c: C,
61 r: R
62 })] /* find the cell in the first row */
63 var hdr = ‘UNKNOWN ‘ + C // <-- replace with your desired default
64 if (cell && cell.t) hdr = XLSX.utils.format_cell(cell)
65 headers.push(hdr)
66 }
67 return headers
68 }
69
70 export const export_table_to_excel = (id, filename) => {
71 const table = document.getElementById(id);
72 const wb = XLSX.utils.table_to_book(table);
73 XLSX.writeFile(wb, filename);
74
75 /* the second way */
76 // const table = document.getElementById(id);
77 // const wb = XLSX.utils.book_new();
78 // const ws = XLSX.utils.table_to_sheet(table);
79 // XLSX.utils.book_append_sheet(wb, ws, filename);
80 // XLSX.writeFile(wb, filename);
81 }
82
83 export const export_json_to_excel = ({
84 data,
85 key,
86 title,
87 filename,
88 autoWidth
89 }) => {
90 const wb = XLSX.utils.book_new();
91 data.unshift(title);
92 const ws = XLSX.utils.json_to_sheet(data, {
93 header: key,
94 skipHeader: true
95 });
96 if (autoWidth) {
97 const arr = json_to_array(key, data);
98 auto_width(ws, arr);
99 }
100 XLSX.utils.book_append_sheet(wb, ws, filename);
101 XLSX.writeFile(wb, filename + ‘.xlsx‘);
102 }
103
104 // 导出不带有汉字标题的execel内容
105 export const export_array_to_excel = ({
106 key,
107 data,
108 title,
109 filename,
110 autoWidth
111 }) => {
112 const wb = XLSX.utils.book_new();
113 const arr = json_to_array(key, data);
114 arr.unshift(title)
115 const ws = XLSX.utils.aoa_to_sheet(arr);
116 if (autoWidth) {
117 auto_width(ws, arr);
118 }
119 XLSX.utils.book_append_sheet(wb, ws, filename);
120 XLSX.writeFile(wb, filename + ‘.xlsx‘);
121 }
122
123 // 导出带有汉字标题的execel内容
124 export const export_array_to_excel2 = ({
125 key,
126 data,
127 title,
128 filename,
129 autoWidth
130 }) => {
131 const wb = XLSX.utils.book_new();
132 const arr = json_to_array(key, data);
133 arr.unshift(key)
134 arr.unshift(title)
135 const ws = XLSX.utils.aoa_to_sheet(arr);
136 if (autoWidth) {
137 auto_width(ws, arr);
138 }
139 XLSX.utils.book_append_sheet(wb, ws, filename);
140 XLSX.writeFile(wb, filename + ‘.xlsx‘);
141 }
142
143 export const read = (data, type) => {
144 /* if type == ‘base64‘ must fix data first */
145 // const fixedData = fixdata(data)
146 // const workbook = XLSX.read(btoa(fixedData), { type: ‘base64‘ })
147 const workbook = XLSX.read(data, {
148 type: type
149 });
150 const firstSheetName = workbook.SheetNames[0];
151 const worksheet = workbook.Sheets[firstSheetName];
152 const header = get_header_row(worksheet);
153 const results = XLSX.utils.sheet_to_json(worksheet);
154 return {
155 header,
156 results
157 };
158 }
159
160 export const readesxle = async (file, header, jsointitle) => {
161 return new Promise(function (resolve, reject) {
162 const resultdata = {
163 ErrCode: "9",
164 ErrText: ‘导入文件格式不正确。‘,
165 Rows: []
166 }
167 const fileExt = file.name.split(‘.‘).pop().toLocaleLowerCase()
168 if (fileExt === ‘xlsx‘ || fileExt === ‘xls‘) {
169 const reader = new FileReader();
170
171 const thisXLSX = XLSX;
172 const thisheader = header;
173 const thisjsointitle = jsointitle;
174 reader.readAsArrayBuffer(file)
175 reader.onloadstart = e => {}
176 // reader.onprogress = e => {
177 // this.progressPercent = Math.round(e.loaded / e.total * 100)
178 // }
179 reader.onerror = e => {
180 resultdata.ErrText = ‘文件读取出错‘;
181 resultdata.ErrCode = "1";
182 resolve(resultdata);
183 }
184 reader.onload = e => {
185 const data = e.target.result
186 const
187 workbook = thisXLSX.read(data, {
188 type: "array"
189 });
190 let tempFlag = true;
191
192 const firstSheetName = workbook.SheetNames[0];
193 const worksheet = workbook.Sheets[firstSheetName];
194 const sheetsheader = get_header_row(worksheet);
195 const sheetarray = thisXLSX.utils.sheet_to_json(worksheet);
196
197 thisheader.forEach((item, index) => {
198 if (sheetsheader.findIndex(x => x == item) == -1) {
199 tempFlag = false
200 }
201 });
202 if (tempFlag) {
203 let sheetresult = [];
204 for (let i = 0; i < sheetarray.length; i++) {
205 sheetresult.push({});
206 for (let j = 0; j < thisheader.length; j++) {
207 if (sheetarray[i][thisheader[j]] == undefined || sheetarray[i][thisheader[j]] == null)
208 sheetresult[i][thisjsointitle[j]] = "";
209 else
210 sheetresult[i][thisjsointitle[j]] = sheetarray[i][thisheader[j]];
211 }
212 }
213 resultdata.ErrCode = "0";
214 resultdata.EErrText = "文件导入成功";
215 resultdata.Rows = sheetresult;
216 } else {
217 resultdata.ErrCode = "1";
218 resultdata.EErrText = "导入文件格式不正确。";
219 resultdata.Rows = [];
220 }
221 resolve(resultdata);
222 }
223 } else {
224 resultdata.ErrCode = "1";
225 resultdata.ErrText = ‘文件:‘ + file.name + ‘不是EXCEL文件,请选择后缀为.xlsx或者.xls的EXCEL文件。‘;
226 resolve(resultdata);
227 }
228 })
229 }
230
231 export default {
232 export_table_to_excel,
233 export_array_to_excel,
234 export_json_to_excel,
235 export_array_to_excel2,
236 read,
237 readesxle
238 }

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);
});

vue实现通用导出(excel,csv, pdf文件)组件 前端导出

标签:技术   pat   navig   def   项目   情况下   不同的   base64   data   

原文地址:https://www.cnblogs.com/masterhxh/p/12991694.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!