java專案從win上佈署到linux上報java.lang.ArrayIndexOutOfBoundsException錯誤
阿新 • • 發佈:2019-01-26
這種錯誤是我在瀏覽一篇博文上看到的,具體原因是:在linux環境UTF8下每個漢字的位元組數為3位(Windows中是2位)的緣故,出現了上訴的奇異現象。
這種錯誤是我在瀏覽一篇博文上看到的,具體原因是:在linux環境UTF8下每個漢字的位元組數為3位(Windows中是2位)的緣故,出現了上訴的奇異現象。
錯誤資訊如下: ...... 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();
轉自:http://lzqdll.blog.163.com/blog/static/200607183201111635447767/