package charts.builder.spreadsheet; import java.io.IOException; import java.io.InputStream; import java.util.regex.Matcher; import java.util.regex.Pattern; import org.apache.commons.lang3.StringUtils; import org.apache.poi.hssf.usermodel.HSSFFormulaEvaluator; import org.apache.poi.hssf.usermodel.HSSFWorkbook; import org.apache.poi.ss.usermodel.Cell; import org.apache.poi.ss.usermodel.FormulaEvaluator; import org.apache.poi.ss.usermodel.Workbook; import org.apache.poi.ss.util.CellReference; import charts.builder.spreadsheet.external.UnresolvedRef; public class XlsDataSource extends SpreadsheetDataSource { private static final Pattern EXTERNAL_REF_FORMULA = Pattern.compile( "^\\+?('?)\\[(.+)\\](.*?)'?!\\$?([A-Za-z]+)\\$?(\\d+)$"); public XlsDataSource(InputStream in) throws IOException { HSSFWorkbook workbook = new HSSFWorkbook(in); HSSFFormulaEvaluator evaluator = workbook.getCreationHelper() .createFormulaEvaluator(); evaluator.setIgnoreMissingWorkbooks(true); init(workbook, evaluator); } private XlsDataSource(Workbook workbook, FormulaEvaluator evaluator, int defaultSheet) { super(workbook, evaluator, defaultSheet); } @Override public SpreadsheetDataSource toSheet(int sheet) { return new XlsDataSource(workbook(), evaluator(), sheet); } @Override UnresolvedRef externalReference(Cell cell) { UnresolvedRef uref = null; if((cell != null) && (cell.getCellType() == Cell.CELL_TYPE_FORMULA)) { Matcher m = EXTERNAL_REF_FORMULA.matcher(cell.getCellFormula()); if(m.matches()) { String nameOrId = m.group(2); String sheetname = m.group(3); String column = m.group(4); String row = m.group(5); if(StringUtils.isNotBlank(m.group(1))) { sheetname = unescapeSheetname(sheetname); } uref = uref(nameOrId, String.format("%s!%s%s", sheetname, column, row), String.format("%s!%s", cell.getSheet().getSheetName(), new CellReference(cell).formatAsString())); } } return uref; } private String unescapeSheetname(String name) { return StringUtils.replace(name, "''", "'"); } }