`

使用JXL生成Excel时发生java.lang.ArrayIndexOutOfBoundsException错误

    博客分类:
  • JXL
 
阅读更多

错误信息如下:

......

java.lang.ArrayIndexOutOfBoundsException
        at java.lang.System.arraycopy(Native Method)
        at jxl.biff.StringHelper.getBytes(StringHelper.java:127)
        at jxl.write.biff.WriteAccessRecord.<init>(WriteAccessRecord.java:59)
        at jxl.write.biff.WritableWorkbookImpl.write(WritableWorkbookImpl.java:726)

......

 

根据错误信息的提示,发现问题出在WriteAccessRecord文件里,其源代码如下所示:
package jxl.write.biff;

import jxl.Workbook;
import jxl.biff.StringHelper;
import jxl.biff.Type;
import jxl.biff.WritableRecordData;
/**
* The name used when Excel was installed.
* When writing worksheets, it uses the value from the WorkbookSettings object,
* if this is not set (null) this is hard coded as
* Java Excel API + Version number
*/
class WriteAccessRecord extends WritableRecordData {
/**
* The data to output to file
*/
 private byte[] data;
// String of length 112 characters
/**
* The author of this workbook (ie. the Java Excel API)
*/
 private final static String authorString = "Java Excel API";
 private String userName;
/**
 * Constructor
 */
 public WriteAccessRecord(String userName) {
 super(Type.WRITEACCESS);

  data = new byte[112];
  String astring = userName != null ?
  userName :
  authorString + " v" + Workbook.getVersion();
 StringHelper.getBytes(astring, data, 0);

 // Pad out the record with space characters
 for (int i = astring.length() ; i < data.length ;i++) {
  data[i] = 0x20;
 }
}

 /**
 * Gets the data for output to file
 *
 * @return the binary data
 */
  public byte[] getData() {
  return data;
  }
}
 

分析上诉代码发现,byte数组data的最大长度被定义为112,当被传入的参数userName达到一定长度时就会抛错。

跟踪代码WritableWorkbookImpl发现,userName实际就是WorkbookSettings类中的writeAccess字段,亦即生成Excel是的用户信息。可能在linux环境UTF8下每个汉字的字节数为3位(Windows中是2位)的缘故,出现了上诉的奇异现象。

解决的办法如下:

1.修改JXL源代码中WriteAccessRecord文件代码,重新设置变量data的长度,例如:data = new byte[astring.getBytes().length];

2.一般我们在读取模板文件生成新的Excel时往往使用如下代码:


import java.io.File; 
 
import jxl.Workbook; 
import jxl.write.WritableSheet; 
import jxl.write.WritableWorkbook;   
public class Test { 
 
    public static void main(String[] args) throws Exception { 
 
        Workbook wb = Workbook.getWorkbook(new File("C:/data_template.xls")); 
        WritableWorkbook workbook = Workbook.createWorkbook(new File("C:/data_output.xls"), wb); 
         
        WritableSheet sheet = workbook.getSheet(3); 
        sheet.getSettings().setSelected(true); 
         
       workbook.write(); 
        workbook.close(); 
    } 

只要在代码中强制设置变量WorkbookSettings.writeAccess的值即可,例如:
File file = new File("data/lglk/excle/LandNeed.xls");
Workbook workbook = Workbook.getWorkbook(file);    
OutputStream outputStream = new FileOutputStream(new File(path));         
WorkbookSettings wbSettings = new WorkbookSettings (); 
wbSettings.setWriteAccess(null);          
// 工作表
WritableWorkbook writableWorkbook = Workbook.createWorkbook(os, workbook,wbSettings);
// 写入文件
writableWorkbook.write();
writableWorkbook.close();
workbook.close();
os.close();

 

分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics