批量处理4——java处理压缩文件

批量处理1——文件的上传(bootstrap+Ajax+SSM)
批量处理2——Java花式处理EXCEL
批量处理3——Excel文件导出
批量处理4——java处理压缩文件

Java知多少——相对路径和绝对路径
HTTP知多少——Content-disposition(文件下载)

如何对ZIP压缩文件进行处理?

1. 前端处理

即使我们使用了accept="aplication/zip"属性。但用户依旧可以选择其他格式的文件,所有我们需要在JS中进一步限制。

function batchSubmit() {
    var self = $('#batchButton');
    if (self.hasClass("disabled")) return;

    var fileName = new String($('#batchFile').val());
    if(fileName == null || fileName == '') {
        layer.alert("请选择文件!", {icon: 2});
        return;
    }
     /*校验文件是否是ZIP格式*/
    if(!fileName.endWith(".zip")) {
        layer.alert("请选择zip文件!", {icon: 2});
        return;
    }
    /*使用formData完成文件上传*/
    var formData = new FormData();
    formData.append("KHSQ", document.getElementById("batchFile").files[0]);


    $.ajax({
        url: "./XXX/upload",
        type: "POST",
        data: formData,
        contentType: false,
        processData: false,
        success: function (data) {
        }
    });

2. 文件上传

将前端上送的文件保存到服务器指定的路径上。使用multipartFile.transferTo(new File(batchPath));方法保存文件。

    @RequestMapping("/upload")
    @ResponseBody
    public ResponseVo upload(HttpServletRequest request, HttpServletResponse response) {
        ResponseVo responseVo = new ResponseVo();
         try{
            MultipartHttpServletRequest multipartRequest = (MultipartHttpServletRequest) request;
            MultipartFile multipartFile = multipartRequest.getFile("KHSQ");
            if(multipartFile!=null){
                // 获得文件名:
                String originalfilename = multipartFile.getOriginalFilename();
               //文件校验TODO
               String batchPath ="XXX/originalfilename";
                //创建目录
                File store = new File(batchPath);
                    if (!store.exists()) {
                        store.mkdirs();
                    }
              /*保存文件*/
              multipartFile.transferTo(new File(batchPath));
             }
            responseVo.setRetcode(200);
            responseVo.setMessage("上传成功");
        }catch (Exception e){
            responseVo.setRetcode(400);
            responseVo.setMessage("上传失败 原因:" + e.getMessage());
            logger.error("上传失败 原因:" + e);
        }
        return responseVo;

3. 文件处理

3.1 ZIP解压缩

将ZIP文件解压缩。本质是重建一颗目录树。采用的是前序遍历的方式。当然我们采用zipFile.getEntries();获取Enumeration对象,进行遍历。需要注意的是,父级目录可操纵子级目录。我们采用一个list集合,将压缩文件内的第一层目录保存到List中。

public static List upZipFilesDic(String path) {
        if(StringUtils.isBlank(path)){
            return null;
        }
        File source=new File(path);
        //获取压缩文件名
        String descDir=path.substring(0,path.lastIndexOf("."));
        //保存第一层文件或目录
        List list = new ArrayList<>() ;
        //此类用于从zip文件读取条目。 
        ZipFile zipFile = null;
        try {
             //解决文件名中文乱码
            zipFile = new ZipFile(source , "GBK") ;
            //遍历ZIP压缩文件的条目的枚举
            for(Enumeration entries = zipFile.getEntries(); entries.hasMoreElements() ; ){
                //此类用于表示ZIP文件条目(目录|文件)
                ZipEntry entry = (ZipEntry)entries.nextElement() ;
                //获取条目的名称
                File file = new File(descDir + File.separator + entry.getName()) ;
                //判断条目是否是目录
                if( entry.isDirectory() ){
                    //File.getName获取路径名称序列中的最后一个名字
                    String current = source.getName().substring(0,source.getName().lastIndexOf("."));
                    //判断该目录是否是压缩文件的第一层目录;即条目的父文件的名称==压缩文件的名字?
                    if(file.getParentFile().getName().equalsIgnoreCase(current)){
                        //将第一层目录保存到List集合中。
                        list.add(file);
                    }
                }else{
                    //条目是文件的情况下
                   //获取条目的后缀名
                    String entityFileSuffix = file.getName().substring(file.getName().lastIndexOf(".")+1);
                    //获取文件的父级目录
                    File parent = file.getParentFile() ;
                    //创建目录
                    if( !parent.exists() ){
                        parent.mkdirs() ;
                    }
                    //返回用于读取指定zip文件条目内容的输入流。 
                    InputStream in = zipFile.getInputStream(entry);
                    //获取文件输出流,输出到条目路径
                    OutputStream out = new FileOutputStream(file) ;
                    int len ;
                    while( (len = in.read(_byte)) > 0){
                        out.write(_byte, 0, len);
                    }
                    if (null !=out){
                        out.close();
                    }
                    if (null !=in){
                        in.close();
                    }
                    //判断后缀是否是xlsx,如果是的话,也保存到list中
                    if(entityFileSuffix.equalsIgnoreCase("xlsx")){
                        list.add(file);
                    }
                }
            }

        }catch(IOException e){
            logger.error(e);
        }finally {
            if(zipFile != null){
                try{
                    zipFile.close();
                }catch(IOException e){
                    logger.error(e);
                }
            }
        }
        return list;
    }

处理完毕之后,只有压缩文件内的第一层目录.xlsx后缀的文件保存到list集合中,并且zip文件完成解压。

3.2 处理解压文件

文件解压后,顶级目录和Excel文件保存到了List中。需要单独对List中目录和文件进行处理。

List fileList = GzipUtil.upZipFilesDic(path);
  //保存List中的目录;
LinkedList directoryList = new LinkedList<>();
  //处理Excel文件
  for (File file: fileList){
     String fileSuffix= file.getName().substring(file.getName().lastIndexOf(".") + 1);
     if(!fileSuffix.equals("xlsx")){
          //将目录保存到LinkedList中
          directoryList.add(file);
      }else{
      //处理Excel文件
      }
    }
  //File.listFiles()表示该抽象路径名表示的目录中的文件。 
   for (File file : directoryList.get(0).listFiles()){
    //处理目录下的文件或目录
    }

需要注意的一点是:listFiles能够获取当前文件夹下的所有文件和文件夹,如果文件夹A下还有文件D,那么D也在里面。

4. 压缩文件的下载

压缩文件的下载,还是设置响应报文头(Content-Disposition以及Content-Type)。

    //文件路径,response,下载的文件名
    public static void downloadZip(String down, HttpServletResponse response,String fileName) {
        try {
            // 输入流
            InputStream fis = new BufferedInputStream(new FileInputStream(down));
            byte[] buffer = new byte[fis.available()];
            //将数据读到buffer数组中
            fis.read(buffer);
            fis.close();
            // 清空response
            response.reset();
            OutputStream toClient = new BufferedOutputStream(response.getOutputStream());
            //以流的形式传输
            response.setContentType("application/octet-stream");
            //如果输出的是中文名的文件,在此处就要用URLEncoder.encode方法进行处理
            response.setHeader("Content-Disposition", "attachment;filename=" + URLEncoder.encode(fileName, "UTF-8"));
            //将数据写到输出流中
            toClient.write(buffer);
            toClient.close();
        } catch (IOException ex) {
            logger.error(ex.getMessage());
        }
    }

你可能感兴趣的:(批量处理4——java处理压缩文件)