Jeecg-Boot 前端读入 excel

使用框架:前端 Ant Design of Vue

1. 安装依赖

yarn add xlsx --save-dev

2. 引用前端上传组件

 3. 定义导入后显示内容

内嵌 Table

 4.代码

<template>
  <a-card :bordered="false">


    <!-- 操作按钮区域 -->
    <div class="table-operator">
      <a-button @click="handleAdd" type="primary" icon="plus">新增</a-button>
      <a-button type="primary" icon="download" @click="handleExportXls('SQ_GRID')">导出</a-button>
      <a-upload name="file" ref="customUpload" :showUploadList="false" :multiple="false" :headers="tokenHeader"  @change="handleImportExcel">
        <a-button type="primary" icon="import" >导入</a-button>
      </a-upload>
      <a-dropdown v-if="selectedRowKeys.length > 0">
        <a-menu slot="overlay">
          <a-menu-item key="1" @click="batchDel">
            <a-icon type="delete"/>
            删除
          </a-menu-item>
        </a-menu>
        <a-button style="margin-left: 8px"> 批量操作
          <a-icon type="down"/>
        </a-button>
      </a-dropdown>
    </div>

    <!-- table区域-begin -->
    <div>
      <div class="ant-alert ant-alert-info" style="margin-bottom: 16px;">
        <i class="anticon anticon-info-circle ant-alert-icon"></i> 已选择 <a style="font-weight: 600">{{ selectedRowKeys.length }}</a>项
        <a style="margin-left: 24px" @click="onClearSelected">清空</a>
      </div>

      <a-table
        ref="table"
        bordered
        rowKey="addressName"
        :columns="columns"
        :dataSource="dataSource"
        :pagination="false"
        :expandedRowKeys= "expandedRowKeys"
        :rowSelection="{selectedRowKeys: selectedRowKeys, onChange: onSelectChange}"
        @change="handleTableChange"
        @expand="handleExpand"
      >

        <span slot="action" slot-scope="text, record">
          <a @click="handleEdit(record)">编辑</a>
          <a-divider type="vertical"/>
          <a-popconfirm title="确定删除吗?" @confirm="() => handleDelete(record.id)">
            <a>删除</a>
          </a-popconfirm>
        </span>
        <a-table
          slot="expandedRowRender"
          slot-scope="text"
          :columns="innerColumns"
          :dataSource="innerData"
          size="middle"
          bordered
          rowKey="villageCode"
          :pagination="false"
          :loading="loading"
        >
        </a-table>
      </a-table>
    </div>
    <!-- table区域-end -->

    <!-- 表单区域 -->
    <jeecgOrderDMain-modal ref="modalForm" @ok="modalFormOk"></jeecgOrderDMain-modal>
  </a-card>
</template>

