技術棧
- 後端:Servlet + JSP + MySQL
- 文件上傳:`commons-fileupload-1.3.1.jar` + `commons-io`
- Excel 解析:`jxl.jar` (僅支持 `.xls`,`.xlsx` 請用 Apache POI)
核心步驟
1. 前端 JSP 上傳表單
<form action="UploadServlet" method="post" enctype="multipart/form-data">
<input type="file" name="excelFile" accept=".xls,.xlsx" />
<input type="submit" value="導入" />
</form>
2. Servlet 處理上傳並解析
@WebServlet("/UploadServlet")
@MultipartConfig // Servlet 3.0+ 可替代 commons-fileupload
public class UploadServlet extends HttpServlet {
protected void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
// 1. 獲取上傳文件 Part (Servlet 3.0 API)
Part filePart = request.getPart("excelFile");
if (filePart == null || filePart.getSize() == 0) {
response.getWriter().write("未選擇文件");
return;
}
// 2. 獲取輸入流
try (InputStream inputStream = filePart.getInputStream()) {
// 3. JXL 解析 .xls
Workbook workbook = Workbook.getWorkbook(inputStream);
Sheet sheet = workbook.getSheet(0); // 第一個工作表
// 4. 遍歷行 (跳過標題行)
for (int i = 1; i < sheet.getRows(); i++) {
Cell[] row = sheet.getRow(i);
if (row.length < 3) continue; // 列數不足跳過
String col1 = row[0].getContents().trim();
String col2 = row[1].getContents().trim();
String col3 = row[2].getContents().trim();
// 5. 插入數據庫 (使用連接池 PreparedStatement)
saveToDatabase(col1, col2, col3);
}
workbook.close();
response.getWriter().write("導入成功 " + (sheet.getRows()-1) + " 條記錄");
} catch (Exception e) {
e.printStackTrace();
response.getWriter().write("導入失敗: " + e.getMessage());
}
}
private void saveToDatabase(String c1, String c2, String c3) {
// 使用 DataSource / 連接池 (Druid/HikariCP)
String sql = "INSERT INTO my_table (col1, col2, col3) VALUES (?, ?, ?)";
try (Connection conn = dataSource.getConnection();
PreparedStatement ps = conn.prepareStatement(sql)) {
ps.setString(1, c1);
ps.setString(2, c2);
ps.setString(3, c3);
ps.executeUpdate();
} catch (SQLException e) {
throw new RuntimeException(e);
}
}
}
3. 依賴配置 (Maven)
<dependencies>
<!-- Servlet 3.0+ 內置上傳支持,無需 commons-fileupload -->
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>javax.servlet-api</groupId>
<version>3.1.0</version>
<scope>provided</scope>
</dependency>
<!-- JXL 僅支持 .xls -->
<dependency>
<groupId>net.sourceforge.jexcelapi</groupId>
<artifactId>jxl</artifactId>
<version>2.6.12</version>
</dependency>
<!-- MySQL 驅動 -->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>8.0.33</version>
</dependency>
<!-- 連接池 Druid -->
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>druid</artifactId>
<version>1.2.18</version>
</dependency>
</dependencies>
關鍵注意事項
| 問題 | 解決方案 |
| .xlsx 文件 JXL 報錯 | JXL 不支持 .xlsx,**必須遷移至 Apache POI** (`workbook = new XSSFWorkbook(inputStream)`) |
| 大文件內存溢出 (OOM) | POI 使用 `SXSSFWorkbook` (流式寫入/讀取) 或分批提交事務 |
| 日期/數字格式解析錯誤 | POI: `cell.getDateCellValue()`, `cell.getNumericCellValue()` + 格式化 |
| 中文亂碼 | 確保 Servlet 容器 URI 編碼 UTF-8 (Tomcat `server.xml` `URIEncoding="UTF-8"`) |
| 事務一致性 | 批量插入使用 `batch` + 事務控制,失敗回滾 |
推薦資源