vue导出Excel(表头合并、样式设置、多sheet页、单sheet页多表格)

1,831 阅读7分钟

安装包

npm install exceljs

npm install file-saver --save

1、效果

界面 image.png

单sheet页单表格 image.png

多sheet页 image.png

单sheet页多表格 image.png

2、准备工作

思路:创建工作簿、创建sheet、处理表格数据、将表格添加到sheet、导出Excel。

准备:需要待导出的JSON类型的表格数据。包下载完成。

页面及数据

<template>
    <div>
        <h1  style="margin-top: 200px; display: inline-block; margin-right: 460px">一班成绩</h1>
        <h1 style="display: inline-block; margin-right: 460px">二班成绩</h1>
        <h1 style="display: inline-block;">三班成绩</h1>
        <br>
        <el-table :data="tableData" border stripe header-cell-class-name="headerBg" style="width: 30%; display: inline-block;margin-right: 30px">
            <el-table-column prop="name" label="姓名"></el-table-column>
            <el-table-column prop="Chinese" label="语文"></el-table-column>
            <el-table-column prop="Math" label="数学"></el-table-column>
            <el-table-column prop="English" label="英语"></el-table-column>
            <el-table-column prop="History" label="历史"></el-table-column>
            <el-table-column prop="Politics" label="政治"></el-table-column>
        </el-table>

        <el-table :data="tableData2" border stripe header-cell-class-name="headerBg" style="width: 30%;display: inline-block;margin-right: 30px">
            <el-table-column prop="name" label="姓名"></el-table-column>
            <el-table-column prop="Chinese" label="语文"></el-table-column>
            <el-table-column prop="Math" label="数学"></el-table-column>
            <el-table-column prop="English" label="英语"></el-table-column>
            <el-table-column prop="History" label="历史"></el-table-column>
            <el-table-column prop="Politics" label="政治"></el-table-column>
        </el-table>

        <el-table :data="tableData2" border stripe header-cell-class-name="headerBg" style="width: 30%;display: inline-block">
            <el-table-column prop="name" label="姓名"></el-table-column>
            <el-table-column prop="Chinese" label="语文"></el-table-column>
            <el-table-column prop="Math" label="数学"></el-table-column>
            <el-table-column prop="English" label="英语"></el-table-column>
            <el-table-column prop="History" label="历史"></el-table-column>
            <el-table-column prop="Politics" label="政治"></el-table-column>
        </el-table>
        <el-button type="primary" style="margin-top: 10px; margin-left: 600px" @click="exportSingleSheet">单个sheet页单表格</el-button>
        <el-button type="primary" style="margin-top: 10px" @click="exportMoreSheet">多个sheet页</el-button>
        <el-button type="primary" style="margin-top: 10px" @click="oneSheetMoreTable">单sheet页多表格</el-button>
    </div>
</template>

<script>
import * as ExcelJS from 'exceljs/dist/exceljs';
import FileSaver from 'file-saver';
export default {
    data() {
        return {
            tableData: [
                {
                    name: '小明1',
                    Chinese: 85,
                    Math: 80,
                    English: 70,
                    History: 60,
                    Politics: 66
                },
                {
                    name: '小红1',
                    Chinese: 95,
                    Math: 70,
                    English: 88,
                    History: 89,
                    Politics: 93
                },
                {
                    name: '小蓝1',
                    Chinese: 88,
                    Math: 89,
                    English: 95,
                    History: 84,
                    Politics: 86
                },
                {
                    name: '小绿1',
                    Chinese: 70,
                    Math: 60,
                    English: 75,
                    History: 66,
                    Politics: 67
                },
            ],
            tableData2: [
                {
                    name: '小明2',
                    Chinese: 85,
                    Math: 80,
                    English: 70,
                    History: 60,
                    Politics: 66
                },
                {
                    name: '小红2',
                    Chinese: 95,
                    Math: 70,
                    English: 88,
                    History: 89,
                    Politics: 93
                },
                {
                    name: '小蓝2',
                    Chinese: 88,
                    Math: 89,
                    English: 95,
                    History: 84,
                    Politics: 86
                },
                {
                    name: '小绿2',
                    Chinese: 70,
                    Math: 60,
                    English: 75,
                    History: 66,
                    Politics: 67
                },
            ],
            tableData3: [
                {
                    name: '小明3',
                    Chinese: 85,
                    Math: 80,
                    English: 70,
                    History: 60,
                    Politics: 66
                },
                {
                    name: '小红3',
                    Chinese: 95,
                    Math: 70,
                    English: 88,
                    History: 89,
                    Politics: 93
                },
                {
                    name: '小蓝3',
                    Chinese: 88,
                    Math: 89,
                    English: 95,
                    History: 84,
                    Politics: 86
                },
                {
                    name: '小绿2',
                    Chinese: 70,
                    Math: 60,
                    English: 75,
                    History: 66,
                    Politics: 67
                },
            ]
        }
    },

3、单sheet页导出Excel方法

这里方法为:exportSingleSheet 代码如下:

exportSingleSheet() {
    // 创建工作簿
    const workbook = new ExcelJS.Workbook();
    workbook.creator = 'Me';
    workbook.lastModifiedBy = 'Her';
    workbook.created = new Date();
    workbook.modified = new Date();
    // 将工作簿日期设置为 1904 年日期系统
    workbook.properties.date1904 = true;

    // 添加sheet页
    const worksheet = workbook.addWorksheet('一班学生成绩汇总');
    worksheet.properties.defaultColWidth = 16; // 默认列宽
    worksheet.properties.defaultRowHeight = 16; // 默认行高


    const collectRow = worksheet.getRow(1); // 获取单元格内第一行
    collectRow.height = 30;
    const collectcell = worksheet.getCell(`A1`);
    worksheet.mergeCells(`A1:C1`);  // 合并单元格,将A1与C1合并
    collectcell.value = '期中考试'; // 表格标题内容,A1与C1合并后填充的内容
    collectcell.font = { name: '宋体', family: 4, size: 14, bold: true }; // 字体
    collectcell.alignment = { vertical: 'middle', horizontal: 'center' };

    // 数据处理,写入Excel的数据需要将json数据转换成二维数据的形式
    const ExcelRows = [];   //导入sheet页的表格数据
    this.tableData.forEach((item) => {
        const excelRow = [];
        Object.values(item).forEach(it => { // Object.values获取对象属性按对象定义顺序输出,这里表格内容值需要和表头对应
            excelRow.push(it);
        });
        ExcelRows.push(excelRow);
    });

    // 将sheet页添加到Excel工作簿
    worksheet.addTable({
        name: 'studentScore',
        ref: 'A2',  // 表内容区域
        headerRow: true, // 在表格顶部显示标题
        filterButton: false, // 切换标题中的过滤器控件
        totalsRow: false, // 在表格底部显示总计
        style: {
            theme: 'TableStyleLight8'
        },
        columns: [  //设置表头,必须和内容对应,顺序不能变
            { name: '姓名' },
            { name: '语文成绩' },
            { name: '数学成绩' },
            { name: '英语成绩' },
            { name: '历史成绩' },
            { name: '政治成绩' }
        ],
        rows: ExcelRows //表内容
    });

    // 导出Excel文件,这里指定Excel名称
    workbook.xlsx.writeBuffer().then((buffer) => {
        FileSaver.saveAs(
            new Blob([buffer], {
                type: 'application/octet-stream'
            }),
            `单sheet学生成绩汇总.xlsx`
        );
    });
},

4、多sheet页导出Excel方法

这里方法为:exportMoreSheet 代码如下:

exportMoreSheet() {
    // 创建工作簿
    const workbook = new ExcelJS.Workbook();
    workbook.creator = 'Me';
    workbook.lastModifiedBy = 'Her';
    workbook.created = new Date();
    workbook.modified = new Date();
    // 将工作簿日期设置为 1904 年日期系统
    workbook.properties.date1904 = true;

    // 添加一班sheet页开始
    const worksheet1 = workbook.addWorksheet('一班学生成绩汇总');
    worksheet1.properties.defaultColWidth = 16; // 默认列宽
    worksheet1.properties.defaultRowHeight = 16; // 默认行高
    const collectRow = worksheet1.getRow(1); // 获取单元格内第一行
    collectRow.height = 30;
    const collectcell = worksheet1.getCell(`A1`);
    worksheet1.mergeCells(`A1:C1`);  // 合并单元格,将A1与C1合并
    collectcell.value = '一班期中考试'; // 表格标题内容,A1与C1合并后填充的内容
    collectcell.font = { name: '宋体', family: 4, size: 14, bold: true }; // 字体
    collectcell.alignment = { vertical: 'middle', horizontal: 'center' };

    // 数据处理,写入Excel的数据需要将json数据转换成二维数据的形式
    const ExcelRows = [];   //导入sheet页的表格数据
    this.tableData.forEach((item) => {
        const excelRow = [];
        Object.values(item).forEach(it => { // Object.values获取对象属性按对象定义顺序输出,这里表格内容值需要和表头对应
            excelRow.push(it);
        });
        ExcelRows.push(excelRow);
    });
    // 将sheet页添加到Excel工作簿
    worksheet1.addTable({
        name: 'studentScore',
        ref: 'A2',  // 表内容区域
        headerRow: true, // 在表格顶部显示标题
        filterButton: false, // 切换标题中的过滤器控件
        totalsRow: false, // 在表格底部显示总计
        style: {
            theme: 'TableStyleLight8'
        },
        columns: [  //设置表头,必须和内容对应,顺序不能变
            { name: '姓名' },
            { name: '语文成绩' },
            { name: '数学成绩' },
            { name: '英语成绩' },
            { name: '历史成绩' },
            { name: '政治成绩' }
        ],
        rows: ExcelRows //表内容
    });
    // 添加一班sheet页结束


    // 添加二班sheet页开始
    // const worksheet2 = workbook.addworksheet('二班学生成绩汇总');
    const worksheet2 = workbook.addWorksheet('二班学生成绩汇总');
    worksheet2.properties.defaultColWidth = 16; // 默认列宽
    worksheet2.properties.defaultRowHeight = 16; // 默认行高


    const collectRow2 = worksheet2.getRow(1); // 获取单元格内第一行
    collectRow2.height = 30;
    const collectcell2 = worksheet2.getCell(`A1`);
    worksheet2.mergeCells(`A1:C1`);  // 合并单元格,将A1与C1合并
    collectcell2.value = '二班期中考试'; // 表格标题内容,A1与C1合并后填充的内容
    collectcell2.font = { name: '宋体', family: 4, size: 14, bold: true }; // 字体
    collectcell2.alignment = { vertical: 'middle', horizontal: 'center' };

    // 数据处理,写入Excel的数据需要将json数据转换成二维数据的形式
    const ExcelRows2 = [];   //导入sheet页的表格数据
    this.tableData2.forEach((item) => {
        const excelRow = [];
        Object.values(item).forEach(it => { // Object.values获取对象属性按对象定义顺序输出,这里表格内容值需要和表头对应
            excelRow.push(it);
        });
        ExcelRows2.push(excelRow);
    });
    // 将sheet页添加到Excel工作簿
    worksheet2.addTable({
        name: 'SecondStudentScore',
        ref: 'A2',  // 表内容区域
        headerRow: true, // 在表格顶部显示标题
        filterButton: false, // 切换标题中的过滤器控件
        totalsRow: false, // 在表格底部显示总计
        style: {
            theme: 'TableStyleLight8'
        },
        columns: [  //设置表头,必须和内容对应,顺序不能变
            { name: '姓名' },
            { name: '二班语文成绩' },
            { name: '二班数学成绩' },
            { name: '二班英语成绩' },
            { name: '二班历史成绩' },
            { name: '二班政治成绩' }
        ],
        rows: ExcelRows2 //表内容
    });

    // 导出Excel文件,这里指定Excel名称
    workbook.xlsx.writeBuffer().then((buffer) => {
        FileSaver.saveAs(
            new Blob([buffer], {
                type: 'application/octet-stream'
            }),
            `多sheet学生成绩汇总.xlsx`
        );
    });
},

5、单sheet页多表格导出Excel方法

这里方法为:oneSheetMoreTable 代码如下:

oneSheetMoreTable() {
    // 创建工作簿
    const workbook = new ExcelJS.Workbook();
    workbook.creator = 'Me';
    workbook.lastModifiedBy = 'Her';
    workbook.created = new Date();
    workbook.modified = new Date();
    // 将工作簿日期设置为 1904 年日期系统
    workbook.properties.date1904 = true;

    // 添加sheet页
    const worksheet = workbook.addWorksheet('一班学生成绩汇总');
    worksheet.properties.defaultColWidth = 16; // 默认列宽
    worksheet.properties.defaultRowHeight = 16; // 默认行高
    let rowCount = 1;   //记录单元格被使用的长度
    const step = 3;

    // 一班成绩
    const collectRow = worksheet.getRow(rowCount); // 获取单元格内第一行
    collectRow.height = 30;
    const collectcell = worksheet.getCell(`A1`);
    worksheet.mergeCells(`A1:C1`);  // 合并单元格,将A1与C1合并
    collectcell.value = '一班期中考试成绩'; // 表格标题内容,A1与C1合并后填充的内容
    collectcell.font = { name: '宋体', family: 4, size: 14, bold: true }; // 字体
    collectcell.alignment = { vertical: 'middle', horizontal: 'center' };
    rowCount++;

    // 数据处理,写入Excel的数据需要将json数据转换成二维数据的形式
    const ExcelRows = [];   //导入sheet页的表格数据
    this.tableData.forEach((item) => {
        const excelRow = [];
        Object.values(item).forEach(it => { // Object.values获取对象属性按对象定义顺序输出,这里表格内容值需要和表头对应
            excelRow.push(it);
        });
        ExcelRows.push(excelRow);
    });

    // 将sheet页添加到Excel工作簿
    worksheet.addTable({
        name: 'studentScore',
        ref: 'A2',  // 表内容区域
        headerRow: true, // 在表格顶部显示标题
        filterButton: false, // 切换标题中的过滤器控件
        totalsRow: false, // 在表格底部显示总计
        style: {
            theme: 'TableStyleLight8'
        },
        columns: [  //设置表头,必须和内容对应,顺序不能变
            { name: '姓名' },
            { name: '语文成绩' },
            { name: '数学成绩' },
            { name: '英语成绩' },
            { name: '历史成绩' },
            { name: '政治成绩' }
        ],
        rows: ExcelRows //表内容
    });
    rowCount += ExcelRows.length + step;

    // 二班成绩
    const secondRow = worksheet.getRow(rowCount); // 获取单元格内第一行
    secondRow.height = 30;
    const secondCell = worksheet.getCell(`A${rowCount}`);
    worksheet.mergeCells(`A${rowCount}:C${rowCount}`);  // 合并单元格,将A1与C1合并
    secondCell.value = '二班期中考试成绩'; // 表格标题内容,A1与C1合并后填充的内容
    secondCell.font = { name: '宋体', family: 4, size: 14, bold: true }; // 字体
    secondCell.alignment = { vertical: 'middle', horizontal: 'center' };
    rowCount++;

    // 数据处理,写入Excel的数据需要将json数据转换成二维数据的形式
    const secondExcelRows = [];   //导入sheet页的表格数据
    this.tableData2.forEach((item) => {
        const excelRow = [];
        Object.values(item).forEach(it => { // Object.values获取对象属性按对象定义顺序输出,这里表格内容值需要和表头对应
            excelRow.push(it);
        });
        secondExcelRows.push(excelRow);
    });

    // 将sheet页添加到Excel工作簿
    worksheet.addTable({
        name: 'SecondeStudentScore',
        ref: `A${rowCount}`,  // 表内容区域
        headerRow: true, // 在表格顶部显示标题
        filterButton: false, // 切换标题中的过滤器控件
        totalsRow: false, // 在表格底部显示总计
        style: {
            theme: 'TableStyleLight8'
        },
        columns: [  //设置表头,必须和内容对应,顺序不能变
            { name: '姓名' },
            { name: '二班语文成绩' },
            { name: '二班数学成绩' },
            { name: '二班英语成绩' },
            { name: '二班历史成绩' },
            { name: '二班政治成绩' }
        ],
        rows: secondExcelRows //表内容
    });

    // 三班成绩
    const thirdRow = worksheet.getRow(rowCount); // 获取单元格内第一行
    thirdRow.height = 30;
    rowCount--;
    const thirdCell = worksheet.getCell(`H${rowCount}`);
    worksheet.mergeCells(`H${rowCount}:J${rowCount}`);  // 合并单元格,将A1与C1合并
    thirdCell.value = '三班期中考试成绩'; // 表格标题内容,A1与C1合并后填充的内容
    thirdCell.font = { name: '宋体', family: 4, size: 14, bold: true }; // 字体
    thirdCell.alignment = { vertical: 'middle', horizontal: 'center' };
    rowCount++;

    // 数据处理,写入Excel的数据需要将json数据转换成二维数据的形式
    const thirdExcelRows = [];   //导入sheet页的表格数据
    this.tableData3.forEach((item) => {
        const excelRow = [];
        Object.values(item).forEach(it => { // Object.values获取对象属性按对象定义顺序输出,这里表格内容值需要和表头对应
            excelRow.push(it);
        });
        thirdExcelRows.push(excelRow);
    });

    // 将sheet页添加到Excel工作簿
    worksheet.addTable({
        name: 'thirdStudentScore',
        ref: `H${rowCount}`,  // 表内容区域
        headerRow: true, // 在表格顶部显示标题
        filterButton: false, // 切换标题中的过滤器控件
        totalsRow: false, // 在表格底部显示总计
        style: {
            theme: 'TableStyleLight8'
        },
        columns: [  //设置表头,必须和内容对应,顺序不能变
            { name: '姓名' },
            { name: '三班语文成绩' },
            { name: '三班数学成绩' },
            { name: '三班英语成绩' },
            { name: '三班历史成绩' },
            { name: '三班政治成绩' }
        ],
        rows: thirdExcelRows //表内容
    });

    // 导出Excel文件,这里指定Excel名称
    workbook.xlsx.writeBuffer().then((buffer) => {
        FileSaver.saveAs(
            new Blob([buffer], {
                type: 'application/octet-stream'
            }),
            `单sheet多表格学生成绩汇总.xlsx`
        );
    });
}

6、注意点:

Excel导出,这里用到的JSON数据需要进行处理,转换为二维数组。这里在方法中已经对JSON数据进行处理了,类似于这样:

image.png