Java后台实现浏览器一键导出下载zip压缩包

使用迭代器模式和组合模式实现浏览器一键导出下载为zip压缩包文件

由于项目需要,于是又想起之前看过的设计模式,于是便有了一键导出的想法。
思路简单明了。一步一步看下去就好。

1.创建组合对象

public abstract class FileComponent {
  /**
   * Description:  递归创建文件夹,或者文件
   */
  public void mkFile(){
    throw new UnsupportedOperationException();
  }

  /**
   * Description:  获取文件输入路径
   */
  public String getInPath(){
    throw new UnsupportedOperationException();
  }
  /**
   * Description:  获取文件输出路径
   */
  public String getOutPath(){
    throw new UnsupportedOperationException();
  }
  /**
   * Description:  对于文件夹来说是可以add其他文件夹或者文件
   */
  public void add(FileComponent fileComponent){
    throw new UnsupportedOperationException();
  }
}

此组合对象,可以是文件夹对象,也可是具体的文件对象,再后面调用中,不需要了解到底是一个文件夹还是一个文件(即组合模式的透明性)。

2.组合对象抽象类的实现

上述抽象类的实现如下:

public class ZipFileItem extends FileComponent{
  //输入文件的路径
  String inPath;
  //输出文件的路径
  String outPath;
  //子节点文件信息
  List<FileComponent> fileComponents = new ArrayList<FileComponent>();

  //inPath 可以为null
  public ZipFileItem(String outPath){
      this.outPath =outPath;
  }
  //压缩文件的源目录路径和压缩好的目标位置
  public ZipFileItem(String inPath,String outPath){
    this.inPath =inPath;
    this.outPath =outPath;
  }
  public void add(FileComponent fileComponent){
    fileComponents.add(fileComponent);
  }

  public void remove(FileComponent fileComponent){
    fileComponents.remove(fileComponent);
  }
  @Override
  public String getInPath(){
    return inPath;
  }
  @Override
  public String getOutPath(){
    return outPath;
  }
  @Override
  public void mkFile(){
    FileUtils.createFile(inPath, outPath);
    Iterator<FileComponent> iterator = fileComponents.iterator();
    //如果是文件夹,那么还可以迭代文件及对象中的具体文件对象
    while (iterator.hasNext()) {
      FileComponent fileComponent = iterator.next();
      fileComponent.mkFile();
    }
  }
}

3.文件工具类

public class ConferenceFileUtils {
  /**
   * Description:  根据文件的绝对路径,在绝对的输出路径进行创建文件
   * @param inPath  输入路径,如果是要根据已有的文件来创建,那么一定要传
   * @param outPath  输出路径,如果是目录则不用
   */
  public static void createFile(String inPath,String outPath){
    File fileIn = new File(inPath);
    File fileOut = new File(outPath);
      //如果目标文件已存在,则忽略,如果文件不存在 。则进行创建
      if (!fileOut.exists()) {

        int lastSeparator = outPath.lastIndexOf(File.separator);
        String lastPart = outPath.substring(lastSeparator);
        //如果不是文件夹,则创建文件
        if (lastPart.lastIndexOf(".")!=-1) {
          LoggerUtil.info("----------making concreteFile--------"+outPath);
          FileInputStream in = null;
          FileOutputStream out = null;
          File directory = null;
              try {
                directory = new File(outPath.substring(0, lastSeparator+1));
                directory.mkdirs();
                out=new FileOutputStream(fileOut);
                //如果源文件存在
                if (fileIn.exists()) {
                  in=new FileInputStream(fileIn);
                  int len;
                  byte[] buf=new byte[10240];
                  while((len=in.read(buf))>0){
                    out.write(buf,0,len);
                  }
                  out.close();
                  in.close();
                  in = null;
                }
              } catch (IOException e) {
                System.err.println("creating file failed!", e);
              }
        }
        //如果是文件夹则创建文件夹,如果父类文件夹不存在,那么也创建
          else {
           System.err.println("----------making directory--------"+outPath);
            fileOut.mkdirs();
          }
      }

  }
  //递归删除文件夹以及文件
  public static boolean deleteDir(File dir) {
    if (dir.isDirectory()) {
      String[] children = dir.list();
      //递归删除目录中的子目录
      for (int i=0; i<children.length; i++) {
        boolean success = deleteDir(new File(dir, children[i]));
        if (!success) {
          return false;
        }
      }
    }
    // 目录此时为空,可以删除
    return dir.delete();
  }
  // 输出文件对象到输出流
    public static void outputFile(File file, HttpServletResponse response) throws IOException {
    OutputStream out=null;
    FileInputStream in=null;
    try {
    byte[] src = new byte[1024];
     out = response.getOutputStream();
     in = new FileInputStream(file);
    int len=0;
    while ((len = in.read(src)) > 0) {
      out.write(src, 0, len);
    }
    out.flush();
    out.close();
    in.close();
    } catch (IOException e) {
      throw new IOException(e);
    }finally{
      if(null!=out){
        FortifyUtil.commonReleasedResource(out);
      }
      if(null!=in){
        FortifyUtil.commonReleasedResource(in);
      }
    }

  }
}

