Después de que el proyecto vue se haya importado con éxito a Excel, descargue el resultado de la importación (la matriz de lista devuelta por el backend)

Requisito:
haga clic en el botón de importación por lotes y aparecerá una ventana emergente.
Descargue la plantilla como se muestra en la Figura 2.
Después de cargar, si hay un error, aparecerá un mensaje emergente, como se muestra en la Figura 3.
Haga clic para ver el motivo de la falla y el Excel fallido se descargará automáticamente como se muestra en la Figura 4 .
inserte la descripción de la imagen aquí
inserte la descripción de la imagen aquí
inserte la descripción de la imagen aquí

Solicitar parámetros y devolver resultados
inserte la descripción de la imagen aquí
inserte la descripción de la imagen aquí

inserte la descripción de la imagen aquí

1. Pasos de implementación de la función de tabla de exportación del proyecto Vue
npm install [email protected]
npm install [email protected]
Las páginas requeridas se presentan en src/utils/exportExcel.js para obtener detalles

2. Realización de la página

<template>
	<div>
			<el-button type="primary" @click="batchUpAndDown" size="mini">导入商品上下架</el-button>
			<up-loader ref="addUploader" @downLoad="addExcelExport" @upLoad="addExcelImport" :tip="tip" :tipRed="tipRed"></up-loader>
		    <el-dialog title="上传结果" :visible.sync="dialogUpLoaderVisible" width="300px">
		      <div style="text-align: center; margin: 20px 0;">上传失败!</div>
		      <div slot="footer" style="text-align: center">
		        <el-button type="primary" @click="handleUpLoaderDialogConfirm" size="mini">下载文件,查看失败原因</el-button>
		      </div>
		    </el-dialog>
	</div>
</template>

<script>
import exportSheet from '@/utils/exportExcel'
import * as utils from '@/utils/utils'
import UpLoader from "@/module/components/uploader/uploader.vue"
export default {
      
      
components: {
      
      
    UpLoader
  },
  data(){
      
      
		tip: '说明:批量导入商品上下架状态信息;支持.xlsx .xls格式。',
	      tipRed: '请根据下载模版编辑文件进行上传!',
	      importAddConfig: {
      
      
	        regionCode: '区域编号',
	        storeNo: '母店编号',
	        goodsNo: '商品编号',
	        shelfStatusName: '状态(上架/下架)',
	      },
	      dialogUpLoaderVisible: false,
	      importAddFailedConfig: {
      
      
	        regionCode: '区域编号',
	        storeNo: '母店编号',
	        goodsNo: '商品编号',
	        shelfStatusName: '状态(上架/下架)',
	        errMsg: '失败原因'
	      },
	      failureList: [],
	},
methods: {
      
      
	
			batchUpAndDown() {
      
      
		      this.$refs.addUploader.open()
		    },
		    // 下载模版
		    addExcelExport() {
      
      
		      console.log('new Date()', new Date())
		      console.log('utils.formatDate(new Date())', utils.formatDate(new Date()))
		      eportsheet.exportFileByConfig([{
      
      }], `菜猫商品信息批量导入${ 
        utils.formatDate(new Date())}.xlsx`, this.importAddConfig)
		    },
		    async addExcelImport(file) {
      
      
		      let parseConfig = {
      
      }
		      for (let key in this.importAddConfig) {
      
      
		        parseConfig[this.importAddConfig[key]] = key
		      }
		      await eportsheet.parseToJSON(file, parseConfig).then(result => {
      
      
		
		        if(!result){
      
      
		          this.$notify.error({
      
       title: '提示', message:"上传文件数据解析为空" })
		          return false
		        }
		        if(result.length > 5000){
      
      
		          this.$notify.error({
      
       title: '提示', message:"文件过大,请上传最大支持5000条数据。" })
		          return false
		        }
		        // 循环excel中的每一项
		        for(let i=0; i<result.length; i++){
      
      
		          let row = result[i]
		          if(!row.regionCode){
      
      
		            this.$notify.error({
      
       title: '提示', message:"区域编号不能为空" })
		            return false
		          }
		          if(!row.storeNo){
      
      
		            this.$notify.error({
      
       title: '提示', message:"母店编号不能为空" })
		            return false
		          }
		          if(!row.goodsNo){
      
      
		            this.$notify.error({
      
       title: '提示', message:"商品编号不能为空" })
		            return false
		          }
		          if(!row.shelfStatusName){
      
      
		            this.$notify.error({
      
       title: '提示', message:"上下架状态不能为空" })
		            return false
		          }
		        }
		        // 将excel的数据转成数组后传给后端,后端返回操作结果的文件流
		        this.$http.post(requestUrl.buyer.batchImportShelfStatus, result).then(res => {
      
      
		          if (res.code === 0) {
      
      
		            this.$refs.addUploader.close()
		            if (res.data.length == 0) {
      
      
		              this.$notify.success({
      
      title: '操作提示',message: "导入成功"})
		              this.doSearchHandle()
		            } else {
      
      
		              this.dialogUpLoaderVisible = true
		              this.failureList = res.data
		              return
		            }
		            // this.exportLoading = false
		          } else {
      
      
		            this.$notify.error({
      
      
		              title: '提示',
		              message: res.msg
		            })
		          }
		        })
		      })
		    },
		    handleUpLoaderDialogConfirm() {
      
      
		      let exportedData = this.failureList
		      try {
      
      
		        const tHeader = utils.objectToArray(this.importAddFailedConfig, false)
		        const filterVal = utils.objectToArray(this.importAddFailedConfig, true)
		        exportSheet.ExportJsonToExcel({
      
      
		          header: tHeader,
		          filterVal,
		          data: exportedData,
		          filename: '商品信息批量导入结果'
		        })
		        this.dialogUpLoaderVisible = false
		      } catch (exception) {
      
      
		        this.loading = false
		        this.$notify.error({
      
      
		          title: '温馨提示',
		          message: '导出遇到错误'
		        })
		      }
		    },
		
	}
}

