JavaJxl开发.docx
《JavaJxl开发.docx》由会员分享,可在线阅读,更多相关《JavaJxl开发.docx(24页珍藏版)》请在冰豆网上搜索。
JavaJxl开发
JavaJXl开发文档
1开发前提
1.1需求
MS的电子表格(Excel)是Office的重要成员,是保存统计数据的一种常用格式。
作为办公文档,势必要涉及到的电子文档的交换,Excel是一种在企业中非常通用的文件格式,打印和管理也比较方便。
在一个Java应用中,将一部分数据生成Excel格式,是与其他系统无缝连接的重要手段。
1.2Excel开发常用开源工具
在开源世界中,有两套比较有影响的API可供使用,一个是POI,一个是jExcelAPI。
1.3比较开源工具的优缺点
1.3.1Jxl优缺点
Jxl特征有如下描述:
●支持Excel95-2000的所有版本
●生成Excel2000标准格式
●支持字体、数字、日期操作
●能够修饰单元格属性
●支持图像和图表
应该说以上功能已经能够大致满足我们的需要。
最关键的是这套API是纯Java的,并不依赖Windows系统,即使运行在Linux下,它同样能够正确的处理Excel文件。
另外需要说明的是,这套API对图形和图表的支持很有限,而且仅仅识别PNG格式。
1.3.2Poi优缺点
Jakarta的POIProject与JavaExcelAPI在开源世界中可以说是并驾齐驱,但是也各有优劣,poi在某些细节有些小Bug并且不支持写入图片(poi其实可以写入图片,不过没有jxl来的方便,比较麻烦),其他方面都挺不错的;而JXL提供了对图片的支持(但是仅仅支持png格式的图片),问题就是对公式支持不是很好,但还是提供了简单的公式读取支持。
因此你的项目中要选用什么样的第三方插件为完全由你的应用来决定。
如果你的软件是跟财务有相当的关系的话,建议采用POIProject,就我所在目前的项目来说由于用不到计算公式,而且很可能需要导出图片,因此,我的选择是JXL。
1.4性能比较以及最终选择
1.4.1内存消耗:
(来自网络)
谈下JVM虚拟机内存消耗的情况.
数据量3000条数据,每条60列.JVM虚拟机内存大小64M.
使用POI:
运行到2800条左右就报内存溢出.
使用JXL:
3000条全部出来,并且内存还有21M的空间.
可想而知,在对内存的消耗方面差距还是挺大的.
也许是由于JXL在对资源回收利用方面做的还挺不错的。
1.4.2速度效率(读取excel数据)(来自网络)
文件POI加载耗时POI总耗时JXL加载耗时Jxl总耗时
文件大小57KB1172ms1172ms1265ms2250ms
文件大小652KB2297ms2313ms4406ms9750ms
文件大小2.24M3109ms3140ms16313ms37453ms
1.4.3写excel速度效率
jxl插入数据比poi速度要快
1.4.4功能对比
相比提供的功能的话,JXL相对弱了点.所以如果要实现的功能比较复杂的情况下可以考虑使用POI,但如果只想生成一些大数据量可以考虑使用JXL,或者CSV也是一个不错的选择,不过CSV并不是真正的excel,然而jxl插入数据比poi速度要快。
2Jxl开发
2.1介绍
jxl操作excel包括对象Workbook,Sheet,Cell。
一个excel就对应一个Workbook对象,
一个Workbook可以有多个Sheet对象
一个Sheet对象可以有多个Cell对象
2.2读取excel操作
通过Workbook,Sheet,Cell这三个对象我们就可以实现Excel文件的读取工作。
我们先想想一下读取步骤,不管是什么样的Excel操作框架必定都要经历
1、选取Excel文件得到工作薄
2、选择工作表
3、选择Cell
4、读取信息
2.2.1读取工作薄
选取Excel文件得到工作薄Workbook
Workbookworkbook=Workbook.getWorkbook(newFile("myfile.xls"));
2.2.2读取工作表
通过Workbook的getSheet方法选择第一个工作表(从0开始)
Sheetsheet=workbook.getSheet(0);
也可以通过工作的名称来得到Sheet
2.2.3读取单元格
通过Sheet的getCell方法选择位置为C2的单元格(两个参数都从0开始)
Cellc2=sheet.getCell(2,1);
2.2.3.1读取单元格的值
2.2.3.2通过Cell的getContents方法
把单元格中的信息以字符的形式读取出来Stringstringc2=c2.getContents();
2.2.3.3Cell提供了一个getType方法
能够返回单元格的类型信息,同时JXL提供了一个CellType类用来预设Excel中的类型信息,而且JXL提供了一些Cell类的子类用来分别用来表示各种类型的单元格,如LabelCell,NumberCell,DateCell分别表示字符、数值、日期类型的单元格
if(c2.getType()==CellType.LABEL)
{
LabelCellnc=(LabelCell)c2;
Stringnumberb2=nc.getString();
}
if(c2.getType()==CellType.DATE)
{
DateCellnc=(DateCell)c2;
Datenumberb2=nc.getDate();
}
if(c2.getType()==CellType.NUMBER)
{
NumberCellnc=(NumberCell)c2;
doublenumberb2=nc.getValue();
}
API提供了以下基本类型,与Excel的数据格式相对应,如下图所示
2.2.4以释放资源:
workbook.close()
当你完成对Excel电子表格数据的处理后,一定要使用close()方法来关闭先前创建的对象,以释放读取数据表的过程中所占用的内存空间,在读取大量数据时显得尤为重要
最后不要忘记关闭workbook以释放资源:
workbook.close();
2.3写excel操作
通过WritableWorkbook,WritableSheet,Label这三个对象我们就可以实现Excel文件的插入工作。
我们先想想一下插入,不管是什么样的Excel操作框架必定都要经历
1、创建Exce工作薄
2、创建工作表
3、创建单元格
2.3.1创建工作薄
API提供了两种方式来处理可写入的输出流,一种是直接生成本地文件,如果文件名不带全路径的话,缺省的文件会定位在当前目录,如果文件名带有全路径的话,则生成的Excel文件则会定位在相应的目录;另外一种是将Excel对象直接写入到输出流,例如:
用户通过浏览器来访问Web服务器,如果HTTP头设置正确的话,浏览器自动调用客户端的Excel应用程序,来显示动态生成的Excel电子表格。
2.3.1.1创建可写入的Excel工作薄
WritableWorkbook
wwb=Workbook.createWorkbook(newFile(targetfile));
2.3.1.2将WritableWorkbook直接写入到输出流
OutputStreamos=newFileOutputStream(targetfile);
WritableWorkbookwwb=Workbook.createWorkbook(os);
2.3.2创建工作表
WritableSheetws=wwb.createSheet("通讯录",0);//创建sheet
2.3.3创建单元格
2.3.3.1添加文本类单元格
LabellabelC=newLabel(0,0,"ThisisaLabelcell");
2.3.3.2添加带有字型Formatting的对象
WritableFontwf=newWritableFont(WritableFont.TIMES,18,WritableFont.BOLD,true);
WritableCellFormatwcfF=newWritableCellFormat(wf);
labelCF=newLabel(1,0,"ThisisaLabelCell",wcfF);
ws.addCell(labelCF);
2.3.3.3添加带有字体颜色Formatting的对象
WritableFontwfc=newWritableFont(WritableFont.ARIAL,10,WritableFont.NO_BOLD,false,
UnderlineStyle.NO_UNDERLINE,jxl.format.Colour.RED);
WritableCellFormatwcfFC=newWritableCellFormat(wfc);
LabellabelCFC=newLabel(1,0,"ThisisaLabelCell",wcfFC);
ws.addCell(labelCF);
2.3.3.4添加Number对象
NumberlabelN=newjxl.write.Number(0,1,3.1415926);
ws.addCell(labelN);
2.3.3.5添加带有formatting的Number对象
NumberFormatnf=newNumberFormat("#.##");
WritableCellFormatwcfN=newWritableCellFormat(nf);
NumberlabelNF=newNumber(1,1,3.1415926,wcfN);
ws.addCell(labelNF);
2.3.3.6添加Boolean对象
BooleanlabelB=newjxl.write.Boolean(0,2,false);
ws.addCell(labelB);
2.3.3.7添加DateTime对象
DateTimelabelDT=newDateTime(0,3,newjava.util.Date());
ws.addCell(labelDT);
2.3.3.8添加带有formatting的DateFormat对象
DateFormatdf=newDateFormat("ddMMyyyyhh:
mm:
ss");
WritableCellFormatwcfDF=newWritableCellFormat(df);
DateTimelabelDTF=newDateTime(1,3,newDate(),wcfDF);
ws.addCell(labelDTF);
2.3.3.9添加公式单元格
Formualformual=newFormual(0,11,”Sum(A1:
A9)”);
wrb.addCell(formual);
2.3.3.10添加图像
WritableImagewrimage=newWritableImage(1,5,10,10,newFile(imageFilepath));
wrb.addImage(wrimage);
注意,API中注明只支持png文件。
2.3.4合并单元格
通过writablesheet.mergeCells(intx,inty,intm,intn);来实现的。
表示将从第x+1列,y+1行到m+1列,n+1行合并(四个点定义了两个坐标,左上角和右下角)结果是合并了m-x+1行,n-y+1列,两者乘积就是合并的单元格数量。
sheet.mergeCells(0,6,3,8);
label=newLabel(0,6,"合并了12个单元格");
sheet.addCell(label);
2.3.5添加单元格样式
主要是改变单元格背景、字体、颜色等等。
WritableCellFormatwc=newWritableCellFormat();
wc.setAlignment(Alignment.CENTRE);//设置居中
wc.setBorder(Border.ALL,BorderLineStyle.THIN);//设置边框线
wc.setBackground(jxl.format.Colour.RED);//设置单元格的背景颜色
label=newLabel(1,5,"字体",wc);
sheet.addCell(label);
2.3.6设置单元格字体
WritableFontwfont=
newWritableFont(WritableFont.createFont("楷书"),20);
WritableCellFormatfont=newWritableCellFormat(wfont);
label=newLabel(2,6,"楷书",font);
sheet.addCell(label);
2.3.7写入到文件
wwb.write();//写入数据
wwb.close();//关闭文件
2.4拷贝、更新Excel工作薄
//创建只读的Excel工作薄的对象
jxl.Workbookrw=jxl.Workbook.getWorkbook(newFile(sourcefile));
//创建可写入的Excel工作薄对象
WritableWorkbookwwb=Workbook.createWorkbook(newFile(targetfile),rw);
//读取第一张工作表
jxl.write.WritableSheetws=wwb.getSheet(0);
//获得第一个单元格对象
jxl.write.WritableCellwc=ws.getWritableCell(0,0);
//判断单元格的类型,做出相应的转化
if(wc.getType()==CellType.LABEL)
{
Labell=(Label)wc;
l.setString("Thevaluehasbeenmodified.");
}
//写入Excel对象
wwb.write();
//关闭可写入的Excel对象
wwb.close();
//关闭只读的Excel对象
rw.close();
为了提高性能,在读取工作表时,与数据相关的一些输出信息,所有的格式信息,如:
字体、颜色等等,是不被处理的,因为我们的目的是获得行数据的值,既使没有了修饰,也不会对行数据的值产生什么影响。
唯一的不利之处就是,在内存中会同时保存两个同样的工作表,这样当工作表体积比较大时,会占用相当大的内存,但现在好像内存的大小并不是什么关键因素了。
一旦获得了可写入的工作表对象,我们就可以对单元格对象进行更新的操作了,在这里我们不必调用API提供的add()方法,因为单元格已经于工作表当中,所以我们只需要调用相应的setXXX()方法,就可以完成更新的操作了。
尽单元格原有的格式化修饰是不能去掉的,我们还是可以将新的单元格修饰加上去,以使单元格的内容以不同的形式表现。
新生成的工作表对象是可写入的,我们除了更新原有的单元格外,还可以添加新的单元格到工作表中。
最后,不要忘记调用write()方法,将更新的内容写入到文件中,然后关闭工作薄对象,这里有两个工作薄对象要关闭,一个是只读的,另外一个是可写入的。
3JXL读写excel文件的例子
3.1实例一
importjava.io.FileOutputStream;
importjava.io.OutputStream;
importjava.text.SimpleDateFormat;
importjava.util.ArrayList;
importjava.util.Date;
importjava.util.List;
importjxl.*;
importjxl.format.Alignment;
importjxl.format.Border;
importjxl.format.BorderLineStyle;
importjxl.format.CellFormat;
importjxl.write.Boolean;
importjxl.write.Label;
importjxl.write.Number;
importjxl.write.WritableCellFormat;
importjxl.write.WritableFont;
importjxl.write.WritableSheet;
importjxl.write.WritableWorkbook;
publicclassJXLExample{
/**
*
*@authorsmart*
*/
publicstaticvoidmain(String[]args){
//准备设置excel工作表的标题
String[]title={"编号","产品名称","产品价格","产品数量","生产日期","产地","是否出口"};
try{
//获得开始时间
longstart=System.currentTimeMillis();
//输出的excel的路径
StringfilePath="c:
\\test.xls";
//创建Excel工作薄
WritableWorkbookwwb;
//新建立一个jxl文件,即在C盘下生成test.xls
OutputStreamos=newFileOutputStream(filePath);
wwb=Workbook.createWorkbook(os);
//添加第一个工作表并设置第一个Sheet的名字
WritableSheetsheet=wwb.createSheet("产品清单",0);
Labellabel;
for(inti=0;i
label=newLabel(i,0,title[i]);
//将定义好的单元格添加到工作表中
sheet.addCell(label);
}
/*
*保存数字到单元格,需要使用jxl.write.Number
*必须使用其完整路径,否则会出现错误
**/
//填充产品编号
jxl.write.Numbernumber=newjxl.write.Number(0,1,20071001);
sheet.addCell(number);
//填充产品名称
label=newLabel(1,1,"金鸽瓜子");
sheet.addCell(label);
/*
*定义对于显示金额的公共格式
*jxl会自动实现四舍五入
*例如2.456会被格式化为2.46,2.454会被格式化为2.45
**/
jxl.write.NumberFormatnf=newjxl.write.NumberFormat("#.##");
jxl.write.WritableCellFormatwcf=newjxl.write.WritableCellFormat(nf);
//填充产品价格
jxl.write.Numbernb=newjxl.write.Number(2,1,2.45,wcf);
sheet.addCell(nb);
//填充产品数量
jxl.write.Numbernumb=newjxl.write.Number(3,1,200);
sheet.addCell(numb);
/*
*定义显示日期的公共格式
*如:
yyyy-MM-ddhh:
mm
**/
SimpleDateFormatsdf=newSimpleDateFormat("yyyy-MM-dd");
Stringnewdate=sdf.format(newDate());
//填充出产日期
label=newLabel(4,1,newdate);
sheet.addCell(label);
//填充产地
label=newLabel(5,1,"陕西西安");
sheet.addCell(label);
/*
*显示布尔值
**/
jxl.write.Booleanbool=newjxl.write.Boolean(6,1,true);
sheet.addCell(bool);
/*
*合并单元格
*通过writablesheet.mergeCells(intx,inty,intm,intn);来实现的
*表示将从第x+1列,y+1行到m+1列,n+1行合并
*
**/
sheet.mergeCells(0,3,2,3);
label=newLabel(0,3,"合并了三个单元格");
sheet.addCell(label);
/*
*
*定义公共字体格式
*通过获取一个字体的样式来作为模板
*首先通过web.getSheet(0)获得第一个sheet
*然后取得第一个sheet的第二列,第一行也就是"产品名称"的字体
**/
CellFormatcf=wwb.getSheet(0).getCell(1,0).getCellFormat();
WritableCellFormatwc=newWritableCellFormat();
//设置居中
wc.setAlignment(Alignment.CENTRE);
//设置边框线
wc.setBorder(Border.ALL,BorderLineStyle.THIN);
//设置单元格的背景颜色
wc.setBackground(jxl.format.Colour.RED);
label=newLabel(1,5,"字体",wc);
sheet.addCell(label);
//设置字体
WritableFontwfont=newWritableFont(W