js-xlsx导出自定义合并列头实现思路

简介: 前两天有几个小伙伴找我问我关于js-xlsx导出时列头合并单元格的问题,因为小伙伴需要导出的效果都不太一样,所以我在这里对其解决思路简单的给讲一下,大家根据实际情况自行修改。
img_c7b30e9ace538d38eeec33b7a2a660df.png

前两天有几个小伙伴找我问我关于js-xlsx导出时列头合并单元格的问题,因为小伙伴需要导出的效果都不太一样,所以我在这里对其解决思路简单的给讲一下,大家根据实际情况自行修改。

1.通过导入获取列头JSON数据

其实合并单元格我早在文章《纯前端利用 js-xlsx 之合并单元格(3)》中有讲到过可能当时将的比较简单所以这次我们讲下比较复杂的情况.。

首先我先创建一个xlsx文件里面只存放我的列头数据比如:


img_f110681e51e0e7d931a389010d43768d.png

导入示例代码:

<!DOCTYPE html>
<html>
<head>
    <meta charset="UTF-8">
    <title></title>
    <script src="xlsx.core.min.js"></script>
</head>
<body>
    <input type="file" onchange="importf(this)" />
    <div id="demo"></div>
    <script>
        var WB;
        var rABS = true; //是否将文件读取为二进制字符串
        function importf(obj) {//导入
            if (!obj.files) { return; }
            var f = obj.files[0];
            {
                var reader = new FileReader();
                var name = f.name;
                reader.onload = function (e) {
                    var data = e.target.result;
                    WB = XLSX.read(data, { type: 'binary' });
                    document.getElementById("demo").innerHTML = JSON.stringify(WB.Sheets[WB.SheetNames[0]]);
                };
                if (rABS) reader.readAsBinaryString(f);
                else reader.readAsArrayBuffer(f);
            }
        }
    </script>
</body>
</html>

可以看到导出结果:


img_9d8b4ce385eb57a4d7e550f82755e9f4.png

整理后我们得到关键数据:

{ "A1": { "v": "日期" }, "B1": { "v": "配送信息" }, "C1": { "v": "" }, "D1": { "v": "" }, "E1": { "v": "" }, "F1": { "v": "" }, "A2": { "v": "" }, "B2": { "v": "姓名" }, "C2": { "v": "地址" }, "D2": { "v": "" }, "E2": { "v": "" }, "F2": { "v": "" }, "A3": { "v": "" }, "B3": { "v": "" }, "C3": { "v": "省份" }, "D3": { "v": "市区" }, "E3": { "v": "地址" }, "F3": { "v": "邮编" }, "!merges": [{ "s": { "c": 1, "r": 0 }, "e": { "c": 5, "r": 0 } }, { "s": { "c": 2, "r": 1 }, "e": { "c": 5, "r": 1 } }, { "s": { "c": 0, "r": 0 }, "e": { "c": 0, "r": 2 } }, { "s": { "c": 1, "r": 1 }, "e": { "c": 1, "r": 2 } }] }

2.尝试导出列头

代码中的xlsx.utils.min.js相关示例可查看文章《js-xlsx工具类库 xlsxUtils 使用示例

代码示例:

<!DOCTYPE html>
<html>
<head>
    <meta charset="UTF-8">
    <title></title>
    <script src="xlsx.core.min.js"></script>
    <script src="xlsx.utils.min.js"></script>
    <script>
        function saveAs(obj, fileName) {//当然可以自定义简单的下载文件实现方式 
            var tmpa = document.createElement("a");
            tmpa.download = fileName || "下载";
            tmpa.href = URL.createObjectURL(obj); //绑定a标签
            tmpa.click(); //模拟点击实现下载
            setTimeout(function () { //延时释放
                URL.revokeObjectURL(obj); //用URL.revokeObjectURL()来释放这个object URL
            }, 100);
        } 
    </script>
</head>

