easyexcel-导入(读取)(read)-示例及核心部件

打印 上一主题 下一主题

主题 982|帖子 982|积分 2946

马上注册,结交更多好友,享用更多功能,让你轻松玩转社区。

您需要 登录 才可以下载或查看,没有账号?立即注册

x
这块内容有点多,单独拉出来,要不看着太乱。
导入(读取)(read)-示例及核心部件

代码:
  1. EasyExcel.read(file.getInputStream(), UserExcelVo.class, userListener).extraRead(CellExtraTypeEnum.MERGE)
  2.         .sheet(0) // 指定读取哪个sheet
  3.         .headRowNumber(1) // 指定标题行
  4.         .doRead(); // 执行读取
复制代码
导入(读取)(read)-核心部件

以上面代码为例。
EasyExcel(EasyExcelFactory) # 入口

read() # read()方法用于构建workbook(工作簿)对象,new ExcelReaderBuilder()

  1. public class EasyExcelFactory {
  2.    public static ExcelReaderBuilder read() {
  3.         return new ExcelReaderBuilder();
  4.     }
  5. }
复制代码
  1. public class ExcelReaderBuilder extends AbstractExcelReaderParameterBuilder<ExcelReaderBuilder, ReadWorkbook> {
  2.     /**
  3.      * Workbook
  4.      */
  5.     private final ReadWorkbook readWorkbook;
  6.     public ExcelReaderBuilder() {
  7.         this.readWorkbook = new ReadWorkbook();
  8.     }
  9. }
复制代码
doReadAll()

  1. public class ExcelReaderBuilder extends AbstractExcelReaderParameterBuilder<ExcelReaderBuilder, ReadWorkbook> {
  2.     public void doReadAll() {
  3.         try (ExcelReader excelReader = build()) {
  4.             excelReader.readAll();
  5.         }
  6.     }
  7. }
复制代码
  1. public class ExcelReader implements Closeable {
  2.    public void readAll() {
  3.         excelAnalyser.analysis(null, Boolean.TRUE);
  4.     }
  5. }
复制代码
  1. public class ExcelAnalyserImpl implements ExcelAnalyser {
  2. @Override
  3.     public void analysis(List<ReadSheet> readSheetList, Boolean readAll) {
  4.         try {
  5.             if (!readAll && CollectionUtils.isEmpty(readSheetList)) {
  6.                 throw new IllegalArgumentException("Specify at least one read sheet.");
  7.             }
  8.             analysisContext.readWorkbookHolder().setParameterSheetDataList(readSheetList);
  9.             analysisContext.readWorkbookHolder().setReadAll(readAll);
  10.             try {
  11.                 excelReadExecutor.execute();
  12.             } catch (ExcelAnalysisStopException e) {
  13.                 if (LOGGER.isDebugEnabled()) {
  14.                     LOGGER.debug("Custom stop!");
  15.                 }
  16.             }
  17.         } catch (RuntimeException e) {
  18.             finish();
  19.             throw e;
  20.         } catch (Throwable e) {
  21.             finish();
  22.             throw new ExcelAnalysisException(e);
  23.         }
  24.     }
  25. }
复制代码
这里选XlsxSaxAnalyser这个实现类吧

  1. public class XlsxSaxAnalyser implements ExcelReadExecutor {
  2. @Override
  3.     public void execute() {
  4.         for (ReadSheet readSheet : sheetList) {
  5.             readSheet = SheetUtils.match(readSheet, xlsxReadContext);
  6.             if (readSheet != null) {
  7.                 xlsxReadContext.currentSheet(readSheet);
  8.                 parseXmlSource(sheetMap.get(readSheet.getSheetNo()), new XlsxRowHandler(xlsxReadContext));
  9.                 // Read comments
  10.                 readComments(readSheet);
  11.                 // The last sheet is read
  12.                 xlsxReadContext.analysisEventProcessor().endSheet(xlsxReadContext);
  13.             }
  14.         }
  15.     }
  16. }