4.核心导出逻辑代码

public class exportMaterialToZipTemplate {

  @Resource
  private EnrichFileLevelsService enrichFileLevelsService;
  //根目录文件夹名称 or 下载浏览器文件名
  private String downloadZipName;
  //根目录地址
  private String savePath = "d:\\tempFile";
  //根目录路径
  private String superRootPath;
  //根目录对象
  private FileComponent superRoot;
  //业务参数DTO
  private ExportAllTheMaterialDTO paramDTO;
  //response
  private HttpServletResponse response;

  public exportMaterialToZipTemplate(ExportAllTheMaterialDTO paramDTO,EnrichFileLevelsService enrichFileLevelsService,HttpServletResponse response) {
    this.downloadZipName = paramDTO.getDownloadZipName();
    this.paramDTO = paramDTO;
    this.response = response;
    this.enrichFileLevelsService = enrichFileLevelsService;
    this.superRootPath =savePath+File.separator+downloadZipName;
    this.superRoot = new ZipFileItem(superRootPath);
  }  

  //1.封装根目录
  private void enrichFileLevels(){
    enrichFileLevelsService.enrichFileLevels(superRoot,superRootPath,paramDTO);
  }
  //2.生成文件目录层级,即创建所有的文件(包括文件夹)
  private void createAllTheFiles(){
    if (null!=superRoot) {
      superRoot.mkFile();
    }
  }
  //3.生成文件层级后后再压缩后下载到浏览器
  private void compressAndDownload() {
    File srcFile = new File(FortifyUtil.filterFileName(superRootPath));
    String targetFilePath = savePath+File.separator+srcFile.getName()+".zip";
    File targetFile = new File(FortifyUtil.filterFileName(targetFilePath));
    ZipFileUtil.zipFiles(srcFile,targetFile);
    try {
      //压缩文件临时路径
      String downFileName = downloadZipName+".zip";
      response.reset();
      // 定义输出类型
      response.setContentType("application/octet-stream");
      response.setHeader("content-disposition", "attachment;filename="
          + new String(downFileName.getBytes("GBK"), "ISO-8859-1")
          + ";size=" + targetFile.length());
      OutputFileUtil.outputFile(targetFile, response);
      // 删除临时存放的文件夹
      if (srcFile.exists()) {
        ConferenceFileUtils.deleteDir(srcFile);
      }
      //删除临时的压缩包
      if (targetFile.exists()) {
        targetFile.delete();
      }
    } catch (IOException e) {
      DevLog.error(e.getMessage());
    }
  }
  //一键导出,外观模式
  public void export() {
    enrichFileLevels();
    createAllTheFiles();
    compressAndDownload();
  }
}

5.丰富文件层级的接口

public interface EnrichFileLevelsService {
  public void enrichFileLevels(FileComponent superRoot,String superRootPath,ExportAllTheMaterialDTO paramDTO);
}

不同的业务场景只要实现这接口,实现enrichFileLevels()方法,将实现此接口的
类实例传到exportMaterialToZipTemplate类的构造方法,然后调用exportMaterialToZipTemplate类实例的export()方法即可。即

new exportMaterialToZipTemplate(dtoParams,
enrichFileLevelsService, response).export();

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持我们。

(0)

