class ExcelSpreadsheetReader implements SpreadsheetReader {

	public void read(InputStream inputStream, Range rowRange, Range columnRange, boolean ignoreBlankRows, SpreadsheetRowProcessor rowProcessor)
			throws SpreadsheetReadException {
		Workbook workbook;
		try {
			workbook = WorkbookFactory.create(inputStream);
		} catch (InvalidFormatException e) {
			throw new SpreadsheetReadException(
					"The file does not have a compatible spreadsheet format", e);
		} catch (IOException e) {
			throw new SpreadsheetReadException("The spreadsheet stream could not be read", e);
		} catch (IllegalArgumentException e) {
			throw new SpreadsheetReadException("The spreadsheet stream could not be read", e);
		}

		DataFormatter dataFormatter = new DataFormatter();
		
		workbook.setMissingCellPolicy(Row.CREATE_NULL_AS_BLANK);
		Sheet sheet = workbook.getSheetAt(0);

		if (rowRange.getEnd() < 0) {
			rowRange.setEnd(sheet.getLastRowNum());
			logger.debug("No end of row range specified, setting to " + rowRange.getEnd());
		}

		SortedMap<Integer, String> currentDataRow = new TreeMap<Integer, String>();

		for (int rowIndex = rowRange.getStart(); rowIndex <= rowRange.getEnd(); rowIndex++) {
			boolean blankRow = true;
			if (rowRange.contains(rowIndex)) {
				Row row = sheet.getRow(rowIndex);
				for (int columnIndex = columnRange.getStart(); columnIndex <= columnRange.getEnd(); columnIndex++) {
					if (columnRange.contains(columnIndex)) {
						String value = null;
						if (row != null) {
							Cell cell = row.getCell(columnIndex);
							if (cell != null) {
								value = getCellValue(cell, dataFormatter);
							}
						}
						if (value != null) {
							blankRow = false;
						}
						currentDataRow.put(columnIndex, value);
						if (columnIndex == columnRange.getEnd()) {
							if (!ignoreBlankRows || !blankRow) {
								rowProcessor.processRow(rowIndex, currentDataRow);
							}
							currentDataRow = new TreeMap<Integer, String>();
						}
					}
				}
			}
		}

	}

}