纯前段实现报表完美导出为excel格式

  1. 相信大家在项目中难免会遇到一些关于数据导出的问题,今天就给大家带来一个相对简单的一种导出数据格式为excel格式的方法
  2. 首先,需要下载一个叫better-xlsx,的插件,以yarn 为例 ' yarn add better-xlsx --save '下载相关依赖包( npm 方式 ' npm i better-xlsx --save ')
  3. 新建一个html文件,引入如下文件
  4.  在页面定义一个按钮,用于点击导出数据,书写导出代码
  5. 首先需要创建一个excel文件

    let file = new xlsx.File()

    //创建一个sheet,如果有子表,还可以同样的方式创建子表

    let sheet = file.addSheet('sheet1');

  6. 创建行,创建单元格 ,给单元格赋值 let row = sheet.addRow()  let cell = row.addCell()

  7. 以下是完整代码,每一步的注释我都写了,就不在这里用文字在叙述一遍了,有不明白的欢迎大家留言.

    $(function () {
            $('#btn').click(function () {
                //首先创建一个xlsx文件
                let file = new xlsx.File()
                //创建一个sheet
                let sheet = file.addSheet('sheet1');
                let data = [
                    ['Auto', 200, 90, 'B2-C2'],
                    ['Entertainment', 200, 32, 'B3-C3'],
                    ['Food', 350, 205.75, 'B4-C4'],
                    ['Home', 300, 250, 'B5-C5'],
                    ['Medical', 100, 35, 'B6-C6'],
                    ['Personal Items', 300, 80, 'B7-C7'],
                    ['Travel', 500, 350, 'B8-C8'],
                    ['Utilities', 200, 100, 'B9-C9'],
                    ['Other', 50, 60, 'B10-C10']
                ];
                //创建sheet的头部行
                let header = sheet.addRow();
                //设置行高
                header.setHeightCM(0.8);
                let headers = ['张三', '李四', '王五', '张柳']
                headers.forEach(item => {
                    //创建头部行中的单元格
                    let hc = header.addCell();
                    //给每个单元格设置值
                    hc.value = item;
                    //设置文本在单元格内水平垂直居中
                    hc.style.align.h = 'center';
                    hc.style.align.v = 'center';
                    //设置字体颜色
                    hc.style.font.color = 'ffffffff';
                    //给每个单元格设置边框和填充颜色
                    border(hc, 0, 0, 1, 0)
                    fillColor(hc, 1)
                })
    
    
    
                data.forEach((item, index) => {
                    //根据数据,创建对应个数的行
                    let row = sheet.addRow();
                    row.setHeightCM(0.8);
                    //创建对应个数的单元格.并填充值
                    //col1
                    let cell1 = row.addCell();
                    cell1.value = item[0]
                    cell1.style.align.v = 'center';
                    cell1.style.align.h = 'center';
                    if (index === 0) {
                        border(cell1, 1, 1, 0, 0)
                    } else {
                        border(cell1, 0, 0, 0, 1)
                    }
                    fillColor(cell1, 2)
                    //col2
                    let cell2 = row.addCell();
                    cell2.value = item[1]
                    cell2.numFmt = '$#,##0.00';
                    cell2.cellType = 'TypeNumeric';
                    cell2.style.align.v = 'center';
                    cell2.style.align.h = 'center';
                    if (index === 0) {
                        border(cell2, 1, 1, 0, 0)
                    } else {
                        border(cell2, 0, 0, 0, 1)
                    }
                    fillColor(cell2, 3)
                    //col3
                    let cell3 = row.addCell();
                    cell3.value = item[2]
                    cell3.numFmt = '$#,##0.00';
                    cell3.cellType = 'TypeNumeric';
                    cell3.style.align.v = 'center';
                    cell3.style.align.h = 'center';
                    if (index === 0) {
                        border(cell3, 1, 1, 0, 0)
                    } else {
                        border(cell3, 0, 0, 0, 1)
                    }
                    fillColor(cell3, 4)
                    //col4
                    let cell4 = row.addCell();
                    cell4.formula = item[3]
                    cell4.numFmt = '$#,##0.00';
                    cell4.cellType = 'TypeFormula';
                    cell4.style.align.v = 'center';
                    cell4.style.align.h = 'center';
                    if (index === 0) {
                        border(cell4, 1, 1, 0, 0)
                    } else {
                        border(cell4, 0, 0, 0, 1)
                    }
                    fillColor(cell4, 4)
                })
                for (var i = 0; i < 4; i++) {
                    //设置每列的宽度
                    sheet.col(i).width = 20;
                }
                file.saveAs('blob').then(function (content) {
                    saveAs(content, "example.xlsx");
                });
            })
    
            //给单元格填充边框
            function border(cell, top, right, bottom, left) {
                const light = 'ffded9d4';
                const dark = 'ff7e6a54';
                cell.style.border.top = 'thin';
                cell.style.border.topColor = top ? dark : light;
                cell.style.border.left = 'thin';
                cell.style.border.leftColor = left ? dark : light;
                cell.style.border.bottom = 'thin';
                cell.style.border.bottomColor = bottom ? dark : light;
                cell.style.border.right = 'thin';
                cell.style.border.rightColor = right ? dark : light;
                // console.log(hc.style.border.topColor=0?2:3)   3
                // console.log(hc.style.border.leftColor=0?2:3)  3
                // console.log(hc.style.border.bottomColor=0?2:3)3
                // console.log(hc.style.border.rightColor=1?2:3) 2
                //也就是说给单元格设置边框颜色时,如果给边框赋值为0,则表示不给该边框赋值,转换为布尔值为false,反之则相反
            }
            //给单元格填充背景,前景色
            function fillColor(cell, type) {
                type = type || 0;
                let colors = ['ffffffff', 'ffa2917d', 'ffe4e2de', 'fffff8df', 'fff1eeec']
                //  0: white ,1: header, 2: first col, 3: second col, 4: gray,
                cell.style.fill.patternType = 'solid';
                cell.style.fill.fgColor = colors[type];
                cell.style.fill.bgColor = 'ffffffff';
            }
    
        })

     

  8. 最后附上该插件文档地址    https://d-band.github.io/better-xlsx/class/src/cell.js~Cell.html

