说明:

  1. 通过poi的工具,导出或者导入excel

1.Excel的导出操作

  1. import org.apache.poi.hssf.usermodel.*;
  2. import org.apache.poi.ss.usermodel.*;
  3. import org.apache.poi.ss.util.CellRangeAddressList;
  4. import org.apache.poi.xssf.usermodel.XSSFDataValidation;
  5. import javax.servlet.http.HttpServletRequest;
  6. import javax.servlet.http.HttpServletResponse;
  7. import java.io.IOException;
  8. import java.io.OutputStream;
  9. import java.io.UnsupportedEncodingException;
  10. import java.net.URLEncoder;
  11. import java.nio.charset.StandardCharsets;
  12. import java.util.UUID;
  13. /**
  14. * 导出的excel,通过流操作写入到response的相相应中。
  15. */
  16. public static void exportTemplate(String eventName, HSSFWorkbook wb, HttpServletRequest request, HttpServletResponse response) {
  17. response.setContentType("application/vnd.ms-excel");
  18. String agent = request.getHeader("user-agent");
  19. try {
  20. if (agent != null && agent.toLowerCase().indexOf("firefox") > -1) {
  21. String event = eventName + ".xls";
  22. response.setHeader("content-Disposition", "attachment;filename=" + (new String(event.getBytes(StandardCharsets.UTF_8), StandardCharsets.ISO_8859_1)));
  23. } else {
  24. response.setHeader("content-Disposition", "attachment;filename=" + URLEncoder.encode(eventName + System.currentTimeMillis() + ".xls", "utf-8"));
  25. }
  26. } catch (UnsupportedEncodingException e) {
  27. logger.error("log", e);
  28. }
  29. try {
  30. OutputStream out = response.getOutputStream();
  31. //将workbook写入
  32. wb.write(out);
  33. out.close();
  34. } catch (IOException e) {
  35. logger.error("log", e);
  36. }
  37. }
  38. /**
  39. * 创建下拉列表选项(常规的简单下拉框)
  40. *
  41. * @param sheet 所在Sheet页面
  42. * @param values 下拉框的选项值
  43. * @param firstRow 起始行(从0开始)
  44. * @param lastRow 终止行(从0开始)
  45. * @param col 起始列(从0开始)
  46. */
  47. public static void setHSSFValidation(HSSFSheet sheet, String[] values, int firstRow, int lastRow, int col) {
  48. DataValidationHelper helper = sheet.getDataValidationHelper();
  49. // 设置数据有效性加载在哪个单元格上,四个参数分别是:起始行、终止行、起始列、终止列
  50. CellRangeAddressList addressList = new CellRangeAddressList(firstRow, lastRow, col, col);
  51. // 设置下拉框数据
  52. DataValidationConstraint constraint = helper.createExplicitListConstraint(values);
  53. DataValidation dataValidation = helper.createValidation(constraint, addressList);
  54. // Excel兼容性问题
  55. if (dataValidation instanceof XSSFDataValidation) {
  56. dataValidation.setSuppressDropDownArrow(true);
  57. dataValidation.setShowErrorBox(true);
  58. } else {
  59. dataValidation.setSuppressDropDownArrow(false);
  60. }
  61. sheet.addValidationData(dataValidation);
  62. }
  63. /**
  64. * 单元格添加下拉菜单(不限制菜单可选项个数)
  65. * [注意:此方法会添加隐藏的sheet,可调用getDataSheetInDropMenuBook方法获取用户输入数据的未隐藏的sheet]
  66. *
  67. * @param @param workbook
  68. * @param @param tarSheet 目标单元格所在的sheet
  69. * @param @param menuItems 下拉菜单可选项数组
  70. * @param @param firstRow 第一个目标单元格所在的行号(从0开始)
  71. * @param @param lastRow 最后一个目标单元格所在的行(从0开始)
  72. * @param @param column 待添加下拉菜单的单元格所在的列(从0开始)
  73. */
  74. /* 通过添加影藏的sheet页。解决cell长度唱过255的限制!! */
  75. public static void setLongHSSFValidation(HSSFWorkbook workbook, HSSFSheet tarSheet, String[] menuItems, int firstRow, int lastRow, int column) {
  76. //必须以字母开头,最长为31位
  77. String hiddenSheetName = "a" + UUID.randomUUID().toString().replace("-", "").substring(1, 31);
  78. //excel中的"名称",用于标记隐藏sheet中的用作菜单下拉项的所有单元格
  79. String formulaId = "form" + UUID.randomUUID().toString().replace("-", "");
  80. //用于存储 下拉菜单数据
  81. HSSFSheet hiddenSheet = workbook.createSheet(hiddenSheetName);
  82. //存储下拉菜单项的sheet页不显示
  83. workbook.setSheetHidden(workbook.getSheetIndex(hiddenSheet), true);
  84. HSSFRow row = null;
  85. HSSFCell cell = null;
  86. //隐藏sheet中添加菜单数据
  87. for (int i = 0; i < menuItems.length; i++) {
  88. row = hiddenSheet.createRow(i);
  89. //隐藏表的数据列必须和添加下拉菜单的列序号相同,否则不能显示下拉菜单
  90. cell = row.createCell(column);
  91. cell.setCellValue(menuItems[i]);
  92. }
  93. //创建"名称"标签,用于链接
  94. HSSFName namedCell = workbook.createName();
  95. namedCell.setNameName(formulaId);
  96. namedCell.setRefersToFormula(hiddenSheetName + "!A$1:A$" + menuItems.length);
  97. HSSFDataValidationHelper dvHelper = new HSSFDataValidationHelper(tarSheet);
  98. DataValidationConstraint dvConstraint = dvHelper.createFormulaListConstraint(formulaId);
  99. CellRangeAddressList addressList = new CellRangeAddressList(firstRow, lastRow, column, column);
  100. //添加菜单(将单元格与"名称"建立关联)
  101. HSSFDataValidation validation = (HSSFDataValidation) dvHelper.createValidation(dvConstraint, addressList);
  102. tarSheet.addValidationData(validation);
  103. }
  104. /**
  105. * 从调用addDropDownList后添加下拉菜单的Workbook中获取用户输入数据的shee列表
  106. * @param book
  107. * @return
  108. */
  109. public static List<HSSFSheet> getDataSheetInDropMenuBook(HSSFWorkbook book){
  110. return getUnHideSheets(book);
  111. }
  112. /**
  113. * 获取所有未隐藏的sheet
  114. * @param book
  115. * @return
  116. */
  117. public static List<HSSFSheet> getUnHideSheets(HSSFWorkbook book){
  118. List<HSSFSheet> ret = new ArrayList<HSSFSheet>();
  119. if(null == book){
  120. return ret;
  121. }
  122. int sheetCnt = book.getNumberOfSheets();
  123. for (int i = 0; i < sheetCnt; i++) {
  124. if(!book.isSheetHidden(i)){
  125. ret.add(book.getSheetAt(i));
  126. }
  127. }
  128. return ret;
  129. }
  130. /**
  131. * 在实际的操作过程中,发现如果直接采用Hutool的ExcelReader工具,能够直接读取到下拉框内的值
  132. */
  133. //在类中添加pattern
  134. private Pattern excelPattern = Pattern.compile("\\.(xls)|(xlsx)");
  135. private Pattern excelBytePattern = Pattern.compile("(((?i)xls)|((?i)xlsx)|((?i)zip))$");
  136. public List<List<Object>> readeExcelInfo(MultipartFile excelFile){
  137. if (excelFile == null) {
  138. throw new ServiceException(UnicomResponseEnums.BAD_REQUEST.getCode(), "上传内容不能为空");
  139. }
  140. Matcher matcher = excelPattern.matcher(excelFile.getOriginalFilename());
  141. if (!matcher.find()) {
  142. throw new ServiceException(UnicomResponseEnums.BAD_REQUEST.getCode(), "文件后缀名不符,只能上传excel文件");
  143. }
  144. InputStream inputStream = null;
  145. try {
  146. String type = null;
  147. inputStream = excelFile.getInputStream();
  148. type = FileTypeUtil.getType(excelFile.getInputStream());
  149. Matcher matcherStream = excelBytePattern.matcher(type);
  150. if (!matcherStream.find()) {
  151. throw new ServiceException(UnicomResponseEnums.BAD_REQUEST.getCode(), "文件类型不符,只能上传excel文件");
  152. }
  153. ExcelReader reader = null;
  154. try {
  155. reader = ExcelUtil.getReader(excelFile.getInputStream()); //Hutool提供的方法,直接从读取文件流
  156. } catch (IOException e) {
  157. e.printStackTrace();
  158. }
  159. List<List<Object>> excelList = reader.read(1, reader.getRowCount());
  160. return excelList;
  161. }catch(IOException e) {
  162. throw new ServiceException(UnicomResponseEnums.BAD_REQUEST.getCode(), "Excel文件流解析失败!");
  163. }
  164. }

