通过Sax方式读取Excel，同时支持03和07格式

@param file Excel文件
@param sheetIndex sheet序号
@param rowHandler 行处理器
@since 3.2.0
762442
public static void readBySax(File file, int sheetIndex, RowHandler rowHandler) {
		BufferedInputStream in = null;
		try {
			in = FileUtil.getInputStream(file);
			readBySax(in, sheetIndex, rowHandler);
		} finally {
			IoUtil.close(in);
		}
	}
217468
public static void checkArrayColumns(final Sheet sheet, final Class<?> recordClass,
            final List<RecordHeader> headers, final AnnotationReader reader, final Configuration config) {
        
        List<FieldAccessor> properties = FieldAccessorUtils.getPropertiesWithAnnotation(recordClass, reader, XlsArrayColumns.class);
        
        for(FieldAccessor property : properties) {
            final XlsArrayColumns arrayColumns = property.getAnnotation(XlsArrayColumns.class).get();
            if(arrayColumns.optional()) {
                continue;
            }
            
            final String columnName = arrayColumns.columnName();
            boolean found = headers.stream()
                .filter(info -> Utils.matches(info.getLabel(), columnName, config))
                .findFirst()
                .isPresent();
            
            if(!found) {
                throw new CellNotFoundException(sheet.getSheetName(), columnName);
            }
            
        }
        
    }
209515
@SneakyThrows @SuppressWarnings("unchecked")
    private void processExcelRowsAnnotation(Field field, Object bean) {
        val excelRows = field.getAnnotation(ExcelRows.class);
        if (excelRows == null) return;

        if (!Generic.of(field.getGenericType()).isRawType(List.class)) return;

        val templateCell = findTemplateCell(excelRows);
        if (templateCell == null) {
            log.warn("unable to locate template cell for field {}", field);
            return; // 找不到模板单元格，直接忽略字段处理。
        }

        val list = (List<Object>) Fields.invokeField(field, bean);
        val itemSize = PoiUtil.shiftRows(sheet, list, templateCell.getRowIndex());
        if (itemSize > 0) {
            writeRows(templateCell, list);
            mergeRows(excelRows, templateCell, itemSize);
            mergeCols(excelRows, templateCell, itemSize);
        }
    }
640839
public void moveRow(Object rowKey, int newRowIndex) {
        checkFrozen();

        this.checkRowIndex(newRowIndex);

        final int rowIndex = this.getRowIndex(rowKey);
        final List<R> tmp = new ArrayList<>(rowLength());
        tmp.addAll(_rowKeySet);
        tmp.add(newRowIndex, tmp.remove(rowIndex));

        _rowKeySet.clear();
        _rowKeySet.addAll(tmp);

        _rowKeyIndexMap = null;

        if (_initialized && _columnList.size() > 0) {
            for (List<E> column : _columnList) {
                column.add(newRowIndex, column.remove(rowIndex));
            }
        }
    }
602265
public String getRowText(int rowIndex) {
        String rowText = null;
        String xPath = getXPathBase() + "tr[" + rowIndex + "]";

        rowText = HtmlElementUtils.locateElement(xPath).getText();

        return rowText;
    }
1191156
public void flushRemainingRowsFrom(final XMLUtil util, final Appendable appendable,
                                       final int rowIndex) throws IOException {
        this.appender.flushRemainingRowsFrom(util, appendable, rowIndex);
    }
856031
public static Row getOrCreateRow(Sheet sheet, int rowIndex) {
		Row row = sheet.getRow(rowIndex);
		if (null == row) {
			row = sheet.createRow(rowIndex);
		}
		return row;
	}
392794
@Override
    public Iterator<Object[]> getDataByFilter(DataProviderFilter dataFilter) {
        logger.entering(dataFilter);
        List<Object[]> objs = new ArrayList<>();
        Field[] fields = resource.getCls().getDeclaredFields();

        // Extracting number of rows of data to read
        // Notice that numRows is returning the actual number of non-blank rows.
        // Thus if there are blank rows in the sheet then we will miss some last rows of data.
        List<Row> rowToBeRead = excelReader.getAllExcelRows(resource.getCls().getSimpleName(), false);
        List<String> excelHeaderRow = getHeaderRowContents(resource.getCls().getSimpleName(), fields.length);
        for (Row row : rowToBeRead) {
            List<String> excelRowData = excelReader.getRowContents(row, fields.length);
            Map<String, String> headerRowDataMap = prepareHeaderRowDataMap(excelHeaderRow, excelRowData);
            if (excelRowData.size() != 0) {
                try {
                    Object temp = prepareObject(getObject(), fields, excelRowData, headerRowDataMap);
                    if (dataFilter.filter(temp)) {
                        objs.add(new Object[] { temp });
                    }
                } catch (IllegalAccessException e) {
                    throw new DataProviderException("Unable to create instance of type '" + resource.getCls().getName()
                            + "'", e);
                }
            }
        }
        logger.exiting(objs.iterator());
        return objs.iterator();
    }
