Excel批量生成SQL脚本工具:POI+JDBC实现数据迁移提效
简介这是一份面向Java开发者与数据库运维人员的数据处理工具源码包用于将Excel表格数据自动解析并生成可执行的SQL脚本再通过JDBC连接写入目标数据库适用于数据迁移、批量导入与数据分析等场景。压缩包共56个文件约24.48MB包含21个jar依赖、20个class与11个java源码另有classpath配置、project工程文件、fatjar打包产物及一份xls测试数据模板结构完整便于直接运行与二次开发。资源核心围绕Apache POI解析Excel、构造INSERT等SQL语句、配置数据库驱动并管理连接执行源码可帮助读者理解从表格字段映射到语句生成、再到JDBC执行与异常处理的完整链路。目前已有979人学习下载适合希望掌握Excel到数据库自动化转换思路的开发者参考借鉴。1. 从手工拼 SQL 到批量生成一个被低估的提效工具做数据迁移或者后台初始化的时候最烦的不是写 SQL而是把 Excel 里几百上千行配置数据一行行拼成 INSERT 语句。字段一多引号、逗号、NULL 值、日期格式随便哪个地方手滑就是一条报错。更别提产品经理隔三差五丢过来一个「补充数据.xlsx」你还得重新对一遍字段顺序。我最近拆的一个小工具就是干这件事的读取 Excel按模板生成可直接执行的 SQL 脚本同时支持通过 JDBC 连接数据库做校验或直接写入。它解决的核心问题很具体——把「人肉拼 SQL」变成「配置一次、批量产出」。适合谁做数据初始化、配置表导入、测试数据构造的后端和运维同学尤其是那种表结构固定、数据来源是 Excel 的场景。下面按「它怎么工作 → 怎么跑起来 → 坑在哪 → 怎么用得更顺」的顺序拆开讲。2. 解析 Excel 生成 SQL 的底层逻辑POI、JDBC 与模板三件套2.1 为什么是 POI JDBC 这套组合Excel 解析这块Java 生态里最稳的还是 Apache POI。它同时支持.xlsHSSF和.xlsxXSSF能拿到单元格的类型、格式、公式结果这对生成 SQL 很关键——因为你要判断一个格子到底是数字、字符串还是日期不能一律当字符串处理。JDBC 在这里有两个用途一是生成脚本前先连库校验表结构字段名、类型对不对二是小批量数据可以直接走PreparedStatement写入省去生成脚本再手动执行的步骤。常见做法是大批量走「生成 .sql 文件 命令行执行」小批量或需要即时反馈的走 JDBC 直连。模板引擎的选择上简单场景用字符串拼接加占位符就够了复杂场景多表、条件字段可以上 FreeMarker 或 Velocity。我一般建议先用最朴素的String.format或StringBuilder因为 SQL 生成的可读性比「优雅」重要——出问题时你得能一眼看出哪条语句拼错了。2.2 一次完整的生成流程拆解整个流程可以拆成五步每一步都有对应的代码落点读取 Excel 文件定位 sheet 和表头行逐行读取单元格按列映射到字段对每个值做类型转换和转义重点字符串单引号、日期格式、NULL套用 INSERT 模板生成 SQL 语句输出到文件或通过 JDBC 执行先看读取和映射的核心代码// 读取 Excel 并映射为字段-值对 public ListMapString, String readExcel(String filePath, int headerRow) throws IOException { ListMapString, String rows new ArrayList(); try (InputStream is new FileInputStream(filePath); Workbook workbook WorkbookFactory.create(is)) { // 自动识别 xls/xlsx Sheet sheet workbook.getSheetAt(0); Row header sheet.getRow(headerRow); ListString columns new ArrayList(); for (Cell cell : header) { columns.add(cell.getStringCellValue().trim()); // 表头即字段名 } // 从表头下一行开始读数据 for (int i headerRow 1; i sheet.getLastRowNum(); i) { Row row sheet.getRow(i); if (row null) continue; MapString, String record new LinkedHashMap(); for (int j 0; j columns.size(); j) { Cell cell row.getCell(j); record.put(columns.get(j), getCellValue(cell)); // 统一转字符串 } rows.add(record); } } return rows; }这段代码的关键点WorkbookFactory.create能自动判断文件格式省去手动区分 HSSF 和 XSSF用LinkedHashMap保证字段顺序和 Excel 列顺序一致生成 SQL 时字段和值的顺序不会错位表头直接当字段名意味着 Excel 第一行必须写数据库真实字段名这是约定也是约束。getCellValue是容易翻车的地方单独拎出来// 单元格取值处理数字、日期、布尔、公式等类型 private String getCellValue(Cell cell) { if (cell null) return null; switch (cell.getCellType()) { case STRING: return cell.getStringCellValue().trim(); case NUMERIC: if (DateUtil.isCellDateFormatted(cell)) { // 日期统一转成 yyyy-MM-dd HH:mm:ss return new SimpleDateFormat(yyyy-MM-dd HH:mm:ss) .format(cell.getDateCellValue()); } // 避免 1.0 这种科学计数法尾巴 double d cell.getNumericCellValue(); if (d Math.floor(d)) return String.valueOf((long) d); return String.valueOf(d); case BOOLEAN: return String.valueOf(cell.getBooleanCellValue()); case FORMULA: return cell.getCellFormula(); // 或按需取计算结果 default: return null; } }参数说明DateUtil.isCellDateFormatted判断是否是日期格式这一步不能省否则日期会变成一串数字序列号数字处理里判断d Math.floor(d)是为了把100.0还原成100不然生成的 SQL 里 ID 字段会变成浮点数插入整型列直接报错。2.3 生成 SQL 时的转义与模板拿到字段-值对之后生成 INSERT 语句// 根据字段映射生成 INSERT 语句 public String buildInsert(String tableName, MapString, String record) { StringBuilder cols new StringBuilder(); StringBuilder vals new StringBuilder(); for (Map.EntryString, String e : record.entrySet()) { cols.append(e.getKey()).append(,); vals.append(toSqlValue(e.getValue())).append(,); } cols.setLength(cols.length() - 1); // 去掉末尾逗号 vals.setLength(vals.length() - 1); return String.format(INSERT INTO %s (%s) VALUES (%s);, tableName, cols, vals); } // 值转 SQL 字面量字符串加引号并转义null 直接写 NULL private String toSqlValue(String value) { if (value null || value.isEmpty()) return NULL; // 单引号转义防止 SQL 注入和语法错误 return value.replace(, ) ; }逻辑说明toSqlValue里把单引号替换成两个单引号这是 SQL 标准转义方式能避免「OBrien」这类数据把语句截断。空字符串按 NULL 处理是个策略选择——如果你的表不允许 NULL就得改成写这个要按实际表结构定。提示如果字段里有纯数字但数据库列是 varchar上面的写法会带上引号没问题但如果列是 int 而 Excel 里混进了空值NULL 是合法的空字符串就会报错。类型边界一定要提前对齐。3. 把工具跑起来环境、依赖与 JDBC 直连配置3.1 依赖引入与最小可运行工程Maven 项目里引入 POI 和数据库驱动即可。POI 建议用 5.x 版本对.xlsx支持更完整dependencies !-- Excel 解析 -- dependency groupIdorg.apache.poi/groupId artifactIdpoi-ooxml/artifactId version5.2.3/version /dependency !-- JDBC 驱动按实际数据库替换 -- dependency groupIdcom.mysql/groupId artifactIdmysql-connector-j/artifactId version8.0.33/version /dependency /dependencies参数说明poi-ooxml已经传递依赖了poi核心包不用重复引驱动版本要和数据库服务端匹配MySQL 8 用com.mysql.cj.jdbc.Driver5.x 用com.mysql.jdbc.Driver写错会报ClassNotFoundException。3.2 JDBC 连接与批量写入如果选择直连写入而不是生成脚本核心是用PreparedStatement加批处理// JDBC 批量写入避免逐条提交 public void batchInsert(ListMapString, String rows) throws SQLException { String sql INSERT INTO config_table (id, name, create_time) VALUES (?, ?, ?); try (Connection conn DriverManager.getConnection(URL, USER, PWD); PreparedStatement ps conn.prepareStatement(sql)) { conn.setAutoCommit(false); // 关闭自动提交 for (MapString, String row : rows) { ps.setLong(1, Long.parseLong(row.get(id))); ps.setString(2, row.get(name)); ps.setTimestamp(3, Timestamp.valueOf(row.get(create_time))); ps.addBatch(); // 加入批次 } ps.executeBatch(); // 一次性提交 conn.commit(); } }逻辑说明setAutoCommit(false)配合executeBatch能把上千条插入合并成一次网络往返性能差距在数据量大时非常明显。addBatch只是攒着executeBatch才真正发送。注意Timestamp.valueOf要求字符串格式严格是yyyy-MM-dd HH:mm:ss和前面 Excel 日期转换的格式必须一致否则抛IllegalArgumentException。3.3 生成脚本 vs JDBC 直连怎么选维度生成 .sql 文件JDBC 直连写入适用数据量大批量、可分批执行中小批量、即时反馈可审查性高脚本可人工检查低直接进库回滚难度低脚本可留存高需事务控制环境依赖只需文件需网络和驱动典型场景生产初始化、交付脚本测试数据、临时导入我一般建议生产环境走生成脚本先人工过一遍再执行测试环境走 JDBC 直连图快。两者不是互斥的同一个工具里可以都实现用参数切换。4. 避坑与排查那些让脚本跑不通的细节4.1 日期变成 45000 这种数字现象Excel 里明明是2024-01-01生成的 SQL 里却是45292。原因POI 把日期存为数字序列号如果没调DateUtil.isCellDateFormatted判断就会按普通数字取值。解决在getCellValue里先判断日期格式用cell.getDateCellValue()取值再格式化。另外注意 Excel 单元格格式本身要是「日期」类型如果只是手动输入了看起来像日期的文本POI 会当字符串处理这种反而不会出问题。4.2 数字精度丢失或多了小数点现象ID 是10000000000000001生成后变成1.0E16或10000000000000000。原因Excel 对超过 15 位的数字本身就会丢精度POI 读出来是 double再转字符串就变形了。解决长数字如订单号、身份证号在 Excel 里必须存成文本格式或者读取时用DataFormatter按显示值取。这是 Excel 的锅不是工具的锅但排查时容易误判。4.3 表头字段名和数据库对不上现象生成的 SQL 执行报Unknown column xxx。原因Excel 表头写了中文名或别名和数据库真实字段名不一致。解决约定表头必须写真实字段名或者在工具里加一层字段映射配置Excel 列名 → 数据库字段名。我倾向于加映射表因为业务同学填 Excel 时更愿意写中文。4.4 空行和合并单元格导致错位现象生成的 SQL 里某些行字段值整体偏移或者多出空 INSERT。原因Excel 里有空行、合并单元格getLastRowNum会把空行也算进去getCell遇到合并单元格只有左上角有值。解决读取时跳过row null和所有单元格都为空的行合并单元格场景建议在 Excel 侧拆开工具侧处理合并单元格成本高且容易出错。4.5 批量执行时事务太大撑爆内存现象JDBC 批量写入几万条时 OOM 或超时。原因一次性addBatch太多或者没分批提交。解决每 500 到 1000 条执行一次executeBatch并commit然后清空批次。这个阈值按数据库和网络情况调没有万能值。5. 进阶技巧用 DataFormatter 兜底与生成前的结构校验5.1 用 DataFormatter 拿到「所见即所得」的值前面getCellValue是按类型手动转换遇到复杂格式百分比、货币、自定义格式还是会翻车。更稳的做法是用 POI 的DataFormatter它按单元格显示格式输出字符串// 用 DataFormatter 按显示格式取值兜底复杂格式 DataFormatter formatter new DataFormatter(); FormulaEvaluator evaluator workbook.getCreationHelper().createFormulaEvaluator(); for (int j 0; j columns.size(); j) { Cell cell row.getCell(j); // 第二个参数传 evaluator公式单元格也能取到计算结果 String value formatter.formatCellValue(cell, evaluator); record.put(columns.get(j), value.trim()); }逻辑说明formatCellValue会尊重单元格的数字格式日期就是日期字符串百分比就是50%不会出现序列号。传evaluator是为了让公式单元格返回计算结果而不是公式本身。代价是它输出的是「显示值」如果 Excel 列宽不够显示成####取出来也可能是异常值所以列宽要正常。我一般会把这个方法和手动转换结合先用DataFormatter取再对日期和长数字做二次校正。纯手动转换适合格式规整的数据DataFormatter适合格式五花八门的业务表格。5.2 生成前先校验表结构与其等 SQL 执行报错不如生成前先连库查一次表结构把 Excel 表头和数据库字段做比对// 查询目标表字段和 Excel 表头比对 public SetString getTableColumns(Connection conn, String tableName) throws SQLException { SetString columns new HashSet(); DatabaseMetaData meta conn.getMetaData(); try (ResultSet rs meta.getColumns(null, null, tableName, null)) { while (rs.next()) { columns.add(rs.getString(COLUMN_NAME).toLowerCase()); } } return columns; }拿到字段集合后遍历 Excel 表头凡是数据库里没有的字段直接报出来让人去改 Excel而不是生成一堆注定失败的 SQL。这一步能省掉大量「执行到一半报错、回滚、改、重来」的循环。5.3 一个我踩过的坑有次给一个配置表导数据Excel 里有个字段叫status值是1和0我按字符串处理生成了1和0结果数据库列是 tinyintMySQL 隐式转换居然没报错数据也进去了。但后来另一个字段amount是 decimalExcel 里填了100.50我按字符串生成100.50插入时精度被截成了100查了半天才发现是引号导致类型没对上。从那以后我每次生成脚本前都会强制走一遍「字段类型比对」把数据库列类型和 Excel 值的形态对一遍数字列不加引号字符串列加引号日期列用标准格式。这个习惯帮我省了至少三次线上排查。希望帮到你。本文还有配套的精品资源点击获取

