`
jiav_net
  • 浏览: 110243 次
文章分类
社区版块
存档分类
最新评论

[经验小结]jxl写excel时产生“java.lang.ArrayIndexOutOfBoundsException: 5”问题的解决办法

 
阅读更多

最近在做一个报表生成系统,为了方便,采用了Servlet + jxl的方式进行报表生成,以excel的形式导出。但是在导出过程中发现了一些问题,研究了很久,也在网上查了很多资料,但是解决方法都不一样,且相对较为复杂,于是自己瞎捣腾了一下,找到了一个适合于自己的解决方法,暂时贴出来供大家参考。本文不一定对适用于你遇到的同类问题,但是希望能在解决问题时可以多提供一种方案。


我遇到的问题是这样的,在收到客户端请求生成报表时,第一次可以顺利生成并下载,但是再发送一个生成请求的时候会抛出异常:java.lang.ArrayIndexOutOfBoundsException: 5


原始测试代码如下:

package com.myCompany.excel.test;

import java.io.File;
import java.io.IOException;

import jxl.Workbook;
import jxl.format.Colour;
import jxl.write.Label;
import jxl.write.WritableCellFormat;
import jxl.write.WritableFont;
import jxl.write.WritableSheet;
import jxl.write.WritableWorkbook;
import jxl.write.WriteException;
import jxl.write.biff.RowsExceededException;

public class App 
{
    public static void main( String[] args )
    {
    	try {
    		ExcelGenerator excel = new ExcelGenerator();
			for(int i = 1; i < 50; ++i)
			{
				String fileName = "Test" + i + ".xls";
				excel.CreateExcel(fileName);
				System.out.println(fileName + " Finished!");
			}
		} catch (WriteException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		}
    }    
}

class ExcelGenerator
{
	private WritableFont fontTitle = new WritableFont(WritableFont.TIMES, 20, WritableFont.BOLD );
	private WritableFont fontHead = new WritableFont(WritableFont.TIMES, 18, WritableFont.BOLD );
	private WritableFont fontBody = new WritableFont(WritableFont.TIMES, 16 );
	private WritableCellFormat cellTitle = new WritableCellFormat(fontTitle);
	private WritableCellFormat cellHead = new WritableCellFormat(fontHead);
	private WritableCellFormat cellBody = new WritableCellFormat(fontBody);
	
	public ExcelGenerator() throws WriteException
	{
		cellTitle.setAlignment(jxl.format.Alignment.CENTRE);
		cellTitle.setBackground(Colour.GREY_40_PERCENT);
		cellTitle.setBorder(jxl.format.Border.ALL, jxl.format.BorderLineStyle.THIN);
		
		cellHead.setAlignment(jxl.format.Alignment.CENTRE);
		cellHead.setBackground(Colour.GREY_25_PERCENT);
		cellHead.setBorder(jxl.format.Border.ALL, jxl.format.BorderLineStyle.THIN);
		
		cellBody.setAlignment(jxl.format.Alignment.LEFT);
		cellBody.setBorder(jxl.format.Border.ALL, jxl.format.BorderLineStyle.THIN);
	}
	
		
	public void CreateExcel(String fileName) throws IOException, RowsExceededException, WriteException
	{
		WritableWorkbook wb = Workbook.createWorkbook(new File(fileName));
		WritableSheet sheet = wb.createSheet("Test", 0);
		
		// 设置列宽
        sheet.setColumnView(0, 30); 
        sheet.setColumnView(1, 30); 
        sheet.setColumnView(2, 15);
        sheet.setColumnView(3, 15);
        sheet.setColumnView(4, 30);
        sheet.setColumnView(5, 40);
        
        sheet.addCell(new Label(0, 0, "公司信息", this.cellTitle));
        sheet.mergeCells(0, 0, 5, 0);
        
        // 插入标题内容
        sheet.addCell(new Label(0, 1, "条码", this.cellHead));
        sheet.addCell(new Label(1, 1, "公司", this.cellHead));
        sheet.addCell(new Label(2, 1, "部门", this.cellHead));
        sheet.addCell(new Label(3, 1, "姓名", this.cellHead));
        sheet.addCell(new Label(4, 1, "类型", this.cellHead));
        sheet.addCell(new Label(5, 1, "描述", this.cellHead));
        
        for(int i = 2; i < 2000; ++i)
        {
        	int col = 0;
        	sheet.addCell(new Label(col++, i, "1353761413" + i, cellBody));
        	sheet.addCell(new Label(col++, i, "XX有限责任公司", cellBody));
        	sheet.addCell(new Label(col++, i, "XX", cellBody));
        	sheet.addCell(new Label(col++, i, "XX", cellBody));
        	sheet.addCell(new Label(col++, i, "XXXXX", cellBody));
        	sheet.addCell(new Label(col++, i, "XXXXX", cellBody));
        }
        
        wb.write();
        wb.close();
	}
}

结果在第二次生成报表时抛出异常:

Exception in thread "main" java.lang.ArrayIndexOutOfBoundsException: 5
	at jxl.biff.IndexMapping.getNewIndex(IndexMapping.java:68)
	at jxl.biff.FormattingRecords.rationalize(FormattingRecords.java:388)
	at jxl.write.biff.WritableWorkbookImpl.rationalize(WritableWorkbookImpl.java:1023)
	at jxl.write.biff.WritableWorkbookImpl.write(WritableWorkbookImpl.java:701)
	at com.myCompany.excel.test.ExcelGenerator.CreateExcel(App.java:101)
	at com.myCompany.excel.test.App.main(App.java:29)

在网上查资料,有人说程序中不能使用太多static,本测试程序中不含static,所以该解决方案不适用。有人说修改jxl的源文件,但是因为jxl.jar已经被其他同事集成到库中,不受我控制,所以只能另找他法。在分析打印出来的异常信息是,发现该异常的产生与单元格的格式控制有关系(因为项目时间紧,没时间分析太久。我想可能是对格式的引用次数有限制之类的,所以在生成不同的文件循环引用同样的格式时,产生了越界,姑且认为是这个很肤浅的原因吧,有时间再仔细研究)。于是先是尝试把格式控制都删除掉,再次运行程序时不会抛出异常。但是如果报表不进行格式控制根本没法看,所以不能去掉格式。于是为了避免出现引用次数过多而造成的越界情况,我决定在每次生成报表时都重新定义格式,而非是在第一次初始化时定义共享格式。修改后的代码如下:

package com.myCompany.excel.test;

import java.io.File;
import java.io.IOException;

import jxl.Workbook;
import jxl.format.Colour;
import jxl.write.Label;
import jxl.write.WritableCellFormat;
import jxl.write.WritableFont;
import jxl.write.WritableSheet;
import jxl.write.WritableWorkbook;
import jxl.write.WriteException;
import jxl.write.biff.RowsExceededException;

public class App 
{
    public static void main( String[] args )
    {
    	try {
    		ExcelGenerator excel = new ExcelGenerator();
			for(int i = 1; i < 50; ++i)
			{
				String fileName = "Test" + i + ".xls";
				excel.CreateExcel(fileName);
				System.out.println(fileName + " Finished!");
			}
		} catch (WriteException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		}
    }    
}

class ExcelGenerator
{
	public ExcelGenerator() throws WriteException
	{
		
	}
		
	public void CreateExcel(String fileName) throws IOException, RowsExceededException, WriteException
	{
		// 定义格式
		WritableFont fontTitle = new WritableFont(WritableFont.TIMES, 20, WritableFont.BOLD );
		WritableFont fontHead = new WritableFont(WritableFont.TIMES, 18, WritableFont.BOLD );
		WritableFont fontBody = new WritableFont(WritableFont.TIMES, 16 );
		WritableCellFormat cellTitle = new WritableCellFormat(fontTitle);
		WritableCellFormat cellHead = new WritableCellFormat(fontHead);
		WritableCellFormat cellBody = new WritableCellFormat(fontBody);
		
		cellTitle.setAlignment(jxl.format.Alignment.CENTRE);
		cellTitle.setBackground(Colour.GREY_40_PERCENT);
		cellTitle.setBorder(jxl.format.Border.ALL, jxl.format.BorderLineStyle.THIN);
		
		cellHead.setAlignment(jxl.format.Alignment.CENTRE);
		cellHead.setBackground(Colour.GREY_25_PERCENT);
		cellHead.setBorder(jxl.format.Border.ALL, jxl.format.BorderLineStyle.THIN);
		
		cellBody.setAlignment(jxl.format.Alignment.LEFT);
		cellBody.setBorder(jxl.format.Border.ALL, jxl.format.BorderLineStyle.THIN);
		
		//创建工作薄
		WritableWorkbook wb = Workbook.createWorkbook(new File(fileName));
		WritableSheet sheet = wb.createSheet("Test", 0);
		
		// 设置列宽
        sheet.setColumnView(0, 30); 
        sheet.setColumnView(1, 30); 
        sheet.setColumnView(2, 15);
        sheet.setColumnView(3, 15);
        sheet.setColumnView(4, 30);
        sheet.setColumnView(5, 40);
        
        // 设置标题
        sheet.addCell(new Label(0, 0, "公司信息", cellTitle));
        sheet.mergeCells(0, 0, 5, 0);
        
        // 插入标题内容
        sheet.addCell(new Label(0, 1, "条码", cellHead));
        sheet.addCell(new Label(1, 1, "公司", cellHead));
        sheet.addCell(new Label(2, 1, "部门", cellHead));
        sheet.addCell(new Label(3, 1, "姓名", cellHead));
        sheet.addCell(new Label(4, 1, "类型", cellHead));
        sheet.addCell(new Label(5, 1, "描述", cellHead));
        
        for(int i = 2; i < 2000; ++i)
        {
        	int col = 0;
        	sheet.addCell(new Label(col++, i, "1353761413" + i, cellBody));
        	sheet.addCell(new Label(col++, i, "XX有限责任公司", cellBody));
        	sheet.addCell(new Label(col++, i, "XX", cellBody));
        	sheet.addCell(new Label(col++, i, "XX", cellBody));
        	sheet.addCell(new Label(col++, i, "XXXXX", cellBody));
        	sheet.addCell(new Label(col++, i, "XXXXX", cellBody));
        }
        
        wb.write();
        wb.close();
	}
}

这样虽然程序效率降低,但是不会再抛出异常。而且考虑到报表生成不是一个频繁发生的事件,所以在每次生成报表时重新定义格式也是可以接受的。

分享到:
评论

相关推荐

    NoClassDefFoundError: jxl/WorkbookSettings

    标题 "NoClassDefFoundError: jxl/WorkbookSettings" 是一个常见的Java运行时错误,意味着在尝试执行程序时,系统无法找到某个类的定义。这个错误通常发生在类路径(ClassPath)配置不正确或者缺少了必要的库依赖时...

    Java操作Excel(jxl.jar)

    本篇文章将深入探讨如何使用jxl.jar库来实现Java操作Excel。 首先,jxl是一个广泛使用的Java库,它允许开发者读写Microsoft Excel文件。它的主要优势在于简单易用且功能丰富,支持多种Excel格式,包括老版本的.BIFF...

    jxl.jar包(java导入导出Excel文件)

    **Java Excel工具包——jxl.jar** 在Java编程中,处理Excel文件是一项常见的任务,尤其在数据导入导出、报表生成或数据分析等场景下。jxl.jar是一个专门为Java设计的库,它允许开发者轻松地读取、写入和修改Excel...

    jxl.zip_excel_jxl_jxl.biff.drawing.dg_jxl.biff.drawingdg

    "jxl.biff.drawing.dg"和"jxl.biff.drawingdg"则涉及到Excel文件内部的结构,BIFF(Binary Interchange File Format)是Excel的二进制文件格式,其中"drawing"部分与Excel的图形元素相关,"dg"可能是Drawing Group的...

    java_Jxl(导入导出Excel).doc

    Java Jxl库是一个专门用于处理Excel文件的开源Java库,它允许开发者在Java应用程序中进行Excel文件的读取、创建和修改。Jxl支持多种Excel版本,包括从Excel 95到2000,而且生成的文件格式符合Excel 2000的标准。这个...

    解决JXL调用copySheet()和importSheet()方法时报异常的jar包

    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读写Excel小例子

    在Java编程环境中,处理Excel文件是一项常见的任务,而JXL库提供了一个简洁的API来实现这一功能。JXL是一个开源的Java库,专门用于读取和写入Microsoft Excel文件(.xls格式)。在这个"JXL读写Excel小例子"中,我们...

    jxl导出excel加水印.zip

    本教程将详细介绍如何使用`jxl`库在导出Excel时添加水印,以及涉及的核心类`WritableWorkbook`、`WritableSheet`和`WritableCellFormat`。 `jxl`库提供了一套完整的API来操作Excel文件,包括创建新的工作簿、添加...

    java使用jxl打印excel报表文件

    在Java开发中,生成和处理Excel文件是一项常见的任务,特别是在数据导出或报表生成的场景。JXL库是一个广泛使用的Java库,它允许开发者读取、写入和修改Excel文件。本篇将深入探讨如何使用JXL库在Java中打印Excel...

    关于jxl操作excel说明以及jxl.jar包下载2.6

    在Java编程环境中,处理Excel文件是一项常见的任务,特别是在数据导入导出、数据分析或者报表生成时。JXL库是一个广泛使用的开源库,它允许开发者用Java来读写Microsoft Excel文件。标题"关于jxl操作excel说明以及...

    JXL读写EXCEL示例

    在Java编程环境中,处理Excel文件是一项常见的任务,而JXL库提供了一个简洁的API来实现这一功能。JXL是一个开源的Java库,专门用于读取和写入Microsoft Excel文件(.xls格式)。在这个示例中,我们将深入探讨如何...

    Java利用JXL读写Excel

    在Java编程领域,处理Excel文件是一项常见的任务,特别是在数据分析、数据导入导出或者报表生成等场景。JXL库是一个广泛使用的开源库,它允许开发者在Java应用程序中方便地读取和写入Excel文件。本篇将详细介绍如何...

    java_Jxl(导入导出Excel).pdf

    【Java Jxl库详解:轻松实现Excel导入导出】 Java Jxl库是一个强大的工具,用于在Java应用程序中处理Microsoft Excel文件。它支持从Excel 95到2000的所有版本,同时也允许生成Excel 2000标准格式的文件。Jxl的主要...

    ExcelDemo_Excel导出_下载_POI读excel_JXL读写excel_java读写excel_列宽_读取合并或拆分单元格内容

    本文将深入探讨Java编程语言中如何使用Apache POI库和JExcelAPI(JXL)来读取、写入及操作Excel文件,同时也包括设置列宽以及处理合并或拆分的单元格内容。 首先,Apache POI是Apache软件基金会的一个开源项目,专...

    jxl.jar——JavaExcel library.zip

    JavaExcel库,通常以jxl.jar的形式出现,是Java开发者用于读取和写入Microsoft Excel文件的一个强大工具。这个库提供了方便的API,使得在Java应用程序中操作Excel电子表格变得非常简单。它不仅支持基本的读写功能,...

    java利用jxl读取excel文件

    在Java编程环境中,读取Excel文件是常见的任务,特别是在数据处理和分析的场景下。`jxl`库是一个广泛使用的第三方库,它允许开发者轻松地读取、写入和修改Excel文件。本篇文章将深入探讨如何利用`jxl.jar`包来实现这...

    jxl.jar 用于java读取 .xls 文件

    在这种情况下,`jxl.jar`库是一个非常实用的工具,它允许开发者用Java轻松地读取和写入Excel文件。`jxl.jar`库提供了丰富的API,使得操作Excel文件变得简单而高效。 `jxl`库的核心概念是工作簿(Workbook)、工作表...

    jxl的excel读写操作

    Java中的JXL库是一个广泛使用的库,用于读取和写入Microsoft Excel文件。这个库使得在Java应用程序中处理Excel数据变得简单,而无需依赖于Microsoft Office。以下是对JXL库在进行Excel读写操作时的一些关键知识点的...

Global site tag (gtag.js) - Google Analytics