Apache POI HSSFWorkbook:工作簿到位元組流的轉換
1. 概述
在企業級 Java 應用程式中,處理 Excel 檔案是最常見的任務之一,從報表到分析匯出,無所不包。 Apache POI 函式庫使得直接從 Java 程式碼讀取和寫入 Excel 檔案變得極為簡單。
在本教程中,我們來探討如何使用 本文將示範如何在 Spring Boot 專案中使用HSSFWorkbook從頭開始建立一個 Excel 工作簿:將其轉換為位元組流,從位元組流重建工作簿,最後透過 REST 端點提供服務。完成本文後,我們將清楚了解 Apache POI 如何與 Spring Boot 無縫集成,實現動態 Excel 生成。
2. 設定 Apache POI
在編寫任何程式碼之前,我們將在 Spring Boot 專案中為 Maven 添加必要的依賴項:
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.apache.poi</groupId>
<artifactId>poi</artifactId>
<version>5.3.0</version>
</dependency>
</dependencies>
這 s pring-boot-starter-web相依性提供了 Spring MVC、REST 功能和嵌入式 Tomcat,這對於暴露下載端點至關重要。 Apache POI( org.apache.poi )處理 Excel 檔案的建立、修改和轉換為位元組。
2.1 從零開始建立HSSFWorkbook
現在設定已經完成,讓我們建立一個簡單的 Excel 工作簿來儲存資料:
public class ExcelCreator {
public static HSSFWorkbook createSampleWorkbook() {
HSSFWorkbook workbook = new HSSFWorkbook();
final String SHEET_NAME = "Employees";
final String[] COLUMN_HEADERS = { "ID", "Name", "Department" };
Object[][] data = { { 101, "John Doe", "Finance" }, { 102, "Jane Smith", "HR" }, { 103, "Michael Clark", "IT" } };
Sheet sheet = workbook.createSheet(SHEET_NAME);
HSSFFont font = workbook.createFont();
font.setBold(true);
HSSFCellStyle headerStyle = workbook.createCellStyle();
headerStyle.setFont(font);
Row header = sheet.createRow(0);
for (int i = 0; i < COLUMN_HEADERS.length; i++) {
Cell cell = header.createCell(i);
cell.setCellValue(COLUMN_HEADERS[i]);
cell.setCellStyle(headerStyle);
}
int rowNum = 1;
for (Object[] rowData : data) {
Row row = sheet.createRow(rowNum++);
for (int i = 0; i < rowData.length; i++) {
Cell cell = row.createCell(i);
Object value = rowData[i];
if (value instanceof Integer) {
cell.setCellValue(((Integer) value).doubleValue());
} else if (value instanceof Double) {
cell.setCellValue((Double) value);
} else if (value != null) {
cell.setCellValue(value.toString());
}
}
}
for (int i = 0; i < COLUMN_HEADERS.length; i++) {
sheet.autoSizeColumn(i);
}
return workbook;
}
}
讓我們來分析一下效用函數, createSampleWorkbook() 。我們先初始化一個新的 HSSFWorkbook是代表 Excel 檔案的核心物件。 我們採用.xls格式。定義範例員工資料和列標題,然後立即建立「員工」工作表。為了提高可讀性,我們定義粗體字體並將其應用於單元格樣式,確保列標題更加醒目。
此方法的主要功能是產生一個包含預先定義員工資料的 HSSFWorkbook 對象,以便進行輸出。在表頭之後,我們遍歷範例資料數組,並根據需要建立新的行和儲存格。
最後,我們使用以下方法根據列的內容長度自動調整所有列的大小: sheet.autoSizeColumn() 。此步驟會自動調整列寬以適應內容,確保最終的電子表格在返回之前看起來整潔且專業。 HSSFWorkbook物件。
2.2. 將HSSFWorkbook轉換為位元組流
既然我們已經可以建立工作簿,接下來讓我們將其轉換為位元組。這在將檔案儲存到資料庫、作為 REST 回應發送檔案或將其快取到記憶體時非常有用:
public class ExcelConverter {
public static byte[] convertWorkbookToBytes(HSSFWorkbook workbook) throws IOException {
try (ByteArrayOutputStream baos = new ByteArrayOutputStream()) {
workbook.write(baos);
return baos.toByteArray();
}
}
}
工作簿被寫入一個ByteArrayOutputStream ,該流會將其暫時儲存在記憶體中。然後我們使用以下方法來提取位元組數組: toByteArray() 。
這種轉換是檔案傳輸的基礎,它是一種輕量級且記憶體效率高的方法,尤其適用於提供動態內容的 RESTful 應用程式。透過使用字節,我們可以將 Excel 處理過程保存在記憶體中,從而無需臨時檔案儲存。
2.3. 將位元組流轉換回 HSSFWorkbook
一旦工作簿轉換為位元組格式,使用以下方法即可輕鬆重建它: ByteArrayInputStream :
public static HSSFWorkbook convertBytesToWorkbook(byte[] excelBytes) throws IOException {
try (ByteArrayInputStream bais = new ByteArrayInputStream(excelBytes)) {
return new HSSFWorkbook(bais);
}
}
這段程式碼逆轉了之前的過程。 位元組數組成為輸入流, HSSFWorkbook建構函數會讀取該輸入流以在記憶體中重建 Excel 工作簿。
當讀取儲存在資料庫、快取物件或從其他服務接收的 Excel 資料時,它尤其有用。
3. Spring Boot 應用程式中的實際用例
讓我們把所有內容整合到一個可用的 REST 端點中。
3.1 將HSSFWorkbook轉換為位元組流
此端點將動態產生 Excel 工作簿並將其作為可下載檔案提供。 .xls檔案:
@RestController
public class ExcelController {
@GetMapping("/download-excel")
public ResponseEntity<byte[]> downloadExcel() {
try {
HSSFWorkbook workbook = ExcelCreator.createSampleWorkbook();
try (ByteArrayOutputStream baos = new ByteArrayOutputStream()) {
workbook.write(baos);
byte[] bytes = baos.toByteArray();
return ResponseEntity.ok()
.header(HttpHeaders.CONTENT_DISPOSITION, "attachment; filename=employee_data.xls")
.contentType(MediaType.parseMediaType("application/vnd.ms-excel"))
.body(bytes);
}
} catch (IOException e) {
System.err.println("Error generating or writing Excel workbook: " + e.getMessage());
return ResponseEntity.internalServerError()
.build();
}
}
}
這個 Spring Boot 控制器,標記為 @RestController ,定義了一個單一的端點, /download-excel ,它處理 HTTP GET 請求。我們透過調用來啟動該過程。 ExcelCreator.createSampleWorkbook() ,它會在記憶體中產生原始的 Excel 資料結構。 此控制器的主要目的是攔截 GET 要求,並將動態產生的 Excel 檔案直接提供給用戶端瀏覽器,而無需存取伺服器的檔案系統。取得工作簿後,我們使用… 使用ByteArrayOutputStream將工作簿內容串流傳輸到位元組數組中。這種方法有效率且可擴展,因為它避免了磁碟 I/O,因此非常適合動態產生報表的微服務。最後,我們建構 ResponseEntity 。我們將 HTTP 狀態設為 200 OK,並配置兩個必要的標頭:Content-Disposition 設定為附件,檔案名為 employee_data.xls ,這將觸發瀏覽器的下載對話框。我們也將 Content-Type 指定為 application/vnd.ms-excel ,讓客戶知道傳入資料流的確切格式。如果流程中的任何步驟失敗(例如, IOException ),我們會捕獲它,記錄錯誤,並傳回 500 內部伺服器錯誤回應。
3.2. 將位元組流轉換回HSSFWorkbook
有時,Excel 檔案會以位元組數組的形式上傳(例如,以 multipart 格式)。以下是我們處理這種情況的方法:
@PostMapping("/upload-excel")
public ResponseEntity<String> uploadExcel(@RequestParam("file") MultipartFile file) {
if (file.isEmpty()) {
return ResponseEntity.badRequest()
.body("File is empty. Please upload a file.");
}
try {
try (HSSFWorkbook workbook = new HSSFWorkbook(file.getInputStream())) {
Sheet sheet = workbook.getSheetAt(0);
return ResponseEntity.ok("Sheet '" + sheet.getSheetName() + "' uploaded successfully!");
}
} catch (IOException e) {
System.err.println("Error processing uploaded Excel file: " + e.getMessage());
return ResponseEntity.internalServerError()
.body("Failed to process the Excel file.");
} catch (Exception e) {
System.err.println("An unexpected error occurred during file upload: " + e.getMessage());
return ResponseEntity.internalServerError()
.body("An unexpected error occurred.");
}
}
此控制器方法映射到 /upload-excel端點透過 POST 請求接收和處理以 Excel 檔案形式提交的檔案。 MultipartFile 。我們首先進行必要的驗證,檢查上傳的文件是否為空;如果為空,則傳回錯誤。 立即返回400 Bad Request狀態,阻止進一步處理。 文件驗證通過後,此方法可協助我們接收上傳的 Excel 文件,將其位元組流轉換為可讀的 Apache POI HSSFWorkbook對象,並確認解析成功。我們使用 file.getInputStream()將原始檔案資料直接輸入到 HSSFWorkbook建構函數。如果轉換成功,我們將取得第一個工作表的名稱( getSheetAt(0) ) 並且回傳一個 200 OK狀態碼並附帶確認訊息,告知用戶端檔案已正確解析和識別。此方法採用結構化異常處理來提供資訊豐富的回饋。我們專門捕獲了以下異常: 如果上傳的資料流不是有效的 Excel 檔案格式,Apache POI 可能會拋出IOException異常,並傳回一則通用的「無法處理 Excel 檔案」訊息。最後的 catch 程式碼區塊會處理任何意外的或系統層級的異常,確保我們傳回可靠的結果。 500 Internal Server Error而不是導致進程崩潰。
4. 結論
在本教程中,我們探討如何 HSSFWorkbook可以有效地用於 Spring Boot 應用程式中,用於在記憶體中建立、轉換和提供 Excel 檔案。我們從空白工作簿開始,學習如何將其序列化為字節,再反序列化,並透過 REST API 將其公開。這種以位元組為基礎的方式處理 Excel 文件,無需處理實體文件,即可簡化與雲端系統、API 和資料庫的整合。
對於此類任務,Apache POI 仍然是一個可靠的選擇,而 Spring Boot 的簡潔性使得 Excel 檔案產生可以無縫地融入企業應用程式中。
與往常一樣,本文的程式碼是公開的。 在 GitHub 上。