Apache POI 是用Java编写的免费开源的跨平台的 Java API,Apache POI提供API给Java程序对Microsoft Office格式档案读和写的功能。本文主要介绍通过SpringBoot集成POI工具实现Excel的导入和导出功能。@pdai

知识准备

需要了解POI工具,以及POI对Excel中的对象的封装对应关系。

什么是POI

Apache POI 是用Java编写的免费开源的跨平台的 Java API,Apache POI提供API给Java程序对Microsoft Office格式档案读和写的功能。POI为“Poor Obfuscation Implementation”的首字母缩写,意为“简洁版的模糊实现”。

Apache POI 是创建和维护操作各种符合Office Open XML(OOXML)标准和微软的OLE 2复合文档格式(OLE2)的Java API。用它可以使用Java读取和创建,修改MS Excel文件.而且,还可以使用Java读取和创建MS Word和MSPowerPoint文件。更多请参考官方文档

POI中基础概念

生成xls和xlsx有什么区别?POI对Excel中的对象的封装对应关系?

生成xls和xlsx有什么区别呢?

XLS XLSX
只能打开xls格式,无法直接打开xlsx格式 可以直接打开xls、xlsx格式
只有65536行、256列 可以有1048576行、16384列
占用空间大 占用空间小,运算速度也会快一点

POI对Excel中的对象的封装对应关系如下:

Excel POI XLS POI XLSX(Excel 2007+)
Excel 文件 HSSFWorkbook (xls) XSSFWorkbook(xlsx)
Excel 工作表 HSSFSheet XSSFSheet
Excel 行 HSSFRow XSSFRow
Excel 单元格 HSSFCell XSSFCell
Excel 单元格样式 HSSFCellStyle HSSFCellStyle
Excel 颜色 HSSFColor XSSFColor
Excel 字体 HSSFFont XSSFFont

实现案例

这里展示SpringBoot集成POI导出用户列表的和导入用户列表的例子。

Pom依赖

引入poi的依赖包

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

导出Excel

UserController中导出的方法

@ApiOperation("Download Excel")
@GetMapping("/excel/download")
public void download(HttpServletResponse response) {
try {
SXSSFWorkbook workbook = userService.generateExcelWorkbook();
response.reset();
response.setContentType("application/vnd.ms-excel");
response.setHeader("Content-disposition",
"attachment;filename=user_excel_" + System.currentTimeMillis() + ".xlsx");
OutputStream os = response.getOutputStream();
workbook.write(os);
workbook.dispose();
} catch (Exception e) {
e.printStackTrace();
}
}

UserServiceImple中导出Excel的主方法

private static final int POSITION_ROW = 1;
private static final int POSITION_COL = 1; /**
* @return SXSSFWorkbook
*/
@Override
public SXSSFWorkbook generateExcelWorkbook() {
SXSSFWorkbook workbook = new SXSSFWorkbook();
Sheet sheet = workbook.createSheet(); int rows = POSITION_ROW;
int cols = POSITION_COL; // 表头
Row head = sheet.createRow(rows++);
String[] columns = new String[]{"ID", "Name", "Email", "Phone", "Description"};
int[] colWidths = new int[]{2000, 3000, 5000, 5000, 8000};
CellStyle headStyle = getHeadCellStyle(workbook);
for (int i = 0; i < columns.length; ++i) {
sheet.setColumnWidth(cols, colWidths[i]);
addCellWithStyle(head, cols++, headStyle).setCellValue(columns[i]);
} // 表内容
CellStyle bodyStyle = getBodyCellStyle(workbook);
for (User user : getUserList()) {
cols = POSITION_COL;
Row row = sheet.createRow(rows++);
addCellWithStyle(row, cols++, bodyStyle).setCellValue(user.getId());
addCellWithStyle(row, cols++, bodyStyle).setCellValue(user.getUserName());
addCellWithStyle(row, cols++, bodyStyle).setCellValue(user.getEmail());
addCellWithStyle(row, cols++, bodyStyle).setCellValue(String.valueOf(user.getPhoneNumber()));
addCellWithStyle(row, cols++, bodyStyle).setCellValue(user.getDescription());
}
return workbook;
} private Cell addCellWithStyle(Row row, int colPosition, CellStyle cellStyle) {
Cell cell = row.createCell(colPosition);
cell.setCellStyle(cellStyle);
return cell;
} private List<User> getUserList() {
return Collections.singletonList(User.builder()
.id(1L).userName("pdai").email("pdai@pdai.tech").phoneNumber(121231231231L)
.description("hello world")
.build());
} private CellStyle getHeadCellStyle(Workbook workbook) {
CellStyle style = getBaseCellStyle(workbook); // fill
style.setFillForegroundColor(IndexedColors.GREY_25_PERCENT.getIndex());
style.setFillPattern(FillPatternType.SOLID_FOREGROUND); return style;
} private CellStyle getBodyCellStyle(Workbook workbook) {
return getBaseCellStyle(workbook);
} private CellStyle getBaseCellStyle(Workbook workbook) {
CellStyle style = workbook.createCellStyle(); // font
Font font = workbook.createFont();
font.setBold(true);
style.setFont(font); // align
style.setAlignment(HorizontalAlignment.CENTER);
style.setVerticalAlignment(VerticalAlignment.TOP); // border
style.setBorderBottom(BorderStyle.THIN);
style.setBottomBorderColor(IndexedColors.BLACK.getIndex());
style.setBorderLeft(BorderStyle.THIN);
style.setLeftBorderColor(IndexedColors.BLACK.getIndex());
style.setBorderRight(BorderStyle.THIN);
style.setRightBorderColor(IndexedColors.BLACK.getIndex());
style.setBorderTop(BorderStyle.THIN);
style.setTopBorderColor(IndexedColors.BLACK.getIndex()); return style;
}