<body>
    <input type="button" onclick="downloadExl()" value="导出" />
    <div id="demo"></div>
    <script>
        var head = { "A1": { "v": "日期" }, "B1": { "v": "配送信息" }, "C1": { "v": "" }, "D1": { "v": "" }, "E1": { "v": "" }, "F1": { "v": "" }, "A2": { "v": "" }, "B2": { "v": "姓名" }, "C2": { "v": "地址" }, "D2": { "v": "" }, "E2": { "v": "" }, "F2": { "v": "" }, "A3": { "v": "" }, "B3": { "v": "" }, "C3": { "v": "省份" }, "D3": { "v": "市区" }, "E3": { "v": "地址" }, "F3": { "v": "邮编" }, "!merges": [{ "s": { "c": 1, "r": 0 }, "e": { "c": 5, "r": 0 } }, { "s": { "c": 2, "r": 1 }, "e": { "c": 5, "r": 1 } }, { "s": { "c": 0, "r": 0 }, "e": { "c": 0, "r": 2 } }, { "s": { "c": 1, "r": 1 }, "e": { "c": 1, "r": 2 } }] };
        function downloadExl() {
            var wb = xlsxUtils.format2WB(head, undefined, undefined, "A1:F3");
            saveAs(xlsxUtils.format2Blob(wb), "这里是下载的文件名.xlsx");
        }
    </script>
</body>
</html>

成功导出的效果:


img_8c3ef54ce0adff9b442e02065dae11d8.png

3.导出数据与自定义列头

一般情况下我们导出的JSON数据是这样的:

 [{
    "riqi": "2016/5/1",
    "ming": "关爱单身狗",
    "sheng": "上海",
    "shi": "普陀区",
    "dizhi": "上海市普陀区金沙江路 1518 弄",
    "youbian": "200333"
}, {
    "riqi": "2016/5/2",
    "ming": "关爱单身狗",
    "sheng": "上海",
    "shi": "普陀区",
    "dizhi": "上海市普陀区金沙江路 1518 弄",
    "youbian": "200333"
}, {
    "riqi": "2016/5/3",
    "ming": "关爱单身狗",
    "sheng": "上海",
    "shi": "普陀区",
    "dizhi": "上海市普陀区金沙江路 1518 弄",
    "youbian": "200333"
}, {
    "riqi": "2016/5/4",
    "ming": "关爱单身狗",
    "sheng": "上海",
    "shi": "普陀区",
    "dizhi": "上海市普陀区金沙江路 1518 弄",
    "youbian": "200333"
}, {
    "riqi": "2016/5/5",
    "ming": "关爱单身狗",
    "sheng": "上海",
    "shi": "普陀区",
    "dizhi": "上海市普陀区金沙江路 1518 弄",
    "youbian": "200333"
}, {
    "riqi": "2016/5/6",
    "ming": "关爱单身狗",
    "sheng": "上海",
    "shi": "普陀区",
    "dizhi": "上海市普陀区金沙江路 1518 弄",
    "youbian": "200333"
}, {
    "riqi": "2016/5/7",
    "ming": "关爱单身狗",
    "sheng": "上海",
    "shi": "普陀区",
    "dizhi": "上海市普陀区金沙江路 1518 弄",
    "youbian": "200333"
}]

那好,只要将数据和列头的json数据进行整合导出就行了,不过注意一点就是因为列头数据跟导出数据列可能无法根据英文字段对应,所以我们需要手动声明顺序数组去匹配对应:

<!DOCTYPE html>
<html>

