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

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。