导出后的excel如下

导入Excel

我们将上面导出的excel文件导入。

UserController中导入的方法

@ApiOperation("Upload Excel")
@PostMapping("/excel/upload")
public ResponseResult<String> upload(@RequestParam(value = "file", required = true) MultipartFile file) {
try {
userService.upload(file.getInputStream());
} catch (Exception e) {
e.printStackTrace();
return ResponseResult.fail(e.getMessage());
}
return ResponseResult.success();
}

UserServiceImple中导入Excel的主方法

@Override
public void upload(InputStream inputStream) throws IOException {
XSSFWorkbook book = new XSSFWorkbook(inputStream);
XSSFSheet sheet = book.getSheetAt(0);
// add some validation here // parse data
int cols;
for (int i = POSITION_ROW; i < sheet.getLastRowNum(); i++) {
XSSFRow row = sheet.getRow(i + 1); // 表头不算
cols = POSITION_COL;
User user = User.builder()
.id(getCellLongValue(row.getCell(cols++)))
.userName(getCellStringValue(row.getCell(cols++)))
.email(getCellStringValue(row.getCell(cols++)))
.phoneNumber(Long.parseLong(getCellStringValue(row.getCell(cols++))))
.description(getCellStringValue(row.getCell(cols++)))
.build();
log.info(user.toString());
} book.close();
} private String getCellStringValue(XSSFCell cell) {
try {
if (null!=cell) {
return String.valueOf(cell.getStringCellValue());
}
} catch (Exception e) {
return String.valueOf(getCellIntValue(cell));
}
return "";
} private long getCellLongValue(XSSFCell cell) {
try {
if (null!=cell) {
return Long.parseLong("" + (long) cell.getNumericCellValue());
}
} catch (Exception e) {
e.printStackTrace();
}
return 0L;
} private int getCellIntValue(XSSFCell cell) {
try {
if (null!=cell) {
return Integer.parseInt("" + (int) cell.getNumericCellValue());
}
} catch (Exception e) {
e.printStackTrace();
}
return 0;
}

通过PostMan进行接口测试

执行接口后,后台的日志如下

2022-06-10 21:36:01.720  INFO 15100 --- [nio-8080-exec-2] t.p.s.f.e.p.s.impl.UserServiceImpl       : User(id=1, userName=pdai, email=pdai@pdai.tech, phoneNumber=121231231231, description=hello world)

示例源码

https://github.com/realpdai/tech-pdai-spring-demos

参考文章

https://poi.apache.org/index.html

更多内容

