Java Hutool 包工具類推薦 ExcelUtil

来源:https://www.cnblogs.com/mlxs/archive/2022/09/30/16745344.html
-Advertisement-
Play Games

Java Hutool 包工具類推薦 ExcelUtil 包引入 hutool包版本號可根據實際情況更換 <dependency> <groupId>cn.hutool</groupId> <artifactId>hutool-all</artifactId> <version>5.8.4.M1</ ...


Java Hutool 包工具類推薦 ExcelUtil

包引入

hutool包版本號可根據實際情況更換

 

<dependency>
    <groupId>cn.hutool</groupId>
    <artifactId>hutool-all</artifactId>
    <version>5.8.4.M1</version>
</dependency>

 

除hutool包之外,還需要引入操作Excel必要包

 

<dependency>
    <groupId>org.apache.poi</groupId>
    <artifactId>poi-ooxml</artifactId>
    <version>5.0.0</version>
</dependency>
<dependency>
    <groupId>org.apache.poi</groupId>
    <artifactId>poi-ooxml-full</artifactId> 
    <version>5.0.0</version>
</dependency>

 

一般簡單表頭Excel封裝工具類

直接上代碼

 

package io.supers.common.utils;

import cn.hutool.core.io.IoUtil;
import cn.hutool.core.util.URLUtil;
import cn.hutool.poi.excel.ExcelUtil;
import cn.hutool.poi.excel.ExcelWriter;
import cn.hutool.poi.excel.style.StyleUtil;
import io.supers.framework.em.BaseErrorEnum;
import io.supers.framework.exception.RRException;
import org.apache.commons.collections.CollectionUtils;
import org.apache.poi.ss.usermodel.CellStyle;
import org.apache.poi.ss.usermodel.DataFormat;
import org.apache.poi.ss.usermodel.HorizontalAlignment;
import org.apache.poi.ss.usermodel.Workbook;
import org.springframework.web.multipart.MultipartFile;

import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.List;
import java.util.Map;

/**
 * Excel 工具類
 *
 * @author guoc
 * @date 2022年05月31日 下午 17:21
 */
public class ExcelUtils {

    /**
     * 下載 Excel 模板 (只有表頭的 Excel)
     *
     * @param response response
     * @param headers  表頭
     * @param fileName 文件名
     */
    public static void exportHeaders(HttpServletResponse response, List<String> headers, String fileName) {
        export(response, null, headers, fileName);
    }

    /**
     * 導出或下載 Excel 公用方法
     *
     * @param response 當前請求的 HttpServletResponse
     * @param rows     需要寫入的數據 List
     * @param fileName 最終文件名
     */
    public static void export(HttpServletResponse response, List<Map<String, Object>> rows, List<String> headers, String fileName) {
        // 獲取 Writer
        ExcelWriter writer = ExcelUtil.getWriter(true);
        // 寫入表頭
        writer = writer.writeHeadRow(headers);
        // 若是有數據 則寫入數據
        if (CollectionUtils.isNotEmpty(rows)) {
            writer.write(rows);
        }
        Workbook workbook = writer.getWorkbook();
        CellStyle defaultCellStyle = StyleUtil.createDefaultCellStyle(workbook);
        DataFormat format = writer.getWorkbook().createDataFormat();
        // 預設為 文本格式
        defaultCellStyle.setDataFormat(format.getFormat("@"));
        // 預設為 居中
        defaultCellStyle.setAlignment(HorizontalAlignment.CENTER);
        for (int i = 0; i < headers.size(); i++) {
            String h = headers.get(i);
            h = h == null ? " " : h;
            writer.setColumnStyle(i, defaultCellStyle);
            // 預設寬度為 3 * 表頭字元數
            writer.setColumnWidth(i, 3 * h.length());
        }
        try {
            // 彈出下載對話框的文件名,不能為中文,中文請自行編碼
            fileName = URLUtil.encode(fileName);
            response.setHeader("Access-Control-Expose-Headers", "Content-Disposition");
            response.setHeader("Content-Disposition", "attachment;filename=" + fileName + ".xlsx");
            response.setContentType(ExcelUtil.XLSX_CONTENT_TYPE);
            // 輸出
            ServletOutputStream out = response.getOutputStream();
            writer.flush(out, true);
            // 關閉writer,釋放記憶體
            writer.close();
            //此處記得關閉輸出Servlet流
            IoUtil.close(out);
        } catch (IOException e) {
            e.printStackTrace();
            throw new RRException(BaseErrorEnum.COMMON_ERROR, "下載文件失敗!\n" + e.getMessage());
        }
    }

