导入Excel并回显 - web前端 | MrNobody = MrNobody's Blog = 保持呼吸 不要断气

# 上传表单数据回显

需要安装并且导入 Excel 表格解析插件
yarn add xlsx -S

import { read, utils } from 'xlsx'

<!--
:auto-upload="false" 是否在选取文件后立即进行上传
:on-change 文件状态改变时的钩子,添加文件、上传成功和上传失败时都会被调用
accept 接受上传的文件类型
:show-file-list='false' 是否显示选取文件的列表
  -->
<el-upload action="" :auto-upload="false" :on-change="handleChange" class="el-upload" accept=".xlsx">
  <el-button size="small" type="primary" class="el-btn">点击上传</el-button>
  <div slot="tip">
    只能上传xlsx文件,且不超过5MB
  </div>
</el-upload>
<el-table v-if="tableHead.length" :data="tableData[0]" style="width: 100%">
  <el-table-column v-for="(data, key) in tableHead" :prop="data" :label="data" :key="key" width="180">
  </el-table-column>
</el-table>

使用 element ui 中的上传组件,点击按钮上传文件,触发文件状态改变事件 handleChange

// 上传表格触发事件
handleChange (file) {
  console.log(file)
  // 获取文件名分割后缀名 判断是是不是 Excel 文件
  const extension = file.name.split('.')[1] === 'xls'
  const extension2 = file.name.split('.')[1] === 'xlsx'
  // 文件大小
  const isLt2M = file.size / 1024 / 1024 < 2
  // 如果不是 Excel 文件就弹出错误消息
  if (!extension && !extension2) {
    return this.$message.error('上传文件只能是 xls、xlsx 格式!')
    
  }
  // 判断文件大小是否超过 2MB
  if (!isLt2M) {
    return this.$message.error('上传文件大小不能超过 2MB!')
  }
  // 清空表格数据
  this.tableData = []
  this.tableHead = []
  const files = { 0: file }
  this.readExcel(files)
},
readExcel (file) {
// 创建一个 FileReader 对象
const fileReader = new FileReader()
// 当文件读取完成时,触发 onload 事件
fileReader.onload = ev => {
  try {
    const data = ev.target.result
    const workbook = read(data, { type: 'binary' })
    // 取对应表生成 json 表格内容
    workbook.SheetNames.forEach(item => {
      this.tableData.push(utils.sheet_to_json(workbook.Sheets[item]))
    })
    // 该算法仅针对表头无合并的情况
    if (this.tableData.length > 0) {
      // 获取 excel 中第一个表格数据 tableData [0][0],并且将表头提取出来
      for (const key in this.tableData[0][0]) {
        this.tableHead.push(key)
      }
    }
    // 重写数据
  } catch (e) {
    console.log('error:' + e)
    return false
  }
}
fileReader.readAsBinaryString(file[0].raw)
},

# 将表格转换成后端接受的数据,并且回显

此方法需要再字段中自定义需要显示的表格 第一种方式则不需要

// utils.js 
// 按照二进制读取文件
export function readFile(file) {
  // console.log(file);
  return new Promise(resolve => {
    let reader = new FileReader()
    reader.readAsBinaryString(file)
    reader.onload = e => {
      resolve(e.target.result)
    }
  })
}
// 字段对应表
export let character = {
  toiletNumber: {
    text: '厕所编号',
    type: 'string'
  },
  toiletType: {
    text: '厕所类型',
    type: 'string'
  },
  territory: {
    text: '所属地',
    type: 'string'
  },
  owner: {
    text: '所有者(多个用英文逗号分隔)',
    type: 'string'
  },
  telephone: {
    text: '联系方式(多个用英文逗号分隔且联系方式顺序要和所有者一致)',
    type: 'string'
  },
  year: {
    text: '年度',
    type: 'string'
  },
  address: {
    text: '地址',
    type: 'string'
  },
  constructionStatus: {
    text: '施工状态',
    type: 'string'
  },
  whetherToRenovateOrNot: {
    text: '是否改造提升',
    type: 'string'
  },
}
<div>
  <div class="buttonBox">
    <el-upload action accept=".xlsx,.xls" :auto-upload="false" :show-file-list="false" :on-change="handle"><el-button
        type="primary" slot="trigger">选取 Excel 文件</el-button>
    </el-upload>
  </div>
  <div class="tableBox" v-show="show" >
    <el-table :data="tempData" border style="width: 100%">
      <el-table-column prop="toiletNumber" label="厕所编号" min-width="50%"></el-table-column>
      <el-table-column prop="toiletType" label="厕所类型" min-width="50%"></el-table-column>
      <el-table-column prop="territory" label="所属地" min-width="50%"></el-table-column>
      <el-table-column prop="owner" label="所有者(多个用英文逗号分隔)" min-width="50%"></el-table-column>
      <el-table-column prop="telephone" label="联系方式(多个用英文逗号分隔且联系方式顺序要和所有者一致)" min-width="50%"></el-table-column>
      <el-table-column prop="year" label="年份" min-width="50%"></el-table-column>
      <el-table-column prop="address" label="地址" min-width="50%"></el-table-column>
      <el-table-column prop="constructionStatus" label="施工状态" min-width="50%"></el-table-column>
      <el-table-column prop="whetherToRenovateOrNot" label="是否改造提升" min-width="50%"></el-table-column>
    </el-table>
  </div>
</div>
import xlsx from 'xlsx'
import { Loading } from 'element-ui'
import { readFile, character, } from '../assets/js/utils'
export default {
  data() {
    return {
      tempData: [],
      // 是否展示表格
      show: false
    }
  },
  methods: {
    async handle(e) {
      let file = e.raw
      // 没有文件则返回
      if (!file) return
      this.show = false
      let loading = Loading.service({
        background: 'rgba(0,0,0,.5)'
      })
      // 使用工具类按照二进制读取文件 赋值给 data
      let data = await readFile(file)
      // 插件解析表格进制数据
      let workbook = xlsx.read(data, { type: 'binary' }),
        worksheet = workbook.Sheets[workbook.SheetNames[0]],
        list = xlsx.utils.sheet_to_json(worksheet)
      // 把读取出来的数据变为可以提交为服务器的数据格式
      let arr = []
      list.forEach(item => {
        let obj = {}
        // 循环渲染字段
        for (let  in character) {
          //hasOwnProperty () 判断属性是否存在 如果存在 返回 true 否则 else
          if (!character.hasOwnProperty(key)) break
          let v = character[key],
            text = v.text,
            type = v.type
          v = item[text] || ''
          type === 'string' ? (v = String(v)) : null
          type === 'number' ? (v = Number(v)) : null
          obj[key] = v
        }
        obj.time = new Date()
        obj.constructionStatus = "竣工"
        obj.whetherToRenovateOrNot = "否"
        arr.push(obj)
      })
      // 展示到页面中
      this.show = true
      this.tempData = arr
      loading.close()
    }
  }
}
更新于 阅读次数

请我喝[茶]~( ̄▽ ̄)~*

Mr_Nobody 微信支付

微信支付

Mr_Nobody 支付宝

支付宝

Mr_Nobody 贝宝

贝宝