<head>
    <meta charset="UTF-8">
    <title></title>
    <script src="xlsx.core.min.js"></script>
    <script src="xlsx.utils.min.js"></script>
    <script>
        function saveAs(obj, fileName) {//当然可以自定义简单的下载文件实现方式 
            var tmpa = document.createElement("a");
            tmpa.download = fileName || "下载";
            tmpa.href = URL.createObjectURL(obj); //绑定a标签
            tmpa.click(); //模拟点击实现下载
            setTimeout(function () { //延时释放
                URL.revokeObjectURL(obj); //用URL.revokeObjectURL()来释放这个object URL
            }, 100);
        } 
    </script>
    <script>
        var Data = [{ "riqi": "2016/5/1", "ming": "关爱单身狗", "sheng": "上海", "shi": "普陀区", "dizhi": "上海市普陀区金沙江路 1518 弄", "youbian": "200333" }, { "riqi": "2016/5/2", "ming": "关爱单身狗", "sheng": "上海", "shi": "普陀区", "dizhi": "上海市普陀区金沙江路 1518 弄", "youbian": "200333" }, { "riqi": "2016/5/3", "ming": "关爱单身狗", "sheng": "上海", "shi": "普陀区", "dizhi": "上海市普陀区金沙江路 1518 弄", "youbian": "200333" }, { "riqi": "2016/5/4", "ming": "关爱单身狗", "sheng": "上海", "shi": "普陀区", "dizhi": "上海市普陀区金沙江路 1518 弄", "youbian": "200333" }, { "riqi": "2016/5/5", "ming": "关爱单身狗", "sheng": "上海", "shi": "普陀区", "dizhi": "上海市普陀区金沙江路 1518 弄", "youbian": "200333" }, { "riqi": "2016/5/6", "ming": "关爱单身狗", "sheng": "上海", "shi": "普陀区", "dizhi": "上海市普陀区金沙江路 1518 弄", "youbian": "200333" }, { "riqi": "2016/5/7", "ming": "关爱单身狗", "sheng": "上海", "shi": "普陀区", "dizhi": "上海市普陀区金沙江路 1518 弄", "youbian": "200333" }];
    </script>
</head>

<body>
    <input type="button" onclick="downloadExl()" value="导出" /> 
    <script>
        var head = { "A1": { "v": "日期" }, "B1": { "v": "配送信息" }, "C1": { "v": "" }, "D1": { "v": "" }, "E1": { "v": "" }, "F1": { "v": "" }, "A2": { "v": "" }, "B2": { "v": "姓名" }, "C2": { "v": "地址" }, "D2": { "v": "" }, "E2": { "v": "" }, "F2": { "v": "" }, "A3": { "v": "" }, "B3": { "v": "" }, "C3": { "v": "省份" }, "D3": { "v": "市区" }, "E3": { "v": "地址" }, "F3": { "v": "邮编" }, "!merges": [{ "s": { "c": 1, "r": 0 }, "e": { "c": 5, "r": 0 } }, { "s": { "c": 2, "r": 1 }, "e": { "c": 5, "r": 1 } }, { "s": { "c": 0, "r": 0 }, "e": { "c": 0, "r": 2 } }, { "s": { "c": 1, "r": 1 }, "e": { "c": 1, "r": 2 } }] };
        var keyMap = ["riqi", "ming", "sheng", "shi", "dizhi", "youbian"];//通过设置数组让导出时可以按顺序显示
        var wopts = { bookType: 'xlsx', bookSST: false, type: 'binary' };
        function downloadExl() {
            var data = xlsxUtils.format2Sheet(Data, 0, 3, keyMap);//偏移3行按keyMap顺序转换
            var dataKeys = Object.keys(data);
            for (var k in head) data[k] = head[k];//追加列头
            var wb = xlsxUtils.format2WB(data, undefined, undefined, "A1:" + dataKeys[dataKeys.length - 1]); 
            saveAs(xlsxUtils.format2Blob(wb), "这里是下载的文件名.xlsx");
        } 
    </script>
</body>
</html>

最终导出效果:


img_4333b63edcf9edbbf6461663958cf675.gif

在线查看

大概思路就是这样的,如果大家有跟好的办法可以在文章下面评论区留言或交流。

