最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

使用EasyPoi完成復(fù)雜一對多excel表格導(dǎo)出功能全過程

 更新時間:2022年12月12日 09:05:35   作者:南獨酌酒nvn  
這篇文章主要介紹了使用EasyPoi完成復(fù)雜一對多excel表格導(dǎo)出功能全過程,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教

業(yè)務(wù)需求

從一個簡單的倉庫業(yè)務(wù)說起,倉庫業(yè)務(wù),會有進庫記錄,會有出庫記錄,會有庫存,客戶的需求就是需要一個庫存盤點單,盤點單通俗來講:將庫存中每個商品的出入庫記錄都統(tǒng)計出來,看看每個商品出過多少貨物,入過多少貨物,本月庫存多少,上月庫存多少。

需求難點

一個貨物會出過多次貨物,入過多次貨物,導(dǎo)出的 excel 就要做成 一對多 格式的導(dǎo)出

簡單舉例:

啤酒:入庫2次,出庫3次,最終體現(xiàn)在 excel 中效果如下圖:

通過 EasyPoi 實現(xiàn)需求

EasyPoi 文檔地址:http://doc.wupaas.com/docs/easypoi/easypoi-1c0u4mo8p4ro8

SpringBoot 使用:

<dependency>
    <groupId>cn.afterturn</groupId>
    <artifactId>easypoi-base</artifactId>
    <version>4.2.0</version>
</dependency>
<dependency>
    <groupId>cn.afterturn</groupId>
    <artifactId>easypoi-annotation</artifactId>
    <version>4.2.0</version>
</dependency>
<dependency>
    <groupId>cn.afterturn</groupId>
    <artifactId>easypoi-web</artifactId>
    <version>4.2.0</version>
</dependency>

Gradle 使用:

implementation 'cn.afterturn:easypoi-base:4.2.0'
implementation 'cn.afterturn:easypoi-annotation:4.2.0'
implementation 'cn.afterturn:easypoi-web:4.2.0'

使用 EasyPoi 提供的注解,自定義導(dǎo)出類模板

import cn.afterturn.easypoi.excel.annotation.Excel;
import cn.afterturn.easypoi.excel.annotation.ExcelCollection;
import cn.afterturn.easypoi.excel.annotation.ExcelIgnore;
import lombok.Getter;
import lombok.Setter;

import java.io.Serializable;
import java.math.BigDecimal;
import java.util.Date;
import java.util.List;

/**
 * 導(dǎo)出 excel 模板類
 */
@Getter
@Setter
public class ExportTemplate implements Serializable {
    @Excel(name = "序號", needMerge = true, type = 10)
    private int index;
    
    @Excel(name = "商品名稱", needMerge = true, width = 30.0)
    private String goodName;
    
    @Excel(name = "商品單位", needMerge = true)
    private String goodUnit;
    
    @Excel(name = "上月庫存數(shù)量", needMerge = true, type = 10)
    private Integer lastMonthSurplusNum;
    
    @Excel(name = "本月庫存數(shù)量", needMerge = true, type = 10)
    private Integer thisMonthSurplusNum;
    
    @ExcelCollection(name = "本月入庫信息")
    private List<GoodInItem> goodInItems;
    
    @ExcelCollection(name = "本月出庫信息")
    private List<GoodOutItem> goodOutItems;
    
    @Excel(name = "備注", needMerge = true, width = 30.0)
    private String remark;

    /**
     * 入庫信息
     */
    @Getter
    @Setter
    public static class GoodInItem {
        @Excel(name = "入庫日期", exportFormat = "yyyy-MM-dd", width = 20.50)
        private Date purchaseDate;
        
        @Excel(name = "入庫號", width = 25.50)
        private String purchaseNum;
        
        @Excel(name = "入庫單價", type = 10)
        private BigDecimal unitPrice;
        
        @Excel(name = "入庫數(shù)量", type = 10)
        private Integer totalNum;
    }

    /**
     * 出庫信息
     */
    @Getter
    @Setter
    public static class GoodOutItem {
        @Excel(name = "出庫日期", exportFormat = "yyyy-MM-dd", width = 20.50)
        private Date outDate;
        
        @Excel(name = "出庫號", width = 25.50)
        private String sellNum;
        
        @Excel(name = "出庫數(shù)量", type = 10)
        private Integer totalNum;
        
        @Excel(name = "成本金額", type = 10)
        private BigDecimal priceIn;
        
        @Excel(name = "銷售金額", type = 10)
        private BigDecimal priceOut;
    }
}

