在网上找了很多方法,主要有三种,个人觉得第三种好用一些。
方法一:
通过tr、td标签等,将table输出到表格上实现,这种方法的弊端在于输出的是伪excel,虽说生成xls为后缀的文件,但文件形式上还是html,代码如下:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Document</title>
</head>
<body>
<p style="font-size: 20px;color: red;">使用table标签方式将json导出xls文件</p>
<button onclick='tableToExcel()'>导出</button>
<script>
function tableToExcel() {
//要导出的json数据
var jsonData = [
{
name: '路人甲',
phone: '123456',
email: '123@123456.com'
},
{
name: '炮灰乙',
phone: '123456',
email: '123@123456.com'
},
{
name: '土匪丙',
phone: '123456',
email: '123@123456.com'
},
{
name: '流氓丁',
phone: '123456',
email: '123@123456.com'
},
]
//列标题
var str = '<tr><td>姓名</td><td>电话</td><td>邮箱</td></tr>';
//循环遍历,每行加入tr标签,每个单元格加td标签
for (let i = 0; i < jsonData.length; i++) {
str += '<tr>';
for (let item in jsonData[i]) {
//增加\t为了不让表格显示科学计数法或者其他格式
str += `<td>${jsonData[i][item] + '\t'}</td>`;
}
str += '</tr>';
}
//Worksheet名
var worksheet = 'Sheet1'
var uri = 'data:application/vnd.ms-excel;base64,';
//下载的表格模板数据
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><!--[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>${str}</table></body></html>`;
//下载模板
window.location.href = uri + base64(template)
}
//输出base64编码
function base64(s) { return window.btoa(unescape(encodeURIComponent(s))) }
</script>
</body>
</html>
方法二:
通过将json遍历进行字符串拼接,将字符串输出到csv文件,输出的文件不会再是html类型的文件而是真正的csv文件,代码如下:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Document</title>
</head>
<body>
<p style="font-size: 20px;color: red;">使用a标签方式将json导出csv文件</p>
<button onclick='tableToExcel()'>导出</button>
<script>
function tableToExcel() {
//要导出的json数据
var jsonData = [
{
name: '路人甲',
phone: '123456789',
email: '000@123456.com'
},
{
name: '炮灰乙',
phone: '123456789',
email: '000@123456.com'
},
{
name: '土匪丙',
phone: '123456789',
email: '000@123456.com'
},
{
name: '流氓丁',
phone: '123456789',
email: '000@123456.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);
}
</script>
</body>
</html>
方法三:
先生成csv,将csv转sheet对象,将一个sheet转成最终的excel文件的blob对象,然后利用URL.createObjectURL下载(代码中有几个函数好像没有用到,但是能实现功能,我就不管了,有兴趣的可以简洁一下。此方法依赖于jquery.js(https://jquery.com/download/)和xlsx.core.min.js(https://download.csdn.net/download/dylbb818/9595652)。代码如下:
<!DOCTYPE html>
<html lang="zh-cn">
<head>
<meta charset="UTF-8">
<title>JS读取和导出excel示例</title>
<meta name="description" content="使用sheetjs读取和导出excel示例">
<style type="text/css">
table {
border-collapse: collapse;
}
th,
td {
border: solid 1px #6D6D6D;
padding: 5px 10px;
}
.mt-sm {
margin-top: 8px;
}
body {
background: #f4f4f4;
padding: 0;
margin: 0;
}
.container {
width: 1024px;
margin: 0 auto;
background: #fff;
padding: 20px;
min-height: 100vh;
}
</style>
</head>
<body>
<div class="container">
<h2>导出带单元格合并的excel</h2>
<input type="button" value="导出" onclick="exportSpecialExcel()" />
</div>
<script type="text/javascript" src="./lib/jquery.min.js"></script>
<script type="text/javascript" src="./lib/xlsx.core.min.js"></script>
<script type="text/javascript">
var obj = {name:'xixi',sex:'女'};
var arr = [{name:'haha',sex:'男'},{name:'xixi',sex:'女'}];
var arr2 = ['haha','xixi'];
var str;
for(let i = 0;i<arr2.length;i++){
str = arr2[i];
}
var st1 = JSON.stringify(arr);
var st2 = JSON.stringify(obj);
// 读取本地excel文件 n
function readWorkbookFromLocalFile(file, callback) {
var reader = new FileReader();
reader.onload = function (e) {
var data = e.target.result;
var workbook = XLSX.read(data, { type: 'binary' });
if (callback) callback(workbook);
};
reader.readAsBinaryString(file);
}
// 读取 excel文件
function outputWorkbook(workbook) {
var sheetNames = workbook.SheetNames; // 工作表名称集合
sheetNames.forEach(name => {
var worksheet = workbook.Sheets[name]; // 只能通过工作表名称来获取指定工作表
for (var key in worksheet) {
// v是读取单元格的原始值
console.log(key, key[0] === '!' ? worksheet[key] : worksheet[key].v);
}
});
}
// 将csv转换成表格
function csv2table(csv) {
var html = '<table>';
var rows = csv.split('\n');
rows.pop(); // 最后一行没用的
rows.forEach(function (row, idx) {
var columns = row.split(',');
columns.unshift(idx + 1); // 添加行索引
if (idx == 0) { // 添加列索引
html += '<tr>';
for (var i = 0; i < columns.length; i++) {
html += '<th>' + (i == 0 ? '' : String.fromCharCode(65 + i - 1)) + '</th>';
}
html += '</tr>';
}
html += '<tr>';
columns.forEach(function (column) {
html += '<td>' + column + '</td>';
});
html += '</tr>';
});
html += '</table>';
return html;
}
function table2csv(table) {
var csv = [];
$(table).find('tr').each(function () {
var temp = [];
$(this).find('td').each(function () {
temp.push($(this).html());
})
temp.shift(); // 移除第一个
csv.push(temp.join(','));
});
csv.shift();
return csv.join('\n');
}
// csv转sheet对象
function csv2sheet(csv) {
var sheet = {}; // 将要生成的sheet
csv = csv.split('\n');
csv.forEach(function (row, i) {
row = row.split(',');
if (i == 0) sheet['!ref'] = 'A1:' + String.fromCharCode(65 + row.length - 1) + (csv.length - 1);
row.forEach(function (col, j) {
sheet[String.fromCharCode(65 + j) + (i + 1)] = { v: col };
});
});
return sheet;
}
// 将一个sheet转成最终的excel文件的blob对象,然后利用URL.createObjectURL下载
function sheet2blob(sheet, sheetName) {
sheetName = sheetName || 'sheet1';
var workbook = {
SheetNames: [sheetName],
Sheets: {}
};
workbook.Sheets[sheetName] = sheet;
// 生成excel的配置项
var wopts = {
bookType: 'xlsx', // 要生成的文件类型
bookSST: false, // 是否生成Shared String Table,官方解释是,如果开启生成速度会下降,但在低版本IOS设备上有更好的兼容性
type: 'binary'
};
var wbout = XLSX.write(workbook, wopts);
var blob = new Blob([s2ab(wbout)], { type: "application/octet-stream" });
// 字符串转ArrayBuffer
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;
}
return blob;
}
/**
* 通用的打开下载对话框方法,没有测试过具体兼容性
* @param url 下载地址,也可以是一个blob对象,必选
* @param saveName 保存文件名,可选
*/
function openDownloadDialog(url, saveName) {
if (typeof url == 'object' && url instanceof Blob) {
url = URL.createObjectURL(url); // 创建blob地址
}
var aLink = document.createElement('a');
aLink.href = url;
aLink.download = saveName || ''; // HTML5新增的属性,指定保存文件名,可以不要后缀,注意,file:///模式下不会生效
var event;
if (window.MouseEvent) event = new MouseEvent('click');
else {
event = document.createEvent('MouseEvents');
event.initMouseEvent('click', true, false, window, 0, 0, 0, 0, 0, false, false, false, false, 0, null);
}
aLink.dispatchEvent(event);
}
function loadRemoteFile(url) {
readWorkbookFromRemoteFile(url, function (workbook) {
readWorkbook(workbook);
});
}
function exportExcel() {
var csv = table2csv($('#result table')[0]);
var sheet = csv2sheet(csv);
var blob = sheet2blob(sheet);
openDownloadDialog(blob, '导出.xlsx');
}
function exportSpecialExcel() {
var aoa = [
['主要信息', null, null, '其它信息'], // 特别注意合并的地方后面预留2个null
['姓名', '性别', '年龄', '注册时间'],
['张三', '男', 18, new Date()],
['李四', '女', 22, new Date()]
];
var sheet = XLSX.utils.aoa_to_sheet(aoa);
sheet['!merges'] = [
// 设置A1-C1的单元格合并
{ s: { r: 0, c: 0 }, e: { r: 0, c: 2 } }
];
openDownloadDialog(sheet2blob(sheet), '单元格合并示例.xlsx');
}
</script>
</body>
</html>