    /**
     * 讀取上傳到後臺的excel
     *
     * @param file MultipartFile 上傳的文件
     * @return 數據列表
     * @throws IOException e
     */
    public static List<Map<String, Object>> readExcelRows(MultipartFile file) throws IOException {
        return ExcelUtil.getReader(file.getInputStream()).readAll();
    }
}

 

工具類封裝了三個方法, 只寫入表頭方法, 寫入表頭和數據方法 和 讀取表格數據列表方法。

三個方法的操作簡單,看代碼就能明白,不多贅述了。

複雜表頭或表格內合併單元格寫入

合併單元格核心方法

 

// cn.hutool.poi.excel.ExcelWriter#merge(int, int, int, int, java.lang.Object, boolean)
	/**
	 * 合併某行的單元格,並寫入對象到單元格<br>
	 * 如果寫到單元格中的內容非null,行號自動+1,否則當前行號不變<br>
	 * 樣式為預設標題樣式,可使用{@link #getHeadCellStyle()}方法調用後自定義預設樣式
	 *
	 * @param firstRow         起始行,0開始
	 * @param lastRow          結束行,0開始
	 * @param firstColumn      起始列,0開始
	 * @param lastColumn       結束列,0開始
	 * @param content          合併單元格後的內容
	 * @param isSetHeaderStyle 是否為合併後的單元格設置預設標題樣式,只提取邊框樣式
	 * @return this
	 * @since 4.0.10
	 */
    public ExcelWriter merge(int firstRow, int lastRow, int firstColumn, int lastColumn, Object content, boolean isSetHeaderStyle) {
		Assert.isFalse(this.isClosed, "ExcelWriter has been closed!");

		CellStyle style = null;
		if (null != this.styleSet) {
			style = styleSet.getStyleByValueType(content, isSetHeaderStyle);
		}

		return merge(firstRow, lastRow, firstColumn, lastColumn, content, style);
	}

 

看完一般表頭寫入的代碼,可以得知,此工具類寫入表頭時只需傳入表頭的字元串列表,即 List<String>,若是遇到動態表頭時,則可以通過遍歷的操作,先生成出導出數據中所有需要的表頭信息,即可為下一步的寫入數據的數據列表List<Map<String,Object>> 做準備了。

若是遇到某列或某些列中有合併單元格的,一般都有規律的,可以遍曆數據時根據合併的數據項內容通過合併單元格方法進行合併單元格操作。

總結

通過以上方法,可以處理絕大多數情況的導出寫入和基本所有的導入讀取(導入時的模板儘量規定為簡單表頭)。

寫入寫出數據基本上都使用的是Map<String,Object>,若是要轉成JavaBean,自行寫方法對應即可。


您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • csv的簡單介紹 CSV (Comma Separated Values),即逗號分隔值(也稱字元分隔值,因為分隔符可以不是逗號),是一種常用的文本格式,用以存儲表格數據,包括數字或者字元。很多程式在處理數據時都會碰到csv這種格式的文件。python自帶了csv模塊,專門用於處理csv文件的讀取 ...
  • 1、任務介紹 需求分析 爬取豆瓣電影Top250的基本信息,包括電影的名稱,豆瓣評分,評價數,電影概況,電影鏈接等。 https://movie.douban.com/top250 2、基本流程 2.1、準備工作 通過瀏覽器查看分析目標網頁,學習編程基礎規範 與Java的一些區別,Python沒有主 ...
  • 2022-09-30 F對象: 在shell中是用於兩個有關聯的屬性之間的查詢。 使用實例: 查詢書籍表中閱讀量大於評論量的記錄 前提,進入pycharm,進入虛擬環境,進入shell環境。 首先,要使用F對象,那麼就需要導入F對象 from django.db.models import F 後進 ...
  • 介紹了分散式鎖的特性,模擬想要實現redis分散式鎖的演變流程,分析redisson源碼是如何實現分散式鎖的,面對高併發下,我們該如何提升分散式鎖性能 ...
  • 1.冒泡排序(Bubble Sort) | 第0輪 | 3 | 1 | 4 | 1 | 5 | 9 | 2 | 6 | 5 | 3 | 5 | 8 | 9 | | | | | | | | | | | | | | | | | 第1輪 | 1 | 3 | 1 | 4 | 5 | 2 | 6 | 5 | ...
  • 前言 tkinter:GUI桌面應用開發模塊,寫軟體界面你還可以打包成exe軟體, 哪怕你沒有python環境, 一樣可以用雖然不一定要有界面, 但是有界面, 用戶體驗很棒… 環境使用 Python 3.8 Pycharm 模塊使用 import tkinter import webbrowser ...
  • 1、無論是淺拷貝還是深拷貝,拷貝對象後是否會開闢新記憶體,取決於被拷貝對象的數據類型是否可變,一般來講,可變的數據類型會開闢新記憶體,不可變數據類型反之不會開闢新記憶體,進行記憶體地址的引用(-5-256以外的大整數池會開闢記憶體,但我本地進行測試比較記憶體還是一樣的,有問題) 2、要在單層、嵌套型對象中逐一比 ...
  • 前言 環境使用 Python 3.8 Pycharm 模塊使用 import requests —> 數據請求模塊 pip install requests import parsel —> 數據解析模塊 pip install parsel from selenium import webdriv ...
