利用Java进行Excel的数据导入导出
发布时间:2012-07-31 18:39:28作者:知识屋
1. 引言
MS 的电子表格(Excel)是Office 的重要成员,是保存统计数据的一种常用格式。在一
个Java 应用中,将一部分数据生成Excel 格式,是与其他系统无缝连接的重要手段。在远程
网络教学系统中,利用Excel 表格统计学生的作业考试情况信息,便于老师了解学生的学习
情况,分析教学效果,制定教学计划。所以,用Java 操作Excel 表格,导出相关的信息对于
远程网络教育系统有着的很重要的意义。
在开源世界中,有两套比较有影响的API 提供Excel 数据导入导出的功能,一个是POI,
一个是jExcelAPI。本文结合基于J2EE 开发的多媒体教学系统中提供的将学生作业信息导出
到Excel 表格中的实例,详细阐述了利用JAVA 开发的jExcelAPI 操作excel 的方法。
2. Jxl 简介
2.1 Java 语言简介
Java 语言具有面向对象、与平台无关、安全、稳定和多线程等优良特性,是目前软件设
计中极为强大的编程语言[1]。它具有以下一些特点[2]:简单,面向对象,分布式,解释执行,
鲁棒,安全,体系结构中立,可移植,高性能,多线程以及动态性。
2.2 什么是Jxl
Java Excel 是一开放源码项目,通过它Java 开发人员可以读取Excel 文件的内容、创建
新的Excel 文件、更新已经存在的Excel 文件。使用该 API 非Windows 操作系统也可以通
过纯Java 应用来处理Excel 数据表。因为是使用Java 编写的,所以我们在Web 应用中可以
通过JSP、 Servlet 来调用API 实现对Excel 数据表的访问。
Jxl 发布的稳定版本是V2.0,提供以下功能:
从 Excel 95、97、2000 等格式的文件中读取数据[3];
读取 Excel 公式(可以读取Excel 97 以后的公式)[3];生成Excel 数据表(格式为Excel 97)[3];
支持字体、数字、日期的格式化[3];
支持单元格的阴影操作,以及颜色操作[3];
修改已经存在的数据表。
2.3 代码举例
2.3.1 从Excel 文件读取数据表
Java Excel API 既可以从本地文件系统的一个文件(.xls),也可以从输入流中读取Excel
数据表。读取Excel 数据表的第一步是创建Workbook(术语:工作薄),相关文献中给出了
部分事例介绍[4],下面的代码片段举例说明了应该如何操作:
import java.io.*;
import jxl.*;
… … … …
try
{
//构建Workbook 对象, 只读Workbook 对象
//直接从本地文件创建Workbook
//从输入流创建Workbook
InputStream is = new FileInputStream(sourcefile);
jxl.Workbook rwb = Workbook.getWorkbook(is);
}
catch (Exception e)
{e.printStackTrace();}
一旦创建了 Workbook,我们就可以通过它来访问Excel Sheet(术语:工作表)。代码如
下:
//获取第一张Sheet 表
Sheet rs = rwb.getSheet(0);
我们既可能通过Sheet 的名称来访问它,也可以通过下标来访问它。如果通过下标来访
问的话,要注意的一点是下标从0 开始,就像数组一样。
一旦得到了 Sheet,我们就可以通过它来访问Excel Cell(术语:单元格)。代码如下:
//获取第一行,第一列的值
Cell c00 = rs.getCell(0, 0);
String strc00 = c00.getContents();
//获取第一行,第二列的值
Cell c10 = rs.getCell(1, 0);
String strc10 = c10.getContents();//获取第二行,第二列的值
Cell c11 = rs.getCell(1, 1);
String strc11 = c11.getContents();
如果仅仅是取得Cell 的值,我们可以方便地通过getContents()方法,它可以将任何类型
的Cell 值都作为一个字符串返回。示例代码中 Cell(0, 0)是文本型,Cell(1, 0)是数字型,
Cell(1,1)是日期型,通过getContents(),三种类型的返回值都是字符型。
当完成对 Excel 电子表格数据的处理后,一定要使用close()方法来关闭先前创建的对象,
以释放读取数据表的过程中所占用的内存空间,在读取大量数据时显得尤为重要。
//操作完成时,关闭对象,释放占用的内存空间
rwb.close();
2.3.2 生成新的Excel 工作薄
与读取 Excel 工作表相似,首先要使用Workbook 类的工厂方法创建一个可写入的工作
薄(Workbook)对象,相关文献中给出了事例介绍[4],具体代码如下:
try
{
//构建Workbook 对象, 只读Workbook 对象
//Method 1:创建可写入的Excel 工作薄
jxl.write.WritableWorkbook wwb = Workbook.createWorkbook(new File(targetfile));
//Method 2:将WritableWorkbook 直接写入到输出流
/*
OutputStream os = new FileOutputStream(targetfile);
jxl.write.WritableWorkbook wwb = Workbook.createWorkbook(os);
*/}
catch (Exception e)
{e.printStackTrace();}
//创建Excel 工作表
jxl.write.WritableSheet ws = wwb.createSheet("Test Sheet 1", 0);
//1.添加Label 对象
jxl.write.Label labelC = new jxl.write.Label(0, 0, "This is a Label cell");
ws.addCell(labelC);//添加带有字型Formatting 的对象
jxl.write.WritableFont wf = new jxl.write.WritableFont(WritableFont.TIMES,18,
WritableFont.BOLD, true);
jxl.write.WritableCellFormat wcfF = new jxl.write.WritableCellFormat(wf);
jxl.write.Label labelCF = new jxl.write.Label(1, 0, "This is a Label Cell", wcfF);
ws.addCell(labelCF);
2.3.3 单元格操作
1)合并单元格
WritableSheet.mergeCells(int m,int n,int p,int q);
作用是从(m,n)到(p,q)的单元格全部合并,比如:
WritableSheet sheet=book.createSheet(“第一页”,0) [5];
//合并第一列第一行到第六列第一行的所有单元格
sheet.mergeCells(0,0,5,0);
合并既可以是横向的,也可以是纵向的。合并后的单元格不能再次进行合并,否则会触
发异常。
2)行高和列宽
WritableSheet.setRowView(int i,int height);
作用是指定第i+1 行的高度,比如:
//将第一行的高度设为200[5]
sheet.setRowView(0,200);
WritableSheet.setColumnView(int i,int width);
作用是指定第i+1 列的宽度,比如:
//将第一列的宽度设为30[5]
sheet.setColumnView(0,30);
3. 应用实例
本文所举的实例为网上多媒体教学系统中对于学生作业导出信息的实现。
3.1 系统界面及导出表实例
下图 1 为导出功能的入口:点击导出此次作业的成绩按钮,就会触发相应的动作,进行
数据表的导出3.2 实现代码
导出之前首先要定义一个 SingleTaskScoreExportInfo 对象,用来存放从数据库中查询出
来的导出表需要的相关字段的信息。它是作业接收者对象的一个子集,只包含了作业接收者
对象中学号,姓名,班级,作业标题,完成时间,分数,查看次数等信息。
为数据导出按钮连接消息处理函数:函数主要包括生成工作表,调用方法从数据库中将
对应某次作业的作业接收者的信息查找出来, 并用相关的属性初始化
SingleTaskScoreExportInfo 对象,放在结果集中,构造循环将查询到的结果集中的对象写入
到Excel 表格中。以下是实现的主要代码:
//定义表格名称为作业成绩,创建工作薄
String filename="作业成绩";
response.setHeader("Content-Disposition" ,"attachment;filename="+new
String(filename.getBytes(),"iso8859-1")+".xls");
OutputStream os=response.getOutputStream();
WritableWorkbook wwb=Workbook.createWorkbook(os);
//创建工作表,并写入相应的表头字段WritableSheet sheet=wwb.createSheet("所有成绩", 0);
String []title={"学号","班级","姓名","作业标题","完成时间","分数","次数"};
for (int j = 0; j < title.length; j++) {// 在sheet 中写标题栏
sheet.addCell(new Label(j, 0, title[j], arial12format));}
//查询需要的数据,放在List 结果集中
List<SingleTaskScoreExportInfo> scores =
studyManager.getSingleTaskScoresByCourse(courseId,taskId);
//将相关的信息写入到工作表
SingleTaskScoreExportInfo item;
int row=1;
for (it = scores.iterator(); it.hasNext();) {
item = (SingleTaskScoreExportInfo) it.next();
if(!"".equals(item.getStudentNum())&&null!=item.getStudentNum()){
//添加学号
Label label = new Label(0, row, item.getStudentNum());
sheet.setColumnView(0, 20);
sheet.addCell(label);
//添加班级
label = new Label(1, row, item.getClassGroupName());
sheet.setColumnView(1, 50);
sheet.addCell(label);
//添加姓名
label = new Label(2,row,item.getStudentName());
sheet.setColumnView(2, 10);
sheet.addCell(label);
//添加作业标题
label = new Label(3,row,item.getTaskTitle());
sheet.setColumnView(3, 30);
sheet.addCell(label);
// 添加完成时间
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
WritableCellFormat wc = new WritableCellFormat();wc.setAlignment(Alignment.CENTRE);
sheet.setColumnView(4,30);
if(item.getFinishTime()!=null){
String newdate = sdf.format(item.getFinishTime());
label = new Label(4,row,newdate,wc);
sheet.addCell(label); }
else{label=new Label(4,row,"未查看此次作业",wc);sheet.addCell(label);}
//添加分数
Number score = new Number(5, row, item.getScore(), wcf);
double score_temp=score.getValue();
if(0<score_temp&&score_temp<0.6)
{ sheet.addCell(new Number(5, row, score_temp*100, redFormat)); }
else if (item.getFinishTime()==null){sheet.addCell(new Number(5, row, -1, redFormat));}
else if(item.getFinishTime()!=null&&(score_temp==0||"".equals(item.getScore())))
{sheet.addCell(new Number(5, row, (double)0, redFormat));}
else sheet.addCell(new Number(5, row, score_temp*100, wcf));
//添加查看次数
Number homeWorkTimes = new Number(6, row, item.getHomeWorkTimes());
sheet.addCell(homeWorkTimes);}
row++;// 指针下移}
//导出后关闭对象,释放内存
wwb.write();
wwb.close();
os.close();
4. 小结
Jxl 提供了有关Java 操纵Excel 的大多数类,可以方便地进行数据读写,单元格格式定
义。在使用的时候需要注意的几个问题包括:
在头文件中要把相关的 Jar 包包含进来;
import java.io.*;
import jxl.*;
import jxl.write.*
如果循环语句中使用到了一定的导出格式,建议把格式定义写在循环体外,特别是在数据量很大的时候。否则超出一定数量的数据可能不能按照定义的格式输出;
本文仅是对 Jxl 包提供的一些接口进行了实例调用,对于不同的需求,Jxl 还提供了更
多的接口方法,可以在今后的实践中继续探索研究。(免责声明:文章内容如涉及作品内容、版权和其它问题,请及时与我们联系,我们将在第一时间删除内容,文章内容仅供参考)