相关推荐

  • Java多文件以ZIP压缩包导出的实现方法

    本文实例为大家分享了Java多文件以ZIP压缩包导出的具体代码,供大家参考,具体内容如下 1.使用java实现吧服务器的图片打包成一个zip格式的压缩包导出,多个文件打包导出. 2.代码如下: **ImageByteUtil.java** public class ImageByteUtil{ private static float QUALITY = 0.6f; public static void compressZip(List<File> listfiles, OutputStrea

  • Java后台实现浏览器一键导出下载zip压缩包

    使用迭代器模式和组合模式实现浏览器一键导出下载为zip压缩包文件 由于项目需要,于是又想起之前看过的设计模式,于是便有了一键导出的想法. 思路简单明了.一步一步看下去就好. 1.创建组合对象 public abstract class FileComponent { /** * Description: 递归创建文件夹,或者文件 */ public void mkFile(){ throw new UnsupportedOperationException(); } /** * Descript

  • java后台批量下载文件并压缩成zip下载的方法

    本文实例为大家分享了java后台批量下载文件并压缩成zip下载的具体代码,供大家参考,具体内容如下 因项目需要,将服务器上的图片文件压缩打包zip,下载到本地桌面. 首先,前端js: function doQueryPic() { var picsDate = $("#picsDate").val(); var piceDate = $("#piceDate").val(); var picInst = $("#pic_inst").combot

  • React获取Java后台文件流并下载Excel文件流程解析

    记录使用blob对象接收java后台文件流并下载为xlsx格式的详细过程,关键部分代码如下. 首先在java后台中设置response中的参数: public void exportExcel(HttpServletResponse response, String fileName, String sheetName, List<String> titleRow, List<List<String>> dataRows) { OutputStream out = nu

  • Java实现导出ZIP压缩包的方法

    最近接触到一个需求要求压缩导出文件,于是乎便要致力于研究一下工具类啦,故也诞生了此篇文章. 下面代码中,溪源也将import导入的依赖也贴出来了,避免大家引入错误. import org.apache.commons.io.FileUtils; import org.apache.commons.io.IOUtils; import javax.servlet.http.HttpServletResponse; import java.io.*; import java.text.SimpleD

  • Java将文件夹保留目录打包为 ZIP 压缩包并下载的教程详解

    上周做了一个需求,要求将数据库保存的 html 界面取出后将服务器下的css和js文件一起打包压缩为ZIP文件,返回给前台:在数据库中保存的是html标签,查出后,我把这些内容写入css和js等其他文件所在目录的一个文件内,然后将这整个文件夹压缩打包下载,解决过程中遇到了下载出来后并没有保存层级目录,在查了好久方法后完成了如下版本,已经可以正常下载并保留层级目录. //ZIP文件包压缩下载 @Override public void downloadZip(String id,HttpServl

  • java后台调用HttpURLConnection类模拟浏览器请求实例(可用于接口调用)

    一般在项目开发中难免遇到外部接口的调用,本文实例讲述了java后台调用HttpURLConnection类模拟浏览器请求的方法.可用于接口调用.分享给大家供大家参考.具体实现方法如下: 复制代码 代码如下: package com.cplatform.movie.back.test; import java.io.BufferedReader; import java.io.DataOutputStream; import java.io.InputStreamReader; import ja

  • python自动打开浏览器下载zip并提取内容写入excel

    前言 佬们轻喷,里面有些代码都是现学现写的,一些细节没处理好的地方还请指出来~~~ 首先贴上效果图:有些部分我没有放进来,比如浏览器的启动,但我详细聪明的你们那个玩意肯定一学就会.有些东西我没放进来 下载 使用到的库和总体思路 这部分用到time,selenium,urllib,re,requests,os这几个库. 代码 #!/usr/bin/python3 # coding=utf-8 import time from selenium import webdriver from urlli

  • Java Springboot如何基于图片生成下载链接

    现有一些图片在服务器上的链接,在浏览器中打开这些链接是直接显示在浏览器页面的形式. 现在需要生成这些图片的单独下载以及打包下载链接,即在浏览器中打开下载链接后弹出下载框提示下载.由于前端存在跨域问题,所以图片下载由后台接口完成. 首先编写文件下载工具类: import java.net.URL; import java.net.MalformedURLException; import org.apache.commons.io.FileUtils; public class FileDownl

  • Java多文件生成并压缩下载功能(思路详解)

    年前一直忙着项目现场实施,没时间整理,今天终于得空开始整理. 做WMS系统经常会遇到导出各种类型的库存单,此时就可以在后台将这些整合压缩到一个压缩包内然后再下载压缩包,一个接口就可以完成的事. 有两个思路: 思路一:将生成的多个文件先逐个存到本地一个临时的文件夹内并压缩,获取压缩文件下载,下载完以后删除该临时文件夹和内部文件 思路二:所有都在内存中实现,将生成的多个文件的输出流转换成为byte数组塞入压缩包的输出流中,最后下载该压缩包 第一个思路虽然操作复杂,但是却很容易想到的. 第二个思路,所

随机推荐