package er.excel; import java.io.File; import java.io.IOException; import java.util.ArrayList; import java.util.Date; import org.apache.poi.hssf.usermodel.HSSFCell; import org.apache.poi.hssf.usermodel.HSSFRow; import org.apache.poi.hssf.usermodel.HSSFSheet; import org.apache.poi.hssf.usermodel.HSSFWorkbook; /** * This class simplifies the creation of HSSFWorkbook objects, allowing one to create * a workbook and add data to it with fairly simple and (hopefully) self-explanatory code. * It also provides a useful subset of a very large API. * <p> * The <code>sheetWithNumber(int)</code> and <code>sheetWithName(String)</code> methods * may return a null object, but any of the other methods for returning a sheet or a cell * are guaranteed to not return a null. If necessary, a sheet or a cell will be created. * The <code>stringAtLocation</code> and <code>numberAtLocation</code> methods are also * guaranteed to not return null. This allows one to use code like the following, without * fear of an exception. * <pre><code> * EGSimpleWorkbookHelper helper = new EGSimpleWorkbookHelper(); * helper.currentSheet().setNumberAtLocation(24, 2, 2); * helper.currentSheet().setStringAtLocation("Hello", 3, 4); * String aNumber = helper.currentSheet().numberAtLocation(1, 1).toString(); * </code></pre> * The POI classes use numbers for rows and, implicitly, columns. This class also allows * the use of the string-based column names one always sees on spreadsheets. So the methods * that take a row number and a column number and return a call can also take a column name, * such as "A", "B", ..., "Z", "AA", "AB", and so on. Using a column name not wholly * composed of capital letters will generate a IllegalArgumentException. */ public class EGSimpleWorkbookHelper { protected HSSFWorkbook _workbook; private int currentSheetIdx; private ArrayList<HSSFSheet> sheets; private static final String alphabet = "ABCDEFGHIJKLMNOPQRSTUVWXYZ"; private static final int NotAValidColumnName = -1; private static int numberForString(String column) { if (column == null || "".equals(column)) throw new java.lang.IllegalArgumentException("Column name \""+column+"\" is not a valid name. Use capital letters only."); int columnNumber = 0; for (int idx = 0, len = column.length(); idx < len; idx++) { int offset = alphabet.indexOf(column.charAt(idx)); if (offset == NotAValidColumnName) throw new java.lang.IllegalArgumentException("Column name \""+column+"\" is not a valid name. Use capital letters only."); columnNumber = (columnNumber * 26) + offset; } return columnNumber; } public EGSimpleWorkbookHelper() { _workbook = new HSSFWorkbook(); currentSheetIdx = 0; sheets = new ArrayList<>(); sheets.add(_workbook.createSheet("Sheet0")); } public static EGSimpleWorkbookHelper newInstance() { return new EGSimpleWorkbookHelper(); } public EGSimpleWorkbookHelper(HSSFWorkbook workbook) { _workbook = workbook; currentSheetIdx = 0; sheets = new ArrayList<>(); for (int idx = 0, num = _workbook.getNumberOfSheets(); idx < num; idx++) { sheets.add(_workbook.getSheetAt(idx)); } } /** * Returns the HSSFWorkbook instance that this class is helping to build. */ public HSSFWorkbook workbook() { return _workbook; } private int numberOfSheet(HSSFSheet sheet) { return sheets.indexOf(sheet); } /** * Switches the current sheet to a sheet identified by number, with the number * being set by the order in which the sheets were created. */ public void switchToSheetNumber(int number) { // will only enter the for loop if number is greater than the number of sheets. // for (int idx = sheets.size(); idx <= number; idx++) { sheets.add(_workbook.createSheet("Sheet"+idx)); } currentSheetIdx = number; } /** * Switches the current sheet to a sheet identified by name. If a name is not explicitly * set on a sheet, its default name is "Sheet#", with "#" being the number of the sheet. */ public void switchToSheetWithName(String name) { HSSFSheet sheet = sheetWithName(name); if (sheet == null) { sheet = _workbook.createSheet(name); sheets.add(sheet); } currentSheetIdx = numberOfSheet(sheet); } /** * Returns the sheet that has been designated as the current sheet. This method * is guaranteed to return a sheet and it will not return <code>null</code>. */ public HSSFSheet currentSheet() { return sheets.get(currentSheetIdx); } /** * Returns the sheet in this workbook that is identified by a number, with the numbers * being set in the order in which the sheets were created. This method is not guaranteed * to return a sheet and may return <code>null</code>. To avoid getting a null, use the * switchToSheetNumber() method and then call currentSheet(). */ public HSSFSheet sheetWithNumber(int number) { if (number < sheets.size()) return sheets.get(number); else return null; } /** * Returns the sheet in this workbook that is identified by a particular name. This * method is not guaranteed to return a sheet and may return <code>null</code>. * To avoid getting a null, use the switchToSheetWithName() method and then * call currentSheet(). */ public HSSFSheet sheetWithName(String name) { return _workbook.getSheet(name); } /** * Returns the number of the current sheet. * @return a non-zero integer */ public int currentSheetNumber() { return currentSheetIdx; } public void setCurrentSheetName(String name) { _workbook.setSheetName(currentSheetIdx, name); } public HSSFCell cellAtLocation(int rownum, int colnum) { HSSFSheet sheet = currentSheet(); HSSFRow row = sheet.getRow(rownum); if (row == null) row = sheet.createRow(rownum); HSSFCell cell = row.getCell(colnum); if (cell == null) row.createCell(colnum); return currentSheet().getRow(rownum).getCell(colnum); } public HSSFCell cellAtLocation(int rownum, String columnName) { int colnum = numberForString(columnName); if (colnum == NotAValidColumnName) throw new java.lang.IllegalArgumentException("Column name \""+columnName+"\" is not a valid name. Use capital letters only."); return cellAtLocation(rownum, colnum); } public Number numberAtLocation(int rownum, int colnum) { return Double.valueOf(this.cellAtLocation(rownum, colnum).getNumericCellValue()); } public void setNumberAtLocation(Number value, int rownum, int colnum) { this.cellAtLocation(rownum, colnum).setCellValue(value.doubleValue()); } public Number numberAtLocation(int rownum, String columnName) { return numberAtLocation(rownum, numberForString(columnName)); } public void setNumberAtLocation(Number value, int rownum, String columnName) { this.setNumberAtLocation(value, rownum, numberForString(columnName)); } public Date dateAtLocation(int rownum, int colnum) { return this.cellAtLocation(rownum, colnum).getDateCellValue(); } public void setDateAtLocation(Date value, int rownum, int colnum) { this.cellAtLocation(rownum, colnum).setCellValue(value); } public Date dateAtLocation(int rownum, String columnName) { return dateAtLocation(rownum, numberForString(columnName)); } public void setDateAtLocation(Date value, int rownum, String columnName) { this.setDateAtLocation(value, rownum, numberForString(columnName)); } public String stringAtLocation(int rownum, int colnum) { return this.cellAtLocation(rownum, colnum).getStringCellValue(); } public void setStringAtLocation(String value, int rownum, int colnum) { this.cellAtLocation(rownum, colnum).setCellValue(value); } public String stringAtLocation(int rownum, String columnName) { return stringAtLocation(rownum, numberForString(columnName)); } public void setStringAtLocation(String value, int rownum, String columnName) { this.setStringAtLocation(value, rownum, numberForString(columnName)); } public String writeToTemp() { File file = null; try { file = File.createTempFile("eg_", ".xls"); } catch (java.io.IOException e) { return null; } if (file == null) return null; return (write(file.getName())) ? file.getName() : null; } /** * Writes the XLS data to a file given the filename. * @param filename to be overwritten with the spreadsheet data * @return true if the file was written to successfully, false is there was an * exception from the java.io classes */ public boolean write(String filename) { java.io.FileOutputStream stream; try { stream = new java.io.FileOutputStream(filename); } catch (java.io.FileNotFoundException e) { return false; } try { _workbook.write(stream); } catch (java.io.IOException e) { return false; } finally { try { stream.close(); } catch (IOException e) { // ignore } } return true; } }