开发者社区> 关爱单身狗> 正文
阿里云
为了无法计算的价值
打开APP
阿里云APP内打开

handsontable结合js-xlsx实现可编辑xlsx导入导出功能(参考)

简介: 详细说明查看官网文档: handsontable 官网:https://handsontable.com/ handsontable github:https://github.
+关注继续查看

详细说明查看官网文档:

img_ad8944ec67d68d009ccba69dcddb44a0.gif
demo

示例页面

<!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">
    <title>Document</title>
    <!--引入相关文件-->
    <link rel="stylesheet" type="text/css" href="https://cdn.bootcss.com/handsontable/0.32.0/handsontable.full.css" />
    <script src="https://cdn.bootcss.com/handsontable/0.32.0/handsontable.full.min.js"></script>
    <script src="http://oss.sheetjs.com/js-xlsx/xlsx.full.min.js"></script>
    <script>
        //----工具类 开始----
        var utl = {};
        utl.Binary = {
            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;
            },
            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;
            }
        }
        utl.XLSX = {
            wb: null,
            rABS: false,
            import(f, c) {//导入根据文件
                this.wb = null;
                var reader = new FileReader();
                reader.onload = function (e) {
                    var data = e.target.result;
                    if (utl.XLSX.rABS) {
                        utl.XLSX.wb = XLSX.read(btoa(utl.Binary.fixdata(data)), {//手动转化
                            type: 'base64'
                        });
                    } else {
                        utl.XLSX.wb = XLSX.read(data, {
                            type: 'binary'
                        });
                    }
                    if (c && typeof (c)) {
                        c();
                    }
                };
                if (utl.XLSX.rABS) {
                    reader.readAsArrayBuffer(f);
                } else {
                    reader.readAsBinaryString(f);
                }
            },
            onImport(obj, c) {//导入根据 input file标签
                if (!obj.files) {
                    return;
                }
                this.import(obj.files[0], c);
            },
            getSheetsByIndex(index = 0) {//获取数据根据Sheets索引
                return XLSX.utils.sheet_to_json(this.wb.Sheets[this.wb.SheetNames[index]]);
            },
            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
            },
            export(json, title, type) {//导出
                var keyMap = [];//获取keys
                for (k in json[0]) {
                    keyMap.push(k);
                }
                var tmpdata = [];//用来保存转换好的json 
                json.map((v, i) => keyMap.map((k, j) => Object.assign({}, {
                    v: v[k],
                    position: (j > 25 ? utl.XLSX.getCharCol(j) : String.fromCharCode(65 + j)) + (i + 1)
                }))).reduce((prev, next) => prev.concat(next)).forEach((v, i) => tmpdata[v.position] = {
                    v: v.v
                });
                var outputPos = Object.keys(tmpdata); //设置区域,比如表格从A1到D10
                var tmpWB = new Object();
                title = title ? title : "mySheet";
                tmpWB.SheetNames = [title];
                tmpWB.Sheets = {};
                tmpWB.Sheets[title] = Object.assign({}, tmpdata, //内容
                    {
                        '!ref': outputPos[0] + ':' + outputPos[outputPos.length - 1] //设置填充区域
                    });
                return new Blob([utl.Binary.s2ab(XLSX.write(tmpWB,
                    { bookType: (type == undefined ? 'xlsx' : type), bookSST: false, type: 'binary' }//这里的数据是用来定义导出的格式类型
                ))], { type: "" }); //创建二进制对象写入转换好的字节流
            },
            onExport(json, title, type) {//直接下载
                utl.Download.byObj(this.export(json, title, type), "下载.xlsx");
            }
        };
        utl.Download = {
            byURL(url, fileName) {//动态下载
                var tmpa = document.createElement("a");
                tmpa.download = fileName || "下载";
                tmpa.href = url; //绑定a标签
                tmpa.click(); //模拟点击实现下载
            },
            byObj(obj, fileName) {//内存二进制数据下载
                this.byURL(URL.createObjectURL(obj), fileName);
                setTimeout(function () { //延时释放
                    URL.revokeObjectURL(obj); //用URL.revokeObjectURL()来释放这个object URL
                }, 100);
            }
        }
        utl.Object = {
            reverse(obj) {//对象键值倒转
                var o = new Object();
                for (var k in obj) {
                    o[obj[k]] = k;
                }
                return o;
            },
            deepCopy() {//深拷贝
                let temp = obj.constructor === Array ? [] : {}
                for (let val in obj) {
                    temp[val] = typeof obj[val] == 'object' ? deepCopy(obj[val]) : obj[val];
                }
                return temp;
            },
            copyJson(o) { return JSON.parse(JSON.stringify(o)); }//拷贝JSON格式
        }
        //----工具类 结束----
    </script>
    <style>
        * {
            margin: 0;
            padding: 0;
        }

        body {
            font-family: Helvetica Neue, Helvetica, PingFang SC, Hiragino Sans GB, Microsoft YaHei, SimSun, sans-serif;
            overflow: auto;
            font-weight: 400;
            -webkit-font-smoothing: antialiased;
        }
    </style>
    <script>
        //---导入头信息 开始--
        const xHred = {
            "ID": "id",
            "账号": "uname",
            "用户名": "rname",
            "密码": "pwd",
            "性别": "sex",
            "出生日期": "birth",
            "电话": "mobPhone"
        };

        const filterVal = {//<=====值转化 
            "pwd":function(value){
                return "假装 被加密了"
            },
            "sex": function (key) {
                key = { "男": 0, "女": 1, "": 0, undefined: 0 }[key];
                return key ? key : 0;
            }
        };
        //---导入头信息 结束--
    </script>
