使用xlsx-js-style进行数据导出excel并个性化表格

黄粱一梦2024-05-1610

介绍

官网介绍:

SheetJS with Style! Create Excel spreadsheets with basic styling options.This project is a fork of SheetJS/sheetjs combined with code from sheetjs-style (by ShanaMaid) and sheetjs-style-v2 (by Raul Gonzalez).All projects are under the Apache 2.0 License

翻译:带有样式的SheetJS!使用基本样式选项创建Excel电子表格。该项目是SheetJS/sheetjs的一个分支,结合了来自sheetjs-style(作者:ChanaMaid)和sheetjs-style-v2(作者:Raul Gonzalez)的代码。
所有项目都在Apache 2.0许可下

文档地址

安装

导出 excel 较常见的 js 库是之一是 xlsx,xlsx 算是基础版本,不能对单元格进行样式(对齐方式、文字颜色、背景颜色等)的修饰,如果需要修饰单元格,可使用 xlsx-js-style

npm install xlsx-js-style

引入

import { utils, writeFileXLSX,writeFile } from 'xlsx-js-style'

使用

<template>
  <div class="hello">
    <!-- 导出excel -->
    <button @click="exportExcelFile">导出excel</button>
    <button @click="xlsxButtonHandler">xlsx-stylebutton</button>
    <button @click="btnHandler">样式xlsx</button>
  </div>
</template>

<script lang="ts" setup>
import axios from 'axios';
import { utils, writeFileXLSX,writeFile } from 'xlsx-js-style'


let requestTabelData = [['订单号', '订单类型', '订单状态', '订单金额', '订单描述', '下单时间', '接单时间', '取消时间']]
/** 请求当前表格页面数据 */
let requestTabledata = () => {
  axios({
    method: "POST",
    url: "https://dev.usemock.com/664574ca424954b7e1865fbe/QueryOrderList"
  }).then(res => {
    console.log('请求成功', res);
    res.data.list.forEach((item: any) => {
      let obj = [item.prepayid, item.type, item.status, item.money, item.descrit, item.create_time, '', '']
      requestTabelData.push(obj)
    })
  }).catch(err => {
    console.log('请求失败', err);

  })
}

requestTabledata()

let exportExcelFile = () => {
  // 创建一个工作簿
  const workbook = utils.book_new();

  // 创建一个工作表
  const worksheet = utils.aoa_to_sheet(requestTabelData);

  // 将工作表添加到工作簿
  utils.book_append_sheet(workbook, worksheet, 'Sheet1');

  // 生成Excel文件
  writeFile(workbook, 'data.xlsx');
}


/* xlsx-stylebutton */
let xlsxButtonHandler = () => {
  /* 定义json对象列表 */
  let list = [
    {
      Name: 'Bill Clinton',
      Date: '2023-01-01',
      'Source category name': 'Excise Taxes',
      'Source subcategory name': 'Corporation Income Taxes',
    },
    {
      Name: 'GeorgeW Bush',
      Date: '2023-01-01',
      'Source category name': 'Excise Taxes',
      'Source subcategory name': 'Corporation Income Taxes',
    },
    {
      Name: 'Barack Obama',
      Date: '2023-01-01',
      'Source category name': 'Excise Taxes',
      'Source subcategory name': 'Corporation Income Taxes',
    },
    {
      Name: 'Donald Trump',
      Date: '2023-01-01',
      'Source category name': 'Excise Taxes',
      'Source subcategory name': 'Corporation Income Taxes',
    },
    {
      Name: 'Joseph Biden',
      Date: '2023-01-01',
      'Source category name': 'Excise Taxes',
      'Source subcategory name': 'Corporation Income Taxes',
    },
  ]

  /* 创建工作环境 */
  let work = utils.book_new()

  /* 创建工作表 */
  let sheet = utils.json_to_sheet(list)

  /* 设置单元格样式 */
  sheet['!cols'] = [
    { wpx: 150 },
    { wpx: 150 },
    { wpx: 150 },
    { wpx: 150 },
    { wpx: 150 },
    { wpx: 150 },
  ]


  sheet["A1"].s = {
    fill: {
      fgColor: { rgb: "c6dfdc" }, // 设置背景颜色为红色
    },
    font: {
      color: { rgb: "3bdf00" } // 设置文本颜色为蓝色
    }
  }


  utils.book_append_sheet(work, sheet, 'sheet1')


  writeFileXLSX(work, `${Math.random()}.xlsx`, {})
}





/** ----------------------------------------------------- */
const header = [
    [[]], // 占位
    [
        {}, // 占位
        {
            v: `工厂统计表 ${'\n'}`,
            t: 's',
            s: {
                font: {
                    sz: 15, //设置标题的字号
                    bold: true, //设置标题是否加粗
                    name: '宋体',
                },
                //设置标题水平竖直方向居中,并自动换行展示
                alignment: {
                    horizontal: 'center',
                    vertical: 'center',
                    wrapText: true,
                },
                fill: {
                    fgColor: { rgb: '9FE3FF' },
                },
            },
        },
    ],
]

