vue+element-ui+axios+springboot实现文件上传&下载

前端技术:vue,element-ui,axios

后台技术:springboot

本篇博客只给出关键的代码,提供思路,完全的涉及保密不方便提供

一,上传:

上传element组件代码,支持多文件,拖动文件进行上传:

<!--选择文件-->
                    <el-form-item label="选择模板" :label-width="formLabelWidth" :required="trueFlag">
                        <el-row>
                            <el-col :span="12">
                                <div class="grid-content bg-purple">
                                    <el-upload
                                            class="upload-demo"
                                            ref="upload"
                                            :action="actionUrl"
                                            :auto-upload="false"
                                            :limit="10"
                                            multiple
                                            accept="application/pdf"
                                            :before-upload="beforeUpload"
                                            :before-remove="beforeRemove"
                                            :on-remove="handleRemove"
                                            :on-change="fileChange"
                                            :file-list="fileList"
                                            :drag="trueFlag">
                                        <el-button size="small" type="primary">选取模板</el-button>
                                        <!--<el-button style="margin-left: 10px;" size="small" type="success" @click="submitUpload">上传到服务器</el-button>-->
                                        <div slot="tip" class="el-upload__tip">只能上传pdf文件,且不超过2M</div>
                                    </el-upload>
                                </div>
                            </el-col>
                        </el-row>
                    </el-form-item>
                </el-form>
                <div slot="footer" class="dialog-footer">
                    <el-button v-on:click="uploadDialogFormVisible = false">关闭</el-button>
                    <!--<el-button type="primary" v-on:click="uploadDialogFormVisible = false">上传</el-button>-->
                    <el-button type="primary" @click="submitUpload">上传到服务器</el-button>
                </div>
            </el-dialog>

 

上传前端js方法:

submitUpload: function () {
            if (this.area == null || this.area == '' || this.fileList.length < 1) {
                this.$message({
                    message: '区域未选择,或未选取上传模板',
                    type: 'error'
                });
                return;
            }
            let formData = new FormData();
            this.fileList.forEach(function (file) {
                formData.append("files", file.raw, file.name);
            });
            let config = {
                'Content-Type': 'multipart/form-data'
            };
            formData.append("area", this.area);
            let var_this = this;
            axios.post('/model/upload', formData, config)
                .then(function (response) {
                    if (response.data.status == 1) {
                        var_this.$message({
                            message: `${var_this.area}区域${var_this.fileList.length}个文件(上传/更新)成功`,
                            type: 'success'
                        });
                    } else {
                        var_this.$message({
                            message: response.data.msg,
                            type: 'error'
                        });
                    }
                }).catch(function (error) {
                console.log(error);
            })
        }

      说明:这里使用的是表单上传多文件,element-ui上传组件默认多文件上传实际上是一个文件一个文件进行上传的,这里利用表单可以实现一次请求上传多个文件,而且,上传文件的同时可以添加其他额外的属性,字段信息

 

后台springboot接口核心代码:

 @PostMapping("upload")
    @ResponseBody
    public ResponseResult uploadModel(@ModelAttribute ModelFileVO modelFileVO) {
          //文件上传具体处理逻辑
        return rs;
    }

处理多文件上传的接口,内部处理逻辑网上很多资料,可以自己查找资料,主要使用到了@ModelAttribute注解,这个注解支持前端表单形式的参数,这里用来接收多文件,以及其他的参数,下面这个类是具体说明,出了多文件,还使用了额外的area字段,files表示多文件数组,@Data是用来解决set,get问题

 

 

@Data
public class ModelFileVO {
    private String area;
    private MultipartFile[] files;

}

 

效果图如下:

 

 

 

二,下载:

element-ui下载核心代码:

   <template slot-scope="scope">
                            <!--下载按钮-->
                            <el-button type="warning" icon="el-icon-download" :circle="isCircle" @click="downloadModel(scope.row)"></el-button>
                            <!--编辑按钮-->
                            <el-button type="primary" v-on:click="editUpload" icon="el-icon-edit"
                                       :circle="isCircle"></el-button>
                            <!--删除按钮-->
                            <el-button type="danger" v-on:click="deleteModel(scope.$index, scope.row)"
                                       icon="el-icon-delete" :circle="isCircle"></el-button>
                        </template>

 

下载vue.js的处理核心代码:

downloadModel: function (row) {
            console.log(row);
            let param = `?area=${this.area}&id=${row.id}&name=${row.name}`;
            axios.post('/model/download'+param
                ,{area:this.area,id:row.id, name:row.name},{responseType: 'blob'})
                .then(response =>{
                    let data = response.data;
                if (!data) {
                    return
                }
                console.log(response);
                let contentDisposition = response.headers['content-disposition'];
                let fileName = contentDisposition.substring(contentDisposition.indexOf('=')+1);
                console.log('fileName=' + fileName);
                let url = window.URL.createObjectURL(new Blob([data]))
                let a = document.createElement('a')
                a.style.display = 'none'
                a.href = url
                a.setAttribute('download',fileName)
                document.body.appendChild(a)
                //点击下载
                a.click()
                // 下载完成移除元素
                document.body.removeChild(a);
                // 释放掉blob对象
                window.URL.revokeObjectURL(url);
                console.log("下载完成");
                }).catch(function (error) {
                console.log(error);
            });
        }

       说明:由于下载的是文件流,所以请求的方法配置参数需要把返回类型设置为blob,eg:responseType: 'blob',另外注意axios的get和post方法的传参顺序问题。get方法第一个参数是url+ur后面的参数,第二个参数是请求配置参数;post:有三个参数,第一个是url,第二个是请求参数,第三个是请求的配置数据。

         下载下来的blob,我们需要创建一个url来指定这个流,创建html的a标签,设置下载属性download,下载的url,最后调用click方法进行下载,下载完成文件以后记得删除创建的a标签,释放资源。

 

后端核心代码:

@PostMapping("/download")
    @ResponseBody
    public ResponseResult download(HttpServletRequest request, HttpServletResponse response, @RequestBody ModelVO modelVO) throws UnsupportedEncodingException {
        //.......................业务代码省略,下面给出下载核心代码
        //下载逻辑:
        // 设置强制下载不打开
        response.setContentType("application/force-download");
        // 设置文件名,fileName是下载文件的文件名
        response.addHeader("Content-Disposition",
                "attachment;fileName=" + URLEncoder.encode(downloadModel.getName()+".pdf","UTF-8"));
        byte[] buffer = new byte[1024];
		//需要下载文件的字节数组
        byte[] modelByte = Base64Utils.base64String2Byte(downloadModel.getContent());
        ByteArrayInputStream byteArrayInputStream = new ByteArrayInputStream(modelByte);
        try {
            OutputStream out = response.getOutputStream();
            int i = byteArrayInputStream.read(buffer);
            while (i != -1) {
                out.write(buffer, 0, i);
                i = byteArrayInputStream.read(buffer);
            }
            out.flush();
            System.out.println("********************下载success**************");
        } catch (IOException e) {
            e.printStackTrace();
        }finally {
            if (byteArrayInputStream != null) {
                try {
                    byteArrayInputStream.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
        return ResponseResult.success();
    }

       说明:ModelVO是封装的一个类,用来接收post传输的参数,我的项目里使用了thymeleaf模板,所以下载接口需要添加@ResponseBody,不然以为不是接口,是需要返回一个页面的,下载接口是支持get和post,只是get和post方式的话,传参不一样,方法上面的注解也不一样,@PostMapping或@GetMapping

 

 

 

   欢迎加群学习交流:331227121

 

 

 

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值