java解压缩(上传和下载)zip压缩包[超详细]包含[前后端]

发布时间:2024年01月13日

前言

在日常中,我们想在没有网络的情况下进行将一个项目中的数据,导入另一个项目中,从而实现数据之前的转换和迁移。这时候,我们可以通过生成压缩包,和解压zip压缩包的形式,将数据进行各种迁移,接下来就让我们开始吧。

一、生成(下载)zip压缩包

1、前端代码

因为我使用的是vue2,所以就按照vue2的形式来编写了,其实就是一个点击按钮,对应的点击事件的方法。具体项目具体分析即可

     <a-button  @click="sendToThreePlatform" type="danger" ghost icon="upload">生成zip压缩包</a-button>







<!-- 下面的代码就是sendToThreePlatform函数方法,具体项目具体分析-->

export default {



methods:{

     sendToThreePlatform(){
        // params理解为参数
             let params = {
        projectId: this.selectedMainId,
      }
      this.$message.loading({ content: '请稍等...', key: 'Zip', duration: 0 })
        //自己封装的ajax方法,你可以使用原始的ajax
        // 参数1:url;参数2:形参
       getAction(this.url.deriveThreeStagePlatform, params).then((res) => {
        if (res.success) {
          // window.open(getFileAccessHttpUrl(res.result))
            
          this.$message.success({ content: '下载开始', key: 'Zip', duration: 1 })
            
          if (typeof window.navigator.msSaveBlob !== 'undefined') {
//允许用户在客户端上下载文件 参数1:生成数据,参数2:指定文件名称
//data 和fileName是我自己封装好的数据,具体,你可以在百度上搜索一下msSaveBlob如何使用
            window.navigator.msSaveBlob(new Blob([data]), fileName)
          } else {
            //下面步骤可以理解为:生成一个下载链接,下载完成之后将改标签删除。
            //获取文件服务访问路径
            let url = getFileAccessHttpUrl(res.result)
            let link = document.createElement('a')
            link.style.display = 'none'
            link.href = url
            link.setAttribute('download', res.result)
            document.body.appendChild(link)
            link.click()
            document.body.removeChild(link) //下载完成移除元素
            window.URL.revokeObjectURL(url) //释放掉blob对象
          }
        } else {
          this.$message.warning({ content: '导出失败!', key: 'Zip', duration: 1 })
        }
      })



    }
}

}

2、后端代码

2.1、需要的maven

	<dependency>
			<groupId>net.lingala.zip4j</groupId>
			<artifactId>zip4j</artifactId>
			<version>1.3.2</version>
		</dependency>
    <dependency>
            <groupId>cn.hutool</groupId>
            <artifactId>hutool-all</artifactId>
            <version>5.8.16</version>
        </dependency>

?2.2、代码

  @GetMapping("/deriveThreeStagePlatform")
 public Result<?> deriveThreeStagePlatform(@RequestParam String projectId, HttpServletRequest request, HttpServletResponse response) {
//我代码中查询出来的数据
 TptProject project = tptProjectService.getById(projectId);
//        //创建压缩文件
        ZipParameters zipParameters = new ZipParameters();
        //设置文件加密
        zipParameters.setEncryptFiles(true);
        //加密
        zipParameters.setEncryptionMethod(Zip4jConstants.ENC_METHOD_STANDARD);
        //设置自定义密码
        zipParameters.setPassword(zipPassword);
        //设置zip文件名
        ZipFile zipFile = getZip(project.getName());

        //将项目的所需信息,查询出来生成JSON字符串;---该方法是自定义封装的方法,我将想要的数据变为一个大的json字符串。
        String jsonString = this.createProjectToJsonString(projectId);

        //生成.txt文件  这个方法在下面会写到
        String JSONStringName = this.createTXTString(jsonString, projectId);
        //获取到该文件
        File txt = new File(upLoadPath + File.separator + JSONStringName);
        if (!txt.exists()) {
            throw new RuntimeException("txt文件生成失败");
        }
        //添加txt文件
        zipFile.addFile(txt, zipParameters);
        
        txt.delete();

        //添加所有文件
        File projectFiles = new File(upLoadPath + File.separator + project.getName() + "_" + project.getId());
        if (projectFiles.exists()) {
            zipFile.addFolder(projectFiles, zipParameters);
        }
        return Result.OK("操作成功!",  "temp"+File.separator + zipFile.getFile().getName());

    }

?createTXTString方法

  private String createTXTString(String jsonString, String projectId) {
        //被测项目信息 --自己项目中查询的数据
        TptProject project = tptProjectService.getById(projectId);
        //被测项目名称  ---自己项目中查询的数据
        String projectName = project.getName();
        try {

            // 创建file类
            /**
                  upLoadPath:表示指定的路径。---这个自己设置
                    File.separator:---代表/
                    TXT_SUFFIX: 自定义的名称 表示 .txt
        总体表示: xx/xxx/xxx/xxx.txt 
        */
            File file = new File(upLoadPath + File.separator+projectName + TXT_SUFFIX);

            //将jsonString数据写入到指定的file文件中,并且格式为utf-8
            OutputStreamWriter out = new OutputStreamWriter(new FileOutputStream(file),"UTF-8");
            out.write(jsonString);

            out.flush();
            out.close();
        }catch(IOException e){
            e.printStackTrace();
        }

        // 返回一个文件名称
        return File.separator + projectName + TXT_SUFFIX;
    }

好了,上述代码就是将一个数据生成.txt文件并且保存到zip压缩包中,并且下载到客户端,上述代码是生成.txt文件,我们还可以生成.sql ;.xml等各种文件,具体代码具体分析。

?二、java解压(上传)zip压缩包

已经下载好的压缩包,我们现在需要在导入到另外一个项目中具体方法如下。

