POI自定义单元格类
在用POI做Excel导出的时候,单元格的创建是一个很头疼的问题,对于有些表格中杂乱无章的单元格顺序,比如:
这种树形结构并不像横向的表格有规律,所以就需要一行一行的插入。这是一项没有啥技术含量且枯燥的事情,但是却又不得不去做。因此我根据单元格的属性,自定义了一个单元格类,稍微简化了一下工作量。。
代码块
public class ExcelCell {
/** sheet **/
private HSSFSheet sheet;
/** 行 **/
private HSSFRow hRow;
/** 列 **/
private int column;
/** 样式 **/
private HSSFCellStyle style;
/** 值 **/
private String value;
/** 区域中最后一个单元格的行号 **/
private Integer lastRow;
/** 区域中最后一个单元格的列号 **/
private Integer lastCol;
public ExcelCell() {
}
public ExcelCell(HSSFSheet sheet, HSSFRow hRow, int column,
HSSFCellStyle style, String value,
Integer lastRow, Integer lastCol) {
super();
this.sheet = sheet;
this.hRow = hRow;
this.column = column;
this.style = style;
this.value = value;
this.lastRow = lastRow;
this.lastCol = lastCol;
}
public HSSFSheet getSheet() {
return sheet;
}
public void setSheet(HSSFSheet sheet) {
this.sheet = sheet;
}
public HSSFRow gethRow() {
return hRow;
}
public void sethRow(HSSFRow hRow) {
this.hRow = hRow;
}
public int getColumn() {
return column;
}
public void setColumn(int column) {
this.column = column;
}
public HSSFCellStyle getStyle() {
return style;
}
public void setStyle(HSSFCellStyle style) {
this.style = style;
}
public String getValue() {
return value;
}
public void setValue(String value) {
this.value = value;
}
public Integer getLastRow() {
return lastRow;
}
public void setLastRow(Integer lastRow) {
this.lastRow = lastRow;
}
public Integer getLastCol() {
return lastCol;
}
public void setLastCol(Integer lastCol) {
this.lastCol = lastCol;
}
}
每个单元格都应该具备以下属性:
- 首行
- 首列
- 末行(用于单元格合并)
- 末列(用于单元格合并)
- 样式
- 值
通过以上属性,可以刻画一个单元格,我们可以通过List保存所有的单元格,最后通过遍历List来创建Excel表格
public static void batchCreateCell(HSSFSheet sheet, ExcelCell ec) {
HSSFCell hCell = ec.gethRow().createCell(ec.getColumn());
hCell.setCellValue(ec.getValue());
hCell.setCellStyle(ec.getStyle());
if (ec.getLastRow() != null && ec.getLastCol() != null) {
CellRangeAddress cad = new CellRangeAddress(ec.gethRow().getRowNum(), ec.getLastRow().intValue(), ec.getColumn(), ec.getLastCol().intValue());
sheet.addMergedRegion(cad);
}
}
这样稍微的简化了代码量。。但是对于某些单元格不能遍历的问题,还是需要手动的在List里面add。。但若是每个单元格里面的值都是对象里的属性的话,就可以通过遍历对象的属性往List里面塞值啦,具体怎么塞要看表格的类型,比如截图中的树形结构表格就可以用树形的数据结构来封装了,看起来还是挺容易的。。
以下为感想
在POI中,合并单元格后格式会有一些没有意识到的bug。比如:
如果觉得没啥问题,我们来看看打印预览:
有的单元格的边框显示不全。这是因为POI对单元格的定义是:在每个Excel表格中,每一个初始单元格(未合并的)都是一个对象,对于每一个单元格,如果不使用createCell方法,这个单元格就不存在(对于打开的.xls或者.xlsx来说,这个单元格能看到,但是什么都没有)。既然不存在这个单元格对象,也就不具备样式的属性了,所以不先定义就合并,结果就像上图这样,单元格边框显示不全。我的解决办法是在合并之前就定义:
/**
*
* @Description: 对表格中所有单元格设置样式
* @param @param sheet
* @param @param style
* @param @param row 表格行数
* @param @param column 表格列数
* @return void
* @throws
* @author HJC
* @date 2017-10-17
*/
public static void createRowAndColumn(HSSFSheet sheet, HSSFCellStyle style, int row, int column) {
for (int i = 0; i < row; i++) {
sheet.createRow((int) i);
for (int j = 0; j < column; j++) {
sheet.getRow(i).createCell(j);
sheet.getRow(i).getCell(j).setCellStyle(style);
}
}
//return sheet;
}
第一次用markdown。。代码格式可能有点难看。。但我永远坚持左大括号不换行╭(╯^╰)╮