批量處理4——java處理壓縮文件

批量處理1——文件的上傳(bootstrap+Ajax+SSM)
批量處理2——Java花式處理EXCEL
批量處理3——Excel文件導(dǎo)出
批量處理4——java處理壓縮文件

Java知多少——相對(duì)路徑和絕對(duì)路徑
HTTP知多少——Content-disposition(文件下載)

如何對(duì)ZIP壓縮文件進(jìn)行處理?

1. 前端處理

<form id="batchForm" action="./XXX/batch">
      <input type="file" name="KHSQ" id="batchFile" class="file-loading"  style="display:none" onchange="$('#batchFilename').val($(this).val());" accept="aplication/zip"/>
      <div class="input-group col-md-7">
          <input id="batchFilename" class="form-control filename" type="text" ><a class="btn btn-default btn-sm input-group-addon" onclick="$('input[id=batchFile]').click();"><i class="fa fa-file-image-o"></i> 選擇文件</a>
      </div>
</form>
<button id="batchButton" type="button" class="btn green" onclick="batchSubmit()">上傳</button>

即使我們使用了accept="aplication/zip"屬性。但用戶依舊可以選擇其他格式的文件,所有我們需要在JS中進(jìn)一步限制。

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

    var fileName = new String($('#batchFile').val());
    if(fileName == null || fileName == '') {
        layer.alert("請(qǐng)選擇文件!", {icon: 2});
        return;
    }
     /*校驗(yàn)文件是否是ZIP格式*/
    if(!fileName.endWith(".zip")) {
        layer.alert("請(qǐng)選擇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. 文件上傳

將前端上送的文件保存到服務(wù)器指定的路徑上。使用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();
               //文件校驗(yàn)TODO
               String batchPath ="XXX/originalfilename";
                //創(chuàng)建目錄
                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文件解壓縮。本質(zhì)是重建一顆目錄樹。采用的是前序遍歷的方式。當(dāng)然我們采用zipFile.getEntries();獲取Enumeration對(duì)象,進(jìn)行遍歷。需要注意的是,父級(jí)目錄可操縱子級(jí)目錄。我們采用一個(gè)list集合,將壓縮文件內(nèi)的第一層目錄保存到List中。

public static List<File> upZipFilesDic(String path) {
        if(StringUtils.isBlank(path)){
            return null;
        }
        File source=new File(path);
        //獲取壓縮文件名
        String descDir=path.substring(0,path.lastIndexOf("."));
        //保存第一層文件或目錄
        List<File> 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獲取路徑名稱序列中的最后一個(gè)名字
                    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);
                    //獲取文件的父級(jí)目錄
                    File parent = file.getParentFile() ;
                    //創(chuàng)建目錄
                    if( !parent.exists() ){
                        parent.mkdirs() ;
                    }
                    //返回用于讀取指定zip文件條目?jī)?nèi)容的輸入流。 
                    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;
    }

處理完畢之后,只有壓縮文件內(nèi)的第一層目錄.xlsx后綴的文件保存到list集合中,并且zip文件完成解壓。

3.2 處理解壓文件

文件解壓后,頂級(jí)目錄和Excel文件保存到了List中。需要單獨(dú)對(duì)List中目錄和文件進(jìn)行處理。

List<File> fileList = GzipUtil.upZipFilesDic(path);
  //保存List中的目錄;
LinkedList<File> 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()){
    //處理目錄下的文件或目錄
    }

需要注意的一點(diǎn)是:listFiles能夠獲取當(dāng)前文件夾下的所有文件和文件夾,如果文件夾A下還有文件D,那么D也在里面。

4. 壓縮文件的下載

壓縮文件的下載,還是設(shè)置響應(yīng)報(bào)文頭(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()];
            //將數(shù)據(jù)讀到buffer數(shù)組中
            fis.read(buffer);
            fis.close();
            // 清空response
            response.reset();
            OutputStream toClient = new BufferedOutputStream(response.getOutputStream());
            //以流的形式傳輸
            response.setContentType("application/octet-stream");
            //如果輸出的是中文名的文件,在此處就要用URLEncoder.encode方法進(jìn)行處理
            response.setHeader("Content-Disposition", "attachment;filename=" + URLEncoder.encode(fileName, "UTF-8"));
            //將數(shù)據(jù)寫到輸出流中
            toClient.write(buffer);
            toClient.close();
        } catch (IOException ex) {
            logger.error(ex.getMessage());
        }
    }
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

友情鏈接更多精彩內(nèi)容