專案架構概覽
java_poi_excel/
├── src/
│ ├── XlsMain.java # 主程式:讀取並匯出
│ ├── XlsDto.java # 資料傳輸物件 (DTO)
│ └── XlsDto2Excel.java # 匯出邏輯類別
├── pldrxkxxmb.xls # 範本檔案
└── POI2Excel/ # 輸出目錄


核心類別實作
XlsDto - 資料模型
public class XlsDto {
private Integer xkh; // 選課號
private String xh; // 學號
private String xm; // 姓名
private String yxsmc; // 學院
private Integer kch; // 課程號
private String kcm; // 課程名
private float cj; // 成績
// 建構子、getter/setter 略...
}
XlsMain - 讀取邏輯 (HSSF 適用 .xls)
public class XlsMain {
public static void main(String[] args) throws IOException {
XlsMain main = new XlsMain();
List list = main.readXls();
// 匯出新檔
try { XlsDto2Excel.xlsDto2Excel(list); }
catch (Exception e) { e.printStackTrace(); }
// 控制台驗證
for (XlsDto dto : list) {
System.out.printf("%s %s %s %s %.1f%n",
dto.getXh(), dto.getXm(), dto.getYxsmc(), dto.getKcm(), dto.getCj());
}
}
private List readXls() throws IOException {
List list = new ArrayList<>();
try (InputStream is = new FileInputStream("pldrxkxxmb.xls")) {
HSSFWorkbook wb = new HSSFWorkbook(is);
for (int sheetIdx = 0; sheetIdx < wb.getNumberOfSheets(); sheetIdx++) {
HSSFSheet sheet = wb.getSheetAt(sheetIdx);
if (sheet == null) continue;
// 從第 1 行開始(跳過標題列)
for (int rowIdx = 1; rowIdx <= sheet.getLastRowNum(); rowIdx++) {
HSSFRow row = sheet.getRow(rowIdx);
if (row == null) continue;
XlsDto dto = new XlsDto();
dto.setXh(getCellValue(row.getCell(0)));
dto.setXm(getCellValue(row.getCell(1)));
dto.setYxsmc(getCellValue(row.getCell(2)));
dto.setKcm(getCellValue(row.getCell(3)));
dto.setCj(Float.parseFloat(getCellValue(row.getCell(4))));
list.add(dto);
}
}
}
return list;
}
/** 安全取得儲存格值,支援多種資料型別 */
private String getCellValue(HSSFCell cell) {
if (cell == null) return "";
switch (cell.getCellType()) {
case BOOLEAN: return String.valueOf(cell.getBooleanCellValue());
case NUMERIC: return String.valueOf(cell.getNumericCellValue());
default: return String.valueOf(cell.getStringCellValue());
}
}
}
XlsDto2Excel - 匯出邏輯
public class XlsDto2Excel {
public static void xlsDto2Excel(List list) throws Exception {
HSSFWorkbook wb = new HSSFWorkbook();
HSSFSheet sheet = wb.createSheet("pldrxkxxmb");
// 建立標題列
String[] headers = {"學號", "姓名", "學院", "課程名", "成績"};
HSSFRow headerRow = sheet.createRow(0);
for (int i = 0; i < headers.length; i++) {
headerRow.createCell(i).setCellValue(new HSSFRichTextString(headers[i]));
}
// 填充資料
for (int i = 0; i < list.size(); i++) {
XlsDto dto = list.get(i);
HSSFRow row = sheet.createRow(i + 1);
row.createCell(0).setCellValue(dto.getXh());
row.createCell(1).setCellValue(dto.getXm());
row.createCell(2).setCellValue(dto.getYxsmc());
row.createCell(3).setCellValue(dto.getKcm());
row.createCell(4).setCellValue(dto.getCj());
}
// 輸出檔案
File outDir = new File("POI2Excel");
if (!outDir.exists()) outDir.mkdirs();
try (OutputStream out = new FileOutputStream("POI2Excel/pldrxkxxmb.xls")) {
wb.write(out);
System.out.println("數據匯出成功");
}
}
}
執行結果驗證
數據庫導出成功
1.0 hongten 信息技術學院 計算機網絡應用基礎 80.0
2.0 王五 信息技術學院 計算機網絡應用基礎 81.0
3.0 李勝基 信息技術學院 計算機網絡應用基礎 82.0
4.0 五班古 信息技術學院 計算機網絡應用基礎 83.0
5.0 蔡詩芸 信息技術學院 計算機網絡應用基礎 84.0
進階擴充建議
| 需求 | 解決方案 |
| 支援 .xlsx (Excel 2007+) | 改用 XSSFWorkbook / SXSSFWorkbook (大數據流式寫入) |
| 樣式格式化 | CellStyle + Font + DataFormat 設定字體、顏色、邊框、數字格式 |
| 公式計算 | FormulaEvaluator 評估公式結果 |
| 大檔案記憶體優化 | SXSSF (Streaming) 僅保留滑動視窗在記憶體 |
| 日期處理 | DateUtil.isCellDateFormatted() 判斷 + getDateCellValue() |
常見坑點提醒
- 數字儲存格可能是日期型別,需用
DateUtil.isCellDateFormatted(cell) 判別
- 合併儲存格讀取需遍歷
sheet.getMergedRegions()
- 大量資料寫入務必使用
SXSSFWorkbook 避免 OOM
- 關閉 Workbook 前確認所有流已正確關閉 (try-with-resources)