首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> Java 程式設計 >> Java 相關知識

Java 讀取 Excel (xls) 並生成可直接執行的 SQL 插入腳本

     編輯:Java 相關知識

業務背景

系統遷移、數據初始化、測試數據準備等場景常需將 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 省略
}

關鍵注意事項

  1. 字段順序一致性:實體類字段聲明順序必須與 Excel 列順序完全一致
  2. 數據類型擴展:需處理 Date、BigDecimal、Boolean 等類型的解析與 SQL 格式化
  3. 特殊字符轉義:字符串值中包含單引號需轉義(' → '')或使用 PreparedStatement 參數化
  4. 大文件處理:超大 Excel 建議使用 Apache POI SXSSF 流式讀取,避免 OOM
  5. .xlsx 支援:JXL 僅支援 .xls,.xlsx 需改用 Apache POI

進階改進方向

  • 引入註解 @ExcelColumn(index=0, name="姓名") 解耦字段順序
  • 支援多 Sheet、合併儲存格、數據驗證規則
  • 生成參數化 SQL + 批量執行,防止 SQL 注入並提升導入效能
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved