【java】上传与下载

一、上传
1.1 前端示例
<template>
  <div class="my-upload">
    <el-upload
      style="height: 100%"
      ref="upload"
      action="action"
      :limit="limitNum"
      :auto-upload="true"
      :drag="true"
      :accept="accept"
      :show-file-list="false"
      :list-type="listType"
      :http-request="httpRequest"
      :before-upload="beforeUpload"
      :on-change="fileChange"
      :on-exceed="exceedFile"
      :on-success="handleSuccess"
      :on-progress="handleProgress"
      :on-error="handleError"
      :on-remove="removeFile"
      :file-list="fileList"
      :class="status == 3? 'upload-red-border':'upload-border'"
    >
      <!--文件显示 #BBC1D9-->
      <div style="width:100%">
        <div class="upload-content">
          <i :class="icon" :style="{'color':color}"></i>
          <el-tooltip
            class="item"
            effect="dark"
            :content="notice"
            placement="top"
          >
            <span v-if="status === 1" :style="{'color':color}">{{text}}</span>
          </el-tooltip>
          <span v-if="status !== 1" :style="{'color':color}">
            <div class= "box" v-if="status == 4">
              <span class= "clip" :style= "clipStyle"></span>
              <span class="clip-num">{{Math.round(progress)+"%"}}</span>
            </div>
            {{text}}
          </span>
        </div>
        <!--点击上传 1-->
        <div class="el-upload__text" v-if="status == 1">
          您也可以将文件拖动到这里
          <el-tooltip
            class="item"
            effect="dark"
            :content="tip"
            placement="top"
          >
            <i class="el-icon-warning"></i>
          </el-tooltip>
        </div>
        <!--上传成功 2-->
        <div class="el-upload__text" v-else-if="status == 2" style="display:flex">
          <div style="width: 70%" class="file-name"><div class="ellipsis"><i class="el-icon-document"></i>{{fileName}}</div></div>
          <div style="flex: 0 0 auto" class="del"><el-link type="danger" @click.stop="handleDelFile(file)">删除</el-link></div>
        </div>
        <!--上传中 4-->
        <div class="el-upload__text" v-else-if="status == 4" style="display:flex">
          <div style="width: 70%" class="file-name"><div class="ellipsis"><i class="el-icon-document"></i>{{fileName}}</div></div>
          <div style="flex: 0 0 auto" class="del"><el-link type="primary" @click.stop="handleDelFile(file)">取消</el-link></div>
        </div>
        <!--上传失败 3-->
        <div class="el-upload__text" v-else-if="status == 3" style="display:flex">
          <div style="width: 70%" class="file-name"><div class="ellipsis"><i class="el-icon-document"></i>{{fileName}}</div></div>
          <div style="flex: 0 0 auto" class="del"><el-link type="primary" @click.stop="handleDelFile(file)">重新上传</el-link></div>
        </div>
      </div>
    </el-upload>
    <div class="errTipText" v-show="status == 3"><i class="el-icon-warning-outline"></i>{{msg}} <div v-if="link != ''">您可以<div class="downModel" @click="downloadError">下载文件</div>查看原因</div>
    </div>
  </div>
</template>

<script>
export default {
  name: "my-upload",
  data () {
    return {
      clipStyle: {
        transform: 'rotate(' + 3.6 * 0 + 'deg)'
      },
      limitNum: 2,
      listType: '',
      isPictureImg: false,
      fileList: [],
      menu: false,
      progress: '0',
      status: 1,
      icon: 'el-icon-upload',
      color: '#1E78FF',
      text: '点击上传',
      button: '',
      msg: '',
      formLabelWidth: '80px',
      file: null,
      fileName: '',
      link: '',
    };
  },
  props:{
    action: {
      type: String,
      default: '#'
    },
    maxSize: {
      type: Number,
      default: 10
    },
    drag: {
      type: Boolean,
      default: true
    },
    accept: {
      type: String
    },
    notice: {
      type: String,
      default: '请上传符合模板格式的文件哦!'
    },
    tip: {
      type: String
    },
    template: {
      type: Object,
      default: () => {
        return {}
      }
    },
    module: {
      type: String,
      default: ''
    },
    errorUrl:{
      type: String
    }
  },
  methods: {
    download(res) {
      const content = res.data
      const blob = new Blob([content], { type: 'application/vnd.ms-excel' })
      const fileName = '错误文件.xlsx'
      // this.exportExcelFile(blob, fileName)
      if ('download' in document.createElement('a')) { // 非IE下载
        var link = document.createElement('a')
        link.download = fileName
        link.style.display = 'none'
        link.href = URL.createObjectURL(blob)
        document.body.appendChild(link)
        link.click()
        URL.revokeObjectURL(link.href)
        document.body.removeChild(link)
      } else {
        // IE10+下载
        navigator.msSaveBlob(blob, fileName)
      }
    },
    downloadError(){
      window.open(this.link)
    },
    httpRequest(param){
      var fd = new FormData()
      fd.append('file', param.file)
      fd.append('name', param.file.name)
      fd.append('template',JSON.stringify(this.template))
      fd.append('module', this.module)
      this.$axios({
        url: this.action,
        method: 'post',
        data: fd,
        headers: { 'Content-Type': 'multipart/form-data', 'Authorization': sessionStorage.getItem("token") },
        onUploadProgress: progressEvent => {
          // progressEvent.loaded:已上传文件大小
          // progressEvent.total:被上传文件的总大小
          param.file.percent = (progressEvent.loaded / progressEvent.total * 100)
          param.onProgress(param.file)
        }
      }).then(res => {
        if (res.data.success) {
          param.onSuccess(res)
        } else {
          param.onError(res)
        }
      }).catch(error => {
        param.onError(error)
        console.log(error)
      })
    },
    handleProgress(event, file, fileList){
      if(file){
        this.status = 4
        this.text = '上传中'
        this.icon = ''
        this.fileName = file.name
        this.color = '#BBC1D9'
        this.button = '取消'
        this.progress = event.percent
      }else{
        this.$refs.upload.abort(file)
        this.status = 3
        this.progress = 0
      }
    },
    removeFile(file, fileList){
      if(fileList.length > 0){
        this.file = fileList[fileList.length-1]
      }else{
        this.file = null
      }
    },
    handleDelFile(file){
      this.text = '点击上传'
      this.icon = 'el-icon-upload',
      this.color = '#409eff',
      this.msg = ''
      this.link = ''
      this.fileName = ''
      this.status = 1
      this.$refs.upload.handleRemove(file);
      this.$emit("handleDisable",true)
    },
    // 文件超出个数限制时的钩子
    exceedFile(file, fileList) {
      // this.$refs.upload.abort(file)
    },
    // 文件状态改变时的钩子
    fileChange(file, fileList) {
      if (fileList.length > 1) {
        fileList.splice(0, 1)
        this.fileName = ''
      }
      if(fileList.length > 0){
        this.file = fileList[fileList.length-1]
        this.fileName = file.name
      }else{
        this.showFileList = false
      }
    },
    // 上传文件之前的钩子, 参数为上传的文件,若返回 false 或者返回 Promise 且被 reject,则停止上传
    beforeUpload(file) {
      this.msg = '';
      var extension = file.name.substring(file.name.lastIndexOf('.') + 1)
      if (this.accept != '' && this.accept.indexOf(extension)<0) {
        this.fileName = file.name
        this.msg = '文件格式错误'
        this.status = 3
        return false
      }
      var size = file.size / 1024 / 1024
      // var imgList = ['png', 'jpg', 'jpeg', 'bmp', 'gif']
      // if(imgList.indexOf(extension) > 0){
      //   if(size > 5) {
      //     this.fileName = file.name
      //     this.msg = '图片大小超过限制'
      //     this.status = 3;
      //     this.button = '重新上传'
      //     this.text = '上传失败'
      //     this.color = '#F43C3C'
      //     this.icon = 'el-icon-error'
      //     this.$emit("handleDisable",true)
      //     return false;
      //   }
      // }else{
        if (size > this.maxSize) {
          this.fileName = file.name
          this.msg = '文件大小超过限制'
          this.status = 3;
          this.button = '重新上传'
          this.text = '上传失败'
          this.color = '#F43C3C'
          this.icon = 'el-icon-error'
          this.$emit("handleDisable",true)
          return false;
        }
      // }
    },
    // 文件上传成功时的钩子
    handleSuccess(res, file, fileList) {
      if(res.data.msg != '操作成功'){
        this.status = 3;
        this.fileName = file.name
        this.icon = 'el-icon-error'
        this.button = '重新上传'
        this.text = '上传失败'
        this.color = '#F43C3C'
        this.msg = res.data.msg
        if(res.data.data != ''){
          this.link = res.data.data
        }
        if(!res.data.msg){
          this.msg = '上传失败,请再试一次'
        }
      }else{
        this.status = 2;
        this.icon = 'el-icon-success'
        this.text = '上传成功'
        this.button = '删除'
        this.color = '#67C23A'
      }
      // res.data.data.size = file.size
      this.$emit("handle",res)
    },
    // 文件上传失败时的钩子
    handleError(err, file, fileList) {
      this.status = 3;
      this.fileName = file.name
      this.icon = 'el-icon-error'
      this.button = '重新上传'
      this.text = '上传失败'
      this.color = '#F43C3C'
      if(err.data && err.data.msg){
        this.msg = err.data.msg
      }else {
        this.msg = '上传失败,请再试一次'
      }
      if(err.msg || err.message){
        this.msg = err.msg || err.message
      }
      if(err.response){
        this.msg = err.response.data.msg
      }
      if(err.data && err.data.code == 1601){
        this.link = err.data.data.link
      }
      this.$emit("handleDisable",true)
    },
    clearFileData(){
      this.text = '点击上传'
      this.icon = 'el-icon-upload',
      this.color = '#1E78FF',
      this.msg = ''
      this.fileName = ''
      this.status = 1
      this.fileList = []
      this.file = null
    }
  }
};
</script>
<style lang="scss">
.my-upload {
  width: 250px;
  height: 110px;
  .ellipsis{
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
  }
  .el-upload-dragger .el-upload__text{
    line-height: 18px;
  }
  .upload-content {
    font-size: 14px;
    line-height: 18px;
    color: #409eff;
    margin-top: 28px !important;
    margin-bottom: 16px !important;
    cursor: pointer;
  }

  .upload-content i {
    font-size: 22px;
    line-height: 24px;
    color: #409eff;
  }

  .upload-content span {
    vertical-align: text-top;
  }

  .el-upload-dragger {
    display: flex;
    border-radius: 8px;
    -webkit-box-orient: vertical;
    -webkit-box-direction: normal;
    -webkit-box-align: center;
    flex-direction: column;
    align-items: center;
    -webkit-box-pack: center;
    justify-content: center;
    width: 248px !important;
    height: 110px !important;
    border:none !important;
    background:transparent !important;
  }
  .uploadFile {
    margin: 0 auto;
    margin-top: 32px;
    width: 250px;
  }

  .downModel {
    font-size: 14px;
    line-height: 22px;
    color: #409eff;
    margin-bottom: 12px;
    cursor: pointer;
    display:inline-block;
  }

  .upload-content {
    font-size: 14px;
    line-height: 18px;
    color: #409eff;
    margin-top: 28px !important;
    margin-bottom: 16px !important;
    cursor: pointer;
  }
  .el-icon-upload {
    margin: 0;
  }

  .upload-content i {
    color: #409eff;
    margin: 0;
    line-height: 20px;
    font-size: 20px;
  }

  .upload-content span {
    vertical-align: text-top;
  }
  .upload-border{
    background: #F9F9FC;
    border: 1px dashed #C3C7CE;
    border-radius: 8px;
  }

  .upload-border:hover {
    background: #F9F9FC;
    border: 1px dashed #504EF2;
    border-radius: 8px;
  }

  .upload-red-border {
    background: #F9F9FC;
    border: 1px dashed #F43C3C;
    border-radius: 8px;
  }
  .clip{
    box-sizing: border-box;
    border-top: 2px solid #1E78FF;
    border-left: 2px solid #1E78FF;
    border-right: 2px solid #ccc;
    border-bottom: 2px solid #ccc;
    border-radius: 50%;
    vertical-align: text-top;
    transform: rotate(
        0deg
    );
    width: 16px;
    height: 16px;
    display: inline-block;
    margin-right: 6px;
  }
  .box{position: relative;
    /*width: 14px;*/
    height: 14px;
    overflow: hidden;
    width: auto;
    text-align: center;
    display: inline-table;
    color: #1E78FF;
  }
  .box span {
    vertical-align: middle;
  }
  .el-progress {
    align-items: center;
    display: flex;
    width: 100%;
  }
  .clip-num {
    width: auto;
    padding: 0 2px;
    display: inline-block;
    background: transparent;
  }
  .errTipText {
    color: #F43C3C;
    font-style: normal;
    font-weight: normal;
    font-size: 12px;
    line-height: 22px;
  }
  /deep/ .el-upload-dragger {
    width: 248px !important;
    height: 110px !important;
    border:none !important;
    background:transparent !important;
  }

  /deep/ .el-icon-upload {
    margin: 0;
  }
}
</style>
1.2 前端调用
<knowledge-upload ref="knowledgeUpload" @handle="handleUpload" @handleDisable="handleDisable" :show-file-list="false" :module="upload.module" :action="upload.action" :notice="upload.notice" :accept="upload.accept" :list-type="upload.listType" :tip="upload.tip" :template="template" :drag="true"></knowledge-upload>


