SpringBoot集成POI实现Excel导入导出的示例详解

作者:pdai 时间:2022-12-05 19:09:10 

知识准备

需要了解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有什么区别呢?

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

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

ExcelPOI XLSPOI XLSX(Excel 2007+)
Excel 文件HSSFWorkbook (xls)XSSFWorkbook(xlsx)
Excel 工作表HSSFSheetXSSFSheet
Excel 行HSSFRowXSSFRow
Excel 单元格HSSFCellXSSFCell
Excel 单元格样式HSSFCellStyleHSSFCellStyle
Excel 颜色HSSFColorXSSFColor
Excel 字体HSSFFontXSSFFont

实现案例

这里展示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如下

SpringBoot集成POI实现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进行接口测试

SpringBoot集成POI实现Excel导入导出的示例详解

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

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://www.cnblogs.com/pengdai/p/16504282.html

标签:SpringBoot,POI,Excel
0
投稿

猜你喜欢

  • C#日期格式字符串的相互转换操作实例分析

    2021-09-01 10:06:56
  • java线程并发控制同步工具CountDownLatch

    2022-09-02 12:18:06
  • C#高级静态语言效率利器之泛型详解

    2023-01-24 09:18:02
  • Java emoji持久化mysql过程详解

    2023-10-10 23:11:49
  • Android Studio 一键生成Json实体类教程

    2023-05-19 20:13:39
  • Java+Selenium实现文件上传下载功能详解

    2021-06-23 23:33:23
  • c#.net多线程编程教学——线程同步

    2021-12-27 06:03:50
  • c#中XML解析文件出错解决方法

    2022-01-21 00:38:50
  • Springboot整合企业微信机器人助手推送消息的实现

    2023-08-18 08:37:37
  • C#访问SqlServer设置链接超时的方法

    2022-11-19 17:43:21
  • Android数字华容道小游戏开发

    2023-10-06 22:31:35
  • C#关闭指定名字进程的方法

    2021-11-23 23:59:42
  • 高并发下restTemplate的错误分析方式

    2023-08-23 12:58:24
  • Java深入浅出数组的定义与使用上篇

    2022-03-10 22:32:58
  • springboot中使用FastJson解决long类型在js中失去精度的问题

    2022-04-05 05:15:27
  • Java I/O流实例之简历替换

    2022-04-23 08:55:07
  • 关于C++中菱形继承和虚继承的问题总结

    2021-10-03 20:22:23
  • 使用maven运行Java Main的三种方法解析

    2021-09-24 10:09:28
  • 基于android实现五子棋开发

    2022-05-22 14:21:43
  • idea 多模块项目依赖父工程class找不到问题的方法

    2022-06-08 10:47:41
  • asp之家 软件编程 m.aspxhome.com