Spring項目中使用EasyExcel實現Excel 多 Sheet 導入導出功能(完整版)


Excel 多 Sheet 導入導出功能完整實現指南


一、環境依賴
1. Maven 依賴
<!-- EasyExcel -->
<dependency><groupId>com.alibaba</groupId><artifactId>easyexcel</artifactId><version>3.3.2</version>
</dependency><!-- Spring Boot Web -->
<dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId>
</dependency>

二、核心工具類封裝
1. Excel 導出工具類
public class ExcelExportUtils {/*** 動態導出多 Sheet Excel(無需模板)* @param sheetDataMap key: Sheet名稱, value: 數據列表(需保證列表元素類型一致)*/public static void exportDynamicMultiSheet(Map<String, List<Object>> sheetDataMap,String filename,HttpServletResponse response) throws IOException {// 設置響應頭response.setContentType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet");response.setHeader("Content-Disposition", "attachment; filename=" + URLEncoder.encode(filename, "UTF-8"));try (ExcelWriter excelWriter = EasyExcel.write(response.getOutputStream()).build()) {WriteCellStyle headerStyle = createHeaderStyle();for (Map.Entry<String, List<Object>> entry : sheetDataMap.entrySet()) {String sheetName = entry.getKey();List<Object> dataList = entry.getValue();if (CollectionUtils.isEmpty(dataList)) {throw new IllegalArgumentException("Sheet [" + sheetName + "] 數據不能為空");}Class<?> dtoClass = dataList.get(0).getClass();WriteSheet writeSheet = EasyExcel.writerSheet(sheetName).head(dtoClass).headStyle(headerStyle).build();excelWriter.write(dataList, writeSheet);}}}private static WriteCellStyle createHeaderStyle() {WriteCellStyle style = new WriteCellStyle();style.setFillForegroundColor(IndexedColors.GREY_25_PERCENT.getIndex());style.setHorizontalAlignment(HorizontalAlignment.CENTER);WriteFont font = new WriteFont();font.setBold(true);font.setFontHeightInPoints((short) 12);style.setWriteFont(font);return style;}
}
2. Excel 導入工具類
public class ExcelImportUtils {/*** 導入多 Sheet Excel* @param file      上傳的文件* @param sheetMap  key: Sheet名稱, value: 該Sheet對應的DTO類*/public static Map<String, List<?>> importMultiSheet(MultipartFile file,Map<String, Class<?>> sheetMap) throws IOException {Map<String, List<?>> resultMap = new LinkedHashMap<>();try (ExcelReader excelReader = EasyExcel.read(file.getInputStream()).build()) {for (Map.Entry<String, Class<?>> entry : sheetMap.entrySet()) {String sheetName = entry.getKey();Class<?> dtoClass = entry.getValue();GenericSheetListener<Object> listener = new GenericSheetListener<>();ReadSheet readSheet = EasyExcel.readSheet(sheetName).head(dtoClass).registerReadListener(listener).build();excelReader.read(readSheet);resultMap.put(sheetName, listener.getDataList());}}return resultMap;}/** 通用數據監聽器 */private static class GenericSheetListener<T> implements ReadListener<T> {private final List<T> dataList = new ArrayList<>();@Overridepublic void invoke(T data, AnalysisContext context) {dataList.add(data);}@Overridepublic void doAfterAllAnalysed(AnalysisContext context) {// 可添加日志或后處理邏輯}public List<T> getDataList() {return dataList;}}
}

三、DTO 類定義
1. 用戶信息 DTO(對應 Sheet1)
public class UserDTO {@ExcelProperty(value = "姓名", index = 0)private String name;@ExcelProperty(value = "年齡", index = 1)private Integer age;// 必須有無參構造方法public UserDTO() {}// Getters & Setters
}
2. 產品信息 DTO(對應 Sheet2)
public class ProductDTO {@ExcelProperty(value = "產品ID", index = 0)private Long id;@ExcelProperty(value = "產品名稱", index = 1)private String name;// 必須有無參構造方法public ProductDTO() {}// Getters & Setters
}

四、Service 層實現
@Service
public class ExcelService {/*** 導出 Excel*/public void exportExcel(HttpServletResponse response) {Map<String, List<Object>> sheetDataMap = new LinkedHashMap<>();// Sheet1: 用戶數據List<Object> users = Arrays.asList(new UserDTO("張三", 25),new UserDTO("李四", 30));sheetDataMap.put("用戶信息", users);// Sheet2: 產品數據List<Object> products = Arrays.asList(new ProductDTO(1L, "筆記本電腦"),new ProductDTO(2L, "智能手機"));sheetDataMap.put("產品信息", products);// 調用工具類ExcelExportUtils.exportDynamicMultiSheet(sheetDataMap, "export_data.xlsx", response);}/*** 導入 Excel*/public void importExcel(MultipartFile file) {// 定義 Sheet 映射關系Map<String, Class<?>> sheetMap = new LinkedHashMap<>();sheetMap.put("用戶信息", UserDTO.class);sheetMap.put("產品信息", ProductDTO.class);// 解析數據Map<String, List<?>> dataMap = ExcelImportUtils.importMultiSheet(file, sheetMap);// 處理業務邏輯List<UserDTO> users = (List<UserDTO>) dataMap.get("用戶信息");List<ProductDTO> products = (List<ProductDTO>) dataMap.get("產品信息");// 保存到數據庫...}
}

五、Controller 層實現
@RestController
@RequestMapping("/api/excel")
public class ExcelController {@Autowiredprivate ExcelService excelService;/*** 導出 Excel*/@GetMapping("/export")public void exportExcel(HttpServletResponse response) {excelService.exportExcel(response);}/*** 導入 Excel*/@PostMapping("/import")public ResponseEntity<String> importExcel(@RequestParam("file") MultipartFile file) {try {excelService.importExcel(file);return ResponseEntity.ok("文件導入成功");} catch (Exception e) {return ResponseEntity.status(500).body("導入失敗: " + e.getMessage());}}
}

六、關鍵概念解釋
1. 監聽器(ReadListener
  • 作用
    在 Excel 導入過程中,逐行讀取數據并處理,避免一次性加載全量數據到內存。
  • 核心方法
    • invoke(T data, AnalysisContext context):每讀取一行數據時觸發。
    • doAfterAllAnalysed(AnalysisContext context):當前 Sheet 解析完成后觸發。
  • 使用場景
    • 數據收集(存儲到 List)。
    • 數據校驗(如字段非空檢查)。
    • 批量插入數據庫(累積一定數量后批量操作)。
2. @ExcelProperty 注解
  • 功能:定義 Java 字段與 Excel 列的映射關系。
  • 參數
    • value:對應 Excel 列名。
    • index:指定列位置(從 0 開始)。
  • 示例
    @ExcelProperty(value = "姓名", index = 0)
    private String name;
    
3. 樣式配置(WriteCellStyle
  • 用途:控制單元格樣式(如字體、顏色、對齊方式)。
  • 常用配置項
    • setFillForegroundColor: 背景色。
    • setHorizontalAlignment: 水平對齊。
    • setWriteFont: 字體配置(加粗、字號)。

七、常見問題
1. 類型轉換異常
  • 表現ClassCastException
  • 原因:DTO 類字段類型與 Excel 單元格數據類型不匹配。
  • 解決:使用 @DateTimeFormat 或自定義轉換器。
2. 表頭不匹配
  • 表現:數據未正確映射到字段。
  • 原因@ExcelPropertyvalueindex 配置錯誤。
  • 解決:檢查 DTO 類注解與 Excel 列名是否一致。
3. 內存溢出
  • 表現:大文件解析時內存占用過高。
  • 解決:確保使用監聽器模式,避免一次性加載全部數據。

八、擴展功能
1. 自定義數據轉換器
public class CustomConverter implements Converter<LocalDate> {@Overridepublic LocalDate convertToJavaData(ReadConverterContext<?> context) {return LocalDate.parse(context.getReadCellData().getStringValue(), DateTimeFormatter.ISO_DATE);}
}// 注冊轉換器
EasyExcel.read(inputStream).registerConverter(new CustomConverter()).build();
2. 復雜表頭合并
WriteSheet writeSheet = EasyExcel.writerSheet("Sheet1").head(Collections.singletonList(Arrays.asList("主標題", "子標題1", "子標題2"))).build();

九、總結

通過本方案可實現:

  • 動態導出:無需模板,根據 DTO 類自動生成表頭。
  • 高效導入:逐行解析,內存占用低。
  • 類型安全:通過泛型和注解保證數據一致性。
  • 靈活擴展:支持自定義樣式、轉換器、校驗邏輯。

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/bicheng/74945.shtml
繁體地址,請注明出處:http://hk.pswp.cn/bicheng/74945.shtml
英文地址,請注明出處:http://en.pswp.cn/bicheng/74945.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

全流程剖析需求開發:打造極致貼合用戶的產品

全流程剖析需求開發&#xff1a;打造極致貼合用戶的產品 一、需求獲取&#xff08;一&#xff09;與用戶溝通1.面談2.問卷調查3.會議討論 &#xff08;二&#xff09;觀察用戶工作&#xff08;三&#xff09;收集現有文檔 二、需求分析&#xff08;一&#xff09;提煉關鍵需求&…

SQL語句及其應用(中)(DQL語句之單表查詢)

SQL語句的定義: 概述: 全稱叫 Structured Query Language, 結構化查詢語言, 主要是實現 用戶(程序員) 和 數據庫軟件(例如: MySQL, Oracle)之間交互用的. 分類: DDL: 數據定義語言, 主要是操作 數據庫, 數據表, 字段, 進行: 增刪改查(CURD) 涉及到的關鍵字: create, drop, …

5000元組裝一臺本地運行中、小模型主機,參考配置 (運行DeepSeek、Qwen)

5000元組裝一臺本地運行中、小模型主機&#xff0c;參考配置 &#xff08;運行DeepSeek、Qwen) 5000元中、小模型主機 DeepSeek、Qwen 各精度模型推薦啟動方式 模型名稱 參數量 精度 模型大小 推薦運行模式 DeepSeek R1 7b Q4 5 GB LM Studio純GPU 14b Q4 9 GB LM…

【新手初學】SQL注入getshell

一、引入 木馬介紹&#xff1a; 木馬其實就是一段程序&#xff0c;這個程序運行到目標主機上時&#xff0c;主要可以對目標進行遠程控制、盜取信息等功能&#xff0c;一般不會破壞目標主機&#xff0c;當然&#xff0c;這也看黑客是否想要搞破壞。 木馬類型&#xff1a; 按照功…

Containerd+Kubernetes搭建k8s集群

虛擬機環境設置&#xff0c;如果不是虛擬機可以忽略不看 1、安裝配置containerd 1.1 添加 Kubernetes 官方倉庫 安裝cri-tools的時候需要用到 cat > /etc/yum.repos.d/kubernetes.repo << EOF [kubernetes] nameKubernetes baseurlhttps://mirrors.aliyun.com/kub…

應用待機分組管控是啥

1. 應用待機群組是啥&#xff1f; Android 9 引入了一個新功能&#xff0c;叫應用待機群組。簡單來說&#xff0c;就是根據你最近使用應用的頻率和時間&#xff0c;系統會把應用分成不同的“群組”。每個群組的應用能用的系統資源不一樣&#xff0c;比如后臺任務、鬧鐘、網絡請…

C/C++后端開發面經

字節跳動 客戶端開發 實習 一面(50min) 自我介紹是否愿意轉語言,是否只愿意搞后端選一個項目來詳細談談HTTP和HTTPS有什么區別?談一下HTTPS加密的具體過程&#xff1a; 非對稱加密 對稱加密 證書認證的方式 非對稱加密是為了保證對稱密鑰的安全性。 對稱…

【第十三屆“泰迪杯”數據挖掘挑戰賽】【2025泰迪杯】A題解題全流程(持續更新)

【第十三屆“泰迪杯”數據挖掘挑戰賽】【2025泰迪杯】A題解題全流程-思路&#xff08;持續更新&#xff09; 寫在前面&#xff1a; 1、A題、C題將會持續更新&#xff0c;陸續更新發布文章 2、賽題交流咨詢Q群&#xff1a;1037590285 3、全家桶依舊包含&#xff1a; 代碼、…

如何讓 history 記錄命令執行時間?Linux/macOS 終端時間戳設置指南

引言:你真的會用 history 嗎? 有沒有遇到過這樣的情況:你想回顧某個重要命令的執行記錄,卻發現 history 只列出了命令序號和內容,根本沒有時間戳?這在運維排查、故障分析、甚至審計時都會帶來極大的不便。 想象一下,你在服務器上誤刪了某個文件,但不知道具體是幾點執…

Redis緩存異常場景深度解析:穿透、擊穿、雪崩及終極解決方案

一、引言 在高并發系統中&#xff0c;緩存承擔著流量洪峰的削峰填谷作用。然而當緩存層出現異常時&#xff0c;可能引發數據庫級聯崩潰&#xff0c;造成系統癱瘓。本文將深入剖析緩存穿透、緩存擊穿、緩存雪崩三大典型問題&#xff0c;并提供企業級解決方案。文章包含7種防御策…

Scala 之 正則

regex 函數提取 import scala.util.matching.Regex// 輸入表達式 val expression "[a#0, round(a#0, 0) AS round(a, 0)#1, abs(a#0) AS abs(a)#2, len(cast(a#0 as string)) AS len(a)#3]"// 定義一個正則表達式來提取函數名稱 val functionPattern: Regex &quo…

CI/CD-Jenkins安裝與應用

CI/CD-Jenkins安裝與應用 Docker安裝Jenkins docker-compose.yaml version: "3.8" # # 自定義網絡配置 # networks:cicd:driver: bridgeservices:jenkins:# 盡量使用新版本的Jenkins, 低版本的Jenkins的有些插件使用不了# jenkins/jenkins:lts-jdk17是長期支持版…

驗證Linux多進程時間片切換的程序

?? 一、軟件需求 在同時運行多個CPU密集型進程時&#xff0c;需采集以下統計信息&#xff1a; 當前運行在邏輯CPU上的進程ID每個進程的運行進度百分比 實驗程序設計要求&#xff1a; 1. 命令行參數 參數說明示例值n并發進程數量3total總運行時長&#xff08;毫秒&…

IvorySQL:兼容Oracle數據庫的開源PostgreSQL

今天給大家介紹一款基于 PostgreSQL 開發、兼容 Oracle 數據庫的國產開源關系型數據庫管理系統&#xff1a;IvorySQL。 IvorySQL 由商瀚高軟件提供支持&#xff0c;主要的功能特性包括&#xff1a; 完全兼容 PostgreSQL&#xff1a;IvorySQL 基于 PostgreSQL 內核開發&#xf…

樹莓派超全系列文檔--(13)如何使用raspi-config工具其二

如何使用raspi-config工具其二 raspi-configPerformance optionsOverclockGPU memoryOverlay file systemFan Localisation optionsLocaleTime zoneKeyboardWLAN country Advanced optionsExpand filesystemNetwork interface namesNetwork proxy settingsBoot orderBootloader…

QT音樂播放器(1):數據庫保存歌曲

實現功能&#xff1a;用數據庫保存本地導入和在線搜索的歌曲記錄 目錄 一. 保存本地添加的歌曲 1. 使用QSettings &#xff08;1&#xff09;在構造函數中&#xff0c;創建對象。 &#xff08;2&#xff09;在導入音樂槽函數中&#xff0c;保存新添加的文件路徑&#xff0c…

自動化發布工具CI/CD實踐Jenkins常用工具和插件的使用

1、安裝常用工具 名稱版本備注jdkjava8代碼打包所需git1.8.3.1maven3.6.3注意配置私服內容nvm0.39.3多Node.js環境管理工具Node.jsv14.18.0 / v16.17.1包管理工具yarn1.22.15包管理工具 1.1 安裝jdk Jenkins 需要使用java11 及以上&#xff0c;但是代碼打包依賴jdk8&#xff…

shared_ptr和 weak_ptr的詳細介紹

關于 shared_ptr 和 weak_ptr 的詳細介紹及使用示例&#xff1a; 1. shared_ptr&#xff08;共享所有權智能指針&#xff09; 核心特性 引用計數&#xff1a;記錄當前有多少個 shared_ptr 共享同一個對象。自動釋放&#xff1a;當引用計數歸零時&#xff0c;自動釋放對象內存…

Spring AI MCP 架構詳解

Spring AI MCP 架構詳解 1.什么是MCP? MCP 是一種開放協議&#xff0c;它對應用程序向大語言模型&#xff08;LLMs&#xff09;提供上下文信息的方式進行了標準化。可以把 MCP 想象成人工智能應用程序的 USB-C 接口。就像 USB-C 為將設備連接到各種外圍設備和配件提供了一種…

騰訊系AI應用,可以生視頻,3D模型...

以下注冊手機后就可以使用了。 騰訊智影 智能抹除-在線去水印去字幕-抹除水印字幕-騰訊智影 混元&#xff08;文字&#xff0c;圖片生成3D&#xff09; 騰訊混元3D 混元視頻&#xff08;文字生成視頻&#xff0c;可惜右下角有文字&#xff09; https://video.hunyuan.tencen…