不吃

导航

个人技术总结

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. 总结

事实证明一个插件之所以广受欢迎不是没有道理的,官方总是为你准备好了各种解决方案,还是要多去自己查阅官方文档。

5.参考文献

官网

官网github

posted on 2020-06-25 17:44  不吃  阅读(334)  评论(0编辑  收藏  举报