Java Web实现数据导出

导出数据至Excel文件

需求

  • 一个Web项目中将表格数据导出至Excel文件中

现有技术或工具

Apache POI

简介

看到标题已然知道,即将介绍的这款用于导出数据的工具又是Apache开源项目之一,不得不说,Apache对IT领域的贡献,程序猿皆知。

Apache POI(以下简称POI)是一款用Java语言编写的开源的跨平台Java API,全称是Poor Obfuscation Implementation(可怜的模糊实现)。该API提供方法完成对Microsoft Office(Excel、WORD、PowerPoint、Visio等)格式档案读和写的功能。

常用类
类名(包名)用途
HSSF提供读写Microsoft Excel XLS格式档案的功能(Excel97-2003)(也即我们用的.xls格式的Excel文件)
XSSF提供读写Microsoft Excel OOXML XLSX格式档案的功能(Excel2007以后)(也即我们用的.xlsx格式的Excel文件)
XWPF提供读写Microsoft Word DOC2003格式档案的功能

这里我们使用到了HSSF来处理Excel数据的导出,我们先介绍HSSF

HSSF

(1) 简介

  • HSSF全称是Horrible SpreadSheet Format,可以通过该方法用纯Java代码处理Excel文件。上面说到HSSFPOI提供的处理Excel文件的一种方法,更准确的说其实一类方法的总称,这些类位于org.apache.poi.hssf包中。打开该包可以发现,又存在多个子包,我们这里使用到的是usermodel包中的类,至于其他包中的内容,后面在研究其用途。
    HSSF使用到的类所处的包位置
    知道了包的基本结构,该如何使用其中的类呢?下面我们从一个简单的例子入手。

(2) 使用HSSF创建并导出一个简单的Excel文件

  • 要使用POI提供的这个工具,首先我们需要导入jar包,当用Maven创建的项目时可以直接在其中加入需要的依赖即可,具体如下。

    • 导入jar包的方式
      在所在项目的lib目录中导入下图所示的jar包即可。
      在这里插入图片描述

    • Maven引入依赖的方式
      在所在Maven项目的pom.xml文件中,引入下图所示的依赖即可。
      在这里插入图片描述

  • 在导入依赖的插件之后,我们就可以开始使用其提供的类和方法了。这里我们首先创建并导出一个简单的Excel文件,具体代码如下,代码中有详细注释。

    /**
     * 导入的包结构
     */
    import org.apache.poi.hssf.usermodel.HSSFCell;
    import org.apache.poi.hssf.usermodel.HSSFRow;
    import org.apache.poi.hssf.usermodel.HSSFSheet;
    import org.apache.poi.hssf.usermodel.HSSFWorkbook;
    
    // 创建Excel工作簿
    HSSFWorkbook wk = new HSSFWorkbook();
    // 创建一张工作表
    HSSFSheet sheet = wk.createSheet("我的工作表");
    // 设置第一列的列宽
    sheet.setColumnWidth(0, 256*15+184); // 这样设置列宽,第二个参数即是Excel中实际显示的列宽
    // 创建第一行
    HSSFRow row = sheet.createRow(0);
    // 创建第一行中的第一个单元格
    HSSFCell column = row.createCell(0);
    // 向单元格中写值
    column.setCellValue("测试");
    // 将工作簿保存到本地目录
    try {
    	wk.write(new FileOutputStream(new File("d:\\poitest.xls")));
    } catch (Exception e) {
    	e.printStackTrace();
    }finally {
    	try {
    		// 关闭资源
    		wk.close();
    	} catch (IOException e) {
    		e.printStackTrace();
    	}
    }
    

    上面的代码就是创建并向本地磁盘输出了一个最基本的Excel表,结果如下图所示。
    在这里插入图片描述

    我们再来分析一下上面的代码到底完成了哪些工作?
    在这里插入图片描述
    可以发现,hssf包中提供的类对应于Excel的每一个对象,每使用包中的一个类,就创建了一个Excel部件对象。我们可以抽象出一个Excel表该有的内容,如下面的树形所示。想必看到类似这样的树形图大家也不陌生,DOM对象就是这种树形结构。

    在两张图中,第一章是整个Excel文件(不管是什么格式的Excel文件)的部件抽象,从最基本的一个工作簿开始到其中的多个工作表,最后到行以及行中的元素(这里抽象层次中行与列的关系有点类似我们学过的二维数组的存储方案:行优先,与此对应的还有列优先算法)。

    第二张图中展示的是HSSF处理xls格式的Excel文件使用的类结构图,与第一张图的类相比,在基本部件的前面加上了具体的包信息HSSF
    在这里插入图片描述

在这里插入图片描述

(3)在Web系统中使用HSSF导出表格数据至Excel文件

有了上面简单的使用实例,我们就可以在真正的Web系统中使用该文件导出表格数据至Excel文件中了。在笔者目前接触到的系统中,导入导出数据操作是很频繁且通用的需求。因为我们知道,网站中的数据大多数是以网格的形式展示和组织的,如果你所开发的系统要操作大量数据,单凭手工导入或导出是不行的,这样我们就需要借助工具来实现数据的导入导出。与展示形式类似,在导出数据的媒介中,我们也选择数据表格,Excel就是不错的输出地。输出到Excel的数据,因为其格式的特殊性,在现在做数据处理时也是比较方面的,无论是纯Excel函数处理还是机器学习算法。

