Apache POI

Apache POI

概述

Apache POI 是用于在 Java 环境中读写 Microsoft Office 格式文件的开源库。

支持对 Excel、Word、PowerPoint 等多种 Office 文件格式进行创建、读取、修改操作。

由于企业开发中最常用的就是导出Excel文件,所以本文就以此进行讲解

入门案例

首先看一个简单的案例,我们需要使用该技术来一个Excel文件

第一步导入坐标

xml 复制代码
<!--poi 和 poi-ooxml 分别用于处理 .xls 和 .xlsx 文件-->
<dependency>
    <groupId>org.apache.poi</groupId>
    <artifactId>poi</artifactId>
    <version>3.16</version>
</dependency>
<dependency>
    <groupId>org.apache.poi</groupId>
    <artifactId>poi-ooxml</artifactId>
    <version>3.16</version>
</dependency>

写Excel

执行思路是先在内存中创建一个Excel表,并设置好内容

然后通过输出流的方式写入磁盘

java 复制代码
main(){
	//在内存中创建一个Excel表
    XSSFWorkbook excel = new XSSFWorkbook();
    //创建一个sheet页
    XSSFSheet sheet = excel.createSheet("info");
    //创建行
    XSSFRow row = sheet.createRow(0);
    //创建行内单元格
    XSSFCell cell = row.createCell(0);
    //设置改单元格的内容
    cell.setCellValue("Name");
    row.createCell(1).setCellValue("Age");

    //通过输出流写入磁盘,注意此处会抛出IO异常
    FileOutputStream file = new FileOutputStream(new File("D:\\info.xlsx"));
    excel.write(file);

    //关闭资源
    file.close();
    excel.close();
}

读Excel

java 复制代码
main() {
    //通过输入流读取磁盘中的Excel文件,注意此处会抛出IO异常
    FileInputStream in = new FileInputStream(new File("D:\\info.xlsx"));
    //通过流获取该Excel文件的对象
    XSSFWorkbook excel = new XSSFWorkbook(in);
    //读取Excel的sheet页
    XSSFSheet sheet = excel.getSheetAt(0);
    //读取当前页中的行
    XSSFRow row = sheet.getRow(0);
    //读取当前行的单元格
    XSSFCell cell = row.getCell(0);
    //获取改单元格的值
    String stringCellValue = cell.getStringCellValue();
    System.out.println(stringCellValue);
    
    //关闭资源
    excel.close();
    fileInputStream.close();
}

完整案例

需求:读取数据库book表中所有的数据,并且存放到带有样式的Excel文件中返回给浏览器下载(第一行为表头,从第二行开始和数据库表格一致)。

需求分析:

  • 请求导出报表属于查询操作,并且不需要携带任何参数。所以使用GET请求方式较为合理
  • 导出文件本质就是后端通过输出流返回给浏览器,然后浏览器下载文件。

所以在接口设计中,不需要请求参数和返回数据

此处我们规定请求url为: localhost:8080://book/exprot GET

在实际需求中,需要导出的Excel具有一些样式,如单元格居中,背景色,字号等样式。

如果完全使用POI代码编写的话,十分繁琐,所以我们会在Windows系统上提前创建好模板。

这样在后端服务器,先读取模板,然后再填充需求的内容。

首先看数据库的具体结构

sql 复制代码
CREATE TABLE `book` (
  `id` int NOT NULL,
  `type` varchar(20) DEFAULT NULL,
  `name` varchar(50) DEFAULT NULL,
  `description` varchar(255) DEFAULT NULL,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;

根据数据库创建出对应的Springboot工程(注意引入坐标),创建对应的Book实体类,以及Controller、Service、Mapper三层架构。(很简单,此处省略)

BookController:

java 复制代码
/*
HttpServletResponse 对象可用来构建响应内容并返回给浏览器。
对于文件下载而言,就是把文件内容以流的形式写入到 HttpServletResponse 的输出流里,再由浏览器接收并处理。
*/
@GetMapping("/export")
public void export(HttpServletResponse response){
    bookService.export(response);
}

BookService:

java 复制代码
@Service
public class BookService {

    @Autowired
    private BookMapper bookMapper;

    public void export(HttpServletResponse response){
        //查询数据库中所有图书数据
        List<Book> books = bookMapper.selectAll();

        // 设置响应头
        response.setContentType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet");
        try {
            response.setHeader("Content-Disposition", "attachment;filename=" + URLEncoder.encode("图书列表.xlsx", "UTF-8"));
        } catch (IOException e) {
            e.printStackTrace();
        }

        try {
            //通过反射获取类加载器中类路径下的Excel模板
            InputStream inputStream = this.getClass().getClassLoader().getResourceAsStream("template/ExcelTemplate.xlsx");
            //基于模板文件创建新的Excel文件
            XSSFWorkbook excel = new XSSFWorkbook(inputStream);
            //由于模板只有一页,此处就写0
            XSSFSheet sheet = excel.getSheetAt(0);
            //因为第一行是表头,所以从第二行开始写
            int rowIndex = 1;
            //通过前面查询到的所有book对象,使用增强for遍历
            for (Book book : books) {
                XSSFRow row = sheet.getRow(rowIndex++);
                row.getCell(0).setCellValue(book.getId());
                row.getCell(1).setCellValue(book.getType());
                row.getCell(2).setCellValue(book.getName());
                row.getCell(3).setCellValue(book.getDescription());
            }
            //通过输出流下载到浏览器
            ServletOutputStream out = response.getOutputStream();
            excel.write(out);

			//关闭资源
            out.close();
            inputStream.close();
            excel.close();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}
相关推荐
沈健_算法小生4 小时前
Apache Kafka核心组件详解
分布式·kafka·apache
lang2015092818 小时前
Apache Ignite 的对等类加载(Peer Class Loading, P2P Class Loading)机制
apache·ignite
chen_note20 小时前
LAMP及其环境的部署搭建
linux·运维·mysql·php·apache·lamp·phpmyadmin
lang2015092820 小时前
Apache Ignite 与 Spring Boot 集成
spring boot·后端·apache·ignite
lang2015092821 小时前
如何使用 Apache Ignite 作为 Spring 框架的缓存(Spring Cache)后端
spring·缓存·apache·ignite
lang201509281 天前
Apache Ignite 的监控与指标(Monitoring and Metrics)
apache·ignite
lang201509281 天前
Apache Ignite 集群状态(Cluster States)
apache·ignite
谈不譚网安1 天前
Apache HTTP Server 2.4.50 路径穿越漏洞(CVE-2021-42013)
网络协议·http·apache
lang201509281 天前
Apache Ignite 的分布式锁Distributed Locks的介绍
apache·ignite
lang201509282 天前
关于 Apache Ignite 中 Job 调度(Job Scheduling)与冲突控制(Collision Control) 的机制说明
apache·ignite