1、前端代码

<!--因为我使用的前端为vue+Ant Design所以就使用这种组件,如果使用的是element-ui那么就去找对应的组件即可。-->

<a-upload
        accept=".zip"
        name="file"
        :showUploadList="false"
        :multiple="false"
        :headers="tokenHeader"
        :action="importProjectZipUrl"
        @change="handleImportExcel"
        :beforeUpload="(file) => doBeforeUpload(file, 'zip')"
      >
        <a-button type="primary" icon="import">导入Zip</a-button>
      </a-upload>

1.1、前端的js文件

importProjectZipUrl:? 表示访问后端的路径

handleImportExcel: 这一块内容复制粘贴即可,全是错误判断条件,如果正确都不会走

/* 导入 */
    handleImportExcel(info) {
      this.loading = true
      debugger
      if (info.file.status !== 'uploading') {
        console.log(info.file, info.fileList)
      }
      if (info.file.status === 'done') {
        this.loading = false
        if (info.file.response.success) {
          // this.$message.success(`${info.file.name} 文件上传成功`);
          if (info.file.response.code === 201) {
            let {
              message,
              result: { msg, fileUrl, fileName },
            } = info.file.response
            let href = window._CONFIG['domianURL'] + fileUrl
            this.$warning({
              title: message,
              content: (
                <div>
                  <span>{msg}</span>
                  <br />
                  <span>
                    具体详情请{' '}
                    <a href={href} target="_blank" download={fileName}>
                      点击下载
                    </a>{' '}
                  </span>
                </div>
              ),
            })
          } else {
            this.$message.success(info.file.response.message || `${info.file.name} 文件上传成功`)
          }
          this.loadData()
        } else {
          this.$message.error(`${info.file.name} ${info.file.response.message}.`)
        }
      } else if (info.file.status === 'error') {
        this.loading = false
        if (info.file.response.status === 500) {
          let data = info.file.response
          const token = Vue.ls.get(ACCESS_TOKEN)
          if (token && data.message.includes('Token失效')) {
            this.$error({
              title: '登录已过期',
              content: '很抱歉,登录已过期,请重新登录',
              okText: '重新登录',
              mask: false,
              onOk: () => {
                store.dispatch('Logout').then(() => {
                  Vue.ls.remove(ACCESS_TOKEN)
                  window.location.reload()
                })
              },
            })
          }
        } else {
          this.$message.error(`文件上传失败: ${info.file.msg} `)
        }
      }
    }

doBeforeUpload(parm1,parm2);

  doBeforeUpload(file, type) {
      if (file.name.indexOf(type) < 0 && type == 'xls') {
        this.$message.warning('请上传xls格式的表格')
        setTimeout(() => {
          this.loading = false
        }, 100)
        return false
      }
      if (file.name.indexOf(type) < 0 && type == 'zip') {
        this.$message.warning('请上传zip格式的压缩包')
        setTimeout(() => {
          this.loading = false
        }, 100)
        return false
      }
      if (file.name.indexOf(type) < 0 && type == 'sql') {
        this.$message.warning('请上传sql格式的文件')
        setTimeout(() => {
          this.loading = false
        }, 100)
        return false
      }
      return true
    }

2、后端代码

 @PostMapping("/importProjectTXTZipUrl")
	 public Result<?> importProjectZip(@RequestParam("file") MultipartFile file) {
	// 创建一个file文件
		 File f = new File(upLoadPath + File.separator + "temp");
	 // 不存在就创建
		 if (!f.exists()) f.mkdirs();
 // 创建另一个文件 名称不一样
		 File zip = new File(f, System.currentTimeMillis() + "_" + file.getOriginalFilename());
		 InputStream in = file.getInputStream();
		 FileOutputStream os = new FileOutputStream(zip);
		 //复制输入流到输出流
		 StreamUtils.copy(in, os);
		 in.close();
		 os.close();
 // 获取zip压缩包
		 ZipFile zipFile = new ZipFile(zip);
		 try {
			 if (!zipFile.isValidZipFile()) {
				 throw new Exception();
			 }
		 } catch (Exception e) {
			 return Result.error("文件格式错误或已损坏!");
		 }
 // 输入密码:这个密码和导出zip的密码一致
		 zipFile.setPassword("123456.a");
        StringBuilder sb = new StringBuilder();
	 //获取zip压缩包文件中的所有文件头部信息
		 List<FileHeader> headers = zipFile.getFileHeaders();
		 for (FileHeader header : headers) {
			 try (ZipInputStream inputStream = zipFile.getInputStream(header)) {
			
				 	//判断文件名后缀是否为.txt文件
				 if (!header.getFileName().contains("/") && header.getFileName().endsWith(".txt")) {
							//将字节流变为字符流并保存到buffer缓冲区中 出现乱码
					 BufferedReader reader = new BufferedReader(new InputStreamReader(inputStream, "UTF-8"));
	            //写文件
					 String line;
					 while ((line = reader.readLine()) != null) {
                        sb.append(line);

					 }
					 reader.close();
				 } else {
					 zipFile.extractFile(header, upLoadPath);
				 }
			 } catch (Exception e) {
				 log.error(e.getMessage());
			 }
		 }
        //进行一系列操作,.txt文件中的数据已经全部读取到sb中,调用自己写的方法进行一系列操作即可
 twoProjectService2.analysisJSON(sb);
//最后删除zip
		 zip.delete();
		 return Result.ok("导入成功!");
	 }

总结

好啦,以上就是基于java和前端代码的zip压缩包的导入和导出啦。超强实战。看完这个之后,希望你能更加激进你的技术,哈哈。

文章来源:https://blog.csdn.net/wang20000102/article/details/135494995
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。