ExcelToolUtils.java 18 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518
  1. package com.steerinfo.dil.util;
  2. import org.apache.commons.lang3.StringUtils;
  3. import org.apache.poi.hssf.usermodel.HSSFCell;
  4. import org.apache.poi.hssf.usermodel.HSSFDataFormat;
  5. import org.apache.poi.hssf.usermodel.HSSFDateUtil;
  6. import org.apache.poi.hssf.usermodel.HSSFWorkbook;
  7. import org.apache.poi.ss.usermodel.*;
  8. import org.apache.poi.xssf.usermodel.XSSFWorkbook;
  9. import org.apache.tomcat.util.http.fileupload.FileItem;
  10. import org.apache.tomcat.util.http.fileupload.FileItemFactory;
  11. import org.apache.tomcat.util.http.fileupload.disk.DiskFileItemFactory;
  12. import org.springframework.web.multipart.MultipartFile;
  13. import java.io.*;
  14. import java.text.DecimalFormat;
  15. import java.text.NumberFormat;
  16. import java.text.SimpleDateFormat;
  17. import java.util.*;
  18. /**
  19. * @Author fubo
  20. * @Description excel导入
  21. * @Date 2020/6/10 8:46
  22. **/
  23. public class ExcelToolUtils {
  24. /**
  25. * MultipartFile转 FileItem 并删除本地临时文件
  26. **/
  27. public static FileItem MultipartFileItem(MultipartFile file) throws Exception {
  28. File files = multipartFileToFile(file);
  29. FileItem fielitem = createFileItem(files, files.getName());
  30. delteTempFile(files);
  31. return fielitem;
  32. }
  33. /*
  34. 创建FileItem
  35. */
  36. public static FileItem createFileItem(File file, String fieldName) {
  37. FileItemFactory factory = new DiskFileItemFactory(16, null);
  38. FileItem item = factory.createItem(fieldName, "text/plain", true, file.getName());
  39. int bytesRead = 0;
  40. byte[] buffer = new byte[8192];
  41. try {
  42. FileInputStream fis = new FileInputStream(file);
  43. OutputStream os = item.getOutputStream();
  44. while ((bytesRead = fis.read(buffer, 0, 8192)) != -1) {
  45. os.write(buffer, 0, bytesRead);
  46. }
  47. os.close();
  48. fis.close();
  49. } catch (IOException e) {
  50. e.printStackTrace();
  51. }
  52. return item;
  53. }
  54. /**
  55. * MultipartFile 转 File
  56. *
  57. * @param file
  58. * @throws Exception
  59. */
  60. public static File multipartFileToFile(MultipartFile file) throws Exception {
  61. File toFile = null;
  62. if (file.equals("") || file.getSize() <= 0) {
  63. file = null;
  64. } else {
  65. InputStream ins = null;
  66. ins = file.getInputStream();
  67. toFile = new File(file.getOriginalFilename());
  68. inputStreamToFile(ins, toFile);
  69. ins.close();
  70. }
  71. return toFile;
  72. }
  73. //获取流文件
  74. private static void inputStreamToFile(InputStream ins, File file) {
  75. try {
  76. OutputStream os = new FileOutputStream(file);
  77. int bytesRead = 0;
  78. byte[] buffer = new byte[8192];
  79. while ((bytesRead = ins.read(buffer, 0, 8192)) != -1) {
  80. os.write(buffer, 0, bytesRead);
  81. }
  82. os.close();
  83. ins.close();
  84. } catch (Exception e) {
  85. e.printStackTrace();
  86. }
  87. }
  88. /**
  89. * 删除本地临时文件
  90. *
  91. * @param file
  92. */
  93. public static void delteTempFile(File file) {
  94. if (file != null) {
  95. File del = new File(file.toURI());
  96. del.delete();
  97. }
  98. }
  99. private static NumberFormat numberFormat = NumberFormat.getInstance();
  100. static {
  101. numberFormat.setGroupingUsed(false);
  102. }
  103. /**
  104. * 解析文件的方法.
  105. *
  106. * @param inputStream 文件输入流, 要解析的Excel文件输入流
  107. * @param fileName 文件名.
  108. * @param startRow 从第几行开始读取数据.
  109. * @return List<String [ ]> 集合中的一个元素对应一行解析的数据.
  110. * 元素为字符串数组类型. 数组中的每个元素对应一列数据.
  111. * @throws IOException
  112. */
  113. public static List<String[]> parseExcel(InputStream inputStream, String fileName, int startRow)
  114. throws Exception {
  115. // 1. 定义excel对象变量
  116. Workbook workbook = null;
  117. //获取后缀
  118. String suffix = fileName.substring(fileName.lastIndexOf("."));
  119. // 2. 判断后缀.决定使用的解析方式. 决定如何创建具体的对象
  120. if (".xls".equals(suffix)) {
  121. // 2003
  122. workbook = new HSSFWorkbook(inputStream);
  123. } else if (".xlsx".equals(suffix)) {
  124. // 2007
  125. workbook = new XSSFWorkbook(inputStream);
  126. } else {
  127. // 未知内容
  128. throw new Exception("请选择xls或者xlsx文件!");
  129. }
  130. // 获取工作表 excel分为若干个表. sheet
  131. Sheet sheet = workbook.getSheetAt(0);
  132. if (sheet == null) {
  133. return null;
  134. }
  135. // 获取表格中最后一行的行号
  136. int lastRowNum = sheet.getLastRowNum();
  137. // 最后一行的行号小于startRow
  138. if (lastRowNum < startRow) {
  139. throw new Exception("请输入数据");
  140. }
  141. List<String[]> result = new ArrayList<>();
  142. // 定义行变量和单元格变量
  143. Row row = null;
  144. Cell cell = null;
  145. // 循环读取
  146. try{
  147. for (int rowNum = startRow; rowNum <= lastRowNum; rowNum++) {
  148. row = sheet.getRow(rowNum);
  149. // 获取当前行的第一列和最后一列的标记(列数)
  150. short firstCellNum = row.getFirstCellNum();//第一列从0开始
  151. short lastCellNum = row.getLastCellNum();//最后一列
  152. if (lastCellNum != 0) {
  153. String[] rowArray = new String[lastCellNum];
  154. for (int cellNum = firstCellNum; cellNum < lastCellNum; cellNum++) {
  155. cell = row.getCell(cellNum);
  156. // 判断单元格是否有数据
  157. if (cell == null) {
  158. rowArray[cellNum] = null;
  159. } else {
  160. rowArray[cellNum] = parseCell(cell);
  161. }
  162. }
  163. if(rowArray[0] != null || !rowArray[0].equals("")){
  164. result.add(rowArray);
  165. }
  166. }
  167. }
  168. } catch (Exception e){
  169. throw new Exception("文件存在隐藏行或合并列!");
  170. }
  171. return result;
  172. }
  173. /**
  174. * 解析文件的方法.
  175. *
  176. * @param inputStream 文件输入流, 要解析的Excel文件输入流
  177. * @param fileName 文件名.
  178. * @param startRow 从第几行开始读取数据.
  179. * @return List<String []> 集合中的一个元素对应一行解析的数据.
  180. * 元素为字符串数组类型. 数组中的每个元素对应一列数据.
  181. * @throws IOException
  182. */
  183. public static List<List<String[]>> parseExcels(InputStream inputStream, String fileName, int startRow)
  184. throws Exception {
  185. // 1. 定义excel对象变量
  186. Workbook workbook = null;
  187. //获取后缀
  188. String suffix = fileName.substring(fileName.lastIndexOf("."));
  189. // 2. 判断后缀.决定使用的解析方式. 决定如何创建具体的对象
  190. if (".xls".equals(suffix)) {
  191. // 2003
  192. workbook = new HSSFWorkbook(inputStream);
  193. } else if (".xlsx".equals(suffix)) {
  194. // 2007
  195. workbook = new XSSFWorkbook(inputStream);
  196. } else {
  197. // 未知内容
  198. throw new Exception("请选择xls或者xlsx文件!");
  199. }
  200. List<List<String[]>> result = new ArrayList<>();
  201. for (int k = 0; k < workbook.getNumberOfSheets();k++) {
  202. // 获取工作表 excel分为若干个表. sheet
  203. Sheet sheet = workbook.getSheetAt(k);
  204. if (sheet == null) {
  205. return null;
  206. }
  207. // 获取表格中最后一行的行号
  208. int lastRowNum = sheet.getLastRowNum();
  209. // 最后一行的行号小于startRow
  210. if (lastRowNum < startRow) {
  211. throw new Exception("请输入数据");
  212. }
  213. List<String[]> res = new ArrayList<>();
  214. // 定义行变量和单元格变量
  215. Row row = null;
  216. Cell cell = null;
  217. // 循环读取
  218. try {
  219. for (int rowNum = startRow; rowNum <= lastRowNum; rowNum++) {
  220. row = sheet.getRow(rowNum);
  221. // 获取当前行的第一列和最后一列的标记(列数)
  222. short firstCellNum = row.getFirstCellNum();//第一列从0开始
  223. short lastCellNum = row.getLastCellNum();//最后一列
  224. if (lastCellNum != 0) {
  225. String[] rowArray = new String[lastCellNum];
  226. for (int cellNum = firstCellNum; cellNum < lastCellNum; cellNum++) {
  227. cell = row.getCell(cellNum);
  228. // 判断单元格是否有数据
  229. if (cell == null) {
  230. rowArray[cellNum] = null;
  231. } else {
  232. rowArray[cellNum] = parseCell(cell);
  233. }
  234. }
  235. res.add(rowArray);
  236. if (rowArray[0] != null && !"".equals(rowArray[0])) {
  237. res.add(rowArray);
  238. }
  239. }
  240. }
  241. result.add(res);
  242. } catch (Exception e) {
  243. e.printStackTrace();
  244. throw new Exception("文件存在隐藏行或合并列!");
  245. }
  246. }
  247. return result;
  248. }
  249. /**
  250. * 解析单元格
  251. *
  252. * @return String 单元格数据
  253. */
  254. private static String parseCell(Cell cell) {
  255. //空返回空
  256. if(cell == null){
  257. return null;
  258. }
  259. String result = null;
  260. switch (cell.getCellType()) {
  261. case HSSFCell.CELL_TYPE_NUMERIC:// 判断单元格的值是否为数字类型
  262. if (HSSFDateUtil.isCellDateFormatted(cell)) {// 处理日期格式、时间格式
  263. SimpleDateFormat sdf = null;
  264. if (cell.getCellStyle().getDataFormat() == HSSFDataFormat
  265. .getBuiltinFormat("h:mm")) {
  266. sdf = new SimpleDateFormat("HH:mm");
  267. } else {// 日期
  268. sdf = new SimpleDateFormat("yyyy-MM-dd");
  269. }
  270. Date date = cell.getDateCellValue();
  271. result = sdf.format(date);
  272. } else if (cell.getCellStyle().getDataFormat() == 58) {
  273. // 处理自定义日期格式:m月d日(通过判断单元格的格式id解决,id的值是58)
  274. /*yyyy年m月d日----->31
  275. yyyy-MM-dd----- 14
  276. yyyy年m月------- 57
  277. m月d日 ----------58
  278. HH:mm-----------20
  279. h时mm分 ------- 32*/
  280. SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
  281. double value = cell.getNumericCellValue();
  282. Date date = DateUtil
  283. .getJavaDate(value);
  284. result = sdf.format(date);
  285. } else {
  286. // 返回数值类型的值
  287. Object inputValue = null;// 单元格值
  288. Long longVal = Math.round(cell.getNumericCellValue());
  289. Double doubleVal = cell.getNumericCellValue();
  290. if (Double.parseDouble(longVal + ".0") == doubleVal) { //判断是否含有小数位.0
  291. inputValue = longVal;
  292. } else {
  293. inputValue = doubleVal;
  294. }
  295. DecimalFormat df = new DecimalFormat("#.##"); //格式化为四位小数,按自己需求选择;
  296. result = String.valueOf(df.format(inputValue)); //返回String类型
  297. // double value = cell.getNumericCellValue();
  298. // CellStyle style = cell.getCellStyle();
  299. // DecimalFormat format = new DecimalFormat("0.00");
  300. // String temp = style.getDataFormatString();
  301. // // 单元格设置成常规
  302. // if (temp.equals("General")) {
  303. // format.applyPattern("#");
  304. // }
  305. // result = format.format(value);
  306. }
  307. break;
  308. case HSSFCell.CELL_TYPE_STRING:// 判断单元格的值是否为String类型
  309. result = cell.getRichStringCellValue().toString();
  310. break;
  311. case HSSFCell.CELL_TYPE_BLANK://判断单元格的值是否为布尔类型
  312. result = "";
  313. default:
  314. result = "";
  315. break;
  316. }
  317. return result;
  318. }
  319. /**
  320. * 生成随机数:当前年月日时分秒+四位随机数
  321. *
  322. * @return
  323. */
  324. public static String getRandom() {
  325. SimpleDateFormat simpleDateFormat;
  326. simpleDateFormat = new SimpleDateFormat("yyyyMMdd");
  327. Date date = new Date();
  328. String str = simpleDateFormat.format(date);//当前年月日
  329. Random random = new Random();
  330. int rannum = (int) (random.nextDouble() * (9999 - 1000 + 1)) + 1000;// 获取5位随机数
  331. return str + rannum;
  332. }
  333. /**
  334. * 发货单页面生成的随机发货单编号-按前端设定
  335. *
  336. * @return
  337. */
  338. public static String Random() {
  339. SimpleDateFormat simpleDateFormat;
  340. simpleDateFormat = new SimpleDateFormat("yyyyMMdd");
  341. Date date = new Date();
  342. String str = simpleDateFormat.format(date);//当前年月日
  343. Random random = new Random();
  344. int rannum = (int) (random.nextDouble() * (99999 - 10000 + 1)) + 10000;// 获取5位随机数
  345. return "CX-" + str + rannum;
  346. }
  347. //截取字符串中数字-按MEs规则来(前八位位年月日,后面拼编号和英文做辨识)
  348. public static String getNumberText(String str){
  349. if(StringUtils.isBlank(str)){
  350. throw new RuntimeException("参数str不能为空");
  351. }
  352. StringBuffer number = new StringBuffer("");
  353. String[] strArray = str.split("");
  354. for (String string : strArray) {
  355. //if(!StringUtils.isBlank(string) && RegUtils.isNumberText(string)){
  356. // number.append(string);
  357. //}
  358. }
  359. return number.toString()+"XG";
  360. }
  361. /**
  362. * 获取Excel中的对象数组
  363. * @param file
  364. * @param startRow 默认0
  365. * @return
  366. * @throws Exception
  367. */
  368. public static List<Map<String,Object>> getExcelList(MultipartFile file, int startRow)
  369. throws Exception {
  370. File excel = multipartFileToFile(file);
  371. FileInputStream inputStream = null;
  372. String fileName = excel.getName();
  373. // 解决fileName兼容性问题
  374. int lastindex = fileName.lastIndexOf("\\");
  375. fileName = fileName.substring(lastindex + 1);
  376. if (fileName != null && fileName.length() > 0) {
  377. inputStream = new FileInputStream(excel);
  378. }
  379. //构建返回数组
  380. List<Map<String,Object>> list = new ArrayList<>();
  381. // 1. 创建工作簿
  382. Workbook workbook = null;
  383. // 2. 根据格式解析文件
  384. if (fileName.endsWith(".xls")) {
  385. workbook = new HSSFWorkbook(inputStream);
  386. }else if(fileName.endsWith(".xlsx")){
  387. workbook = new XSSFWorkbook(inputStream);
  388. }else {
  389. throw new Exception("请选择xls或者xlsx文件!");
  390. }
  391. for (int sheetIndex = 0; sheetIndex < workbook.getNumberOfSheets();sheetIndex++) {
  392. // 获取工作表 excel分为若干个表. sheet
  393. Sheet sheet = workbook.getSheetAt(sheetIndex);
  394. if (sheet == null) {
  395. break;
  396. }
  397. // 获取表格中最后一行的行号
  398. int lastRowNum = sheet.getLastRowNum();
  399. if (lastRowNum < startRow) {
  400. throw new Exception("第"+sheetIndex+"个工作簿无数据!请检查Excel!");
  401. }
  402. // 定义行变量和单元格变量
  403. Row row = null;
  404. Cell cell = null;
  405. //获取表头
  406. Row titlesRow = sheet.getRow(startRow);
  407. // 获取当前行的第一列和最后一列的标记(列数)
  408. int firstCellNum = titlesRow.getFirstCellNum();//第一列
  409. int lastCellNum = titlesRow.getLastCellNum();//最后一列
  410. String[] titles = new String[lastCellNum];
  411. if (lastCellNum > firstCellNum) {
  412. for (int cellNum = firstCellNum; cellNum < lastCellNum; cellNum++) {
  413. cell = titlesRow.getCell(cellNum);
  414. // 判断单元格是否有数据
  415. if (cell == null) {
  416. titles[cellNum] = null;
  417. } else {
  418. titles[cellNum] = parseCell(cell);
  419. }
  420. }
  421. }else {
  422. throw new Exception("第"+sheetIndex+"个工作簿无表头数据!请检查Excel!");
  423. }
  424. try {
  425. //遍历除表头外的所有行
  426. for (int rowNum = startRow+1; rowNum <= lastRowNum; rowNum++) {
  427. row = sheet.getRow(rowNum);
  428. //遍历行的所有列
  429. Map<String,Object> item = new HashMap<>();
  430. for (int cellNum = firstCellNum; cellNum < lastCellNum; cellNum++) {
  431. cell = row.getCell(cellNum);
  432. //获取表头对应数据
  433. if (titles[cellNum] != null && !titles[cellNum].equals("")
  434. && cell !=null && !cell.toString().equals("")) {
  435. item.put(titles[cellNum],parseCell(cell));
  436. }
  437. }
  438. if(item.keySet().toArray().length >0 ){
  439. list.add(item);
  440. }
  441. }
  442. } catch (Exception e) {
  443. e.printStackTrace();
  444. throw new Exception("文件存在隐藏行或合并列!");
  445. }
  446. }
  447. return list;
  448. }
  449. }