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

原创 2007年09月24日 14:21:00

开发过程中,需要把数据导出到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)。下次再举一个实现类。

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

继承上次的抽象基类,实现一个具体的报表,这个报表没有统计/** * 反馈信息结果 * @author  */public class ExcelReportShydFkMaker extends Ab...
  • bee2518
  • bee2518
  • 2007年09月26日 18:33
  • 565

Java 读写 Excel 数据 - jxl(JExcelAPI)

jxl
  • cool__wang
  • cool__wang
  • 2016年05月31日 15:18
  • 1422

JExcelAPI读写excel文件的例子。支持excel2003文件格式。

import java.io.*;import jxl.*;import jxl.write.*;import jxl.format.*;import java.util.*;import java....
  • wonder4
  • wonder4
  • 2006年07月04日 12:45
  • 10214

全面挖掘Java Excel API 使用方法(JExcelApi)

使用Windows操作系统的朋友对Excel(电子表格)一定不会陌生,但是要使用Java语言来操纵Excel文件并不是一件容易的事。在Web应用日益盛行的今天,通过Web来操作Excel文件的需求越来...
  • kevinwu629
  • kevinwu629
  • 2010年09月09日 16:38
  • 2514

Java操作Excel的2种方法--Poi,jExcelApi

老师让查一些java操作excel的方法,在网上查了半天,看的也不太懂,就把有价值的总结一下。发现java操作Excel的第三方jar包比较多,有两套比较有影响的API可供使用,一个是POI,一个是j...
  • zdwzzu2006
  • zdwzzu2006
  • 2008年04月02日 22:37
  • 1695

java使用JexcelApi和POI两种方法操作excel

在java里面如何操作excel,其中有两种方法:JexcelApi和POI两种方法,参考网上别人做的,发现对于简单的操作,两种效果都不错。在其中JexcelApi操作时,对于在已有表格中添加数据,没...
  • u013766436
  • u013766436
  • 2016年03月16日 20:19
  • 3187

Jxl读写Excel文件

最近要使用Excel文件的导入导出,比较了一下Jxl和poi两种方式,Jxl相对简单,但是不支持xlsx格式的(2003之上版本的),下面先写一下Jxl的demo。无论是那方式,将Excel分为 Wo...
  • fengshizty
  • fengshizty
  • 2015年04月09日 12:14
  • 1603

JExcelAPI与Apache POI两者对比

一,JExcelAPI与Apache POI两者对比  1、JExcelAPI不适合商业应用,它都是会莫名其妙的读不出来数据。  2、Apache POI是一纯Java的实现,不仅能读微软的Excel...
  • pengchua
  • pengchua
  • 2007年08月09日 13:36
  • 5975

java对word、excel、pdf等操作综合文章

原文地址:http://dev.csdn.net/author/lyj_china/3d58e4ea25454e358def5e331dbbf970.html 有人问我如何用java操作word,ex...
  • mimicimim
  • mimicimim
  • 2006年08月03日 10:50
  • 2005

使用 jExcelAPI 操作 Excel 文件

在开源世界中,有两套比较有影响的API可 供使用,一个是POI,一个是jExcelAPI。其中功能相对POI比较弱一点。但jExcelAPI对中文支持非常好,API是纯Java的, 并不 依赖Wind...
  • m13666368773
  • m13666368773
  • 2011年08月10日 17:41
  • 1015
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:jexcelapi写excel文件的抽象类(一)
举报原因:
原因补充:

(最多只允许输入30个字)