前端xlsx导入导出 简单易懂

425 阅读3分钟

xlsx安装

在终端执行:

npm install xlsx --save-dev

引入包:

import * as XLSX from "xlsx"

XLSX对象包含的内容比较多主要有以下内容:

xls.png

我们用的比较多的是read、utils、write,所以经常也会按需引入:

import {read,utils,write} from "xlsx"

官方文档:sheetjs

Excel基础

excel表格有几个基础内容:

  • workbook
  • sheet

base.png

导入Excel

主要是利用XLSX.read()方法读取文件,这个方法接收两个参数,并返回一个workbook对象,语法:

read(data,option)
  • data 文件数据
  • options 配置项,内容太多(详细查看配置项),主要介绍type,type表示以什么格式解析数据,type主要取值如下:
    • base64:文件的 Base64 编码
    • binary:二进制字符串
    • string:JS 字符串(仅适用于 UTF-8 文本格式)
    • buffer: nodejs Buffer
    • array: Uint8Array,8位无符号数组;
    • file: 将读取的文件的路径(仅限 NodeJS)

利用<input type=file>选择本地文件practice.xls,然后利用read方法将文件二进制数据转换为workbook对象,并将这个workbook对象打印出来:

import {read} from "xlsx"

const input = document.createElement('input')
input.type="file"
input.onchange=()=>{
  const file = input.files[0]
  const fileread= new FileReader()
  fileread.readAsBinaryString(file)
  fileread.onload=()=>{
    const result=fileread.result
    const wb=read(result,{type:"binary"})
    console.log(wb)
  }
}
document.body.append(input)

在浏览器上打印结果为:

workbook.png

这个workbook对象上包含了很多属性,其中Sheets属性是我们需要的,这个Sheets属性是一个对象,保存了excel表格不同sheet的数据,展开Sheets可以看到:

sheet.png

这里我们选择的表格只用到了一个sheet,其他两个sheet都是空数据,我们可以遍历Sheet1将数据转换为我们想要的格式,当然xlsx也提供了API,我们可以调用xlsx中的API将sheet转换为不同格式,这些API都在XLSX.utils中,其中比较常用的有:

  • utils.sheet_to_csv()
  • utils.sheet_to_html()
  • utils.sheet_to_json()
  • utils.sheet_to_txt()

例如上面的代码我们可以通过utils.sheet_to_json()将sheet转换为json:

import {read,utils} from "xlsx"//新增

const input = document.createElement('input')
input.type="file"
input.onchange=()=>{
  const file = input.files[0]
  const fileread= new FileReader()
  fileread.readAsBinaryString(file)
  fileread.onload=()=>{
    const result=fileread.result
    const wb=read(result,{type:"binary"})
    const sheet=wb.Sheets.Sheet1//新增
    const data=utils.sheet_to_json(sheet)//新增
    console.log(data)
  }
}
document.body.append(input)

打印结果:

json.png

我们也可以通过utils.sheet_to_html()将sheet转换为html,然后呈现在网页上:

import {read,utils} from "xlsx"//新增

const input = document.createElement('input')
input.type="file"
input.onchange=()=>{
  const file = input.files[0]
  const fileread= new FileReader()
  fileread.readAsBinaryString(file)
  fileread.onload=()=>{
    const result=fileread.result
    const wb=read(result,{type:"binary"})
    const sheet=wb.Sheets.Sheet1
    const data=utils.sheet_to_html(sheet)//新增
    const div=document.createElement("div")//新增
    div.innerHTML=data.split(/<body>|<\/body>/)[1]//新增
    document.body.append(div)//新增
  }
}
document.body.append(input)

效果:

file.gif

导出Excel

想要导出Excel文件,我们可以分几步完成:

  1. 创建一个workbook
  2. 需要一个保存目标数据数据的sheet对象
  3. 将sheet对象插入workbook中
  4. 将workbook转换为blob对象,便于通过a标签实现下载

xlsx为我们提供了API,我们可以使用这些API将目标数据经过处理直接转换为sheet对象,常用的是:

  • utils.json_to_sheet():将一个由对象组成的数组转成sheet
  • utils.aoa_to_sheet():这个工具类最强大也最实用了,将一个二维数组转成sheet,会自动处理number、string、boolean、date等类型数据
  • utils.table_to_sheet():将一个table dom直接转成sheet,会自动识别colspan和rowspan并将其转成对应的单元格合并

首先创建一个workbook对象:

const wb=utils.book_new()

需要一个保存目标数据数据的sheet对象(这里我们使用utils.json_to_sheet()):

const data=[
  {name:"Apil",age:18,sex:1},
  {name:"Wamn",age:18,sex:0},
  {name:"Tom",age:20,sex:1},
  {name:"Kevin",age:15,sex:0},
]
const sheet=utils.json_to_sheet(data)

将sheet对象插入到workbook中:

utils.book_append_sheet(wb,sheet,"sheet1")

将workbook对象转换为blob对象:

function wb_to_blob(wb){
  //先将wb转换为二进制字符串
  const wbs=write(wb,{
    bookType: 'xlsx',//要生成的文件类型
    type:"binary",//二进制类型
  })
  const buffer=new ArrayBuffer(wbs.length)
  const view=new Uint8Array(buffer)
  for(let i=0;i<wbs.length;i++){
    view[i]=wbs.charCodeAt(i) ?? 0xff
  }
  return new Blob([view],{type:"application/octet-stream"})
}
const blob=wb_to_blob(wb)//调用方法得到blob

利用a标签实现下载:

function download(blob,name){
  const a=document.createElement('a')
  a.href=URL.createObjectURL(blob)
  a.download=name || ""
  a.click()
  a.remove()
  URL.revokeObjectURL(blob)
}
//可以在页面上写一个button,点击实现下载
const button=document.createElement("button")
button.textContent="下载"
button.onclick=()=>{
  download(blob,"excel.xls")
}
document.body.append(button)

最终效果:

download.gif