在工作中遇到一个需求是希望前端解析用户上传的txt文件后封装成一个数组通过json格式发给后端,在这里我并没有用antd的组件,而是用了js原生的input来做
思路:通过js的fileReader对象来读取用户上传的txt文件,然后通过\n切割成一个数组再通过post请求发给后端
页面布局&功能
用户可以通过粘贴订单到订单列表来发送订单,也可以通过上传txt文件来发送订单,也可以同时粘贴订单和上传文件
<Input type="file" onChange={e => this.Upload(e)} accept='text/plain'></Input>
//导入
Upload = (e) => {
console.log('e---------------------', e)
console.log('e.target-----------------------', e.target)
//判断用户是否上传了文件
if (e.target.value) {
//let order_list = this.state.order_list
//改变this的指向
let that = this
//拿到用户上传的文件
let file = e.target.files[0]
console.log('e.target.files[0]---------------------',e.target.files[0])
//判断上传的文件是否为txt文件
if(file.type === 'text/plain'){
//创建 FileReader 对象
let reader = new FileReader()
console.log('file------------------------', file)
//readAsText 方法可以将 Blob 或者 File 对象转根据特殊的编码格式转化为内容 (字符串形式)
reader.readAsText(file, 'UTF-8')
console.log(reader)
//onload事件在读取操作完成时触发。
reader.onload = function (event) {
//event.target.result即是用户上传的txt文件的内容
let data = event.target.result
//把文件中的\r和\n和''都去掉
let reg = (/\r\n/g)
let arr = data.split(reg).filter(item => item !== '')
//这一步是可以存储用户上传的多个文件,现在的需求是上传一个文件
// that.setState({
// order_list: [
// ...order_list,
// ...arr
// ]
// })
that.setState({
order_list: arr
})
message.success(file.name+'上传成功',2)
console.log('orderlist--------------------', that.state.order_list)
}
}else{
message.error('上传的不是txt文件',2)
//return
}
}//else{
// this.setState({
// order_list: []
// })
// }
}
注意:假如用户上传文件后关闭模态框了,那此时我们需要在组件的onCancel事件清空state里面的订单数组,因为其他数据的清空可以通过在组件设置destroyOnClose={true},但是用户上传的文件我是直接setState进去state的订单数组存着的,所以此时我需要清空。
handleCancel = () => {
this.setState({
visible: false,
//关闭模态框时清空上传的txt文件,其他数据的清空在modal设置 destroyOnClose={true}
order_list: []
})
}
如果用户在订单列表粘贴了订单也上传了文件,那我们可以在发请求的时候解构订单数组把用户粘贴的订单加进去
//判断用户是否在订单列表输入内容
if(order_list){
//同理通过\n切割
let arr = order_list.split('\n').filter(item => item !== '')
order_list = arr
//判断用户在订单列表输入内容的情况是否还上传了txt文件
if(this.state.order_list !== []){
//解构order_list
order_list = [
...order_list,
...list
]
}
}else{
order_list = list
}