vue+exceljs+file-saver导出excel文件加水印

1 安装依赖

npm install file-saver --save
npm install exceljs 

2 在plugins文件夹下创建creatWsSheet.js文件

image.png
/**
 *
 * 导出 excel(带水印) 公共方法
 * @param header v 为头,k 为对应 data 数据的 name
 * 例:
    const header = [
      {
        k: 'region',
        v: '所属区域',
      }
    ]
 * @param data 要导出的数据
    例:
    const data = [
      {
        region:'广州'
      },
      {
        region:'深圳'
      }
    ]
 * @param filename 导出的 excel 文件名称
 * @param sheetName 指定第一个工作表的名称
 * @param staff 水印名称
 * @param params 导出多个工作表
 * 格式为:
 * [{header:[],data:[],sheetName:''}]
 * @returns
 */
 import { saveAs } from 'file-saver';
const ExcelJS = require('exceljs');
/* eslint-disable */
 export const createWsSheet = (
    header, 
    columns, 
    dataList, 
    staff,
    filename,
) => {
    if (!((header && dataList) && (header.length && dataList.length))) {
        // Message.error('导出失败');
        return;
    }
    const EXCEL_TYPE = "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet;charset=UTF-8";
    
    // 创建工作簿
    const workbook = new ExcelJS.Workbook();
    workbook.created = new Date()
    workbook.modified = new Date()
    // 获取水印
    const base64 = setWatermark(staff);
    const imageId1 = workbook.addImage({ base64, extension: 'png' });
    // 创建带有红色标签颜色的工作表
    let worksheet = workbook.addWorksheet('Sheet1', {  //新建工作表
      views: [{ state: 'frozen', xSplit:0, ySplit: 2}], // 冻结视图:xSplit:冻结多少列

  });
    worksheet.properties.defaultColWidth = 14
      worksheet.columns = columns
      worksheet.columns.forEach(function (column) {
        var dataMax = 0;
        column.eachCell({ includeEmpty: true }, function (cell) { 
          dataMax = cell.value?cell.value.toString().length:0;
          if(dataMax <= (column.header.length+2) ){
              if(column.width > dataMax){
                  //retain its default width
              } else {
                  column.width = column.header.length+3;
              }
          } else {
              column.width = dataMax+3;
             column.header.length = dataMax+3;
          }
          dataMax = 0;
        })
        
      });
    // 添加背景图片
    worksheet.addBackgroundImage(imageId1);
    worksheet.getRow(1).values = [`${filename}(${staff})`];
    worksheet.mergeCells(1, 1, 1, columns.length) //第1行  第1列  合并到第1行的第n列

    // worksheet.getRow(1).height = 40
    worksheet.getRow(1).eachCell({ includeEmpty: true }, (cell, colNumber) => {
      worksheet.getRow(1).getCell(colNumber).fill = {
        type: 'pattern',
        pattern: 'solid',
        // fgColor: { argb: 'ffd3d3d3' },
        // bgColor: { argb: 'FF0000FF' },
        
      }
      worksheet.getRow(1).getCell(colNumber).font = {
        bold: true,
      }
      worksheet.getRow(1).getCell(colNumber).border = {
        top: { style: 'thin' },
        left: { style: 'thin' },
        bottom: { style: 'thin' },
        right: { style: 'thin' },
      }
    })
    // 添加数据
    worksheet.getRow(2).values = []
    worksheet.getRow(2).values = header
    
    // 表头样式

    worksheet.getRow(2).eachCell({ includeEmpty: true }, (cell, colNumber) => {
        worksheet.getRow(2).getCell(colNumber).fill = {
          type: 'pattern',
          pattern: 'solid',
          // fgColor: { argb: 'ffd3d3d3' },
          // bgColor: { argb: 'FF0000FF' },
          
        }
        worksheet.getRow(2).getCell(colNumber).font = {
          bold: true,
        }
        worksheet.getRow(2).getCell(colNumber).border = {
          top: { style: 'thin' },
          left: { style: 'thin' },
          bottom: { style: 'thin' },
          right: { style: 'thin' },
        }
       
      })
     
      worksheet.addRows(dataList)
      // 自定义样式
      worksheet.eachRow({ includeEmpty: true }, (row, rowNumber) => {
        // if (rowNumber > 2) {
        //   worksheet.getRow(rowNumber).height = 28.6
        // }
        worksheet.getRow(rowNumber).eachCell({ includeEmpty: true }, (cell, colNumber) => {
          // 文字居中
          worksheet.getRow(rowNumber).getCell(colNumber).alignment = {
            vertical: 'middle',
            horizontal: 'center',
            wrapText: true  // 设置自动换行
          }
          //边框样式
          worksheet.getRow(rowNumber).getCell(colNumber).border = {
            top: { style: 'thin' },
            left: { style: 'thin' },
            bottom: { style: 'thin' },
            right: { style: 'thin' },
          }
          
        })
      })
      worksheet.columns.forEach((column) => {
         column.width = 20;
      });
      workbook.xlsx.writeBuffer().then((buffer) => {
        const blob = new Blob([buffer], { type: EXCEL_TYPE })
        saveAs(blob, `${filename}.xlsx`)
      })

    
    // Message.success('导出成功');
};
/**
 * 判断该数据是否为空
 * @param data 要判断的数据
 * @returns 布尔值:true/false
 */
