report.java
来自「Excel Report是一款基于Excel的报表生成工具」· Java 代码 · 共 1,082 行 · 第 1/3 页
JAVA
1,082 行
try {
if(log.isDebugEnable()){
log.debug("Begin create workbook.");
}
Workbook wbTemplet = this.reportConfig.getTempletWorkbook();
wb = Workbook.createWorkbook(os, wbTemplet);
if(log.isDebugEnable()){
log.debug("create workbook success!");
}
String[] sheetNames = reportConfig.getSheetName();
WritableSheet sheet = null;
if(log.isDebugEnable()){
log.debug("Writing data...");
}
for (int i = 0; i < sheetNames.length; i++) {
sheet = wb.getSheet(sheetNames[i]);
if (null == sheet) {
log.error("Can't get the sheet with the specified name(:"
+ sheetNames[i] + ") from templet file");
} else {
//writeSheet(sheet, reportConfig.getSheet(sheetNames[i]), this.dataSources);
writeSheetEx(sheet, reportConfig.getSheet(sheetNames[i]));
}
}
wb.write();
if(log.isDebugEnable()){
log.debug("Writing data success!");
}
} catch (Exception e) {
log.error("Error:" + e.getMessage());
throw e;
} finally {
if (wb != null)
wb.close();
}
}
public void writeSheet(WritableSheet sheet, SheetConfig sheetConfig,
Map dataSource) throws Exception{
WritableCell wc = null;
CellFormat cf = null;
Group group = null;
//生成嵌套组
groups = new GroupManager();
Stack groupStack = new Stack();
//取得数据源
this.dataSources = dataSource;
//分析模板文件
int rows = sheet.getRows();
for(int i=0; i<rows; i++){
Cell[] cells = sheet.getRow(i);
for(int j=0; j<cells.length; j++){
wc = sheet.getWritableCell(cells[j].getColumn(),cells[j].getRow());
//配置信息记录单元都为LABEL
if ((wc.getType() != CellType.LABEL) ){
continue;
}
if(this.isGroupBegin(wc)){
//处理组信息.
group = getGroup(wc);
groups.add(group);
groupStack.push(group);
}else if(this.isGroupEnd(wc)){
//判断当前组是否正确关闭.如果组正常关闭则记录组结束信息.
if(!isGroupEnd(wc, (Group)groupStack.pop())){
//无效的组配置信息,组必须按顺序嵌套.
throw new Exception("Error: Invalid group config!");
}
}else if(isVariable(wc) && groupStack.isEmpty()){
//从数据源中取出相应变量值,并写入报表文件.
writeValue(wc, dataSources);
}
}
}
if(groups.size() > 0){
//读取模板组包含的其他信息.
getGroupOtherInfo(sheet);
//写入组信息.
writeGroup(sheet, dataSources);
//删除模板
deleteTempletTrace(sheet);
}
}
public void writeGroup(WritableSheet sheet, Map dataSource)
throws Exception{
//取得顶层组
int rows = 0, curGroupIndex = 0;
Group group = groups.get(curGroupIndex);
//取得组对应数据源.
IDataSource ds = getGroupDataSource(dataSource, group);
Map rowData = null;
WritableCell wc = null;
int curRow = 0, curCol = 0;
int endRow = 0, endCol = 0;
int templetEndRow = 0, templetBeginRow = 0;
//按照组模板定义格式生成报表数据.
if(null != ds && ds.size() > 0){
templetBeginRow = group.getBeginRow();
templetEndRow = group.getEndRow();
//第一组信息用作模板,其他信息都是根据模板来生成.
curRow = group.getEndRow() + 1;
do{
curRow = writeCurrentRecordToSheet(sheet,
dataSource,
ds,
curGroupIndex,
curRow);
ds.next();
}while(ds.hasNext());
}
}
//输出嵌套组的报表信息.
public int writeSubGroup(WritableSheet sheet,
Map dataSource,
int curGroupIndex,
int curRow) throws Exception {
//取得datasource
Group group = groups.get(curGroupIndex);
//取得组对应数据源.
IDataSource ds = getGroupDataSource(dataSource, group);
if(null != ds && ds.size() > 0){
int templetBeginRow = group.getBeginRow();
int templetEndRow = group.getEndRow();
Group nextGroup = groups.get(curGroupIndex + 1);
//输出嵌套组报表数据
do{
curRow = writeCurrentRecordToSheet(sheet,
dataSource,
ds,
curGroupIndex,
curRow);
ds.next();
}while(ds.hasNext());
}
return curRow;
}
private void deleteTempletTrace(WritableSheet sheet){
ArrayList allGroups = groups.getAllGroups();
Group rootGroup = (Group)allGroups.get(0);
int beginRow = rootGroup.getBeginRow();
int endRow = rootGroup.getEndRow();
//此处不能从结束行开始删除,否则保存数据时会出现合并错误的单元格.
for (int i = beginRow; i <= endRow; i++) {
sheet.removeRow(beginRow);
}
}
/*
* 读取模板组内的其他信息,如组内包含的图片信息,超链接信息,
* 合并单元格信息等,因为这些信息不能通过单个单元格的拷贝操作
* 来拷贝,只能标识出来一个一个手动拷贝.
*/
public void getGroupOtherInfo(WritableSheet sheet){
ArrayList allGroups = groups.getAllGroups();
Range[] mergedCells = sheet.getMergedCells();
Group curGroup = null;
//不存在合并单元格则退出.
if(mergedCells.length <= 0) return;
//将合并单元格信息拷贝到链表中,方便动态删除已经保存过的合并单元格.
List mergedCellLists = new LinkedList();
for(int i=0; i<mergedCells.length; i++){
mergedCellLists.add(mergedCells[i]);
}
//这里循环必须从最里面的组开始循环
int row = 0, col = 0;
Range rang = null;
for (int i = groups.size() - 1; i >= 0; i--) {
curGroup = groups.get(i);
//链表的大小会改变.
Iterator itr = mergedCellLists.iterator();
while(itr.hasNext()){
rang = (Range)itr.next();
row = rang.getTopLeft().getRow();
col = 0;
if(curGroup.contain(row, col)){
curGroup.setMergedCell(rang);
//从链表中删除该记录,否则上级组会重复包含该信息.
itr.remove();
}
}
}
}
/*
* 将数据源的当前记录数据写入报表.(数据分布格式根据模板来取得)
*/
private int writeCurrentRecordToSheet(WritableSheet sheet,
Map dataSource, //所有dataSource集合
IDataSource ds, //当前组正在处理的DataSource
int curGroupIndex, //嵌套组数据
int currentRow //当前数据写入行
) throws Exception {
//当前处理组.
Group group = this.groups.get(curGroupIndex);
int templetBeginRow = group.getBeginRow();
int templetEndRow = group.getEndRow();
//取得嵌套组
Group nextGroup = groups.get(curGroupIndex + 1);
//组写入开始行
int beginRow = currentRow;
int curRow = beginRow;
int cells = sheet.getColumns();
for (int i = templetBeginRow + 1; i < templetEndRow; ) {
//判断当前行是否嵌套组
if(nextGroup != null){
if (nextGroup.contain(i, 0)) {
//存在嵌套组
curRow = writeSubGroup(sheet, dataSource, curGroupIndex + 1, curRow);
//跳过嵌套组行数,继续处理本组数据.
//嵌套组的数据writeSubGroup函数负责处理
i += nextGroup.getEndRow() - nextGroup.getBeginRow() + 1;
continue;
}
}
//拷贝行高度
CellView rowView = sheet.getRowView(i);
sheet.insertRow(curRow);
sheet.setRowView(curRow, rowView.getSize());
//拷贝模板行数据, 将模板行对应的数据写入目标行,如果存在变量则取出变量值.
copyRow(sheet, i, curRow, 0, cells);
curRow++;
i++;
}
//拷贝组内合并单元格信息.
copyMergedCells(sheet, curGroupIndex, beginRow);
//拷贝组内图片信息.
//拷贝组内超链接信息.
return curRow;
}
/*
* 拷贝组内合并单元格信息
*/
public void copyMergedCells(WritableSheet sheet,
int curGroupIndex,
int beginRow)
throws Exception{
//处理当前组.
Group group = this.groups.get(curGroupIndex);
Object[] mergedCells = group.getMergedCells();
Cell topLeft = null, bottonRight = null;
int topLeftRow = 0, btRightRow = 0;
for(int i=0; i<mergedCells.length; i++){
topLeft = ((Range)mergedCells[i]).getTopLeft();
bottonRight = ((Range)mergedCells[i]).getBottomRight();
topLeftRow = beginRow + (topLeft.getRow() - (group.beginRow + 1));
btRightRow = beginRow + (bottonRight.getRow() - (group.beginRow + 1));
//debug info
log.debug("merge cell beginrow:" + topLeftRow
+ " begincol:" + topLeft.getColumn()
+ " endRow:" + btRightRow
+ " endCol:" + bottonRight.getColumn());
sheet.mergeCells(topLeft.getColumn(),
topLeftRow,
bottonRight.getColumn(),
btRightRow);
}
}
/*
* 拷贝一行数据到另外一行.
*/
public void copyRow(WritableSheet sheet,
int sourceRow,
int destRow)
throws Exception{
Cell[] cells = sheet.getRow(sourceRow);
copyRow(sheet, sourceRow, destRow, 0, cells.length);
}
/*
* 拷贝指定行数据, sourceRow开始行,destRow拷贝目标行,
* beginCol开始列,endCol结束列.
*/
public void copyRow(WritableSheet sheet,
int sourceRow,
int destRow,
int beginCol,
int endCol)
throws Exception{
WritableCell wc = null;
Cell[] cells = sheet.getRow(sourceRow);
//循环模板单元格,处理组当前行数据
for (int i = beginCol; i < endCol; i++) {
wc = sheet.getWritableCell(i, sourceRow);
WritableCell newWc = wc.copyTo(i, destRow);
//配置信息记录单元都为LABEL
if ((newWc.getType() == CellType.LABEL)
&& isVariable(newWc)) {
//从数据源中取出相应变量值,并写入报表文件.
writeValue(newWc, this.dataSources);
}
sheet.addCell(newWc);
}
}
/*
* 根据组配置的数据源信息,取得组对应数据源及数据.
*/
private IDataSource getGroupDataSource(Map dataSource, Group group)
throws Exception {
String fieldMap = null;
boolean resetParam = false;
String groupSourceName = group.getDataSource();
IDataSource ds = (IDataSource)dataSource.get(groupSourceName);
if(null != ds){
String temp = "", value = "";
Map paramsMap = group.getParamsMap();
List params = ds.getConfig().getParams();
if(paramsMap.size() != params.size()){
log.warn("The number of user passed parameters are not equal " +
"the number of the config file defined! Group name=" + group.getName());
}
if(paramsMap.size() == params.size()){
//取得检索组数据的DataSource的参数值
for(int i=0; i<params.size(); i++){
fieldMap = (String)paramsMap.get(params.get(i));
if(null != fieldMap){
String fieldValue = getDataFromDataSource(dataSource, "[" + fieldMap + "]");
if(null != fieldValue){
ds.setParameter((String)params.get(i), fieldValue);
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?