使用xlsx、xlsx-style导出表格添加背景色;合并单元格部分样式缺失问题解决_xlsx.utils 添加背景色-程序员宅基地

技术标签: vue  前端  html  javascript  

这篇说一下使用xlsx-style导出excel时样式的设置。需要安装xlsx、xlsx-style、file-saver插件(file-saver可以不装,用a标签代替也可以),安装时可能会碰到一些报错问题,可以去看下我之前一篇博客:纯前端导出Excel并修改样式

由于上次写的修改样式只关注了单元格的宽度,并没有设置颜色以及没关注到合并的单元格部分样式没设置上等问题,所以这篇来说下。

我们通过xlsx可以通过dom元素、或者数据来生产sheet页,然后我们修改样式就操作对应的sheet页就可以了。

直接上代码如下:

我这个是直接通过传入dom生产的sheet页,也可以通过数据生成sheet页,xlsx都有对应的方法,其实不影响我们修改样式 。主要关注addRangeBorder(给合并行列赋值样式)、setExcelStyle(设置导出Excel样式)这两个方法。

import * as XLSX from 'xlsx'
import FileSaver from 'file-saver'
import XLSXS from 'xlsx-style'

/**
 * 根据DOM进行导出
 * @param {Element} dom 
 * @param {String} fileName 
 */
export function exportExcelByDom(dom, fileName) {
  const book = XLSX.utils.book_new()
  const sheet = XLSX.utils.table_to_sheet(dom)
  XLSX.utils.book_append_sheet(book, sheet, 'Sheet1')
  addRangeBorder(sheet['!merges'], sheet) // 给合并行列赋值样式
  setExcelStyle(sheet) // 设置样式
  let wbout = XLSXS.write(book, {
    bookType: 'xlsx',
    bookSST: false,
    type: 'binary'
  })
  try {
    FileSaver.saveAs(new Blob([s2ab(wbout)], { type: "application/octet-stream" }), fileName);
  } catch (e) {
    console.error(e, wbout, '----->>>')
  }
}

// 设置导出Excel样式(统一样式)
function setExcelStyle(data, wpx = 80) {
  data["!cols"] = []
  const excludes = ['!cols', '!fullref', '!merges', '!ref', '!rows']
  for (let key in data) {
    if (data.hasOwnProperty(key)) {
      if (!excludes.includes(key)) {
        data[key].s = {
          alignment: {
            horizontal: "center", //水平居中对齐
            vertical: "center", // 垂直居中
            wrapText: true,
          },
          border: {
            top: {
              style: 'thin',
              color: { rgb: '000000' }
            },
            bottom: {
              style: 'thin',
              color: { rgb: '000000' }
            },
            left: {
              style: 'thin',
              color: { rgb: '000000' }
            },
            right: {
              style: 'thin',
              color: { rgb: '000000' }
            }
          },
          // fill: {
          //   fgColor: { rgb: "00a2ff" },
          // },
          font: {
            sz: 11,
          },
          bold: true,
          numFmt: 0
        }
        // 单元格宽度
        data["!cols"].push({ wpx });
        // 根据不同行添加单元格背景颜色
        let color = ''
        let num = Number(key.slice(1))
        if (num < 12) {
          color = 'f8cbad'
        } else if (num >= 12 && num < 22) {
          color = '70ad47'
        } else if (num >= 22 && num < 24) {
          let letter = key[0]
          const leftCol = ['A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J']
          if(leftCol.includes(letter)) {
            color = '9bc2e6'
          } else {
            color = '8ea9db'
          }
        } else if(num >= 24 && num < 26) {
          color = '00b0f0'
        } else if (num >= 26 && num < 29) {
          color = 'fff2cc'
        } else if (num >= 29 && num < 44) {
          color = 'a9d08e'
        } else {
          color = 'bfbfbf'
        }
        data[key].s.fill = { fgColor: { rgb: color, patternType: 'solid' } }
      }
    }
  }
}

