SpringBoot集成POI實現Excel導入導出的示例詳解

知識準備

需要瞭解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("[email protected]").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 protected], phoneNumber=121231231231, description=hello world)

示例源碼

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

到此這篇關於SpringBoot集成POI實現Excel導入導出的示例詳解的文章就介紹到這瞭,更多相關SpringBoot Excel導入導出內容請搜索WalkonNet以前的文章或繼續瀏覽下面的相關文章希望大傢以後多多支持WalkonNet!

推薦閱讀: