JAVA通过Easypoi实现后端接口模板导出和数据导入

easypoi功能如同名字easy,主打的功能就是容易,让一个没见接触过poi的人员
就可以方便的写出Excel导出,Excel模板导出,Excel导入,Word模板导出,通过简单的注解和模板
语言(熟悉的表达式语法),完成以前复杂的写法

特点

  • 1.设计精巧,使用简单
  • 2.接口丰富,扩展简单
  • 3.默认值多,write less do more
  • 4.spring mvc支持,web导出可以简单明了

1、依赖引入

如果是使用springmvc的便捷,可直接引入easypoi-base

<dependency>
    <groupId>cn.afterturn</groupId>
    <artifactId>easypoi-base</artifactId>
    <version>4.2.0</version>
</dependency>
<dependency>
	<groupId>cn.afterturn</groupId>
	<artifactId>easypoi-web</artifactId>
	<version>4.2.0</version>
</dependency>
<dependency>
	<groupId>cn.afterturn</groupId>
	<artifactId>easypoi-annotation</artifactId>
	<version>4.2.0</version>
</dependency>

2、封装工具类

封装对象转化为Map的工具类

public class ConvertUtil {
	
	private static final Logger logger = LoggerFactory.getLogger(ConvertUtil.class);
	
	/**
	 * 对象转换map
	 * 
	 * @param object
	 * @return
	 */
	public static Map<String, Object> objectToMap(Object object) {
		Field[] fields = object.getClass().getDeclaredFields();
		Map<String, Object> map = new HashMap<>(fields.length);
		for (Field field : fields) {
			field.setAccessible(true);
			try {
				map.put(field.getName(), field.get(object));
			} catch (IllegalArgumentException e) {
				logger.error(e.getMessage(), e);
			} catch (IllegalAccessException e) {
				logger.error(e.getMessage(), e);
			}
		}
		return map;
	}
	
	public static Map<String, String> getConvertMap(List<ExcelCisdiEntity> entityList) {
		Map<String, String> map = new HashMap<>(entityList.size());
		for (ExcelCisdiEntity entity : entityList) {
			map.put(entity.getName(), entity.getKey());
		}
		return map;
	}
	
	public static Map<String, String> getFomartMap(List<ExcelCisdiEntity> entityList) {
		Map<String, String> map = new HashMap<>(entityList.size());
		for (ExcelCisdiEntity entity : entityList) {
			map.put(entity.getKey(), entity.getFormat());
		}
		return map;
	}
	
}

封装Excel导入导出的工具类

@Slf4j
public class ExcelUtil {
	
	private static int USE_SXSSF_LIMIT = 100000;

	/**
	 * 导出excel     注解方式
	 * 
	 * 
	 * @param fileName
	 *               文件名称
	 * @param dataList
	 *               导出数据
	 * @param response
	 * @param clazz
	 */
	public static void exportExcel(String fileName, List<?> dataList, HttpServletResponse response, Class<?> clazz){
		Workbook workbook = ExcelExportUtil.exportExcel(new ExportParams(null, null), clazz, dataList);
		
		response.reset();
		response.setCharacterEncoding("UTF-8");
		response.setContentType("application/x-download");
		
		fileName = fileName + ".xls";
		try {
			fileName = URLEncoder.encode(fileName, "UTF-8");
		} catch (UnsupportedEncodingException e) {
			log.error(e.getMessage(), e);
		}
		response.addHeader("Content-Disposition", "attachment;filename=" + fileName);
		OutputStream out = null;
		try {
			out = response.getOutputStream();
			workbook.write(out);
			out.flush();
			out.close();
		} catch (IOException e) {
			log.error(e.getMessage(), e);
		}
	}
	