//给合并行列赋值样式
function addRangeBorder (range, ws) {
  let cols = ["A", "B", "C", "D", "E", "F", "G", "H", "I", "J", "K", "L", "M", "N", "O", "P", "Q", "R", "S", "T", "U", "V", "W", "X", "Y", "Z"];
  range.forEach(item => {
    let style = {
      s: {
        border: {
          top: {
            style: 'thin',
            color: { rgb: '000000' }
          },
          bottom: {
            style: 'thin',
            color: { rgb: '000000' }
          },
          left: {
            style: 'thin',
            color: { rgb: '000000' }
          },
          right: {
            style: 'thin',
            color: { rgb: '000000' }
          }
        }
      }
    }
    // 处理合并行
    for (let i = item.s.c; i <= item.e.c; i++) {
      ws[`${cols[i]}${Number(item.e.r) + 1}`] = ws[`${cols[i]}${Number(item.e.r) + 1}`] || style
      // 处理合并列
      for (let k = item.s.r + 2; k <= item.e.r + 1; k++) {
        ws[cols[i] + k] = ws[cols[k] + item.e.r] || style
      }
    }
  })
  return ws;
}

function s2ab(s) {
  var buf = new ArrayBuffer(s.length)
  var view = new Uint8Array(buf)
  for (var i = 0; i != s.length; ++i) view[i] = s.charCodeAt(i) & 0xff
  return buf
}

调用:

exportExcelByDom(document.getElementById('custom-table'), '生产日报表.xlsx')

然后下面是我开发的表格长这个样子:

 

上面两种图片是一个表格哈,比较长,其实下面还有,然后导出的效果是这样子:

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/m0_51431448/article/details/135935612

智能推荐

字符,字节和编码-程序员宅基地

文章浏览阅读39次。级别:中级摘要:本文介绍了字符与编码的发展过程,相关概念的正确理解。举例说明了一些实际应用中,编码的实现方法。然后,本文讲述了通常对字符与编码的几种误解,由于这些误解而导致乱码产生的原因,以及消除乱码的办法。本文的内容涵盖了“中文问题”,“乱码问题”。掌握编码问题的关键是正确地理解相关概念,编码所涉及的技术其实是很简单的。因此,阅读本文时需要慢读多想,多思考。引言“字符与编码”...

Linux 修改 ELF 解决 glibc 兼容性问题_glibc_private-程序员宅基地

文章浏览阅读1.1k次。Linux glibc 问题相信有不少 Linux 用户都碰到过运行第三方(非系统自带软件源)发布的程序时的 glibc 兼容性问题,这一般是由于当前 Linux 系统上的 GNU C 库(glibc)版本比较老导致的,例如我在 CentOS 6 64 位系统上运行某第三方闭源软件时会报:[root@centos6-dev ~]# ldd tester./tester: /lib64/libc.so.6: version `GLIBC_2.17' not found (required by._glibc_private

wxWidgets:常用表达式_wxwidget 正则表达式 非数字字符-程序员宅基地

文章浏览阅读282次。wxWidgets:常用表达式wxWidgets:常用表达式不同风味的正则表达式转义Escapes元语法匹配限制和兼容性基本正则表达式正则表达式字符名称wxWidgets:常用表达式一个正则表达式描述字符的字符串。这是一种匹配某些字符串但不匹配其他字符串的模式。不同风味的正则表达式POSIX 定义的正则表达式 (RE) 有两种形式:扩展正则表达式(ERE) 和基本正则表达式(BRE)。ERE 大致是传统egrep 的那些,而 BRE 大致是传统ed 的那些。这个实现增加了第三种风格:高级正则表达式_wxwidget 正则表达式 非数字字符

Java中普通for循环和增强for循环的对比_for循环10万数据需要时间-程序员宅基地

文章浏览阅读3.4k次,点赞5次,收藏11次。Java中普通for循环和增强for循环的对比_for循环10万数据需要时间

学习PCB设计前的知识扫盲_pcb端子设计基础知识-程序员宅基地