一周排行
    -Advertisement-
    Play Games
  • 概述:在C#中,++i和i++都是自增運算符,其中++i先增加值再返回,而i++先返回值再增加。應用場景根據需求選擇,首碼適合先增後用,尾碼適合先用後增。詳細示例提供清晰的代碼演示這兩者的操作時機和實際應用。 在C#中,++i 和 i++ 都是自增運算符,但它們在操作上有細微的差異,主要體現在操作的 ...
  • 上次發佈了:Taurus.MVC 性能壓力測試(ap 壓測 和 linux 下wrk 壓測):.NET Core 版本,今天計劃準備壓測一下 .NET 版本,來測試並記錄一下 Taurus.MVC 框架在 .NET 版本的性能,以便後續持續優化改進。 為了方便對比,本文章的電腦環境和測試思路,儘量和... ...
  • .NET WebAPI作為一種構建RESTful服務的強大工具,為開發者提供了便捷的方式來定義、處理HTTP請求並返迴響應。在設計API介面時,正確地接收和解析客戶端發送的數據至關重要。.NET WebAPI提供了一系列特性,如[FromRoute]、[FromQuery]和[FromBody],用 ...
  • 原因:我之所以想做這個項目,是因為在之前查找關於C#/WPF相關資料時,我發現講解圖像濾鏡的資源非常稀缺。此外,我註意到許多現有的開源庫主要基於CPU進行圖像渲染。這種方式在處理大量圖像時,會導致CPU的渲染負擔過重。因此,我將在下文中介紹如何通過GPU渲染來有效實現圖像的各種濾鏡效果。 生成的效果 ...
  • 引言 上一章我們介紹了在xUnit單元測試中用xUnit.DependencyInject來使用依賴註入,上一章我們的Sample.Repository倉儲層有一個批量註入的介面沒有做單元測試,今天用這個示例來演示一下如何用Bogus創建模擬數據 ,和 EFCore 的種子數據生成 Bogus 的優 ...
  • 一、前言 在自己的項目中,涉及到實時心率曲線的繪製,項目上的曲線繪製,一般很難找到能直接用的第三方庫,而且有些還是定製化的功能,所以還是自己繪製比較方便。很多人一聽到自己畫就害怕,感覺很難,今天就分享一個完整的實時心率數據繪製心率曲線圖的例子;之前的博客也分享給DrawingVisual繪製曲線的方 ...
  • 如果你在自定義的 Main 方法中直接使用 App 類並啟動應用程式,但發現 App.xaml 中定義的資源沒有被正確載入,那麼問題可能在於如何正確配置 App.xaml 與你的 App 類的交互。 確保 App.xaml 文件中的 x:Class 屬性正確指向你的 App 類。這樣,當你創建 Ap ...
  • 一:背景 1. 講故事 上個月有個朋友在微信上找到我,說他們的軟體在客戶那邊隔幾天就要崩潰一次,一直都沒有找到原因,讓我幫忙看下怎麼回事,確實工控類的軟體環境複雜難搞,朋友手上有一個崩潰的dump,剛好丟給我來分析一下。 二:WinDbg分析 1. 程式為什麼會崩潰 windbg 有一個厲害之處在於 ...
  • 前言 .NET生態中有許多依賴註入容器。在大多數情況下,微軟提供的內置容器在易用性和性能方面都非常優秀。外加ASP.NET Core預設使用內置容器,使用很方便。 但是筆者在使用中一直有一個頭疼的問題:服務工廠無法提供請求的服務類型相關的信息。這在一般情況下並沒有影響,但是內置容器支持註冊開放泛型服 ...
  • 一、前言 在項目開發過程中,DataGrid是經常使用到的一個數據展示控制項,而通常表格的最後一列是作為操作列存在,比如會有編輯、刪除等功能按鈕。但WPF的原始DataGrid中,預設只支持固定左側列,這跟大家習慣性操作列放最後不符,今天就來介紹一種簡單的方式實現固定右側列。(這裡的實現方式參考的大佬 ...