zoukankan      html  css  js  c++  java
  • vue导入,导出,列表展示excel数据

      • vue导入导出,名称过滤,不需要的功能可自行删减,列表获取接口展示
     1 <template>
     2   <div class="index" v-loading.fullscreen.lock="fullscreenLoading" element-loading-text="拼命加载中...">
     3     <input type="file" @change="importFile(this)" id="imFile" style="display: none"
     4            accept="application/vnd.openxmlformats-officedocument.spreadsheetml.sheet, application/vnd.ms-excel"/>
     5     <a id="downlink"></a>
     6     <el-button class="button" @click="uploadFile()">导入</el-button>
     7     <el-button class="button" @click="downloadFile(list)">导出</el-button>
     8     <el-select
     9       v-model="search"
    10       multiple
    11       filterable
    12       placeholder="请输入关键词"
    13       :loading="loading">
    14       <el-option
    15         v-for="item in list"
    16         :key="item.id"
    17         :label="item.name"
    18         :value="item.id">
    19       </el-option>
    20     </el-select>
    21     <!--错误信息提示-->
    22     <el-dialog title="提示" v-model="errorDialog" size="tiny">
    23       <span>{{errorMsg}}</span>
    24       <span slot="footer" class="dialog-footer">
    25           <el-button type="primary" @click="errorDialog=false">确认</el-button>
    26         </span>
    27 
    28     </el-dialog>
    29     <!--展示导入信息-->
    30     <el-table :data="listClone" tooltip-effect="dark">
    31       <el-table-column label="名称" prop="name" show-overflow-tooltip></el-table-column>
    32       <el-table-column label="请求方法" prop="method" show-overflow-tooltip></el-table-column>
    33       <el-table-column label="路径" prop="path" show-overflow-tooltip></el-table-column>
    34       <el-table-column label="所属项目" prop="project.name" show-overflow-tooltip></el-table-column>
    35       <el-table-column label="创建时间" prop="created_at" show-overflow-tooltip></el-table-column>
    36       <el-table-column label="操作" show-overflow-tooltip>
    37         <el-link icon="el-icon-edit" @click="dialog = true">编辑</el-link>
    38         <!-- 侧边栏修改项目 -->
    39         <!-- 弹出框,新增,编辑 -->
    40         <el-drawer
    41           title="修改"
    42           :before-close="handleClose"
    43           :visible.sync="dialog"
    44           direction="ltr"
    45           custom-class="demo-drawer"
    46           @click="handleUpdate(row)"
    47           ref="drawer"
    48           size="55%"
    49         >
    50           <Interface></Interface>
    51         </el-drawer>
    52       </el-table-column>
    53     </el-table>
    54     <!-- 分页 -->
    55     <pagination
    56       v-show="total > 0"
    57       :total="total"
    58       :page.sync="queryInfo.page"
    59       :limit.sync="queryInfo.limit"
    60       @pagination="getList"
    61     />
    62   </div>
    63 </template>
    <script>
      import {
        fetchList,
        projectList,
        fetchName,
      } from '/api/case'
      import service from "../../utils/axios";
      import Interface from "../../components/interface";
      // import Pagination from "../../components/Pagination"
      // 引入xlsx
      var XLSX = require('xlsx')
      export default {
        name: 'info',
        components: {Interface,},
        data() {
          return {
            total: 0,
            search: [],
            value: [],
            loading: false,
            timeout: null,
            dialog: false,
            filter: '',
            fullscreenLoading: false, // 加载中
            imFile: '', // 导入文件el
            outFile: '',  // 导出文件el
            errorDialog: false, // 错误信息弹窗
            errorMsg: '', // 错误信息内容
            list: [], // 返回数据
            listClone: [],
            queryInfo: {
              page: 1,
              limit: 20,
              name: ''
            },
            dialogStatus: '',
            textMap: {
              update: '编辑',
              create: '创建'
            },
       
            formLabelWidth: '80px',
            timer: null,
          }
        },
        mounted() {
          this.imFile = document.getElementById('imFile')
          this.outFile = document.getElementById('downlink')
          this.list = this.list.map(item => {
            return {value: `value:${item}`, label: `label:${item}`};
          });
        },
        watch: {
          search: {
            handler(val) {
              this.listClone = val.length ? this.list.filter((e) => val.find((item) => item === e.id)) : this.list;
            },
            deep: true,
            immediate: true,
          },
        },
        created() {
          this.getList()
        },
        methods: {
    
          /* 筛选 */
          nameList() {
            fetchName(this.queryInfo).then((service) => {
              this.list = service.data.data.items
            })
          },
    
          /* 修改数据 */
          handleUpdate() {
            projectList().then((res) => (this.projects = res.data.items))
            this.list = Object.assign({}, row) // copy obj
            this.dialogStatus = 'update'
            this.$nextTick(() => {
              this.$refs['dataForm'].clearValidate()
            })
          },
    
          /* 获取list数据 */
          getList() {
            this.listLoading = true
            fetchList(this.queryInfo).then((service) => {
              this.list = service.data.data.items
              this.listClone = this.list;
              this.total = service.data.data.total
    
              // Just to simulate the time of the request
              setTimeout(() => {
                this.listLoading = false
              }, 1.5 * 1000)
            })
          },
    
          /*  导入按钮  */
          uploadFile: function () { // 点击导入按钮
            this.imFile.click()
          },
    
          /* 导出  */
          downloadFile: function (rs) { // 点击导出按钮
            let data = [{}]
            for (let k in rs[0]) {
              data[0][k] = k
            }
            data = data.concat(rs)
            this.downloadExl(data, 'test用例')
          },
    
          /* 导入execl */
          importFile: function () { // 导入excel
            this.fullscreenLoading = true
            let obj = this.imFile
            if (!obj.files) {
              this.fullscreenLoading = false
              return
            }
            var f = obj.files[0]
            var reader = new FileReader()
            let $t = this
            reader.onload = function (e) {
              var data = e.target.result
              if ($t.rABS) {
                $t.wb = XLSX.read(btoa(this.fixdata(data)), {  // 手动转化
                  type: 'base64'
                })
              } else {
                $t.wb = XLSX.read(data, {
                  type: 'binary'
                })
              }
              let json = XLSX.utils.sheet_to_json($t.wb.Sheets[$t.wb.SheetNames[0]])
              console.log(typeof json)
              $t.dealFile($t.analyzeData(json)) // analyzeData: 解析导入数据
            }
            if (this.rABS) {
              reader.readAsArrayBuffer(f)
            } else {
              reader.readAsBinaryString(f)
            }
          },
    
          /* 导出execl  */
          downloadExl: function (json, downName, type) {  // 导出到excel
            let keyMap = [] // 获取键
            for (let k in json[0]) {
              keyMap.push(k)
            }
            console.info('keyMap', keyMap, json)
            let tmpdata = [] // 用来保存转换好的json
            json.map((v, i) => keyMap.map((k, j) => Object.assign({}, {
              v: v[k],
              position: (j > 25 ? this.getCharCol(j) : String.fromCharCode(65 + j)) + (i + 1)
            }))).reduce((prev, next) => prev.concat(next)).forEach(function (v) {
              tmpdata[v.position] = {
                v: v.v
              }
            })
            let outputPos = Object.keys(tmpdata)  // 设置区域,比如表格从A1到D10
            let tmpWB = {
              SheetNames: ['mySheet'], // 保存的表标题
              Sheets: {
                'mySheet': Object.assign({},
                  tmpdata, // 内容
                  {
                    '!ref': outputPos[0] + ':' + outputPos[outputPos.length - 1] // 设置填充区域
                  })
              }
            }
            let tmpDown = new Blob([this.s2ab(XLSX.write(tmpWB,
              {bookType: (type === undefined ? 'xlsx' : type), bookSST: false, type: 'binary'} // 这里的数据是用来定义导出的格式类型
            ))], {
              type: ''
            })  // 创建二进制对象写入转换好的字节流
            var href = URL.createObjectURL(tmpDown)  // 创建对象超链接
            this.outFile.download = downName + '.xlsx'  // 下载名称
            this.outFile.href = href  // 绑定a标签
            this.outFile.click()  // 模拟点击实现下载
            setTimeout(function () {  // 延时释放
              URL.revokeObjectURL(tmpDown) // 用URL.revokeObjectURL()来释放这个object URL
            }, 100)
          },
    
          /* 解析数据  */
          analyzeData: function (data) {  // 此处可以解析导入数据
            return data
          },
    
          /* 处理导入数据 */
          dealFile: function (data) {   // 处理导入的数据
            console.log(data)
            this.imFile.value = ''
            this.fullscreenLoading = false
            if (data.length <= 0) {
              this.errorDialog = true
              this.errorMsg = '请导入正确信息'
            } else {
              this.listClone = data
            }
          },
          s2ab: function (s) { // 字符串转字符流
            var buf = new ArrayBuffer(s.length)
            var view = new Uint8Array(buf)
            for (var i = 0; i !== s.length; ++i) {
              view[i] = s.charCodeAt(i) & 0xFF
            }
            return buf
          },
          getCharCol: function (n) { // 将指定的自然数转换为26进制表示。映射关系:[0-25] -> [A-Z]。
            let s = ''
            let m = 0
            while (n > 0) {
              m = n % 26 + 1
              s = String.fromCharCode(m + 64) + s
              n = (n - m) / 26
            }
            return s
          },
          fixdata: function (data) {  // 文件流转BinaryString
            var o = ''
            var l = 0
            var w = 10240
            for (; l < data.byteLength / w; ++l) {
              o += String.fromCharCode.apply(null, new Uint8Array(data.slice(l * w, l * w + w)))
            }
            o += String.fromCharCode.apply(null, new Uint8Array(data.slice(l * w)))
            return o
          },
          handleClose(done) {
            if (this.loading) {
              return;
            }
            this.$confirm('确定要提交表单吗?')
              .then(_ => {
                this.loading = true;
                this.timer = setTimeout(() => {
                  done();
                  // 动画关闭需要一定的时间
                  setTimeout(() => {
                    this.loading = false;
                  }, 10);
                }, 10);
              })
              .catch(_ => {
              });
          },
        }
      }
    </script>
        •  导出表格

     

  • 相关阅读:
    根据租户id获取部门树状结构有父子结构的数据list
    JAVA 中 Map 与实体类相互转换的简单方法
    JAVA 实体类List<Entity >转 List<Map>
    在eclipse中怎样查找一个类中的方法在其他哪个类中被调用了?快捷键是什么?
    eclipse项目包层级显示方式调整
    怎样查看JDK是32位还是64位
    python 面向对象专题(十三):元类(二): metaclass魔术方法
    python 面向对象专题(十二):元类(一): metaclass概述
    Hive高级(7):优化(7) 数据倾斜问题剖析
    数据可视化基础专题(二十七):numpy80题(六)NumPy进阶修炼第四期|NumPy最后二十问
  • 原文地址:https://www.cnblogs.com/cheng10/p/15375534.html
Copyright © 2011-2022 走看看