Excel導出

目錄

Maven依賴

實體類

表頭列寬自適應處理器

行列凍結處理器

合并單元格處理器

工具類


Maven依賴

        <!--easy excel--><dependency><groupId>com.alibaba</groupId><artifactId>easyexcel</artifactId><version>3.3.2</version></dependency><!-- excel工具 --><dependency><groupId>org.apache.poi</groupId><artifactId>poi-ooxml</artifactId><version>4.1.2</version></dependency><!--lombok--><dependency><groupId>org.projectlombok</groupId><artifactId>lombok</artifactId><version>1.16.10</version><scope>provided</scope></dependency><!--工具集--><dependency><groupId>cn.hutool</groupId><artifactId>hutool-all</artifactId><version>5.8.12</version></dependency>

實體類


import com.alibaba.excel.annotation.ExcelIgnoreUnannotated;
import com.alibaba.excel.annotation.ExcelProperty;
import com.alibaba.excel.annotation.format.DateTimeFormat;
import lombok.Data;import java.io.Serializable;
import java.util.Date;/*** entity實體類** @Package_Name * @Author Leslie Lee* @TIME * @Version 1.0*/
@Data
@ExcelIgnoreUnannotated //忽略未標注的字段
public class EntityDemo implements Serializable {private static final long serialVersionUID = 1L;@ExcelProperty("姓名")private String name;//private String age;//@ExcelProperty("申請日期")@DateTimeFormat("yyyy-MM-dd")//時間格式private Date applicationDate;//申請日期}

表頭列寬自適應處理器

import com.alibaba.excel.metadata.Head;
import com.alibaba.excel.metadata.data.WriteCellData;
import com.alibaba.excel.write.metadata.holder.WriteSheetHolder;
import com.alibaba.excel.write.style.column.AbstractColumnWidthStyleStrategy;
import org.apache.poi.ss.usermodel.Cell;
import org.apache.poi.ss.usermodel.Sheet;import java.util.List;/*** 表頭自動列寬** @Package_Name * @Author Leslie Lee* @TIME * @Version 1.0*/
public class ExcelWidthStyleStrategy extends AbstractColumnWidthStyleStrategy {// 統計setColumnWidth被調用多少次private static int count = 0;@Overrideprotected void setColumnWidth(WriteSheetHolder writeSheetHolder, List<WriteCellData<?>> cellDataList, Cell cell, Head head,Integer relativeRowIndex, Boolean isHead) {// 簡單設置Sheet sheet = writeSheetHolder.getSheet();sheet.setColumnWidth(cell.getColumnIndex(), 5000);}
}

行列凍結處理器

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;/*** excel導出,凍結列和行 處理器** @Package_Name* @Author Leslie Lee* @TIME* @Version 1.0*/
public class FreezeRowColHandler implements SheetWriteHandler {/*** colSplit:表示要凍結的列數;* rowSplit:表示要凍結的行數;* firstCellNum:表示被固定列右邊第一列的列號;* firstRollNum :表示被固定行下邊第一列的行號;*/private int colSplit = 0, rowSplit = 1, firstCellNum = 0, firstRollNum = 0;/* 空參構造,不傳值默認凍結一行 */public FreezeRowColHandler() {}public FreezeRowColHandler(int colSplit, int rowSplit, int firstCellNum, int firstRollNum) {this.colSplit = colSplit;this.rowSplit = rowSplit;this.firstCellNum = firstCellNum;this.firstRollNum = firstRollNum;}@Overridepublic void beforeSheetCreate(WriteWorkbookHolder writeWorkbookHolder, WriteSheetHolder writeSheetHolder) {}@Overridepublic void afterSheetCreate(WriteWorkbookHolder writeWorkbookHolder, WriteSheetHolder writeSheetHolder) {Sheet sheet = writeSheetHolder.getSheet();sheet.createFreezePane(colSplit, rowSplit, firstCellNum, firstRollNum);}
}

合并單元格處理器

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.util.ReflectUtil;
import cn.hutool.core.util.StrUtil;
import com.alibaba.excel.annotation.ExcelProperty;
import com.alibaba.excel.write.handler.SheetWriteHandler;
import com.alibaba.excel.write.metadata.holder.WriteSheetHolder;
import com.alibaba.excel.write.metadata.holder.WriteWorkbookHolder;
import lombok.extern.slf4j.Slf4j;
import org.apache.poi.ss.usermodel.Sheet;
import org.apache.poi.ss.util.CellRangeAddress;import java.lang.reflect.Field;
import java.util.List;/*** easyExcel合并單元格** @Package_Name* @Author Leslie Lee* @TIME* @Version 1.0*/
@Slf4j
public class ExcelCellMergeStrategy implements SheetWriteHandler {private List<CellRangeAddress> addressList;public ExcelCellMergeStrategy() {}public ExcelCellMergeStrategy(List<CellRangeAddress> addressList) {this.addressList = addressList;}@Overridepublic void beforeSheetCreate(WriteWorkbookHolder writeWorkbookHolder, WriteSheetHolder writeSheetHolder) {}/* 執行合并 */@Overridepublic void afterSheetCreate(WriteWorkbookHolder writeWorkbookHolder, WriteSheetHolder writeSheetHolder) {Sheet sheet = writeSheetHolder.getSheet();//打印合并信息
//        log.info("ExcelCellMergeStrategy|start|合并單元格|sheet名稱:{}|開始執行", sheet.getSheetName());for (CellRangeAddress address : addressList) {sheet.addMergedRegionUnsafe(address);}}/*** 合并單元格策略,根據首列相同,合并指定列數** @param mergeColumnIndexes 合并列數 前{x}列* @param tableHeaderRows    表頭行數* @param list               導出的數據* @param <T>                導出數據-實體類* @return 合并范圍*/public static <T> List<CellRangeAddress> getOneColAddressList(int mergeColumnIndexes, int tableHeaderRows, List<T> list) {List<CellRangeAddress> addressList = CollUtil.newArrayList();if (CollUtil.isNotEmpty(list)) {Class<?> aClass = list.get(0).getClass();Field f = null;Field[] fields = aClass.getDeclaredFields();for (Field field : fields) {if (field.isAnnotationPresent(ExcelProperty.class)) {f = field;break;}}if (f != null) {//list長度,最大行數int size = list.size();//防止下標越界使用int i2 = size - 2;for (int i = 0; i < size; i++) {//開始行 從 不合并標題int firstRow = i + tableHeaderRows;//結束行int lastRow = firstRow;//開始列,結束列//int firstCol,lastCol = 0;String value = StrUtil.toString(ReflectUtil.getFieldValue(list.get(i), f));boolean flag = true;while (flag) {//最后一行不再進行匹配,直接退出if (i > i2) {break;}String value1 = StrUtil.toString(ReflectUtil.getFieldValue(list.get(i + 1), f));//值相同則合并 -> 合并行數+1 下標+1遍歷跳過相同行if (StrUtil.equals(value1, value)) {i++;lastRow++;} else {flag = false;}if (i == size) {flag = false;}}if (lastRow != firstRow) {for (int i1 = 0; i1 < mergeColumnIndexes; i1++) {addressList.add(new CellRangeAddress(firstRow, lastRow, i1, i1));}}}}}return addressList;}
}

工具類

import com.alibaba.excel.EasyExcel;import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.net.URLEncoder;
import java.util.List;/*** @Package_Name * @Author Leslie Lee* @TIME * @Version 1.0*/
public class EasyExcelUtils<T> {/*** 分片導出** @param response* @param list* @param sheetName* @throws IOException*/public static void downloadFragmentation2(HttpServletResponse response, List<?> list, String sheetName, int mergeColumnIndexs, int hdrRow) throws IOException {Class<?> clazz = list.get(0).getClass();response.setContentType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet");response.setCharacterEncoding("utf-8");// URLEncoder.encode 防止中文亂碼 和easyexcel沒有關系String fileName = URLEncoder.encode(sheetName, "UTF-8").replaceAll("\\+", "%20");response.setHeader("Content-disposition", "attachment;filename*=utf-8''" + fileName + ".xlsx");// 定義每次寫入的數據量int batchSize = 2000;// 定義寫入的起始位置int start = 0;// 定義寫入的結束位置int end = 0;while (end < list.size()) {// 計算下一次寫入的結束位置end = Math.min(start + batchSize, list.size());// 獲取本次寫入的數據List<?> subList = list.subList(start, end);// 寫入數據EasyExcel.write(response.getOutputStream(), clazz)/* 列寬自適應 */.registerWriteHandler(new ExcelWidthStyleStrategy())/* 行列凍結 */.registerWriteHandler(new FreezeRowColHandler())/* 單元格合并 */.registerWriteHandler(new ExcelCellMergeStrategy(getOneColAddressList(mergeColumnIndexs,hdrRow,list))).sheet(sheetName).doWrite(list);// 更新起始位置start = end;}}
}

? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? Leslie Lee 隨筆

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

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

相關文章

數獨游戲(dfs)

代碼注釋如下 #include <iostream> using namespace std; const int N 10; bool col[N][N], rol[N][N], cell[3][3][N]; char g[N][N]; bool dfs(int x, int y) { //用bool這樣在找到一個方案就可以迅速退出if(y 9) x, y 0; //若y超出邊界&#xff0c;則第二…

S1---FPGA硬件板級原理圖實戰導學

視頻鏈接 FPGA板級實戰導學01_嗶哩嗶哩_bilibili FPGA硬件板級原理圖實戰導學 【硬件電路設計的方法和技巧-嗶哩嗶哩】硬件電路設計的方法和技巧01_嗶哩嗶哩_bilibili&#xff08;40min&#xff09; 【高速板級硬件電路設計-嗶哩嗶哩】 高速板級硬件電路設計1_嗶哩嗶哩_bil…

【RT-Thread基礎教程】郵箱的使用

文章目錄 前言一、郵箱的特性二、郵箱操作函數2.1 創建郵箱創建動態郵箱創建靜態郵箱 2.2 刪除郵箱2.3 發郵件2.4 取郵件 三、示例代碼總結 前言 RT-Thread是一個開源的實時嵌入式操作系統&#xff0c;廣泛應用于各種嵌入式系統和物聯網設備。在RT-Thread中&#xff0c;郵箱是…

輸入一個整數,輸出其最長連續因子。

輸入一個整數&#xff0c;輸出其最長連續因子。 例如 輸入&#xff1a;60 輸出&#xff1a;2 3 4 5 6 注意&#xff1a;1不算因子 輸入輸出格式 輸入描述: 輸入一個整數N&#xff0c;N<10000。 輸出描述: 輸出其最長連續因子&#xff0c;如果有多個最長&#xff0c;輸出…

HTML5浮動

1.標準文檔流組成 塊級元素&#xff08;block&#xff09; 內聯元素&#xff08;inline&#xff09; 2.display屬性 作用&#xff1a;指定HTML標簽的顯示方式 常用屬性 值 說明 block 塊級元素的默認值&#xff0c;元素會被顯示為塊級元素&#xff0c;該元素前后會帶有換行…

Linux UnixODBC安裝配置

配置 UnixODBC 夢之上關注IP屬地: 香港 0.2322020.12.09 13:23:10字數 1,202閱讀 5,447 麒麟&達夢適配系列: 1.麒麟服務器上安裝 DM8 2.配置 UnixODBC 3.beego-ORM 適配達夢 資源緊張的時候&#xff0c;服務器是大家共用的&#xff0c;上面部署了一堆服務。所以選用doc…

Lua速成(7)

一、Lua 元表(Metatable) 在 Lua table 中我們可以訪問對應的 key 來得到 value 值&#xff0c;但是卻無法對兩個 table 進行操作(比如相加)。 因此 Lua 提供了元表(Metatable)&#xff0c;允許我們改變 table 的行為&#xff0c;每個行為關聯了對應的元方法。 例如&#xf…

ShardingJdbc實戰-分庫分表

文章目錄 基本配置分庫分表的分片策略一、inline 行表達時分片策略algorithm-expression行表達式完整案例和配置如下 二、根據實時間日期 - 按照標準規則分庫分表標準分片 - Standard完整案例和配置如下 基本配置 邏輯表 邏輯表是指&#xff1a;水平拆分的數據庫或者數據表的相…

SpringBoot實戰(1)

SpringBoot總結 一,Spring 設計思想 OOP: 面向對象編程-》封裝、繼承、多態 BOP: 面向Bean編程-》一切從Bean開始 AOP: 面向切面編程-》解藕、專 人做專事 IOC: 控制反轉,將new 對象的操作交給Spring統一管理-》轉交控制權 DI/DL: 依賴注入/依賴查找-》自動賦值 DI和AOP…

LLVM 一些重要文檔 LLVM 3.0

基于LLVM 3.0: Documentation for the LLVM System at SVN head LLVM 作為庫的使用方法&#xff1a; Using The LLVM Libraries LLVM C 的編程規范&#xff1a; LLVM Coding Standards

stl 迭代器(Iterator)

定義 迭代器&#xff08;Iterator&#xff09;是STL&#xff08;Standard Template Library&#xff0c;標準模板庫&#xff09;中的一個核心概念&#xff0c;用于提供一種通用的方式來遍歷容器&#xff08;如vector、list、map等&#xff09;中的元素&#xff0c;而無需暴露容…

大小端問題

0. 介紹 大小端計算機存儲數據而安排字節的兩種順序。 針對的是字節。 大端與我們平時書寫的順序一致。 1. 大小端的判定 不需要手動判斷。 有一個頭文件endian.h; 可能會有宏 __BYTE_ORDER __BIG_ENDIAN __LITTLE_ENDIAN通過庫來進行判斷。 手動判斷 根據字節存取的順序…

【JSON2WEB】07 Amis可視化設計器CRUD增刪改查

總算到重點中的核心內容&#xff0c;CRUD也就是增刪改查&#xff0c;一個設計科學合理的管理信息系統&#xff0c;95%的就是CRUD&#xff0c;達不到這個比例要重新考慮一下你的數據庫設計了。 1 新增頁面 Step 1 啟動amis-editor Setp 2 新增頁面 名稱和路徑隨便命名&#xf…

Dynamo幕墻探究系列(一)

一直想寫個系列教程&#xff0c;但是沒有那么多時間整理資料&#xff0c;這次呢&#xff0c;先弄個小系列吧&#xff0c;還是和之前差不多的幕墻測試&#xff0c;我們分幾節課&#xff0c;一步一步深入研究。 今天先開個小頭兒&#xff0c;要弄的&#xff0c;就是下面這么個模型…

對象鎖與類鎖

不同鎖互不影響&#xff0c;共用一個鎖&#xff0c;可能會發生阻塞。 1.在修飾靜態方法時&#xff0c;鎖定的是當前類的 Class 對象&#xff0c;在下面的例子中就是SycTest1.class 2.當修飾非靜態方法時&#xff0c;鎖定的就是 this 對象&#xff0c;即當前的實例化對象 public…

【Git教程】(四)版本庫 —— 存儲系統,存儲目錄,提交對象及其命名、移動與復制~

Git教程 版本庫 1?? 一種簡單而高效的存儲系統2?? 存儲目錄&#xff1a;Blob 與 Tree3?? 相同數據只存儲一次4?? 壓縮相似內容5?? 不同文件的散列值相同6?? 提交對象7?? 提交歷史中的對象重用8?? 重命名、移動與復制&#x1f33e; 總結 事實上&#xff0c;我們…

keil MDK安裝armcc V5編譯器

不知道從什么時候開始&#xff0c;Keil MDK默認不支持V5的編譯器了&#xff0c;里面默認只有V6的編譯器&#xff0c;設置界面跟V5有很大的差異不太熟悉。最可怕的是&#xff0c;之前使用V5編譯的工程&#xff0c;換成V6編譯器后居然報錯...雖然修改一下應該也可以正常編譯&…

神經網絡基礎知識:LeNet的搭建-訓練-預測

1.參考視頻&#xff1a; 2.1 pytorch官方demo(Lenet)_嗶哩嗶哩_bilibili 2.總結&#xff1a; &#xff08;1&#xff09;LeNet網絡就是 我最開始用來預測mnist數據集的那個網絡&#xff0c;簡單的2個conv2個maxpool3個linear層 &#xff08;2&#xff09;up主整理的train.py…

SQL面試題(2)

第一題 創建trade_orders表: create table `trade_orders`( `trade_id` varchar(255) NULL DEFAULT NULL, `uers_id` varchar(255), `trade_fee` int(20), `product_id` varchar(255), `time` varchar(255) )ENGINE = InnoDB CHARACTER SET = utf8mb4 COLLATE = utf8mb4_0900_…

web自動化筆記九:驗證碼的處理方式

一、驗證碼常用的處理方式 ①、說明&#xff1a;Selenium中并沒有對驗證碼處理的方法&#xff0c;在這里我們介紹一下針對驗證碼的幾種常用處理方式 ②、方式&#xff1a; 1&#xff09;、去掉驗證碼&#xff08;測試環境下采用&#xff09; …