const isNull = (data) => {
    return !!data;
}

/**
 * 绘画水印
 * @param str 要做出水印的文字
 * @returns Base64
 */
const setWatermark = (str) => {
    let id = '1.23452384164.123412416';

    if (document.getElementById(id) !== null) {
        document.body.removeChild(document.getElementById(id));
    }
    // 创建一个画布
    let can = document.createElement('canvas');
    // 设置画布的长宽
    can.width = 500;
    can.height = 220;
    let cans = can.getContext('2d');
    // 旋转角度
    cans.rotate(-25 * Math.PI / 180);
    // 设置字体大小
    cans.font = "300 30px Microsoft JhengHei";
    // 设置填充绘画的颜色、渐变或者模式
    cans.fillStyle = "rgba(130, 142, 162, 0.5)";
    // 设置文本内容的当前对齐方式
    cans.textAlign = 'center';
    // 设置在绘制文本时使用的当前文本基线
    cans.textBaseline = 'Middle';
    cans.fillText(str, 80, 180);

    const dataURL = can.toDataURL('image/png');
    return dataURL;
}

3 引用

<template>
  <div>
     <div @click="exportExcel"  >导出EXCEL</div>
  </div>
</template>
 <script>
      import { createWsSheet } from '../../../plugins/creatWsSheet'
   export default {
      data() {
        return {
            itemsExcel: [],
          }
      },
 methods: {
      async getDbType() {
      this.applyDb = await getDict({ dicttype: "dbType"});
    },
      //导出报告
      exportExcel(){
        const header = ["平台系统名称", "是否并网", "主机关联数据", "数据库关联数据"]
            const columns = header.map((item) => {
                return {
                  header: item,
                  key: item,
                }
            })
            let itemsExcel = this.watermark == ''  ? this.itemsExcel : this.itemsExcel.slice(0,this.exportNum)  //测试版加水印,导出前exportNum条数据
            const datas =  itemsExcel.map((item) => {
                let res = {}
                res.平台系统名称 = item.name
                res.是否并网 = item.isonline
                res.主机关联数据 = item.host
                res.数据库关联数据 = item.db          
                return res
            })
            createWsSheet(header, columns, datas, this.watermark ,'平台系统清单');
      },
    }

</script>

4 结果

image.png

参考资料:
1:https://www.cnblogs.com/0627st/p/17359010.html

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 200,783评论 5 472
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 84,396评论 2 377
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 147,834评论 0 333
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,036评论 1 272
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,035评论 5 362
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,242评论 1 278
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,727评论 3 393
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,376评论 0 255
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,508评论 1 294
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,415评论 2 317
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,463评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,140评论 3 316
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,734评论 3 303
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,809评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,028评论 1 255
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 42,521评论 2 346
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,119评论 2 341