告别碎片化学习,无套路一站式体系化学习后端开发: Java 全栈知识体系(https://pdai.tech)

SpringBoot集成文件 - 集成POI之Excel导入导出的更多相关文章

  1. Java之POI的excel导入导出

    一.Apache POI是一种流行的API,它允许程序员使用Java程序创建,修改和显示MS Office文件.这由Apache软件基金会开发使用Java分布式设计或修改Microsoft Offic ...

  2. 基于POI的Excel导入导出(JAVA实现)

    今天做了个excel的导入导出功能,在这记录下. 首先现在相关poi的相关jar包,资源链接:http://download.csdn.net/detail/opening_world/9663247 ...

  3. Spring Boot学习笔记----POI(Excel导入导出)

    业务:动态生成模板导出Excel,用户修改完再导入Excel. Spring boot + bootstrap + poi 1.添加Dependence <dependency> < ...

  4. 【原创】POI操作Excel导入导出工具类ExcelUtil

    关于本类线程安全性的解释: 多数工具方法不涉及共享变量问题,至于添加合并单元格方法addMergeArea,使用ThreadLocal变量存储合并数据,ThreadLocal内部借用Thread.Th ...

  5. POI实现Excel导入导出

    我们知道要创建一张excel你得知道excel由什么组成,比如说sheet也就是一个工作表格,例如一行,一个单元格,单元格格式,单元格内容格式…这些都对应着poi里面的一个类. 一个excel表格: ...

  6. apache POI 操作excel<导入导出>

    1.首先导入maven依赖 <!-- POI核心依赖 --> <dependency> <groupId>org.apache.poi</groupId> ...

  7. 一个基于POI的通用excel导入导出工具类的简单实现及使用方法

    前言: 最近PM来了一个需求,简单来说就是在录入数据时一条一条插入到系统显得非常麻烦,让我实现一个直接通过excel导入的方法一次性录入所有数据.网上关于excel导入导出的例子很多,但大多相互借鉴. ...

  8. poi excel导入导出

    pom <dependency> <groupId>org.apache.poi</groupId> <artifactId>poi</artif ...

  9. Excel导入导出工具(简单、好用且轻量级的海量Excel文件导入导出解决方案.)

    Excel导入导出工具(简单.好用且轻量级的海量Excel文件导入导出解决方案.) 置顶 2019-09-07 16:47:10 $9420 阅读数 261更多 分类专栏: java   版权声明:本 ...

随机推荐

  1. 一文说透 MySQL JSON 数据类型(收藏)

    JSON 数据类型是 MySQL 5.7.8 开始支持的.在此之前,只能通过字符类型(CHAR,VARCHAR 或 TEXT )来保存 JSON 文档. 相对字符类型,原生的 JSON 类型具有以下优 ...

  2. 使用NFS作为Glance存储后端

    NFS服务介绍 NFS网络文件系统提供了一种在类UNIX系统上共享文件的方法.目前NFS有3个版本:NFSv2.NFSv3.NFSv4.CentOS7默认使用NFSv4提供服务,优点是提供了有状态的连 ...

  3. 弃用!Github 上用了 Git.io 缩址服务的都注意了

    GitHub 是面向开源及私有软件项目的托管平台,因为只支持 Git 作为唯一的版本库格式进行托管,故名 GitHub.对程序员来说,GitHub 可以说是开源精神之所系.在 GitHub 任何职业程 ...

  4. DOM 事件与事件委托

    DOM 事件与事件委托 本文写于 2020 年 5 月 28 日 先思考一个问题:我们如何给一百个 button 添加点击事件? 遍历? 那岂不是要添加一百个监听器? 这就需要事件委托了. 其实这根本 ...

  5. Vulnhub-napping

    1.信息收集 先用arp-scan探测出靶机地址 arps-scan -l 显然靶机地址 10.1.1.106,然后利用nmap进行详细信息收集 nmap -A 10.1.1.106 可以看到,目标的 ...

  6. 【多线程】线程优先级 Priority

    线程优先级 Priority Java提供一个线程调度器来监控程序中启动后进入就绪状态的所有线程,线程调度 器按照优先级决定应该调度哪个线程来执行. 线程的优先级用数字表示,范围从1~10. Thre ...

  7. layui数据表格导入数据

    作为一个后端程序员,前端做的确实很丑,所以就学习了一下layui框架的使用.数据表格主要的问题就是传输数据的问题,这里我用我的前后端代码来做一个实际的分解. 前端部分 可以到layui官网示例中找到数 ...

  8. 每日一题20180330-Linux

    一.问题 1.1 统计/var/log/下所有文件个数 1.2 查找出/var/log目录下面修改时间是7天以前,大小在50k到2M之间,并以.log结尾的文件把这些文件复制到/data目录中 1.3 ...

  9. 编程语言与python与pycharm的下载

    目录 编程语言的发展史 编程语言的分类 python解释器 python解释器的下载与安装 环境变量 执行python程序方式 pycharm编辑器 编程语言的发展史 机器语言是最开始的编程语言,之后 ...

  10. 给小白的 PostgreSQL 容器化部署教程(上)

    作者:王志斌 编辑:钟华龙 本文来自社区小伙伴 王志斌 的投稿.从小白的角度,带你一步步实现将 RadonDB PostgreSQL 集群部署到 Kubernetes 上.文章分为上下两部分,第一部分 ...