VUE批量导入/读取excel、下载模板文件功能实现

232 阅读3分钟

 

 

excel文件读取,事前都是基于xlsx这个插件的,可以npm install自己安装,然后引入即可。

首先是页面实现HTML:

<!-- 导入按钮 -->
          <div id="label-import" class="label-import" >
              <span style="color: #FFFFFF;margin-left: 10px;">批量导入</span>
             <!-- 顶部 -->
             <div id="import_dingbu">
 
                <a href = "javascript:void(0)" onclick = "closeImport()" id="import_dingbu_close"><img src="img/03_part/tk_button_close_press.png" style=""></a>
 
             </div> <!-- dialog_dingbu -->
 
              <!-- 中部 -->
             <div id="import_zhongbu">
                  <div id="import_buju">
                    <input type="file" name="file" id="fileid" value="" accept=".xlsx,.xls,.csv"  onclick="filechoose()" /> <!-- onclick="filechoose()" -->
                    <input type="button" id="daoru" value="导入" onclick="fileimport()"/></br>
                    <a herf="#" download="moban.xlsx"  id="moban" class="downloadBtn" onclick="downloadmoban()">下载模板</a>
                      <!-- <button class="downloadBtn" type="button" onclick="downloadImg()" id="moban">下载模板</button> -->
                 </div>
 
                   <p style="float: right;margin-right: 50px;margin-top: 40px;" >
                     <b>注意:</b>
                         <span >1)必须根据模板格式录入,否则导入失败</br></span>
                         <span style="float: right;margin-right: 70px;">2)不支持IE等部分浏览器下载</span>
                   </p>
 
             </div> <!-- dialog_zhongbu -->
 
          </div> <!-- label-dialog -->

data数据:

 //批量导入
data(){
    return{
        thisObj: {}, //把change的this传给click
        isUploadflag: false, //上传按钮标志位,先点击
        result: [],
    }
}
      

excel表格内容大概是:

nameagesexnumble
张三12 
李四1613838380438

选择文件按钮:

 filechoose() {
      var objFile = document.getElementById("fileid").files[0];
      var objStr = /\.(xlsx|xls|csv)$/;
      console.log("选文件", objFile);
      
      if (!objStr.test(objFile.name)) {
        this.$alert('选择的文件格式不对,请选对excel表格!', '警告', {
                confirmButtonText: '确定',
          });
        return false;
      }
      this.thisObj = objFile;
      console.log("选中的elsx文件", this.thisObj);

      //上传按钮
      this.$root.DataBus.setElsxFile(this.thisObj);
      this.isUploadflag = true;
      // this.$message({
      //     message: '已上传文件,可继续下一步!',
      //     type: 'success'
      // });
    },

点击导入按钮:

 //批量导入
fileimport(){

            let biaogesj = [],
              biaogename = [],
              biaogeImei = [],
              biaogeZWnumeber = [];
            var elsxData = this.$root.DataBus.elsxData;
            var objFile = this.thisObj;
            var objStr = /\.(xlsx|xls|csv)$/;
            console.log("objFile身份", objFile); 

            // if (this.isUploadflag == false) {
            //     this.$alert('请先点击上传按钮!', '警告', {
            //           confirmButtonText: '确定',
            //     });
            //     return;
            // }else 
            if(objFile === undefined || objFile === null || objFile === {}){
                this.$alert('没有选中任何文件 或 格式选中错误', '警告', {
                    confirmButtonText: '确定',
                });
                return false;  
            }else 
            if(!objStr.test(objFile.name)){
                this.$alert('上传格式错误', '警告', {
                    confirmButtonText: '确定',
                });
                return false;  
            }
            else{
              for (var i = 0; i < elsxData.length; i++) {
                if (
                  elsxData[i].name!= null ||
                  elsxData[i].age != null ||
                  elsxData[i].sex!= -1 ||
                  elsxData[i].numble!= -1
                ) {
                  //numble这个允许为空  
                  let elsxNumber;
                  if (elsxData[i].numble== null) {//
                    elsxNumber = "";
                  } else {
                    elsxNumber = elsxData[i].numble;
                  }
                  biaogesj.push({
                    name: elsxData[i].name,
                    age:  elsxData[i].age,
                    sex: elsxData[i].sex,
                    numble: elsxData[i].numble,
                  });
                }else {
                  this.$message({
                    message: "这里是男校,这里设置sex一定为男,不能是女",
                    type: "error",
                  });
                  return;
                }
              }
              senddele1 = JSON.stringify(biaogesj);
              console.log("批量导入数据:" + senddele1); 
              /*这里可以获取数去发送给后端*/
              this.isUploadflag = false;
              return;
            }
}

