easyexcel 是阿里开源的一款 Excel导入导出器具巨屌 porn,具有科罚速率快、占用内存小、使用八成的特色,底层逻辑亦然基于 apache poi 进行二次诞生的,当今的诈欺也长短常广!
代码实战1、pom.xml依赖引入
<dependency> <groupId>com.alibaba</groupId> <artifactId>easyexcel</artifactId> <version>3.0.5</version> </dependency>
导出导入复旧两种阵势
实体类注解阵势来生成文献和反暴露文献数据映射成对象
动态参数化生成文献和反暴露文献数据
2、纯粹导入、导出
老色哥首发2.1、创建UserWriteEntity实体类
public class UserWriteEntity { @ExcelProperty(value = "姓名") private String name; @ExcelProperty(value = "年齿") private int age; @DateTimeFormat("yyyy-MM-dd HH:mm:ss") @ExcelProperty(value = "操作时辰") private Date time; //set、get... }
2.2、导出代码
public static void main(String[] args) throws FileNotFoundException { List<UserWriteEntity> dataList = new ArrayList<>(); for (int i = 0; i < 10; i++) { UserWriteEntity userEntity = new UserWriteEntity(); userEntity.setName("张三" + i); userEntity.setAge(20 + i); userEntity.setTime(new Date(System.currentTimeMillis() + i)); dataList.add(userEntity); } //界说文献输出位置 FileOutputStream outputStream = new FileOutputStream(new File("/export-user.xlsx")); EasyExcel.write(outputStream, UserWriteEntity.class).sheet("用户信息").doWrite(dataList); }
2.3、导出截止
图片
2.4、导入代码
/** * 读取实体类 */ public class UserReadEntity { @ExcelProperty(value = "姓名") private String name; /** * 强制读取第三个 这里不漠视 index 和 name 同期用,要么一个对象只用index,要么一个对象只用name去匹配 */ @ExcelProperty(index = 1) private int age; @DateTimeFormat("yyyy-MM-dd HH:mm:ss") @ExcelProperty(value = "操作时辰") private Date time; //set、get... }
public static void main(String[] args) throws FileNotFoundException { //同步读取文献内容 FileInputStream inputStream = new FileInputStream(new File("/Users/panzhi/Documents/easyexcel-user1.xls")); List<UserReadEntity> list = EasyExcel.read(inputStream).head(UserReadEntity.class).sheet().doReadSync(); System.out.println(JSONArray.toJSONString(list)); }
输出音信
[{"age":20,"name":"张三0","time":1616920360000},{"age":21,"name":"张三1","time":1616920360000},{"age":22,"name":"张三2","time":1616920360000},{"age":23,"name":"张三3","time":1616920360000},{"age":24,"name":"张三4","time":1616920360000},{"age":25,"name":"张三5","time":1616920360000},{"age":26,"name":"张三6","time":1616920360000},{"age":27,"name":"张三7","time":1616920360000},{"age":28,"name":"张三8","time":1616920360000},{"age":29,"name":"张三9","time":1616920360000}]
3、动态导出、导入
好多业务需求,需要凭据不同的字段来动态导入导出,没见识基于实体类注解的阵势来读取文献或者写入文献。因此,基于EasyExcel提供的动态参数化生成文献和动态监听器读取文献设施!
3.1、导出器具类
public class DynamicEasyExcelExportUtils { private static final Logger log = LoggerFactory.getLogger(DynamicEasyExcelExportUtils.class); private static final String DEFAULT_SHEET_NAME = "sheet1"; /** * 动态生成导出模版(单表头) * @param headColumns 列称号 * @return excel文献流 */ public static byte[] exportTemplateExcelFile(List<String> headColumns){ List<List<String>> excelHead = Lists.newArrayList(); headColumns.forEach(columnName -> { excelHead.add(Lists.newArrayList(columnName)); }); byte[] stream = createExcelFile(excelHead, new ArrayList<>()); return stream; } /** * 动态生成模版(复杂表头) * @param excelHead 列称号 * @return */ public static byte[] exportTemplateExcelFileCustomHead(List<List<String>> excelHead){ byte[] stream = createExcelFile(excelHead, new ArrayList<>()); return stream; } /** * 动态导出文献(通过map阵势筹算) * @param headColumnMap 有序列头部 * @param dataList 数据体 * @return */ public static byte[] exportExcelFile(LinkedHashMap<String, String> headColumnMap, List<Map<String, Object>> dataList){ //得回列称号 List<List<String>> excelHead = new ArrayList<>(); if(MapUtils.isNotEmpty(headColumnMap)){ //key为匹配符,value为列名,若是多级列名用逗号离隔 headColumnMap.entrySet().forEach(entry -> { excelHead.add(Lists.newArrayList(entry.getValue().split(","))); }); } List<List<Object>> excelRows = new ArrayList<>(); if(MapUtils.isNotEmpty(headColumnMap) && CollectionUtils.isNotEmpty(dataList)){ for (Map<String, Object> dataMap : dataList) { List<Object> rows = new ArrayList<>(); headColumnMap.entrySet().forEach(headColumnEntry -> { if(dataMap.containsKey(headColumnEntry.getKey())){ Object data = dataMap.get(headColumnEntry.getKey()); rows.add(data); } }); excelRows.add(rows); } } byte[] stream = createExcelFile(excelHead, excelRows); return stream; } /** * 生成文献(自界说头部陈设) * @param rowHeads * @param excelRows * @return */ public static byte[] customerExportExcelFile(List<List<String>> rowHeads, List<List<Object>> excelRows){ //将行头部转成easyexcel能识别的部分 List<List<String>> excelHead = transferHead(rowHeads); return createExcelFile(excelHead, excelRows); } /** * 生成文献 * @param excelHead * @param excelRows * @return */ private static byte[] createExcelFile(List<List<String>> excelHead, List<List<Object>> excelRows){ try { if(CollectionUtils.isNotEmpty(excelHead)){ ByteArrayOutputStream outputStream = new ByteArrayOutputStream(); EasyExcel.write(outputStream).registerWriteHandler(new LongestMatchColumnWidthStyleStrategy()) .head(excelHead) .sheet(DEFAULT_SHEET_NAME) .doWrite(excelRows); return outputStream.toByteArray(); } } catch (Exception e) { log.error("动态生成excel文献失败,headColumns:" + JSONArray.toJSONString(excelHead) + ",excelRows:" + JSONArray.toJSONString(excelRows), e); } return null; } /** * 将行头部转成easyexcel能识别的部分 * @param rowHeads * @return */ public static List<List<String>> transferHead(List<List<String>> rowHeads){ //将头部列进行回转 List<List<String>> realHead = new ArrayList<>(); if(CollectionUtils.isNotEmpty(rowHeads)){ Map<Integer, List<String>> cellMap = new LinkedHashMap<>(); //遍历行 for (List<String> cells : rowHeads) { //遍历列 for (int i = 0; i < cells.size(); i++) { if(cellMap.containsKey(i)){ cellMap.get(i).add(cells.get(i)); } else { cellMap.put(i, Lists.newArrayList(cells.get(i))); } } } //将列一转一转加入realHead cellMap.entrySet().forEach(item -> realHead.add(item.getValue())); } return realHead; } /** * 导出文献测试 * @param args * @throws IOException */ public static void main(String[] args) throws IOException { //导出包含数据内容的文献(阵势一) LinkedHashMap<String, String> headColumnMap = Maps.newLinkedHashMap(); headColumnMap.put("className","班级"); headColumnMap.put("name","学生信息,姓名"); headColumnMap.put("sex","学生信息,性别"); List<Map<String, Object>> dataList = new ArrayList<>(); for (int i = 0; i < 5; i++) { Map<String, Object> dataMap = Maps.newHashMap(); dataMap.put("className", "一年级"); dataMap.put("name", "张三" + i); dataMap.put("sex", "男"); dataList.add(dataMap); } byte[] stream1 = exportExcelFile(headColumnMap, dataList); FileOutputStream outputStream1 = new FileOutputStream(new File("/Users/panzhi/Documents/easyexcel-export-user5.xlsx")); outputStream1.write(stream1); outputStream1.close(); //导出包含数据内容的文献(阵势二) //头部,第一层 List<String> head1 = new ArrayList<>(); head1.add("第一记忆部列1"); head1.add("第一记忆部列1"); head1.add("第一记忆部列1"); head1.add("第一记忆部列1"); //头部,第二层 List<String> head2 = new ArrayList<>(); head2.add("第二行头部列1"); head2.add("第二行头部列1"); head2.add("第二行头部列2"); head2.add("第二行头部列2"); //头部,第三层 List<String> head3 = new ArrayList<>(); head3.add("第三行头部列1"); head3.add("第三行头部列2"); head3.add("第三行头部列3"); head3.add("第三行头部列4"); //封装头部 List<List<String>> allHead = new ArrayList<>(); allHead.add(head1); allHead.add(head2); allHead.add(head3); //封装数据体 //第一转数据 List<Object> data1 = Lists.newArrayList(1,1,1,1); //第二行数据 List<Object> data2 = Lists.newArrayList(2,2,2,2); List<List<Object>> allData = Lists.newArrayList(data1, data2); byte[] stream2 = customerExportExcelFile(allHead, allData); FileOutputStream outputStream2 = new FileOutputStream(new File("/Users/panzhi/Documents/easyexcel-export-user6.xlsx")); outputStream2.write(stream2); outputStream2.close(); } }
3.2、动态导入器具
/** * 创建一个文献读取监听器 */ public class DynamicEasyExcelListener extends AnalysisEventListener<Map<Integer, String>> { private static final Logger LOGGER = LoggerFactory.getLogger(UserDataListener.class); /** * 表头数据(存储通盘的表头数据) */ private List<Map<Integer, String>> headList = new ArrayList<>(); /** * 数据体 */ private List<Map<Integer, String>> dataList = new ArrayList<>(); /** * 这里会一转行的复返头 * * @param headMap * @param context */ @Override public void invokeHeadMap(Map<Integer, String> headMap, AnalysisContext context) { LOGGER.info("暴露到一条头数据:{}", JSON.toJSONString(headMap)); //存储一起表头数据 headList.add(headMap); } /** * 这个每一条数据暴露王人会来调用 * * @param data * one row value. Is is same as {@link AnalysisContext#readRowHolder()} * @param context */ @Override public void invoke(Map<Integer, String> data, AnalysisContext context) { LOGGER.info("暴露到一条数据:{}", JSON.toJSONString(data)); dataList.add(data); } /** * 所少见据暴露完成了 王人会来调用 * * @param context */ @Override public void doAfterAllAnalysed(AnalysisContext context) { // 这里也要保存数据,确保终末留传的数据也存储到数据库 LOGGER.info("所少见据暴露完成!"); } public List<Map<Integer, String>> getHeadList() { return headList; } public List<Map<Integer, String>> getDataList() { return dataList; } }
/** * 编写导入器具类 */ public class DynamicEasyExcelImportUtils { /** * 动态得回一起列和数据体,默许从第一转初始暴露数据 * @param stream * @return */ public static List<Map<String,String>> parseExcelToView(byte[] stream) { return parseExcelToView(stream, 1); } /** * 动态得回一起列和数据体 * @param stream excel文献流 * @param parseRowNumber 指定读取行 * @return */ public static List<Map<String,String>> parseExcelToView(byte[] stream, Integer parseRowNumber) { DynamicEasyExcelListener readListener = new DynamicEasyExcelListener(); EasyExcelFactory.read(new ByteArrayInputStream(stream)).registerReadListener(readListener).headRowNumber(parseRowNumber).sheet(0).doRead(); List<Map<Integer, String>> headList = readListener.getHeadList(); if(CollectionUtils.isEmpty(headList)){ throw new RuntimeException("Excel未包含表头"); } List<Map<Integer, String>> dataList = readListener.getDataList(); if(CollectionUtils.isEmpty(dataList)){ throw new RuntimeException("Excel未包含数据"); } //得回头部,取终末一次暴露的列头数据 Map<Integer, String> excelHeadIdxNameMap = headList.get(headList.size() -1); //封装数据体 List<Map<String,String>> excelDataList = Lists.newArrayList(); for (Map<Integer, String> dataRow : dataList) { Map<String,String> rowData = new LinkedHashMap<>(); excelHeadIdxNameMap.entrySet().forEach(columnHead -> { rowData.put(columnHead.getValue(), dataRow.get(columnHead.getKey())); }); excelDataList.add(rowData); } return excelDataList; } /** * 文献导入测试 * @param args * @throws IOException */ public static void main(String[] args) throws IOException { FileInputStream inputStream = new FileInputStream(new File("/Users/panzhi/Documents/easyexcel-export-user5.xlsx")); byte[] stream = IoUtils.toByteArray(inputStream); List<Map<String,String>> dataList = parseExcelToView(stream, 2); System.out.println(JSONArray.toJSONString(dataList)); inputStream.close(); } }
小结
在骨子的业务诞生经过中,凭据参数动态罢了 Excel 的导出导入还长短常广的。
本站仅提供存储就业,通盘内容均由用户发布,如发现存害或侵权内容,请点击举报。