2. Excel的导入

  1. /**
  2. * 导入Excel之后,解析对象
  3. */
  4. public Boolean importNodesExcel(MultipartFile excelFile) {
  5. if (excelFile == null) {
  6. throw new ServiceException(UnicomResponseEnums.BAD_REQUEST.getCode(), "上传内容不能为空");
  7. }
  8. Matcher matcher = excelPattern.matcher(excelFile.getOriginalFilename());
  9. if (!matcher.find()) {
  10. throw new ServiceException(UnicomResponseEnums.BAD_REQUEST.getCode(), "文件后缀名不符,只能上传excel文件");
  11. }
  12. InputStream inputStream = null;
  13. try {
  14. try {
  15. inputStream = excelFile.getInputStream();
  16. } catch (IOException e) {
  17. e.printStackTrace();
  18. }
  19. String type = null;
  20. try {
  21. type = FileTypeUtil.getType(excelFile.getInputStream());
  22. } catch (IOException e) {
  23. e.printStackTrace();
  24. }
  25. Matcher matcherStream = excelBytePattern.matcher(type);
  26. if (!matcherStream.find()) {
  27. throw new ServiceException(UnicomResponseEnums.BAD_REQUEST.getCode(), "文件类型不符,只能上传excel文件");
  28. }
  29. ExcelReader reader = null;
  30. try {
  31. reader = ExcelUtil.getReader(excelFile.getInputStream());
  32. } catch (IOException e) {
  33. e.printStackTrace();
  34. }
  35. List<List<Object>> excelList = reader.read(1, reader.getRowCount());
  36. // 用来记录导入的内容:
  37. List<Entity> nodeEntityList=new ArrayList<>();
  38. excelList.forEach(t -> {
  39. NodeEntity nodeEntity = new NodeEntity();
  40. nodeEntity.setId(Integer.valueOf(checkValue(t.get(0))));
  41. nodeEntity.setBId(checkValue(t.get(1)));
  42. nodeEntity.setName(checkValue(t.get(2)));
  43. nodeEntity.setCType(Integer.valueOf(checkValue(t.get(3))));
  44. nodeEntity.setAType(Integer.valueOf(checkValue(t.get(4))));
  45. nodeEntity.setEType(Integer.valueOf(checkValue(t.get(5))));
  46. nodeEntity.setDType(Integer.valueOf(checkValue(t.get(6))));
  47. String guid = IdUtil.simpleUUID();
  48. nodeEntity.setStandardNodeId(guid);
  49. nodeEntity.setCreateDate(System.currentTimeMillis());
  50. nodeEntity.setFlag(1);
  51. nodeEntityList.add(nodeEntity);
  52. });
  53. int num = nodeMapper.batchInsert(nodeEntityListlist);
  54. if (num < 1) {
  55. throw new ServiceException(UnicomResponseEnums.ADD_DATA.getCode(), "新增失败没有数据入库--->nodeEntity");
  56. }
  57. return true;
  58. }catch (ServiceException e){
  59. throw new ServiceException(UnicomResponseEnums.ADD_DATA.getCode(), e.getErrorMessage());
  60. } finally {
  61. if (inputStream != null) {
  62. try {
  63. inputStream.close();
  64. } catch (IOException e) {
  65. System.out.println("关闭inputStream流失败:{}", e.getMessage());
  66. }
  67. }
  68. }
  69. }
  70. /**
  71. * <检查单元格值,防止null>
  72. *
  73. * @author:
  74. * @date:
  75. * @return: java.lang.String
  76. */
  77. private String checkValue(Object value) {
  78. if (ObjectUtil.isNotEmpty(value)) {
  79. if("null".equals(value)) {
  80. return null;
  81. }
  82. if(value.toString().contains("-")) {
  83. return value.toString().split("-")[1];
  84. }else {
  85. return value.toString();
  86. }
  87. }
  88. return null;
  89. }