997317
public List<Map<String, Object>> read(int headerRowIndex, int startRowIndex, int endRowIndex) {
		checkNotClosed();
		// 边界判断
		final int firstRowNum = sheet.getFirstRowNum();
		final int lastRowNum = sheet.getLastRowNum();
		if (headerRowIndex < firstRowNum) {
			throw new IndexOutOfBoundsException(StrUtil.format("Header row index {} is lower than first row index {}.", headerRowIndex, firstRowNum));
		} else if (headerRowIndex > lastRowNum) {
			throw new IndexOutOfBoundsException(StrUtil.format("Header row index {} is greater than last row index {}.", headerRowIndex, firstRowNum));
		}
		startRowIndex = Math.max(startRowIndex, firstRowNum);// 读取起始行（包含）
		endRowIndex = Math.min(endRowIndex, lastRowNum);// 读取结束行（包含）

		// 读取header
		List<Object> headerList = readRow(sheet.getRow(headerRowIndex));

		final List<Map<String, Object>> result = new ArrayList<>(endRowIndex - startRowIndex + 1);
		List<Object> rowList;
		for (int i = startRowIndex; i <= endRowIndex; i++) {
			if (i != headerRowIndex) {
				// 跳过标题行
				rowList = readRow(sheet.getRow(i));
				if (CollUtil.isNotEmpty(rowList) || false == ignoreEmptyRow) {
					if (null == rowList) {
						rowList = new ArrayList<>(0);
					}
					result.add(IterUtil.toMap(aliasHeader(headerList), rowList, true));
				}
			}
		}
		return result;
	}
73039
@Override
	public void updateRowId(final int columnIndex, final RowId x) throws SQLException {
		wrapped.updateRowId(columnIndex, x);
	}
566692
@Override
    public void setRowId(int parameterIndex, RowId x) throws SQLException
    {
        checkParameterBounds(parameterIndex);
        throw SQLError.noSupport();
    }
1063979
@Override
	public Excel07SaxReader read(File file, int sheetIndex) throws POIException {
		try {
			return read(OPCPackage.open(file), sheetIndex);
		} catch (Exception e) {
			throw new POIException(e);
		}
	}
852300
public static String rowIndexListToString(final List<Integer> row) {
		if (row == null || row.isEmpty()) {
			return null;
		}

		StringBuffer index = new StringBuffer();
		boolean addDelimiter = false;

		for (Integer lvl : row) {
			if (addDelimiter) {
				index.append(INDEX_DELIMITER);
			}
			index.append(lvl);
			addDelimiter = true;
		}

		return index.toString();
	}
644301
void switchTwoRows(int rowIndex, int rowToIndex) {
        for (int i = 0; i < getItems().length; i++) {
            Object cellData = getItems()[rowToIndex][i];
            getItems()[rowToIndex][i] = getItems()[rowIndex][i];
            getItems()[rowIndex][i] = cellData;
        }
    }
1284865
private void addIndex(final Object connection, final AttributeWrapper wrapper, final String rowKey,
            final EntityMetadata metadata)
    {

        Indexer indexer = indexManager.getIndexer();

        if (indexer != null && indexer.getClass().getSimpleName().equals("RedisIndexer"))
        {
            // Add row key to list(Required for wild search over table).
            wrapper.addIndex(
                    getHashKey(metadata.getTableName(),
                            ((AbstractAttribute) metadata.getIdAttribute()).getJPAColumnName()), getDouble(rowKey));

            // Add row-key as inverted index as well needed for multiple clause
            // search with key and non row key.
            wrapper.addIndex(
                    getHashKey(metadata.getTableName(),
                            getHashKey(((AbstractAttribute) metadata.getIdAttribute()).getJPAColumnName(), rowKey)),
                    getDouble(rowKey));

            indexer.index(metadata.getEntityClazz(), metadata, wrapper.getIndexes(), rowKey, null);
        }
    }
1323653
private void checkIndices(int row, int col) {
        if (row < 0 || col < 0 || row >= rows || col >= cols) {
            throw new IndexOutOfBoundsException();
        }
    }
816424
public String getCell(String row, String col) throws Exception {
		if (col.equals(this.getIndexColumnName())) {
			return row;
		}
		HeaderInfo rowIndex = rowLookup.get(row);
		HeaderInfo colIndex = columnLookup.get(col);

		if (rowIndex == null) {
			//allow for case insentive search
			for (String rowtable : rowLookup.keySet()) {
				if (row.equalsIgnoreCase(rowtable)) {
					rowIndex = rowLookup.get(rowtable);
					break;
				}
			}
			if (rowIndex == null) {
				throw new Exception("Row " + row + " not found in worksheet");
			}
		}
		if (colIndex == null) {
			//allow for case insentive search
			for (String coltable : columnLookup.keySet()) {
				if (col.equalsIgnoreCase(coltable)) {
					colIndex = columnLookup.get(coltable);
					break;
				}
			}
			if (colIndex == null) {
				throw new Exception("Column " + col + " not found in worksheet");
			}
		}

		CompactCharSequence ccs = data[rowIndex.getIndex()][colIndex.getIndex()];
		if (ccs != null) {
			return ccs.toString();
		} else {
			return "";
		}

		// return .toString();
	}