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

Java?EasyExcel利用填充模版動(dòng)態(tài)生成多個(gè)sheet頁

 更新時(shí)間:2023年12月12日 09:22:56   作者:小王博客基地  
這篇文章主要為大家詳細(xì)介紹了Java?EasyExcel如何利用填充模版動(dòng)態(tài)生成多個(gè)sheet頁,文中的示例代碼講解詳細(xì),感興趣的小伙伴可以跟隨小編一起學(xué)習(xí)一下

一、前言

今天收到一個(gè)導(dǎo)出Excel的需求,這種需求經(jīng)常做,看到模版還是是有點(diǎn)復(fù)雜的有頭有行,一般的導(dǎo)出是不好做,使用模板填充比較簡單! 另外還有一個(gè)需求小編是第一次見,所以來記錄一下,為后來人鋪路!

需求:導(dǎo)出有單子的頭信息和一些多個(gè)行信息,前端可以多選,多個(gè)放在一個(gè)excel里的sheet中

明白了需求我們技術(shù)選型,現(xiàn)在基本都是EasyExcel用的比較多,今天使用的版本為:3.1.5,低版本已經(jīng)不維護(hù),建議使用高點(diǎn)的版本哈!

在這里先說一下,EasyExcel單獨(dú)是無法實(shí)現(xiàn)一個(gè)模版動(dòng)態(tài)填充多個(gè)sheet頁,所以我們使用POI來幫忙復(fù)制sheet頁即可!

二、準(zhǔn)備工作

1. 閹割版效果圖

我簡化了一些功能,自己做了一個(gè)簡單的模板,但是功能都是有的,大致如下圖所示:

多個(gè)就使用合同號作為sheet名稱,每個(gè)里面也會(huì)有多個(gè)行垂直填充即可!

2. 填充模版

3. 導(dǎo)入依賴

中間使用了Hutool來獲取流,很多公司不讓使用Hutool的,大家自己選擇,不使用可以用:

  • Spring的ResourceUtils.getFile()
  • JDK的new File()

本次使用Hutool的ClassPathResource

<dependency>
    <groupId>com.alibaba</groupId>
    <artifactId>easyexcel</artifactId>
    <version>3.1.5</version>
</dependency>
<dependency>
    <groupId>cn.hutool</groupId>
    <artifactId>hutool-all</artifactId>
    <version>5.8.4</version>
</dependency>

4. 導(dǎo)出實(shí)體

/**
 * @author wangzhenjun
 * @date 2023/7/4 17:09
 */
@Data
public class TestExcel {

    private String contractNo;

    private String address;
    
	private String dateTime;

    private List<Item> itemList;

    @Data
    public static class Item{

        private String name;

        private BigDecimal price;
    }
}

三、實(shí)戰(zhàn)代碼

為了方便直接寫在Controller里了,大家不要學(xué)習(xí)哈,業(yè)務(wù)的處理還是要在service里寫!

整體思路:

使用POIXSSFWorkbook 來根據(jù)要導(dǎo)出的個(gè)數(shù)來進(jìn)行復(fù)制sheet頁,名稱為合同號

將復(fù)制好的sheet頁轉(zhuǎn)換成字節(jié)數(shù)組,然后再通過輸入流的方式讀取字節(jié)數(shù)組中的數(shù)據(jù)。

EasyExcel 將使用輸入流中的模板數(shù)據(jù)生成 Excel 數(shù)據(jù),并將生成的 Excel 文件寫入到 HttpServletResponse 的輸出流中,以便將其發(fā)送給客戶端進(jìn)行下載或其他處理。

創(chuàng)建一個(gè) WriteSheet 對象,并將其與上面復(fù)制的sheet頁名稱關(guān)聯(lián),就可以往里面填充數(shù)據(jù)了!

如果有這種list多個(gè)行填充的并且list不是最后一行,下面還有數(shù)據(jù)需要填充 就必須設(shè)置 forceNewRow=true

不加的話會(huì)把你后面的內(nèi)容給覆蓋了!

但是這個(gè)就會(huì)把所有數(shù)據(jù)放到內(nèi)存 會(huì)很耗內(nèi)存!