	/**
	 * 导出excel     非注解方式
	 * 
	 * @param fileName 
	 *               文件名称
	 * @param dataList 
	 *               导出数据
	 * @param entityList 
	 *               配置实体 
     *               1.key:对象实体属性名,name:字段名
     *               2.如果对象实体属性都是基础数据类型,该参数可以为空,导出的excel字段名为对象实体属性名
     *               3.其他参数相关配置,请参考easypoi,http://easypoi.mydoc.io/#text_186905
	 * @param response
	 * @param clazz
	 */
	public static void exportExcel(String fileName, List<?> dataList, List<ExcelExportEntity> entityList,
									HttpServletResponse response, Class<?> clazz) {
		List<Map<String, Object>> map = new ArrayList<Map<String, Object>>();
		for (Object object : dataList) {
			map.add(ConvertUtil.objectToMap(object));
		}
		
		if (CollectionUtils.isEmpty(entityList)) {
			entityList = new ArrayList<ExcelExportEntity>();
			Field[] fields = clazz.getDeclaredFields();
			for (Field field : fields) {
				entityList.add(new ExcelExportEntity(field.getName(), field.getName()));
			}
		}
		
		Workbook workbook = ExcelExportUtil.exportExcel(new ExportParams(null, null), entityList, map);
		
		response.reset();
		response.setCharacterEncoding("UTF-8");
		response.setContentType("application/x-download");
		
		fileName = fileName + ".xls";
		try {
			fileName = URLEncoder.encode(fileName, "UTF-8");
		} catch (UnsupportedEncodingException e) {
			log.error(e.getMessage(), e);
		}
		response.addHeader("Content-Disposition", "attachment;filename=" + fileName);
		OutputStream out = null;
		try {
			out = response.getOutputStream();
			workbook.write(out);
			out.flush();
			out.close();
		} catch (IOException e) {
			log.error(e.getMessage(), e);
		}
	}

	/**
	 * 多sheet表格导出    注解方式
	 * @param fileName
	 * @param response
	 * @param sheetsList
	 */
	public static void exportExcel(String fileName,HttpServletResponse response,List<Map<String,Object>> sheetsList) {
		Workbook workBook = ExcelExportUtil.exportExcel(sheetsList, ExcelType.HSSF);

		response.reset();
		response.setCharacterEncoding("UTF-8");
		response.setContentType("application/x-download");

		fileName = fileName + ".xls";
		try {
			fileName = URLEncoder.encode(fileName, "UTF-8");
		} catch (UnsupportedEncodingException e) {
			log.error(e.getMessage(), e);
		}
		response.addHeader("Content-Disposition", "attachment;filename=" + fileName);
		OutputStream out = null;
		try {
			out = response.getOutputStream();
			workBook.write(out);
			out.flush();
			out.close();
		} catch (IOException e) {
			log.error(e.getMessage(), e);
		}
	}

	/**
	 * 多sheet表格导出    非注解方式
	 * @param fileName
	 * @param response
	 * @param list
	 */
	public static void newExportExcel(String fileName,HttpServletResponse response,List<NewExcelExportEntity> list) {
		Workbook workBook = exportNewExcel(list, ExcelType.HSSF);

		response.reset();
		response.setCharacterEncoding("UTF-8");
		response.setContentType("application/x-download");

		fileName = fileName + ".xls";
		try {
			fileName = URLEncoder.encode(fileName, "UTF-8");
		} catch (UnsupportedEncodingException e) {
			log.error(e.getMessage(), e);
		}
		response.addHeader("Content-Disposition", "attachment;filename=" + fileName);
		OutputStream out = null;
		try {
			out = response.getOutputStream();
			workBook.write(out);
			out.flush();
			out.close();
		} catch (IOException e) {
			log.error(e.getMessage(), e);
		}
	}

