成人免费xxxxx在线视频软件_久久精品久久久_亚洲国产精品久久久_天天色天天色_亚洲人成一区_欧美一级欧美三级在线观看

太強了!Spring Boot 3.3 一個接口就能搞定 Excel 導入導出所有表!

開發 前端
如果你正在開發一個后臺系統、BI平臺或需要支持可配置表單數據導入導出功能的系統,這種通用設計無疑能大大提升系統的靈活性和擴展性。

在日常的企業系統或后臺管理系統中,數據的 Excel 導入導出是非常常見的需求。傳統方式通常是:

  • 每張表都寫一個專門的導入導出方法;
  • 每張表都建立一個 Java Bean 類,硬編碼字段;
  • 新增或修改表結構時需要修改大量代碼。

這些方式帶來的問題有:代碼重復多、維護成本高、靈活性差

因此,本文基于 Spring Boot 3.3 + EasyExcel 實現一個 "支持任意表結構、無需綁定實體類、異步處理大文件導入" 的通用 Excel 導入導出功能。

技術選型與優勢

技術

用途

Spring Boot 3.3

構建 RESTful Web 項目

EasyExcel

快速讀取/寫入 Excel 文件

JdbcTemplate

動態操作任意表結構

ThreadPool

支持異步導入,釋放主線程

數據庫準備(支持任意表結構)

-- 用戶表
CREATETABLEuser(
  id BIGINTPRIMARYKEYAUTO_INCREMENT,
  name VARCHAR(100),
  phone VARCHAR(50),
  id_card VARCHAR(50),
  created_at DATETIMEDEFAULTCURRENT_TIMESTAMP
);

-- 商品表
CREATETABLE product (
  id BIGINTPRIMARYKEYAUTO_INCREMENT,
  name VARCHAR(100),
  price DECIMAL(10,2),
  stock INT,
  created_at DATETIMEDEFAULTCURRENT_TIMESTAMP
);

通用導入導出接口設計

@RestController
@RequestMapping("/excel")
@RequiredArgsConstructor
public class ExcelController {


    private final JdbcTemplate jdbcTemplate;
    private final ThreadPoolTaskExecutor taskExecutor;


    /**
     * Excel 導入任意表(異步)
     */
    @PostMapping("/import")
    public ResponseEntity<String> importExcel(@RequestParam("file") MultipartFile file,
                                              @RequestParam("tableName") String tableName) throws IOException {


        List<Map<Integer, String>> rowData = new ArrayList<>();


        EasyExcel.read(file.getInputStream(), new AnalysisEventListener<Map<Integer, String>>() {
            @Override
            public void invoke(Map<Integer, String> data, AnalysisContext context) {
                rowData.add(data);
            }


            @Override
            public void doAfterAllAnalysed(AnalysisContext context) {}
        }).sheet().doRead();


        // 獲取目標表字段名(排除主鍵)
        List<String> columns = jdbcTemplate.queryForList(
                "SHOW COLUMNS FROM " + tableName + " WHERE Field != 'id'", String.class);


        if (columns.size() != rowData.get(0).size()) {
            return ResponseEntity.badRequest().body("Excel列數與表字段不匹配");
        }


        // 異步處理
        taskExecutor.execute(() -> {
            for (Map<Integer, String> row : rowData) {
                String sql = "INSERT INTO " + tableName + " (" + String.join(",", columns) + ") VALUES (" +
                        String.join(",", Collections.nCopies(columns.size(), "?")) + ")";
                Object[] values = columns.stream().map(col -> row.get(columns.indexOf(col))).toArray();
                jdbcTemplate.update(sql, values);
            }
        });


        return ResponseEntity.ok("文件上傳成功,已異步導入中");
    }


    /**
     * Excel 導出任意表
     */
    @GetMapping("/export")
    public void exportExcel(@RequestParam("tableName") String tableName, HttpServletResponse response) throws IOException {
        List<String> columnNames = jdbcTemplate.queryForList("SHOW COLUMNS FROM " + tableName, String.class);
        List<Map<String, Object>> rows = jdbcTemplate.queryForList("SELECT * FROM " + tableName);


        List<List<String>> excelData = new ArrayList<>();
        excelData.add(columnNames);


        for (Map<String, Object> row : rows) {
            List<String> rowList = columnNames.stream().map(col -> {
                Object value = row.get(col);
                return value == null ? "" : value.toString();
            }).collect(Collectors.toList());
            excelData.add(rowList);
        }


        response.setContentType("application/vnd.ms-excel");
        response.setCharacterEncoding("utf-8");
        String fileName = URLEncoder.encode(tableName + "_export.xlsx", "UTF-8");
        response.setHeader("Content-Disposition", "attachment;filename=" + fileName);


        EasyExcel.write(response.getOutputStream())
                .sheet("數據")
                .doWrite(excelData);
    }
}