upload: {
  importDialogVisible: false,
  fileList: [],
  tip: '仅支持上传xls或者xlsx文件 大小不超过10m',
  listType: '',
  action: '/integration/word/upload',
  accept: '.xlsx,.xls',
  notice: '点我上传',
  module: 'word',
},
1.3 后端示例
@PostMapping(value = "/upload")
    @ApiOperation(value = "导入")
    public R<Boolean> upload(@Validated UploadDTO uploadDTO) {
        String template = uploadDTO.getTemplate();
        String tmpDir = System.getProperty("java.io.tmpdir") + "upload/";
        File tmpDirFile = new File(tmpDir);
        if (!tmpDirFile.exists() && !tmpDirFile.isDirectory()) {
            tmpDirFile.mkdir();
        }
        String pathName = tmpDir + System.currentTimeMillis();
        File file = new File(pathName);
        try {
            uploadDTO.getFile().transferTo(file);
            service.upload(template, file, pathName);
        } catch (Exception e) {
            e.printStackTrace();
        }
        return R.status(true);
    }
@Data
public class UploadDTO {
    @NotNull(message = "文件不能为空")
    private MultipartFile file;
    @NotBlank(message = "模板不能为空")
    private String template;
}

二、下载
2.1 前端示例
<el-button icon="el-icon-download" size="small" type="primary" @click="download">导出</el-button>
download(){
      let fd = new FormData();
      fd.append("template", JSON.stringify(this.template));//模板
      download(fd).then(res => {
        this.$message({
          showClose: true,
          message: "下载成功",
          type: "success"
        });
        this.download(res);
      })
    },
    download(res){
      const content = res.data;
      const blob = new Blob([content]);
      const fileName = "导出.xlsx";
      if ('download' in document.createElement('a')) { // 非IE下载
        var link = document.createElement('a');
        link.download = fileName;
        link.style.display = 'none';
        link.href = URL.createObjectURL(blob);
        document.body.appendChild(link);
        link.click();
        URL.revokeObjectURL(link.href); // 释放URL 对象
        document.body.removeChild(link);
      } else { // IE10+下载
        navigator.msSaveBlob(blob, fileName);
      }
    },
2.2 后端代码示例
@PostMapping(value = "/download")
@ApiOperation(value = "导出")
public ResponseEntity<byte[]> download(@Validated DownloadDTO downloadDTO) {
    String displayName = System.currentTimeMillis()+".xlsx";
    byte[] bytes = service.download(downloadDTO, displayName);
    HttpHeaders headers = new HttpHeaders();
    headers.setContentType(MediaType.APPLICATION_OCTET_STREAM);
    headers.setContentDispositionFormData("attachment", displayName);
    return new ResponseEntity<byte[]>(bytes, headers, HttpStatus.OK);
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

王佑辉

老板,赏点吧

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值