首页 诗词 字典 板报 句子 名言 友答 励志 学校 网站地图
当前位置: 首页 > 教程频道 > 其他教程 > 开源软件 >

JXL调用copySheet()和importSheet()方法时报错误

2012-09-29 
JXL调用copySheet()和importSheet()方法时报异常处理EXCEL的开源java util中我了解的有JXL、POI。而我一直是

JXL调用copySheet()和importSheet()方法时报异常
处理EXCEL的开源java util中我了解的有JXL、POI。
而我一直是用jxl来处理excel文件的,之前只是用它来做简单的读写等操作,因此觉得这个jxl还是比较简单轻便的。然而,最近项目中客户有一个带宏(Macro)的sheet要做处理,而JXL貌似在处理带宏的excel方面有些局限(不是一点点),不是很能够处理这方面内容。
我查看了jxl的API文档,发现在jxl.WorkbookSettings中有这么一段:
java.lang.NullPointerException at jxl.write.biff.WritableSheetCopier.shallowCopyCells(WritableSheetCopier.java:499) [jxl.ja r:na] at jxl.write.biff.WritableSheetCopier.copySheet(WritableSheetCopier.java:239) [jxl.jar:na] at jxl.write.biff.WritableSheetImpl.copy(WritableSheetImpl.java:1622) [jxl.jar:na] at jxl.write.biff.WritableWorkbookImpl.copySheet(WritableWorkbookImpl.java:987) [jxl.jar:na]
今天跟了下jexcel的源代码,发现在jxl.write.biff.WritableSheetCopier.shallowCopyCells方法中

if (c.getCellFeatures() != null & c.getCellFeatures().hasDataValidation())  {      validatedCells.add(c);  } 

代码中少写了一个&符,虽然也可以用来表示“且”的逻辑,但一个&符是没有用到短路算法的,这样就会导致不 管&前面表达式的结果是true还是flase,&符后面的表达式都会执行。在这段代码中,在c.getCellFeatures()是 null 的情况下,c.getCellFeatures().hasDataValidation()必然会报 java.lang.NullPointerException异常。

http://www.oschina.net/question/42346_67474

我在jxl的原站上http://www.andykhan.com/jexcelapi/download.html下载了最新版本的源包,并查看了源码,发现确实如以上网友所言。

并且,我在网上找到了一个jxl.jar(688 KB),这个jar包与最新版本有区别,我调用这个包就不会出异常,我想应该是好心人已经把源码修正了并打包成jar包,这里我也把它贴出来,好方便大家使用,省得自己还得修改源码再打包,浪费时间。

现在,用新jxl包,copySheet()出异常问题解决了,并且,我可以按上面我的想法尝试用jxl能否对带宏(macro)的sheet进行copy,以下是具体实现代码:
package test_JXL;import java.io.File;import jxl.Sheet;import jxl.Workbook;import jxl.WorkbookSettings;import jxl.write.WritableSheet;import jxl.write.WritableWorkbook;public class Test_JXL_copysheet {File to_file,from_file;public Test_JXL_copysheet(String from_filename, String to_filename) {to_file = new File(to_filename);from_file = new File(from_filename);try {WritableWorkbook to_wwb; //创建可写入workbook对象if(!this.to_file.exists()) {//如果该文件不存在,则先创建一个wwbto_wwb = Workbook.createWorkbook(this.to_file);} else {//如果该文件已经存在,则应该是获取该workbook,并update其Workbook rw = jxl.Workbook.getWorkbook(this.to_file);to_wwb = Workbook.createWorkbook(this.to_file, rw);}WritableSheet ws = to_wwb.createSheet("Product Tree", to_wwb.getNumberOfSheets()); //创建工作表1 -- Tree型文件jxl.write.Label label = new jxl.write.Label(0, 0, "This is Sheet 1"); //写excel单元格数据ws.addCell(label);//--------testing...------------------------WorkbookSettings newSettings = new WorkbookSettings();newSettings.setPropertySets(true);Workbook from_rw = jxl.Workbook.getWorkbook(this.from_file, newSettings);Sheet from_sheet1 = from_rw.getSheet(0);Sheet from_sheet2 = from_rw.getSheet(1);WritableWorkbook from_wwb = Workbook.createWorkbook(this.from_file, from_rw, newSettings);from_wwb.copySheet(1, "yes", 2);to_wwb.copySheet("Product Tree", "copy", 1);to_wwb.importSheet("YES", 2, from_sheet1);to_wwb.importSheet("hao", 3, from_sheet2);//写入到Exel工作表中to_wwb.write();from_wwb.write();//关闭Excel工作薄对象to_wwb.close();from_rw.close();from_wwb.close();}catch (Exception e) {e.printStackTrace();System.err.println("There is an error!\n");}}public static void main(String[] args) {new Test_JXL_copysheet("d:\\FAP1301578_4_Item_Upload.xls", "d:\\test.xls");}}


程序大概是这样:
其中"d:\\FAP1301578_4_Item_Upload.xls"是一个带宏的excel文件,而 "d:\\test.xls" 是想要把带宏的excel文件中的表单拷贝到这个文件的目的文件。
然后我就设置了一下setPropertySets属性,然后调用了copySheet()和importSheet()进行了复制和导入,其中importSheet()是从另一个workbook中深拷贝一个sheet。

程序运行结果是,可以正常运行,拷贝也成功,但是宏好像失效了
于是,我想到了另外一种方法,避开这个问题:
先将我们要拷贝的excel文件以字节流的形式拷贝一份,然后打开那个带有宏的sheet,因为我不需要对宏做什么修改,只是在这个带宏的表单上修改一些字符,比如在指定Cell中写入一些字符等,这时只需要正常的用jxl的addCell()即可,写完后再保存,ok!
这样我们就实现了一个拷贝了带宏的excel文件,并在相关sheet上进行了更新!
代码修改如下:
... ...//--------testing...------------------------WorkbookSettings newSettings = new WorkbookSettings();newSettings.setPropertySets(true);Workbook from_rw = jxl.Workbook.getWorkbook(this.from_file, newSettings);Sheet from_sheet1 = from_rw.getSheet(0);Sheet from_sheet2 = from_rw.getSheet(1);WritableWorkbook from_wwb = Workbook.createWorkbook(this.from_file, from_rw, newSettings);WritableSheet from_ws = from_wwb.getSheet(1); //修改部分label = new jxl.write.Label(1, 1, "This has been changed!"); //写excel单元格数据  修改部分from_ws.addCell(label);//修改部分to_wwb.copySheet("Product Tree", "copy", 1);to_wwb.importSheet("YES", 2, from_sheet1);to_wwb.importSheet("hao", 3, from_sheet2);//写入到Exel工作表中to_wwb.write();from_wwb.write();//关闭Excel工作薄对象to_wwb.close();from_rw.close();from_wwb.close();... ...

热点排行