<script>
  import { getAction } from '@/api/manage'
  import JeecgOrderDMainModal from '@/views/jeecg/tablist/form/JeecgOrderDMainModal'
  import {JeecgListMixin} from '@/mixins/JeecgListMixin'

  export default {
    name: "SqImportAdressInfo",
    mixins: [JeecgListMixin],
    components: {
      JeecgOrderDMainModal
    },
    data() {
      return {
        // 子表表头
        innerColumns:[
          {
            title: '社区编码',
            align: "center",
            width: 100,
            dataIndex: 'communityCode',
            key: 'communityCode'
          },
          {
            title: '小区编码',
            align: "center",
            width: 100,
            dataIndex: 'villageCode',
          },
          {
            title: '楼栋编码',
            align: "center",
            width: 100,
            dataIndex: 'buildingCode',
          },
          {
            title: '单元编码',
            align: "center",
            width: 100,
            dataIndex: 'doorCode',
          },
          {
            title: '房间ID',
            align: "center",
            width: 100,
            dataIndex: 'roomId',
          },
          {
            title: '房间编码',
            align: "center",
            width: 100,
            dataIndex: 'roomCode',
          }
        ],
        innerData: [],
        expandedRowKeys: [],
        id: ' ',
        description: '列表展开子表Demo',
        // 列表表头
        columns: [{
          title: '#',
          dataIndex: '',
          key: 'rowIndex',
          width: 60,
          align: "center",
          customRender: function (t, r, index) {
            return parseInt(index) + 1;
          }
        }, {
            title: '地址信息',
            align: "center",
            dataIndex: 'addressName'
          },
          {
            title: '创建人',
            align: "center",
            dataIndex: 'createBy'
          },
          {
            title:'创建时间',
            align:"center",
            dataIndex: 'createTime',
            customRender:function (text) {
              return !text?"":(text.length>10?text.substr(0,10):text)
            }
          },
          {
            title: '更新人',
            align: "center",
            dataIndex: 'updateBy'
          },
          {
            title:'更新时间',
            align:"center",
            dataIndex: 'updateTime',
            customRender:function (text) {
              return !text?"":(text.length>10?text.substr(0,10):text)
            }
          },
          {
            title: '操作',
            dataIndex: 'action',
            align: "center",
            scopedSlots: {customRender: 'action'},
          }],
        // 分页参数
        type: "radio",
        url: {
          list: "/test/order/orderList",
          delete: "/test/order/delete",
          deleteBatch: "/test/order/deleteBatch",
          customerListByMainId: "/test/order/listOrderCustomerByMainId",
        },
      }
    },
    computed: {
      currentId(){
        return this.id;
      }
    },
    methods: {
      loadData(arg){
        return;
      },
      handleExpand(expanded, record){
        this.expandedRowKeys=[];
        this.innerData=[];
        if(expanded===true){
        this.loading = true;
        this.expandedRowKeys.push(record.addressName);
        var innerData = [];
        this.dataSource.map(d => {
          if(record.addressName == d.addressName)
          {
            var arr = d.addressName.split("-");
            let obj = {};
            obj.addressName = d.addressName;
            obj.communityCode = arr[0];//社区
            obj.villageCode = arr[1];//小区
            obj.buildingCode = this.matchNumberByStr(arr[2], 3);//楼栋
            obj.doorCode = this.matchNumberByStr(arr[3], 3);//单元
            obj.roomId = this.matchNumberByStr(arr[4], 4);//房间ID
            obj.roomCode = this.matchNumberByStr(arr[4], 4);//房间
            innerData.push(obj);
          }

        });
        // this.loading = false;
        this.innerData = innerData;
        this.loading = false;

        }
        // return true;
      },

      matchNumberByStr(str,len){
        var num = str.replace(/[^\d]/g,"");
        var str1 = this.formatNum(num, len);
        return str1;

      },
      formatNum(number, len) {
        var strLength = len - number.length;//格式长度减去数字的长度,就是数字前补"0"的个数
        for (var i = 0; i < strLength; i++) {
          number = "0" + number;
        }
        return number;
      },
      handleImportExcel(info){
        //ant design 框架中此回调会运行三次,上传中、完成、失败都会调用这个函数。
        if(info.event){
          this.importFile(info.file).then(this.handleData).catch(function(error){
            console.log('文件上传发生错误', error);
          })
        }
      },
      handleData(outdata){
        let arr = [];
        outdata.map(v => {
          let obj = {};
          obj.addressName = v['_10'];
          if(obj.addressName != "" && obj.addressName != "addressname"){
            obj.createBy = '';
            obj.createTime = '';
            obj.updateBy = '';
            obj.updateTime = '';
            arr.push(obj);
          }
        });
        this.dataSource = arr;
        debugger;
      },
      //导入文件
      importFile(obj) {
        return new Promise((result,reject) => {
          let _this = this;
          let inputDOM = this.$refs.customUpload;
          // 通过DOM取文件数据

          this.file = obj.originFileObj;

          var rABS = false; //是否将文件读取为二进制字符串
          var f = this.file;

          var reader = new FileReader();
          //if (!FileReader.prototype.readAsBinaryString) {
          FileReader.prototype.readAsBinaryString = function(f) {
            var binary = "";
            var rABS = false; //是否将文件读取为二进制字符串
            var pt = this;
            var wb; //读取完成的数据
            var outdata;
            var reader = new FileReader();
            reader.onload = function(e) {
              var bytes = new Uint8Array(reader.result);
              var length = bytes.byteLength;
              for (var i = 0; i < length; i++) {
                binary += String.fromCharCode(bytes[i]);
              }
              //此处引入,用于解析excel
              var XLSX = require("xlsx");
              if (rABS) {
                wb = XLSX.read(btoa(fixdata(binary)), {
                  //手动转化
                  type: "base64"
                });
              } else {
                wb = XLSX.read(binary, {
                  type: "binary"
                });
              }
              outdata = XLSX.utils.sheet_to_json(wb.Sheets[wb.SheetNames[0]]);
              result(outdata);
            };
            reader.readAsArrayBuffer(f);
          };
          if (rABS) {
            reader.readAsArrayBuffer(f);
          } else {
            reader.readAsBinaryString(f);
          }


        });
      }
    }
  }
</script>
<style scoped>
  .ant-card-body .table-operator {
    margin-bottom: 18px;
  }

  .ant-table-tbody .ant-table-row td {
    padding-top: 15px;
    padding-bottom: 15px;
  }

  .anty-row-operator button {
    margin: 0 5px
  }

  .ant-btn-danger {
    background-color: #ffffff
  }

  .ant-modal-cust-warp {
    height: 100%
  }

  .ant-modal-cust-warp .ant-modal-body {
    height: calc(100% - 110px) !important;
    overflow-y: auto
  }

  .ant-modal-cust-warp .ant-modal-content {
    height: 90% !important;
    overflow-y: hidden
  }
</style>

5. 注意事项: 

报错:Warning: [antdv: Each record in table should have a unique `key` prop,or set `rowKey` to an unique primary key.]

表格选择框无法正常选中:例如:无论选择哪一行都默认选择第一行

 修改表格的行关键字

 修改为每行数据包含的列的列名:

 内嵌表格中rowKey 同样需要如此

  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
根据提供的引用内容,我无法找到关于"jeecg-boot 前端for循环"的具体实现。引用和引用提到了关于jeecg-boot的数据库设计和视图的使用,但没有提及前端for循环的实现方法。jeecg-boot是一个基于Spring Boot和MyBatis的开源快速开发平台,它提供了一套代码生成器和一些默认的前端控件,但具体的前端for循环实现可能需要根据具体的业务需求进行自定义开发。 如果你需要在jeecg-boot前端页面中使用for循环,你可以通过以下步骤实现: 1. 在前端页面中使用JavaScript的for循环语句来遍历数据。 2. 根据具体的业务需求,使用for循环来生成动态的HTML元素或执行其他操作。 以下是一个示例,展示了在jeecg-boot前端页面中使用for循环来遍历数据并生成动态的HTML元素的方法: ```javascript <script> // 假设data是一个包含多个对象的数组 var data = [{name: 'John', age: 25}, {name: 'Jane', age: 30}, {name: 'Bob', age: 35}]; // 使用for循环遍历数据 for (var i = 0; i < data.length; i++) { var item = data[i]; // 根据数据生成动态的HTML元素 var div = document.createElement('div'); div.innerHTML = 'Name: ' + item.name + ', Age: ' + item.age; // 将生成的元素添加到页面中的某个容器中 document.getElementById('container').appendChild(div); } </script> ``` 请注意,以上示例仅为演示目的,具体的实现方法可能因具体业务需求而异。你可以根据自己的需求进行适当的修改和调整。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值