package com.alibaba.excel.read.metadata.holder; import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; import com.alibaba.excel.context.AnalysisContext; import com.alibaba.excel.converters.Converter; import com.alibaba.excel.converters.ConverterKeyBuild; import com.alibaba.excel.converters.DefaultConverterLoader; import com.alibaba.excel.enums.CellDataTypeEnum; import com.alibaba.excel.enums.HeadKindEnum; import com.alibaba.excel.enums.HolderEnum; import com.alibaba.excel.event.AnalysisEventListener; import com.alibaba.excel.exception.ExcelAnalysisException; import com.alibaba.excel.exception.ExcelDataConvertException; import com.alibaba.excel.metadata.AbstractHolder; import com.alibaba.excel.metadata.CellData; import com.alibaba.excel.metadata.Head; import com.alibaba.excel.metadata.property.ExcelContentProperty; import com.alibaba.excel.read.listener.ModelBuildEventListener; import com.alibaba.excel.read.listener.ReadListener; import com.alibaba.excel.read.listener.ReadListenerRegistryCenter; import com.alibaba.excel.read.listener.event.AnalysisFinishEvent; import com.alibaba.excel.read.metadata.ReadBasicParameter; import com.alibaba.excel.read.metadata.property.ExcelReadHeadProperty; import com.alibaba.excel.util.StringUtils; /** * Read Holder * * @author zhuangjiaju */ public abstract class AbstractReadHolder extends AbstractHolder implements ReadHolder, ReadListenerRegistryCenter { /** * Count the number of added heads when read sheet. * *
  • 0 - This Sheet has no head ,since the first row are the data *
  • 1 - This Sheet has one row head , this is the default *
  • 2 - This Sheet has two row head ,since the third row is the data */ private Integer headRowNumber; /** * Excel head property */ private ExcelReadHeadProperty excelReadHeadProperty; /** * Read listener */ private List readListenerList; public AbstractReadHolder(ReadBasicParameter readBasicParameter, AbstractReadHolder parentAbstractReadHolder, Boolean convertAllFiled) { super(readBasicParameter, parentAbstractReadHolder); if (readBasicParameter.getUse1904windowing() == null && parentAbstractReadHolder != null) { getGlobalConfiguration() .setUse1904windowing(parentAbstractReadHolder.getGlobalConfiguration().getUse1904windowing()); } else { getGlobalConfiguration().setUse1904windowing(readBasicParameter.getUse1904windowing()); } // Initialization property this.excelReadHeadProperty = new ExcelReadHeadProperty(getClazz(), getHead(), convertAllFiled); if (readBasicParameter.getHeadRowNumber() == null) { if (parentAbstractReadHolder == null) { if (excelReadHeadProperty.hasHead()) { this.headRowNumber = excelReadHeadProperty.getHeadRowNumber(); } else { this.headRowNumber = 1; } } else { this.headRowNumber = parentAbstractReadHolder.getHeadRowNumber(); } } else { this.headRowNumber = readBasicParameter.getHeadRowNumber(); } if (parentAbstractReadHolder == null) { this.readListenerList = new ArrayList(); } else { this.readListenerList = new ArrayList(parentAbstractReadHolder.getReadListenerList()); } if (HolderEnum.WORKBOOK.equals(holderType())) { readListenerList.add(new ModelBuildEventListener()); } if (readBasicParameter.getCustomReadListenerList() != null && !readBasicParameter.getCustomReadListenerList().isEmpty()) { this.readListenerList.addAll(readBasicParameter.getCustomReadListenerList()); } if (parentAbstractReadHolder == null) { setConverterMap(DefaultConverterLoader.loadDefaultReadConverter()); } else { setConverterMap(new HashMap(parentAbstractReadHolder.getConverterMap())); } if (readBasicParameter.getCustomConverterList() != null && !readBasicParameter.getCustomConverterList().isEmpty()) { for (Converter converter : readBasicParameter.getCustomConverterList()) { getConverterMap().put( ConverterKeyBuild.buildKey(converter.supportJavaTypeKey(), converter.supportExcelTypeKey()), converter); } } } @Override public void register(AnalysisEventListener listener) { readListenerList.add(listener); } @Override public void notifyEndOneRow(AnalysisFinishEvent event, AnalysisContext analysisContext) { Map cellDataMap = event.getAnalysisResult(); ReadRowHolder readRowHolder = analysisContext.readRowHolder(); readRowHolder.setCurrentRowAnalysisResult(cellDataMap); if (readRowHolder.getRowIndex() >= analysisContext.readSheetHolder().getHeadRowNumber()) { for (ReadListener readListener : analysisContext.currentReadHolder().readListenerList()) { try { readListener.invoke(readRowHolder.getCurrentRowAnalysisResult(), analysisContext); } catch (Exception e) { for (ReadListener readListenerException : analysisContext.currentReadHolder().readListenerList()) { try { readListenerException.onException(e, analysisContext); } catch (Exception exception) { throw new ExcelAnalysisException("Listen error!", exception); } } } } return; } // Now is header if (analysisContext.readSheetHolder().getHeadRowNumber().equals(readRowHolder.getRowIndex() + 1)) { buildHead(analysisContext, cellDataMap); } } @Override public void notifyAfterAllAnalysed(AnalysisContext analysisContext) { for (ReadListener readListener : readListenerList) { readListener.doAfterAllAnalysed(analysisContext); } } private void buildHead(AnalysisContext analysisContext, Map cellDataMap) { if (!HeadKindEnum.CLASS.equals(analysisContext.currentReadHolder().excelReadHeadProperty().getHeadKind())) { return; } Map dataMap = buildStringMap(cellDataMap, analysisContext.currentReadHolder()); ExcelReadHeadProperty excelHeadPropertyData = analysisContext.readSheetHolder().excelReadHeadProperty(); Map headMapData = excelHeadPropertyData.getHeadMap(); Map contentPropertyMapData = excelHeadPropertyData.getContentPropertyMap(); Map tmpHeadMap = new HashMap(headMapData.size() * 4 / 3 + 1); Map tmpContentPropertyMap = new HashMap(contentPropertyMapData.size() * 4 / 3 + 1); for (Map.Entry entry : headMapData.entrySet()) { Head headData = entry.getValue(); if (headData.getForceIndex() || !headData.getForceName()) { tmpHeadMap.put(entry.getKey(), headData); tmpContentPropertyMap.put(entry.getKey(), contentPropertyMapData.get(entry.getKey())); continue; } String headName = headData.getHeadNameList().get(0); for (Map.Entry stringEntry : dataMap.entrySet()) { String headString = stringEntry.getValue(); Integer stringKey = stringEntry.getKey(); if (StringUtils.isEmpty(headString)) { continue; } if (analysisContext.currentReadHolder().globalConfiguration().getAutoTrim()) { headString = headString.trim(); } if (headName.equals(headString)) { headData.setColumnIndex(stringKey); tmpHeadMap.put(stringKey, headData); tmpContentPropertyMap.put(stringKey, contentPropertyMapData.get(entry.getKey())); break; } } } excelHeadPropertyData.setHeadMap(tmpHeadMap); excelHeadPropertyData.setContentPropertyMap(tmpContentPropertyMap); } private Map buildStringMap(Map cellDataMap, ReadHolder readHolder) { Map stringMap = new HashMap(cellDataMap.size() * 4 / 3 + 1); for (Map.Entry entry : cellDataMap.entrySet()) { CellData cellData = entry.getValue(); if (cellData.getType() == CellDataTypeEnum.EMPTY) { stringMap.put(entry.getKey(), null); continue; } Converter converter = readHolder.converterMap().get(ConverterKeyBuild.buildKey(String.class, cellData.getType())); if (converter == null) { throw new ExcelDataConvertException( "Converter not found, convert " + cellData.getType() + " to String"); } try { stringMap.put(entry.getKey(), (String)(converter.convertToJavaData(cellData, null, readHolder.globalConfiguration()))); } catch (Exception e) { throw new ExcelDataConvertException("Convert data " + cellData + " to String error ", e); } } return stringMap; } public List getReadListenerList() { return readListenerList; } public void setReadListenerList(List readListenerList) { this.readListenerList = readListenerList; } public ExcelReadHeadProperty getExcelReadHeadProperty() { return excelReadHeadProperty; } public void setExcelReadHeadProperty(ExcelReadHeadProperty excelReadHeadProperty) { this.excelReadHeadProperty = excelReadHeadProperty; } public Integer getHeadRowNumber() { return headRowNumber; } public void setHeadRowNumber(Integer headRowNumber) { this.headRowNumber = headRowNumber; } @Override public List readListenerList() { return getReadListenerList(); } @Override public ExcelReadHeadProperty excelReadHeadProperty() { return getExcelReadHeadProperty(); } }