使用POI导出数据到Excel报表

我们在做 学生管理系统的时候 可能需要完成到处学生报表之类的功能,那么怎么实现导出数据到Excel报表呢?

首先我们要知道Excel报表也是一种文件(通常以xls,xlsx结尾),也就是说我们操作Excel报表和操作文件差不多。Excel是一种特殊格式的文件。

使用java生成Excel数据报表的步骤如下:

  1. 导入相关依赖(jar包)
  2. 生成Excel文件对象(但是注意对象现在只存在内存中,并没有保存到文件)
  3. 操作Excel文件(即导入数据,操作样式之类的)
  4. 将该对象保存到文件中。

相关依赖如下,如果是maven工程直接添加依赖就行了,非maven工程需要下载jar包然后手动添加到工程中:

<dependency>
      <groupId>org.apache.poi</groupId>
      <artifactId>poi</artifactId>
      <version>4.0.1</version>
    </dependency>
    <dependency>
      <groupId>org.apache.poi</groupId>
      <artifactId>poi-ooxml-schemas</artifactId>
      <version>4.0.1</version>
    </dependency>
    <dependency>
      <groupId>org.apache.poi</groupId>
      <artifactId>poi-ooxml</artifactId>
      <version>4.0.1</version>
    </dependency>

接下来就是代码操作了,简单的代码实现如下:

//创建文件对象
SXSSFWorkbook wb = new SXSSFWorkbook();
//创建 表并指定名称
SXSSFSheet sheet = wb.createSheet("样式表");
//获取行对象
SXSSFRow row = sheet.createRow(0);
//获取具体的单元格
SXSSFCell cell = row.createCell(0);
cell.setCellValue("this is a test value!");
//创建文件并获取输出流
File file = new File("test.xlsx");
OutputStream os = new FileOutputStream(file);
wb.write(os);
wb.close();
os.close();

这里面各个对象之间一定要搞清楚,我们知道一个Excel文件中有多张表,所以我们要先创建一张表并获取它的对象,然后一张表又分为多个Row,我们先创建一个row并获取它的对象,一个row里面又分为多个小隔间(cell),创建并获取一个cell对象,然后设置该cell对象的值就行了。

POI的操作非常非常非常多且复杂,我只是提供一个十分简单的 关于 如何创建xlsx文件并设置其中的值的例子,不过对于导出学生报表来说以已经够用了。

但是当我们仔细思考后发现不对啊,虽然是生成了一个xlsx文件,但是…. 这个文件 好像是在服务器生成的啊,用户点击生成报表,结果在服务器生成了文件,用户又获取不到,这不是笑话了吗。所以最后的文件保存有问题,解决办法如下:

我们不应该直接通过 文件输出流输出,这样仅仅将文件输出到了服务器,我们应该将数据通过response发送给用户,我们知道response中有一个getOutputSream方法可以获取输出流。但是response在servlet中,而根据项目规范我们获取数据流的操作应该在service层,而在servlet中调用service层的方法,所以我们应该将数据流作为方法的参数返回。什么类型的数据流? ByteArrayOutputSream

然后通过ByteArrayOutputSream的writeTo方法将该流写入到response的输出流中。这样可以将数据输出,但是都是乱码,因为我们没有设置输出文件的格式。

通过response.setContentType("类型")来设置输出类型,但是这个类型是什么呢?难道是xlsx?不是,对于每一种文件格式都有规定的类型名,查看方式如下:

打开tomcat安装目录,打开conf目录下的web.xml文件,然后搜索 xlsx,可以得到如下信息

<mime-mapping>
        <extension>xlsx</extension>
        <mime-type>application/vnd.openxmlformats-officedocument.spreadsheetml.sheet</mime-type>
    </mime-mapping>

下面的那一串application/vnd.openxmlformats-officedocument.spreadsheetml.sheet就是我们需要的东西了。

response.setContentType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet;charset=utf-8")

后面别忘了加一个 charset=utf-8 哦 !