FilesUtil.java 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480
  1. package com.minpay.common.util;
  2. import java.io.BufferedOutputStream;
  3. import java.io.BufferedReader;
  4. import java.io.ByteArrayOutputStream;
  5. import java.io.File;
  6. import java.io.FileOutputStream;
  7. import java.io.IOException;
  8. import java.io.InputStream;
  9. import java.io.InputStreamReader;
  10. import java.io.OutputStream;
  11. import java.io.UnsupportedEncodingException;
  12. import java.net.HttpURLConnection;
  13. import java.net.URL;
  14. import java.net.URLEncoder;
  15. import java.text.DateFormat;
  16. import java.text.DecimalFormat;
  17. import java.text.SimpleDateFormat;
  18. import java.util.ArrayList;
  19. import java.util.Date;
  20. import java.util.HashMap;
  21. import java.util.List;
  22. import java.util.Map;
  23. import java.util.regex.Matcher;
  24. import java.util.regex.Pattern;
  25. import javax.servlet.ServletOutputStream;
  26. import javax.servlet.http.HttpServletResponse;
  27. import org.apache.commons.fileupload.FileItem;
  28. import org.apache.poi.hssf.usermodel.HSSFDateUtil;
  29. import org.apache.poi.openxml4j.exceptions.InvalidFormatException;
  30. import org.apache.poi.openxml4j.util.ZipSecureFile;
  31. import org.apache.poi.ss.usermodel.Cell;
  32. import org.apache.poi.ss.usermodel.Row;
  33. import org.apache.poi.ss.usermodel.Sheet;
  34. import org.apache.poi.ss.usermodel.Workbook;
  35. import org.apache.poi.ss.usermodel.WorkbookFactory;
  36. import com.minpay.common.constant.Constant;
  37. import com.minpay.common.exception.BusinessCodeException;
  38. import com.startup.minpay.frame.exception.MINBusinessException;
  39. import com.startup.minpay.util.Log;
  40. /**
  41. * 文件处理工具类
  42. * @author sunbz
  43. *
  44. */
  45. public class FilesUtil {
  46. /**
  47. * 文件上传到指定路径下
  48. * @param file
  49. * @param basePath 根路径(文件服务器路径例如F:/Files、/home/Files)
  50. * @param savePath 子路径,用于根路径下子文件夹
  51. * @param saveFileName 保存文件名
  52. * @param size 字节流缓存区大小
  53. * @throws MINBusinessException
  54. */
  55. public static String uploadFile(FileItem file,String basePath,String savePath,String saveFileName,int size) throws IOException, MINBusinessException{
  56. String url = "";
  57. int numberRead = 0;
  58. if(size == 0){
  59. size = 20000;
  60. }
  61. byte[] buffer=new byte[size];//缓冲区
  62. InputStream in = null;
  63. FileOutputStream out = null;
  64. System.out.println("getContentType "+file.getContentType());
  65. try {
  66. String fileName = file.getName();
  67. if(fileName.indexOf("\\")!=-1){
  68. int le = fileName.lastIndexOf("\\");
  69. fileName = fileName.substring(le+1, fileName.length());
  70. System.out.println("saveFileName "+fileName);
  71. }
  72. in = file.getInputStream();
  73. if(saveFileName==null ||"".equals(saveFileName)){
  74. saveFileName = fileName ;
  75. }else{
  76. if(saveFileName.indexOf(".")!=-1){
  77. throw new MINBusinessException("文件名称格式异常,请检查");
  78. }
  79. }
  80. //处理路径问题 判断是否存在,不存在则创建
  81. if (!(new File(basePath + savePath).isDirectory())) {
  82. new File(basePath + savePath).mkdir();
  83. }
  84. System.out.println("上传路径:"+basePath + savePath + saveFileName);
  85. out = new FileOutputStream( basePath + savePath + saveFileName);
  86. while ((numberRead=in.read(buffer))!=-1) { //numberRead的目的在于防止最后一次读取的字节小于buffer长度,
  87. out.write(buffer, 0, numberRead); //否则会自动被填充0
  88. }
  89. } catch (IOException e) {
  90. e.printStackTrace();
  91. }finally{
  92. try {
  93. in.close();
  94. out.close();
  95. } catch (IOException e2) {
  96. e2.printStackTrace();
  97. }
  98. }
  99. url = Constant.FILE_SERVER_PATH + savePath + saveFileName;
  100. return url;
  101. }
  102. /**
  103. * 读取txt、csv等文件
  104. */
  105. public static List<String> getReadFileInfo(FileItem file)
  106. throws MINBusinessException {
  107. return getReadFileInfo(file, "");
  108. }
  109. /**
  110. * 读取text、csv等文件
  111. * @param file
  112. * @param code 编码格式
  113. * @return
  114. * @throws MINBusinessException
  115. */
  116. public static List<String> getReadFileInfo(FileItem file,String code)throws MINBusinessException {
  117. List<String> list = new ArrayList<String>();
  118. if(file==null || file.getSize()<=0){
  119. throw new MINBusinessException("请选择文件");
  120. }
  121. try {
  122. BufferedReader in = null;
  123. String line = "";
  124. if("".equals(code)){
  125. String[] array = {"GBK","UTF-8","ISO-8859-1","ASCII","GB2312","Big5","Unicode"};
  126. for (int i = 0; i < array .length; i++) {
  127. in = new BufferedReader(new InputStreamReader(file.getInputStream(),array[i]));
  128. line = in.readLine();
  129. BufferedReader in1 = new BufferedReader(new InputStreamReader(file.getInputStream(),array[i]));
  130. String line1 = in1.readLine();
  131. boolean isMessyCode_flag=false;
  132. while(line1 != null){
  133. if(isMessyCode(line1)){
  134. isMessyCode_flag=true;
  135. break;
  136. }
  137. line1 = in1.readLine();
  138. //测试是否为乱码,否就退出循环
  139. }
  140. if(!isMessyCode_flag){
  141. break;
  142. }
  143. }
  144. }else{
  145. in = new BufferedReader(new InputStreamReader(file.getInputStream(),code));
  146. line = in.readLine();
  147. if("UTF-8".equalsIgnoreCase(code)){
  148. if(line.startsWith("\uFEFF")){
  149. line = line.replace("\uFEFF", "");
  150. }
  151. }
  152. //测试是否为乱码,否就退出循环
  153. if(isMessyCode(line)){
  154. throw new MINBusinessException("文件编码错误");
  155. }
  156. }
  157. while (line != null) {
  158. list.add(line);
  159. line = in.readLine();
  160. }
  161. in.close();
  162. } catch (Exception e) {
  163. e.printStackTrace();
  164. throw new MINBusinessException("导入文件内容不正确");
  165. }
  166. return list;
  167. }
  168. public static boolean isChinese(char c) {
  169. Character.UnicodeBlock ub = Character.UnicodeBlock.of(c);
  170. if (ub == Character.UnicodeBlock.CJK_UNIFIED_IDEOGRAPHS
  171. || ub == Character.UnicodeBlock.CJK_COMPATIBILITY_IDEOGRAPHS
  172. || ub == Character.UnicodeBlock.CJK_UNIFIED_IDEOGRAPHS_EXTENSION_A
  173. || ub == Character.UnicodeBlock.GENERAL_PUNCTUATION
  174. || ub == Character.UnicodeBlock.CJK_SYMBOLS_AND_PUNCTUATION
  175. || ub == Character.UnicodeBlock.HALFWIDTH_AND_FULLWIDTH_FORMS) {
  176. return true;
  177. }
  178. return false;
  179. }
  180. /**
  181. * 根据地址获得数据的字节流
  182. * @param strUrl 网络连接地址
  183. * @return
  184. */
  185. public static byte[] getVMFromNetByUrl(String strUrl){
  186. try {
  187. URL url = new URL(strUrl);
  188. HttpURLConnection conn = (HttpURLConnection)url.openConnection();
  189. conn.setRequestMethod("GET");
  190. conn.setConnectTimeout(5 * 1000);
  191. InputStream inStream = conn.getInputStream();//通过输入流获取数据
  192. byte[] btImg = readInputStream(inStream);//得到的二进制数据
  193. return btImg;
  194. } catch (Exception e) {
  195. e.printStackTrace();
  196. }
  197. return null;
  198. }
  199. /**
  200. * 从输入流中获取数据
  201. * @param inStream 输入流
  202. * @return
  203. * @throws Exception
  204. */
  205. public static byte[] readInputStream(InputStream inStream) throws Exception{
  206. ByteArrayOutputStream outStream = new ByteArrayOutputStream();
  207. byte[] buffer = new byte[1024];
  208. int len = 0;
  209. while( (len=inStream.read(buffer)) != -1 ){
  210. outStream.write(buffer, 0, len);
  211. }
  212. inStream.close();
  213. return outStream.toByteArray();
  214. }
  215. public static boolean isMessyCode(String strName) {
  216. Pattern p = Pattern.compile("\\s*|\t*|\r*|\n*");
  217. Matcher m = p.matcher(strName);
  218. String after = m.replaceAll("");
  219. String temp = after.replaceAll("\\p{P}", "").replaceAll("\\|", "");
  220. char[] ch = temp.trim().toCharArray();
  221. float chLength = ch.length;
  222. float count = 0;
  223. for (int i = 0; i < ch.length; i++) {
  224. char c = ch[i];
  225. if (!Character.isLetterOrDigit(c)) {
  226. if (!isChinese(c)) {
  227. count = count + 1;
  228. System.out.print(c);
  229. }
  230. }
  231. }
  232. float result = count / chLength;
  233. if (count > 0) {
  234. return true;
  235. }else{
  236. return false;
  237. }
  238. }
  239. /**
  240. * 读取xlsx格式Execl文档,暂不支持xls格式
  241. * @param execl 文件
  242. * @param titleKey map中存放key,与execl中每列对应
  243. * @param firstrow 读取开始行
  244. * @return
  245. * @throws InvalidFormatException
  246. * @throws IOException
  247. * @throws MINBusinessException
  248. */
  249. public static List<Map<String,Object>> readExecl(FileItem execl,String[] titleKey,int firstrow) throws InvalidFormatException, IOException, MINBusinessException{
  250. List<Map<String,Object>> list = new ArrayList<Map<String,Object>>();
  251. Workbook wb = WorkbookFactory.create(execl.getInputStream());
  252. /** 得到第一个shell */
  253. Sheet sheet = wb.getSheetAt(0);
  254. Row firstRow = sheet.getRow(0);
  255. if(titleKey.length != firstRow.getPhysicalNumberOfCells()){
  256. throw new BusinessCodeException("PBIM2800");//文件数据格式不正确
  257. }
  258. int rownum = sheet.getPhysicalNumberOfRows();
  259. //获取最后一行的下标
  260. int lastNum = sheet.getLastRowNum();
  261. Log.info("物理行数 "+sheet.getLastRowNum()+" lastNum:"+lastNum);
  262. int cellnum = firstRow.getLastCellNum();
  263. if(cellnum>titleKey.length){
  264. throw new MINBusinessException("PBIM2800");//提示数据格式不正确
  265. }
  266. DecimalFormat df = new DecimalFormat("#");
  267. for(int i=firstrow; i<=lastNum; i++){
  268. //用来判断当前行所有单元格是否为空
  269. int count = 0;
  270. Row row = sheet.getRow(i);
  271. if(row == null){
  272. continue;
  273. }
  274. Map<String,Object> map = new HashMap<String,Object>();
  275. for(int j=0; j<titleKey.length; j++){
  276. System.out.println(i+":"+j);
  277. Cell cell = row.getCell(j);
  278. String cellValue="";
  279. if(cell != null){
  280. switch (cell.getCellType()){
  281. case NUMERIC: // 数字
  282. cellValue = df.format(cell.getNumericCellValue()); //cell.getNumericCellValue() + "";
  283. break;
  284. case STRING: // 字符串
  285. cellValue = cell.getStringCellValue();
  286. break;
  287. case BOOLEAN: // Boolean
  288. cellValue = cell.getBooleanCellValue() + "";
  289. break;
  290. case FORMULA: // 公式
  291. cellValue = cell.getCellFormula() + "";
  292. break;
  293. case BLANK: // 空值
  294. cellValue = "";
  295. break;
  296. case ERROR: // 故障
  297. cellValue = "非法字符";
  298. break;
  299. default:
  300. cellValue = "未知类型";
  301. break;
  302. }
  303. }
  304. if("".equals(cellValue) || cellValue == null){
  305. count ++;
  306. }
  307. map.put(titleKey[j], cellValue);
  308. }
  309. if(count != titleKey.length){
  310. map.put("currentLine", i+1);
  311. list.add(map);
  312. }
  313. }
  314. return list;
  315. }
  316. /**
  317. * 读取xlsx格式Execl文档,暂不支持xls格式 简版
  318. * @param execl 文件
  319. * @param titleKey map中存放key,与execl中每列对应
  320. * @param firstrow 读取开始行
  321. * @return
  322. * @throws InvalidFormatException
  323. * @throws IOException
  324. * @throws MINBusinessException
  325. */
  326. public static List<Map<String,Object>> readExecleasy(FileItem execl,String[] titleKey,int firstrow) throws InvalidFormatException, IOException, MINBusinessException{
  327. List<Map<String,Object>> list = new ArrayList<Map<String,Object>>();
  328. ZipSecureFile.setMinInflateRatio(-1.0d);
  329. Workbook wb = WorkbookFactory.create(execl.getInputStream());
  330. /** 得到第一个shell */
  331. Sheet sheet = wb.getSheetAt(0);
  332. Row firstRow = sheet.getRow(0);
  333. int rownum = sheet.getPhysicalNumberOfRows();
  334. System.out.println("getContentType "+sheet.getPhysicalNumberOfRows()+" rownum:"+rownum);
  335. //判断行数是否为0
  336. if(rownum == 0){
  337. throw new BusinessCodeException("PBIM2800");//提示数据格式不正确
  338. }
  339. // int cellnum = firstRow.getLastCellNum();
  340. /*if(cellnum>titleKey.length){
  341. throw new BusinessCodeException("PBIM2800");//提示数据格式不正确
  342. }*/
  343. DecimalFormat df = new DecimalFormat("###.####");
  344. for(int i=firstrow; i<rownum; i++){
  345. Row row = sheet.getRow(i);
  346. if(row != null) {
  347. Map<String,Object> map = new HashMap<String,Object>();
  348. for(int j=0; j<titleKey.length; j++){
  349. System.out.println(i+":"+j);
  350. Cell cell = row.getCell(j);
  351. String cellValue="";
  352. if(cell != null){
  353. switch (cell.getCellType()){
  354. case NUMERIC: // 数字
  355. if(HSSFDateUtil.isCellDateFormatted(cell)){
  356. //用于转化为日期格式
  357. Date d = cell.getDateCellValue();
  358. DateFormat formater = new SimpleDateFormat("yyyyMMdd");
  359. cellValue = formater.format(d);
  360. }else{
  361. // 用于格式化数字,只保留数字的整数部分
  362. cellValue = df.format(cell.getNumericCellValue()); //cell.getNumericCellValue() + "";
  363. }
  364. break;
  365. case STRING: // 字符串
  366. cellValue = cell.getStringCellValue();
  367. break;
  368. case BOOLEAN: // Boolean
  369. cellValue = cell.getBooleanCellValue() + "";
  370. break;
  371. case FORMULA: // 公式
  372. cellValue = cell.getCellFormula() + "";
  373. break;
  374. case BLANK: // 空值
  375. cellValue = "";
  376. break;
  377. case ERROR: // 故障
  378. cellValue = "非法字符";
  379. break;
  380. default:
  381. cellValue = "未知类型";
  382. break;
  383. }
  384. }
  385. map.put(titleKey[j], cellValue);
  386. }
  387. list.add(map);
  388. }
  389. }
  390. return list;
  391. }
  392. public static void writeFile2Response(HttpServletResponse response, String filUrl) {
  393. String fileName = filUrl.split("\\/")[filUrl.split("\\/").length - 1];
  394. try {
  395. fileName = URLEncoder.encode(fileName, "UTF-8");
  396. } catch (UnsupportedEncodingException e1) {
  397. e1.printStackTrace();
  398. }
  399. response.setContentType("application/x-download;charset=UTF-8");
  400. response.addHeader("Content-disposition", "filename=" + fileName);
  401. OutputStream os = null;
  402. ServletOutputStream ros = null;
  403. InputStream inStream = null;
  404. try {
  405. ros = response.getOutputStream();
  406. os = new BufferedOutputStream(ros);
  407. // 获取输入流
  408. URL url = new URL(filUrl);
  409. HttpURLConnection conn = (HttpURLConnection)url.openConnection();
  410. conn.setRequestMethod("GET");
  411. conn.setConnectTimeout(120 * 1000);
  412. response.addHeader("Content-Length", "" + conn.getContentLength());
  413. inStream = conn.getInputStream();//通过输入流获取数据
  414. // 新的 byte 数组输出流,缓冲区容量1024byte
  415. ByteArrayOutputStream bos = new ByteArrayOutputStream(1024);
  416. byte[] bs = new byte[1024];
  417. int n;
  418. while ((n = inStream.read(bs)) != -1) {
  419. bos.write(bs, 0, n);
  420. }
  421. // 改变为byte[]
  422. byte[] data = bos.toByteArray();
  423. bos.close();
  424. os.write(data);
  425. os.flush();
  426. ros.flush();
  427. } catch (IOException e) {
  428. Log.error("意外的异常:", e);
  429. } finally {
  430. if (os != null) {
  431. try {
  432. os.close();
  433. } catch (IOException e) {
  434. Log.error("意外的异常:", e);
  435. }
  436. }
  437. if (ros != null) {
  438. try {
  439. ros.flush();
  440. ros.close();
  441. } catch (IOException e) {
  442. Log.error("意外的异常:", e);
  443. }
  444. }
  445. if (inStream != null) {
  446. try {
  447. inStream.close();
  448. } catch (IOException e) {
  449. Log.error("意外的异常:", e);
  450. }
  451. }
  452. }
  453. }
  454. }