最近在做一个项目,涉及到导出数据到Excel表格,由于是采用的前后端分离模式开发的,之前常用的方法已经失效,在网上找了一些资料和方法
js文件下载地址
1.是采用的一个插件 xlsx.full.min.js,实现在服务器请求过来数据,按照格式就可以实现导出到Excel表,废话不多说,直接贴代码:
<!-- 这是页面代码 -->
<button class="am-btn am-btn-default" onclick="findExcelData();" type="button">导出</button>
<a href="" download="客户信息.xlsx" id="downloadA"></a>
//这是js代码
//查询客户信息列表 导出Excel
function findExcelData() {
var startDate = $("input[name=startDate]").val();
var endDate = $("input[name=endDate]").val();
var param = {
startDate: startDate,
endDate: endDate
};
$.post(Url + 'customer/toExcel', param, function(data, status) {
console.log(data);
if (data['result'] == '0000') {
var list = eval(data['list']);
var size = data['size'];
if (size > 0) {
downloadExl(list);
} else {
alert("选择的时间区域没有数据");
}
//时间回显
$("#startDate").val(data['startDate']);
$("#endDate").val(data['endDate']);
} else {
alert(data['message']);
}
})
}
var tmpDown; //导出的二进制对象
function downloadExl(json, type) {
//根据json数据,获取excel的第一行存至map
var tmpdata = json[0];
json.unshift({});
var keyMap = []; //获取keys
for (var k in tmpdata) {
keyMap.push(k);
json[0][k] = k;
}
var tmpdata = [];
json.map((v, i) => keyMap.map((k, j) => Object.assign({}, {
v: v[k],
position: (j > 25 ? getCharCol(j) : String.fromCharCode(65 + j)) + (i + 1)
}))).reduce((prev, next) => prev.concat(next)).forEach((v, i) => tmpdata[v.position] = {
v: v.v
});
//设置区域,比如表格从A1到D10
var outputPos = Object.keys(tmpdata);
var tmpWB = {
SheetNames: ['mySheet'], //保存的表标题
Sheets: {
'mySheet': Object.assign({},
tmpdata, //内容
{
'!ref': outputPos[0] + ':' + outputPos[outputPos.length - 1] //设置填充区域
})
}
};
//创建二进制对象写入转换好的字节流
tmpDown = new Blob([s2ab(XLSX.write(tmpWB, {
bookType: (type == undefined ? 'xlsx' : type),
bookSST: false,
type: 'binary'
} //这里的数据是用来定义导出的格式类型
))], {
type: ""
});
var href = URL.createObjectURL(tmpDown); //创建对象超链接
var timestamp = (new Date()).getTime();
var excelName = timestamp + ".xlsx";
document.getElementById("downloadA").download = excelName;
document.getElementById("downloadA").href = href; //绑定a标签
document.getElementById("downloadA").click(); //模拟点击实现下载
setTimeout(function() { //延时释放
URL.revokeObjectURL(tmpDown); //用URL.revokeObjectURL()来释放这个object URL
}, 100);
}
//字符串转字符流
function s2ab(s) {
var buf = new ArrayBuffer(s.length);
var view = new Uint8Array(buf);
for (var i = 0; i != s.length; ++i) view[i] = s.charCodeAt(i) & 0xFF;
return buf;
}
//将指定的自然数转换为26进制表示。映射关系:[0-25] -> [A-Z]。
function getCharCol(n) {
let temCol = '',
s = '',
m = 0
while (n > 0) {
m = n % 26 + 1
s = String.fromCharCode(m + 64) + s
n = (n - m) / 26
}
return s
}
2.第二种方法是获取页面table,将table标签,包括tr、td等对json数据进行拼接,将table输出到表格上实现,这种方法的弊端在于输出的是伪excel,虽说生成xls为后缀的文件,但文件形式上还是html,下面贴代码
前端代码
<button class="am-btn am-btn-default" onclick="method5('kehuTable');" type="button">导出Excel</button>
js代码
//打印表格
var idTmr;
function getExplorer() {
var explorer = window.navigator.userAgent;
//ie
if (explorer.indexOf("MSIE") >= 0) {
return 'ie';
}
//firefox
else if (explorer.indexOf("Firefox") >= 0) {
return 'Firefox';
}
//Chrome
else if (explorer.indexOf("Chrome") >= 0) {
return 'Chrome';
}
//Opera
else if (explorer.indexOf("Opera") >= 0) {
return 'Opera';
}
//Safari
else if (explorer.indexOf("Safari") >= 0) {
return 'Safari';
}
}
//tableid 为table表格ID
function method5(tableid) {
if (getExplorer() == 'ie') {
var curTbl = document.getElementById(tableid);
var oXL = new ActiveXObject("Excel.Application");
var oWB = oXL.Workbooks.Add();
var xlsheet = oWB.Worksheets(1);
var sel = document.body.createTextRange();
sel.moveToElementText(curTbl);
sel.select();
sel.execCommand("Copy");
xlsheet.Paste();
oXL.Visible = true;
try {
var fname = oXL.Application.GetSaveAsFilename("Excel.xls",
"Excel Spreadsheets (*.xls), *.xls");
} catch (e) {
print("Nested catch caught " + e);
} finally {
oWB.SaveAs(fname);
oWB.Close(savechanges = false);
oXL.Quit();
oXL = null;
idTmr = window.setInterval("Cleanup();", 1);
}
} else {
tableToExcel(tableid)
}
}
function Cleanup() {
window.clearInterval(idTmr);
CollectGarbage();
}
var tableToExcel = (function() {
var uri = 'data:application/vnd.ms-excel;base64,',
template = '<html><head><meta charset="UTF-8"></head><body><table border="1">{table}</table></body></html>',
base64 = function(
s) {
return window.btoa(unescape(encodeURIComponent(s)))
},
format = function(s, c) {
return s.replace(/{(\w+)}/g, function(m, p) {
return c[p];
})
}
return function(table, name) {
if (!table.nodeType)
table = document.getElementById(table)
var ctx = {
worksheet: name || 'Worksheet',
table: table.innerHTML
}
window.location.href = uri + base64(format(template, ctx))
}
})()
3.通过将json遍历进行字符串拼接,将字符串输出到csv文件,代码如下
<button onclick='tableToExcel()'>导出</button>
function tableToExcel(){
//要导出的json数据
var jsonData = [
{
name:'李四',
phone:'1777829****',
email:'20838****@qq.com'
},
{
name:'张三',
phone:'1777829****',
email:'20838****@qq.com'
},
{
name:'王五',
phone:'1777829****',
email:'20838****@qq.com'
},
{
name:'老刘',
phone:'1777829****',
email:'20838****@qq.com'
}
]
//列标题,逗号隔开,每一个逗号就是隔开一个单元格
let str = `姓名,电话,邮箱\n`;
//增加\t为了不让表格显示科学计数法或者其他格式
for(let i = 0 ; i < jsonData.length ; i++ ){
for(let item in jsonData[i]){
str+=`${jsonData[i][item] + '\t'},`;
}
str+='\n';
}
//encodeURIComponent解决中文乱码
let uri = 'data:text/csv;charset=utf-8,\ufeff' + encodeURIComponent(str);
//通过创建a标签实现
var link = document.createElement("a");
link.href = uri;
//对下载的文件命名
link.download = "json数据表.csv";
document.body.appendChild(link);
link.click();
document.body.removeChild(link);