当前位置:   article > 正文

使用apache poi 3.17导入excel

org.apache.poi:poi:3.17

最近在项目开发中,有需要导入、导出excel的功能,使用了alibaba的easyexcel。自己水平太菜,踩了许多坑。在alibaba-easyexcel使用问题总结 这里总结了一番,也涨了点姿势:

  1. 恶补了下maven的相关知识:maven包冲突的解决方式
  2. 如果机器上装了“中软防水坝”等相关的安全软件,文件读写是要失败的。因为 inputStream.markSupported()会返回false 从而无法操作 抛出异常 easyexcel是ExcelAnalysisException io is must be available markSupported。

发现easyexcel也是引用了apache的poi,在poi基础上做了更改。

今天也来学习下使用poi 3.17来导入、导出excel

参考自这里,写的很好,跟着撸一遍


maven依赖

  1. <dependency>
  2. <groupId>org.apache.commons</groupId>
  3. <artifactId>commons-collections4</artifactId>
  4. <version>4.1</version>
  5. </dependency>
  6. <dependency>
  7. <groupId>commons-io</groupId>
  8. <artifactId>commons-io</artifactId>
  9. <version>2.4</version>
  10. </dependency>
  11. <dependency>
  12. <groupId>org.apache.xmlbeans</groupId>
  13. <artifactId>xmlbeans</artifactId>
  14. <version>2.6.0</version>
  15. </dependency>
  16. <dependency>
  17. <groupId>org.apache.poi</groupId>
  18. <artifactId>poi</artifactId>
  19. <version>3.17</version>
  20. </dependency>
  21. <dependency>
  22. <groupId>org.apache.poi</groupId>
  23. <artifactId>poi-ooxml</artifactId>
  24. <version>3.17</version>
  25. </dependency>
  26. <dependency>
  27. <groupId>org.apache.poi</groupId>
  28. <artifactId>poi-ooxml-schemas</artifactId>
  29. <version>3.17</version>
  30. </dependency>

如果你想简化你的代码,可以加上

  1. <dependency>
  2. <groupId>org.projectlombok</groupId>
  3. <artifactId>lombok</artifactId>
  4. <version>1.16.10</version>
  5. <scope>provided</scope>
  6. </dependency>
导入

准备excel表 人员信息.xlsx

EXCLE

创建与excel列名对应的bean

  1. package io.github.newmean.demo.domain;
  2. import lombok.Data;
  3. import java.util.Date;
  4. @Data
  5. public class Persion {
  6. private String deptName;
  7. private String createName;
  8. private Date createDate;
  9. private String politicStatus;
  10. private int age;
  11. }

Lombok 注解在线帮助文档:http://projectlombok.org/features/index
介绍几个常用的 lombok 注解:

  • @Data :注解在类上;提供类所有属性的 get 和 set 方法,此外还提供了equals、canEqual、hashCode、toString 方法
  • @Setter:注解在属性上;为属性提供 sett方法
  • @Getter:注解在属性上;为属性提供 get 方法
  • @Log4j :注解在类上;为类提供一个 属性名为log 的 log4j 日志对象
  • @NoArgsConstructor:注解在类上;为类提供一个无参的构造方法
  • @AllArgsConstructor:注解在类上;为类提供一个全参的构造方法

再加上一个注解,让属性和列名对应起来

  1. package io.github.newmean.demo.annotation;
  2. import java.lang.annotation.*;
  3. @Target({ElementType.FIELD})
  4. @Retention(RetentionPolicy.RUNTIME)
  5. @Documented
  6. public @interface ExcelColumn {
  7. public String value() default "";
  8. }

那么bean就可以改写为:

  1. package io.github.newmean.demo.domain;
  2. import io.github.newmean.demo.util.ExcelColumn;
  3. import lombok.Data;
  4. import lombok.Setter;
  5. import lombok.ToString;
  6. import java.util.Date;
  7. @Data
  8. @ToString
  9. public class Persion {
  10. @Setter
  11. @ExcelColumn(value = "处室")
  12. private String deptName;
  13. @Setter
  14. @ExcelColumn(value = "填表人")
  15. private String createName;
  16. @Setter
  17. @ExcelColumn(value = "填表时间")
  18. private Date createDate;
  19. @Setter
  20. @ExcelColumn(value = "政治面貌")
  21. private String politicStatus;
  22. @Setter
  23. @ExcelColumn(value = "年龄")
  24. private int age;
  25. }