	/**
	 * 导入excel   非注解方式
	 * 
	 * @param in 
	 *             文件输入流
	 * @param entityList 
	 *             配置实体
	 *             1.key:对象实体属性名,name:字段名
     *             2.如果对象实体属性都是基础数据类型,导入的excel字段名为对象实体属性名,该参数可以为空
	 * @param clazz
	 * @return
	 * @throws Exception
	 */
	public static <T> List<T> importExcel(FileInputStream in, List<ExcelCisdiEntity> entityList, Class<T> clazz) throws Exception {
		List<Map<String, Object>> maps = ExcelImportUtil.importExcel(in, Map.class, new ImportParams());
 		List<T> list = new ArrayList<T>();
		if (CollectionUtils.isEmpty(entityList)) {
			for (Map<String, Object> map : maps) {
				map = map.entrySet().stream().filter(k ->null !=k &&  k.getKey() != null && null != k.getValue()).collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue));
				final Set<Object> collect = map.values().stream().collect(Collectors.toSet());
				Boolean canDeal = !collect.isEmpty();
				if (canDeal){
					T obj = clazz.newInstance();
					BeanUtils.populate(obj, map);
					list.add(obj);
				}
			}
		} else {
			Map<String, String> convertMap = ConvertUtil.getConvertMap(entityList);
			Map<String, String> fomartMap = ConvertUtil.getFomartMap(entityList);
			
			List<Map<String, Object>> entityMaps = new ArrayList<>();
			for (Map<String, Object> map : maps) {
				Map<String, Object> entityMap = new HashMap<>(map.size());
				map.forEach((k, v) -> {
					String key = convertMap.get(k);
					String fomart = fomartMap.get(key);
					if (fomart != null) {
						SimpleDateFormat sdf = new SimpleDateFormat(fomart);
						Date date = null;
						try {
							date = sdf.parse(String.valueOf(v));
						} catch (Exception e) {
							log.error(e.getMessage(), e);
						}
						entityMap.put(key, date);
					} else {
						entityMap.put(key, v);
					}
				});
				entityMaps.add(entityMap);
			}
			for (Map<String, Object> map : entityMaps) {
				map = map.entrySet().stream().filter(k ->null !=k &&  k.getKey() != null && null != k.getValue()).collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue));
				final Set<Object> collect = map.values().stream().collect(Collectors.toSet());
				Boolean canDeal = !collect.isEmpty();
 				if (canDeal){
//					T obj = clazz.newInstance();
//					BeanUtils.populate(obj, map);
					T obj = JSON.parseObject(JSON.toJSONString(map),clazz);
					list.add(obj);
				}
			}
		}
		return list;
	}

	public static Workbook exportNewExcel(List<NewExcelExportEntity> list, ExcelType type) {
		Workbook workbook = getWorkbook(type, 0);
		for (NewExcelExportEntity entity : list) {
			ExcelExportService service = new ExcelExportService();
			service.createSheetForMap(workbook, entity.getEntity(),entity.getEntityList(), entity.getDataSet());
		}
		return workbook;
	}

	private static Workbook getWorkbook(ExcelType type, int size) {
		if (ExcelType.HSSF.equals(type)) {
			return new HSSFWorkbook();
		} else {
			return (Workbook)(size < USE_SXSSF_LIMIT ? new XSSFWorkbook() : new SXSSFWorkbook());
		}
	}

    /**
     * 多sheet动态导入的准备工作
     * @param list
     * @param entityList
     * @param clazz
     * @param exportParams
     * @return
     */
    public static NewExcelExportEntity setExcelExportEntity(List<?> list, List<ExcelExportEntity> entityList, Class<?> clazz, ExportParams exportParams){
        NewExcelExportEntity result = new NewExcelExportEntity();
        List<Map<String, Object>> map = new ArrayList<Map<String, Object>>();
        for (Object object : list) {
            map.add(ConvertUtil.objectToMap(object));
        }


        if (CollectionUtils.isEmpty(entityList)) {
            entityList = new ArrayList<ExcelExportEntity>();
            Field[] fields = clazz.getDeclaredFields();
            for (Field field : fields) {
                entityList.add(new ExcelExportEntity(field.getName(), field.getName()));
            }
        }

        result.setEntityList(entityList);
        result.setEntity(exportParams);
        result.setDataSet(map);
        return result;
    }
}

创建Excel样式初始化类

public class ExcelStyleUtil implements IExcelExportStyler {

    private static final short STRING_FORMAT = (short) BuiltinFormats.getBuiltinFormat("TEXT");
    private static final short FONT_SIZE_TEN = 10;
    private static final short FONT_SIZE_ELEVEN = 11;
    private static final short FONT_SIZE_TWELVE = 12;

