马上注册,结交更多好友,享用更多功能,让你轻松玩转社区。
您需要 登录 才可以下载或查看,没有账号?立即注册
x
这块内容有点多,单独拉出来,要不看着太乱。
导入(读取)(read)-示例及核心部件
代码:
- EasyExcel.read(file.getInputStream(), UserExcelVo.class, userListener).extraRead(CellExtraTypeEnum.MERGE)
- .sheet(0) // 指定读取哪个sheet
- .headRowNumber(1) // 指定标题行
- .doRead(); // 执行读取
复制代码 导入(读取)(read)-核心部件
以上面代码为例。
EasyExcel(EasyExcelFactory) # 入口
read() # read()方法用于构建workbook(工作簿)对象,new ExcelReaderBuilder()
- public class EasyExcelFactory {
- public static ExcelReaderBuilder read() {
- return new ExcelReaderBuilder();
- }
- }
复制代码- public class ExcelReaderBuilder extends AbstractExcelReaderParameterBuilder<ExcelReaderBuilder, ReadWorkbook> {
- /**
- * Workbook
- */
- private final ReadWorkbook readWorkbook;
- public ExcelReaderBuilder() {
- this.readWorkbook = new ReadWorkbook();
- }
- }
复制代码 doReadAll()
- public class ExcelReaderBuilder extends AbstractExcelReaderParameterBuilder<ExcelReaderBuilder, ReadWorkbook> {
- public void doReadAll() {
- try (ExcelReader excelReader = build()) {
- excelReader.readAll();
- }
- }
- }
复制代码- public class ExcelReader implements Closeable {
- public void readAll() {
- excelAnalyser.analysis(null, Boolean.TRUE);
- }
- }
复制代码- public class ExcelAnalyserImpl implements ExcelAnalyser {
- @Override
- public void analysis(List<ReadSheet> readSheetList, Boolean readAll) {
- try {
- if (!readAll && CollectionUtils.isEmpty(readSheetList)) {
- throw new IllegalArgumentException("Specify at least one read sheet.");
- }
- analysisContext.readWorkbookHolder().setParameterSheetDataList(readSheetList);
- analysisContext.readWorkbookHolder().setReadAll(readAll);
- try {
- excelReadExecutor.execute();
- } catch (ExcelAnalysisStopException e) {
- if (LOGGER.isDebugEnabled()) {
- LOGGER.debug("Custom stop!");
- }
- }
- } catch (RuntimeException e) {
- finish();
- throw e;
- } catch (Throwable e) {
- finish();
- throw new ExcelAnalysisException(e);
- }
- }
- }
复制代码 这里选XlsxSaxAnalyser这个实现类吧
- public class XlsxSaxAnalyser implements ExcelReadExecutor {
- @Override
- public void execute() {
- for (ReadSheet readSheet : sheetList) {
- readSheet = SheetUtils.match(readSheet, xlsxReadContext);
- if (readSheet != null) {
- xlsxReadContext.currentSheet(readSheet);
- parseXmlSource(sheetMap.get(readSheet.getSheetNo()), new XlsxRowHandler(xlsxReadContext));
- // Read comments
- readComments(readSheet);
- // The last sheet is read
- xlsxReadContext.analysisEventProcessor().endSheet(xlsxReadContext);
- }
- }
- }
- }
复制代码 然后到这个类XlsxRowHandler,这里利用了策略模式,会根据xml差异的标签拿到对应的处置惩罚类来举行处置惩罚。
- public class XlsxRowHandler extends DefaultHandler {
- static {
- CellFormulaTagHandler cellFormulaTagHandler = new CellFormulaTagHandler();
- XLSX_CELL_HANDLER_MAP.put(ExcelXmlConstants.CELL_FORMULA_TAG, cellFormulaTagHandler);
- XLSX_CELL_HANDLER_MAP.put(ExcelXmlConstants.X_CELL_FORMULA_TAG, cellFormulaTagHandler);
- XLSX_CELL_HANDLER_MAP.put(ExcelXmlConstants.NS2_CELL_FORMULA_TAG, cellFormulaTagHandler);
- CellInlineStringValueTagHandler cellInlineStringValueTagHandler = new CellInlineStringValueTagHandler();
- XLSX_CELL_HANDLER_MAP.put(ExcelXmlConstants.CELL_INLINE_STRING_VALUE_TAG, cellInlineStringValueTagHandler);
- XLSX_CELL_HANDLER_MAP.put(ExcelXmlConstants.X_CELL_INLINE_STRING_VALUE_TAG, cellInlineStringValueTagHandler);
- XLSX_CELL_HANDLER_MAP.put(ExcelXmlConstants.NS2_CELL_INLINE_STRING_VALUE_TAG, cellInlineStringValueTagHandler);
- CellTagHandler cellTagHandler = new CellTagHandler();
- XLSX_CELL_HANDLER_MAP.put(ExcelXmlConstants.CELL_TAG, cellTagHandler);
- XLSX_CELL_HANDLER_MAP.put(ExcelXmlConstants.X_CELL_TAG, cellTagHandler);
- XLSX_CELL_HANDLER_MAP.put(ExcelXmlConstants.NS2_CELL_TAG, cellTagHandler);
- CellValueTagHandler cellValueTagHandler = new CellValueTagHandler();
- XLSX_CELL_HANDLER_MAP.put(ExcelXmlConstants.CELL_VALUE_TAG, cellValueTagHandler);
- XLSX_CELL_HANDLER_MAP.put(ExcelXmlConstants.X_CELL_VALUE_TAG, cellValueTagHandler);
- XLSX_CELL_HANDLER_MAP.put(ExcelXmlConstants.NS2_CELL_VALUE_TAG, cellValueTagHandler);
- CountTagHandler countTagHandler = new CountTagHandler();
- XLSX_CELL_HANDLER_MAP.put(ExcelXmlConstants.DIMENSION_TAG, countTagHandler);
- XLSX_CELL_HANDLER_MAP.put(ExcelXmlConstants.X_DIMENSION_TAG, countTagHandler);
- XLSX_CELL_HANDLER_MAP.put(ExcelXmlConstants.NS2_DIMENSION_TAG, countTagHandler);
- HyperlinkTagHandler hyperlinkTagHandler = new HyperlinkTagHandler();
- XLSX_CELL_HANDLER_MAP.put(ExcelXmlConstants.HYPERLINK_TAG, hyperlinkTagHandler);
- XLSX_CELL_HANDLER_MAP.put(ExcelXmlConstants.X_HYPERLINK_TAG, hyperlinkTagHandler);
- XLSX_CELL_HANDLER_MAP.put(ExcelXmlConstants.NS2_HYPERLINK_TAG, hyperlinkTagHandler);
- MergeCellTagHandler mergeCellTagHandler = new MergeCellTagHandler();
- XLSX_CELL_HANDLER_MAP.put(ExcelXmlConstants.MERGE_CELL_TAG, mergeCellTagHandler);
- XLSX_CELL_HANDLER_MAP.put(ExcelXmlConstants.X_MERGE_CELL_TAG, mergeCellTagHandler);
- XLSX_CELL_HANDLER_MAP.put(ExcelXmlConstants.NS2_MERGE_CELL_TAG, mergeCellTagHandler);
- RowTagHandler rowTagHandler = new RowTagHandler();
- XLSX_CELL_HANDLER_MAP.put(ExcelXmlConstants.ROW_TAG, rowTagHandler);
- XLSX_CELL_HANDLER_MAP.put(ExcelXmlConstants.X_ROW_TAG, rowTagHandler);
- XLSX_CELL_HANDLER_MAP.put(ExcelXmlConstants.NS2_ROW_TAG, rowTagHandler);
- }
- }
复制代码 从上面代码找到RowTagHandler这个类,每剖析了一行数据后都会举行处置惩罚
- public class RowTagHandler extends AbstractXlsxTagHandler {
- @Override
- public void endElement(XlsxReadContext xlsxReadContext, String name) {
- XlsxReadSheetHolder xlsxReadSheetHolder = xlsxReadContext.xlsxReadSheetHolder();
- RowTypeEnum rowType = MapUtils.isEmpty(xlsxReadSheetHolder.getCellMap()) ? RowTypeEnum.EMPTY : RowTypeEnum.DATA;
- // It's possible that all of the cells in the row are empty
- if (rowType == RowTypeEnum.DATA) {
- boolean hasData = false;
- for (Cell cell : xlsxReadSheetHolder.getCellMap().values()) {
- if (!(cell instanceof ReadCellData)) {
- hasData = true;
- break;
- }
- ReadCellData<?> readCellData = (ReadCellData<?>)cell;
- if (readCellData.getType() != CellDataTypeEnum.EMPTY) {
- hasData = true;
- break;
- }
- }
- if (!hasData) {
- rowType = RowTypeEnum.EMPTY;
- }
- }
- xlsxReadContext.readRowHolder(new ReadRowHolder(xlsxReadSheetHolder.getRowIndex(), rowType,
- xlsxReadSheetHolder.getGlobalConfiguration(), xlsxReadSheetHolder.getCellMap()));
- xlsxReadContext.analysisEventProcessor().endRow(xlsxReadContext);
- xlsxReadSheetHolder.setColumnIndex(null);
- xlsxReadSheetHolder.setCellMap(new LinkedHashMap<>());
- }
- }
复制代码 然后看endRow()方法
- public class DefaultAnalysisEventProcessor implements AnalysisEventProcessor {
- @Override
- public void endRow(AnalysisContext analysisContext) {
- if (RowTypeEnum.EMPTY.equals(analysisContext.readRowHolder().getRowType())) {
- if (LOGGER.isDebugEnabled()) {
- LOGGER.debug("Empty row!");
- }
- if (analysisContext.readWorkbookHolder().getIgnoreEmptyRow()) {
- return;
- }
- }
- dealData(analysisContext);
- }
- }
复制代码 进入到dealData方法中
- private void dealData(AnalysisContext analysisContext) {
- ReadRowHolder readRowHolder = analysisContext.readRowHolder();
- Map<Integer, ReadCellData<?>> cellDataMap = (Map)readRowHolder.getCellMap();
- readRowHolder.setCurrentRowAnalysisResult(cellDataMap);
- int rowIndex = readRowHolder.getRowIndex();
- int currentHeadRowNumber = analysisContext.readSheetHolder().getHeadRowNumber();
- boolean isData = rowIndex >= currentHeadRowNumber;
- // Last head column
- if (!isData && currentHeadRowNumber == rowIndex + 1) {
- buildHead(analysisContext, cellDataMap);
- }
- // Now is data
- for (ReadListener readListener : analysisContext.currentReadHolder().readListenerList()) {
- try {
- if (isData) {
- readListener.invoke(readRowHolder.getCurrentRowAnalysisResult(), analysisContext);
- } else {
- readListener.invokeHead(cellDataMap, analysisContext);
- }
- } catch (Exception e) {
- onException(analysisContext, e);
- break;
- }
- if (!readListener.hasNext(analysisContext)) {
- throw new ExcelAnalysisStopException();
- }
- }
- }
复制代码 这里可以看到,每剖析了一行数据后都会逐个调用监听器的invoke方法(包括easyexcel默认的监听器和我们自定义的监听器)
跟踪invoke()方法,选用ModelBuildEventListener这个实现类吧
进入到ModelBuildEventListener实现类,这个实现类是easyexcel自带的默认的监听器,这个监听器的主要作用是将excel的每行数据封装
- public class ModelBuildEventListener implements IgnoreExceptionReadListener<Map<Integer, ReadCellData<?>>> {
- @Override
- public void invoke(Map<Integer, ReadCellData<?>> cellDataMap, AnalysisContext context) {
- ReadSheetHolder readSheetHolder = context.readSheetHolder();
- if (HeadKindEnum.CLASS.equals(readSheetHolder.excelReadHeadProperty().getHeadKind())) {
- context.readRowHolder()
- .setCurrentRowAnalysisResult(buildUserModel(cellDataMap, readSheetHolder, context));
- return;
- }
- context.readRowHolder().setCurrentRowAnalysisResult(buildNoModel(cellDataMap, readSheetHolder, context));
- }
- }
复制代码 进入到buildUserModel方法中
- private Object buildUserModel(Map<Integer, ReadCellData<?>> cellDataMap, ReadSheetHolder readSheetHolder,
- AnalysisContext context) {
- ExcelReadHeadProperty excelReadHeadProperty = readSheetHolder.excelReadHeadProperty();
- Object resultModel;
- try {
- resultModel = excelReadHeadProperty.getHeadClazz().newInstance();
- } catch (Exception e) {
- throw new ExcelDataConvertException(context.readRowHolder().getRowIndex(), 0,
- new ReadCellData<>(CellDataTypeEnum.EMPTY), null,
- "Can not instance class: " + excelReadHeadProperty.getHeadClazz().getName(), e);
- }
- Map<Integer, Head> headMap = excelReadHeadProperty.getHeadMap();
- BeanMap dataMap = BeanMapUtils.create(resultModel);
- for (Map.Entry<Integer, Head> entry : headMap.entrySet()) {
- Integer index = entry.getKey();
- Head head = entry.getValue();
- String fieldName = head.getFieldName();
- if (!cellDataMap.containsKey(index)) {
- continue;
- }
- ReadCellData<?> cellData = cellDataMap.get(index);
- Object value = ConverterUtils.convertToJavaObject(cellData, head.getField(),
- ClassUtils.declaredExcelContentProperty(dataMap, readSheetHolder.excelReadHeadProperty().getHeadClazz(),
- fieldName, readSheetHolder), readSheetHolder.converterMap(), context,
- context.readRowHolder().getRowIndex(), index);
- if (value != null) {
- dataMap.put(fieldName, value);
- }
- }
- return resultModel;
- }
复制代码 可以看到,先是通过反射创建对象,然后根据反射对各个对象赋值。
至此,excel的一行数据就被easyexcel默认的监听器剖析成了对应的java对象,然后我们在自定义的监听器中就能拿到这个对象并举行处置惩罚了。
免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。 |