vue+xlsx实现前端模版下载、导入和导出excel文件

vue+xlsx

  • 前言
  • 模版下载
  • 导入功能
  • 导出功能

前言

产品需求:后端不想写下载,导入和导出的接口,让我们前端自己实现。
这里我们就可以用xlsx插件来实现,我们不多说了,先放一下实现的图片,下面我们分别把模版下载、导入和导出的代码放上来,想用的话,直接复制粘贴即可!

模版下载图片
vue+xlsx实现前端模版下载、导入和导出excel文件_第1张图片

导出图片:
vue+xlsx实现前端模版下载、导入和导出excel文件_第2张图片
好了,下面我们就直接上代码!

模版下载

首先,安装xlsx插件

 //我这里用的是0.18.5版本
  npm install xlsx@0.18.5

其次,配置表格导入导出的下载属性


<Button  @click="downloadTemplate(tableInfo)">导出</Button>
...
data(){
   return {
       tableData:[],//表格数据
	   tableInfo:{
	      rowMerge:false,//行合并
	      columnsCheckAll: true,
	      columnsChecked:[],
	      exportColumnAll: true,
	      exportColumns:[],
	      exportColumnChecked: [],
	      visible:false,
	      importModal:false,//控制导入弹框显示
	      importFile:null,//存放导入excel
	      showImportTable:false,//控制导入展示数据表格显示
	      importTableData:[],//导入excel的数据
	      columns:[
	          {title: '考核维度', key: 'checkDimension'},
	          {title: '考核指标', key: 'checkIndicators'},
	          {title: '分值', key: 'score'}
	      ],
	      importTableColumns:[],//导入excel的列
	      importTableNewData:[],//导入excel解析后的数据
	  },
  }
}

然后,写下载方法

   //下载导入模板
	downloadTemplate(tableInfo){
       let expData = [];
        tableInfo.importColumns = this.appendTableImportColumns(tableInfo.columns);
        var header = [];
        tableInfo.importColumns.map((item,index)=>{
           header[index] = item.title;
        });
        //1. 新建一个工作簿
        let workbook = XLSX.utils.book_new();
        //2.2 把json对象转成工作表
        let sheet1 = XLSX.utils.json_to_sheet(expData,{header:header});
        //3.在工作簿中添加工作表
        XLSX.utils.book_append_sheet(workbook, sheet1, '导入模板'); //工作簿名称
        XLSX.writeFile(workbook, '考核指标导入模板.xlsx'); // 保存的文件名
    
    },
     //获取导入表格的列
    appendTableImportColumns(columns){
        return columns.filter((item) =>{
            if(item.hasOwnProperty("title")){
                if(item.hasOwnProperty("key")){
                    return true;
                }else{
                    if(item.hasOwnProperty("slot") && item.slot.split(".").length > 1){
                        item.key = item.slot.split(".")[1];
                        return true;
                    }else{
                        return false;
                    }
                }
            }
        });
    },

导入功能

这里vue项目我用的是iview ui,也用了上传组件,我把下载模版和上传写在了一个弹窗内,如下图:

vue+xlsx实现前端模版下载、导入和导出excel文件_第3张图片

弹窗代码如下:

 <Modal
  title="导入数据"
   v-model="tableInfo.importModal"
   v-on:on-ok="poCheckKeyTableImportClass(tableInfo,tableData)"
   width="400"
   >
   <div class="button_content_box">
       <div class="finance_goods_list_main_content">
       <div style="margin-bottom: 5px;" >点击此处进行 <a  @click="downloadTemplate(tableInfo)">模版下载</a></div>
           <Row>
               <Col span="24">
               <div>
                   <Upload type="drag" action=""
                   :before-upload="function(file) { return poCheckKeyTableHandleUpload(file,tableInfo)}">
                       <div style="padding: 20px 0">
                           <Icon type="ios-cloud-upload" size="52"></Icon>
                           <p>将文件拖到此处,<a>点击上传</a></p>
                       </div>
                   </Upload>
               
               </div>
               </Col>
           </Row>
       </div>
       <div v-if="tableInfo.importFile"><span><Icon type="ios-podium" /></span>{{tableInfo.importFile.name }}</div>
   </div>
 </Modal>
      

