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

    错误信息如下:  
      
    ......  
      
    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)   
      
    ......  
      
       
      
    神奇的是,在项目中发现该现象只有在Linux环境下才发生而Window下则正常运行。  
      
    根据错误信息的提示,发现问题出在WriteAccessRecord文件里,其源代码如下所示:  
      
    view plain  
    1.package jxl.write.biff;    
    2.    
    3.import jxl.Workbook;    
    4.import jxl.biff.StringHelper;    
    5.import jxl.biff.Type;    
    6.import jxl.biff.WritableRecordData;    
    7.    
    8./**   
    9. * The name used when Excel was installed.     
    10. * When writing worksheets, it uses the value from the WorkbookSettings object,   
    11. * if this is not set (null) this is hard coded as   
    12. * Java Excel API + Version number   
    13. */    
    14.class WriteAccessRecord extends WritableRecordData    
    15.{    
    16.  /**   
    17.   * The data to output to file   
    18.   */    
    19.  private byte[] data;    
    20.    
    21.  // String of length 112 characters    
    22.  /**   
    23.   * The author of this workbook (ie. the Java Excel API)   
    24.   */    
    25.  private final static String authorString = "Java Excel API";    
    26.  private String userName;    
    27.    
    28.  /**   
    29.   * Constructor   
    30.   */    
    31.  public WriteAccessRecord(String userName)    
    32.  {    
    33.    super(Type.WRITEACCESS);    
    34.    
    35.    data = new byte[112];    
    36.    String astring = userName != null ?    
    37.        userName :    
    38.        authorString + " v" + Workbook.getVersion();    
    39.    
    40.    StringHelper.getBytes(astring, data, 0);    
    41.    
    42.    // Pad out the record with space characters    
    43.    for (int i = astring.length() ; i < data.length ;i++)    
    44.    {    
    45.      data[i] = 0x20;    
    46.    }    
    47.  }    
    48.    
    49.  /**   
    50.   * Gets the data for output to file   
    51.   *    
    52.   * @return the binary data   
    53.   */    
    54.  public byte[] getData()    
    55.  {    
    56.    return data;    
    57.  }    
    58.}    
    分析上诉代码发现,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时往往使用如下代码:  
      
    view plain  
    1.import java.io.File;    
    2.    
    3.import jxl.Workbook;    
    4.import jxl.write.WritableSheet;    
    5.import jxl.write.WritableWorkbook;    
    6.    
    7.public class Test {    
    8.    
    9.    public static void main(String[] args) throws Exception {    
    10.    
    11.        Workbook wb = Workbook.getWorkbook(new File("C:/data_template.xls"));    
    12.        WritableWorkbook workbook = Workbook.createWorkbook(new File("C:/data_output.xls"), wb);    
    13.            
    14.        WritableSheet sheet = workbook.getSheet(3);    
    15.        sheet.getSettings().setSelected(true);    
    16.            
    17.        workbook.write();    
    18.        workbook.close();    
    19.    }    
    20.}    
    只要在代码中强制设置变量WorkbookSettings.writeAccess的值即可,例如:  
      
    Workbook wb = Workbook.getWorkbook(new File("C:/data_template.xls"));  
    WorkbookSettings settings = new WorkbookSettings ();  
    settings.setWriteAccess(null);  
    WritableWorkbook workbook = Workbook.createWorkbook(new File("C:/data_output.xls"), wb, settings);  
      
    WritableSheet sheet = workbook.getSheet(3);  
    sheet.getSettings().setSelected(true);  
      
    workbook.write();  
    workbook.close();   


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值