前端使用xlsx模板导出表格

前言

前端导出表格有很多种方案,但是表格样式一旦复杂了,那么就得用代码写excel的样式,还是比较麻烦的。每次样式不一样,就得重新写,这时使用表格模板的优势就体现出来了,想导出不同样式的表格直接修改表格模板即可。

方案

我找了两种方案:

1、使用xlsx-template,利用模板语法在xlsx中占位填充后编辑导出。

2、使用exceljs,读取模板后,利用行列坐标定位编辑后导出。

两种我都尝试过,第一种方案类似我这篇文章(https://xiblogs.top/?id=27) 中使用的docxtemplater,只不过是docx换成了xlsx,但xlsx-template在浏览器端的兼容不如docxtemplater那么好,你得处理fs、path之类的问题,当然也有老哥(https://www.jianshu.com/p/85c844d96cfb) 通过改项目配置的方式解决了。还是比较麻烦的而且老项目不一定适用,所以我使用了第二种方案。

步骤

1、安装exceljs与file-saver

复制代码
npm i exceljs
npm i file-saver

2、xlsx模板放在项目的public目录下。

3、使用fetch的方式读取public下的xlsx模板。

复制代码
let response = await fetch('./static/xlsx/t1.xlsx'); //读取文件

4、将读取的数据转换为buffer再使用exceljs的workbook.xlsx.load加载数据。

复制代码
let data = await response.arrayBuffer(); //转为二进制
const workbook = new ExcelJS.Workbook();
await workbook.xlsx.load(data); //读取buffer
const worksheet = workbook.getWorksheet(1); //读取第一张表

5、利用exceljs的worksheet.getCell()给指定单元格赋值,getCell参数为行列,如修改第一行第一列数据为test。

复制代码
worksheet.getCell('1A').value = 'test'

6、使用exceljs的writeBuffer()读取表格为buffer后再使用file-saver的saveAs下载。

复制代码
await workbook.xlsx.writeBuffer().then(async (buffer) => {
	let blob = new Blob([buffer], { type: 'application/octet-stream' });
	await saveAs(blob, 'exportExcel.xlsx');
	this.loading = false;
});

完整方法如下:

复制代码
async exportExcel() {
      this.loading = true;
      let response = await fetch('./static/xlsx/t1.xlsx'); //读取文件
      let data = await response.arrayBuffer(); //转为二进制
      const workbook = new ExcelJS.Workbook();
      await workbook.xlsx.load(data); //读取buffer
      const worksheet = workbook.getWorksheet(1); //读取第一张表
      let cols = []; //竖列//A~Z
      for (let i = 65; i < 91; i++) {
        cols.push(String.fromCharCode(i));
      }
      let row = []; //横行1~116
      for (let i = 1; i < 117; i++) {
        row.push(i);
      }
      //坐标定位更新数据
      row.forEach(async (r) => {
        cols.forEach(async (c) => {
          if (r >= 9 && r <= 15 && c >= 'B' && c <= 'R') {
            worksheet.getCell(`${c}${r}`).value = `${c}${r}`;
          }
          if (r >= 17 && r <= 30 && c >= 'B' && c <= 'X') {
            worksheet.getCell(`${c}${r}`).value = `${c}${r}`;
          }
        });
      });
      worksheet.eachRow({ includeEmpty: true }, (row, rowNumber) => {
        // console.log(rowNumber, row.values);
      });
      //下载
      await workbook.xlsx.writeBuffer().then(async (buffer) => {
        let blob = new Blob([buffer], { type: 'application/octet-stream' });
        await saveAs(blob, 'exportExcel.xlsx');
        this.loading = false;
      });
}

最后下载导出的表格如下:

结语

使用过程中需要注意读取数据时的异步处理。

原文链接:https://xiblogs.top/?id=71

相关推荐
Cache技术分享几秒前
355. Java IO API -去除路径中的冗余信息
前端·后端
catoop10 分钟前
Excel 实战技巧:单元格相对引用 INDIRECT、ROW、COLUMN 函数
excel
牛马11111 分钟前
Flutter CustomPaint
开发语言·前端·javascript
炽烈小老头22 分钟前
函数式编程范式(三)
前端·typescript
ruoyusixian34 分钟前
chrome二维码识别查插件
前端·chrome
fengfuyao9851 小时前
一个改进的MATLAB CVA(Change Vector Analysis)变化检测程序
前端·算法·matlab
路光.1 小时前
uniappVue2升级Vue3内存溢出解决方式
vue·vue3·uniapp
yuhaiqiang1 小时前
为什么这道初中数学题击溃了所有 AI
前端·后端·面试
djk88881 小时前
支持手机屏幕的layui后台html模板
前端·html·layui
紫_龙1 小时前
最新版vue3+TypeScript开发入门到实战教程之watch详解
前端·javascript·typescript