線程池配置支持異步導入

@Configuration
public class ThreadConfig {
    @Bean
    public ThreadPoolTaskExecutor taskExecutor() {
        ThreadPoolTaskExecutor pool = new ThreadPoolTaskExecutor();
        pool.setCorePoolSize(4);
        pool.setMaxPoolSize(8);
        pool.setQueueCapacity(100);
        pool.setKeepAliveSeconds(30);
        pool.setThreadNamePrefix("excel-import-");
        pool.initialize();
        return pool;
    }
}
spring:
  task:
    execution:
      pool:
        core-size: 4
        max-size: 8
        queue-capacity: 100

前端 Thymeleaf 示例

<form method="post" enctype="multipart/form-data" action="/excel/import">
    <input type="file" name="file">
    <input type="text" name="tableName" placeholder="輸入表名">
    <button type="submit">導入 Excel</button>
</form>

<a href="/excel/export?tableName=user">導出用戶表</a>

總結:如何提升系統通用能力

通過本文的設計與實戰,我們實現了一個通用 Excel 導入導出框架,具備如下優勢:

  • 高通用性:支持任意數據庫表結構導入導出
  • 低維護成本:無需重復寫實體類和 mapper
  • 異步處理能力:導入可處理大文件不阻塞主線程
  • 適配前后端分離/低代碼平臺使用場景

如果你正在開發一個后臺系統、BI平臺或需要支持可配置表單數據導入導出功能的系統,這種通用設計無疑能大大提升系統的靈活性和擴展性。

責任編輯:武曉燕 來源: 路條編程
相關推薦

2025-03-26 00:35:00

Javaweb開發

2025-01-13 13:47:13

2022-06-06 08:42:04

spring-boo開發接口防盜刷

2025-02-17 07:48:45

2021-10-19 18:22:50

Map 注冊表源碼

2025-04-10 00:25:00

Spring@JsonView注解

2020-06-22 07:55:28

接口爬蟲

2025-05-14 01:00:00

Spring工具工廠類

2025-01-22 14:02:35

2025-03-26 08:28:36

2022-06-23 08:42:08

配置加密解密

2025-06-09 01:22:00

2021-09-15 08:45:55

Python文本文件代碼

2024-02-19 00:21:45

開源圖片

2021-11-23 23:01:40

Windows微軟系統

2022-05-30 16:31:08

CSS

2025-02-08 08:00:00

JavaDeepSeekIDEA

2025-04-02 04:55:00

2025-06-26 01:22:00

SpringBean開發

2025-03-03 08:00:00

SpringBootEasyExcel數據導出
點贊
收藏

51CTO技術棧公眾號

主站蜘蛛池模板: 自拍偷拍小视频 | 国产成人jvid在线播放 | 在线综合视频 | 国产日韩欧美 | 久久国产精品视频免费看 | 国产成人网 | 成人在线视频免费观看 | 激情黄色在线观看 | 一区二区三区四区国产 | 欧美成人a∨高清免费观看 91伊人 | 黄色大片网 | 亚洲日韩中文字幕一区 | 国产精品免费一区二区三区四区 | 天天爱综合 | 精品免费视频一区二区 | 日日摸夜夜添夜夜添精品视频 | 免费在线观看一区二区 | 伊久在线| 精品亚洲一区二区 | 国产91 在线播放 | 久久曰视频 | 99精品免费在线观看 | 激情久久网 | 国产资源网 | 99精品在线 | 国产男女视频 | 国产激情一区二区三区 | 久久午夜视频 | 一区二区三区不卡视频 | 国产精品成人久久久久a级 久久蜜桃av一区二区天堂 | 欧美日韩福利 | 福利视频网 | 日本精品一区二区在线观看 | 中文字幕亚洲视频 | 国产精品视频区 | 午夜视频在线免费观看 | 午夜视频免费在线观看 | 日本一区二区高清视频 | 综合国产在线 | 亚洲午夜视频 | 欧美日韩专区 |