</script>

@/módulo/componentes/uploader/uploader.vue

<template>
  <!--批量导入弹窗-->
  <el-dialog :visible.sync="visible" size="large" title="批量导入" :loading="loadingInfo">
    <el-row class="mv10">
      <el-col :span="24">
        <label :for="`excelFile${tmp}`" class="excelFileLabel">
          <span class="file-label-text">请选择文件</span>
          <input accept=".xlm,.xls,.xlt,.xlw,.xlsx" type="file" :id="`excelFile${tmp}`" hidden @change="handleFileSelect" :value="fileValue" />
          <el-input class="search-input" v-model="file.name" disabled></el-input>
        </label>
        <el-button style="margin-left: 10px" size="small" type="text" @click="exportTemp">下载模版</el-button>
      </el-col>
      <el-col v-if="tip || tipRed">
        <div class="tipBox">{
    
    {
    
    tip}}<span class="tipRed">{
    
    {
    
    tipRed}}</span></div>
      </el-col>
    </el-row>
    <el-row>
      <el-col :span="24">
        <el-button style="margin-top: 20px" :loading="loadingInfo" size="small" type="primary" @click="submitUpload">导入
        </el-button>
        <el-button @click="exportErrorFile" v-if="upStatus.code">下载错误列表</el-button>
      </el-col>
    </el-row>
    <el-row class="mt20" v-if="upStatus.code">
      <el-col :span="24" style="color:red">
        <p>{
    
    {
    
    file.name}} 导入失败,请修改后重新上传</p>
        <p>失败原因:{
    
    {
    
    upStatus.msg}}</p>
      </el-col>
    </el-row>
  </el-dialog>
</template>
<script>

