个人技术总结
1. 技术概述
使用js-xlsx实现纯前端导入excel表格
2.技术详述
出于自动化记账的需求,此次项目要求能够完成对用户的excel账单的导入和读取,出于分工和功能划分的考虑,最后决定由前端web来实现这个功能。
通过在网上查找了几种纯前端实现excel表格导入的实现方法之后,最后我选择了js-xlsx来实现。
由SheetJS出品的js-xlsx是一款非常方便的只需要纯JS即可读取和导出excel的工具库,功能强大,支持格式众多,支持xls、xlsx、ods等十几种格式。官方github里提供了各种电子表格格式的解析器和编写器,需要jquery依赖,通过Pure-JS cleanroom实现,强调解析和编写的健壮性,跨格式功能与统一的JS表示兼容,以及ES3/ES5浏览器与IE6的兼容性。
3.技术使用中遇到的问题和解决过程。
js-xlsx导入CSV文件的时候会遇到中文乱码的问题,以下是使用官方提供的转换测试网站结果:

可以看到其中的中文全部变成了乱码。
在网上搜索相关问题,查阅相关资料之后发现这是由于文件的编码不对造成的,通过记事本打开,将excel文件另存为,并将编码改为带有BOM的UTF-8即可。

当然用户是上帝,不可能让用户来做转码工作,经过查找,发现官方是有一个叫https://github.com/sheetjs/js-codepage的库来专门处理文件编码的,以下是导入功能的代码:
<!DOCTYPE html>
<html>
<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">
<script src="http://oss.sheetjs.com/js-xlsx/xlsx.core.min.js"></script>
<script src="./js-codepage-master/dist/cptable.full.js"></script>
<!-- 引入库文件 -->
</head>
<body>
<input type="file" onchange="importf(this)" />
<div id="demo"></div>
<script>
var wb;//读取完成的数据
var rABS = false; //是否将文件读取为二进制字符串
var isCSV;
function importf(obj) {//导入
if (!obj.files) return;
var f = obj.files[0];
var reader = new FileReader();
reader.onload = function (e) {
var data = e.target.result;
wb = null;
if (isCSV) {
data = rABS ? new Uint8Array(data) : data;
var str = cptable.utils.decode(936, data);
wb = XLSX.read(str, { type: "string" });
}
if (!wb) {
wb = rABS ? XLSX.read(btoa(fixdata(data)), { type: 'base64' }) : XLSX.read(data, { type: 'binary' });
}
//wb.SheetNames[0]是获取Sheets中第一个Sheet的名字
//wb.Sheets[Sheet名]获取第一个Sheet的数据
document.getElementById("demo").innerHTML = JSON.stringify(XLSX.utils.sheet_to_json(wb.Sheets[wb.SheetNames[0]]));
};
isCSV = f.name.split(".").reverse()[0] == "csv";//判断是否是 CSV
if (rABS) {
reader.readAsArrayBuffer(f);
} else {
reader.readAsBinaryString(f);
}
obj.value = "";
}
function fixdata(data) { //文件流转BinaryString
var o = "",
l = 0,
w = 10240;
for (; l < data.byteLength / w; ++l) o += String.fromCharCode.apply(null, new Uint8Array(data.slice(l * w, l * w + w)));
o += String.fromCharCode.apply(null, new Uint8Array(data.slice(l * w)));
return o;
}
</script>
</body>
</html>
4. 总结
事实证明一个插件之所以广受欢迎不是没有道理的,官方总是为你准备好了各种解决方案,还是要多去自己查阅官方文档。
浙公网安备 33010602011771号