• 一个基于POI的通用excel导入导出工具类的简单实现及使用方法


    前言:

    最近PM来了一个需求,简单来说就是在录入数据时一条一条插入到系统显得非常麻烦,让我实现一个直接通过excel导入的方法一次性录入所有数据。网上关于excel导入导出的例子很多,但大多相互借鉴。经过思考,认为一百个客户在录入excel的时候,就会有一百个格式版本,所以在实现这个功能之前,所以要统一excel的格式。于是提供了一个通用excel模版的下载功能。当所有客户用模版录入好数据再上传到系统,后端对excel进行解析,然后再持久化到数据库。

    概述:

       此工具类的几大特点

       1、基本导入导出

       2、提供excel模版自动生成及下载功能

       3、创建模版过程简单通用,只需要在实体类上进行注解

       4、springMVC框架

       5、模版可以生成下拉框选择列

    废话不多说,上代码......

    一、引入poi相关依赖(及spring上传文件相关配置,不再解释)

     1 <!-- apache poi start -->
     2         <poi.version>3.14</poi.version>
     3         <dependency>
     4             <groupId>org.apache.poi</groupId>
     5             <artifactId>poi</artifactId>
     6             <version>${poi.version}</version>
     7         </dependency>
     8 
     9         <dependency>
    10             <groupId>org.apache.poi</groupId>
    11             <artifactId>poi-scratchpad</artifactId>
    12             <version>${poi.version}</version>
    13         </dependency>
    14 
    15         <dependency>
    16             <groupId>org.apache.poi</groupId>
    17             <artifactId>poi-ooxml</artifactId>
    18             <version>${poi.version}</version>
    19         </dependency>
    20 <!-- apache poi end -->

    二、excel导入导出工具类的实现

      1 /**
      2  * @Description
      3  * @author zhaomin E-mail:min.zhao@mljr.com
      4  * @date 创建时间:2017年2月14日 下午2:13:30
      5  * @version 1.0
      6  */
      7 public class ImportExcelUtil {
      8     final static String notnullerror = "请填入第{0}行的{1},{2}不能为空";
      9     final static String errormsg = "第{0}行的{1}数据导入错误";
     10 
     11     /**
     12      * 导入Excel
     13      * 
     14      * @param clazz
     15      * @param xls
     16      * @return
     17      * @throws Exception
     18      */
     19     @SuppressWarnings("rawtypes")
     20     public static List importExcel(Class<?> clazz, InputStream xls) throws Exception {
     21         try {
     22             // 取得Excel
     23             HSSFWorkbook wb = new HSSFWorkbook(xls);
     24             HSSFSheet sheet = wb.getSheetAt(0);
     25             Field[] fields = clazz.getDeclaredFields();
     26             List<Field> fieldList = new ArrayList<Field>(fields.length);
     27             for (Field field : fields) {
     28                 if (field.isAnnotationPresent(ModelProp.class)) {
     29                     ModelProp modelProp = field.getAnnotation(ModelProp.class);
     30                     if (modelProp.colIndex() != -1) {
     31                         fieldList.add(field);
     32                     }
     33                 }
     34             }
     35             EmployeeDTO employee = new EmployeeDTO();
     36             // 行循环
     37             List<ImportModel> modelList = new ArrayList<ImportModel>(sheet.getPhysicalNumberOfRows() * 2);
     38             for (int i = 2; i < sheet.getPhysicalNumberOfRows(); i++) {
     39                 // 数据模型
     40                 ImportModel model = (ImportModel) clazz.newInstance();
     41                 int nullCount = 0;
     42                 Exception nullError = null;
     43                 for (Field field : fieldList) {
     44                     ModelProp modelProp = field.getAnnotation(ModelProp.class);
     45                     HSSFCell cell = sheet.getRow(i).getCell(modelProp.colIndex());
     46                     try {
     47                         if (cell == null || cell.toString().length() == 0) {
     48                             nullCount++;
     49                             if (!modelProp.nullable()) {
     50                                 nullError = new Exception(StringUtil.format(notnullerror,
     51                                         new String[] { "" + (1 + i), modelProp.name(), modelProp.name() }));
     52 
     53                             }
     54                         } else if (field.getType().equals(Date.class)) {
     55                             if (Cell.CELL_TYPE_STRING == cell.getCellType()) {
     56                                 BeanUtils.setProperty(model, field.getName(), new Date(parseDate(parseString(cell))));
     57                             } else {
     58                                 BeanUtils.setProperty(model, field.getName(),
     59                                         new Date(cell.getDateCellValue().getTime()));
     60 
     61                             }
     62                         } else if (field.getType().equals(Timestamp.class)) {
     63                             if (Cell.CELL_TYPE_STRING == cell.getCellType()) {
     64                                 BeanUtils.setProperty(model, field.getName(),
     65                                         new Timestamp(parseDate(parseString(cell))));
     66                             } else {
     67                                 BeanUtils.setProperty(model, field.getName(),
     68                                         new Timestamp(cell.getDateCellValue().getTime()));
     69                             }
     70 
     71                         } else if (field.getType().equals(java.sql.Date.class)) {
     72                             if (Cell.CELL_TYPE_STRING == cell.getCellType()) {
     73                                 BeanUtils.setProperty(model, field.getName(),
     74                                         new java.sql.Date(parseDate(parseString(cell))));
     75                             } else {
     76                                 BeanUtils.setProperty(model, field.getName(),
     77                                         new java.sql.Date(cell.getDateCellValue().getTime()));
     78                             }
     79                         } else if (field.getType().equals(java.lang.Integer.class)) {
     80                             if (Cell.CELL_TYPE_NUMERIC == cell.getCellType()) {
     81                                 BeanUtils.setProperty(model, field.getName(), (int) cell.getNumericCellValue());
     82                             } else if (Cell.CELL_TYPE_STRING == cell.getCellType()) {
     83                                 BeanUtils.setProperty(model, field.getName(), Integer.parseInt(parseString(cell)));
     84                             }
     85                         } else if (field.getType().equals(java.math.BigDecimal.class)) {
     86                             if (Cell.CELL_TYPE_NUMERIC == cell.getCellType()) {
     87                                 BeanUtils.setProperty(model, field.getName(),
     88                                         new BigDecimal(cell.getNumericCellValue()));
     89                             } else if (Cell.CELL_TYPE_STRING == cell.getCellType()) {
     90                                 BeanUtils.setProperty(model, field.getName(), new BigDecimal(parseString(cell)));
     91                             }
     92                         } else {
     93                             if (Cell.CELL_TYPE_NUMERIC == cell.getCellType()) {
     94                                 BeanUtils.setProperty(model, field.getName(),
     95                                         new BigDecimal(cell.getNumericCellValue()));
     96                             } else if (Cell.CELL_TYPE_STRING == cell.getCellType()) {
     97                                 BeanUtils.setProperty(model, field.getName(), parseString(cell));
     98                             }
     99                         }
    100                     } catch (Exception e) {
    101                         e.printStackTrace();
    102                         throw new Exception(StringUtil.format(errormsg, new String[] { "" + (1 + i), modelProp.name() })
    103                                 + "," + e.getMessage());
    104                     }
    105                 }
    106                 if (nullCount == fieldList.size()) {
    107                     break;
    108                 }
    109                 if (nullError != null) {
    110                     throw nullError;
    111                 }
    112                 modelList.add(model);
    113             }
    114             return modelList;
    115 
    116         } finally {
    117             xls.close();
    118         }
    119     }
    120 
    121     private final static int colsizeN = 630;
    122     private final static int colsizeM = 1000;
    123 
    124     /**
    125      * 下载Excel模版
    126      * 
    127      * @param clazz
    128      * @param map
    129      * @param rowSize
    130      * @return
    131      */
    132     public static InputStream excelModelbyClass(Class<?> clazz, Map<Integer, String[]> map, Integer rowSize) {
    133         try {
    134             if (!clazz.isAnnotationPresent(ModelTitle.class)) {
    135                 throw new Exception("请在此类型中加上ModelTitle注解");
    136             }
    137             if (rowSize == null) {
    138                 rowSize = 1000;
    139             }
    140             HSSFWorkbook wb = new HSSFWorkbook();
    141             HSSFSheet sheet = wb.createSheet();
    142             /**
    143              * 设置标题样式
    144              */
    145             HSSFCellStyle titleStyle = wb.createCellStyle();
    146             titleStyle.setAlignment(HSSFCellStyle.ALIGN_CENTER);
    147             HSSFFont font = wb.createFont();
    148             font.setBoldweight(HSSFFont.BOLDWEIGHT_BOLD);
    149             font.setFontHeight((short) 400);
    150             titleStyle.setFont(font);
    151             HSSFCell titleCell = sheet.createRow(0).createCell(0); // 创建第一行,并在该行创建单元格,设置内容,做为标题行
    152             /**
    153              * 获取标题
    154              */
    155             ModelTitle modelTitle = clazz.getAnnotation(ModelTitle.class);
    156             titleCell.setCellValue(new HSSFRichTextString(modelTitle.name()));
    157             titleCell.setCellStyle(titleStyle);
    158 
    159             Field[] fields = clazz.getDeclaredFields();
    160             HSSFRow headRow = sheet.createRow(1);
    161             int colSzie = 0;
    162             /**
    163              * 设置表头样式
    164              */
    165             HSSFCellStyle headStyle = wb.createCellStyle();
    166             headStyle.setAlignment(HSSFCellStyle.ALIGN_CENTER);
    167             HSSFFont headFont = wb.createFont();
    168             headFont.setBoldweight(HSSFFont.BOLDWEIGHT_BOLD);
    169             headFont.setFontHeight((short) 240);
    170             headStyle.setFont(headFont);
    171             List<Integer> cells = new ArrayList<Integer>();
    172 
    173             for (Field field : fields) {
    174                 if (field.isAnnotationPresent(ModelProp.class)) {
    175                     ModelProp modelProp = field.getAnnotation(ModelProp.class);
    176                     if (modelProp.colIndex() == -1)
    177                         continue;
    178                     cells.add(modelProp.colIndex());
    179                     HSSFCell cell = headRow.createCell(modelProp.colIndex());
    180                     cell.setCellValue(new HSSFRichTextString(modelProp.name()));
    181                     cell.setCellStyle(headStyle);
    182                     colSzie++;
    183                     sheet.autoSizeColumn((short) modelProp.colIndex());
    184                     sheet.setColumnWidth(modelProp.colIndex(), modelProp.name().length() * colsizeN + colsizeM);
    185 
    186                     // 设置列为下拉框格式
    187                     if (map != null && map.get(new Integer(modelProp.colIndex())) != null) {
    188                         DVConstraint constraint = DVConstraint
    189                                 .createExplicitListConstraint(map.get(modelProp.colIndex()));
    190                         CellRangeAddressList regions = new CellRangeAddressList(2, rowSize, modelProp.colIndex(),
    191                                 modelProp.colIndex());
    192                         HSSFDataValidation dataValidation = new HSSFDataValidation(regions, constraint);
    193                         sheet.addValidationData(dataValidation);
    194                     }
    195                 }
    196             }
    197             HSSFCellStyle cellStyle = wb.createCellStyle();
    198             HSSFDataFormat format = wb.createDataFormat();
    199             cellStyle.setDataFormat(format.getFormat("@"));
    200             for (int i = 2; i < rowSize; i++) {
    201                 HSSFRow row = sheet.createRow(i);
    202                 for (Integer integer : cells) {
    203                     HSSFCell cell = row.createCell(integer);
    204                     cell.setCellStyle(cellStyle);
    205                 }
    206             }
    207             sheet.addMergedRegion(new CellRangeAddress(0, 0, 0, colSzie - 1));
    208             if (map != null) {
    209                 for (Integer colIndex : map.keySet()) {
    210                     DVConstraint constraint = DVConstraint.createExplicitListConstraint(map.get(colIndex));
    211                     CellRangeAddressList regions = new CellRangeAddressList(2, 1000, colIndex, colIndex);
    212                     HSSFDataValidation dataValidation = new HSSFDataValidation(regions, constraint);
    213                     sheet.addValidationData(dataValidation);
    214                 }
    215             }
    216 
    217             ByteArrayOutputStream os = new ByteArrayOutputStream();
    218             try {
    219                 wb.write(os);
    220             } catch (IOException e) {
    221                 e.printStackTrace();
    222             }
    223 
    224             byte[] b = os.toByteArray();
    225 
    226             ByteArrayInputStream in = new ByteArrayInputStream(b);
    227             return in;
    228         } catch (Exception e) {
    229             e.printStackTrace();
    230             return null;
    231         }
    232     }
    233 
    234     private static String parseString(HSSFCell cell) {
    235         return String.valueOf(cell).trim();
    236     }
    237 
    238     private static long parseDate(String dateString) throws ParseException {
    239         if (dateString.indexOf("/") == 4) {
    240             return new SimpleDateFormat("yyyy/MM/dd").parse(dateString).getTime();
    241         } else if (dateString.indexOf("-") == 4) {
    242             return new SimpleDateFormat("yyyy-MM-dd").parse(dateString).getTime();
    243         } else if (dateString.indexOf("年") == 4) {
    244             return new SimpleDateFormat("yyyy年MM月dd").parse(dateString).getTime();
    245         } else if (dateString.length() == 8) {
    246             return new SimpleDateFormat("yyyyMMdd").parse(dateString).getTime();
    247         } else {
    248             return new Date().getTime();
    249         }
    250     }
    251 
    252 }

     三、自定义spring注解

    1 @Retention(RetentionPolicy.RUNTIME)
    2 @Target(ElementType.FIELD)
    3 public @interface ModelProp{
    4     public String name();
    5     public int colIndex() default -1;
    6     public boolean nullable() default true;
    7     public String interfaceXmlName() default "";
    8 }
    1 @Retention(RetentionPolicy.RUNTIME)
    2 @Target(ElementType.TYPE)
    3 public @interface ModelTitle{
    4     public String name();
    5 }

    四、定义实体类父类

    1 public class ImportModel {
    2 
    3 }

    五、定义实体类

     1 @ModelTitle(name="人员列表")
     2 public class EmployeeDTO extends ImportModel implements Serializable {
     3 
     4     private static final long serialVersionUID = -3434719712955859295L;
     5 
     6     private Long id;
     7     @ModelProp(name = "电话", colIndex = 1, nullable = false)
     8     private String telephone;
     9 
    10     @ModelProp(name = "名称", colIndex = 0, nullable = false)
    11     private String name;
    12 
    13     @ModelProp(name = "性别", colIndex = 2, nullable = false)
    14     private Integer sex;
    15 }

    六、定义controller

     1 @RestController
     2 @RequestMapping("/api/excelOpera")
     3 public class ImportEmployeeController extends BaseController {
     4     
     5     private static Logger logger = LoggerFactory.getLogger(ImportEmployeeController.class);
     6     /**
     7      * 导入excel表
     8      * @version 1.0
     9      * @since 1.0
    10      */
    11     @RequestMapping(path = "/importEmployee", method = RequestMethod.POST)
    12     public RespMsg uploadExcel(@RequestParam("file") MultipartFile file, HttpServletRequest request) {
    13         try{
    14            
    15             List<EmployeeDTO> employeeDTOList  = ImportExcelUtil.importExcel(EmployeeDTO.class, file.getInputStream());
    16             //可做持久化操作,现只打印观察
    17             for(EmployeeDTO employeeDTO : employeeDTOList){
    18                 logger.info("name=" + employeeDTO.getName() + ",telephone=" + employeeDTO.getTelephone()+",sex=" + employeeDTO.getSex());
    19             }
    20         }catch(Exception e){
    21             logger.error(e.getMessage());
    22         }
    23         return null;
    24     }
    25     /**
    26      * 导出excel模版
    27      * @version 1.0
    28      * @since 1.0
    29      */
    30     @RequestMapping(path = "/downloadEmployeeModel", method = RequestMethod.GET)
    31     public RespMsg downloadEmployeeModel(HttpServletResponse response) {
    32         try{
    33             response.setContentType("application/xls");
    34             response.addHeader("Content-Disposition", "attachment;filename="+new String(("eeelist").getBytes("UTF-8"),"iso-8859-1")+".xls");
    35             Map<Integer,String[]> paramMap = new HashMap<Integer,String[]>();
    36             //excel第三行为下拉选择框
    37             paramMap.put(2, new String[]{"man","women"});
    38             BufferedInputStream input = new BufferedInputStream(ImportExcelUtil.excelModelbyClass(EmployeeDTO.class, paramMap, null));
    39             byte buffBytes[] = new byte[1024];
    40             OutputStream os = response.getOutputStream();
    41             int read = 0;
    42             while ((read = input.read(buffBytes)) != -1) {
    43                 os.write(buffBytes, 0, read);
    44             }
    45             os.flush();
    46             os.close();
    47             input.close();
    48             return success("下载成功!");
    49         }catch(Exception e){
    50             logger.error("downloadEmployeeModel() catch Exception ",e);
    51             return fail("下载失败!");
    52         }
    53     }
    54     
    55 }
    56         

    至此全部工具类的实现已经完成,可以请求访问检验一下结果。

      下载下来的excel模版

      

      填写数据上传

      

      后台控制台打印输出结果

      

      检验结果能够达到预期效果且能通用,是不是很简单呢,欢迎大神们提出意见,小女子感谢了。

  • 相关阅读:
    div 垂直居中的方法
    vs code添加到鼠标右键
    win10系统迁移到新的硬盘
    使用layui iframe弹层,各弹层之前的传值问题
    layui js动态添加的面板不能折叠
    Nginx系列6:对称加密与非对称加密各自的应用场景
    Nginx系列5:从网络原理来看SSL安全协议
    Nginx系列0:Nginx学习历程
    加扰与加密&解扰与解密
    微信小程序学习过程
  • 原文地址:https://www.cnblogs.com/blueness-sunshine/p/6400485.html
Copyright © 2020-2023  润新知