最后获取的结果:就说表格的内容了。

 

你可以写成公用的方法进行调用:

//批量导入
       setElsxFile(e){
            // var e = this.thisObj;
            let file = e // .file文件信息

            console.log("file内容",file)

                if (!file) {   // 没有文件
                    this.$message.error('没有选择任何文件');
                     return false
                }else if (!/\.(xls|xlsx|csv|vcf)$/.test(file.name)) {//.toLowerCase()
                    // this.$message.error('上传格式不正确,请上传正确格式的文件!')
                    this.$alert('上传格式不正确,请上传正确格式的文件', '警告DataBus', {
                        confirmButtonText: '确定',
                        callback: action => {
                            this.$message({
                            type: 'info',
                            message: `所需文件后缀,请根据说明`
                            });
                        }
                    });
                    return false
                }
                const fileReader = new FileReader()
                fileReader.onload = (ev) =>{
                    try{
                        const data = ev.target.result
                        const workbook = XLSX.read(data, {
                            type: 'binary'  // 以字符编码的方式解析
                        })
                        const exlname = workbook.SheetNames[0]   // 取第一张表
                        const exl = XLSX.utils.sheet_to_json(workbook.Sheets[exlname]) //生成json表格内容
                        this.elsxData = exl
                        console.log("导入表格内容",this.elsxData)
                        // document.getElementsByName('file')[0].value = '' 
                        // 根据自己需求,可重置上传value为空,允许重复上传同一文件
                    }catch(e){
                        console.log('导入表格出错了!!!')
                        return false
                    }
                }
            fileReader.readAsBinaryString(file)
       },

导入文件后,调用这个方法就可以导入excel文件实现了。

 

 

附加:加上element实现

我们原生按钮不好看,加上element的插件<el-upload>,我这里是写了读取excel和VCF格式

页面显示:

 <!-- 中部2-批量导入 -->
        <div id="dialog_imports" style="display:none;margin-top: 0.3rem;">
            <div class="scrollcelue6" id="tabs-2">
                <div id="import_buju">
                     <!-- <input type="file" name="file" id="fileid" accept=".xlsx,.xls,.csv,.vcf" @change="importFile()" style="margin-left:1rem;" >
                     <el-upload
                        action=""
                        class="upload-demo"
                        ref="upload"
                        :on-change="importFile"
                        :auto-upload="false"
                        :limit="1"> 点击上传
                    </el-upload>
                     <input type="button" id="daoru" value="上传" style="margin-left:0.02rem;" @click="httpRequest()"> -->
                    <el-upload
                            style="margin-left:2.7rem;"
                            action=""
                            class="upload-demo"
                            accept=".xlsx,.xls,.csv,.vcf"
                            ref="upload"
                            :on-change="importFile"
                            :auto-upload="false"
                            :on-exceed="handleExceed"
                            :limit="1">
                        <el-button slot="trigger" size="small" type="primary" >选取文件</el-button>
                        <!-- <el-button style="margin-left: 10px;" size="small" type="success" @click="httpRequest">点击上传</el-button> -->
                        <div slot="tip" class="el-upload__tip">只能选择一个文件</div>
                    </el-upload>

                    <div style="margin-top:0.1rem;float: right;margin-right:1rem;">
                        <el-link download="BtruncContactsMoban.xlsx" :href="downloadUrl" id="moban" class="downloadBtn" type="primary" >下载模板</el-link>
                    </div>                     
                </div>

                <p style="float: right;margin-right: 50px;margin-top: 0.1rem;">
                    <b>注意:</b>
                    <a>1)必须根据模板格式录入,否则导入失败</a>
                    <span style="float: right;margin-right: 4rem;">2)仅支持文件后缀为.xls|.xlsx|.vcf</span>
                    <span style="float: right;margin-right: 2.98rem;">3)不支持IE等部分浏览器,建议使用谷歌浏览器</span>
                </p>
            </div>
        </div>

