react 上传excel处理成json数据后发送请求

最近接到一个需求,是导入excel表格,请求后台的接口需要提供两个数据,一个是导入的数据对应的分类id,一个是导入的数据对应的json类型,这就要求在请求之前要把excel数据处理成json数据,前端用的是react框架,首先是界面

<Button icon="plus">
    import
    <input type="file" onChange={()=>this.uploadExcel()}     
    id="channelFile" ref='pathClear'
    accept="application/vnd.ms-excel,application/vnd.openxmlformats- 
    officedocument.spreadsheetml.sheet"/>
</Button>

把input框放到button控件里,这时候,input的样式和Button的样式都在,页面显示是这样的

这样很丑

给input框加个样式

css文件里

app.css

.fileInput{
  opacity:0;
  width:100%;
  height:100%;
  position:absolute;
  top:0;
  left:0
}

list.js 

<Button icon="plus">import
    <input type="file" className="fileInput" onChange={()=>this.uploadExcel()} 
    id="channelFile" ref='pathClear'
    accept="application/vnd.ms-excel,application/vnd.openxmlformats- 
    officedocument.spreadsheetml.sheet"/>
</Button>

这样页面的显示就是正常的了

接下来是input 的onChange方法

list.js

uploadExcel(){
      var _this = this
      let file = document.getElementById("channelFile").files[0]
      var fileReader = new FileReader();
      fileReader.onload = function(ev) {
          try {
              var data = ev.target.result,
                  workbook = xlsx.read(data, {type: 'binary'}),
                  channels = []; // 存储获取到的数据
          } catch (e) {
              console.log('文件类型不正确');
              return;
          }
          // 表格的表格范围,可用于判断表头是否数量是否正确
          var fromTo = '';
          // 遍历每张表读取
          for (var sheet in workbook.Sheets) {
              if (workbook.Sheets.hasOwnProperty(sheet)) {
                  fromTo = workbook.Sheets[sheet]['!ref'];
                  channels = 
                  channels.concat(xlsx.utils.sheet_to_json(workbook.Sheets[sheet]));
                  // break; // 如果只取第一张表,就取消注释这行
              }
          }    
_this.props.uploadExcel(channels,_this.props.categoryid,_this.props.currentPage,_this.props.pageSize)
          _this.refs.pathClear.value = '';
        }
      // 以二进制方式打开文件
      if(file!=null&&typeof(file)!="undefined"){
        fileReader.readAsBinaryString(file);
      }
    }

上面的xlsx插件需要下载,然后在js文件中引入

npm i xlsx

list.js

import xlsx from 'xlsx'

打开excel文件后,读取文件中的数据到channels,然后调用mapDispatch里的uploadExcel方法

list.js

const mapDispatch = (dispatch) => {
  return {
    uploadExcel(channels,categoryid,currentPage,pageSize){
      dispatch(actionCreators.uploadExcel(channels,categoryid,currentPage,pageSize))
    }
  }
}

actitonCreators.js

export const uploadExcel = (channels,categoryId,currentPage,pagesize) =>{
    return(dispatch)=>{
        let params = {
            cid:categoryId,
            data:channels
        }
        axios({
            dataType: 'json',
            headers: {
                "Content-Type": "application/json;charset=utf-8"
            },
            method:'post',
            url:'/api/importExcel',
            data:JSON.stringify(params),
        }).then(res=>{
            if (res.data.returnCode === 0) {
                message.success("importSuccess")
                dispatch(getChannelListByPage(currentPage,pagesize,categoryId))
            } else if(res.data.returnCode === 1){
                message.warning("uploadTypeNotRight")
            }
        })
    }
}

在这里,要注意把上传的数据,用JSON.stringify转换为json字符串,同时headers里面的Content-Type也要设置为application/json;charset=utf-8,不然会报415

需要注意的是,在uploadExcel方法中,调用完成_this.props.uploadExcel方法之后,要清空input中的内容,因为对input而言,如果不清空,上传同一个文件的时候,onChange方法是不会触发的,这里是直接把input的value值设置为‘’

 _this.refs.pathClear.value = '';

后台Java代码是这样的

Importcontroller.java

@PostMapping("/importExcel")
@ResponseBody
public String importExcel(@RequestBody JSONObject jsonObject) {
		List<Channel> channels = JSON.parseArray(JSONArray.toJSONString(jsonObject.get("data")), Channel.class);
		String cidTemp = jsonObject.getString("cid");
		Integer cid = Integer.parseInt(cidTemp);
		return clientLinkService.importExcel(channels,cid);
	}

前端部分react结合了redux,如果没有了解过,可能不太看得懂各文件之间的关联,不过这一篇的重点是说到导入excel,拿到excel的数据之后,可以根据自己的业务去调用具体的方法

  • 3
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值