export default {
    
    
  name: 'upLoader',
  props: {
    
    
    loadingInfo: {
    
     type: Boolean, default: false },
    tip: {
    
     type: String, default: '' },
    tipRed: {
    
     type: String, default: '' },
  },
  data () {
    
    
    return {
    
    
      tmp: Date.now(),
      visible: false,
      fileValue: '',
      loading: false,
      file: {
    
     name: '' },
      upStatus: {
    
    
        code: '',
        msg: '',
        data: []
      },
      tempConfig: {
    
    }
    }
  },
  methods: {
    
    
    handleFileSelect (e) {
    
    
      this.file = e.target.files[0] || {
    
     name: '' }
      console.log(e.target.files)
      console.log(this.file)
      // 如果文件改变需要初始化上传状态
      this.upStatus = {
    
     code: '', msg: '', data: [] }
    },
    exportTemp () {
    
    
      try {
    
    
        // let item = {}
        // Object.keys(this.tempConfig).forEach(v => {
    
    
        //   item[v] = ''
        // })
        // exportsheet.exportFileByConfig([item], '配送中心盘点.xlsx', this.tempConfig)
        // this.$notify.success({
    
    
        //   title: '提示',
        //   message: '下载模块成功'
        // })
        this.$emit('downLoad')
      } catch (e) {
    
    
        this.$notify.error({
    
    
          title: '提示',
          message: '模板下载遇到错误'
        })
      }
    },
    submitUpload () {
    
    
      if (!this.file.name || this.file.name.indexOf(".xl") === -1) {
    
    
        this.$notify.warning({
    
    
          title: '提示',
          message: '请选择excel文件'
        })
        return
      }
      this.$emit('upLoad', this.file)
      // let items = []
      // let parseConfig = {}
      // for (let key in this.tempConfig) {
    
    
      //   parseConfig[this.tempConfig[key]] = key
      // }
      // this.loading = true
      // try {
    
    
      //   items = await exportsheet.parseToJSON(this.file, parseConfig)
      //   // 过滤空行
      //   items = items.filter(item => !!item.LocatorNO)
      //   api.post('/api/CheckInventory/CheckLovInvImport', items, true)
      //     .then(res => {
    
    
      //       this.loading = false
      //       if (res.code === 0) {
    
    
      //         this.$notify.success({
    
    
      //           title: '提示',
      //           message: '导入成功'
      //         })
      //         this.$emit('success', res.data)
      //         this.upStatus.code = 0
      //         this.visible = false
      //       } else {
    
    
      //         this.upStatus = {...res}
      //       }
      //     })
      //     .catch(e => {
    
    
      //       this.loading = false
      //       this.$notify.error({
    
    
      //         title: '提示',
      //         message: e.message
      //       })
      //     })
      // } catch (e) {
    
    
      //   this.loading = false
      //   this.$notify.error({
    
    
      //     title: '提示',
      //     message: e.message
      //   })
      // }
    },
    open () {
    
    
      this.visible = true
      this.fileValue = ''
      this.file = {
    
     name: '' }
    },
    close () {
    
    
      this.visible = false
    }
  }
}
</script>
<style scoped>
.file-label-text {
    
    
  cursor: pointer;
  color: #409eff;
}
.tipBox {
    
    
  margin: 10px 0;
}
.tipRed {
    
    
  color: red;
}
</style>

/src/utils/utils.js

/**
 * @description: 将对象的key转化成数组
 * @param {type} byeKey true 将key转化成数组   false将key对应的值转化成数组
 * @return:
 */
export function objectToArray(obj, byeKey) {
    
    
  let arrList = []
  for(let key in obj) {
    
    
    if(byeKey) {
    
    
      arrList.push(key)
    }else {
    
    
      arrList.push(obj[key])
    }
  }
  return arrList
}

src/utils/exportExcel.js

/* eslint-disable */
import {
    
     saveAs } from 'file-saver'
import XLSX from 'xlsx'