相关文章
|
6月前
|
开发框架 前端开发 JavaScript
在Vue&Element前端项目中,使用FastReport + pdf.js生成并展示自定义报表
在Vue&Element前端项目中,使用FastReport + pdf.js生成并展示自定义报表
|
8月前
|
前端开发 JavaScript
使用JavaScript实现复杂功能:构建一个自定义的拖拽功能
使用JavaScript实现复杂功能:构建一个自定义的拖拽功能
|
5月前
|
存储 前端开发 JavaScript
javascript 异常问题之为自定义异常提供丰富的上下文信息如何实现
javascript 异常问题之为自定义异常提供丰富的上下文信息如何实现
|
3月前
|
移动开发 JavaScript 前端开发
原生js如何获取dom元素的自定义属性
原生js如何获取dom元素的自定义属性
103 4
|
7月前
|
前端开发 JavaScript 数据处理
前端新手指南:如何解决JavaScript导出CSV文件不完整的问题
【6月更文挑战第4天】在JavaScript中处理CSV文件时,需要特别注意一些特殊字符,例如逗号、双引号、换行符等。这些字符可能会影响CSV文件的解析,导致数据错乱。
249 0
|
5月前
|
前端开发 微服务 API
微服务浪潮下的JSF革新:如何在分散式架构中构建统一而强大的Web界面
【8月更文挑战第31天】随着微服务架构的兴起,企业将应用拆分成小型、独立的服务以提高系统可维护性和可扩展性。本文探讨如何在微服务架构下构建和部署JavaServer Faces (JSF) 应用,通过RESTful服务实现前后端分离,提升灵活性和适应性。
71 1
|
5月前
|
前端开发 程序员
HTML+CSS+JavaScript制作动态七夕表白网页(含音乐+自定义文字)
一年一度的520情人节/七夕情人节/女朋友生日/程序员表白,是不是要给女朋友或者正在追求的妹子一点小惊喜呢,今天这篇博客就分享下前端代码如何实现HTML+CSS+JavaScript制作七夕表白网页(含音乐+自定义文字)。赶紧学会了,来制作属于我们程序员的浪漫吧!
168 0
|
6月前
|
JavaScript NoSQL Serverless
函数计算产品使用问题之如何创建一个自定义运行时并指定Node.js版本
阿里云Serverless 应用引擎(SAE)提供了完整的微服务应用生命周期管理能力,包括应用部署、服务治理、开发运维、资源管理等功能,并通过扩展功能支持多环境管理、API Gateway、事件驱动等高级应用场景,帮助企业快速构建、部署、运维和扩展微服务架构,实现Serverless化的应用部署与运维模式。以下是对SAE产品使用合集的概述,包括应用管理、服务治理、开发运维、资源管理等方面。
|
5月前
|
JavaScript 前端开发 数据安全/隐私保护
Vue.js 表单处理技巧大揭秘!v-model 与自定义验证综合运用,打造高效表单处理体验!
【8月更文挑战第31天】Vue.js 是一款备受欢迎的前端框架,其表单处理功能强大且灵活。v-model 指令可实现双向数据绑定,简化表单元素值与 Vue 实例数据的同步过程;结合自定义验证规则,则能确保用户输入数据符合特定要求。无论是简单的单字段校验还是复杂的多字段验证,Vue.js 均提供了简洁有效的解决方案,有效提升了表单处理效率及用户体验。通过综合运用 v-model 和自定义验证,开发者能够实时反馈错误信息并控制表单状态,从而增强应用的交互性与可靠性。
79 0
|
5月前
|
JavaScript PHP 开发者
PHP中的异常处理与自定义错误处理器构建高效Web应用:Node.js与Express框架实战指南
【8月更文挑战第27天】在PHP编程世界中,异常处理和错误管理是代码健壮性的关键。本文将深入探讨PHP的异常处理机制,并指导你如何创建自定义错误处理器,以便优雅地管理运行时错误。我们将一起学习如何使用try-catch块捕获异常,以及如何通过set_error_handler函数定制错误响应。准备好让你的代码变得更加可靠,同时提供更友好的错误信息给最终用户。