實體類中使用的注解作用解釋:

  • 1.@Getter lombok 注解,用于給所有屬性提供 getter 方法
  • 2.@Setter lombok 注解,用于給所有屬性提供 setter 方法
  • 3.@Excel easypoi 注解,name 就等于導(dǎo)出 excel 的列名稱,width 就是寬度,type 就是這個屬性的類型,1表示文本,默認也是文本,10就是數(shù)字,needMerge 表示是否縱向合并單元格,也就是上下列合并
  • 4.@ExcelCollection easypoi 注解,name 就等于導(dǎo)出 excel 的列名稱,被此注解標注的集合,就等于在其列下面創(chuàng)建對等數(shù)量的行,就類似于這種

最后模板弄好之后,就可以通過easypoi 的工具類來導(dǎo)出,easypoi 推薦的導(dǎo)出工具類如下:

這個方法的三個參數(shù)表示含義解釋:

  • ExportParams :參數(shù)表示Excel 導(dǎo)出參數(shù)設(shè)置類,easypoi 自定義的類
  • pojoClass:你要導(dǎo)出的類模板
  • dataSet:數(shù)據(jù)集合

具體實現(xiàn)

@GetMapping(value = "export")
public void export(HttpServletRequest req, HttpServletResponse resp) {
	List<ExportTemplate> exportData = new ArrayList();
	// 步驟1:構(gòu)建要導(dǎo)出excel的數(shù)據(jù)集合
	for (int i = 0; i < 5; i++) {
		ExportTemplate data = new ExportTemplate();
        data.setIndex(i);
		data.setGoodName("測試商品");
		data.setGoodUnit("瓶");
		data.setLastMonthSurplusNum(5); // 上月庫存
		data.setThisMonthSurplusNum(3); // 本月庫存
		// ... 剩下的就是類似的加值
        exportData.add(data);
	}

	try {
		// 步驟2:開始導(dǎo)出 excel
		ExportParams params = new ExportParams();
		params.setTitle("庫存盤點單標題");
		params.setSheetName("庫存盤點單工作表名稱");
		params.setType(ExcelType.XSSF);
		Workbook workbook = ExcelExportUtil.exportExcel(params, ExportTemplate.class, exportData);
		
		String nowStr = DateTimeFormatter.ofPattern(LocalDateTime.now()).format("yyyyMMddHHmm"); // 時間串
		String fileName = nowStr + "_庫存盤點單"; // 文件名稱
		String tempDir = "C:/Users/huxim/Downloads";
		File filePath = new File(tempDir + File.separator);
		if (!filePath.exists()) filePath.mkdirs(); // 如果文件目錄不存在就創(chuàng)建這個目錄

		FileOutputStream fos = new FileOutputStream(tempDir + File.separator + fileName);
		workbook.write(fos);
		fos.close();

		resp.setContentType("application/octet-stream");
		resp.setCharacterEncoding("utf-8");
		response.addHeader("Content-disposition", "attachment; filename="
                    + this.makeDownloadFileName(req, fileName));
		IOUtils.copy(new FileInputStream(tempFile), response.getOutputStream());
		System.out.println("導(dǎo)出成功~~~");
	} catch (Exception e) {
		throw new RuntimeException("導(dǎo)出 excel 失敗~~~");
	}
}

/**
 * 判斷是否是 IE 瀏覽器
 * 返回對應(yīng)的字符串格式
 */
public static String makeDownloadFileName(HttpServletRequest request, String fileName) {
	String agent = request.getHeader("User-Agent");
    byte[] bytes = fileName.getBytes(StandardCharsets.UTF_8);
    if (agent.contains("MSIE") || agent.contains("Trident") || agent.contains("Edge")) {
    	// IE
        return new String(bytes, StandardCharsets.UTF_8);
	} else {
       	return new String(bytes, StandardCharsets.ISO_8859_1);
	}
}

導(dǎo)出成功后的excel 就類似于如下這種:

總結(jié)

以上為個人經(jīng)驗,希望能給大家一個參考,也希望大家多多支持腳本之家。

