如何通过Spring Boot将Angular转换的动态Excel JSON数据存入MySQL
解决方案:Spring Boot 存储动态列 JSON 数据到 MySQL
核心思路
由于Excel表头是动态的,对应JSON字段不固定,常规固定实体类映射无法满足需求,推荐两种实现方案:JSON类型字段存储(实现简单,适配多数场景)、动态表结构存储(适配需对动态列做SQL查询的复杂场景)。
方案一:MySQL JSON 字段存储(推荐)
1. 数据库表设计
创建表时用JSON类型字段存储整条动态数据,同时添加元数据字段记录上传信息:
CREATE TABLE excel_data ( id BIGINT AUTO_INCREMENT PRIMARY KEY, file_name VARCHAR(255) NOT NULL, upload_time DATETIME DEFAULT CURRENT_TIMESTAMP, dynamic_data JSON NOT NULL );
2. Spring Boot 实体类编写
用Map<String, Object>接收动态字段,通过JPA注解映射JSON类型列:
import jakarta.persistence.*; import java.time.LocalDateTime; import java.util.Map; @Entity @Table(name = "excel_data") public class ExcelData { @Id @GeneratedValue(strategy = GenerationType.IDENTITY) private Long id; @Column(name = "file_name") private String fileName; @Column(name = "upload_time") private LocalDateTime uploadTime; @Column(columnDefinition = "JSON") private Map<String, Object> dynamicData; // 无参构造、全参构造 public ExcelData() {} public ExcelData(String fileName, LocalDateTime uploadTime, Map<String, Object> dynamicData) { this.fileName = fileName; this.uploadTime = uploadTime; this.dynamicData = dynamicData; } // getter、setter方法自行生成 }
3. Repository 层
基于JpaRepository实现基础CRUD:
import org.springframework.data.jpa.repository.JpaRepository; public interface ExcelDataRepository extends JpaRepository<ExcelData, Long> { }
4. Controller 层接收前端数据
批量接收Angular传来的JSON数组,完成存储:
import org.springframework.web.bind.annotation.*; import java.time.LocalDateTime; import java.util.List; import java.util.Map; @RestController @RequestMapping("/api/excel") public class ExcelDataController { private final ExcelDataRepository repository; public ExcelDataController(ExcelDataRepository repository) { this.repository = repository; } @PostMapping("/save") public List<ExcelData> saveExcelData(@RequestBody List<Map<String, Object>> dataList, @RequestParam String fileName) { return repository.saveAll( dataList.stream() .map(data -> new ExcelData(fileName, LocalDateTime.now(), data)) .toList() ); } }
方案二:动态表结构存储(复杂场景)
若需要对动态列执行SQL查询(如按Age筛选),可动态创建匹配表头的表:
1. 动态建表与插入逻辑
用JdbcTemplate执行动态生成的SQL:
import org.springframework.jdbc.core.JdbcTemplate; import java.util.Set; import java.util.stream.Collectors; @Service public class DynamicTableService { private final JdbcTemplate jdbcTemplate; public DynamicTableService(JdbcTemplate jdbcTemplate) { this.jdbcTemplate = jdbcTemplate; } public void createDynamicTable(String tableName, Set<String> columns) { String columnDefinitions = columns.stream() .map(col -> { // 根据字段名简单判断类型,可根据JSON值类型优化逻辑 if (col.matches("Age|Id|\\d+")) { return col + " INT"; } else if (col.equals("Date")) { return col + " DATE"; } else { return col + " VARCHAR(255)"; } }) .collect(Collectors.joining(", ")); String sql = String.format("CREATE TABLE IF NOT EXISTS %s (id BIGINT AUTO_INCREMENT PRIMARY KEY, %s)", tableName, columnDefinitions); jdbcTemplate.execute(sql); } // 批量插入数据方法:动态生成INSERT语句,用JdbcTemplate执行 }
注意:该方案需处理字段类型匹配、表名冲突、权限控制等问题,复杂度较高,仅在必要场景使用。
Angular 端调用示例
设置正确请求头,发送POST请求:
import { HttpClient } from '@angular/common/http'; export class ExcelUploadService { constructor(private http: HttpClient) {} saveExcelData(data: any[], fileName: string) { return this.http.post('/api/excel/save', data, { params: { fileName } }); } }
内容的提问来源于stack exchange,提问作者abhinav-sol
相关产品推荐
相关产品推荐