</head>

<body>
    <script>
        //------导入导出 -----
        function impt(emt) {//<===导入
            utl.XLSX.onImport(emt, function () {
                var rt = utl.XLSX.getSheetsByIndex();//<===默认获取Sheet1
                var tmp = [];
                rt.forEach(function (value, index, array) {
                    var t = new Object();
                    for (var k in value) {
                        t[xHred[k]] = value[k];
                    }
                    tmp.push(t);
                });
                hot.loadData(tmp);//<====将读取完成数据显示到handsontable
            });
        }
        function down() {//<===下载导出数据
            var d = utl.Object.copyJson(hot.getSourceData());//<=====读取handsontable的数据
            d.unshift(utl.Object.reverse(xHred));//<====追加到列头
            utl.XLSX.onExport(d);//<====导出
        }
        function showData() {//<====获取真实数据
            var tmp = [];
            hot.getSourceData().forEach(function (value, index, array) {
                var t = new Object();
                for (var k in value) {
                    t[k] = filterVal[k] ? filterVal[k](value[k]) : value[k];//<====将xlsx数据转为实际需要的值
                }
                tmp.push(t);
            });
            /*
            *更多规则自己定义吧
            */
            alert(JSON.stringify(tmp));
            window.open("data:text/html;charset=utf-8,"+JSON.stringify(tmp));
            console.log(tmp);
            return tmp;
        }
        //------导入导出 -----
    </script>
    数据量大于1万条时,文件解析可能需要10秒以上读取,当然这也跟你当前使用电脑性能有关系
    <input type="file" onchange="impt(this)" />
    <input type="button" value="下载" onclick="down()" />
    <input type="button" value="查看结果数据数据" onclick="showData()" />
    <div id="hot"></div>
    <script>
        //----handsontable 初始化 开始------
        var hotElement = document.querySelector('#hot');//<====绑定handsontable初始化div 
        var colHeaders = [];//<===handsontable列头显示值
        var cols = [];//<====handsontable列头显示值对应的实际字段与其他配置
        for (var key in xHred) {
            cols.push({ data: xHred[key] });
            colHeaders.push(key);
        }
        var hotSettings = {//<====handsontable的配置
            colHeaders: colHeaders,//当值为true时显示列头,当值为数组时,列头为数组的值
            data: [],//数据源
            columns: cols,//列具体配置 
            // width: 906,
            autoWrapRow: true,
            // height: 641,
            // maxRows: 22,
            minRows: 1,
            // currentRowClassName:当前行样式的名称,
            // currentColClassName:当前列样式的名称,
            manualColumnResize: true,//当值为true时,允许拖动,当为false时禁止拖动
            manualRowResize: true,//当值为true时,允许拖动,当为false时禁止拖动
            stretchH: "all",     //last:延伸最后一列,all:延伸所有列,none默认不延伸。
            manualColumnMove: true,// 当值为true时,列可拖拽移动到指定列
            manualRowMove: true,// 当值为true时,行可拖拽至指定行
            rowHeaders: true, //当值为true时显示行头,当值为数组时,行头为数组的值
            columnSorting: true,//允许排序
            sortIndicator: true,
            contextMenu: true,//显示右键菜单
            autoColumnSize: true //当值为true且列宽未设置时,自适应列大小
        };
        var hot = new Handsontable(hotElement, hotSettings);
    //----handsontable 初始化 完成------
    </script>
