SpringBoot集成POI實(shí)現(xiàn)Excel導(dǎo)入導(dǎo)出的示例詳解
知識(shí)準(zhǔn)備
需要了解POI工具,以及POI對(duì)Excel中的對(duì)象的封裝對(duì)應(yīng)關(guān)系。
什么是POI
Apache POI 是用Java編寫的免費(fèi)開源的跨平臺(tái)的 Java API,Apache POI提供API給Java程序?qū)icrosoft Office格式檔案讀和寫的功能。POI為“Poor Obfuscation Implementation”的首字母縮寫,意為“簡(jiǎn)潔版的模糊實(shí)現(xiàn)”。
Apache POI 是創(chuàng)建和維護(hù)操作各種符合Office Open XML(OOXML)標(biāo)準(zhǔn)和微軟的OLE 2復(fù)合文檔格式(OLE2)的Java API。用它可以使用Java讀取和創(chuàng)建,修改MS Excel文件.而且,還可以使用Java讀取和創(chuàng)建MS Word和MSPowerPoint文件。更多請(qǐng)參考官方文檔。
POI中基礎(chǔ)概念
生成xls和xlsx有什么區(qū)別?POI對(duì)Excel中的對(duì)象的封裝對(duì)應(yīng)關(guān)系?
生成xls和xlsx有什么區(qū)別呢?
| XLS | XLSX |
|---|---|
| 只能打開xls格式,無(wú)法直接打開xlsx格式 | 可以直接打開xls、xlsx格式 |
| 只有65536行、256列 | 可以有1048576行、16384列 |
| 占用空間大 | 占用空間小,運(yùn)算速度也會(huì)快一點(diǎn) |
POI對(duì)Excel中的對(duì)象的封裝對(duì)應(yīng)關(guān)系如下:
| 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 |
實(shí)現(xiàn)案例
這里展示SpringBoot集成POI導(dǎo)出用戶列表的和導(dǎo)入用戶列表的例子。
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>
導(dǎo)出Excel
UserController中導(dǎo)出的方法
@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中導(dǎo)出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]);
}
// 表內(nè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;
}
導(dǎo)出后的excel如下

導(dǎo)入Excel
我們將上面導(dǎo)出的excel文件導(dǎo)入。
UserController中導(dǎo)入的方法
@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中導(dǎo)入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進(jìn)行接口測(cè)試

執(zhí)行接口后,后臺(tái)的日志如下
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
到此這篇關(guān)于SpringBoot集成POI實(shí)現(xiàn)Excel導(dǎo)入導(dǎo)出的示例詳解的文章就介紹到這了,更多相關(guān)SpringBoot Excel導(dǎo)入導(dǎo)出內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
Mybatis-plus使用selectList查詢數(shù)據(jù)為null的問題及解決辦法
這篇文章主要介紹了Mybatis-plus使用selectList查詢數(shù)據(jù)為null的問題及解決方法,本文給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2022-07-07
Java泛型之協(xié)變與逆變及extends與super選擇
這篇文章主要介紹了Java泛型之協(xié)變與逆變及extends與super選擇,文章圍繞主題內(nèi)容展開詳細(xì)內(nèi)容介紹,需要的小伙伴可以參考一下2022-05-05
Java中ArrayList和LinkedList的遍歷與性能分析
這篇文章主要給大家介紹了ArrayList和LinkedList這兩種list的五種循環(huán)遍歷方式,各種方式的性能測(cè)試對(duì)比,根據(jù)ArrayList和LinkedList的源碼實(shí)現(xiàn)分析性能結(jié)果,總結(jié)結(jié)論。相信對(duì)大家的理解和學(xué)習(xí)具有一定的參考價(jià)值,有需要的朋友們下面跟著小編一起來(lái)學(xué)習(xí)學(xué)習(xí)吧。2016-12-12
SpringBoot使用thymeleaf實(shí)現(xiàn)一個(gè)前端表格方法詳解
Thymeleaf是一個(gè)現(xiàn)代的服務(wù)器端 Java 模板引擎,適用于 Web 和獨(dú)立環(huán)境。Thymeleaf 的主要目標(biāo)是為您的開發(fā)工作流程帶來(lái)優(yōu)雅的自然模板,本文就來(lái)用它實(shí)現(xiàn)一個(gè)前端表格,感興趣的可以了解一下2022-10-10
springcloud教程之zuul路由網(wǎng)關(guān)的實(shí)現(xiàn)
這篇文章主要介紹了springcloud教程之zuul路由網(wǎng)關(guān)的實(shí)現(xiàn),文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2020-02-02
如何創(chuàng)建SpringBoot項(xiàng)目
這篇文章主要介紹了如何創(chuàng)建SpringBoot項(xiàng)目,幫助大家更好的學(xué)習(xí)和使用springboot框架,感興趣的朋友可以了解下2021-01-01
如何更優(yōu)雅地獲取spring boot yml中的值
這篇文章主要給大家介紹了關(guān)于如何更優(yōu)雅地獲取spring boot yml中值的相關(guān)資料,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家學(xué)習(xí)或者使用spring boot具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2019-06-06