//------------------------------底部确定按钮--------------
<el-button
                    id="dibu_queding"
                    type="primary"
                    style="float: right;display: none;margin-top:-0.4rem"
                    @click="queding_newphone(edit)"
                    plain
                    v-loading.fullscreen.lock="fullscreenLoading"
                    >确定</el-button
                >

 

选择文件后显示:

importFile(file){
                //原生选择文件按钮适用
                 //     var objFile = document.getElementById('fileid').files[0];//element框架不适用,仅用于原生js
                console.log("文件",file);
                var objFile = file.raw;
                var objStr = /\.(xlsx|xls|csv|vcf|txt)$/;
                console.log("是否存在文件",!objStr.test(objFile.name));
                if(!objStr.test(objFile.name)){
                    this.$alert('选择的文件格式不对,请选对格式1', '警告', {
                        confirmButtonText: '确定',
                    });
                    return false;
                }else{
                    this.suffix = objFile.name.split('.')[1];
                }

                if (typeof FileReader === "undefined") {  //用来判断你的浏览器是否支持 FileReader
                    this.$message({
                        type: "info",
                        message: "您的浏览器不支持文件读取。"
                    });
                    return;
                }
                this.thisObj=objFile;
                console.log("选中的xlsx文件",this.thisObj.name);

                //上传按钮
                this.isUploadflag = true;
                var imageLocations = new Array();//存放文件内容--原始内容
                var temp = new Array();//存放文件内容--每行转换为数组

                if(this.suffix  === "xlsx" || this.suffix === "xls" || this.suffix === "csv"){
                    console.log("选择得是EXCEL格式",this.suffix,"文件名",this.thisObj)
                    this.$root.DataBus.setElsxFile(this.thisObj);//如果木有上传这步,elsxData这个就获取不到
                    this.fileFlod = "isExcel";
                    // var elsxData = this.$root.DataBus.elsxData;
                    // console.log("测试1",elsxData.length)
                    // if(elsxData.length === 0){
                    //     this.$root.DataBus.setElsxFile(this.thisObj);//如果木有上传这步,elsxData这个就获取不到
                    //     elsxData = this.$root.DataBus.elsxData;
                    // }else{
                        
                        // console.log("测试",elsxData)
                        // if(elsxData.Name === undefined || elsxData.Tel === undefined ||
                        //     elsxData.Name === null || elsxData.Tel === null ||
                        //     elsxData.Name === "" || elsxData.Tel === ""){
                        //     this.$alert('表格中内容为空或异常,请检查!', '警告', {
                        //                 confirmButtonText: '确定',
                        //     });
                        //     return false; 
                        // // }

                        // }
                    
                    
                }else if(this.suffix  === "vcf" ){
                    /*这里参考另篇文章*/
                    https://blog.csdn.net/bbs11007/article/details/114404530
                    
                }else if(this.suffix  === "txt" ){
                     /*这里参考另篇文章*/
                    https://blog.csdn.net/bbs11007/article/details/116800843

                }else{
                    this.$alert('请选择正确文件后再上传', '警告', {
                        confirmButtonText: '确定',
                    });
                }

                // this.fullscreenLoading = true;
                //         setTimeout(() => {
                //             this.fullscreenLoading = false;
                //             if(this.LoadingFlag === false){
                //             //   this.$message({
                //             //     message: '服务端无响应,请检查网络或服务器!',
                //             //     type: 'warning'
                //             //   });
                //                 this.LoadingFlag = false;
                //             }
                // }, 1000);
         },

 

 