复制代码
然后到这个类XlsxRowHandler,这里利用了策略模式,会根据xml差异的标签拿到对应的处置惩罚类来举行处置惩罚。

  1. public class XlsxRowHandler extends DefaultHandler {
  2. static {
  3.         CellFormulaTagHandler cellFormulaTagHandler = new CellFormulaTagHandler();
  4.         XLSX_CELL_HANDLER_MAP.put(ExcelXmlConstants.CELL_FORMULA_TAG, cellFormulaTagHandler);
  5.         XLSX_CELL_HANDLER_MAP.put(ExcelXmlConstants.X_CELL_FORMULA_TAG, cellFormulaTagHandler);
  6.         XLSX_CELL_HANDLER_MAP.put(ExcelXmlConstants.NS2_CELL_FORMULA_TAG, cellFormulaTagHandler);
  7.         CellInlineStringValueTagHandler cellInlineStringValueTagHandler = new CellInlineStringValueTagHandler();
  8.         XLSX_CELL_HANDLER_MAP.put(ExcelXmlConstants.CELL_INLINE_STRING_VALUE_TAG, cellInlineStringValueTagHandler);
  9.         XLSX_CELL_HANDLER_MAP.put(ExcelXmlConstants.X_CELL_INLINE_STRING_VALUE_TAG, cellInlineStringValueTagHandler);
  10.         XLSX_CELL_HANDLER_MAP.put(ExcelXmlConstants.NS2_CELL_INLINE_STRING_VALUE_TAG, cellInlineStringValueTagHandler);
  11.         CellTagHandler cellTagHandler = new CellTagHandler();
  12.         XLSX_CELL_HANDLER_MAP.put(ExcelXmlConstants.CELL_TAG, cellTagHandler);
  13.         XLSX_CELL_HANDLER_MAP.put(ExcelXmlConstants.X_CELL_TAG, cellTagHandler);
  14.         XLSX_CELL_HANDLER_MAP.put(ExcelXmlConstants.NS2_CELL_TAG, cellTagHandler);
  15.         CellValueTagHandler cellValueTagHandler = new CellValueTagHandler();
  16.         XLSX_CELL_HANDLER_MAP.put(ExcelXmlConstants.CELL_VALUE_TAG, cellValueTagHandler);
  17.         XLSX_CELL_HANDLER_MAP.put(ExcelXmlConstants.X_CELL_VALUE_TAG, cellValueTagHandler);
  18.         XLSX_CELL_HANDLER_MAP.put(ExcelXmlConstants.NS2_CELL_VALUE_TAG, cellValueTagHandler);
  19.         CountTagHandler countTagHandler = new CountTagHandler();
  20.         XLSX_CELL_HANDLER_MAP.put(ExcelXmlConstants.DIMENSION_TAG, countTagHandler);
  21.         XLSX_CELL_HANDLER_MAP.put(ExcelXmlConstants.X_DIMENSION_TAG, countTagHandler);
  22.         XLSX_CELL_HANDLER_MAP.put(ExcelXmlConstants.NS2_DIMENSION_TAG, countTagHandler);
  23.         HyperlinkTagHandler hyperlinkTagHandler = new HyperlinkTagHandler();
  24.         XLSX_CELL_HANDLER_MAP.put(ExcelXmlConstants.HYPERLINK_TAG, hyperlinkTagHandler);
  25.         XLSX_CELL_HANDLER_MAP.put(ExcelXmlConstants.X_HYPERLINK_TAG, hyperlinkTagHandler);
  26.         XLSX_CELL_HANDLER_MAP.put(ExcelXmlConstants.NS2_HYPERLINK_TAG, hyperlinkTagHandler);
  27.         MergeCellTagHandler mergeCellTagHandler = new MergeCellTagHandler();
  28.         XLSX_CELL_HANDLER_MAP.put(ExcelXmlConstants.MERGE_CELL_TAG, mergeCellTagHandler);
  29.         XLSX_CELL_HANDLER_MAP.put(ExcelXmlConstants.X_MERGE_CELL_TAG, mergeCellTagHandler);
  30.         XLSX_CELL_HANDLER_MAP.put(ExcelXmlConstants.NS2_MERGE_CELL_TAG, mergeCellTagHandler);
  31.         RowTagHandler rowTagHandler = new RowTagHandler();
  32.         XLSX_CELL_HANDLER_MAP.put(ExcelXmlConstants.ROW_TAG, rowTagHandler);
  33.         XLSX_CELL_HANDLER_MAP.put(ExcelXmlConstants.X_ROW_TAG, rowTagHandler);
  34.         XLSX_CELL_HANDLER_MAP.put(ExcelXmlConstants.NS2_ROW_TAG, rowTagHandler);
  35.     }
  36. }
