前端excel文件处理,vue2 、file-saver、xlsx, excel文件生成与excel文件链接数据导出

news/2024/7/21 3:51:46 标签: 前端, excel, 文件导出, 文件下载

excel_0">1、前端excel文件生成

安装插件

npm install file-saver --save

如使用TS开发,可安装file-saver的TypeScript类型定义

npm install @types/file-saver --save-dev

下载文件流

import { saveAs } from 'file-saver'
/**
 *
 * @param {*} fileStream // 文件流
 * @param {*} saveFileName // 文件下载名称
 * @returns
 */
export const downloadFile = (fileStream, saveFileName = '.xlsx') => {
  return new Promise((resolve, reject) => {
    const blob = new Blob([fileStream])
    // 兼容IE
    if (navigator.msSaveBlob) {
      navigator.msSaveBlob(blob, saveFileName)
    } else {
      const url = window.URL.createObjectURL(blob)
      saveAs(url, saveFileName + '.xlsx')
    }
    resolve()
  })
}
/**
 * @description 方法调用
 */
downloadFile(fileStream, saveFileName).then(res => {
  console.log('下载成功!')
})

本地文件下载

import { saveAs } from 'file-saver'
/**
 *
 * @param {*} localFileUrl 本地地址
 * @param {*} saveFileName 文件名称
 * @returns
 */
export const downloadFile = (localFileUrl, saveFileName) => {
  return new Promise((resolve, reject) => {
    axios({
      url: localFileUrl, // 文件地址
      method: 'get',
      responseType: 'blob'
    })
      .then(res => {
        const blob = new Blob([res.data])
        if (navigator.msSaveBlob) {
          navigator.msSaveBlob(blob, saveFileName)
        } else {
          const url = window.URL.createObjectURL(blob)
          saveAs(url, saveFileName)
        }
        resolve()
      })
      .catch(err => {
        if (err.message === 'Request failed with status code 404') {
          // 未找到相关文件
        } else {
          // 下载失败
        }
        reject(err)
      })
  })
}

/**
 * @description 方法调用
 */
downloadFile(localFileUrl, saveFileName).then(res => {
  console.log('下载成功!')
})

文件下载(列宽自适应)

import fs from 'file-saver'
import XLSX from 'xlsx'
export function xlsxGenerate(json, fields, filename = '.xlsx') {
  json.forEach(item => {
    for (let i in item) {
      if (fields.hasOwnProperty(i)) {
        item[fields[i]] = item[i]
      }
      delete item[i]
    }
  })
  let sheetName = filename
  let wb = XLSX.utils.book_new()
  let ws = XLSX.utils.json_to_sheet(json, {
    header: Object.values(fields)
  })
  const defaultCellStyle = {
    font: {
      name: 'Verdana',
      sz: 16,
      color: 'FF00FF88'
    },
    alignment: {
      horizontal: 'center',
      vertical: 'center'
    },
    fill: {
      fgColor: {
        rgb: 'FFFFAA00'
      }
    }
  }
  let headsArr = Object.values(fields)
  const headsWidth = headsArr.map(value => {
    if (/.*[\u4e00-\u9fa5]+.*$/.test(value)) {
      return parseFloat(value.toString().length * 2.1)
    } else {
      return parseFloat(value.toString().length * 1.1)
    }
  })
  // console.log("所有表头的宽度:", headsWidth);
  // 2.所有表体值的宽度
  json.unshift(fields)
  const rowsWidth = json.map(item => {
    const maxValue = Object.values(item).map((value, index) => {
      let valueWidth
      if (/.*[\u4e00-\u9fa5]+.*$/.test(value)) {
        valueWidth = parseFloat(value.toString().length * 2.1)
      } else {
        valueWidth = parseFloat(value.toString().length * 1.1)
      }
      return Math.max(valueWidth, headsWidth[index])
    })
    return maxValue
  })
  // console.log("每行数据对比出的最大宽度:", rowsWidth)
  // 3.对比每列最大值
  let aotuWidth = []
  rowsWidth.map((row, index) => {
    let maxWidth = []
    row.map((value, i) => {
      if (index === 0) {
        maxWidth.push({
          wch: value
        })
      } else {
        maxWidth.push({
          wch: Math.max(value, aotuWidth[i].wch)
        })
      }
    })
    aotuWidth = maxWidth
  })
  // ws["!rows"] // 杭高
  ws['!cols'] = aotuWidth // 列宽

  wb.SheetNames.push(sheetName)
  wb.Sheets[sheetName] = ws
  let wopts = {
    bookType: 'xlsx',
    bookSST: false,
    type: 'binary',
    cellStyles: true,
    defaultCellStyle: defaultCellStyle,
    showGridLines: false
  }
  let wbout = XLSX.write(wb, wopts)
  let blob = new Blob([s2ab(wbout)], {
    type: 'application/octet-stream'
  })
  fs.saveAs(blob, filename + '.xlsx')
}
/**
 * 数据下载
 * @param {*} header 表头
 * @param {*} tableData 数据
 */