确定按钮实现:

 queding_newphone(edit){

//判断选择的文件是否异常
             //var objFile = document.getElementById('fileid').files[0];
              var objFile = this.thisObj;
              var objStr = /\.(xlsx|xls|csv|vcf|txt)$/;
              console.log("objFile身份", objFile); 
              var elsxData = this.$root.DataBus.elsxData;
              console.log("表格内容", elsxData.length); 

              var biaogesj=[], ss=[],ii=[]
              this.$root.DataBus.randomSuiji(elsxData.length);
              var ssui=this.$root.DataBus.suijiId;
              console.log("随机数333",ssui);

            //   if(this.isUploadflag == false){
            //         this.$alert('请先点击上传按钮!', '警告', {
            //             confirmButtonText: '确定',
            //         });
            //         return;
            //   }else 
              if(objFile === undefined){
                    this.$alert('没有选中任何文件 或 格式选中错误', '警告', {
                        confirmButtonText: '确定',
                    });
                    return false;  
              }else if(!objStr.test(objFile.name)){
                    this.$alert('上传格式错误', '警告', {
                        confirmButtonText: '确定',
                    });
                    return false;  
              }
              else{
                    //打开界面
                    document.getElementById("dialog_newContacts").style.display = "none";
                    document.getElementById("dialog_imports").style.display = "none";
                    document.getElementById("dialog_xiafachoose").style.display = "block";
                    document.getElementById("dialog_newxiafa").style.display = "none";
                    document.getElementById('dialog_lookPhoneLine').style.display = "none";
                    // document.getElementById("dialog_phonexiafa").style.display = "none";
                    document.getElementById("dibu_quxiao").style.display = "none";
                    document.getElementById("dibu_queding").style.display = "none";
                    document.getElementById("dibu_xiafa").style.display = "none";
                    this.biaoti3 = "请选择下发到群组还是终端";
                    this.edit3 = "importData"
                    
                    //判断导入的是表格
                    var objStr1 = /\.(vcf)$/;
                    if(!objStr1.test(objFile.name)){
                       
                       for(var i=0;i<elsxData.length;i++){
                           if(elsxData[i].Name === undefined || elsxData[i].Tel === undefined ||
                                elsxData[i].Name === null || elsxData[i].Tel === null ||
                                elsxData[i].Name === "" || elsxData[i].Tel === ""){
                                this.$alert('表格中内容为空或异常,请检查!否则强行发送会出异常。', '警告', {
                                            confirmButtonText: '确定',
                                });
                                return false; 
                           }else{
                               biaogesj.push({"FName":elsxData[i].Name,"AccountType":"person","Name":elsxData[i].Name,
                                           "Tel":elsxData[i].Tel});
                               console.log("测试读取Excel文件2:",biaogesj);
                               this.biaogesjData = biaogesj;
                           }
                            
                       }      
                    }
                            

                        }

                        // this.fullscreenLoading = true;
                        // setTimeout(() => {
                        //     this.fullscreenLoading = false;
                        //      if(this.LoadingFlag === false){
                        //     //   this.$message({
                        //     //     message: '服务端无响应,请检查网络或服务器!',
                        //     //     type: 'warning'
                        //     //   });
                        //       this.LoadingFlag === false;
                        //     }
                        // }, 5000);
                        // return;
              }
}

 

下载模板

点击下载按钮(组件a标签等方式也行,这里用elemnet),这里重点是绑定:href="downloadUrl"

 <!-- <a download="moban.xlsx" :href="downloadUrl"  id="moban" class="downloadBtn"  @click="downloadmoban()">下载模板</a> -->
                        <el-link download="moban.xlsx" :href="downloadUrl" id="moban" class="downloadBtn" type="primary">下载模板</el-link>
                            <!-- <el-tag>
                                <i class="el-icon-download" />
                                <a :href="downloadUrl">点击下载模版</a>
                            </el-tag> -->

定义:

data(){
    return{
        //下载模板
      loaded: false,
      downloadUrl: "/file/moban.xlsx", // 模板下载文件地址
    }
}

另外:

我们若想用按钮下载,不是link,发现上面得办法没法下载,那就试试嵌到方式:参考:www.jb51.net/article/171…

<el-link download="moban.xlsx" :href="downloadUrl" id="moban" class="downloadBtn" type="primary">
         <el-button type="warning" plain round icon="el-icon-download" @click="pullLog()">拉取日志</el-button>
</el-link> 

然后还可以增添功能,如,监测下载完后该提示,或者做什么操作

pullLog(){
            let URL = this.downloadUrl;
            let me = this
            
            axios.get(URL).then(function (response) {
                console.log("是否下载成功",response.status)
                if (response.status === 200) {
                    me.$message.success('下载成功!')
                }else{
                    me.$message.warning('下载失败!')
                }
            }).catch(function (response) {
                console.log("打印看里面是什么",response);
            });

        },

注意:response是没有返回200,你要打印出来看看,我打印出来看看response中的status为200,所以才是我要获取的response.status==200(打印出来的200不是字符串,看看你的是什么)

这样就只显示按钮而已,去试试吧!

 

没了,是不是非常的简单,主要,文件建议放在public中,因为后续build编译后,怕找不到这个文件。