vue3前端excel导出;组件表格,自定义表格导出;Vue3 + xlsx + xlsx-style

news/2024/7/10 0:40:30 标签: 前端, excel, vue

当画面有自定义的表格或者样式过于复杂的表格时,导出功能可以由前端实现

1. 使用的插件 : sheet.js-xlsx

文档地址:https://docs.sheetjs.com/
中文地址:https://geekdaxue.co/read/SheetJS-docs-zh/README.md
xlsx-style:https://www.npmjs.com/package/xlsx-style
在这里插入图片描述

2. 安装引用

安装插件-vue3

yarn add xlsx 
yarn add xlsx-style-vite (有样式需求才需要安装;背景色等)

引用插件

import * as XLSX from 'xlsx';
import * as XLSX_STYLE from 'xlsx-style-vite'

3. 组件表格的导出(无样式)

以ant design vue 表格为例,只导出表格内容

<a-table :columns="columns" :dataSource="detaildata" :scroll="{ x: 'max-content',y:700 }" ></table?>
<a-button @click="exportData">导出</a-button>

<script>
   //数据处理为数组
	const transData=(columns, tableList)=> {
       const obj = columns.reduce((acc, cur) => {
         if (!acc.titles && !acc.keys) {
           acc.titles = [];
           acc.keys = [];
         }
         acc.titles.push(cur.title);
         acc.keys.push(cur.dataIndex);
         return acc;
       }, {});
       const tableBody = tableList.map((item,i) => {
         return obj.keys.map((key,index) => item[key]);
       });
       return [ obj.titles, ...tableBody ];
    }
     const exportData=()=>{
          const tableData = transData(
              columns.value,
              detaildata.value
          );
          // 将数据数组转换为工作表
          const ws = XLSX.utils.aoa_to_sheet(tableData);
          // 创建 workbook
          const wb = XLSX.utils.book_new();
          ws['!ref'] = `A1:AI${tableData.length}`;
          //设置列宽
          ws["!cols"] = [
            {wpx: 120}, 
            {wpx: 100},
            {wpx: 110},
            {wpx: 110},];
          //合并单元格
          ws['!merges'] = [{ s: { r: 0, c: 0 }, e: { r: 0, c: 1 } }]
          // 将 工作表 添加到 workbook
          XLSX.utils.book_append_sheet(wb, ws, 'Sheet1');
          // 将 workbook 写入文件
          XLSX.writeFile(wb, 'tablename.xlsx');
  }
</script>

3. 自定义表格的导出 (div拼成的表格)

比如这种前端拼成的,又附带各种样式的表格
在这里插入图片描述
一些常用的格式:
(1):合并单元格
(2):列宽
(3):背景色
(4):字体相关-大小粗细颜色字体等
(5):表格线,边框
详细的格式可以参考:
https://www.jianshu.com/p/869375439fee
https://www.npmjs.com/package/xlsx-style

数据处理就不写了,数据处理为数组就可以了
const toExcel=()=>{
	const data = [
	        ['左上表头','','','右上',''],
	        ['标题1','','','',''],
	        ['标题','测试合并','','',''],
	        ['固定标题','123','123','',''],
	        ['左下表头','','','右下',''],
			['2021','¥28337','测试数据','北京','黑龙江'],
			......
	    ]
	const worksheet = XLSX.utils.aoa_to_sheet([headers, ...data])
	const workbook = XLSX.utils.book_new()
	worksheet['!ref'] = `A1:AI${data.length}`
	
	//列宽 按excel的列顺序排列,对应A列,B列, C列......
	worksheet["!cols"] = [
	  {wpx: 200}, 
	  {wpx: 80},
	  {wpx: 80},
	  {wpx: 110}, 
	  {wpx: 110},
	];
	
	/* 
	合并单元格 默认合并当前格的右侧格子
	{ s: { r: 0, c: 0 }, e: { r: 0, c: 1 } }
	A1 与 B1 合并 内容为 A1 的内容
	
	s:start 合并开始 e:end 合并结束
	r:row 行 c:col 列 
	*/
	
	worksheet['!merges'] = [
	  { s: { r: 0, c: 0 }, e: { r: 0, c: 1 } },
	  { s: { r: 0, c: 4 }, e: { r: 0, c: 5 } },
	  { s: { r: 4, c: 0 }, e: { r: 4, c: 1 } },
	  ......
	];
	
	//表格详细样式
	for (let key in worksheet) {
	   if (key == '!ref' || key == '!merges' || key == '!cols' || key == '!rows') {
	     continue
	   } else {
		 //通过key值来选择筛选想要的设置样式的单元格
	     if (key.substring(1)=='1'||key.substring(1)=='5'|| key == 'A2') {
	        worksheet[key].s = { // 设置单元格样式
	            fill: { // 设置背景色
	              fgColor: { rgb: 'F2F3F7' },
	            },
	            font: { // 设置字体
	              name: '等线', // 字体名称
	              sz: 16, // 字体大小
	              bold: true, // 字体是否加粗
	              color:{ //字体颜色
	                    rgb:'ed263d'
	               }
	            },
	            border:{ //设置边框
	              top: {
	                  style: 'thin',
	                  color:{
	                      rgb:'e5e7eb'
	                  }
	              },
	              bottom: {
	                  style: 'thin',
	                  color:{
	                      rgb:'e5e7eb'
	                  }
	              }
	          },
	          alignment: {
	            horizontal: 'center', // 横向(向左、向右、居中)
	            vertical: 'center', // 纵向(向上、向下、居中)
	            wrapText: true, // 设置单元格自动换行,目前仅对非合并单元格生效
	            indent: 0 // 设置单元格缩进
	          }
	        }
	     }else if(key == 'B1'){
	     	......
	     }
	   }
	}
	
	XLSX.utils.book_append_sheet(workbook, worksheet, 'Sheet1')
	const tmpDown = new Blob([
	    s2ab(
	    XLSX_STYLE.write(workbook, {
	        bookType: 'xlsx',
	        bookSST: false,
	        type: 'binary',
	        cellStyles: true,
	    })
	    ),
	])
	downloadExcelFile(tmpDown, 'excelname' + '.xlsx')
}

