Spring Boot + Easy Excel 自定義復雜樣式導入導出

tips:能用模板就用模板,當模板不適用的情況下,再選擇自定義生成 Excel。

官網:https://easyexcel.opensource.alibaba.com

安裝

        <dependency><groupId>com.alibaba</groupId><artifactId>easyexcel</artifactId><version>3.1.1</version></dependency>

一、處理自定義導出復雜場景

1、列不固定,動態列
2、動態下拉
3、自定義鎖定行/列,添加密碼
4、合并單元格
5、導入自定義統一注解統一校驗
6、樣式處理(字體,顏色,底色,富文本,列寬,行寬等)
7、凍結窗格
8、多Sheet處理

1、列不固定,動態列

  • 首先定義一個公共實體,處理公共字段和動態列字段,具體實體則繼承該類即可。
package com.example.springbootexcel.excel.base.model;import com.alibaba.excel.annotation.ExcelProperty;
import lombok.Data;import java.util.List;
import java.util.Map;@Data
public class BaseExcel {@ExcelProperty( value = "序號")private String num;/*** 動態字段處理*/private List<Map<String, Object>> dynamicList;}

2、動態下拉

封裝一個公共類,構造入參Map,key為表頭,value為下拉字符串數組。
.registerWriteHandler(new DropDownHandler(dropDownMap));

package com.example.springbootexcel.excel.base.style;import com.alibaba.excel.write.handler.SheetWriteHandler;
import com.alibaba.excel.write.metadata.holder.WriteSheetHolder;
import com.alibaba.excel.write.metadata.holder.WriteWorkbookHolder;
import org.apache.poi.ss.usermodel.DataValidation;
import org.apache.poi.ss.usermodel.DataValidationConstraint;
import org.apache.poi.ss.usermodel.DataValidationHelper;
import org.apache.poi.ss.usermodel.Sheet;
import org.apache.poi.ss.util.CellRangeAddressList;import java.util.Map;/*** 添加下拉選單** @author jason*/
public class DropDownHandler implements SheetWriteHandler {private final Map<Integer, String[]> dropDownMap;  // key:列號(從0開始), value:下拉數據public DropDownHandler(Map<Integer, String[]> dropDownMap) {this.dropDownMap = dropDownMap;}@Overridepublic void beforeSheetCreate(WriteWorkbookHolder writeWorkbookHolder, WriteSheetHolder writeSheetHolder) {// 不需要實現}@Overridepublic void afterSheetCreate(WriteWorkbookHolder writeWorkbookHolder, WriteSheetHolder writeSheetHolder) {if (dropDownMap == null || dropDownMap.isEmpty()) {return;}Sheet sheet = writeSheetHolder.getSheet();DataValidationHelper helper = sheet.getDataValidationHelper();dropDownMap.forEach((columnIndex, dropDownData) -> {// 設置下拉框數據范圍 (這里設置從第2行到第10000行)CellRangeAddressList addressList = new CellRangeAddressList(1, 9999, columnIndex, columnIndex);// 創建數據驗證約束DataValidationConstraint constraint = helper.createExplicitListConstraint(dropDownData);// 創建數據驗證DataValidation validation = helper.createValidation(constraint, addressList);// 阻止輸入非下拉選項的值validation.setErrorStyle(DataValidation.ErrorStyle.STOP);validation.setShowErrorBox(true);validation.setSuppressDropDownArrow(true);validation.createErrorBox("提示", "請從下拉選項中選擇");// 添加驗證到sheetsheet.addValidationData(validation);});}
}

3、自定義鎖定行/列,添加密碼

@Overridepublic void afterCellCreate(CellWriteHandlerContext context) {WriteSheetHolder writeSheetHolder = context.getWriteSheetHolder();Sheet sheet = writeSheetHolder.getSheet();Workbook workbook = sheet.getWorkbook();Cell cell = context.getCell();int columnIndex = cell.getColumnIndex();Row row = cell.getRow();// 設置工作表保護if (!sheet.getProtect()) {XSSFSheet xssfSheet = (XSSFSheet) sheet;// 啟用保護xssfSheet.protectSheet("1234");// 設置保護選項:允許刪除未鎖定行xssfSheet.lockDeleteRows(false);// 設置保護選項:允許插入未鎖定行xssfSheet.lockInsertRows(false);}// 設置工作表的默認單元格樣式為不鎖定CellStyle defaultStyle = workbook.createCellStyle();defaultStyle.setLocked(false);sheet.setDefaultColumnStyle(columnIndex, defaultStyle);row.setRowStyle(defaultStyle);}

4、合并單元格

sheet.addMergedRegion(new CellRangeAddress(relativeRowIndex, relativeRowIndex, 0, 10));

5、導入自定義統一注解統一校驗

package com.example.springbootexcel.excel.base.component;import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;/*** tips:非必填校驗,填了就校驗,不填不校驗*/
@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.FIELD})
public @interface ExcelValidation {/*** 日期校驗** @return true表示必須為日期,false表示不限制*/boolean date() default false;/*** 是否必須為數字** @return true表示必須為數字,false表示不限制*/boolean numeric() default false;/*** 是否允許小數,且最多兩位小數** @return true表示允許最多兩位小數,false表示不允許小數*/boolean decimal() default false;/*** 是否允許斜杠** @return true表示允許斜杠,false表示不允許*/boolean allowSlash() default false;/*** 校驗失敗時的錯誤提示信息** @return 錯誤提示信息*/String message() default "字段校驗失敗";}