复制代码
从上面代码找到RowTagHandler这个类,每剖析了一行数据后都会举行处置惩罚

  1. public class RowTagHandler extends AbstractXlsxTagHandler {
  2. @Override
  3.     public void endElement(XlsxReadContext xlsxReadContext, String name) {
  4.         XlsxReadSheetHolder xlsxReadSheetHolder = xlsxReadContext.xlsxReadSheetHolder();
  5.         RowTypeEnum rowType = MapUtils.isEmpty(xlsxReadSheetHolder.getCellMap()) ? RowTypeEnum.EMPTY : RowTypeEnum.DATA;
  6.         // It's possible that all of the cells in the row are empty
  7.         if (rowType == RowTypeEnum.DATA) {
  8.             boolean hasData = false;
  9.             for (Cell cell : xlsxReadSheetHolder.getCellMap().values()) {
  10.                 if (!(cell instanceof ReadCellData)) {
  11.                     hasData = true;
  12.                     break;
  13.                 }
  14.                 ReadCellData<?> readCellData = (ReadCellData<?>)cell;
  15.                 if (readCellData.getType() != CellDataTypeEnum.EMPTY) {
  16.                     hasData = true;
  17.                     break;
  18.                 }
  19.             }
  20.             if (!hasData) {
  21.                 rowType = RowTypeEnum.EMPTY;
  22.             }
  23.         }
  24.         xlsxReadContext.readRowHolder(new ReadRowHolder(xlsxReadSheetHolder.getRowIndex(), rowType,
  25.             xlsxReadSheetHolder.getGlobalConfiguration(), xlsxReadSheetHolder.getCellMap()));
  26.         xlsxReadContext.analysisEventProcessor().endRow(xlsxReadContext);
  27.         xlsxReadSheetHolder.setColumnIndex(null);
  28.         xlsxReadSheetHolder.setCellMap(new LinkedHashMap<>());
  29.     }
  30. }
复制代码
然后看endRow()方法

  1. public class DefaultAnalysisEventProcessor implements AnalysisEventProcessor {
  2.     @Override
  3.     public void endRow(AnalysisContext analysisContext) {
  4.         if (RowTypeEnum.EMPTY.equals(analysisContext.readRowHolder().getRowType())) {
  5.             if (LOGGER.isDebugEnabled()) {
  6.                 LOGGER.debug("Empty row!");
  7.             }
  8.             if (analysisContext.readWorkbookHolder().getIgnoreEmptyRow()) {
  9.                 return;
  10.             }
  11.         }
  12.         dealData(analysisContext);
  13.     }
  14. }
复制代码
进入到dealData方法中

  1. private void dealData(AnalysisContext analysisContext) {
  2.         ReadRowHolder readRowHolder = analysisContext.readRowHolder();
  3.         Map<Integer, ReadCellData<?>> cellDataMap = (Map)readRowHolder.getCellMap();
  4.         readRowHolder.setCurrentRowAnalysisResult(cellDataMap);
  5.         int rowIndex = readRowHolder.getRowIndex();
  6.         int currentHeadRowNumber = analysisContext.readSheetHolder().getHeadRowNumber();
  7.         boolean isData = rowIndex >= currentHeadRowNumber;
  8.         // Last head column
  9.         if (!isData && currentHeadRowNumber == rowIndex + 1) {
  10.             buildHead(analysisContext, cellDataMap);
  11.         }
  12.         // Now is data
  13.         for (ReadListener readListener : analysisContext.currentReadHolder().readListenerList()) {
  14.             try {
  15.                 if (isData) {
  16.                     readListener.invoke(readRowHolder.getCurrentRowAnalysisResult(), analysisContext);
  17.                 } else {
  18.                     readListener.invokeHead(cellDataMap, analysisContext);
  19.                 }
  20.             } catch (Exception e) {
  21.                 onException(analysisContext, e);
  22.                 break;
  23.             }
  24.             if (!readListener.hasNext(analysisContext)) {
  25.                 throw new ExcelAnalysisStopException();
  26.             }
  27.         }
  28.     }
