jexcelapi写excel文件的抽象类(一)

开发过程中,需要把数据导出到excel中,用jxl_2_6_4.jar包实现java对excel的操作。

下面介绍两种方法写excel文件,一个是sheet模板,填入数据;一个是row模板,然后填入excel。

利用模板操作excel比较方便,可以用excel设置好所需要的单元格格式,然后读入按照业务规则填写,实现所有的excel格式设置,而不用研究jxl的api,是一种偷懒的做法。

我的项目中,报表全部是生成excel文件输出。

首先,建立一个excel报表接口

/**
 * 报表生成器
 * @author zhengmw
 *
 */
public interface IReportMaker {

 /**
  * 输出报表
  * @return 报表文件路径,让调用者直接打开文件,可能生成多个文件
  * @throws GeneException 自定义异常
  */
 public List<String> report() throws GeneException;
}

然后实现一个excel报表的抽象类

/**
 * EXCEL报表基类
 *
 * @author zhengmw
 *
 */
public abstract class AbstractExcelReportMaker implements IReportMaker {
 /**
  * 模板文件名, 构造函数传入
  */
 private String fileName;

 /**
  * 每页行数, 构造函数传入
  */
 private int iRowAmt;

 /**
  * 当前行
  */
 private int iRow = 0;

 /**
  * 报表页数
  */
 private int iPageAmt = 0;

 /**
  * 报表数据, 构造函数传入
  */
 protected List data;

 /**
  * 报表列表,保存报表的文件路径
  */
 private List<String> reports = new ArrayList<String>();

 /**
  * 输出默认地址
  */
 private final String default_report_path =  "report_bak/";

 /**
  * 工作簿
  */
 private WritableSheet ws;

 /**
  * @param data
  *            报表数据
  * @param fileName
  *            模板文件名
  * @param iRowAmt
  *            每页行数
  */
 public AbstractExcelReportMaker(List data, String fileName, int iRowAmt) {
  this.data = data;
  this.fileName = fileName;
  this.iRowAmt = iRowAmt;
 }

 /**
  * 报表输出路径
  *
  * @return
  */
 protected String getReportOutputDirectory() {
  return "";
 }

 /**
  * 获取模板文件
  *
  * @return
  */
 protected File getSourceFile() {
  return new File(PluginUtil.getFullPath(DrawbackPlugin.PLUGIN_ID, "report/") + fileName);
 }

 /**
  * 获取生成报表文件
  *
  * @return
  */
 protected File getReportFileUrl() {
  return new File(getReportOutputDirectory() + getOutputFileName());
 }

 /**
  * 获取报表文件名
  *
  * @return
  */
 private String getOutputFileName() {
  return fileName.substring(0, fileName.length() - 4) + iPageAmt + ".xls";
 }

 /**
  * 取字符CELL,用于替换数字类型的CELL
  *
  * @return
  */
 protected abstract Label getLabelCell(WritableSheet ws);

 /**
  * 给单元格赋值
  *
  * @param wc
  * @param value
  * @throws GeneException
  */
 protected void setLableValue(Cell wc, Object value) throws GeneException {
  try {
   // 判断单元格的类型, 做出相应的转化
   if (wc.getType() == CellType.LABEL) {
    setCellValue(wc, value);
   } else if (wc.getType() == CellType.DATE) {
    if (value == null) {
     WritableCell c = getLabelCell(ws).copyTo(wc.getColumn(), wc.getRow());
     setCellValue(c, value);
     ws.addCell(c);
    } else {
     setCellValue(wc, value);
    }
   } else if (wc.getType() == CellType.NUMBER) {
    if (value == null) {
     WritableCell c = getLabelCell(ws).copyTo(wc.getColumn(), wc.getRow());
     setCellValue(c, value);
     ws.addCell(c);
    } else {
     setCellValue(wc, value);
    }
   }
  } catch (GeneException e) {
   throw e;
  } catch (Exception e) {
   throw GeneException.getGeneException(ERR.ERROR_ERR_MSG, "数据类型不匹配");
  }
 }

 private void setCellValue(Cell wc, Object value) throws GeneException {
  try {
   // 判断单元格的类型, 做出相应的转化
   if (wc.getType() == CellType.LABEL) {
    ((Label) wc).setString((String) value);
   } else if (wc.getType() == CellType.DATE) {
    ((DateTime) wc).setDate((Date) value);
   } else if (wc.getType() == CellType.NUMBER) {
    if (value instanceof Integer) {
     ((jxl.write.Number) wc).setValue(((Integer) value).doubleValue());
    } else if (value instanceof BigDecimal) {
     ((jxl.write.Number) wc).setValue(Double.parseDouble(StringUtility
       .strNull((BigDecimal) value)));
    }
   }
  } catch (Exception e) {
   throw GeneException.getGeneException(ERR.ERROR_ERR_MSG, "数据类型不匹配");
  }
 }