/*用到的方法*/
export function s2ab(s) {
  if (typeof ArrayBuffer !== 'undefined') {
    const buf = new ArrayBuffer(s.length)
    const view = new Uint8Array(buf);
    for (let i = 0; i != s.length; ++i) {
      view[i] = s.charCodeAt(i) & 0xff
    }
    return buf
  } else {
    const buf = new Array(s.length)
    for (let i = 0; i != s.length; ++i) {
      buf[i] = s.charCodeAt(i) & 0xff
    }
    return buf
  }
}

/**
 * 使用 a 标签下载文件
 */
export function downloadExcelFile(obj, fileName){
  const a_node = document.createElement('a')
  a_node.download = fileName
  if ('msSaveOrOpenBlob' in navigator) {
    window.navigator.msSaveOrOpenBlob(obj, fileName)
  } else {
    a_node.href = URL.createObjectURL(obj)
  }
  a_node.click()
  setTimeout(() => {
    URL.revokeObjectURL(obj)
  }, 2000)
}

参考文章:https://blog.csdn.net/Cai181191/article/details/131130926


http://www.niftyadmin.cn/n/5384708.html

相关文章

oracle INSERT 批量插入写法

直接采用mysql那种INSERT批量插入语句的写法&#xff0c;会报 SQL 错误 [933] [42000]: ORA-00933: SQL 命令未正确结束 它可以使用以下方法来批量插入数据&#xff1a; 使用INSERT ALL语句&#xff1a;可以在一条INSERT语句中插入多个记录。使用这种方法&#xff0c;您可以为…

为什么需要写Java单元测试总结

目录 前言 一、为什么写单元测试 写单测好处 1、提升效率 2、场景覆盖全 单测怎么写 1、集成测试 2、单元测试 Mock框架 1、Mockito单元测试 2、Mockito 中文文档地址 二、强制要求 1.好的单元测试必须遵守AIR原则。 2.单元测试应该是全自动执行的&#xff0c;并…

NestJS入门8:拦截器

前文参考&#xff1a; NestJS入门1&#xff1a;创建项目 NestJS入门2&#xff1a;创建模块 NestJS入门3&#xff1a;不同请求方式前后端写法 NestJS入门4&#xff1a;MySQL typeorm 增删改查 NestJS入门5&#xff1a;加入Swagger NestJS入门6&#xff1a;日志中间件 Nes…

2月20日,每日信息差

第一、中国联通 1 月智慧客服客户问题解决率为 97.9%&#xff0c;大联接用户达 10.02 亿户&#xff0c;5G 套餐用户约 2.64 亿户&#xff0c;物联网终端连接约 5.06 亿户。5G 行业虚拟专网服务客户数为 9185 个&#xff0c;智慧客服问题解决率 97.9%&#xff0c;智能服务占比 8…

pom.xml常见依赖及其作用

1.org.mybatis.spring.boot下的mybatis-spring-boot-starter&#xff1a;这个依赖是mybatis和springboot的集成库&#xff0c;简化了springboot项目中使用mybatis进行持久化操作的配置和管理 2.org.projectlombok下的lombok&#xff1a;常用注解Data、NoArgsConstructor、AllA…

计算机编程中十进制转二进制,二进制转八进制和十六进制

十进制转二进制&#xff1a;除二取余法 比如123转成二进制为:01111011 验证一下:26 2524232120643216821123 123转成八进制和十六进制很简单&#xff0c;只需要弄懂其原理并把123的二进制算出来转成八进制和十六进制即可。 八进制、十六进制介绍 为了便于观察和表示二进制&a…

【洛谷 P8780】[蓝桥杯 2022 省 B] 刷题统计 题解(贪心算法+模拟+四则运算)

[蓝桥杯 2022 省 B] 刷题统计 题目描述 小明决定从下周一开始努力刷题准备蓝桥杯竞赛。他计划周一至周五每天做 a a a 道题目&#xff0c;周六和周日每天做 b b b 道题目。请你帮小明计算&#xff0c;按照计划他将在第几天实现做题数大于等于 n n n 题? 输入格式 输入一…

一个检测主站与从站是否存在通讯故障的小技巧

文章目录 前言一、从站程序编写二、主站程序编写总结 前言 本文提供了一个西门子PLC与远程设备建立通讯后&#xff0c;检测通讯故障的程序思路。 关于通讯程序的编写&#xff0c;请参考文章&#xff1a; S7-1200PLC通讯问题总结 这里不再赘述。 一、从站程序编写 在从站PLC中…