效果图 

10.附上一个带多个sheet页的案例

<!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>
    <script type="text/javascript" src="./node_modules/jszip/dist/jszip.min.js"></script>
    <script type="text/javascript" src="./node_modules/better-xlsx/dist/xlsx.js"></script>
    <script type="text/javascript" src="./node_modules/jszip/vendor/FileSaver.js"></script>
    <script src="./node_modules/jquery/dist/jquery.min.js"></script>
</head>

<body>
    <div style="margin:40 auto;position: relative">
        <span style="display:block;width:80px;height: 40px;line-height: 40px;background-color: #0094ff;position: absolutez;color: #fff;text-align:center;cursor: pointer"
            id="btn">导出报表</span>
    </div>
</body>
<script>
    $(function () {
        let data = [{
            'keyColumn': '姓名',
            'mainID': 'UUID001',
            '姓名': '张三',
            '性别': '男',
            '班级': '高三( 1) 班',
            'children': [{
                    'tname': '课程',
                    'dataList': [{
                        'reMainID': 'UUID001',
                        '课程': '语文',
                        '老师': '张老师',
                        '分数': 89
                    }, {
                        'reMainID': 'UUID001',
                        '课程': '数学',
                        '老师': '王老师',
                        '分数': 92
                    }, {
                        'reMainID': 'UUID001',
                        '课程': '英语',
                        '老师': '李老师',
                        '分数': 93
                    }]
                },
                {
                    'tname': '爱好',
                    'dataList': [{
                        'reMainID': 'UUID001',
                        '爱好': '足球',
                        '活动': '比赛',
                        '时间': '7 月1日'
                    }, {
                        'reMainID': 'UUID001',
                        '爱好': '跑步',
                        '活动': '马拉松',
                        '时间': '2 月4日'
                    }]
                }
            ]
        }, {
            'keyColumn': '姓名',
            'mainID': 'UUID002',
            '姓名': '李四',
            '性别': '女',
            '班级': '高三(15) 班',
            'children': [{
                    'tname': '课程',
                    'dataList': [{
                        'reMainID': 'UUID002',
                        '课程': '语文',
                        '老师': '网老师',
                        '分数': 89
                    }, {
                        'reMainID': 'UUID002',
                        '课程': '数学',
                        '老师': '找老师',
                        '分数': 92
                    }, {
                        'reMainID': 'UUID002',
                        '课程': '英语',
                        '老师': '李老师',
                        '分数': 93
                    }]
                },
                {
                    'tname': '爱好',
                    'dataList': [{
                        'reMainID': 'UUID002',
                        '爱好': '篮球',
                        '活动': '比赛',
                        '时间': '7 月8日'
                    }, {
                        'reMainID': 'UUID002',
                        '爱好': '美术',
                        '活动': '马拉松',
                        '时间': '2 月8日'
                    }]
                }
            ]
        }, ]
        $('#btn').click(function () {
            //首先创建一个xlsx文件
            let file = new xlsx.File()
            //创建一个sheet
            let sheet = file.addSheet('sheet1');
            //创建sheet的头部行
            let header = sheet.addRow();
            //存储头部单元格
            let headArr = []
            //设置行高
            header.setHeightCM(0.8);
            for (subitem in data[0]) {
                if (subitem != 'children' && subitem != 'keyColumn') {
                    headArr.push(subitem)
                }
            }
            console.log(headArr)
            //主表顶部一栏
            headArr.forEach(item => {
                let hc = header.addCell();
                hc.value = item;
                //设置文本在单元格内水平垂直居中
                hc.style.align.h = 'center';
                hc.style.align.v = 'center';
                //设置字体颜色
                hc.style.font.color = 'ffffffff';
                border(hc, 0, 0, 1, 0)
                fillColor(hc, 1)
            })
            //主表body部分
            let bodyArr = []
            for (let i = 0; i < data.length; i++) {
                let bodyObj = {}
                for (let subitem in data[i]) {
                    // console.log(data[i])
                    if (subitem != 'children' && subitem != 'keyColumn') {
                        // console.log(data[i][subitem])
                        bodyObj[subitem] = data[i][subitem]
                    }
                }
                bodyArr.push(bodyObj)
            }
            bodyArr.forEach(item => {
                //根据数据,创建对应个数的行
                let row = sheet.addRow();
                row.setHeightCM(0.8);
                //创建对应的列
                headArr.forEach((it, index) => {
                    let cell = 'cell' + index
                    cell = row.addCell()
                    cell.value = item[it]
                    cell.style.align.v = 'center';
                    cell.style.align.h = 'center';
                    if (index === 0) {
                        border(cell, 1, 1, 0, 0)
                    } else {
                        border(cell, 0, 0, 0, 1)
                    }
                    fillColor(cell, 2)
                })
            })
            for (let i = 0; i < headArr.length; i++) {
                sheet.col(i).width = 20;
            }

            //导出子表
            //创建子表名
            let subArr = []

            if (data[0].children) {
                data[0].children.forEach(it => {
                    subArr.push(it.tname)
                })
            }
            let subId = []
            data.forEach(item => {
                let subNa = {}
                subNa.id = item.mainID
                subNa.name = item[item.keyColumn]
                subId.push(subNa)
            })
            console.log(subId)
            subArr.forEach((item, index) => {
                let sheet = file.addSheet(item);
                //每创建一个sheet,就要知道这个sheet中有几个人填报
                //有几个人填报就有几张表,有几个大对象就有几个人填报
                //每张表有一个连头,还有一个真正的头部
                for (let i = 0; i < data.length; i++) {
                    let NameAndId = ['姓名', subId[i].name, '关联主数据id', subId[i].id];
                    let headerTop = sheet.addRow();
                    headerTop.setHeightCM(0.8);

                    for (let i = 0; i < 4; i++) {
                        let cellTop = headerTop.addCell();
                        //设置文本在单元格内水平垂直居中
                        cellTop.style.align.h = 'center';
                        cellTop.style.align.v = 'center';
                        cellTop.value = NameAndId[i];
                        border(cellTop, 0, 0, 1, 0)
                        fillColor(cellTop, 1)
                    }
                    for (let i = 0; i < 4; i++) {
                        sheet.col(i).width = 20;
                    }

                    //次级顶部栏
                    let header = sheet.addRow();
                    header.setHeightCM(0.8);
                    let subHeadName = []

                    for (j in data[0].children[index].dataList[0]) {
                        if (j != 'reMainID') {
                            subHeadName.push(j)
                        }
                    }
                    console.log(subHeadName)
                    subHeadName.forEach(item => {
                        //创建头部行中的单元格
                        let hc = header.addCell();
                        //给每个单元格设置值
                        hc.value = item;
                        //设置文本在单元格内水平垂直居中
                        hc.style.align.h = 'center';
                        hc.style.align.v = 'center';
                        //设置字体颜色
                        hc.style.font.color = 'ffffffff';
                        //给每个单元格设置边框和填充颜色
                        border(hc, 0, 0, 1, 0)
                        fillColor(hc, 2)
                    })
                    //表身体
                    data[i].children.forEach((ev, ins) => {
                        //循环subArr中的index  表示数据在哪个sheet中显示
                        //subArr中的第一个for循环中的i  表示数据在哪个子表中显示
                        if (ev.tname === item && index == ins) {
                            ev.dataList.forEach(es => {
                                let subBody = sheet.addRow();
                                subBody.setHeightCM(0.8);
                                let subBodyArr = []
                                for (let value in es) {
                                    if (value != 'reMainID') {
                                        subBodyArr.push(es[value])
                                    }
                                }
                                console.log(subBodyArr)
                                subBodyArr.forEach(item => {
                                    //创建头部行中的单元格
                                    let hc = subBody.addCell();
                                    //给每个单元格设置值
                                    hc.value = item;
                                    //设置文本在单元格内水平垂直居中
                                    hc.style.align.h = 'center';
                                    hc.style.align.v = 'center';
                                    //设置字体颜色
                                    hc.style.font.color = '00000000';
                                    //给每个单元格设置边框和填充颜色
                                    border(hc, 0, 0, 1, 0)
                                    fillColor(hc, 3)
                                })
                            })
                        }
                    })
                }
            })

            file.saveAs('blob').then(function (content) {
                saveAs(content, "example.xlsx");
            });

        })

        //给单元格填充边框
        function border(cell, top, right, bottom, left) {
            const light = 'ffded9d4';
            const dark = 'ff7e6a54';
            cell.style.border.top = 'thin';
            cell.style.border.topColor = top ? dark : light;
            cell.style.border.left = 'thin';
            cell.style.border.leftColor = left ? dark : light;
            cell.style.border.bottom = 'thin';
            cell.style.border.bottomColor = bottom ? dark : light;
            cell.style.border.right = 'thin';
            cell.style.border.rightColor = right ? dark : light;
        }
        //给单元格填充背景,前景色
        function fillColor(cell, type) {
            type = type || 0;
            let colors = ['ffffffff', 'ffa2917d', 'ffe4e2de', 'fffff8df', 'fff1eeec']
            //  0: white ,1: header, 2: first col, 3: second col, 4: gray,
            cell.style.fill.patternType = 'solid';
            cell.style.fill.fgColor = colors[type];
            cell.style.fill.bgColor = 'ffffffff';
        }
    })
</script>

</html>

以供大家参考,如有更好的方法,恳请各位大佬赐教 

 

  • 1
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值