6、樣式處理(字體,顏色,底色,富文本,列寬,行寬等)

// 基本樣式設置cellStyle.setBorderTop(BorderStyle.THIN);cellStyle.setBorderBottom(BorderStyle.THIN);cellStyle.setBorderLeft(BorderStyle.THIN);cellStyle.setBorderRight(BorderStyle.THIN);// 設置水平對齊為左對齊cellStyle.setAlignment(HorizontalAlignment.LEFT);// 設置垂直對齊為垂直居中cellStyle.setVerticalAlignment(VerticalAlignment.CENTER);// 設置自動換行cellStyle.setWrapText(true);// 創建默認字體Font defaultFont = workbook.createFont();defaultFont.setFontName(DEFAULT_FONT_NAME);defaultFont.setFontHeightInPoints(DEFAULT_FONT_POINTS);defaultFont.setColor(IndexedColors.BLACK.getIndex());defaultFont.setBold(false);// 創建紅色字體Font redFont = workbook.createFont();redFont.setFontName(DEFAULT_FONT_NAME);redFont.setFontHeightInPoints(DEFAULT_FONT_POINTS);redFont.setColor(IndexedColors.RED.getIndex());redFont.setBold(true);// 自定義列寬String cellValue = cell.getStringCellValue();Integer columnWidth = COLUMN_WIDTHS.get(cellValue);if (ObjectUtil.isNotNull(columnWidth) && !CollectionUtil.contains(COLUMN_WIDTHS_EXIST, context.getColumnIndex())) {sheet.setColumnWidth(context.getColumnIndex(), columnWidth);COLUMN_WIDTHS_EXIST.add(context.getColumnIndex());}// 設置默認寬度if (!CollectionUtil.contains(COLUMN_WIDTHS_EXIST, context.getColumnIndex())) {sheet.setColumnWidth(context.getColumnIndex(), DEFAULT_COLUMN_WIDTH);}// 提示詞if (CollectionUtil.contains(TIPS_LIST, relativeRowIndex)) {defaultFont = redFont;// 合并單元格sheet.addMergedRegion(new CellRangeAddress(relativeRowIndex, relativeRowIndex, 0, 10));}// 表頭if (CollectionUtil.contains(HEAD_LIST, relativeRowIndex)) {defaultFont.setBold(true);// 背景色cellStyle.setFillForegroundColor(IndexedColors.GREY_25_PERCENT.getIndex());cellStyle.setFillPattern(FillPatternType.SOLID_FOREGROUND);// 動態字段標紅if (CollectionUtil.contains(HEAD_READ_COLOR, cell.getColumnIndex())) {defaultFont = redFont;} else {// 星號標紅RichTextString richText = cell.getRichStringCellValue();if (StrUtil.startWith(cellValue, "*")) {richText.applyFont(0, 1, redFont);if (cellValue.length() > 1) {richText.applyFont(1, cellValue.length(), defaultFont);}cell.setCellValue(richText);}}}cellStyle.setFont(defaultFont);

7、凍結窗格

.registerWriteHandler(new FreezePaneHandler(2))

package com.example.springbootexcel.excel.base.style;import com.alibaba.excel.write.handler.SheetWriteHandler;
import com.alibaba.excel.write.metadata.holder.WriteSheetHolder;
import com.alibaba.excel.write.metadata.holder.WriteWorkbookHolder;
import org.apache.poi.ss.usermodel.Sheet;/*** 凍結窗格** @author jason*/
public class FreezePaneHandler implements SheetWriteHandler {private final int row;  // 需要凍結的行public FreezePaneHandler(int row) {this.row = row;}@Overridepublic void beforeSheetCreate(WriteWorkbookHolder writeWorkbookHolder, WriteSheetHolder writeSheetHolder) {}@Overridepublic void afterSheetCreate(WriteWorkbookHolder writeWorkbookHolder, WriteSheetHolder writeSheetHolder) {Sheet sheet = writeSheetHolder.getSheet();// 凍結首行// sheet.createFreezePane(0, 1, 0, 1);sheet.createFreezePane(0, row, 0, row);}}

8、多Sheet處理

