java处理excel的一点实践积累
java处理excel的一点实践积累
作者:佟亮 日期:2008-11-06
1 文档说明
目的:编写本文档主要的目的是与大家分享下如何用java处理excel,文档中的代码一部分来自《企业项目管理系统V2.0》的源码,一部分copy网上的。
背景:使用Windows操作系统的同事对Excel(电子表格)一定不会陌生,但是要使用Java语言来操纵Excel文件并不是一件容易的事。在Web应用日益盛行的今天,通过Web来操作Excel文件的需求越来越强烈。
2 需求
本部分与技术无关,没兴趣的同事可以跳过直接看下一章。
之所以我要把“需求”单列出来讲讲,是因为通过实现这个需要,我学到的不只是技术,更重要的是思想和工作的方式。客户的原始需求是,在web系统实现数据以表格的形式录入,然后对这些数据能够进行公式计算处理(一部分表格里面配置的是公式)。当时接到这个需求的时候,我们二话没说直接用js画表格,js实现公式的计算。结果由于客户不断的按照excel中的功能要求我们实现,我们终于吃不消了,要知道联通的这个需求实际上是excel的全部功能呀。闭门造车的我们殊不知早在几年前就已经有类似的weboffice中间件了。造成我们有这么失误的主要原因是思想的局限和工作方式的死板,所以这是我的一个教训,希望看到文档的同事引以为鉴。之后我们引用了金格公司的weboffice2003这个中间件,其实我们用的只是通过这个中间件将excel在jsp页面打开,然后将excel的内容用他封装的提交方式发送给action,然后我们在action、Bo、dao中处理这个excel,其中如何处理excel就是我接下来要讲的。
3 技术实现
要学习java处理excel,首先大家需要了解jxl这个包,我们引用的所有方法都来自这个包,我的介绍也主要围绕着这个包里的类和方法展开。
3.1 读excel
3.1.1 读取本地excel文件
读取Excel数据表的第一步是创建Workbook(术语:工作薄)。
InputStream is = new FileInputStream(sourcefile[w1] );
Workbook wb = Workbook.getWorkbook(is);
创建了Workbook对象,我们就可以通过它来访问Excel Sheet(术语:工作表)。
Sheet rs = rwb.getSheet(0[w2] );
类似这样还可以取到Cell对象,以及cell的相应属性信息。大家可以查看jxl的api文档。
此外,当你完成对Excel电子表格数据的处理后,一定要使用close()方法来关闭先前创建的对象,以释放读取数据表的过程中所占用的内存空间,在读取大量数据时显得尤为重要。 wb.close();
3.1.2 读取数据库文件
与读取本地excel类似,区别在于输入流的获取。一般excel在数据库以blob类型存储,所以我们在查询的时候要读blob字段,获取输入流。
代码如下:
InputStream instream = vField[w3] .getBinaryStream();
3.2 写excel文件
3.2.1 创建excel文件
3.2.1.1 创建方式
1、写到本地文件
WritableWorkbook wwb = Workbook.createWorkbook(new File(targetfile[w4] ));
2、直接写入到输出流
ByteArrayOutputStream outs = new ByteArrayOutputStream();
WritableWorkbook wb = Workbook.createWorkbook(outs);
3.2.1.2 创建步骤
1、创建可写的Workbook[w5] (createWorkbook)。
2、创建可写的Sheet[w6] (createSheet)。
3、如果想美化生成的excel可以创建WritableFont,WritableCellFormat来设定颜色,字体等
4、添加Number对象,.添加Boolean对象,添加DateTime对象,添加Label对象及使用mergeCells方法合并单元格。
5、写入Exel工作表 wb.write();
6、关闭Excel工作薄对象wb.close();
详细代码见备注4.1
3.2.2 修改excel文件
3.2.2.1 获取方式
1、本地文件
InputStream is = new FileInputStream(sourcefile[w7] );
ByteArrayOutputStream outs = new ByteArrayOutputStream();
2、数据库对象
InputStream instream = vField[w8] .getBinaryStream();
ByteArrayOutputStream outs = new ByteArrayOutputStream();
3.2.2.2 修改步骤
1、创建可写的Workbook[w9] 。
wwbook = Workbook.createWorkbook(outstream, this.rwbook,new WorkbookSettings());
接下来的操作和创建excel一样,返回的都是一个输出流。你可以对这个输出流做你想要的操作。
详细代码见备注4.2
4 备注
4.1 创建excel文件代码举例
//1.添加Label对象
Label labelC = new jxl.write.Label(0, 0, "This is a Label cell");
ws.addCell(labelC);
//添加带有字型Formatting的对象
jxl.write.WritableFont wf = new jxl.write.WritableFont(WritableFont.TIMES, 18, WritableFont.BOLD, true);
jxl.write.WritableCellFormat wcfF = new jxl.write.WritableCellFormat(wf);
jxl.write.Label labelCF = new jxl.write.Label(1, 0, "This is a Label Cell", wcfF);
ws.addCell(labelCF);
//添加带有字体颜色Formatting的对象
jxl.write.WritableFont wfc = new jxl.write.WritableFont(WritableFont.ARIAL, 10, WritableFont.NO_BOLD, false,
UnderlineStyle.NO_UNDERLINE, jxl.format.Colour.RED);
jxl.write.WritableCellFormat wcfFC = new jxl.write.WritableCellFormat(wfc);
jxl.write.Label labelCFC = new jxl.write.Label(1, 0, "This is a Label Cell", wcfFC);
ws.addCell(labelCF);
//2.添加Number对象
jxl.write.Number labelN = new jxl.write.Number(0, 1, 3.1415926);
ws.addCell(labelN);
//添加带有formatting的Number对象
jxl.write.NumberFormat nf = new jxl.write.NumberFormat("#.##");
jxl.write.WritableCellFormat wcfN = new jxl.write.WritableCellFormat(nf);
jxl.write.Number labelNF = new jxl.write.Number(1, 1, 3.1415926, wcfN);
ws.addCell(labelNF);
//3.添加Boolean对象
jxl.write.Boolean labelB = new jxl.write.Boolean(0, 2, false);
ws.addCell(labelB);
//4.添加DateTime对象
jxl.write.DateTime labelDT = new jxl.write.DateTime(0, 3, new java.util.Date());
ws.addCell(labelDT);
//添加带有formatting的DateFormat对象
jxl.write.DateFormat df = new jxl.write.DateFormat("dd MM yyyy hh:mm:ss");
jxl.write.WritableCellFormat wcfDF = new jxl.write.WritableCellFormat(df);
jxl.write.DateTime labelDTF = new jxl.write.DateTime(1, 3, new java.util.Date(), wcfDF);
ws.addCell(labelDTF);
4.2 修改excel文件代码举例
/**
* <p>Description: 初始化模板信息</p>
* <p>Remark: </p>
* @return
* @throws ServiceException
*/
public AccessoryVO doInit(String initExtId,String departmentCode) throws ServiceException
{
AccessoryVO accessoryVO = new AccessoryVO();
/*重新初始化,通过初始化编号获得规划模板编号*/
String templateExtId = initDAO.getTemplateIdByInitId(initExtId);
String rpSno = initDAO.getRpSno(templateExtId);
FilloutVO filloutVO = new FilloutVO();
filloutVO.setRpSno(rpSno);
filloutVO.setDepartmentCode(departmentCode);
List list= initDAO.getHistoryData(filloutVO);
// initDAO.updateFilloutStatus("5",initExtId);
/*获得初始化模板*/
InputStream ins = initDAO.getExcelTemplate(templateExtId);
/*获得空附件输出流*/
ByteArrayOutputStream outs = new ByteArrayOutputStream();
createExcel(ins,outs,list);
accessoryVO.setAccessoryBody(outs.toByteArray());
//initDAO.updateRpStatus("5",rpSno);
try
{
if(outs!=null)
{
outs.close();
}
if(ins!=null)
{
ins.close();
}
}
catch (IOException e)
{
// TODO Auto-generated catch block
e.printStackTrace();
}
return accessoryVO;
}
/**
* <p>Description: 生成带初始化数据的excel</p>
* <p>Remark: </p>
* @return
* @throws ServiceException
*/
public String createExcel(InputStream ins,OutputStream outs,List list)
throws ServiceException
{
changeWorkbookByStream(ins,outs);
try
{
WritableWorkbook book = null;
book = this.wwbook;
//设置格式
jxl.write.NumberFormat nf = new jxl.write.NumberFormat("#,###");
jxl.write.WritableCellFormat wcfN = new jxl.write.WritableCellFormat(nf);
wcfN.setBorder(Border.ALL,BorderLineStyle.THIN);
wcfN.setVerticalAlignment(VerticalAlignment.CENTRE);
int length = list.size();
WritableSheet rs = null;
RdVO vo = null;
//循环取得处理sheet数据
for(int j = 0;j<length;j++){
vo = (RdVO)list.get(j);
sheetId = vo.getSheetId();
cellRow = vo.getCellRow();
cellColumn = vo.getCellColumn();
rpData = NullProcessUtil.nvlToString(vo.getRpData(), "0");
rs = (WritableSheet)book.getSheet(Integer.parseInt(sheetId));
labeltemp = new Number( Integer.parseInt(cellColumn),Integer.parseInt(cellRow), Double.parseDouble(rpData),wcfN);
((WritableSheet) rs).addCell(labeltemp);
}
book.write();
//关闭book,释放资源
book.close();
rwbook.close();
}catch(Exception e){
errorMsg = e.getMessage();
//errorMsg += " 错误在行 :"+rowTemp+" 列:"+colTemp;
System.out.println("出错了啊!!"+errorMsg);
System.out.println(e);
e.printStackTrace();
return this.errorMsg;
}
return this.errorMsg;
}
/**
* 变更取得Workbook的方式为流获取
* @author
* @date Jun 2, 2008
* @return void
*/
public void changeWorkbookByStream(InputStream instream,OutputStream outstream) {
try {
this.rwbook = Workbook.getWorkbook(instream);
System.out.println("this.wbook init() OK!!");
} catch (IOException e) {
e.printStackTrace();
} catch (BiffException e) {
e.printStackTrace();
}
try {
this.wwbook = Workbook.createWorkbook(outstream, this.rwbook,new WorkbookSettings());
} catch (IOException e) {
e.printStackTrace();
}
}