vue项目将文件导出excel,pdf,图片

本文介绍了如何使用JavaScript库(如XLSX,pdfMake,dom-to-image)在项目中实现数据导出功能,包括将数据导出为Excel文件,生成带有中文字体的PDF文件,以及从HTML元素截图并下载为PNG图片。
摘要由CSDN通过智能技术生成
/**
 * @module Utils
 * @description 功能类函数集合
 * @author li cong
 * @date 2024-03-26
 */

import * as XLSX from 'xlsx'
import * as pdfMake from 'pdfmake-support-chinese-fonts/pdfmake.min'
import * as pdfFonts from 'pdfmake-support-chinese-fonts/vfs_fonts'
import domToImage from 'dom-to-image'

class Utils {
  /**
   * 将数据导出为Excel文件。
   * @author li cong
   * @param {Array|Object} data 要导出的数据,可以是数组或对象。
   * @param {String} filename 导出的文件名,默认为'default.xlsx'。
   */

  exportToExcel(data, filename = 'default') {
    if (!Array.isArray(data) && typeof data !== 'object') {
      console.error('Invalid data format. Expected array or object.')
      return false
    }
    if (typeof filename !== 'string') {
      console.error('Invalid filename. Expected a string.')
      return false
    }
    let jsonData
    if (Array.isArray(data)) {
      jsonData = data
    } else if (typeof data === 'object' && data !== null) {
      jsonData = [data]
    } else {
      console.error('Invalid data format. Expected array or object.')
      return false
    }

    const worksheet = XLSX.utils.json_to_sheet(jsonData)
    // 计算每列的最大文本长度
    const columnWidths = jsonData.reduce((acc, row) => {
      Object.keys(row).forEach(col => {
        const cellLength = String(row[col]).length
        acc[col] = Math.max(acc[col] || 0, cellLength)
      })
      return acc
    }, {})

    // 根据最大文本长度设置列宽
    Object.keys(columnWidths).forEach(col => {
      worksheet['!cols'] = worksheet['!cols'] || []
      worksheet['!cols'].push({ wch: columnWidths[col] + 1 })
    })
    const workbook = XLSX.utils.book_new()
    XLSX.utils.book_append_sheet(workbook, worksheet, 'Sheet1')
    XLSX.writeFile(workbook, filename + '.xlsx')
    return true
  }

  /**
   * 将数据导出为PDF文件。
   * @author li cong
   * @param {Array} header 表头数据,需要和表格列对应
   * @param {Array} data 要导出的数据(多维数组-[[1,2],[3,4]])
   * @param {String} filename 导出的文件名,默认为'default.pdf'
   * @param {String} title 页面标题,默认为'default'
   * @example 页面引入调用示例
   * recordData: [
        {
          uid: 123,
          activityName: '活动名称',
          ranking: '送礼Top1',
          type: '类型1',
          ID: 345,
          num: 999,
          time: 1648779794
        },
        {
          uid: 545231,
          activityName: '活动名称2',
          ranking: '送礼Top2',
          type: '类型2',
          ID: 782,
          num: 999,
          time: 1648879794
        }
      ]
      const header = ['UID', '活动名称', '排名', '类型', 'ID', '数量', '时间']
      const data = this.recordData.map(item => [
        item.uid,
        item.activityName,
        item.ranking,
        item.type,
        item.ID,
        item.num,
        item.time
      ])
      Utils.exportToPDF(header, data, '活动奖励自动发放记录','发放记录')
   */
  exportToPDF(
    header = ['x', 'x', 'x'],
    data = [[1, 2, 3]],
    filename = 'default',
    title = 'default'
  ) {
    // 检查参数是否符合预期
    if (!Array.isArray(header) || header.length === 0) {
      console.error('Invalid parameter: header. Please check the input parameters.')
      return false
    }

    if (!Array.isArray(data) || data.length === 0 || !data.every(Array.isArray)) {
      console.error('Invalid parameter: data. Please check the input parameters.')
      return false
    }

    if (typeof filename !== 'string' || typeof title !== 'string') {
      console.error('Invalid parameter: filename or title. Please check the input parameters.')
      return false
    }
    /* 字体 */
    pdfMake.vfs = pdfFonts.pdfMake.vfs
    pdfMake.fonts = {
      /* 注意:后缀必须大写(源码的vfs_fonts.js文件第二行说明:"fzhei-jt.TTF": ) */
      fangzhen: {
        normal: 'fzhei-jt.TTF',
        bold: 'fzhei-jt.TTF',
        italics: 'fzhei-jt.TTF',
        bolditalics: 'fzhei-jt.TTF'
      }
    }
    const docDefinition = {
      content: [
        { text: title, alignment: 'center', fontSize: 20 },
        {
          table: {
            headerRows: 1,
            // widths: ['*', '*', '*', '*', '*', '*', '*'], //生成适合数据的表格宽度,并且宽度将由内容自动决定。(要不然很丑)
            widths: Array(header.length).fill('*'),
            body: [header, ...data]
          }
        }
      ],
      defaultStyle: {
        font: 'fangzhen'
      }
    }

    pdfMake.createPdf(docDefinition).download(filename + '.pdf')
    return true
  }

  /**
   * 将指定部分下载为png图片。
   * @author li cong
   * @param {HTMLElement} element 需要截图的HTML元素。
   * @param {String} filename 导出的文件名,默认为'default'。
   */
  exportToPng(element = null, filename = 'default') {
    if (!(element instanceof HTMLElement)) {
      console.error('HTMLElement Error:请传入需要截图的HTML元素')
      return false
    }
    domToImage.toPng(element).then(function(dataUrl) {
      const link = document.createElement('a')
      link.href = dataUrl
      link.download = `${filename}.png`
      link.style.display = 'none'
      document.body.appendChild(link)
      link.click()
      document.body.removeChild(link)
    })
    return true
  }
}

const utils = new Utils()
export default utils

这个代码可以帮助项目中需要导出数据文件的功能,复制代码到项目中直接使用

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值