Java 上传解压zip文件,并且解析文件里面的excel和图片
程序员文章站
2022-08-01 20:55:45
需求:上传一个zip文件,zip文件里面包含一个excel和很多图片,需要把excel里面的信息解析出来保存到表中,同时图片也转化成base64保存到数据库表中。 PS:为了方便不同水平的开发人员阅读,我把代码全部写到Controller里面。这个demo的file入参的类型是MultipartFi ......
需求:上传一个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这些代码的时候有可能因为引入包的不同,不一定走得成功,如有疑问,在评论区联系本人,写得不好的地方也欢迎指正。
上一篇: 在畑俊六提供的战时资料中,里面记载了什么