function generateArray(table) {
    
    
  var out = [];
  var rows = table.querySelectorAll('tr');
  var ranges = [];
  for (var R = 0; R < rows.length; ++R) {
    
    
    var outRow = [];
    var row = rows[R];
    var columns = row.querySelectorAll('td');
    for (var C = 0; C < columns.length; ++C) {
    
    
      var cell = columns[C];
      var colspan = cell.getAttribute('colspan');
      var rowspan = cell.getAttribute('rowspan');
      var cellValue = cell.innerText;
      if (cellValue !== "" && cellValue == +cellValue) cellValue = +cellValue;

      //Skip ranges
      ranges.forEach(function (range) {
    
    
        if (R >= range.s.r && R <= range.e.r && outRow.length >= range.s.c && outRow.length <= range.e.c) {
    
    
          for (var i = 0; i <= range.e.c - range.s.c; ++i) outRow.push(null);
        }
      });

      //Handle Row Span
      if (rowspan || colspan) {
    
    
        rowspan = rowspan || 1;
        colspan = colspan || 1;
        ranges.push({
    
    
          s: {
    
    
            r: R,
            c: outRow.length
          },
          e: {
    
    
            r: R + rowspan - 1,
            c: outRow.length + colspan - 1
          }
        });
      };

      //Handle Value
      outRow.push(cellValue !== "" ? cellValue : null);

      //Handle Colspan
      if (colspan)
        for (var k = 0; k < colspan - 1; ++k) outRow.push(null);
    }
    out.push(outRow);
  }
  return [out, ranges];
};

function datenum(v, date1904) {
    
    
  if (date1904) v += 1462;
  var epoch = Date.parse(v);
  return (epoch - new Date(Date.UTC(1899, 11, 30))) / (24 * 60 * 60 * 1000);
}

function sheet_from_array_of_arrays(data, opts) {
    
    
  var ws = {
    
    };
  var range = {
    
    
    s: {
    
    
      c: 10000000,
      r: 10000000
    },
    e: {
    
    
      c: 0,
      r: 0
    }
  };
  for (var R = 0; R != data.length; ++R) {
    
    
    for (var C = 0; C != data[R].length; ++C) {
    
    
      if (range.s.r > R) range.s.r = R;
      if (range.s.c > C) range.s.c = C;
      if (range.e.r < R) range.e.r = R;
      if (range.e.c < C) range.e.c = C;
      var cell = {
    
    
        v: data[R][C]
      };
      if (cell.v == null) continue;
      var cell_ref = XLSX.utils.encode_cell({
    
    
        c: C,
        r: R
      });

      if (typeof cell.v === 'number') cell.t = 'n';
      else if (typeof cell.v === 'boolean') cell.t = 'b';
      else if (cell.v instanceof Date) {
    
    
        cell.t = 'n';
        cell.z = XLSX.SSF._table[14];
        cell.v = datenum(cell.v);
      } else cell.t = 's';

      ws[cell_ref] = cell;
    }
  }
  if (range.s.c < 10000000) ws['!ref'] = XLSX.utils.encode_range(range);
  return ws;
}

function Workbook() {
    
    
  if (!(this instanceof Workbook)) return new Workbook();
  this.SheetNames = [];
  this.Sheets = {
    
    };
}

function s2ab(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;
}

/**
 * @description: 格式化要导出的数据
 * @param {type} 
 * @return: 
 */
function formatJson(filterVal, jsonData) {
    
    
  return jsonData.map(v => filterVal.map(j => {
    
    
    if (j === 'timestamp') {
    
    
      return parseTime(v[j])
    } else {
    
    
      return v[j]
    }
  }))
}

function export_table_to_excel(id) {
    
    
  var theTable = document.getElementById(id);
  var oo = generateArray(theTable);
  var ranges = oo[1];

  /* original data */
  var data = oo[0];
  var ws_name = "SheetJS";

  var wb = new Workbook(),
    ws = sheet_from_array_of_arrays(data);

  /* add ranges to worksheet */
  // ws['!cols'] = ['apple', 'banan'];
  ws['!merges'] = ranges;

  /* add worksheet to workbook */
  wb.SheetNames.push(ws_name);
  wb.Sheets[ws_name] = ws;

  var wbout = XLSX.write(wb, {
    
    
    bookType: 'xlsx',
    bookSST: false,
    type: 'binary'
  });

  saveAs(new Blob([s2ab(wbout)], {
    
    
    type: "application/octet-stream"
  }), "test.xlsx")
}

