Java 上传解压zip文件,并且解析文件里面的excel和图片
Posted jamespan23
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Java 上传解压zip文件,并且解析文件里面的excel和图片相关的知识,希望对你有一定的参考价值。
需求:上传一个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
第③个方法:解压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
第④个方法: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
第⑤个方法: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
第⑥个方法: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
最后附上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;
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
水平有限,可能写得不是很完整,大家copy这些代码的时候有可能因为引入包的不同,不一定走得成功,如有疑问,在评论区联系本人,写得不好的地方也欢迎指正。
以上是关于Java 上传解压zip文件,并且解析文件里面的excel和图片的主要内容,如果未能解决你的问题,请参考以下文章