如何在Java Spring Boot MVC中读取并解析.accdb文件的所有表
解决方案:读取Access数据库所有表数据
后端代码修改思路
核心是通过DatabaseMetaData遍历所有用户表(排除系统表),逐个查询每张表的结构和数据,最后将所有表的数据封装成统一结构返回给前端。
修改后的后端代码:
@PostMapping("/upload") @ResponseBody public Map<String, Object> upload(@RequestParam("file") MultipartFile file) { Map<String, Object> result = new HashMap<>(); // 用Map存储所有表的数据,key是表名,value是包含列和行的对象 Map<String, Map<String, Object>> allTablesData = new HashMap<>(); try { // 将上传文件转为临时文件,程序结束自动删除 File tempFile = File.createTempFile("access_temp", ".accdb"); file.transferTo(tempFile); tempFile.deleteOnExit(); String url = "jdbc:ucanaccess://" + tempFile.getAbsolutePath(); // 自动关闭连接资源 try (Connection conn = DriverManager.getConnection(url)) { DatabaseMetaData metaData = conn.getMetaData(); // 获取所有用户表(排除系统表) try (ResultSet tables = metaData.getTables(null, null, null, new String[]{"TABLE"})) { while (tables.next()) { String tableName = tables.getString("TABLE_NAME"); // 跳过Access系统表(以MSys开头) if (tableName.startsWith("MSys")) { continue; } // 查询当前表数据,自动关闭Statement和ResultSet try (Statement stmt = conn.createStatement(); ResultSet rs = stmt.executeQuery("SELECT * FROM " + tableName)) { ResultSetMetaData rsmd = rs.getMetaData(); int columnCount = rsmd.getColumnCount(); // 收集表头 List<String> columns = new ArrayList<>(); for (int i = 1; i <= columnCount; i++) { columns.add(rsmd.getColumnName(i)); } // 收集行数据 List<Map<String, Object>> rows = new ArrayList<>(); while (rs.next()) { Map<String, Object> row = new HashMap<>(); for (int i = 1; i <= columnCount; i++) { String columnName = rsmd.getColumnName(i); row.put(columnName, rs.getObject(i)); } rows.add(row); } // 封装当前表的列和行数据 Map<String, Object> tableData = new HashMap<>(); tableData.put("columns", columns); tableData.put("rows", rows); allTablesData.put(tableName, tableData); } } } } catch (SQLException e) { e.printStackTrace(); result.put("success", false); result.put("message", "读取数据库失败:" + e.getMessage()); return result; } result.put("success", true); result.put("content", allTablesData); } catch (IOException e) { e.printStackTrace(); result.put("success", false); result.put("message", "保存临时文件失败:" + e.getMessage()); } return result; }
关键修改点说明
- 临时文件处理:补充上传文件转临时文件的逻辑,确保数据库连接正常
- 过滤系统表:跳过Access自带的
MSys开头系统表,只处理用户创建的表 - 资源自动回收:使用
try-with-resources语法,自动关闭数据库连接、语句、结果集,避免资源泄漏 - 统一返回结构:用表名作为key存储每张表的表头和数据,方便前端快速定位
前端代码调整
后端返回的content是表名与对应数据的映射,前端需添加表选择功能,支持切换显示不同表的数据:
修改后的Ajax代码:
$.ajax({ url: '/data_visualization/upload', type: 'POST', processData: false, contentType: false, data: formData, success: function (res) { console.log(res); if (res.success) { toastr.success("所有表数据读取成功!", "Success"); const allTables = res.content; // 动态生成表选择下拉框(需提前在页面添加id为tableSelector的容器) const selector = $('#tableSelector'); selector.empty(); $.each(allTables, function(tableName) { selector.append(`<option value="${tableName}">${tableName}</option>`); }); // 默认显示第一张表的数据 const firstTableName = Object.keys(allTables)[0]; renderTable(allTables[firstTableName]); // 监听下拉框切换,重新渲染表格 selector.on('change', function() { const selectedTable = allTables[$(this).val()]; renderTable(selectedTable); }); } else { toastr.error(res.message || "读取失败!"); } }, error: function (err) { console.log(err); toastr.error("请求失败!"); } }); // 封装表格渲染函数 function renderTable(tableData) { // 销毁已有DataTable实例避免冲突 if ($.fn.DataTable.isDataTable('#kt_table')) { $('#kt_table').DataTable().destroy(); } // 重新渲染表格 $('#kt_table').DataTable({ data: tableData.rows, columns: tableData.columns.map(col => ({ title: col, data: col })), // 保留你原有的其他配置 ... }); }
前端修改说明
- 添加表选择器:动态生成下拉列表展示所有用户表
- 切换表功能:监听下拉框变化,销毁旧表格实例后重新渲染选中表的数据
- 状态提示:根据后端返回的
success状态展示对应提示信息
内容的提问来源于stack exchange,提问作者Top Dev
相关产品推荐
相关产品推荐