function export_json_to_excel({
    
    
  multiHeader = [],
  header,
  filterVal,
  data,
  filename,
  merges = [],
  autoWidth = true,
  bookType = 'xlsx'
} = {
    
    }) {
    
    
  /* original data */
  filename = filename || 'excel-list'
  data = formatJson(filterVal, data)
  data.unshift(header);

  for (let i = multiHeader.length - 1; i > -1; i--) {
    
    
    data.unshift(multiHeader[i])
  }

  var ws_name = "SheetJS";
  var wb = new Workbook(),
      ws = sheet_from_array_of_arrays(data);

  if (merges.length > 0) {
    
    
    if (!ws['!merges']) ws['!merges'] = [];
    merges.forEach(item => {
    
    
      ws['!merges'].push(XLSX.utils.decode_range(item))
    })
  }

  if (autoWidth) {
    
    
    /*设置worksheet每列的最大宽度*/
    const colWidth = data.map(row => row.map(val => {
    
    
      /*先判断是否为null/undefined*/
      if (val == null) {
    
    
        return {
    
    
          'wch': 10
        };
      }
      /*再判断是否为中文*/
      else if (val.toString().charCodeAt(0) > 255) {
    
    
        return {
    
    
          'wch': val.toString().length * 2
        };
      } else {
    
    
        return {
    
    
          'wch': val.toString().length
        };
      }
    }))
    /*以第一行为初始值*/
    let result = colWidth[0];
    for (let i = 1; i < colWidth.length; i++) {
    
    
      for (let j = 0; j < colWidth[i].length; j++) {
    
    
        if (result[j]['wch'] < colWidth[i][j]['wch']) {
    
    
          result[j]['wch'] = colWidth[i][j]['wch'];
        }
      }
    }
    ws['!cols'] = result;
  }

  /* add worksheet to workbook */
  wb.SheetNames.push(ws_name);
  wb.Sheets[ws_name] = ws;

  var wbout = XLSX.write(wb, {
    
    
    bookType: bookType,
    bookSST: false,
    type: 'binary'
  });
  saveAs(new Blob([s2ab(wbout)], {
    
    
    type: "application/octet-stream"
  }), `${
      
      filename}.${
      
      bookType}`);
}

/*
 *  @excelFile File
 *  @config Object 解析字段
 *  @setter Object XLSX.utils.sheet_to_json的配置
*/
function parseToJSON (excelFile, config, setter = {
     
     }) {
    
    
  return new Promise((resolve, reject) => {
    
    
    if (window.FileReader) {
    
    
      let result = []
      let fr = new FileReader()
      fr.readAsBinaryString(excelFile)
      fr.onload = ev => {
    
    
        try {
    
    
          let data = ev.target.result
          // 以二进制形式读取excel文件
          let workbook = XLSX.read(data, {
    
    
            type: 'binary'
          })
          // 只遍历第一个表
          let name = workbook.SheetNames[0]
          let sheet = workbook.Sheets[name]
          if (sheet) {
    
    
            result = XLSX.utils.sheet_to_json(sheet, {
    
    defval: '', ...setter})
            if (config) {
    
    
              result.forEach(item => {
    
    
                for (let key in item) {
    
    
                  if (config[key]) {
    
    
                    item[config[key]] = item[key]
                    if(config[key] !== key) {
    
    
                      delete item[key]
                    }
                  }
                }
              })
            }
          }
          resolve(result)
        } catch (e) {
    
    
          reject(new Error("文件类型不正确"))
        }
      }
      return
    }
    reject(new Error("该浏览器不支持该功能,请更换或升级浏览器"))
  })
}


export default {
    
    
  export_table_to_excel,
  ExportJsonToExcel: export_json_to_excel,
  parseToJSON
}

Supongo que te gusta

Origin blog.csdn.net/guairena/article/details/130225911
Recomendado
Clasificación