Apache POI
概述
Apache POI 是用于在 Java 环境中读写 Microsoft Office 格式文件的开源库。
支持对 Excel、Word、PowerPoint 等多种 Office 文件格式进行创建、读取、修改操作。
由于企业开发中最常用的就是导出Excel文件,所以本文就以此进行讲解
入门案例
首先看一个简单的案例,我们需要使用该技术来读
和写
一个Excel文件
第一步导入坐标
<!--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表,并设置好内容
然后通过输出流的方式写入磁盘
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
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系统上提前创建好模板。
这样在后端服务器,先读取模板,然后再填充需求的内容。
首先看数据库的具体结构
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:
/*
HttpServletResponse 对象可用来构建响应内容并返回给浏览器。
对于文件下载而言,就是把文件内容以流的形式写入到 HttpServletResponse 的输出流里,再由浏览器接收并处理。
*/
@GetMapping("/export")
public void export(HttpServletResponse response){bookService.export(response);
}
BookService:
@Service
public class BookService {@Autowiredprivate 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);//由于模板只有一页,此处就写0XSSFSheet 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();}}
}