</body>

</html>

版权声明:本文内容由阿里云实名注册用户自发贡献,版权归原作者所有,阿里云开发者社区不拥有其著作权,亦不承担相应法律责任。具体规则请查看《阿里云开发者社区用户服务协议》和《阿里云开发者社区知识产权保护指引》。如果您发现本社区中有涉嫌抄袭的内容,填写侵权投诉表单进行举报,一经查实,本社区将立刻删除涉嫌侵权内容。

相关文章
Handsontable - 汉化包(Vue 项目)
Handsontable - 汉化包(Vue 项目)
61 0
不敢相信!JDK 8 的 HashMap 依然会死循环…
是否你听说过JDK8之后HashMap已经解决的扩容死循环的问题,虽然HashMap依然说线程不安全,但是不会造成服务器load飙升的问题。
42 0
2017广东工业大学程序设计竞赛初赛 题解&源码(A,水 B,数学 C,二分 D,枚举 E,dp F,思维题 G,字符串处理 H,枚举)
Problem A: An easy problem Description       Peter Manson owned a small house in an obscure street.
950 0
【pom.xml 依赖】使用net.sf.json-lib-2.4-jdk15.jar所需要的其他依赖架包 以及其一直在pom.xml报错的问题
特此声明: json-lib-2.4-jdk15.jar仅它本身不够,必须如下的几个依赖架包都有才能使用!!! 首先 将.json-lib-2.4-jdk15.jar以及其相关的依赖架包的正确配置给出【pom.
3468 0
Following unknown configure options were used:--enable-fpm
执行cd   php-5.2.13安装时候 ./configure --prefix=/usr/local/php/ --with-config-file-path=/usr/local/php/etc/ --with-mysql=/usr/local/mysql/ --with-libxml-dir=/usr/local/libxml2/ --with-jpeg-dir=/usr/lo
1460 0
Windows下创建PXE网络安装Linux[Redhat AS5.5]IBM X3650
版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/zergskj/article/details/6303442 IBM x3650 M3服务器未配置DVD光驱,但提供了PXE网络方式安装,我们便通过一台普通PC机搭建PXE网络,安装Linux操作系统。
1376 0
GNU C library dynamic linker $ORIGIN expansion Vulnerability
# Create a directory in /tmp we can control. $ mkdir /tmp/exploit    # Li...
711 0
+关注
关爱单身狗
简书:https://www.jianshu.com/u/f19e29243ff6
103
文章
0
问答
文章排行榜
最热
最新
相关电子书
更多
低代码开发师(初级)实战教程
立即下载
阿里巴巴DevOps 最佳实践手册
立即下载
冬季实战营第三期:MySQL数据库进阶实战
立即下载