借鉴第一个网友的:
目前在项目中,因为需要操作Excel,所以对相关的excel开源项目进行了了解,目前对excel的操作支持比较完善的主有两个项目:一个是POI,一个是JXL。
关于POI与JXL的大致区别为:
Jxl对中文支持非常好,操作简单,方法看名知意。
Jxl是纯javaAPI,在跨平台上表现的非常完美,代码可以再windows或者Linux上运行而无需重新编写
支持Excel 95-2000的所有版本
生成Excel 2000标准格式
支持字体、数字、日期操作
能够修饰单元格属性
支持图像和图表,但是这套API对图形和图表的支持很有限,而且仅仅识别PNG格式。
缺点:效率低,图片支持部完善,对格式的支持不如POI强大
POI
1. 效率高,这点很好
2. 支持公式,宏,一些企业应用上会非常实用
3. 能够修饰单元格属性
4. 支持字体、数字、日期操作
缺点:不成熟,代码不能跨平台。
这里再补充点更细节的区别,首先是POI不提供直接的通过单元格名称获取,如excel的某个单元格是B5,那么POI获取此单元格必须按行和列的编号进行获取,方法如getCell(1,4)这样;而JXL非常简单可以直接进行获取,方法如getCell("B5")这样。
还有一点是它们都具有一个共同的特点,就是都不提供复制功能,我所说的复制是从一个xls文件里的sheet复制到另一个xls文件里(不过POI提供在一个xls文件里的sheet复制)。后来我自己实现复制的操作。也略微明白了为什么它们都不提供复制功能,一个原因就是太复杂了。
关于POI复制(JXL也一样)需要注意以下几点:
1、printSetup的复制
2、CellStyle的复制
3、单元格合并
4、单元格隐藏
5、冻结窗口
6、FontStyle和Comment
7、各种单元格的类型(如数字型、字符型、公式类型、背景颜色等)
其中Cellstyle和FontStyle的复制有个小问题需要注意,就是不能创建太多的CellStyle和FontStyle,不然复制完成后,复制文件的大小比被复制文件的大小大很多。还有打开复制文件会报“单元格字体类型太多”或者是“单元格风格太多”之类的错误信息。CellStyle和FontStyle都需要进行缓存的方式进行处理。
借鉴第二个网友的:
测试环境:
jxl包:好像是1.4 低于2.0 (忘记了)
poi:poi-3.5-FINAL-20090928.jar
环境:CPU:Pentium(R) 1.4GHZ ,1.5GB内存 MyEclipse5.0 JDK1.5
机器不行,不同电脑上跑出效果不一样,但是仍然可以窥视到POI和jxl效率
- package com.jarvis.mul;
- import java.io.File;
- import java.io.FileInputStream;
- import java.io.FileNotFoundException;
- import java.io.FileOutputStream;
- import java.io.IOException;
- import java.io.InputStream;
- import java.util.HashMap;
- import jxl.Cell;
- import jxl.LabelCell;
- import jxl.Sheet;
- import jxl.Workbook;
- import jxl.read.biff.BiffException;
- import org.apache.poi.hssf.usermodel.HSSFCell;
- import org.apache.poi.hssf.usermodel.HSSFName;
- import org.apache.poi.hssf.usermodel.HSSFRow;
- import org.apache.poi.hssf.usermodel.HSSFSheet;
- import org.apache.poi.hssf.usermodel.HSSFWorkbook;
- /**
- * @作者 Jarvis
- * @创建日期 Dec 2, 2009
- * @版本 V 1.0
- */
- public class PoiredadXLS {
- String filepath ="E:/5.xls" ;
- public void readSpeed(){
- try {
- // 创建对Excel工作簿文件的引用
- long t1 = System.currentTimeMillis();
- FileInputStream rs = new FileInputStream(filepath) ;
- HSSFWorkbook workbook = new HSSFWorkbook(rs);
- long t2 = System.currentTimeMillis();
- System.out.println("加载耗时:"+ (t2-t1));
- HashMap map = new HashMap();
- int total = workbook.getNumberOfSheets(); //获取sheet个数
- int start = 0;int end = 0 ;
- for(int i = 0 ; i < total ; i ++){
- HSSFSheet sheet = workbook.getSheetAt(i);// 按索引获取sheet引用
- System.out.println(sheet.getSheetName());
- start = sheet.getFirstRowNum(); //sheet起始行索引
- end = sheet.getLastRowNum();//sheet起结束行索引
- int temp = 1;
- HSSFRow row = null ;
- HSSFCell cell1 = null ;
- HSSFCell cell2 = null ;
- while(temp < end){
- row = sheet.getRow(temp);//获取第N行表格数据
- cell1 = row.getCell(2);//获取指定列单元格
- cell2 = row.getCell(3);//获取指定列单元格
- if(cell1 != null && cell1!= null){
- map.put(cell1.toString(), cell2.toString()) ;
- }
- temp ++ ;
- }
- }
- } catch (FileNotFoundException e) {
- // TODO Auto-generated catch block
- e.printStackTrace();
- } catch (IOException e) {
- // TODO Auto-generated catch block
- e.printStackTrace();
- }
- }
- public void readExcel(){
- try {
- HashMap map = new HashMap();
- long t1 = System.currentTimeMillis();
- FileInputStream is = new FileInputStream(filepath);
- Workbook rwb = Workbook.getWorkbook(is); // 从输入流创建Workbook
- long t2 = System.currentTimeMillis();
- System.out.println("加载耗时:"+ (t2-t1));
- String[] sheetname = rwb.getSheetNames();//获取所有的sheet名称,返回一个String数组
- int sleng = sheetname.length ;
- for(int i = 0 ; i < sleng ; i ++){
- Sheet sheet = rwb.getSheet(sheetname[i]) ;
- System.out.println(sheetname[i]);
- int rows = sheet.getRows();//获取表格的总行数
- int temp = 1;
- Cell cell1 = null ;
- Cell cell2 = null ;
- while(temp < rows){
- cell1 = sheet.getCell(2, temp);//第一个参数代表列 第二个参数代表行
- cell2 = sheet.getCell(3, temp);//第一个参数代表列 第二个参数代表行
- if(cell1 != null && cell2 != null){
- map.put(cell1.getContents(), cell2.getContents()) ;
- }
- temp ++ ;
- }
- }
- rwb.close();//关闭工作薄 流
- } catch (BiffException e) {
- // TODO Auto-generated catch block
- e.printStackTrace();
- } catch (IOException e) {
- // TODO Auto-generated catch block
- e.printStackTrace();
- }
- }
- public static void main(String[] args) {
- PoiredadXLS r = new PoiredadXLS();
- long s = System.currentTimeMillis();
- r.readSpeed();
- r.readExcel();
- long e = System.currentTimeMillis();
- System.out.println("总耗时:"+ (e-s));
- }
- }
package com.jarvis.mul;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.HashMap;
import jxl.Cell;
import jxl.LabelCell;
import jxl.Sheet;
import jxl.Workbook;
import jxl.read.biff.BiffException;
import org.apache.poi.hssf.usermodel.HSSFCell;
import org.apache.poi.hssf.usermodel.HSSFName;
import org.apache.poi.hssf.usermodel.HSSFRow;
import org.apache.poi.hssf.usermodel.HSSFSheet;
import org.apache.poi.hssf.usermodel.HSSFWorkbook;
/**
* @作者 Jarvis
* @创建日期 Dec 2, 2009
* @版本 V 1.0
*/
public class PoiredadXLS {
String filepath ="E:/5.xls" ;
public void readSpeed(){
try {
// 创建对Excel工作簿文件的引用
long t1 = System.currentTimeMillis();
FileInputStream rs = new FileInputStream(filepath) ;
HSSFWorkbook workbook = new HSSFWorkbook(rs);
long t2 = System.currentTimeMillis();
System.out.println("加载耗时:"+ (t2-t1));
HashMap map = new HashMap();
int total = workbook.getNumberOfSheets(); //获取sheet个数
int start = 0;int end = 0 ;
for(int i = 0 ; i < total ; i ++){
HSSFSheet sheet = workbook.getSheetAt(i);// 按索引获取sheet引用
System.out.println(sheet.getSheetName());
start = sheet.getFirstRowNum(); //sheet起始行索引
end = sheet.getLastRowNum();//sheet起结束行索引
int temp = 1;
HSSFRow row = null ;
HSSFCell cell1 = null ;
HSSFCell cell2 = null ;
while(temp < end){
row = sheet.getRow(temp);//获取第N行表格数据
cell1 = row.getCell(2);//获取指定列单元格
cell2 = row.getCell(3);//获取指定列单元格
if(cell1 != null && cell1!= null){
map.put(cell1.toString(), cell2.toString()) ;
}
temp ++ ;
}
}
} catch (FileNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
public void readExcel(){
try {
HashMap map = new HashMap();
long t1 = System.currentTimeMillis();
FileInputStream is = new FileInputStream(filepath);
Workbook rwb = Workbook.getWorkbook(is); // 从输入流创建Workbook
long t2 = System.currentTimeMillis();
System.out.println("加载耗时:"+ (t2-t1));
String[] sheetname = rwb.getSheetNames();//获取所有的sheet名称,返回一个String数组
int sleng = sheetname.length ;
for(int i = 0 ; i < sleng ; i ++){
Sheet sheet = rwb.getSheet(sheetname[i]) ;
System.out.println(sheetname[i]);
int rows = sheet.getRows();//获取表格的总行数
int temp = 1;
Cell cell1 = null ;
Cell cell2 = null ;
while(temp < rows){
cell1 = sheet.getCell(2, temp);//第一个参数代表列 第二个参数代表行
cell2 = sheet.getCell(3, temp);//第一个参数代表列 第二个参数代表行
if(cell1 != null && cell2 != null){
map.put(cell1.getContents(), cell2.getContents()) ;
}
temp ++ ;
}
}
rwb.close();//关闭工作薄 流
} catch (BiffException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
public static void main(String[] args) {
PoiredadXLS r = new PoiredadXLS();
long s = System.currentTimeMillis();
r.readSpeed();
r.readExcel();
long e = System.currentTimeMillis();
System.out.println("总耗时:"+ (e-s));
}
}
测试数据和结果如下:
文件 POI加载耗时 POI总耗时 JXL加载耗时 Jxl总耗时
文件大小57KB 1172 ms 1172 ms 1265 ms 2250 ms
100行数据
文件大小652KB 2297 ms 2313 ms 4406 ms 9750 ms
1000行数据
文件大小2.24M 3109ms 3140ms 16313ms 37453ms
大约6000行数据