采用MultipartFile上传,可以读取.xlsx或者.xls格式的Excel(POI3.15以上版本兼容)

  1. package io.github.newmean.demo.util;
  2. import java.io.IOException;
  3. import java.io.InputStream;
  4. import java.lang.reflect.Field;
  5. import java.text.DecimalFormat;
  6. import java.util.ArrayList;
  7. import java.util.HashMap;
  8. import java.util.LinkedList;
  9. import java.util.List;
  10. import java.util.Map;
  11. import java.util.Objects;
  12. import io.github.newmean.demo.annotation.ExcelColumn;
  13. import org.apache.commons.io.IOUtils;
  14. import org.apache.commons.lang3.time.FastDateFormat;
  15. import org.apache.poi.ss.usermodel.Cell;
  16. import org.apache.poi.ss.usermodel.DateUtil;
  17. import org.apache.poi.ss.usermodel.Row;
  18. import org.apache.poi.ss.usermodel.Sheet;
  19. import org.apache.poi.ss.usermodel.Workbook;
  20. import org.apache.poi.ss.usermodel.WorkbookFactory;
  21. import org.springframework.util.StringUtils;
  22. import org.springframework.web.multipart.MultipartFile;
  23. public class ExcelUtil {
  24. private static final DecimalFormat DECIMAL_FORMAT = new DecimalFormat("0");// 格式化 number为整
  25. private static final FastDateFormat FAST_DATE_FORMAT = FastDateFormat.getInstance("yyyy-MM-dd HH:mm:ss");
  26. /**
  27. * 对外提供读取excel 的方法
  28. * @param file
  29. * @return
  30. * @throws IOException
  31. */
  32. public static List<List<Object>> readExcel(MultipartFile file) throws IOException {
  33. String extension = file.getOriginalFilename().substring(file.getOriginalFilename().lastIndexOf(".") + 1).toLowerCase();
  34. if(Objects.equals("xls", extension) || Objects.equals("xlsx", extension)) {
  35. return readExcel(file.getInputStream());
  36. } else {
  37. throw new IOException("不支持的文件类型");
  38. }
  39. }
  40. /**
  41. * 对外提供读取excel 的方法
  42. * @param file
  43. * @param cls
  44. * @return
  45. * @throws IOException
  46. */
  47. public static <T> List<T> readExcel(MultipartFile file, Class<T> cls) throws IOException {
  48. String extension = file.getOriginalFilename().substring(file.getOriginalFilename().lastIndexOf(".") + 1).toLowerCase();
  49. if(Objects.equals("xls", extension) || Objects.equals("xlsx", extension)) {
  50. return readExcel(file.getInputStream(), cls);
  51. } else {
  52. throw new IOException("不支持的文件类型");
  53. }
  54. }
  55. /**
  56. * 读取 office excel
  57. *
  58. * @param inputStream
  59. * @return
  60. * @throws IOException
  61. */
  62. public static List<List<Object>> readExcel(InputStream inputStream) throws IOException {
  63. List<List<Object>> list = new LinkedList<>();
  64. Workbook workbook = null;
  65. try {
  66. workbook = WorkbookFactory.create(inputStream);
  67. int sheetsNumber = workbook.getNumberOfSheets();
  68. for (int n = 0; n < sheetsNumber; n++) {
  69. Sheet sheet = workbook.getSheetAt(n);
  70. Object value = null;
  71. Row row = null;
  72. Cell cell = null;
  73. for (int i = sheet.getFirstRowNum() + 1; i <= sheet.getPhysicalNumberOfRows(); i++) { // 从第二行开始读取
  74. row = sheet.getRow(i);
  75. if (StringUtils.isEmpty(row)) {
  76. continue;
  77. }
  78. List<Object> linked = new LinkedList<>();
  79. for (int j = row.getFirstCellNum(); j <= row.getLastCellNum(); j++) {
  80. cell = row.getCell(j);
  81. if (StringUtils.isEmpty(cell)) {
  82. continue;
  83. }
  84. value = getCellValue(cell);
  85. linked.add(value);
  86. }
  87. list.add(linked);
  88. }
  89. }
  90. } catch (Exception e) {
  91. e.printStackTrace();
  92. } finally {
  93. IOUtils.closeQuietly(workbook);
  94. IOUtils.closeQuietly(inputStream);
  95. }
  96. return list;
  97. }
  98. /**
  99. * 获取excel数据 将之转换成bean
  100. * @param cls
  101. * @param <T>
  102. * @return
  103. */
  104. public static <T> List<T> readExcel(InputStream inputStream, Class<T> cls) {
  105. List<T> dataList = new LinkedList<>();
  106. Workbook workbook = null;
  107. try {
  108. workbook = WorkbookFactory.create(inputStream);
  109. Map<String, List<Field>> classMap = new HashMap<>();
  110. Field[] fields = cls.getDeclaredFields();
  111. for (Field field : fields) {
  112. ExcelColumn annotation = field.getAnnotation(ExcelColumn.class);
  113. if (annotation != null) {
  114. String value = annotation.value();
  115. if (!classMap.containsKey(value)) {
  116. classMap.put(value, new ArrayList<>());
  117. }
  118. field.setAccessible(true);
  119. classMap.get(value).add(field);
  120. }
  121. }
  122. Map<Integer, List<Field>> reflectionMap = new HashMap<>();
  123. int sheetsNumber = workbook.getNumberOfSheets();
  124. for (int n = 0; n < sheetsNumber; n++) {
  125. Sheet sheet = workbook.getSheetAt(n);
  126. for (int j = sheet.getRow(0).getFirstCellNum(); j < sheet.getRow(0).getLastCellNum(); j++) { //首行提取注解
  127. Object cellValue = getCellValue(sheet.getRow(0).getCell(j));
  128. if (classMap.containsKey(cellValue)) {
  129. reflectionMap.put(j, classMap.get(cellValue));
  130. }
  131. }
  132. Row row = null;
  133. Cell cell = null;
  134. for (int i = sheet.getFirstRowNum() + 1; i < sheet.getPhysicalNumberOfRows(); i++) {
  135. row = sheet.getRow(i);
  136. T t = cls.newInstance();
  137. for (int j = row.getFirstCellNum(); j < row.getLastCellNum(); j++) {
  138. cell = row.getCell(j);
  139. if (reflectionMap.containsKey(j)) {
  140. Object cellValue = getCellValue(cell);
  141. List<Field> fieldList = reflectionMap.get(j);
  142. for (Field field : fieldList) {
  143. try {
  144. field.set(t, cellValue);
  145. } catch (Exception e) {
  146. //logger.error()
  147. }
  148. }
  149. }
  150. }
  151. dataList.add(t);
  152. }
  153. }
  154. } catch (Exception e) {
  155. dataList = null;
  156. } finally {
  157. IOUtils.closeQuietly(workbook);
  158. IOUtils.closeQuietly(inputStream);
  159. }
  160. return dataList;
  161. }
  162. /**
  163. * 获取excel 单元格数据
  164. *
  165. * @param cell
  166. * @return
  167. */
  168. private static Object getCellValue(Cell cell) {
  169. Object value = null;
  170. switch (cell.getCellTypeEnum()) {
  171. case _NONE:
  172. break;
  173. case STRING:
  174. value = cell.getStringCellValue();
  175. break;
  176. case NUMERIC:
  177. if(DateUtil.isCellDateFormatted(cell)){ //日期
  178. value = FAST_DATE_FORMAT.format(DateUtil.getJavaDate(cell.getNumericCellValue()));
  179. } else if("@".equals(cell.getCellStyle().getDataFormatString())
  180. || "General".equals(cell.getCellStyle().getDataFormatString())
  181. || "0_ ".equals(cell.getCellStyle().getDataFormatString())){
  182. //文本 or 常规 or 整型数值
  183. value = DECIMAL_FORMAT.format(cell.getNumericCellValue());
  184. }
  185. break;
  186. case BOOLEAN:
  187. value = cell.getBooleanCellValue();
  188. break;
  189. case BLANK:
  190. //value = ",";
  191. break;
  192. default:
  193. value = cell.toString();
  194. }
  195. return value;
  196. }
  197. }

转载于:https://www.cnblogs.com/nm666/p/10764807.html

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/菜鸟追梦旅行/article/detail/170206
推荐阅读
相关标签
  

闽ICP备14008679号