dataDownload() {
  let headerArr = ['Name', 'Age', 'Address']
  let header = {
    title0: 'Name',
    title1: 'Age',
    title2: 'Address'
  }
  let tableData = [
    {
      Name: '喜洋洋',
      Age: '108',
      Address: '青青草原-羊村-2幢'
    },
    {
      Name: '美羊羊',
      Age: '108',
      Address: '青青草原-羊村-1幢'
    }
  ]
  let tableDataList = []
  tableData.forEach((item, index) => {
    let obj = {}
    for (let i = 0; i < headerArr.length; i++) {
      if (i === 0) {
        obj['title0'] = item.Name
      } else if (i === 1) {
        obj['title1'] = item.Age
      } else if (i === 2) {
        obj['title2'] = item.Address
      }
    }
    tableDataList.push(obj)
  })
  xlsxGenerate(tableDataList, header, '羊村登记表')
}

在这里插入图片描述表格显示,每列列宽自适应

xlsx文件链接数据导出

import fs from 'file-saver'
import XLSX from 'xlsx'
export function readWorkbookFromRemoteFile(url, callback) {
  var xhr = new XMLHttpRequest()
  xhr.open('get', url, true)
  xhr.responseType = 'arraybuffer'
  xhr.onload = function(e) {
    if (xhr.status == 200) {
      var tableData = new Uint8Array(xhr.response)
      var workbook = XLSX.read(tableData, { type: 'array' }) // 该方法接收一个二进制的数据,和数据的类型,返回解析完成后的对象
      if (callback) callback(workbook)
    }
  }
  xhr.send()
}
export function readWorkbook(workbook) {
  let sheetNames = workbook.SheetNames // 工作表名称集合
  let worksheet = workbook.Sheets[sheetNames[0]] // 这里我们只读取第一张sheet
  let csv = XLSX.utils.sheet_to_csv(worksheet)
  return csv2table(csv)
}
// 将csv转换成简单的表格,会忽略单元格合并,在第一行和第一列追加类似excel的索引
export function csv2table(csv) {
  let arrs = []
  let rows = csv.split('\n')
  let first_rows = rows.shift().split(',') // 第一行没用的
  rows.pop() // 最后一行没用的
  rows.forEach(function(row, idx) {
    let columns = row.split(',')
    let obj = {}
    columns.forEach(function(col, idx) {
      obj[first_rows[idx]] = col
    })
    arrs.push(obj)
  })
  return { first_rows, arrs }
}

方法调用

let urlNew = url.replace(/http:/, 'https:') // url xlsx文件链接,转https
readWorkbookFromRemoteFile(
  urlNew,
  workbook => {
    let param = readWorkbook(workbook)
    param.arrs // 表格数据
    param.first_rows // 表头
  }
)

http://www.niftyadmin.cn/n/477130.html

相关文章

SpringBoot:整合 Minio 文件上传操作

简介 对象存储服务OSS&#xff08;Object Storage Service&#xff09;是一种海量、安全、低成本、高可靠的云存储服务&#xff0c;适合存放任意类型的文件。容量和处理能力弹性扩展&#xff0c;多种存储类型供选择&#xff0c;全面优化存储成本&#xff0c;今天我这里主要讲解…

IntelliJ IDEA maven 引用本地 jar 文件

一、背景说明 由于某些特定原因&#xff0c;不能在远程maven仓库中下载所需要版本的jar文件&#xff0c;需要在maven中引用本地jar文件。 二、解决方案 1、创建 libs 目录 为了方便jar包管理&#xff0c;可以在工程目录下&#xff0c;创建一个与src目录平级的libs目录。如下…

dubbo升级至2.7.18版本后,客户端调用失败解决方案和原因

因安全需要决定对dubbo进行安全升级&#xff0c;升级至2.7.22版本&#xff0c;升级过程中遇到泛化调用失败 主要错误提示&#xff1a; Failed to invoke the method $invoke in the service org.apache.dubbo.rpc.service.GenericService. No provider available for the servi…

四、Docker镜像详情

学习参考&#xff1a;尚硅谷Docker实战教程、Docker官网、其他优秀博客(参考过的在文章最后列出) 目录 前言一、Docker镜像1.1 概念1.2 UnionFS&#xff08;联合文件系统&#xff09;1.3 Docker镜像加载原理1.4 重点理解 二、docker commit 命令2.1 是什么&#xff1f;2.2 命令…

shardingsphere-proxy 搭建mysql的分库分表

1、docker安装mysql5.7版本 拉取mysql的镜像 docker pull mysql:5.7创建mysql的配置目录&#xff0c;日志目录&#xff0c;数据存储的目录 mkdir -p /home/sunyuhua/docker/mysql/conf mkdir -p /home/sunyuhua/docker/mysql/logs mkdir -p /home/sunyuhua/docker/mysql/dat…

Chrome/Edge 浏览器多账号登录,测试同一业务系统的不同账号角色

文章目录 如何使用多账户&#xff1f;ChromeEdge 虽然说用不同浏览器测试也比较方便、还能顺带测试多浏览器兼容问题…… 但我是开发呀&#xff0c;我只想用我最习惯的谷歌浏览器完成快速开发&#xff0c;把功能铺上&#xff0c;专注于业务逻辑的开发 这些浏览器差异等只会给我…

k8s控制器之job--第五弹Job的自动清理

系统中已经完成的 Job 通常是不在需要里的&#xff0c;长期在系统中保留这些对象&#xff0c;将给 apiserver 带来很大的压力。如果通过更高级别的控制器&#xff08;例如 CronJobs&#xff09;来管理 Job&#xff0c;则 CronJob 可以根据其中定义的基于容量的清理策略&#xf…