和一个同事聊功能实现,发现有些页面的csv下载功能没有发http请求,是js实现的。
以前总是用后端java来实现生成csv,查了一下js如何实现生成并导出csv文件,记录一下。
虽然最后还是用后端来实现,需要做鉴权。但是知识面还是要扩展的。
转自:https://www.cnblogs.com/victor-leeson/p/10708019.html
另外一篇:https://www.cnblogs.com/tugenhua0707/p/11188117.html
/* * 参数: * headers:表头 * 格式如: * [ * { * column:"userid", //列字段 * title: "姓名", //表头标题 * formatter:(value) =>{return ... } //格式化函数 * }, * ... * ] * * rows:行 * 格式如:[{userid:101,gender:0 },{userid:102,gender:1}] * filename:导出保存的文件名 */ export default function exportCsv(headers, rows, filename) { if (Array.isArray(headers) && headers.length > 0) { //表头信息不能为空 if (!filename || typeof filename != "string") { fileName = "export.csv" } let blob = getCsvBlob(headers, rows); if (navigator.msSaveOrOpenBlob) { navigator.msSaveOrOpenBlob(blob, filename); } else { let url = URL.createObjectURL(blob); let downloadLink = document.createElement('a'); downloadLink.href = url; downloadLink.download = filename; document.body.appendChild(downloadLink); downloadLink.click(); document.body.removeChild(downloadLink); URL.revokeObjectURL(url); } } } function getCsvBlob(headers, rows) { const BOM = 'uFEFF'; let columnDelimiter = ','; //默认列分隔符',' let rowDelimiter = ' '; //默认行分隔符 ' ' let csv = headers.reduce((previous, header) => { return (previous ? previous + columnDelimiter : '') + (header.title || header.column); }, ''); if (Array.isArray(rows) && rows.length > 0) { let columns = headers.map(header => header.column); csv = rows.reduce((previous, row) => { let rowCsv = columns.reduce((pre, column) => { if (row.hasOwnProperty(column)) { let cell = row[column]; if (cell != null) { let header = headers.find(item => item.column == column); if (header.formatter != null && typeof (header.formatter) == "function") { cell = header.formatter(cell); } if (cell != null) { cell = cell.toString().replace(new RegExp(rowDelimiter, 'g'), ' '); // 若数据中本来就含行分隔符,则用' '替换 cell = new RegExp(columnDelimiter).test(cell) ? `"${cell}"` : cell; //若数据中本来就含列分隔符,则用""包起来 return pre ? pre + columnDelimiter + cell : pre + cell; } } return pre ? pre + columnDelimiter : pre + " ";//reduce初始值为'',故第一次迭代时不会在行首加列分隔符。后面的遇到值为空或不存在的列要填充含空格的空白" ",则pre返回true,会加列分隔符 } else { return pre ? pre + columnDelimiter : pre + " ";//即使不存在该列也要填充空白,避免数据和表头错位不对应 } }, ''); return previous + rowDelimiter + rowCsv; }, csv); } let blob = new Blob([BOM + csv], { type: 'text/csv;charset=utf-8;' }); return blob; }