近期在进行一个报表项目,页面是做了一个模版,支持用户配置sql显示数据,自然而然导出也要支持动态数据,这里我采用POI导出功能,听说JXLS支持模版式的表头功能,也比较强大,毕竟是对POI进行了封装。
下面我对POI生成动态表头的功能做封装
这里提供了更详细的POI数据封装及流下载方式
概要
1.这里主要用到 CellRangeAddress合并单元格,这里明白构造方法的参数就可以了,一目了然
/**
*
* @param firstRow 起始行
* @param lastRow 结束行
* @param firstCol 起始列
* @param lastCol 结束列
*/
public CellRangeAddress(int firstRow, int lastRow, int firstCol, int lastCol);
2.HeaderNode包含单个单元格的节点数据与位置
3.这里添加了一个键值类RowKey,并且重写了hasCode()和equals()方法,不然没法从map中取出已存在的行HSSFRow
4.maven info
<dependency>
<groupId>org.apache.poi</groupId>
<artifactId>poi</artifactId>
<version>3.9</version>
</dependency>
5.最后上源码,包含测试主方法
import org.apache.poi.hssf.usermodel.*;
import org.apache.poi.ss.usermodel.Cell;
import org.apache.poi.ss.util.CellRangeAddress;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.*;
public final class PoiUtil {
public static void main(String[] args) {
// 第一步,创建一个webbook,对应一个Excel文件
HSSFWorkbook workbook = new HSSFWorkbook();
// 第二步,在webbook中添加一个sheet,对应Excel文件中的sheet
HSSFSheet sheet = workbook.createSheet("测试");
// 第四步,创建单元格,并设置值表头 设置表头居中
HSSFCellStyle style = workbook.createCellStyle();
style.setAlignment(HSSFCellStyle.ALIGN_CENTER); // 水平居中格式
style.setVerticalAlignment(HSSFCellStyle.VERTICAL_CENTER); //垂直居中
List<HeaderNode> nodes = new ArrayList<>();
HeaderNode headerNode1 = new HeaderNode();
headerNode1.setName("test1");
headerNode1.setFirstRow(0);
headerNode1.setLastRow(1);
headerNode1.setFirstCol(0);
headerNode1.setLastCol(5);
nodes.add(headerNode1);
HeaderNode headerNode34 = new HeaderNode();
headerNode34.setName("test4");
headerNode34.setFirstRow(3);
headerNode34.setLastRow(4);
headerNode34.setFirstCol(0);
headerNode34.setLastCol(5);
nodes.add(headerNode34);
HeaderNode headerNode2 = new HeaderNode();
headerNode2.setName("test2");
headerNode2.setFirstRow(2);
headerNode2.setLastRow(2);
headerNode2.setFirstCol(0);
headerNode2.setLastCol(3);
nodes.add(headerNode2);
HeaderNode headerNode3 = new HeaderNode();
headerNode3.setName("test3");
headerNode3.setFirstRow(2);
headerNode3.setLastRow(2);
headerNode3.setFirstCol(4);
headerNode3.setLastCol(5);
nodes.add(headerNode3);
generateHeader(nodes,sheet,style);
try {
FileOutputStream output=new FileOutputStream("e:\\workbook.xls");
workbook.write(output);
output.flush();
} catch (IOException e) {
e.printStackTrace();
}
}
private PoiUtil() {
}
/**
* 此方法生成表头并写入表头名称
* @param nodes 节点
* @param sheet 工作簿
* @param style 单元格样式
*/
public static void generateHeader(List<HeaderNode> nodes,HSSFSheet sheet,HSSFCellStyle style){
Map<RowKey,HSSFRow> hssfRowMap = new HashMap<>();
for (HeaderNode node : nodes){
CellRangeAddress cra = new CellRangeAddress(node.getFirstRow(),node.getLastRow(),
node.getFirstCol(),node.getLastCol());
sheet.addMergedRegion(cra);
RowKey key = new RowKey();
key.setFirstRow(node.getFirstRow());
key.setLastRow(node.getLastRow());
HSSFRow row = hssfRowMap.get(key);
if (null == row){
row = sheet.createRow(node.getFirstRow());
hssfRowMap.put(key,row);
}
Cell cell = row.createCell(node.getFirstCol());
cell.setCellValue(new HSSFRichTextString(node.getName()));
cell.setCellStyle(style);
}
}
/**
* 节点数据
*/
public static class HeaderNode{
private String name;
private int firstRow;
private int lastRow;
private int firstCol;
private int lastCol;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getFirstRow() {
return firstRow;
}
public void setFirstRow(int firstRow) {
this.firstRow = firstRow;
}
public int getLastRow() {
return lastRow;
}
public void setLastRow(int lastRow) {
this.lastRow = lastRow;
}
public int getFirstCol() {
return firstCol;
}
public void setFirstCol(int firstCol) {
this.firstCol = firstCol;
}
public int getLastCol() {
return lastCol;
}
public void setLastCol(int lastCol) {
this.lastCol = lastCol;
}
}
private static class RowKey{
private int firstRow;
private int lastRow;
public int getFirstRow() {
return firstRow;
}
public void setFirstRow(int firstRow) {
this.firstRow = firstRow;
}
public int getLastRow() {
return lastRow;
}
public void setLastRow(int lastRow) {
this.lastRow = lastRow;
}
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (!(o instanceof RowKey)) return false;
RowKey key = (RowKey) o;
return firstRow == key.firstRow &&
lastRow == key.lastRow;
}
@Override
public int hashCode() {
return Objects.hash(firstRow, lastRow);
}
}
}