`

JExcelAPI(jxl)读写Excel应用

阅读更多

 

  这篇博文在我的草稿箱里已经放够久了,又到一年樱花时,想起母校到处灿烂的樱花了。不知道老班这个感性的女人今年有没有再去老校区拍些照片传到空间里,也好解下思念母校之苦啊!当然了,今天去蠡湖公园欣赏樱花的来着。呵呵呵~今天结束jxl读写Excel表的应用吧。

  JExcelAPI简称JXL,一套纯Java实现读写Excel功能的API;非常的简洁,只需要一个jxl.jar (该博文对应的jxl版本为2.6.12)就可以。有多个传说中的官网,也不知道怎么搞的,整得乱七八糟的,最后找到这个http://www.andykhan.com/jexcelapi,绝对有你所有想要的资料。

  我们也知道Apache POI项目相对于JXL,则提供了更为功能强大的Excel读取功能,还包括了Microsoft其它文档的读写API,包括word、powerpoint等等,拥有着强大的社区支持,在2011-03-07已经出了3.8的测试版本,相对于JXL,它的功能确实够强大。不过,要读写不同版本的Excel还得切换不同的API,也不得不说,这是件幸福而烦恼的事情。

  今天暂且介绍JXL读写Excel,有需要的朋友,学习POI项目还是有必要的,我这都是图省事儿。

  先说说这个JXL的实用类的由来吧,主要是面向加拿大和美国的项目产品,所以,国际化就成了必不可少的功能,英文能猜个八九不离十,法文就糟糕了。所以,我们这边必须得整理出项目中的单词发给加拿大那边的同事给我们进行法文和英文的翻译,最后我们共同协商决定用Excel统一发过去,N多的国际化资源文件,让你一个个的往Excel里面拷贝,搞这个玩意儿,我相信你搞会儿有够你郁闷的。

  所以,急需要一个工具类,将*.properties和*.js文件读取到Excel表中,然后再把翻译完的Excel表的内容读出再写到properties和js文件中,所以ExcelOperator.java应运而生。

  不管怎么样,先得把properties以及js文件写入Excel表中,properties文件我们肯定是很清楚了,也是存储key-value值的一种方式,当然,在我们的项目中,js也采用了这种key-value的方式,便于国际化,现列出properties和js文件的格式:

   Properties:

res_properties_i18n_test1 =国际化1
res_properties_i18n_test2 =国际化2
res_properties_i18n_test3 =国际化3
res_properties_i18n_test4 =国际化4

   Js:

res_js_i18n_test1 = "国际化1";
res_js_i18n_test2 = "国际化2";
res_js_i18n_test3 = "国际化3";
res_js_i18n_test4 = "国际化4";

  一、 先看将这两种类型的文件写入Excel的方法writeExcel(String[] fileNames,String specName):

  现对此代码的分析如下:

 

/**
 * 将Js/Properties文件读取存储到xls文件中
 * @param fileNames  待处理的文件集合
 * @param specName 指定的文件名
 * @throws WriteException 
 * @throws RowsExceededException 
 * */
public String writeExcel(String[] fileNames,String specName) throws BiffException, IOException, RowsExceededException, WriteException
{
	if(null!=fileNames&&fileNames.length>0){     
        //如未指定Excel文件名则根据当前时间获取                        
        if(null==specName||specName.length()<=0){
			specName = new Date().getTime()+".xls";
		}
        //1)创建Excel
        OutputStream os = new FileOutputStream(specName);
		WritableWorkbook workbook =  Workbook.createWorkbook(os);
		for(int i=0;i<fileNames.length;i++){
			String fileName = fileNames[i];//文件名
			InputStream is = this.getClass().getResourceAsStream(fileName);
			BufferedReader reader = new BufferedReader(new InputStreamReader(is));
			String prefixName = fileName.substring(0,fileName.indexOf("."));
			//获取i18n类型,并格式化成诸如:的ZH-CN形式
			String i18nType = ((prefixName.substring(prefixName.length()-5)).replace("_","-")).toUpperCase();
			
			//文件的扩展名
			String suffixName = fileName.substring(fileName.indexOf(".")+1);
			
			//2)创建sheet
			String sheetName = prefixName.substring(0,prefixName.indexOf("_"))+"."+suffixName;
			WritableSheet wSheet = null;

			if(i==0){
				wSheet = workbook.createSheet(sheetName,i);
			}else{
				//获取已建立的sheet名称
				String[] sheetNames = workbook.getSheetNames();
				//与之前的创建的sheet进行比较,看是否已存在同名,
				//如果存在,则把此sheet赋给当前sheet,否则新建一个sheet。
				for(int k=0;k<sheetNames.length;k++){
					WritableSheet frontSheet = workbook.getSheet(k);//获取之前创建的sheet
					if(sheetName.equals(frontSheet.getName())){
						wSheet = frontSheet;
						break;
					}
				}
				if(wSheet==null){//不存在同名的sheet,则新建一个sheet
					wSheet = workbook.createSheet(sheetName,sheetNames.length);
				}
			}
                             

            //3)需要每次初始化,否则抛异常
			//Exception in thread "main" jxl.write.biff.JxlWriteException:Cell has already been added to a worksheet
			WritableCell[] wcells = newInstanceHeaderCell();
			
			for(int j=0;j<wcells.length;j++){//添加表头
				wSheet.addCell(wcells[j]);
			}
			//4)
            if(suffixName.equals(FILE_SUFFIX_PROPERTIES)){
				readProperties(wSheet,reader,i18nType);//读取Properties
			}else if(suffixName.equals(FILE_SUFFIX_JS)){
				readJs(wSheet, reader, i18nType);//读取js
			}
		}
		workbook.write();
		workbook.close();
	}
	return null;
}
 

    1)通过指定的文件名(或者自动生成),得到一个Excel的文件输出流,接着通过WorkBook这个抽象类的静态方法createWorkbook(OutputStream os)创建一个可读写的工作薄实例WritableWorkbook,这里有必要解释一下WorkBook,此抽象类就是代表一个工作簿,即一个具体的Excel,该类包含了多种的工厂方法以及提供了多种访问工作表的访问器。除了通过指定输出流来生成一个可读写的WritableWorkbook实例外,你还可以通过指定File对象,具体的可参见源代码,在此不详述!

   2)创建一个工作簿的Sheet对象,如何获取Sheet的文件名,现在大概说一下,我之前有说过,Excel表格的格式,而在我的项目中,它是分别放在中、英、法对应的国际化目录中的,所以,我会将每个国家对应的国家化文件读取到同一个Sheet中。所以,通过指定的SheetName和位置生成一个可读写的WritableSheet对象,如果此Sheet已经存在,则获取,否则新建一个。

  3)有了工作表之后,之后的工作当然要往里面写入表格内容,每一个元件即对应JXL中的Cell对象,创建当前工作表的表头元件集合,即newInstanceHeaderCell方法:

 

	/**
	 * 返回新cell实例集合
	 * */
	private WritableCell[]  newInstanceHeaderCell(){
		WritableCell[] 	wcells 	= 	new Label[4];
		wcells[0] = new Label(0,0,RESOURCES_KEY);
		wcells[1] = new Label(1,0,RESOURCES_EN_US);
		wcells[2] = new Label(2,0,RESOURCES_FR_BE);
		wcells[3] = new Label(3,0,RESOURCES_ZH_CN);
		return wcells;
	}

    该方法返回一个WritableCell的数据,数组里每个元素的实例为Label,实际上,顾名思议就是指单元格的文本了,呵呵,不再多说,咱继续看。

   4)根据不同文件的后缀名,来读取对应文件里的内容,着重说一下readProperties这个方法吧(readJs原理相同,具体可参见附件源码):

 

// 读取properties的全部信息
protected static void readProperties(WritableSheet wSheet,BufferedReader reader,String i18nType){
	Properties props = new Properties();
	try {
        props.load(reader); //1)读入Properties
		Enumeration en = props.propertyNames();
		int row=1;
		while (en.hasMoreElements()){
			String key = (String) en.nextElement();
			//2)获取当前的Key值,以便与其进行匹配
			String nowKey = wSheet.getCell(0,row).getContents();
			boolean addFlag = false;
			if(null==nowKey||""==nowKey){
				wSheet.addCell(new Label(0,row,key));
				addFlag = true;
			}else{
				if(key.equals(nowKey)){
					addFlag = true;
				}
			}
            //3)
			if(addFlag){
				//获取当前Properties主键对应的值
                String value = props.getProperty(key);
                if(i18nType.equalsIgnoreCase(RESOURCES_EN_US)){
					wSheet.addCell(new Label(1,row,value));
				}else if(i18nType.equalsIgnoreCase(RESOURCES_FR_BE)){
					wSheet.addCell(new Label(2,row,value));
				}else if(i18nType.equalsIgnoreCase(RESOURCES_ZH_CN)){
					wSheet.addCell(new Label(3,row,value));
				}
			}
			row++;
		}
	} catch (Exception e) {
		e.printStackTrace();
	}
}

     1)通过Properties的load方法载入包含数据的文件,然后再通过propertyNames方法返回此property文件的key值集合并保存到Enumeration类型的en变量中。

     2)遍历Properties文件,通过wSheet.getCell(0,row).getContents(),获取当第一列每一行的表格主键值的内容,如果不存在,则通过wSheet.addCell(new Label(0,row,key))这个方法来创建。row是个变量,记录每一行。

     3)如果一切顺利的话,则比较后缀名,将获取到properties的值存储到对应的国际化列下。

  OK,将Properties和Js的文件写入到Excel算是搞定了,以下测试代码:

 

	ExcelOperator eo = ExcelOperator.getInstance();
	String[] fileNames = {"Jsi18nTestResource_ZH_CN.js","Jsi18nTestResource_EN_US.js","Proi18nTestResource_ZH-CN.properties"};
	eo.writeExcel(fileNames, "i18n_2011_04_04.xls");

     如果一切运行正常的话,则会在项目目录下生成一个名为i18n_2011_04_04.xls的文件,内容截图如下:

    

     从结果来看,传入三个文件名,生成两个Sheet,Sheet名为Jsi18nTestResource.js的内容,除了FR-BE法文没有内容外,另外两个分别从Jsi18nTestResource_ZH_CN.js和Jsi18nTestResource_EN_US.js中读取并写入。

  二、将对应的文件写入到Excel表之后,经过国际化的翻译,我还得把它转过来不是嘛~接下来,做这样的事情之前呢,为了能够生成法文文件,所以,将Sheet名为Jsi18nTestResource.js的FR-BE列分别加入testFr1~testFr4

 

/**
 * @param path 文件路径
 *            js/properties 最终生成的文件是.js/.properties
 */
public String readExcel(String path) throws BiffException, IOException
{
	InputStream in = getClass().getResourceAsStream(path);
	if (in == null)
	{
		throw new IllegalArgumentException(path + " not found.");
	}
	//1)
	WorkbookSettings wbs = new WorkbookSettings();
	wbs.setEncoding("ISO-8859-1");// 解决乱码
	Workbook wb = Workbook.getWorkbook(in, wbs);
	//2)获取sheet工作表
	Sheet[] sheets = wb.getSheets();	
	for(Sheet sheet:sheets){
		String sheetName = sheet.getName();//获取工作表名		
		String fileName = sheetName.substring(0,sheetName.indexOf("."));
		String suffix = sheetName.substring(sheetName.indexOf(".")+1);
		
		OutputStream zh_cn_os = new FileOutputStream(fileName + "_" + RESOURCES_ZH_CN + "." + suffix);
		OutputStream en_us_os = new FileOutputStream(fileName + "_" + RESOURCES_EN_US + "." + suffix);
		OutputStream fr_be_os = new FileOutputStream(fileName + "_" + RESOURCES_FR_BE + "." + suffix);
        //3) 得到行数
        int rows = sheet.getRows();
		for (int i = 1; i < rows; i++)
		{
			Cell[] rowCells = sheet.getRow(i);// 针对每行进行数据的加工处理
			String key = "";
			for (int j = 0; j < rowCells.length; j++)
			{// 读取值
				if (j == 0)
				{
					key = rowCells[j].getContents();
				}
				else
				{
					String value = (key + "=");
					String content = rowCells[j].getContents();
					content = content.replace("\"", "").replace(";", "");
					if ("js".equals(suffix))
					{
						content = ("\"" + content + "\";");// 加上双引号以及分号
					}
					value += (content+"\n");

					byte[] bytes = value.getBytes("UTF-8");
					if (j == 1)
					{
						en_us_os.write(bytes);
					}else if (j == 2)
					{
						fr_be_os.write(bytes);
					}else{
					 	zh_cn_os.write(bytes);
					}
				}
				zh_cn_os.flush();
				en_us_os.flush();
				fr_be_os.flush();
			}
		}
		zh_cn_os.close();
		en_us_os.close();
		fr_be_os.close();
	}
	return null;
}
 

    1)通过WorkbookSettings对象的setEncoding("ISO-8859-1")来解决乱码的问题,再通过Workbook wb = Workbook.getWorkbook(in, wbs)来获取Workbook对象。记得写Excel表是什么对象来着?!对了:WritableWorkbook,这两个都代表当前的工作薄,唯一的区别就是前者是只读的,后者是可写的。

    2)获取当前工作薄里所有内容不为空的Sheet集合,然后循环所有的Sheet对象,通过Sheet的名字及后缀名,生成对象的国际化文件输出流,并将Sheet内容读出写入到对应的国际化文件中。

    3)获取当前工作表的所有行,然后从第二行开始遍历(第一行为对应的表头,第二行才是真正的数据)。

         Cell[] rowCells = sheet.getRow(i);该方法返回当前行所有的元件集合,然后遍历该行的表格内容,每一行的第一列为国际化文件的主键值,所以通过key = rowCells[j].getContents()返回其内容,否则,则获取数值内容并通过转义保存到对应的国际化文件中。

  看如下的测试代码:

 

eo.readExcel("i18n_2011_04_04.xls");

  如果一切正常的话,项目中会成功生成如下的文件:

  

  该博文的内容看起来虽然不少,但是真正涉及到Excel读写的代码,也就几行,倒是大量的篇幅花在了业务逻辑上 ,可以看到JXL读写Excel是多么的简单易用,可惜的是官网说明只支持Excel 95, 97, 2000,即不支持*.xlsx格式,所以,这是一个很遗憾的事情,要想读取*xlsx,还是得选择 POI,事实再一次的证明了研究POI的重要性,所以,有时间,POI再见!

  • 大小: 28.9 KB
  • 大小: 16.8 KB
分享到:
评论

相关推荐

    JXL读写Excel小例子

    在这个"JXL读写Excel小例子"中,我们将深入探讨如何使用JXL库来操作Excel数据。 首先,为了开始使用JXL,你需要将其添加到你的项目依赖中。如果你使用Maven,可以在pom.xml文件中添加以下依赖: ```xml ...

    jxl的excel读写操作

    以下是对JXL库在进行Excel读写操作时的一些关键知识点的详细解释: 1. **安装与引入** 首先,你需要将JXL库添加到你的项目类路径中。如果你使用的是Maven,可以在pom.xml文件中添加以下依赖: ```xml ...

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

    接下来,我们讨论JExcelAPI(JXL),这是一个轻量级的Java库,适用于读写Excel文件。尽管POI提供了更全面的功能,但JXL对于简单的读写操作来说足够便捷。以下是一个使用JXL读取Excel文件的示例: ```java import ...

    jxl读写excel源码

    Java编程语言提供了多种库来处理Excel文件,其中jxl是一个广泛使用的开源库,它使得在Java应用程序中读取和写入Excel文件变得简单。本文将详细介绍如何使用jxl库进行Excel文件的读写操作,以及适合初学者的关键知识...

    Java利用JXL读写Excel

    以上就是使用JXL库进行Java读写Excel的基本操作。在实际应用中,你可能还需要处理更复杂的情况,比如读写公式、样式、图表等。JXL库提供了丰富的API来支持这些功能,可以根据需求进行深入学习和使用。 最后,如果你...

    利用JXL(JExcelApi)操作Excel文档

    5. **兼容性**:JXL支持读写早期版本的Excel文件(.xls),但不直接支持较新的Excel 2007及以后的xlsx格式。如果需要处理xlsx格式,可以考虑使用Apache POI库。 6. **性能**:JXL相对轻量级,适合小到中型的数据...

    jxl读写excel常见操作搜集整理

    `jxl`是一个开源库,它允许Java应用程序以读写方式与Microsoft Excel文件进行交互。这个文档将详细介绍使用`jxl`库进行Excel文件操作的一些常见方法和技巧。 首先,安装`jxl`库非常简单,只需将`jxl.jar`文件添加到...

    jxl模版生成excel

    总的来说,jxl是一个强大的工具,适用于需要在Java应用中生成或处理Excel文件的场景,特别是需要基于模板动态生成复杂报表的情况。通过学习和掌握jxl库,开发者能够高效地处理Excel数据,提升工作效率。

    jexcelapi_2_4.tar.gz_java项目_jexcelapi_2_4_jexcelapi_2_4-2.tar._j

    这个开源项目为Java开发者提供了一个方便的接口,可以直接在Java代码中读写Excel文件,大大提高了开发效率。 JExcelAPI,全称为Java Excel API,是一个完全用Java编写的库,允许开发者无缝地处理Excel工作簿、工作...

    java读写Excel(JXL)

    Java读写Excel是Java开发中常见的一项任务,特别是在数据处理、报表生成以及数据分析等领域。JXL库是一个广泛使用的Java库,专门用于处理Microsoft Excel文件。本文将深入探讨使用JXL库进行Excel文件的读写操作,并...

    jxl导出excel总结

    jxl库是由JExcelAPI项目提供的,它是一个开源的Java库,专门用于处理Microsoft Excel文件。在本文中,我们将深入探讨jxl的使用方法,包括它的API和实际操作技巧,以帮助开发者更好地利用这一工具。 首先,让我们来...

    jxl导出excel

    标题中的“jxl导出excel”指的是使用JExcelApi(简称jxl)库来生成和导出Microsoft Excel格式的文件。JExcelApi是一个开源Java库,允许开发者在Java应用程序中读取、写入和修改Excel文件。这个工具类在处理大量数据...

    jxl解析excel

    在IT行业中,处理数据时,Excel表格是一种广泛使用的格式,特别是在数据分析、报表生成等领域。...通过学习和掌握jxl库的使用,你可以轻松地在Java应用程序中实现Excel数据的读取、写入和格式控制,从而提升工作效率。

    poi jxl 生成EXCEL 报表

    JXL是另一个处理Excel文件的Java库,它提供了简单的API用于读写Excel文件。在描述中提到的"jxl-2.6.jar"是JXL的一个版本。虽然POI功能更强大,但JXL在某些场景下可能更易于使用,尤其是对于简单的Excel操作。 - ...

    浅谈jxl解析excel —————复制、修改excel表

    而JXL库则是一个专门用于Java平台的Excel文件读写工具,它允许开发者以编程方式来处理Excel文件,包括创建、读取、修改和保存Excel工作簿。本文将围绕“浅谈jxl解析excel ——复制、修改excel表”这一主题,深入探讨...

    Java Web应用开发 59 课堂案例-应用jExcelAPI组件生成Excel文件.docx

    - `jExcelAPI`是一款用于读写Microsoft Excel文件的开源Java库。它支持从Excel 2.0到Excel 2007版本的文件格式,并提供了丰富的API来处理这些文件。 - 该组件可以独立使用,也可以集成到Web应用程序或其他Java应用...

    java使用jxl进行Excel导入导出

    Java 使用 JXL 进行Excel导入导出是一个常见的任务,特别是在数据处理和分析场景中。JXL 是一个 Java 库,允许开发者...通过熟练掌握 JXL 的 API,开发者可以轻松地在 Java 应用程序中实现 Excel 数据的读写和操作。

    jxl导出Excel基础

    `jxl`库是Java中一个广泛使用的库,它允许开发者方便地读写Excel文件。本篇文章将深入探讨如何利用`jxl`库进行Excel的基础导出。 首先,让我们了解`jxl`库。`jxl`(Java Excel API)是一个开源库,专门设计用来处理...

    JXL导出Excel数据表

    在实际应用中,这通常通过遍历数据库查询结果,然后使用JXL提供的API创建对应的Excel工作表。例如,你可以决定只导出某些字段,设置每个字段的标题,甚至调整它们在工作表中的排列顺序。这样,即使数据库结构发生...

Global site tag (gtag.js) - Google Analytics