    /**
     * 大标题样式
     */
    private CellStyle headerStyle;
    /**
     * 每列标题样式
     */
    private CellStyle titleStyle;
    /**
     * 数据行样式
     */
    private CellStyle styles;

    private ExcelStyleUtil(Workbook workbook) {
        this.init(workbook);
    }

    private void init(Workbook workbook) {
        this.headerStyle = initHeaderStyle(workbook);
        this.titleStyle = initTitleStyle(workbook);
        this.styles = initStyles(workbook);
    }

    /**
     * 初始化--大标题样式
     *
     * @param workbook workbook
     * @return CellStyle
     */
    private CellStyle initHeaderStyle(Workbook workbook) {
        CellStyle style = getBaseCellStyle(workbook);
        style.setFont(getFont(workbook, FONT_SIZE_TWELVE, true));
        return style;
    }

    /**
     * 初始化--每列标题样式
     *
     * @param workbook workbook
     * @return CellStyle
     */
    private CellStyle initTitleStyle(Workbook workbook) {
        CellStyle style = getBaseCellStyle(workbook);
        style.setFont(getFont(workbook, FONT_SIZE_ELEVEN, false));
        //背景色
        style.setFillForegroundColor(IndexedColors.GREY_25_PERCENT.getIndex());
        style.setFillPattern(FillPatternType.SOLID_FOREGROUND);
        return style;
    }

    /**
     * 初始化--数据行样式
     *
     * @param workbook workbook
     * @return CellStyle
     */
    private CellStyle initStyles(Workbook workbook) {
        CellStyle style = getBaseCellStyle(workbook);
        style.setFont(getFont(workbook, FONT_SIZE_TEN, false));
        style.setDataFormat(STRING_FORMAT);
        return style;
    }

    @Override
    public CellStyle getHeaderStyle(short i) {
        return headerStyle;
    }

    @Override
    public CellStyle getTitleStyle(short i) {
        return titleStyle;
    }

    @Override
    public CellStyle getStyles(boolean b, ExcelExportEntity excelExportEntity) {
        return styles;
    }

    @Override
    public CellStyle getStyles(Cell cell, int i, ExcelExportEntity excelExportEntity, Object o, Object o1) {
        return getStyles(true,excelExportEntity);
    }

    @Override
    public CellStyle getTemplateStyles(boolean b, ExcelForEachParams excelForEachParams) {
        return null;
    }

    /**
     * 基础样式
     *
     * @return CellStyle
     */
    private CellStyle getBaseCellStyle(Workbook workbook) {
        CellStyle style = workbook.createCellStyle();
        //下边框
        style.setBorderBottom(BorderStyle.THIN);
        //左边框
        style.setBorderLeft(BorderStyle.THIN);
        //上边框
        style.setBorderTop(BorderStyle.THIN);
        //右边框
        style.setBorderRight(BorderStyle.THIN);
        //水平居中
        style.setAlignment(HorizontalAlignment.CENTER);
        //上下居中
        style.setVerticalAlignment(VerticalAlignment.CENTER);
        //设置自动换行
        style.setWrapText(true);
        style.setDataFormat((short) BuiltinFormats.getBuiltinFormat("TEXT"));
        return style;
    }

    /**
     * 字体样式
     *
     * @param size   字体大小
     * @param isBold 是否加粗
     * @return Font
     */
    private Font getFont(Workbook workbook, short size, boolean isBold) {
        Font font = workbook.createFont();
        //字体样式
        font.setFontName("宋体");
        //是否加粗
        font.setBold(isBold);
        //字体大小
        font.setFontHeightInPoints(size);
        return font;
    }

}

3、导出模板

创建一个Excel的sheet

