vue项目多个文件上传和下载

文件上传

上传文件是项目里经常遇到的需求,我之前基本上是碰到的单个文件上传,最近的项目有多个文件同时上传的需求并下载,遂记录一下。

注意:文件上传时必须使用FormData形式传参。

以Element-UI为例:

<el-form-item label="事件描述:" prop="parent_data.description"
 :label-width="formLabelWidth">
   <el-input v-model="form.parent_data.description" 
    placeholder="请输入事件背景,核心问题及解决要求" type="textarea"
     :autosize="{ minRows: 4, maxRows: 8}" autocomplete="off"/>
   <div class="fileContainer">
       <el-upload ref="upload" class="upload-demo" action="#" :auto-upload="false" :on-change="selectFile" multiple :limit="3" :file-list="fileList"
            >
              <el-button size="small" type="primary">点击上传</el-button>
              <span slot="tip" class="el-upload__tip">单个附件大小不超过20M</span>
       </el-upload>
    </div>
</el-form-item>

 点击上传按钮选择文件(上传组件的使用方法请参考Element官网)

/* 选择上传文件 */
selectFile(file, fileList) {
    this.fileList = fileList
	this.fileList.map((item, index) => {
	    const fileSize = item.size / 1024 / 1024
	    if (fileSize > 20) {
	    this.$message.error('单个附件大小不能超过20M')
		this.fileList.splice(index, 1)
	    }
    })
},

将选择的文件保存到`fileList`数组中。有条件限制的可以在这处理。

我们知道上传文件时参数要用`FormData`形式传参,下一步就是把添加的文件放到`FormData`里面。

const fileData = new FormData()
this.fileList.map((file,index)=>{
    // data_report为请求接口时的参数,将文件存放到此参数中,多个文件会有多个data_report参数
    // 这里添加的是file.raw,file格式文件(二进制)
    fileData.append('data_report', file.raw)
}
)

例如,我一次上传两个文件,如图:

 当然有时候上传接口不止一个文件参数,还有其它参数,我们要把它们拼接起来。

const params = {
	...this.form, // 表单数据
    parent_data: JSON.stringify(this.form.parent_data),// 其它参数
	creator_username: getUserInfo().name, // 其它参数
	job_num: getUserInfo().job_num, // 其它参数
	user_id: getUserInfo().userId // 其它参数		 		
}

然后把上面的参数储存到`fileData`中

// 参数合并
for (const key in params) {
	fileData.append(key, params[key])
}

// 现在`fileData`里包含了上传的文件参数和其它参数

最后就可以调用接口了

API.createList(fileData).then(async res => {
    // TODO

})

文件下载

下载时怎么监听进度呢?

首先我们在封装下载接口时添加一个配置对象config,然后要指定服务器返回的数据类型:

// 下载附件
export function downloadFile(data, config = {}) {
	return request({
		url: '/workflows/download_file/',
		method: 'post',
		data,
		responseType: 'blob', // 表明服务器返回的数据类型(文件流的形式)
		...config // config对象主要用来添加上传/下载附件监听
	})
}

 点击下载按钮请求接口:

/* 下载附件 */
downloadFile(item) {
	const that = this
	const params = {
		path: item.path
	}
	API.downloadFile(params,
	    { // 文件下载监听
		    onDownloadProgress(progress) {
				const loading = that.$loading({
				    lock: true,
				    text: '下载中...',
				    spinner: 'el-icon-loading',
				    background: 'rgba(0, 0, 0, 0.7)'
				})

				// 下载进度
				const percent = Math.round((progress.loaded / progress.total) * 100) + '%'

				if (percent === '100%') {
					loading.close()
				}
			}
		}
			).then(res => { // 以流的形式返回的,这里没有code状态码
				const blob = new Blob([res.data])
				// 切割出文件名
				const fileNameEncode = res.headers['content-disposition'].split('filename=')[1]
				// 解码
				let fileName = decodeURIComponent(fileNameEncode)
				// 解码后的文件名会首尾多_,截取掉
				fileName = fileName.substring(1, fileName.length - 1)

				if (window.navigator.msSaveOrOpenBlob) {
					navigator.msSaveBlob(blob, fileName)
				} else {
					var link = document.createElement('a')
					link.href = window.URL.createObjectURL(blob)
					link.download = fileName
					link.click()
					// 释放内存
					window.URL.revokeObjectURL(link.href)
				}
			})
		},

  • 2
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
好的,针对你的问题,我可以为你提供以下的思路和代码示例: 1. 在前端页面中添加上传文件的表单,可以使用 VUE 中的 el-upload 组件实现。 2. 在后端代码中编写接收上传文件的接口,可以使用 SpringBoot 中的 MultipartFile 类来处理上传文件。 3. 对于多文件上传,前端页面可以使用 el-upload 组件的 multiple 属性,后端接口则可以使用 MultipartFile[] 数组来接收。 下面是一个示例的前端代码: ```vue <template> <el-upload action="/upload" multiple :on-success="handleSuccess" :before-upload="beforeUpload" > <el-button size="small" type="primary">选择文件</el-button> <div slot="tip" class="el-upload__tip">只能上传jpg/png文件,且不超过500k</div> </el-upload> </template> <script> export default { methods: { beforeUpload(file) { const isJPG = file.type === 'image/jpeg' || file.type === 'image/png'; const isLt500K = file.size / 1024 < 500; if (!isJPG) { this.$message.error('只能上传jpg/png文件'); } if (!isLt500K) { this.$message.error('上传文件大小不能超过 500KB'); } return isJPG && isLt500K; }, handleSuccess(response) { this.$message.success(`上传成功:${response}`); }, }, }; </script> ``` 其中,el-upload 组件的 action 属性表示上传文件的后端接口地址,multiple 属性表示支持多文件上传。beforeUpload 方法用于在上传前对文件进行校验,handleSuccess 方法则是上传成功后的回调函数。 下面是一个示例的后端代码: ```java @PostMapping("/upload") public String handleFileUpload(@RequestParam("files") MultipartFile[] files) { List<String> fileNames = new ArrayList<>(); for (MultipartFile file : files) { String fileName = StringUtils.cleanPath(file.getOriginalFilename()); fileNames.add(fileName); try { Path path = Paths.get(uploadDir + fileName); Files.copy(file.getInputStream(), path, StandardCopyOption.REPLACE_EXISTING); } catch (IOException e) { e.printStackTrace(); } } return "Uploaded files: " + fileNames; } ``` 其中,@RequestParam("files") MultipartFile[] files 表示接收名为 files 的文件数组,uploadDir 表示文件上传的目录路径。 希望这个代码示例能够对你有所帮助!

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值