使用POI生成Excel报表 (四)
* @create Jul 5, 2013 9:54:46 PM
* @author 玄玉
*/
public enum ExcelReport {
//实现单例模式的唯一实例
INSTANCE;
/**报表模板文件的存储位置*/
private static final String REPORT_TEMPLATE_FILE_PATH = "/ReportTemplate.xls";
/**本列开始填充序号的标识*/
private static final String SERIAL_NO = "serialNo";
/**本行开始填充数据的标识*/
private static final String DATA_BEGIN = "dataBegin";
/**表格采用同列样式的标识*/
private static final String USE_STYLES = "useStyles";
/**表格样式采用的默认样式*/
private static final String DEFAULT_STYLES = "defaultStyles";
/**初始行的下标(指的是填充数据的第一个单元格下标)*/
private int initRowIndex;
/**初始列的下标(指的是填充数据的第一个单元格下标)*/
private int initColIndex;
/**当前行的下标(指的是填充数据的当前单元格下标)*/
private int currRowIndex;
/**当前列的下标(指的是填充数据的当前单元格下标)*/
private int currColIndex;
/**最后一行的下标*/
private int lastRowIndex;
/**序号列的第一个单元格的下标*/
private int serialColIndex;
/**默认行高(指的是填充数据的第一个单元格的行高)*/
private float defaultRowHeight;
/**存放模板中所有表格样式(键为99表示表格的默认样式)*/
private Map allCellStyle = new HashMap();
private Row currRow;
private Sheet sheet;
private Workbook wb;
/**
* 基础数据初始化
*/
private ExcelReport(){
try {
//从指定目录中读取
//wb = WorkbookFactory.create(new File(REPORT_TEMPLATE_FILE_PATH));
//从classpath中读取模板文档
wb = WorkbookFactory.create(ExcelReport.class.getResourceAsStream(REPORT_TEMPLATE_FILE_PATH));
//获取模板中的第一个Sheet
sheet = wb.getSheetAt(0);
} catch (InvalidFormatException e) {
throw new RuntimeException("模板文件格式无效", e);
} catch (IOException e) {
throw new RuntimeException("模板文件不存在", e);
}
for(Row row : sheet){
for(Cell cell : row){
//报表模板文件default.xls中约定序号和SERIAL_NO和DATA_BEGIN都是String类型的
if(Cell.CELL_TYPE_STRING != cell.getCellType()){
continue;
}
String str = cell.getStringCellValue().trim();
//收集默认的表格样式
if(DEFAULT_STYLES.equals(str)){
this.allCellStyle.put(99, cell.getCellStyle());
}
//收集除默认表格样式以外的所有表格样式
if(USE_STYLES.equals(str)){
this.allCellStyle.put(cell.getColumnIndex(), cell.getCellStyle());
}
//定位序号列的第一个单元格下标
if(SERIAL_NO.equals(str)){
this.serialColIndex = cell.getColumnIndex();
}
//定位开始填充数据的第一个单元格的下标
if(DATA_BEGIN.equals(str)){
this.initColIndex = cell.getColumnIndex();
this.initRowIndex = row.getRowNum();
this.currColIndex = this.initColIndex;
this.currRowIndex = this.initRowIndex;
this.lastRowIndex = sheet.getLastRowNum();
this.defaultRowHeight = row.getHeightInPoints();
}
}
}
}
/**
* 创建行
*/
public void createNewRow(){
//下移行的条件有2个:当前行非初始行,且当前行没有超过最后一行
if(this.currRowIndex!=this.initRowIndex && this.lastRowIndex>
this.currRowIndex){
//将指定的几行进行下移一行
sheet.shiftRows(this.currRowIndex, this.lastRowIndex, 1, true, true);
//既然下移了那么最后一行下标就也要增大了
this.lastRowIndex++;
}
//在指定的行上创建一个空行(如果此行原本有单元格和数据,那么也会被空行覆盖,且创建出来的空行是没有单元格的)
this.currRow = sheet.createRow(this.currRowIndex);
this.currRow.setHeightInPoints(this.defaultRowHeight);
this.currRowIndex++;
this.currColIndex = this.initColIndex;
}
/**
* 构造单元格(包括创建单元格和填充数据)
*/
public void buildCell(String value){
Cell cell = this.currRow.createCell(this.currColIndex);
if(this.allCellStyle.containsKey(this.currColIndex)){
cell.setCellStyle(this.allCellStyle.get(this.currColIndex));
}else{
cell.setCellStyle(this