系統遷移、數據初始化、測試數據準備等場景常需將 Excel 表格數據轉為 SQL 腳本批量導入資料庫。本文提供基於 JXL 庫的完整解決方案,支援反射自動映射實體屬性,可擴展支援多種數據類型。
<dependency>
<groupId>net.sourceforge.jexcelapi</groupId>
<artifactId>jxl</artifactId>
<version>2.6.12</version>
</dependency>
public class ExcelToSqlConverter {
public static void main(String[] args) throws Exception {
// 1. 讀取 Excel 數據映射為實體列表
List<Student> list = readExcel("C:/data/students.xls");
// 2. 生成 SQL 文件
try (BufferedWriter writer = new BufferedWriter(
new FileWriter("C:/output/insert_students.sql"))) {
for (Student s : list) {
String sql = "INSERT INTO cfg_avatar VALUES (" + entityToSql(s) + ");";
writer.write(sql);
writer.newLine();
}
}
}
/** 讀取 Excel 並通過反射填充實體 */
public static List<Student> readExcel(String filePath) {
List<Student> list = new ArrayList<>();
try (Workbook wb = Workbook.getWorkbook(new File(filePath))) {
Sheet sheet = wb.getSheet(0);
int rows = sheet.getRows(), cols = sheet.getColumns();
// 假設數據從第 3 行開始(索引 2),表頭佔前 2 行
for (int i = 2; i < rows; i++) {
List<String> rowData = new ArrayList<>();
for (int j = 0; j < cols; j++) {
rowData.add(sheet.getCell(j, i).getContents());
}
list.add(reflectCreate(new Student(), rowData));
}
} catch (Exception e) { throw new RuntimeException("Excel 讀取失敗", e); }
return list;
}
/** 反射實例化實體並按字段順序賦值 */
public static <T> T reflectCreate(T obj, List<String> values) {
Field[] fields = obj.getClass().getDeclaredFields();
for (int i = 0; i < fields.length && i < values.size(); i++) {
Field f = fields[i];
f.setAccessible(true);
String val = values.get(i);
try {
if (f.getType() == String.class) f.set(obj, val);
else if (f.getType() == int.class || f.getType() == Integer.class)
f.set(obj, Integer.parseInt(val));
else if (f.getType() == long.class || f.getType() == Long.class)
f.set(obj, Long.parseLong(val));
// 可擴展 Double, Date, BigDecimal 等
} catch (Exception e) { throw new RuntimeException("字段 " + f.getName() + " 賦值失敗", e); }
}
return obj;
}
/** 實體轉 SQL VALUES 片段 */
public static String entityToSql(Object obj) throws IllegalAccessException {
StringBuilder sb = new StringBuilder();
Field[] fields = obj.getClass().getDeclaredFields();
for (int i = 0; i < fields.length; i++) {
Field f = fields[i];
f.setAccessible(true);
Object val = f.get(obj);
if (f.getType() == String.class) sb.append('\'');
sb.append(val != null ? val : "NULL");
if (f.getType() == String.class) sb.append('\'');
if (i < fields.length - 1) sb.append(',');
}
return sb.toString();
}
}
public class Student {
private int id;
private String name;
private int age;
private String email;
// getter/setter 省略
}
Date、BigDecimal、Boolean 等類型的解析與 SQL 格式化' → '')或使用 PreparedStatement 參數化@ExcelColumn(index=0, name="姓名") 解耦字段順序