相關(guān)文章

  • Java 中的 Class.forName(類名) 使用及原理解析

    Java 中的 Class.forName(類名) 使用及原理解析

    Class.forName是Java中用于動態(tài)加載類的強大工具,廣泛應(yīng)用于數(shù)據(jù)庫驅(qū)動加載、反射機制和插件系統(tǒng)等場景,它通過ClassLoader加載類并執(zhí)行靜態(tài)初始化代碼,但在使用時需要注意類路徑、初始化副作用和類加載器的選擇等問題,感興趣的朋友一起看看吧
    2024-12-12
  • Java無需解壓直接讀取ZIP壓縮包里的文件及內(nèi)容

    Java無需解壓直接讀取ZIP壓縮包里的文件及內(nèi)容

    最近開發(fā)的時候遇到要獲取到zip壓縮包里面的文件內(nèi)容,解決方案就是通過ZipInputStream來讀取,下面通過實例代碼介紹Java無需解壓直接讀取ZIP壓縮包里的文件及內(nèi)容,感興趣的朋友跟隨小編一起看看吧
    2024-03-03
  • 重學(xué)SpringBoot3之日志Logging使用方式

    重學(xué)SpringBoot3之日志Logging使用方式

    在日常開發(fā)中會遇到不同的異常,日志方便我們?nèi)ヅ挪樘幚?這篇文章主要給大家介紹了關(guān)于重學(xué)SpringBoot3之日志Logging使用方式的相關(guān)資料,文中通過代碼介紹的非常詳細,需要的朋友可以參考下
    2024-06-06
  • Windows配置多版本JDK的詳細步驟

    Windows配置多版本JDK的詳細步驟

    JDK是Java開發(fā)工具包的縮寫,包含了Java編譯器、Java虛擬機、Java類庫等眾多組件,是Java開發(fā)的基石,提供了編寫、編譯和運行Java程序所必需的工具,有時候項目需要不同的JDK版本,所以本文給大家介紹了Windows配置多版本JDK的詳細步驟,需要的朋友可以參考下
    2025-04-04
  • 詳解如何把Java中if-else代碼重構(gòu)成高質(zhì)量代碼

    詳解如何把Java中if-else代碼重構(gòu)成高質(zhì)量代碼

    這篇文章主要介紹了詳解如何把Java中if-else代碼重構(gòu)成高質(zhì)量代碼,文中通過示例代碼介紹的非常詳細,對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2020-11-11
  • Java中正則表達式的語法以及matches方法的使用方法

    Java中正則表達式的語法以及matches方法的使用方法

    正則表達式(Regular Expression)是一門簡單語言的語法規(guī)范,是強大、便捷、高效的文本處理工具,這篇文章主要給大家介紹了關(guān)于Java中正則表達式的語法以及matches方法的使用方法,文中通過代碼介紹的非常詳細,需要的朋友可以參考下
    2024-05-05
  • 詳解Java如何簡化條件表達式

    詳解Java如何簡化條件表達式

    在復(fù)雜的實際業(yè)務(wù)中,往往會出現(xiàn)各種嵌套的條件判斷邏輯。隨著需求的增加,條件邏輯會變得越來越復(fù)雜。面對這種情況,簡化判斷邏輯就是不得不做的事情,下面為大家介紹幾種方法
    2022-06-06
  • Java類的加載時機與過程

    Java類的加載時機與過程

    這篇文章主要介紹了Java類的加載時機與過程,小編覺得挺不錯的,現(xiàn)在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧
    2021-12-12
  • Java雜談之類和對象 封裝 構(gòu)造方法以及代碼塊詳解

    Java雜談之類和對象 封裝 構(gòu)造方法以及代碼塊詳解

    在現(xiàn)實世界中,真實存在的東西,比如吉普車,卡丁車,貨車。我們在認識它的時候就會在腦海中將它抽象為一種類別叫做車。 好了,那再計算機世界中,它同樣的也會這樣做
    2021-09-09
  • spring boot如何使用POI讀取Excel文件

    spring boot如何使用POI讀取Excel文件

    本文主要介紹使用POI進行Excel文件的相關(guān)操作,涉及讀取文件,獲取sheet表格,對單元格內(nèi)容進行讀寫操作,以及合并單元格的操作
    2021-08-08

最新評論

龙口市| 咸阳市| 安塞县| 琼海市| 海宁市| 临朐县| 沾益县| 孟村| 耒阳市| 江都市| 肃宁县| 灌南县| 吉安县| 东兰县| 郑州市| 姜堰市| 依安县| 库伦旗| 昌江| 赤城县| 当雄县| 德阳市| 措勤县| 江口县| 荥阳市| 元朗区| 邵阳县| 白沙| 牟定县| 唐山市| 梁山县| 康保县| 依安县| 广丰县| 博罗县| 呼玛县| 兴山县| 黄大仙区| 民权县| 西充县| 潢川县|