前端表格操作,插件XLSX之表格+样式导出

207 阅读4分钟

以下内容为个人根据网上查阅+个人实践得出经验,供个人纪录和其他开发者参考。

安装:

  • npm i xlsx(不需要设置样式安装这个)
  • npm i xlsx-js-style(需要设置样式,背景色,字体颜色大小等就安装这个)

导入

  • import XLSX from 'xlsx-js-style' 或 const XLSX = require('xlsx-js-style')

生成xslx需要的数据

生成xslx需要的数据分为四种方法可以根据实际需要自行选择

  1. json格式处理
// 数据
const sheetData = [
    { name: '张三', age: 125 },
    { name: '李四', age: 180 }
];
// 使用XLSX.utils.json_to_sheet
const sheet = XLSX.utils.json_to_sheet(sheetData)
  1. 数组格式处理
// 数据
const sheetData = [  ['姓名', '年龄', '城市'],
  ['张三', 25, '上海'],
  ['李四', 30, '北京']
]
// 使用 XLSX.utils.utils.aoa_to_sheet() 处理
const sheet = XLSX.utils.aoa_to_sheet(sheetData) // 数组类型数据
  1. table表格
// 此方法可以直接获取table渲染的内容生成表格,合并数据与表格实际展示的一致,比较方便,缺陷是只能处理当前列表展示的数据,而且添加自定义数据比较麻烦。
// 使用方式是获取当前列表的DOM,
const sheet = XLSX.utils.table_to_sheet(document.getElementById('table'))
  1. csv字符集(未作尝试,一般是需要后端返回合适的数据)

生成一个空白的工作表

const etx = XLSX.utils.book_new()

数据写入空白工作表

XLSX.utils.book_append_sheet(etx, sheet, '测试')

导出该工作表

XLSX.writeFile(etx, '测试.xlsx')

VUE版简单示例

<template>
  <div>
    <button @click="test">测试</button>
  </div>
  </template>

<script>
// 根据环境选择两种不同的导入方式
import XLSX from 'xlsx-js-style'
// const XLSX = require('xlsx-js-style')
export default {
  data () {
    return {

    }
  },
  mounted () {
  },
  methods: {
    test () {
      const sheetData = [
        ['姓名', '年龄', '城市'],
        ['张三', 25, '上海'],
        ['李四', 30, '北京']
      ]
      const sheet = XLSX.utils.aoa_to_sheet(sheetData)
      const etx = XLSX.utils.book_new()
      XLSX.utils.book_append_sheet(etx, sheet, '测试')
      XLSX.writeFile(etx, '测试.xlsx')
    }
  }
}
</script>
  <style>
  </style>

  • 实际效果如下图

array.png

这样一个基本的列表导出就完成了。实际工作中可能需要设置表格的样式字体合并等 需求,有需求的可以继续看。

有关需求样式导出方法

  • 安装必须使用 npm i xlsx-js-style
  • 导入import XLSX from 'xlsx-js-style' 或 const XLSX = require('xlsx-js-style')
  • 在上图的示例中可以打印一下 sheet这个字段。如下图:

sheet.png

可以进行数据和单元格实际效果对比,A1,A2,A3,B1...等等分别代表不同的单元格。

style

其中:

  • !ref代表数据范围,可以理解为坐标。
  • v 代表vlue, t代表type(数据类型), s为string,n为number 这里还一个重要属性为 s,推测代表style。
  • s属性(style) 里面包含了大量属性,我验证过的会进行一个注释,不知道的就空着,大家自行探索。
      sheet.A1.s = {
        font: {
          sz: 13, // 字体大小 Number
          bold: true, // 加粗 true/false
          name: 'Calibri', // 字体
          color: { // 字体颜色
            rgb: 'ec2e8d'
          },
          underline: true, // default false 字体下面的线
          italic: true, // default false 斜体
          strike: true, // default false 中间划线
          shadow: false,
          vertAlign: false
        },
        fill: {
          fgColor: { // 背景颜色,不知道其他颜色格式是否生效
            rgb: 'bcedf9'
          },
          bgColor: {
            rgb: '00000'
          }
        },
        alignment: {
          horizontal: 'center', // 垂直方向的展示位置 center|bottom|top
          vertical: 'center', // 水平方向的展示位置 center|bottom|top
          wrap_text: true // 猜测是换行,不知道为啥不生效
        }
      }
merges

merges很简单,示例如下。

        // 数据
      const sheetData = [        ['公司员工表'],
        ['', '信息'],
        ['姓名', '年龄', '城市'],
        ['张三', 25, '上海'],
        ['李四', 30, '北京']
      ]
      // 合并示例
      sheet['!merges'] = [        {          s: { r: 0, c: 0 }, // 合并开始位置          e: { r: 1, c: 5 } // 合并结束位置 c:列位置(0开始) r:表示行位置(0开始)        },        {          s: { r: 2, c: 1 }, // 合并开始位置          e: { r: 2, c: 5 } // 合并结束位置 c:列位置 r:表示行位置        }      ]

实际导出效果如下

meg.png

如果加上上面的style,效果如图

style.png

rols&cols

该功能设置列宽和行高的

      const cols = [        {          wpx: 100        },        {          wpx: 300        },        {          wpx: 600        }      ]
      sheet['!cols'] = cols

完整代码示例和效果图

<template>
<div style="width: 600px;height: 300px;position: relative;color: #ec2e8d;"  id="echartBox">
  <button @click="test">测试</button>
</div>
</template>

<script>
import XLSX from 'xlsx-js-style'
// const XLSX = require('xlsx-js-style')
export default {
  data () {
    return {

    }
  },
  mounted () {
  },
  methods: {
    test () {
      const sheetData = [
        ['公司员工表'],
        ['', '信息'],
        ['姓名', '年龄', '城市'],
        ['张三', 25, '上海'],
        ['李四', 30, '北京']
      ]
      const sheet = XLSX.utils.aoa_to_sheet(sheetData)
      sheet['!merges'] = [
        {
          s: { r: 0, c: 0 }, // 合并开始位置
          e: { r: 1, c: 5 } // 合并结束位置 c:列位置(0开始) r:表示行位置(0开始)
        },
        {
          s: { r: 2, c: 1 }, // 合并开始位置
          e: { r: 2, c: 5 } // 合并结束位置 c:列位置 r:表示行位置
        }
      ]
      sheet.A1.s = {
        font: {
          sz: 13, // 字体大小 Number
          bold: true, // 加粗 true/false
          name: 'Calibri', // 字体
          color: { // 字体颜色
            rgb: 'ec2e8d'
          },
          underline: true, // default false 字体下面的线
          italic: true, // default false 斜体
          strike: true, // default false 中间划线
          shadow: false,
          vertAlign: false
        },
        fill: {
          fgColor: { // 背景颜色,不知道其他颜色格式是否生效
            rgb: 'bcedf9'
          },
          bgColor: {
            rgb: '00000'
          }
        },
        alignment: {
          horizontal: 'center', // 垂直方向的展示位置 center|bottom|top
          vertical: 'center', // 水平方向的展示位置 center|bottom|top
          wrap_text: true // 猜测是换行,不知道为啥不生效
        }
      }
      const cols = [
        {
          wpx: 100
        },
        {
          wpx: 300
        },
        {
          wpx: 600
        }

      ]
      sheet['!cols'] = cols
      const etx = XLSX.utils.book_new()
      XLSX.utils.book_append_sheet(etx, sheet, '测试')
      XLSX.writeFile(etx, '测试.xlsx')
    }
  }
}
</script>
<style>
</style>

效果图:

Snipaste_2024-01-25_16-20-09.png