`
guhanjie
  • 浏览: 298888 次
  • 性别: Icon_minigender_1
  • 来自: 上海
社区版块
存档分类
最新评论

JXL调用copySheet()和importSheet()方法时报异常

 
阅读更多
处理EXCEL的开源java util中我了解的有JXL、POI。
而我一直是用jxl来处理excel文件的,之前只是用它来做简单的读写等操作,因此觉得这个jxl还是比较简单轻便的。然而,最近项目中客户有一个带宏(Macro)的sheet要做处理,而JXL貌似在处理带宏的excel方面有些局限(不是一点点),不是很能够处理这方面内容。
我查看了jxl的API文档,发现在jxl.WorkbookSettings中有这么一段:
引用

setPropertySets(boolean r)
          Sets whether or not to enable any property sets (such as macros) to be copied along with the workbook Leaving this feature enabled will result in the JXL process using more memory


因为我不需要对宏做任何修改,只是简单地想把这个宏拷贝下来,因此我认为我只需要将以上这个方法置true,然后再调用copySheet()或者importSheet()方法拷贝这个sheet,应该就能把这个带宏的sheet拷贝下来。

但是当我这样做的时候,我发现我在copySheet()方法中捕获了一个异常,显示如下:
引用

java.lang.NullPointerException
at java.lang.String.compareTo(Unknown Source)
at java.lang.String.compareTo(Unknown Source)
at java.util.Arrays.binarySearch0(Unknown Source)
at java.util.Arrays.binarySearch(Unknown Source)
at jxl.write.biff.SheetCopier.importNames(SheetCopier.java:1049)
at jxl.write.biff.SheetCopier.importSheet(SheetCopier.java:784)
at jxl.write.biff.WritableSheetImpl.importSheet(WritableSheetImpl.java:2638)
at jxl.write.biff.WritableWorkbookImpl.importSheet(WritableWorkbookImpl.java:1897)
at test_JXL.Test_JXL_copysheet.<init>(Test_JXL_copysheet.java:62)
at test_JXL.Test_JXL_copysheet.main(Test_JXL_copysheet.java:80)


于是,我在网上搜索了一下,关于这个“JXL的copySheet()方法出现异常”,看到在OSChina讨论组里有一篇跟我遇到一样情况的人写的帖子:
这两天使用Jexcel进行copySheet时总是报异常:
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()) {//如果该文件不存在,则先创建一个wwb				
				to_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();
... ...
  • jxl.jar (688 KB)
  • 下载次数: 417
分享到:
评论
6 楼 ww_xx 2018-03-09  
宏还是丢失了啊
5 楼 贝塔ZQ 2017-02-14  
处理excel文件,可以用pageoffice插件实现,使用PageOffice的RunMacro方法可以运行Office文档本身包含的宏命令。需要的可以看看。
4 楼 johenry 2016-01-04  
谢谢,今天进行excel文件合并,恰好遇到了这个问题
3 楼 bjuth 2014-10-10  
官方到现在都没改 注册itele号 又等了一天 终于能过了
2 楼 ying890 2014-03-28  
非常感谢!花了我一天的时间。
1 楼 Ray.Allen 2013-06-27  
尴尬的遇到这个问题,多谢了~

相关推荐

Global site tag (gtag.js) - Google Analytics