复制代码
这里可以看到,每剖析了一行数据后都会逐个调用监听器的invoke方法(包括easyexcel默认的监听器和我们自定义的监听器)
跟踪invoke()方法,选用ModelBuildEventListener这个实现类吧

进入到ModelBuildEventListener实现类,这个实现类是easyexcel自带的默认的监听器,这个监听器的主要作用是将excel的每行数据封装
  1. public class ModelBuildEventListener implements IgnoreExceptionReadListener<Map<Integer, ReadCellData<?>>> {
  2.     @Override
  3.     public void invoke(Map<Integer, ReadCellData<?>> cellDataMap, AnalysisContext context) {
  4.         ReadSheetHolder readSheetHolder = context.readSheetHolder();
  5.         if (HeadKindEnum.CLASS.equals(readSheetHolder.excelReadHeadProperty().getHeadKind())) {
  6.             context.readRowHolder()
  7.                 .setCurrentRowAnalysisResult(buildUserModel(cellDataMap, readSheetHolder, context));
  8.             return;
  9.         }
  10.         context.readRowHolder().setCurrentRowAnalysisResult(buildNoModel(cellDataMap, readSheetHolder, context));
  11.     }
  12. }
复制代码
进入到buildUserModel方法中

  1. private Object buildUserModel(Map<Integer, ReadCellData<?>> cellDataMap, ReadSheetHolder readSheetHolder,
  2.         AnalysisContext context) {
  3.         ExcelReadHeadProperty excelReadHeadProperty = readSheetHolder.excelReadHeadProperty();
  4.         Object resultModel;
  5.         try {
  6.             resultModel = excelReadHeadProperty.getHeadClazz().newInstance();
  7.         } catch (Exception e) {
  8.             throw new ExcelDataConvertException(context.readRowHolder().getRowIndex(), 0,
  9.                 new ReadCellData<>(CellDataTypeEnum.EMPTY), null,
  10.                 "Can not instance class: " + excelReadHeadProperty.getHeadClazz().getName(), e);
  11.         }
  12.         Map<Integer, Head> headMap = excelReadHeadProperty.getHeadMap();
  13.         BeanMap dataMap = BeanMapUtils.create(resultModel);
  14.         for (Map.Entry<Integer, Head> entry : headMap.entrySet()) {
  15.             Integer index = entry.getKey();
  16.             Head head = entry.getValue();
  17.             String fieldName = head.getFieldName();
  18.             if (!cellDataMap.containsKey(index)) {
  19.                 continue;
  20.             }
  21.             ReadCellData<?> cellData = cellDataMap.get(index);
  22.             Object value = ConverterUtils.convertToJavaObject(cellData, head.getField(),
  23.                 ClassUtils.declaredExcelContentProperty(dataMap, readSheetHolder.excelReadHeadProperty().getHeadClazz(),
  24.                     fieldName, readSheetHolder), readSheetHolder.converterMap(), context,
  25.                 context.readRowHolder().getRowIndex(), index);
  26.             if (value != null) {
  27.                 dataMap.put(fieldName, value);
  28.             }
  29.         }
  30.         return resultModel;
  31.     }
复制代码
可以看到,先是通过反射创建对象,然后根据反射对各个对象赋值。
至此,excel的一行数据就被easyexcel默认的监听器剖析成了对应的java对象,然后我们在自定义的监听器中就能拿到这个对象并举行处置惩罚了。

免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。
回复

使用道具 举报

0 个回复

倒序浏览

快速回复

您需要登录后才可以回帖 登录 or 立即注册

本版积分规则

耶耶耶耶耶

金牌会员
这个人很懒什么都没写!
快速回复 返回顶部 返回列表