下面方法能看懂最好,看不懂也无妨,直接复制粘贴拿去用就行,方法代码如下:

 //上传导入文件前事件
 poCheckKeyTableHandleUpload(file, tableInfo) {
     let vm = this;
     tableInfo.importFile = file;
     let reader = new FileReader()
     let rABS = typeof FileReader !== "undefined" && (FileReader.prototype || {}).readAsBinaryString
     if (rABS) {
         reader.readAsBinaryString(file)
     } else {
         reader.readAsArrayBuffer(file)
     }
     reader.onload = function (e) {
         let data = e.target.result
         if (!rABS) {
         data = new Uint8Array(data)
         }
         let workBook = XLSX.read(data, {type: rABS ? 'binary' : 'array'})
         workBook.SheetNames.forEach(name => {
             let sheet = workBook.Sheets[name]
             let json = XLSX.utils.sheet_to_json(sheet, {
                 raw: true,
                 header: 1,
                 defval: null
             });
         let tableData = [];
         json.map((itemData, indexData) => {
             if (indexData > 0) {
             var attr = {};
             json[0].map((item, index) => {
                 attr[item] = itemData[index];
             });
             tableData.push(attr);
             }
         });
         let importTableColumns = [];
         json[0].map((item, index) => {
             var attr = {};
             attr.title = item;
             attr.key = item;
             attr.width = 100;
             importTableColumns.push(attr);
         })

         let tableNewData = [];
         let columnCount = 0;
         tableInfo.columns.map((item, index) => {
             importTableColumns.some((itemColumn, indexColumn) => {
             if (item.title == itemColumn.title) {
                 columnCount++;
                 var field = item.key;
                 if (field == undefined) {
                 field = item.slot.split(".")[1];
                 }
                 tableData.map((itemData, indexData) => {
                 if (columnCount == 1) {
                     var attr = {};
                     attr[field] = itemData[itemColumn.title];
                     tableNewData.push(attr);
                 } else {
                     tableNewData[indexData][field] = itemData[itemColumn.title];
                 }
                 })
                 return true;
             }
             });
         });
         if (tableNewData.length > 0) {
             tableInfo.importTableData = tableData;
             tableInfo.importTableColumns = importTableColumns;
             tableInfo.importTableNewData = tableNewData;
             tableInfo.showImportTable = true;
         } else {
             vm.$Message.error('请规范录入表格数据!');
         }
         })
     }
     return false;
 },
 //点击导入确认
 poCheckKeyTableImportClass(tableInfo, data) {
     tableInfo.showImportTable = false;
     if (tableInfo.importTableNewData.length > 0) {
         tableInfo.importTableNewData.map(item => {
          data.push(item);
         })
         tableInfo.importTableNewData = [];
     }
 },
        

导出功能

<Button type="primary" @click="onBtnExporttableClick(tableInfo,'考核得分信息')">
   <span>导出</span>
</Button>

导出方法如下:

 onBtnExporttableClick(tableInfo, fileName) {
    tableInfo.visible = false;
    if (tableInfo.params === undefined) {
      tableInfo.params = {};
    }
    let expData = [];
    tableInfo.columns.map((item, index) => {
        this.tableData.map((itemData, indexData) => {

            if (index == 0) {
                var attr = {};
                attr[item.title] = itemData[item.key];
                expData.push(attr);
            } else {
                expData[indexData][item.title] = itemData[item.key];
            }
        })
    })
    //1. 新建一个工作簿
    let workbook = XLSX.utils.book_new();
    //2.2 把json对象转成工作表
    let sheet1 = XLSX.utils.json_to_sheet(expData);
    //3.在工作簿中添加工作表
    XLSX.utils.book_append_sheet(workbook, sheet1, fileName); //工作簿名称
    //4.输出工作表,由文件名决定的输出格式
    XLSX.writeFile(workbook, fileName + '.xlsx'); // 保存的文件名
},

不要看到那么多代码就感觉很复杂,然而很简单没因为需要你作改动的并不多,当然你也可以根据自己需求去做的更加完善,简单的导入导出实现,这就足够啦,不需要做什么更改,复制粘贴就可以!

你可能感兴趣的:(vue,导入导出,前端,vue.js,excel)