const info = [
    [
        null,
        {
            v: '                                                                                                                                                                                                                                                                                                                                                                                                    统计时间:2023/01/01 00:00',
            t: 's',
            s: {
                fill: {
                    fgColor: { rgb: '9FE3FF' },
                },
            },
        },
    ],
    [
        null,
        {
            v: '                                                                                                                                                                                                                                                                                                                                                                                                    统计维度:按月',
            t: 's',
            s: {
                fill: {
                    fgColor: { rgb: '9FE3FF' },
                },
            },
        },
    ],
    [
        null,
        {
            v: '                                                                                                                                                                                                                                                                                                                                                                                                    统计周期:2023/01/01 至 2023/01/01',
            t: 's',
            s: {
                alignment: {
                    vertical: 'top',
                },
                fill: {
                    fgColor: { rgb: '9FE3FF' },
                },
            },
        },
    ],
]

const risk = [
    '序号',
    '险别',
    '企财险',
    '家财险',
    '机动车',
    '责任险',
    '意外险',
    '货运险',
    '保证险',
    '其他险',
]

const data = risk.map((e) => {
    return {
        v: e,
        t: 's',
        s: {
            font: {
                bold: true, //设置标题是否加粗
                name: '宋体',
            },
            //设置标题水平竖直方向居中,并自动换行展示
            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: '9FE3FF' },
            },
        },
    }
})

const random = (min: number, max: number): number => {
    return Math.floor(Math.random() * (max - min)) + min
}

const dataArr = () => {
    const items: (Object | null)[][] = []
    Array.apply(null, { length: 18 } as any).map((e, index: number) => {
        const item: (Object | null)[] = [null]
        Array.apply(null, { length: 10 } as any).map((ele, idx: number) => {
            item.push({
                v: idx === 0 ? index + 1 : random(1, 100000),
                t: 's',
                s: {
                    font: {
                        name: '宋体',
                    },
                    alignment: {
                        horizontal: 'center',
                        vertical: 'center',
                    },
                    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' } },
                    },
                },
            })
        })
        items.push(item)
    })
    return items
}

const exportFile = () => {
    var ws = utils.aoa_to_sheet([
        ...header,
        ...info,
        [null, ...data],
        ...dataArr(),
    ])

    // 合并单元格
    if (!ws['!merges']) ws['!merges'] = []
    ws['!merges'].push(utils.decode_range('B2:K2'))
    ws['!merges'].push(utils.decode_range('B3:K3'))
    ws['!merges'].push(utils.decode_range('B4:K4'))
    ws['!merges'].push(utils.decode_range('B5:K5'))
    ws['!merges'].push(utils.decode_range('A2:A5'))
    ws['!merges'].push(utils.decode_range('L2:L5'))

    // 设置列宽
    // cols 为一个对象数组,依次表示每一列的宽度
    if (!ws['!cols']) ws['!cols'] = []
    ws['!cols'] = [
        { wpx: 70 },
        { wpx: 118 },
        { wpx: 118 },
        { wpx: 118 },
        { wpx: 118 },
        { wpx: 118 },
        { wpx: 118 },
        { wpx: 118 },
        { wpx: 118 },
        { wpx: 118 },
        { wpx: 200 },
    ]

    // 设置行高
    // rows 为一个对象数组,依次表示每一行的高度
    if (!ws['!rows']) ws['!rows'] = []
    ws['!rows'] = [
        { hpx: 0 },
        { hpx: 40 },
        { hpx: 15 },
        { hpx: 15 },
        { hpx: 20 },
        { hpx: 20 },
        ...Array.apply(null, { length: dataArr().length } as any).map(() => {
            return { hpx: 20 }
        }),
    ]
    var wb = utils.book_new()
    utils.book_append_sheet(wb, ws, 'Sheet1')
    writeFile(wb, 'SheetJSVueAoO.xlsx')
}

let btnHandler =() => exportFile()


</script>

<!-- Add "scoped" attribute to limit CSS to this component only -->
<style scoped lang="less">
h3 {
  margin: 40px 0 0;
}

ul {
  list-style-type: none;
  padding: 0;
}

li {
  display: inline-block;
  margin: 0 10px;
}

a {
  color: #42b983;
}
</style>

效果

image.png

image.png

分类:前端Vue

标签:前端vue3随笔

上一篇ElementUI响应式Layout布局xs,sm,md,lg,xl 下一篇IntersectionObserver--交叉观察器

版权声明

本文系作者 @黄粱一梦 转载请注明出处,文中若有转载的以及参考文章地址也需注明。\(^o^)/~

Preview