一个Excel文件可包含多个sheet

	List<ExcelExportEntity> sheet1 = getSheet();
	List<ExcelExportEntity> sheet2 = getSheet();
	List<ExcelExportEntity> sheet3 = getSheet();
    private List<ExcelExportEntity> getSheet() {
        List<ExcelExportEntity> result = new ArrayList<>();
        result.add(new ExcelExportEntity("设备编码(必填)", "code", 30));
        result.add(new ExcelExportEntity("设备名称(必填)", "name", 30));
        result.add(new ExcelExportEntity("供应商编码", "providerCode", 30));
        result.add(new ExcelExportEntity("设备类型", "sensorTypeId", 30));
        result.add(new ExcelExportEntity("所属组织", "orgId", 30));
        result.add(new ExcelExportEntity("设备标签(选填,请用'-'隔开)", "tags", 60));
        result.add(new ExcelExportEntity("备注", "remark", 60));
        return result;
    }

把3个sheet数据进行组装

 //假设sheet数据为下面这个List,实际情况下根据接口获取
 List<TestData> sheetData = new ArrayList<>();

  ExportParams exportParams1 = new ExportParams(null, "Sheet1的数据列表");
  exportParams1.setStyle(ExcelStyleUtil.class);  //设置样式
  ExportParams exportParams2 = new ExportParams(null, "Sheet2的数据列表");
  exportParams2.setStyle(ExcelStyleUtil.class);
  ExportParams exportParams3 = new ExportParams(null, "Sheet3的数据列表");
  exportParams3.setStyle(ExcelStyleUtil.class);  
  
  NewExcelExportEntity newExcelExportEntity1 = ExcelUtil.setExcelExportEntity(sheetData, sheet1, TestData.class, exportParams1);
  NewExcelExportEntity newExcelExportEntity2 = ExcelUtil.setExcelExportEntity(sheetData, sheet2, TestData.class, exportParams2);
  NewExcelExportEntity newExcelExportEntity3 = ExcelUtil.setExcelExportEntity(sheetData, sheet3, TestData.class, exportParams3);
  

  
  

导出封装好的数据

	//创建导出的sheet列表
	List<NewExcelExportEntity> newExcelExportEntityList = new ArrayList<>();
	//把组装后的数据放入sheet列表
	newExcelExportEntityList.add(newExcelExportEntity1);
	newExcelExportEntityList.add(newExcelExportEntity2);
	newExcelExportEntityList.add(newExcelExportEntity3);
	//导出Excel
	ExcelUtil.newExportExcel("导出模板Excel的文件名称", response, newExcelExportEntityList);

4、导入数据

读入上传的Excel文件并解析

封装Excel的基础实体

public class ExcelCisdiEntity extends ExcelBaseEntity {
	
	private String key;
	
    public ExcelCisdiEntity(String name, String key) {
        super.name = name;
        this.key = key;
    }

	public String getKey() {
		return this.key;
	}

	public void setKey(String key) {
		this.key = key;
	}
	
}

读取上传文件

public void upload(MultipartFile file) {
        FileInputStream inputStream;
        try {
            inputStream = (FileInputStream) file.getInputStream();
        } catch (IOException e) {
            log.error(e.getMessage(), e);
            throw new BusinessException("读取文件失败!");
        }
        List<ExcelCisdiEntity> entityList = new ArrayList<ExcelCisdiEntity>();
        entityList.add(new ExcelCisdiEntity("设备编码(必填)", "code"));
        entityList.add(new ExcelCisdiEntity("设备名称(必填)", "name"));
        entityList.add(new ExcelCisdiEntity("供应商编码", "providerCode"));
        entityList.add(new ExcelCisdiEntity("设备类型", "sensorTypeId"));
        entityList.add(new ExcelCisdiEntity("所属组织", "orgId"));
        entityList.add(new ExcelCisdiEntity("设备标签(选填,请用'-'隔开)", "tags"));
        entityList.add(new ExcelCisdiEntity("备注", "remark"));
        List<TestData> list = null;
        try {
            list = ExcelUtil.importExcel(inputStream, entityList, TestData.class);
        } catch (Exception e) {
            log.error(e.getMessage(), e);
            throw new BusinessException("导入文件时解析失败!");
        }
}

list则为解析出的数据,根据自己的业务逻辑对数据进行处理即可。

你可能感兴趣的:(Java,java,poi,excel)