在笔者的认识里,要将系统中的数据写入Excel文件,首先要做的就是写入表头的信息,也即表格首行的栏目项,但一般我们可能将表头信息在前端页面中配置(现在想明白了我们所接触的项目中为什么将表头信息也存储在数据库中,即这样可以避免前端页面中大量重复冗余的代码;同时配置时也比较方便,改变数据库中的内容即可;如有加载表头信息的需求,可以直接读取数据库即可),这样需要在后端代码中定义数组或列表来保存全部的字段值。

以我们的例子为例,我们的需求是要导出供应商的信息,前端中的展示如下图所示。

在这里插入图片描述
可以看出,我们需要导出的字段并不多。在表格中我们也需要表头信息,故我们在服务端代码中加入需要的表头信息。代码如下:

// 定义好每一列的标题
String[] headerNames = {"名称", "地址", "联系人", "电话", "Email"};

定义好了表头,我们需要在写入数据时,严格按照表头内容对应的字段写入。这李我们需要首先将表头信息写入表格中,代码如下:

// 创建工作簿
HSSFWorkbook wk = new HSSFWorkbook();
// 创建工作表sheet
HSSFSheet sheet = null;

// 写入表头信息
HSSFRow row = sheet.createRow(0);
// 定义好每一列的标题
String[] headerNames = {"名称", "地址", "联系人", "电话", "Email"};
// 指定每一列的宽度
int[] columnsWidths = {256*15+184, 256*40+184, 256*15+184, 256*15+184, 256*30+184};
// 创建每一行的元素(列)
HSSFCell cell = null;
// 写入表头内容
for (int i = 0; i < headerNames.length; i++) {
	cell = row.createCell(i);
	cell.setCellValue(headerNames[i]);
	sheet.setColumnWidth(i, columnsWidths[i]);
}

我们可以将上面的内容抽象为一个方法,这样每次只需要传入具体的表头信息,实现代码的重复使用。

在写好上面的表头信息后,我们就可以遍历数据并将其写入到数据行中了。注意,为了内容不出错,一定严格按照表头信息字段写入数据。我们例子中的代码如下:

// 写入数据
int i = 1;
for (Supplier supplier : supplierList) {
	row = sheet.createRow(i);
	// 按照表头顺序写入数据
	row.createCell(0).setCellValue(supplier.getName()); // 名称
	row.createCell(1).setCellValue(supplier.getAddress()); // 地址
	row.createCell(2).setCellValue(supplier.getContact()); // 联系人
	row.createCell(3).setCellValue(supplier.getTele()); // 电话
	row.createCell(4).setCellValue(supplier.getEmail()); // Email
	i++;
}

(4)在Web系统中使用Excel模板写入数据

在笔者接触到的系统中,将表头信息直接写在Excel模板中,这样可以不用在后端代码中再写入。这样一来,我们只需要将模板表存入指定路径中,之后通过文件输入流的方式创建HSSFHSSFWorkbook对象,代码如下:

FileInputStream fis = new FileInputStream(new File(SupplierAction.class.getClassLoader().getResource("template.xls").getPath()));
HSSFWorkbook wk =  new HSSFWorkbook(fis);

通过这种方式写入时,若想改变模板表的Sheet名称,可以直接通过索引修改,代码如下:

wk.setSheetName(0, "供应商列表");

之后严格按照模板表的表头信息写入数据即可。

POI操作Excel高低版本区别

上面介绍的HSSF类主要是操作低版本Excel(Excel97-2003)的类,正如在简介中介绍的那样,使用POI提供的其他类可以操作其他版本的Excel。不管哪个类或哪个版本,基本与HSSF操作Excel类似,只不过类的名字或方法的名字存在差异,这里只对这种差异列出对比。
在使用Maven构建项目时,需要引入的依赖如下,版本可按实际需求进行更改。

<!-- 操作低版本Excel时 -->
<dependency>
	<groupId>org.apache.poi</groupId>
    <artifactId>poi</artifactId>
    <version>4.0.1</version>
</dependency>

<!-- 操作高版本Excel时 -->
<dependency>
	<groupId>org.apache.poi</groupId>
    <artifactId>poi-ooxml</artifactId>
    <version>4.0.1</version>
</dependency>

<!-- 辅助工具 如导入大批量数据 -->
<dependency>
	<groupId>org.apache.poi</groupId>
    <artifactId>poi-ooxml-schemas</artifactId>
    <version>4.0.1</version>
</dependency>

高低版本中对象的差异如下表所示。

对应Excel名称低版本类名高版本类名
工作簿HSSFWorkbookXSSFWorkbook
工作表HSSFSheetXSSFSheet
HSSFRowXSSFRow
单元格HSSFCellXSSFCell
单元格样式HSSFCellStyleXSSFCellStyle
  • 3
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值