用完記得把流關(guān)閉哈!

@SneakyThrows
@GetMapping("/excel")
public void excel (HttpServletResponse response){
    int size = 2;
    List<TestExcel> testExcels = new ArrayList<>();
    for (int i = 0; i < size; i++) {
        TestExcel testExcel = new TestExcel();
        testExcel.setContractNo("HT07040" + (i + 1));
        testExcel.setAddress("青島" + i + "號基地");
        testExcel.setDateTime("2023-07-05");
        testExcels.add(testExcel);
        List<TestExcel.Item> itemList = new ArrayList<>();
        for (int j = 0; j < size; j++) {
            TestExcel.Item item = new TestExcel.Item();
            item.setName("商品" + (j + 1));
            item.setPrice(new BigDecimal("188").multiply(new BigDecimal(j + 1)));
            itemList.add(item);
        }
        testExcel.setItemList(itemList);
    }
    response.setCharacterEncoding("utf-8");
    String fileName = URLEncoder.encode("測試", "UTF-8").replaceAll("\\+", "%20");
    response.setHeader("Content-disposition", "attachment;filename*=utf-8''" + fileName + ".xlsx");
    ClassPathResource classPathResource = new ClassPathResource("template" + File.separator + "測試.xlsx");
    InputStream stream = classPathResource.getStream();
    // 把excel流給這個(gè)對象,后續(xù)可以操作
    XSSFWorkbook workbook = new XSSFWorkbook(stream);
    // 設(shè)置模板的第一個(gè)sheet的名稱,名稱我們使用合同號
    workbook.setSheetName(0, testExcels.get(0).getContractNo());
    for (int i = 1; i < size; i++) {
        // 剩余的全部復(fù)制模板sheet0即可
        workbook.cloneSheet(0, testExcels.get(i).getContractNo());
    }
    // 把workbook寫到流里
    ByteArrayOutputStream baos = new ByteArrayOutputStream();
    workbook.write(baos);
    byte[] bytes = baos.toByteArray();
    stream = new ByteArrayInputStream(bytes);
    ExcelWriter excelWriter = EasyExcel.write(response.getOutputStream()).withTemplate(stream).build();

    for (TestExcel testExcel : testExcels) {
        WriteSheet writeSheet = EasyExcel.writerSheet(testExcel.getContractNo()).build();
        // list不是最后一行,下面還有數(shù)據(jù)需要填充 就必須設(shè)置 forceNewRow=true 但是這個(gè)就會(huì)把所有數(shù)據(jù)放到內(nèi)存 會(huì)很耗內(nèi)存
        FillConfig fillConfig = FillConfig.builder().forceNewRow(Boolean.TRUE).direction(WriteDirectionEnum.VERTICAL).build();
        excelWriter.fill(testExcel, writeSheet);
        excelWriter.fill(new FillWrapper("item", testExcel.getItemList()), fillConfig, writeSheet);
    }
    excelWriter.finish();
    baos.close();
    stream.close();
}

四、總結(jié)

這樣就完成了,主要的難點(diǎn)是復(fù)制sheet頁,多行填充在EasyExcel官網(wǎng)都是有的,還有一些我這邊沒有用到的東西,大家可以根據(jù)自己的需求去找找看!

