­

Java 上传解压zip文件,并且解析文件里面的excel和图片

  • 2019 年 10 月 7 日
  • 筆記

需求:上传一个zip文件,zip文件里面包含一个excel和很多图片,需要把excel里面的信息解析出来保存到表中,同时图片也转化成base64保存到数据库表中。

PS:为了方便不同水平的开发人员阅读,我把代码全部写到Controller里面。这个demo的file入参的类型是MultipartFile,很多网上的例子是File类型。这两个类型在解析文件的时候还是有点区别的。

第①个方法:

 1     /**   2      * 这个deomo入参的类型是MultipartFile,很多网上的例子是File类型   3      * @param file (zip)   4      * @param request   5      * @param response   6      * @return   7      * @throws Exception   8      */   9     @PostMapping("/addPersonsFileOfZip")  10     public String addPersonsFileOfZip(@RequestParam("file") MultipartFile file, HttpServletRequest request) throws Exception {  11         String createdId = request.getParameter(KEY_CREATED_ID);  12         //正常上这里需要检查一下createdId是否为空  13  14         //原则上这个uploadZipFilesAndParse方法需要写到service和serviceImpl中  15         String result =uploadZipFilesAndParse(file,createdId);  16         return  result;  17     }

第②个方法:

 1     /**   2      *返回的是批次号   3      *同时我另外开了线程处理zip文件里面的图片和excel,   4      */   5     @Override   6     public String uploadZipFilesAndParse(MultipartFile file, String createdId) throws Exception {   7         String filename = file.getOriginalFilename();   8         String fileType = filename.substring(filename.lastIndexOf(".") + 1).toLowerCase(Locale.US);   9         String uuid = UUID.randomUUID().toString();  10         //判断文件是不是zip类型  11         if(fileType.equals("zip")){  12  13             //FileConfig.localtion是配置文件和config类生产的,我会在评论区附上这些代码,测试demo的时候大家可以直接把FileConfig.localtion替换成D:/test  14             //String desPath = FileConfig.localtion + File.separator + uuid.replaceAll("-", "");  15             String desPath = "D:/test" + File.separator + uuid.replaceAll("-", "");  16  17  18             //下面这三行的代码就是把上传文件copy到服务器,一定不要遗漏了。  19             //遗漏了这个代码,在本地测试环境不会出问题,在服务器上一定会报没有找到文件的错误  20             String savePath = FileConfig.localtion + File.separator;  21             File savefile = new File(savePath+filename);  22             file.transferTo(savefile);  23  24             FileUtil fileUtil = new FileUtil();  25             //解压zip文件,我是写在公共类里面,FileUtil类代码评论区见  26             FileUtil.unZip(file, desPath,savePath);  27             new Thread(new Runnable() {  28                 @Override  29                 public void run() {  30                     List<File> fileList = new ArrayList<>();  31                     fileList = fileUtil.getSubFiles(desPath,fileList);  32                         for (File oneFile : fileList){  33                             if (oneFile.getName().toLowerCase().endsWith(".xls") || oneFile.getName().toLowerCase().endsWith(".xlsx") ) {  34                                 try {  35                                     //解析处理excel文件  36                                     parseExcelFile(oneFile,createdId,uuid);  37                                 } catch (Exception e) {  38                                     LogUtils.error(e.getMessage());  39                                 }  40                             }else if(oneFile.getName().toLowerCase().endsWith(".jpg")) {  41                                 try {  42                                     //解析处理图片文件  43                                     parseImageFile(oneFile,createdId,uuid);  44                                 } catch (Exception e) {  45                                     LogUtils.error(e.getMessage());  46                                 }  47                             }  48                         }  49  50                         //最后要删除文件,删除文件的方法见评论区FileUtil类  51                         FileUtil.clearFiles(desPath);  52  53                 }  54             }).start();  55  56         }  57         return uuid;  58     }    

View Code

 第③个方法:解压zip文件的unzip方法

 1     public static void unZip(MultipartFile  srcFile, String destDirPath,String savePath) throws RuntimeException, IOException {   2         long startTime = System.currentTimeMillis();   3   4         File file = null;   5         InputStream ins = srcFile.getInputStream();   6         file=new File(savePath+srcFile.getOriginalFilename());   7         LogUtils.info("MultipartFile transform to File,MultipartFile name:"+srcFile.getOriginalFilename());   8         inputStreamToFile(ins, file);   9  10         if (!file.exists()) {  11             throw new RuntimeException(file.getPath() + ",file is not found");  12         }  13         ZipFile zipFile = null;  14         try {  15             zipFile = new ZipFile(file);  16             Enumeration<?> entries = zipFile.entries();  17             while (entries.hasMoreElements()) {  18                 ZipEntry entry = (ZipEntry) entries.nextElement();  19                 LogUtils.info("zipFile context name:"+entry.getName());  20                 if (entry.isDirectory()) {  21                     String dirPath = destDirPath + File.separator+ entry.getName();  22                     File dir = new File(dirPath);  23                     dir.mkdirs();  24                 }else {  25                     File targetFile = new File(destDirPath + File.separator + entry.getName());  26                     targetFile.setExecutable(true);  27                     if(!targetFile.getParentFile().exists()){  28                         targetFile.getParentFile().mkdirs();  29                     }  30                     targetFile.createNewFile();  31                     InputStream is = zipFile.getInputStream(entry);  32                     FileOutputStream fos = new FileOutputStream(targetFile);  33                     int len;  34                     byte[] buf = new byte[1024];  35                     while ((len = is.read(buf)) != -1) {  36                         fos.write(buf, 0, len);  37                     }  38                     fos.close();  39                     is.close();  40                 }  41             }  42             long endTime = System.currentTimeMillis();  43             LogUtils.info("unZip time-->" + (endTime - startTime) + " ms");  44         }catch(Exception e) {  45             throw new RuntimeException("unzip error from FileUtil", e);  46         } finally {  47             if(zipFile != null){  48                 try {  49                     zipFile.close();  50                 } catch (IOException e) {  51                     e.printStackTrace();  52                 }  53             }  54  55             //MultipartFile change to file may create a temp file in the project root folder(delete the temp file)  56             File del = new File(file.toURI());  57             del.delete();  58         }  59     }

View Code

第④个方法:unzip方法中的inputStreamToFile方法,这个方法的目的是把MultipartFile转成File类型,但是会在项目根目录下生成一个临时文件,切记要删除

 1     private static void inputStreamToFile(InputStream ins, File file) {   2         try {   3             OutputStream os = new FileOutputStream(file);   4             int bytesRead = 0;   5             byte[] buffer = new byte[8192];   6             while ((bytesRead = ins.read(buffer, 0, 8192)) != -1) {   7                 os.write(buffer, 0, bytesRead);   8             }   9             os.close();  10             ins.close();  11             LogUtils.info("MultipartFile transform to File completed!");  12         }catch(Exception e) {  13             e.printStackTrace();  14         }  15     }

View Code

第⑤个方法:parseExcelFile方法是解析excel的方法,里面包括我自己项目的逻辑处理,大家可以删除这些代码,只保留解析excel的代码就好

 1     private void parseExcelFile(File file,String createdId,String uuid) throws Exception {   2   3         LogUtils.info("file name:"+file.getName());   4         FileInputStream is = new FileInputStream(file);   5         Workbook workbook = WorkbookFactory.create(is);   6         Sheet sheet = workbook.getSheetAt(0);   7   8         int firstRowIndex = sheet.getFirstRowNum() + 1;   9         int lastRowIndex = sheet.getLastRowNum();  10  11         List<VapBatchPersonInfo> batchPersonList = new ArrayList<>();  12         for (int rIndex = firstRowIndex; rIndex <= lastRowIndex; rIndex++) {  13  14             VapBatchPersonInfo vapBatchPersonInfo  = new VapBatchPersonInfo();  15             Row row = sheet.getRow(rIndex);  16             if (row != null) {  17                 int firstCellIndex = row.getFirstCellNum();  18                 int lastCellIndex = row.getLastCellNum();  19                 JSONObject jsonObject = new JSONObject();  20                 jsonObject.put(KEY_CREATED_ID, createdId);  21  22                 Cell resultCell = row.createCell(lastCellIndex);  23                 Cell msgCell = row.createCell(lastCellIndex + 1);  24                 Boolean flag = false;  25                 for (int cIndex = firstCellIndex; cIndex < lastCellIndex; cIndex++) {  26                     Cell cell = row.getCell(cIndex);  27                     String titleName = sheet.getRow(0).getCell(cIndex).toString();  28                     String checkTitleName = checkTitleName(cIndex, titleName);  29                     if (!"SUCCESS".equals(checkTitleName)) {  30                         msgCell.setCellValue(checkTitleName);  31                         resultCell.setCellValue("Failed");  32                         flag = true;  33                         break;  34                     }  35                     if (cell != null) {  36                         cell.setCellType(CellType.STRING);  37                         jsonObject.put(titleName, cell.toString());  38                     }  39  40                 }  41                 if (flag) {  42                     rIndex = 0;  43                     lastRowIndex = 0;  44                 } else {  45                     vapBatchPersonInfo.setBatchNo(uuid);  46                     vapBatchPersonInfo.setName(jsonObject.getString("fullName"));  47                     vapBatchPersonInfo.setImageName(jsonObject.getString("imageName"));  48                     vapBatchPersonInfo.setConfidenceThreshold(jsonObject.getString("confidenceThreshold"));  49                     vapBatchPersonInfo.setCreatedId(jsonObject.getString("createdId"));  50                     vapBatchPersonInfo.setIdentityNo(jsonObject.getString("identityNo"));  51                     vapBatchPersonInfo.setCreatedDate(new Date());  52                     vapBatchPersonInfo.setLastUpdatedId(jsonObject.getString("createdId"));  53                     vapBatchPersonInfo.setLastUpdatedDate(new Date());  54                     vapBatchPersonInfo.setStatus(TaskStatus.RUNNING);  55                     batchPersonList.add(vapBatchPersonInfo);  56                 }  57             }  58         }  59         batchPersonInfoRepository.saveAll(batchPersonList);  60  61     }

View Code

第⑥个方法:parseImageFile方法是解析图片的方法

 1     private void parseImageFile(File file, String createdId, String uuid) throws Exception {   2   3         String imgStr ="";   4         FileInputStream fis = new FileInputStream(file);   5         byte[] buffer = new byte[(int) file.length()];   6         int offset = 0;   7         int numRead = 0;   8         while (offset < buffer.length && (numRead = fis.read(buffer, offset, buffer.length - offset)) >= 0) {   9             offset += numRead;  10         }  11         if (offset != buffer.length) {  12             throw new IOException("Could not completely read file " + file.getName());  13         }  14         fis.close();  15         Base64 encoder = new Base64();  16         imgStr = Base64.encodeBase64String(buffer);  17         imgStr.length();  18         LogUtils.info("file name:"+file.getName());  19 //        LogUtils.info("file imgStr:"+imgStr);  20 //        LogUtils.info("file imgStr.length:"+imgStr.length());  21  22     }

View Code

 最后附上FileConfig和FileUtil的代码

FileConfig代码:

import org.springframework.boot.context.properties.ConfigurationProperties;  import org.springframework.core.annotation.Order;  import org.springframework.stereotype.Component;    /**   *Jun 12, 2019   *   * FileConfig.java   */  @ConfigurationProperties(prefix = "upload")  @Component  @Order  public class FileConfig {        public static String localtion;      public static String maxFileSize;      public static String maxRequestSize;        /**       * @param localtion the localtion to set       */      public void setLocaltion(String localtion) {          FileConfig.localtion = localtion;      }        /**       * @param maxFileSize the maxFileSize to set       */      public void setMaxFileSize(String maxFileSize) {          FileConfig.maxFileSize = maxFileSize;      }        /**       * @param maxRequestSize the maxRequestSize to set       */      public void setMaxRequestSize(String maxRequestSize) {          FileConfig.maxRequestSize = maxRequestSize;      }      }

View Code

FileConfig类里面读取的配置文件信息:

配置文件类型是yml,大家也可以自己改成properties文件格式

upload:    #localtion: ${UPLOAD_DIR:/home/data/test}    localtion: ${UPLOAD_DIR:D:/test}    maxFileSize: 10240KB    maxRequestSize: 102400KB  

FileUtil类的代码:

  1 import java.io.*;    2 import java.nio.channels.FileChannel;    3 import java.nio.file.Files;    4 import java.nio.file.Path;    5 import java.nio.file.Paths;    6 import java.nio.file.attribute.PosixFilePermission;    7 import java.util.ArrayList;    8 import java.util.Enumeration;    9 import java.util.HashSet;   10 import java.util.List;   11 import java.util.Set;   12 import java.util.zip.ZipEntry;   13 import java.util.zip.ZipFile;   14   15 import org.springframework.web.multipart.MultipartFile;   16   17 import sg.com.mha.ummi.common.util.LogUtils;   18   19   20 public class FileUtil {   21   22     public static void clearFiles(String workspaceRootPath) {   23         File file = new File(workspaceRootPath);   24         deleteFile(file);   25     }   26   27     public static void deleteFile(File file) {   28         if (file.exists()) {   29             if (file.isDirectory()) {   30                 File[] files = file.listFiles();   31                 for (int i = 0; i < files.length; i++) {   32                     deleteFile(files[i]);   33                 }   34             }   35         }   36         file.delete();   37     }   38   39     public static void fileWrite(String str, String fileNamePath) throws IOException {   40         FileWriter writer = null;   41         try {   42             File file = new File(fileNamePath);   43             if (!file.getParentFile().exists()) {   44                 file.getParentFile().mkdirs();   45                 file.createNewFile();   46             }   47             writer = new FileWriter(file, true);   48             writer.write(str + System.getProperty("line.separator"));   49   50         } catch (IOException e) {   51             LogUtils.error(e.getMessage());   52         } finally {   53             if (writer != null) {   54                 writer.close();   55             }   56         }   57     }   58   59     public static void changePermission(File dirFile, int mode) throws IOException {   60         char[] modes = Integer.toOctalString(mode).toCharArray();   61         if (modes.length != 3) {   62             return;   63         }   64         Set<PosixFilePermission> perms = new HashSet<PosixFilePermission>();   65         switch (modes[0]) {   66             case '1':   67                 perms.add(PosixFilePermission.OWNER_EXECUTE);   68                 break;   69             case '2':   70                 perms.add(PosixFilePermission.OWNER_WRITE);   71                 break;   72             case '4':   73                 perms.add(PosixFilePermission.OWNER_READ);   74                 break;   75             case '5':   76                 perms.add(PosixFilePermission.OWNER_READ);   77                 perms.add(PosixFilePermission.OWNER_EXECUTE);   78                 break;   79             case '6':   80                 perms.add(PosixFilePermission.OWNER_READ);   81                 perms.add(PosixFilePermission.OWNER_WRITE);   82                 break;   83             case '7':   84                 perms.add(PosixFilePermission.OWNER_READ);   85                 perms.add(PosixFilePermission.OWNER_WRITE);   86                 perms.add(PosixFilePermission.OWNER_EXECUTE);   87                 break;   88   89             default:   90                 break;   91         }   92         switch (modes[1]) {   93             case '1':   94                 perms.add(PosixFilePermission.GROUP_EXECUTE);   95                 break;   96             case '2':   97                 perms.add(PosixFilePermission.GROUP_WRITE);   98                 break;   99             case '4':  100                 perms.add(PosixFilePermission.GROUP_READ);  101                 break;  102             case '5':  103                 perms.add(PosixFilePermission.GROUP_READ);  104                 perms.add(PosixFilePermission.GROUP_EXECUTE);  105                 break;  106             case '6':  107                 perms.add(PosixFilePermission.GROUP_READ);  108                 perms.add(PosixFilePermission.GROUP_WRITE);  109                 break;  110             case '7':  111                 perms.add(PosixFilePermission.GROUP_READ);  112                 perms.add(PosixFilePermission.GROUP_WRITE);  113                 perms.add(PosixFilePermission.GROUP_EXECUTE);  114                 break;  115             default:  116                 break;  117         }  118         switch (modes[2]) {  119             case '1':  120                 perms.add(PosixFilePermission.OTHERS_EXECUTE);  121                 break;  122             case '2':  123                 perms.add(PosixFilePermission.OTHERS_WRITE);  124                 break;  125             case '4':  126                 perms.add(PosixFilePermission.OTHERS_READ);  127                 break;  128             case '5':  129                 perms.add(PosixFilePermission.OTHERS_EXECUTE);  130                 perms.add(PosixFilePermission.OTHERS_READ);  131                 break;  132             case '6':  133                 perms.add(PosixFilePermission.OTHERS_READ);  134                 perms.add(PosixFilePermission.OTHERS_WRITE);  135                 break;  136             case '7':  137                 perms.add(PosixFilePermission.OTHERS_EXECUTE);  138                 perms.add(PosixFilePermission.OTHERS_READ);  139                 perms.add(PosixFilePermission.OTHERS_WRITE);  140                 break;  141             default:  142                 break;  143         }  144  145         try {  146             Path path = Paths.get(dirFile.getAbsolutePath());  147             Files.setPosixFilePermissions(path, perms);  148         } catch (Exception e) {  149             e.printStackTrace();  150         }  151     }  152  153     public static File mkFile(String fileName) {  154         File f = new File(fileName);  155         try {  156             if (f.exists()) {  157                 f.delete();  158             }  159             f.createNewFile();  160         } catch (IOException e) {  161             e.printStackTrace();  162         }  163         return f;  164     }  165  166  167     public static void copyDirAndFile(String oldPath, String newPath) throws IOException {  168         if (!(new File(newPath)).exists()) {  169             (new File(newPath)).mkdir();  170         }  171         File file = new File(oldPath);  172         //file name list  173         String[] filePaths = file.list();  174         for (String filePath : filePaths) {  175             String oldFullPath = oldPath + file.separator + filePath;  176             String newFullPath = newPath + file.separator + filePath;  177             File oldFile = new File(oldFullPath);  178             File newFile = new File(newFullPath);  179             if (oldFile.isDirectory()) {  180                 copyDirAndFile(oldFullPath, newFullPath);  181             } else if (oldFile.isFile()) {  182                 copyFile(oldFile, newFile);  183             }  184         }  185     }  186  187     public static void copyFile(File source, File dest) throws IOException {  188         FileChannel inputChannel = null;  189         FileChannel outputChannel = null;  190         try {  191             inputChannel = new FileInputStream(source).getChannel();  192             outputChannel = new FileOutputStream(dest).getChannel();  193             outputChannel.transferFrom(inputChannel, 0, inputChannel.size());  194         } finally {  195             inputChannel.close();  196             outputChannel.close();  197         }  198     }  199  200     /**  201      * @author panchaoyuan  202      * @param srcFile    Unzipped file  203      * @param destDirPath   Unzipped destination folder  204      * @throws RuntimeException  205      * @throws IOException  206      */  207     public static void unZip(MultipartFile  srcFile, String destDirPath,String savePath) throws RuntimeException, IOException {  208         long startTime = System.currentTimeMillis();  209  210         File file = null;  211         InputStream ins = srcFile.getInputStream();  212         file=new File(savePath+srcFile.getOriginalFilename());  213         LogUtils.info("MultipartFile transform to File,MultipartFile name:"+srcFile.getOriginalFilename());  214         inputStreamToFile(ins, file);  215  216         if (!file.exists()) {  217             throw new RuntimeException(file.getPath() + ",file is not found");  218         }  219         ZipFile zipFile = null;  220         try {  221             zipFile = new ZipFile(file);  222             Enumeration<?> entries = zipFile.entries();  223             while (entries.hasMoreElements()) {  224                 ZipEntry entry = (ZipEntry) entries.nextElement();  225                 LogUtils.info("zipFile context name:"+entry.getName());  226                 if (entry.isDirectory()) {  227                     String dirPath = destDirPath + File.separator+ entry.getName();  228                     File dir = new File(dirPath);  229                     dir.mkdirs();  230                 }else {  231                     File targetFile = new File(destDirPath + File.separator + entry.getName());  232                     targetFile.setExecutable(true);  233                     if(!targetFile.getParentFile().exists()){  234                         targetFile.getParentFile().mkdirs();  235                     }  236                     targetFile.createNewFile();  237                     InputStream is = zipFile.getInputStream(entry);  238                     FileOutputStream fos = new FileOutputStream(targetFile);  239                     int len;  240                     byte[] buf = new byte[1024];  241                     while ((len = is.read(buf)) != -1) {  242                         fos.write(buf, 0, len);  243                     }  244                     fos.close();  245                     is.close();  246                 }  247             }  248             long endTime = System.currentTimeMillis();  249             LogUtils.info("unZip time-->" + (endTime - startTime) + " ms");  250         }catch(Exception e) {  251             throw new RuntimeException("unzip error from FileUtil", e);  252         } finally {  253             if(zipFile != null){  254                 try {  255                     zipFile.close();  256                 } catch (IOException e) {  257                     e.printStackTrace();  258                 }  259             }  260  261             //MultipartFile change to file may create a temp file in the project root folder(delete the temp file)  262             File del = new File(file.toURI());  263             del.delete();  264         }  265     }  266  267     /**  268      * MultipartFile changed to File  269      * @author panchaoyuan  270      * @return  271      */  272     private static void inputStreamToFile(InputStream ins, File file) {  273         try {  274             OutputStream os = new FileOutputStream(file);  275             int bytesRead = 0;  276             byte[] buffer = new byte[8192];  277             while ((bytesRead = ins.read(buffer, 0, 8192)) != -1) {  278                 os.write(buffer, 0, bytesRead);  279             }  280             os.close();  281             ins.close();  282             LogUtils.info("MultipartFile transform to File completed!");  283         }catch(Exception e) {  284             e.printStackTrace();  285         }  286     }  287  288       /**  289      * @author panchaoyuan  290      */  291     public List<File> getSubFiles(String  desFile,List<File> fileList) {  292         File file = new File(desFile);  293         File[] files = file.listFiles();  294         for (File fileIndex : files) {  295             if (!fileIndex.exists()) {  296                 throw new NullPointerException("Cannot find " + fileIndex);  297             } else if (fileIndex.isFile()) {  298                 fileList.add(fileIndex);  299             } else {  300                 if (fileIndex.isDirectory()) {  301                     getSubFiles(fileIndex.getAbsolutePath(),fileList);  302                 }  303             }  304         }  305         return fileList;  306     }  307  308  309 }

View Code

 

水平有限,可能写得不是很完整,大家copy这些代码的时候有可能因为引入包的不同,不一定走得成功,如有疑问,在评论区联系本人,写得不好的地方也欢迎指正。