文章浏览阅读2.7k次,点赞13次,收藏97次。0.工厂制作PCB线路板流程1.PCB的结构铜层阻焊丝印本质(PCB画电路板到底在画什么)基础工艺指标2.PCB图中的元素元素布局布线叠层设计3.PCB的设计依据原理图原理图元件库4.PCB的设计流程——总结_pcb端子设计基础知识

Python读取Excel内容;将读取的数据转换为list类型便于切片处理;列表的操作方法;pandas处理DataFrame类型数据;pandas操作;Python几种取整的方法_pandas excel list-程序员宅基地

文章浏览阅读4.5k次,点赞5次,收藏19次。Python读取Excel内容;将读取的数据转换为list类型便于切片处理;列表的操作方法;pandas处理DataFrame类型数据_pandas excel list

随便推点

java小易——Spring_spring的beanfactory是hashmap吗-程序员宅基地

文章浏览阅读109次。SpringIoC DI AOPspring底层用的是ConcurrentHashMap解耦合:工厂模式:需要一个模板控制反转 IoC将原来有动作发起者(Main)控制创建对象的行为改成由中间的工厂来创建对象的行为的过程叫做IoC一个类与工厂之间如果Ioc以后,这个时候,动作发起者(Main)已经不能明确的知道自己获得到的对象,是不是自己想要的对象了,因为这个对象的创建的权利与交给我这个对象的权利全部转移到了工厂上了所用包:DOM4j解析XML文件lazy-init = _spring的beanfactory是hashmap吗

温故而知新:部分常见的图像数学运算处理算法的用途_图像处理算啊-程序员宅基地

文章浏览阅读1.3k次,点赞29次,收藏24次。本文将图像处理中常用的数学运算算法及其对图像的作用做了个汇总介绍,有助于图像处理时针对对应场景快速选择合适的数学算法。_图像处理算啊

EM Agent Fatal agent error: State Manager failed at Startup_check agent status retcode=1-程序员宅基地

文章浏览阅读1.1k次。EM 不定期异常宕机,问题重复出现,之前几次因为忙于其它事,无力兼顾,等回头处理时,发现EM已恢复正常。这次问题又重现,准备彻底解决,过程如下:1. 重新启动EM失败,报错:/u01/oracle/agent/core/12.1.0.5.0/bin/emctl status agentOracle Enterprise Manager Cloud Control 12c Relea_check agent status retcode=1

JVM常用调优参数 ——JVM篇_jvm调优-程序员宅基地

文章浏览阅读1.9w次,点赞50次,收藏366次。JVM常用性能调优参数详解​ 在学习完整个JVM内容后,其实目标不仅是学习了解整个JVM的基础知识,而是为了进行JVM性能调优做准备,所以以下的内容就是来说说JVM性能调优的知识。一、性能调优​ 性能调优包含多个层次,比如:架构调优、代码调优、JVM调优、数据库调优、操作系统调优等等。​ 架构调优和代码调优是JVM调优的基础,其中架构调优是对系统影响最大的。性能调优基本上按照以下步骤进行:明确优化目标发现性能瓶颈性能调优通过监控及数据统计工具获得数据确认是否达到目标二、何时进_jvm调优

三级嵌入式准备(二)_八个gpio引脚最多构成几个按键-程序员宅基地

文章浏览阅读435次,点赞3次,收藏7次。转载来源为https://blog.csdn.net/ReCclay/article/details/79439686 1、嵌入式系统的CPU主要使用的有DSP、ARM以及FPGA。2、DSP适用于数字信号处理的微处理器支持单指令多数据(DIMD)并行处理的指令显著提高音频、视频等数字信号的数据处理效率3、片上系统SOC已成为嵌入式处理器芯片的主流发展趋势它是..._八个gpio引脚最多构成几个按键

OpenStack的容器服务体验-程序员宅基地

文章浏览阅读70次。magnum 是用于 OpenStack 的容器服务。它有以下特点:抽象的容器、节点、服务等集成了用于容器技术的Kubernetes和Docker集成了多租户安全的 Keystone继承了k8s多租户网络安全的 Neutron环境准备在VMware Workstations建台虚拟机,Ubuntu 14.04 LTS,..._openstack 安装好没有容器服务