 /**
  * 设置拷贝cell的值,一般应用与无限制行的模板
  *
  * @param cell
  * @param col
  * @param row
  * @param value
  * @throws GeneException
  */
 protected void setCopyCellValue(WritableCell cell, int col, int row, Object value)
   throws GeneException {
  WritableCell wc = cell.copyTo(col, row);
  setCellValue(wc, value);
  try {
   ws.addCell(wc);
  } catch (Exception e) {
   throw GeneException.getGeneException(ERR.ERROR_ERR_MSG, "EXCEL数据操作失败");
  }
 }

 /**
  * 生成报表头部
  *
  * @param ws
  */
 protected abstract void reportHeadMaker(WritableSheet ws) throws GeneException;

 /**
  * 生成报表内容
  *
  * @param ws
  * @param i
  *            从0行开始
  */
 protected abstract void reportContentMaker(WritableSheet ws, Object obj, int iRow)
   throws GeneException;

 /**
  * 生成报表底部
  *
  * @param ws
  */
 protected abstract void reportBottomMaker(WritableSheet ws) throws GeneException;

 /**
  * 清除报表模板内容
  *
  * @param ws
  * @param i
  */
 protected abstract void clearReport(WritableSheet ws, int i) throws GeneException;

 /**
  * 每页生成报表小计
  *
  * @param ws
  * @throws GeneException
  */
 protected abstract void reportSubtotalMaker(WritableSheet ws) throws GeneException;

 /**
  * 最后一页生成报表总计
  *
  * @param ws
  * @throws GeneException
  */
 protected abstract void reportTotalizeMaker(WritableSheet ws) throws GeneException;

 /**
  * 对数据进行额外处理
  */
 protected void reportDataProcessor() {
  // do nothing
 }

 /**
  * 是否新页面
  *
  * @return
  */
 protected boolean isNewPage() {
  return iRow % iRowAmt == 0;
 }

 /**
  * 拷贝报表模板到指定路径
  *
  * @throws GeneException
  */
 protected void copyFileToDirectory() throws GeneException {
  try {
   FileUtils.copyFile(getSourceFile(), getReportFileUrl(), false);
  } catch (IOException e) {
   throw GeneException.getGeneException(ERR.FW_IO_FILE_ERR);
  }
 }

 /**
  * 生成报表
  *
  * @throws GeneException
  */
 protected void reportMaker() throws GeneException {
  reportDataProcessor();
  if (data == null || data.size() < 1) {
   throw GeneException.getGeneException(ERR.ERROR_INFO_MSG, "没有找到数据!");
  }
  Workbook rwb = null;
  WritableWorkbook wwb = null;
  try {
   for (int i = 0; i < data.size(); i++) {
    if (isNewPage()) {
     // 关闭原来的工作簿
     if (wwb != null) {
      reportSubtotalMaker(ws);
      wwb.write();
      wwb.close();
      rwb.close();
     }
     // 填写报表
     rwb = Workbook.getWorkbook(this.getSourceFile());
     // 页面加1
     iPageAmt++;
     // 行重置为0
     iRow = 0;
     // 加入报表列表
     reports.add(getReportFileUrl().getPath());
     // copyFileToDirectory();
     // 利用已经创建的Excel工作薄创建新的可写入的Excel工作薄
     wwb = Workbook.createWorkbook(this.getReportFileUrl(), rwb);
     // 读取第一张工作表
     ws = wwb.getSheet(0);
     reportHeadMaker(ws);
     reportBottomMaker(ws);
    }
    reportContentMaker(ws, data.get(i), iRow);
    // 行加1
    iRow++;
   }
   // 清空剩余行内容
   int iClear = data.size() % iRowAmt;
   iClear = iClear == 0 || iRowAmt == Integer.MAX_VALUE ? 0 : iRowAmt - iClear;
   for (int i = 0; i < iClear; i++) {
    clearReport(ws, iRow + i);
   }
   // 生成报表总计
   reportTotalizeMaker(ws);
   // 写入Excel对象
   wwb.write();
  } catch (GeneException e) {
   throw e;
  } catch (IOException e) {
   throw GeneException.getGeneException(ERR.FW_IO_FILE_ERR);
  } catch (Exception e) {
   throw GeneException.getGeneException(ERR.ERROR_ERR_MSG, new String[] { "报表生成意外终止" }, e);
  } finally {
   // 操作完成时,关闭对象,释放占用的内存空间
   if (wwb != null) {
    try {
     wwb.close();
    } catch (Exception e) {
     throw GeneException.getGeneException(ERR.FW_IO_FILE_ERR);
    }
   }
   if (rwb != null) {
    rwb.close();
   }
  }

 }

 /*
  * (non-Javadoc)
  *
  * @see com.jl.drawback.business.entity.IReportMaker#report()
  */
 public List<String> report() throws GeneException {
  // 生成报表
  reportMaker();
  // 返回报表文件路径
  return reports;

 }

 /**
  * 当前报表页数
  *
  * @return
  */
 protected int getPageAmt() {
  return iPageAmt;
 }
}

这个抽象类主要实现按照模板生成报表,出入每页条数,自动生成多个文件(其实可以改成生成一个文件,多个sheet)。下次再举一个实现类。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值