到此這篇關(guān)于Java EasyExcel利用填充模版動(dòng)態(tài)生成多個(gè)sheet頁的文章就介紹到這了,更多相關(guān)Java EasyExcel生成多個(gè)sheet內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • SpringBoot WebService服務(wù)端&客戶端使用案例教程

    SpringBoot WebService服務(wù)端&客戶端使用案例教程

    這篇文章主要介紹了SpringBoot WebService服務(wù)端&客戶端使用案例教程,本文通過實(shí)例代碼給大家介紹的非常詳細(xì),對大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友參考下吧
    2023-10-10
  • java list集合排序按某一屬性排序操作

    java list集合排序按某一屬性排序操作

    這篇文章主要介紹了java list集合排序按某一屬性排序操作,具有很好的參考價(jià)值,希望對大家有所幫助。一起跟隨小編過來看看吧
    2020-08-08
  • Kotlin修飾符lateinit(延遲初始化)案例詳解

    Kotlin修飾符lateinit(延遲初始化)案例詳解

    這篇文章主要介紹了Kotlin修飾符lateinit(延遲初始化)案例詳解,本篇文章通過簡要的案例,講解了該項(xiàng)技術(shù)的了解與使用,以下就是詳細(xì)內(nèi)容,需要的朋友可以參考下
    2021-09-09
  • Spring IO Platform簡單介紹

    Spring IO Platform簡單介紹

    這篇文章主要介紹了Spring IO Platform簡單介紹,具有一定借鑒價(jià)值,需要的朋友可以參考下
    2017-12-12
  • Java內(nèi)存模型知識匯總

    Java內(nèi)存模型知識匯總

    本文中,有很多定義和說法,都是筆者自己理解后定義出來的。希望能夠讓讀者可以對Java內(nèi)存模型有更加清晰的認(rèn)識。當(dāng)然,如有偏頗,歡迎指正。
    2018-09-09
  • 解決MyBatis中模糊搜索使用like匹配帶%字符時(shí)失效問題

    解決MyBatis中模糊搜索使用like匹配帶%字符時(shí)失效問題

    Mybatis是我們?nèi)粘m?xiàng)目中經(jīng)常使用的框架,在項(xiàng)目中我們一般會(huì)使用like查詢作為模糊匹配字符進(jìn)行搜索匹配,下面的Mapper.xml是我們使用like在項(xiàng)目中進(jìn)行模糊匹配的常用方式,感興趣的朋友跟隨小編一起看看吧
    2021-09-09
  • 如何通過Java生成一個(gè)隨機(jī)數(shù)

    如何通過Java生成一個(gè)隨機(jī)數(shù)

    當(dāng)我們需要在Java中生成隨機(jī)數(shù)時(shí),可以借助JDK中提供的Random類來實(shí)現(xiàn),通過使用Random類,我們可以輕松地生成各種類型的隨機(jī)數(shù),下面我們就來看看如何利用Random類生成隨機(jī)數(shù)吧
    2023-09-09
  • java中char對應(yīng)的ASCII碼的轉(zhuǎn)化操作

    java中char對應(yīng)的ASCII碼的轉(zhuǎn)化操作

    這篇文章主要介紹了java中char對應(yīng)的ASCII碼的轉(zhuǎn)化操作,具有很好的參考價(jià)值,希望對大家有所幫助。一起跟隨小編過來看看吧
    2020-08-08
  • Java中的WeakHashMap淺析

    Java中的WeakHashMap淺析

    這篇文章主要介紹了Java中的WeakHashMap淺析,weakhashmap關(guān)鍵是:當(dāng)一個(gè)對象被GC回收時(shí),響應(yīng)的值對象的引用從map中刪除,weakhashmap能節(jié)約存儲(chǔ)空間,來實(shí)現(xiàn)緩存那些非必要的數(shù)據(jù),需要的朋友可以參考下
    2023-09-09
  • 通過java備份恢復(fù)mysql數(shù)據(jù)庫的實(shí)現(xiàn)代碼

    通過java備份恢復(fù)mysql數(shù)據(jù)庫的實(shí)現(xiàn)代碼

    這篇文章主要介紹了如何通過java備份恢復(fù)mysql數(shù)據(jù)庫,其實(shí)一般情況下通過bat或sh就可以,這里主要是介紹了java的實(shí)現(xiàn)思路,喜歡的朋友可以參考下
    2013-09-09

最新評論

图木舒克市| 武强县| 瑞安市| 嵊州市| 沙洋县| 庆云县| 油尖旺区| 凤庆县| 古田县| 灵丘县| 舟山市| 鄯善县| 牙克石市| 易门县| 皮山县| 威信县| 吉安市| 安乡县| 双江| 垣曲县| 长乐市| 邮箱| 通榆县| 自贡市| 长春市| 崇礼县| 济源市| 阆中市| 霞浦县| 同心县| 应用必备| 柏乡县| 会宁县| 中宁县| 邵东县| 博罗县| 洮南市| 洛川县| 共和县| 侯马市| 萨嘎县|