相关新闻

汽车制造数据孤岛怎么破?多智能体协同架构实战解析

汽车制造数据孤岛怎么破?多智能体协同架构实战解析

做汽车制造数字化转型这几年,最让我头疼的不是算法精度不够,也不是算力不够,而是数据孤岛。设计部门用一套PLM,工艺部门用一套CAPP,车间MES是另一套,质量系统QMS又自己一套,采购和物流走的ERP/S…

2026/10/18 12:40:33 阅读更多 →
LSTM-Kalman融合:构建可解释时序状态估计器

LSTM-Kalman融合:构建可解释时序状态估计器

简介:本资源是一个面向机器学习与信号处理初学者的温度预测实践项目,聚焦LSTM神经网络与卡尔曼滤波器的协同建模方法,解决时间序列中噪声干扰下的高精度状态估计问题,适用于气象预测、传感器数据校正及智能控制等场景。压缩包共15…

2026/10/18 12:40:33 阅读更多 →
PostgreSQL uuid-ossp扩展安装指南:从Linux到Docker的避坑实战

PostgreSQL uuid-ossp扩展安装指南:从Linux到Docker的避坑实战

简介:PostgreSQL 的 uuid-ossp 扩展是数据库生成标准 UUID 的常用组件,这份资源正适合需要在 PostgreSQL 中启用该扩展的 DBA 与后端开发者,解决唯一标识符生成、分布式数据同步、微服务拆分等场景下的插件部署问题。压缩包体积仅 11KB&#…