        // 創建 ExcelWriter 對象ExcelWriter excelWriter = EasyExcel.write(filePath).inMemory(true).build();// 寫入第1個 SheetWriteSheet sheet1 = EasyExcel.writerSheet("Sheet1").registerWriteHandler(new CommonStyleHandler(MockDataUtil.getHeadReadColor(headList, dynamicList))).registerWriteHandler(new DropDownHandler(dropDownMap)).registerWriteHandler(new FreezePaneHandler(2)).build();excelWriter.write(sheet1DataList, sheet1);// 寫入第2個 SheetWriteSheet sheet2 = EasyExcel.writerSheet("Sheet2").head(BrandModelExcel.class).registerWriteHandler(new FreezePaneHandler(1)).build();excelWriter.write(MockDataUtil.brandModelExcelList(), sheet2);// 寫入第3個 SheetWriteSheet sheet3 = EasyExcel.writerSheet("Sheet3").head(VehicleNameExcel.class).registerWriteHandler(new FreezePaneHandler(1)).build();excelWriter.write(MockDataUtil.vehicleNameExcelList(), sheet3);// 非常重要:最后一定要關閉 excelWriterexcelWriter.finish();log.info("導出成功:{}", filePath);

源碼:https://gitee.com/zhaomingjian/workspace_dora/tree/master/spring-boot-excel

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

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

相關文章

Spark從入門到實戰:安裝與使用全攻略

目錄一、Spark 簡介1.1 Spark 的概念1.2 Spark 的優勢1.3 Spark 的應用場景二、安裝前準備2.1 硬件要求2.2 軟件要求2.3 下載 Spark三、Spark 安裝步驟3.1 解壓安裝包3.2 配置環境變量3.3 配置 spark-env.sh3.4 配置 slaves 文件&#xff08;分布式模式&#xff09;3.5 啟動 Sp…

Python 進程間的通信:原理剖析與項目實戰

在 Python 編程中,當涉及多進程編程時,進程間的通信(Inter-Process Communication,簡稱 IPC)是一個重要的課題。多個進程在運行過程中,常常需要交換數據、傳遞狀態或協同工作,這就離不開進程間通信機制。本文將深入講解 Python 進程間通信的原理,并結合實際項目案例,展…

神經網絡之BP算法

一、正向傳播正向傳播&#xff08;Forward Propagation&#xff09;是神經網絡中數據從輸入層流向輸出層的過程。輸入數據通過各層的權重和激活函數逐層計算&#xff0c;最終得到預測輸出。數學表示&#xff1a; 對于第 ( l ) 層的神經元&#xff0c;其輸出計算如下&#xff1a…

Ubuntu 版本號與別名對照表(部分精選)

Ubuntu 的別名遵循 形容詞 動物名 的命名規則&#xff0c;且兩個單詞首字母相同&#xff0c;按字母表順序循環使用&#xff08;從 Ubuntu 6.06 開始&#xff09;。 &#x1f4c5; Ubuntu 版本號與別名對照表&#xff08;部分精選&#xff09; 版本號別名 (開發代號)發布時間…

實驗03-Spark批處理開發

使用Spark Shell探索RDD 啟動并使用Scala Spark Shell 在終端窗口&#xff0c;啟動Scala Spark shell&#xff1a; spark-shell --master local查看對象&#xff1a; scala> sc scala> spark輸入spark.[TAB]然后可以看到所有可用的方法。 讀并顯示文本文件 查看文本…

【R語言】Can‘t subset elements that don‘t exist.

Error in select(): ? In argument: all_of(label_col). Caused by error in all_of(): ! Cant subset elements that dont exist. ? Element Label doesnt exist. Run rlang::last_trace() to see where the error occurred.原文中文解釋涉及關鍵詞Error in select()報錯發生…

Spring的依賴注入(xml)

引入 首先先明白&#xff0c;依賴注入描述的是在容器中建立bean與bean之間的依賴關系&#xff0c;本質就是將一個類中和別的類解耦的方式&#xff0c;就是把別的類&#xff0c;寫在成員變量位置&#xff0c;再對外提供可以給成員變量賦值的方法&#xff0c;外界就直接調用來給…

docker運行的一些常用命令

docker images 顯示可以加載的鏡像docker ps 顯示運行的docker容器 加-a顯示所有的容器docker run --name 容器名字 -d 鏡像名字docker start 容器名/ID 開啟容器docker stop 容器名/ID 關閉容器docker exec -it dock…

Django跨域

步驟 1&#xff1a;安裝 django-cors-headerspip install django-cors-headers步驟 2&#xff1a;修改 Django 配置 在 settings.py 中添加&#xff1a;INSTALLED_APPS [...,"corsheaders", # 新增 ]MIDDLEWARE [...,"corsheaders.middleware.CorsMiddleware…

20250706-10-Docker快速入門(下)-Harbor鏡像倉庫_筆記

一、Harbor鏡像倉庫搭建與使用1. Harbor概述&#xfeff;&#xfeff;定義: 由VMWare公司開源的容器鏡像倉庫系統技術基礎: 在Docker Registry基礎上進行企業級擴展核心特性:提供管理用戶界面(GUI)基于角色的訪問控制(RBAC)支持&#xfeff;AD/LDAP\mathrm{AD}/\mathrm{LDAP}AD…

JavaScript之數組方法詳解

JavaScript之數組方法詳解一、數組的創建與基礎特性1.1 數組的創建方式1.2 數組的核心特性二、修改原數組的方法2.1 添加/刪除元素2.1.1 push()&#xff1a;尾部添加元素2.1.2 pop()&#xff1a;尾部刪除元素2.1.3 unshift()&#xff1a;頭部添加元素2.1.4 shift()&#xff1a;…

品牌增長困局突圍:大模型時代,AI 如何幫我的品牌少走彎路?

AI時代對企業戰略的沖擊與機遇 在當今瞬息萬變的商業環境中&#xff0c;大模型的崛起正以前所未有的力量重塑著各行各業的競爭格局。傳統的市場營銷、品牌傳播模式正在被顛覆&#xff0c;消費者獲取信息、認知品牌的方式發生了根本性變化。如果說過去十年是“互聯網”的時代&am…

從單體到微服務:Spring Cloud 開篇與微服務設計

一、單體架構的核心痛點與微服務化目標 1. 單體架構的致命缺陷問題表現后果可維護性差百萬行代碼耦合&#xff0c;修改一處需全量測試迭代周期長&#xff0c;創新停滯擴展性受限無法按模塊獨立擴縮容&#xff08;如訂單模塊需擴容時&#xff0c;用戶模塊被迫一起擴容&#xff0…

篇二 OSI七層模型,TCP/IP四層模型,路由器與交換機原理

一 前言 本章節主要介紹OSI七層模型&#xff0c;TCP/IP四層模型劃分&#xff0c;以及日常使用的路由器&#xff0c;交換機的一些基礎知識 二 OSI 七層 OSI&#xff08;Open Systems Interconnection Model&#xff09;即開放式系統互聯模型&#xff0c;是國際標準化組織提出的&…

【JavaSE面試篇】Java集合部分高頻八股匯總

目錄 概念 1. 說說Java中的集合&#xff1f; 2. Java中的線程安全的集合有什么&#xff1f; 3. Collections和Collection的區別&#xff1f; 4. 集合遍歷的方法有哪些&#xff1f; List 5. 講一下java里面list的幾種實現&#xff0c;幾種實現有什么不同&#xff1f; 6.…

利用低空無人機影像進行樹種實例分割

在本項先導研究中,我們開發了一個基于低空無人機影像的本地樹種機器學習實例分割模型,用于生態調查。該實例分割包括單株樹冠的描繪和樹種的分類。我們利用無人機影像對20個樹種及其對應的學名進行了訓練,并收集了這些樹種的學名用于機器學習。為了評估該機器學習模型的準確…

二、Flutter基礎

目錄1. 什么是Widget&#xff1f;Flutter中的Widget分為哪幾類&#xff1f;2. StatelessWidget和StatefulWidget的區別3. StatefulWidget生命周期4. 什么是BuildContext&#xff1f;5. 如何優化Widget重建&#xff1f;6. Flutter布局機制7. Row/Column的主軸和交叉軸8. Expande…

設計模式筆記_創建型_建造者模式

1. 建造者模式介紹 建造者模式是一種創建型設計模式&#xff0c;旨在通過將復雜對象的構建過程與其表示分離&#xff0c;使得同樣的構建過程可以創建不同的表示。它通常用于構造步驟固定但具體實現可能變化的對象。 1.1 功能&#xff1a; 封裝復雜對象的創建過程&#xff1a;適…

【ROS2 自動駕駛學習】03-ROS2常用命令

目錄 1. ros2 pkg list 2. ros2 node list 3. ros2 node info 節點名稱 4. ros2 topic list 5. ros2 topic info 話題名 6. ros2 topic type 話題名 7. ros2 topic find 消息類型 8. ros2 service list 9. ros2 service type 服務名稱 10. ros2 service find 服…

MyBatis-Plus:提升數據庫操作效率的利器

在Java開發中&#xff0c;MyBatis是一個非常流行的持久層框架&#xff0c;它簡化了數據庫操作&#xff0c;提供了靈活的SQL映射功能。然而&#xff0c;隨著項目規模的擴大和業務復雜度的增加&#xff0c;開發者需要更高效、更便捷的方式來處理數據庫操作。MyBatis-Plus應運而生…