一、通过后端处理导出
1.) 后端响应头设置
前端若想下载一个根据查询参数生成的 excel 报表文件,需要后端设置请求内容的类型,具体设置如下:
response.reset();
response.setContentType(“application/vnd.ms-excel;charset=utf-8”); // 表明是 excel 类型
//response.setContentType(“application/octet-stream”); // 或设成通用二进制流类型
response.setHeader(“Content-Disposition”, “attachment;filename=test.xls”)); // 将请求的内容存为一个名为 test 的文件
2.) 前端相应的代码
正常情况下,用以下两种方法均可:
window.open(‘/url/download?param=xxx’)
window.location = ‘/url/download?param=xxx’ // 不加 href,是因为有些浏览器有兼容问题
但如果 window.open 是在一个 ajax 回调里执行,浏览器会被安全拦截,解决方案:
$.ajax({
….
success: function() {
var win = window.open()
win.location = ‘/url/download?param=xxx’
}
})
或直接用 window.location
$.ajax({
….
success: function() {
window.location = ‘/url/download?param=xxx’
}
})
二、前端直接将 json 数据处理成 excel 文件
具体完整代码如下:
<button onclick=’tableToExcel()’>json 导出 xls 文件 </button>
<script>
function tableToExcel() {
var jsonData = [{
name: ‘ 路人甲 ’,
phone: ‘123456’,
email: ‘123@123456.com’
}, {
name: ‘ 炮灰乙 ’,
phone: ‘123456’,
email: ‘123@123456.com’
}]
// 列标题
var table = ‘<tr><td> 姓名 </td><td> 电话 </td><td> 邮箱 </td></tr>’
// 循环遍历,每行加入 tr 标签,每个单元格加 td 标签
jsonData.forEach(function(item) {
table += ‘<tr>’;
for (let key in item) {
// 增加 t 为了不让表格显示科学计数法或者其他格式
table += `<td>${item[key] + ‘t’}</td>`
}
table += ‘</tr>’;
})
//Worksheet 名
var worksheet = ‘Sheet1’
// 下载的表格模板数据
var template = `<html xmlns:o=”urn:schemas-microsoft-com:office:office”
xmlns:x=”urn:schemas-microsoft-com:office:excel”
xmlns=”http://www.w3.org/TR/REC-html40″>
<head>
<meta http-equiv=”Content-Type” content=”text/html; charset=UTF-8″>
<!–[if gte mso 9]>
<xml>
<x:ExcelWorkbook>
<x:ExcelWorksheets>
<x:ExcelWorksheet>
<x:Name>${worksheet}</x:Name>
<x:WorksheetOptions>
<x:DisplayGridlines/>
</x:WorksheetOptions>
</x:ExcelWorksheet>
</x:ExcelWorksheets>
</x:ExcelWorkbook>
</xml>
<![endif]–>
</head>
<body>
<table>${table}</table>
</body>
</html>`
// 下载模板
window.location.href = ‘data:application/vnd.ms-excel;base64,’ + base64(template)
}
// 输出 base64 编码
function base64(s) {return window.btoa(unescape(encodeURIComponent(s))) }
</script>