2026/10/18 12:40:33 阅读更多 →

最新新闻

Java在线教育平台源码解析:DWD-DWS-DIM分层架构与毕设实战指南

Java在线教育平台源码解析:DWD-DWS-DIM分层架构与毕设实战指南

简介:这是一套面向Java开发者与教育信息化建设者的在线教育平台6.2版本完整设计源码,聚焦教学管理、课程学习、在线考试与数据治理等核心场景,适用于高校IT课程实践、教育类毕业设计或中小型在线教育系统二次开发。资源共69个文件&#xff0c…

2026/10/18 13:25:59 阅读更多 →
ARTEMIS双模式架构:LLM移动端自动化测试的脚本与代理协同实践

ARTEMIS双模式架构:LLM移动端自动化测试的脚本与代理协同实践

1. 移动端自动化测试的现状与ARTEMIS的切入点移动端自动化测试这件事,做过的人都懂——写起来容易,跑起来难,跑稳了更难。尤其是这两年大模型能力下放到端侧之后,测试场景从传统的UI点击流,一下子扩展到了对话生成、意…

2026/10/18 13:25:59 阅读更多 →
Vue+Node.js+ElementUI构建在线考试系统:从设计到部署全流程实战

Vue+Node.js+ElementUI构建在线考试系统:从设计到部署全流程实战

去年帮某高校教研室做的高校在线考试系统,技术栈就是标题里的 Vue Node.js ElementUI,从数据库到前端页面再到部署上线,整个链路走完后我最大的感受是:在线考试系统的难点从来不是“能考试”,而是“考得准、交得稳、…

2026/10/18 13:25:59 阅读更多 →
Photoshop Connection SDK 实战:C++ 外部程序控制 PS 自动化

Photoshop Connection SDK 实战:C++ 外部程序控制 PS 自动化

1. 从插件开发者的视角看Photoshop Connection SDK的定位第一次接触Photoshop插件开发的人,往往会被Adobe那一长串SDK名字搞晕:Photoshop SDK、UXP、CEP、Connection SDK……它们之间到底是什么关系?我该从哪个入手?这个问题我在不…

2026/10/18 13:25:59 阅读更多 →
从模糊缩写到可运行原型:拆解rea标题的工程实践方法论

从模糊缩写到可运行原型:拆解rea标题的工程实践方法论

1. 从“rea”这个标题说起:一个被低估的缩写背后藏着什么第一次看到“rea”这个标题的时候,我承认自己愣了几秒。没有正文,没有关键词,没有摘要描述,就孤零零三个字母。这种极简到近乎“空白”的输入,反而让…

2026/10/18 13:25:59 阅读更多 →
高并发XML解析性能优化:从DOM到StAX的实战改造

高并发XML解析性能优化:从DOM到StAX的实战改造

1. 高并发场景下XML解析的性能困局做过电商大促、金融交易或者物联网数据接入的朋友,大概率都踩过这样一个坑:平时跑得好好的服务,一到流量高峰,CPU直接飙满,接口响应时间从几十毫秒涨到几秒甚至超时。排查半天发现&am…

2026/10/18 13:24:58 阅读更多 →

日新闻

基于GMM的语音识别系统原理与MATLAB实现详解

基于GMM的语音识别系统原理与MATLAB实现详解

说到基于高斯混合模型(GMM)的语音识别系统,很多人第一反应就是一堆数学公式,觉得门槛很高。但如果你真的在MATLAB里把它落地跑通,会发现核心其实就是三件事:把声音变成特征向量,用GMM给每个类别…

2026/10/18 0:00:55 阅读更多 →
数字图像处理入门:反白、灰度化、调色板修改与导出txt实践

数字图像处理入门:反白、灰度化、调色板修改与导出txt实践

数字图像处理这四个字听起来挺唬人,但落到具体操作上,无非就是让计算机按你的想法“摆弄”像素。我在一个模拟项目X里用了一套特别经典的基础处理流程:对图像做反白、改调色板、彩色转灰度,最后把像素数据导出成txt文件。单看每一…

2026/10/18 0:00:55 阅读更多 →
机器人大脑技术盘点:具身智能的感知、决策与数据闭环

机器人大脑技术盘点:具身智能的感知、决策与数据闭环

如果你的信息流最近也天天刷到“机器人大脑”这个词,你会发现一个很有意思的现象:每个人说的“大脑”根本不是同一个东西。有人指的是大语言模型,有人指的是运动控制系统,还有人指的是能理解物理世界的端到端模型。在2026年这个时…

2026/10/18 0:00:55 阅读更多 →

周新闻

基于GMM的语音识别系统原理与MATLAB实现详解

基于GMM的语音识别系统原理与MATLAB实现详解

说到基于高斯混合模型(GMM)的语音识别系统,很多人第一反应就是一堆数学公式,觉得门槛很高。但如果你真的在MATLAB里把它落地跑通,会发现核心其实就是三件事:把声音变成特征向量,用GMM给每个类别…

2026/10/18 0:00:55 阅读更多 →
数字图像处理入门:反白、灰度化、调色板修改与导出txt实践

数字图像处理入门:反白、灰度化、调色板修改与导出txt实践

数字图像处理这四个字听起来挺唬人,但落到具体操作上,无非就是让计算机按你的想法“摆弄”像素。我在一个模拟项目X里用了一套特别经典的基础处理流程:对图像做反白、改调色板、彩色转灰度,最后把像素数据导出成txt文件。单看每一…

2026/10/18 0:00:55 阅读更多 →
机器人大脑技术盘点:具身智能的感知、决策与数据闭环

机器人大脑技术盘点:具身智能的感知、决策与数据闭环

如果你的信息流最近也天天刷到“机器人大脑”这个词,你会发现一个很有意思的现象:每个人说的“大脑”根本不是同一个东西。有人指的是大语言模型,有人指的是运动控制系统,还有人指的是能理解物理世界的端到端模型。在2026年这个时…

2026/10/18 0:00:55 阅读更多 →

月新闻

我发现了一个新思路:用 Remotion + Claude Code 像写代码一样自动化生成短视频

我发现了一个新思路:用 Remotion + Claude Code 像写代码一样自动化生成短视频

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/18 0:55:02 阅读更多 →
Windows下 Codex 中 Chrome 和 Computer Use 插件不可用问题排查及解决参考方式:TaoToken 统一 Key 配置与验证

Windows下 Codex 中 Chrome 和 Computer Use 插件不可用问题排查及解决参考方式:TaoToken 统一 Key 配置与验证

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/17 17:22:31 阅读更多 →
黑夜航拍船只数据集训练YOLOV5模型全流程解析

黑夜航拍船只数据集训练YOLOV5模型全流程解析

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/18 12:16:16 阅读更多 →