欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

Java?EasyExcel實現(xiàn)合并相同內(nèi)容單元格與動態(tài)標(biāo)題功能

 更新時間:2023年12月20日 08:43:11   作者:myprince003  
這篇文章主要為大家詳細(xì)介紹了Java?EasyExcel如何實現(xiàn)合并相同內(nèi)容單元格與動態(tài)標(biāo)題功能,文中的示例代碼講解詳細(xì),有需要的小伙伴可以參考下

一、最初版本

導(dǎo)出的結(jié)果:

對應(yīng)實體類代碼:

import com.alibaba.excel.annotation.ExcelProperty;
import com.alibaba.excel.annotation.write.style.ColumnWidth;
import com.alibaba.excel.annotation.write.style.ContentLoopMerge;
import com.alibaba.excel.annotation.write.style.ContentRowHeight;
import com.alibaba.excel.annotation.write.style.HeadRowHeight;
import lombok.*;

import java.io.Serializable;

@Getter
@Setter
@NoArgsConstructor
@AllArgsConstructor
@Data
@ContentRowHeight(30)
@HeadRowHeight(40)
@ColumnWidth(25)
public class StudentExportVo implements Serializable {

    private static final long serialVersionUID = -5809782578272943999L;

    @ExcelProperty(value = "學(xué)校", order = 1)
    @ContentLoopMerge(eachRow = 3)
    private String school;

    @ExcelProperty(value = "姓名", order = 2)
    private String name;

    @ExcelProperty(value = "性別", order = 3)
    private String sex;

    @ExcelProperty(value = "年齡", order = 4)
    private String age;

    @ExcelProperty(value = "城市", order = 5)
    private String city;

    @ExcelProperty(value = "備注", order = 6)
    private String remarks;

    }

對應(yīng)業(yè)務(wù)代碼:

@ApiOperation(value = "導(dǎo)出學(xué)生信息", notes = "導(dǎo)出學(xué)生信息")
@PostMapping("/exportStudent")
public void exportStudent(@RequestBody String str, HttpServletResponse response) {
    List<StudentExportVo> list = this.getStudentExportVos();
    ExcelUtils.writeExcel(response, StudentExportVo.class, list, "導(dǎo)出學(xué)生信息", "sheet1");
}
//數(shù)據(jù)制造
private List<StudentExportVo> getStudentExportVos() {
    List<StudentExportVo> list = new ArrayList<>();
    StudentExportVo v1 = new StudentExportVo();
    v1.setSchool("北京大學(xué)");
    v1.setName("張三");
    v1.setSex("男");
    v1.setAge("20");
    v1.setCity("北京");
    v1.setRemarks("無");
    list.add(v1);
    StudentExportVo v2 = new StudentExportVo();
    v2.setSchool("北京大學(xué)");
    v2.setName("李四");
    v2.setSex("男");
    v2.setAge("22");
    v2.setCity("上海");
    v2.setRemarks("無");
    list.add(v2);
    StudentExportVo v3 = new StudentExportVo();
    v3.setSchool("北京大學(xué)");
    v3.setName("王五");
    v3.setSex("女");
    v3.setAge("22");
    v3.setCity("青島");
    v3.setRemarks("無");
    list.add(v3);
    StudentExportVo v4 = new StudentExportVo();
    v4.setSchool("清華大學(xué)");
    v4.setName("趙六");
    v4.setSex("女");
    v4.setAge("21");
    v4.setCity("重慶");
    v4.setRemarks("無");
    list.add(v4);
    StudentExportVo v5 = new StudentExportVo();
    v5.setSchool("武漢大學(xué)");
    v5.setName("王強(qiáng)");
    v5.setSex("男");
    v5.setAge("24");
    v5.setCity("長沙");
    v5.setRemarks("無");
    list.add(v5);
    StudentExportVo v6 = new StudentExportVo();
    v6.setSchool("武漢大學(xué)");
    v6.setName("趙燕");
    v6.setSex("女");
    v6.setAge("21");
    v6.setCity("深圳");
    v6.setRemarks("無");
    list.add(v6);
    StudentExportVo v7 = new StudentExportVo();
    v7.setSchool("廈門大學(xué)");
    v7.setName("陸仟");
    v7.setSex("女");
    v7.setAge("21");
    v7.setCity("廣州");
    v7.setRemarks("無");
    list.add(v7);
    return list;
}

二、使用注解的版本

導(dǎo)出的結(jié)果:

對應(yīng)實體類代碼:

@Getter
@Setter
@NoArgsConstructor
@AllArgsConstructor
@Data
@ContentRowHeight(30)
@HeadRowHeight(40)
@ColumnWidth(25)
public class StudentExportVo implements Serializable {

    private static final long serialVersionUID = -5809782578272943999L;

    @ExcelProperty(value = {"學(xué)生信息","學(xué)校"}, order = 1)
    @ContentLoopMerge(eachRow = 3)
    private String school;

    @ExcelProperty(value = {"學(xué)生信息","姓名"}, order = 2)
    private String name;

    @ExcelProperty(value = {"學(xué)生信息","性別"}, order = 3)
    private String sex;

    @ExcelProperty(value = {"學(xué)生信息","年齡"}, order = 4)
    private String age;

    @ExcelProperty(value = {"學(xué)生信息","城市"}, order = 5)
    private String city;

    @ExcelProperty(value = {"學(xué)生信息","備注"}, order = 6)
    private String remarks;

    }

對應(yīng)業(yè)務(wù)代碼:同上

@ContentLoopMerge(eachRow = 3) 可以合并單元格,但是他是按指定行數(shù)合并,并不能實現(xiàn)內(nèi)容相同的合并

@ExcelProperty(value = {“學(xué)生信息”,“備注”},能實現(xiàn)多個標(biāo)題,但標(biāo)題是固定的,不是動態(tài)的

三、自定義改造

導(dǎo)出的結(jié)果:

對應(yīng)實體類代碼:

@Getter
@Setter
@NoArgsConstructor
@AllArgsConstructor
@Data
@ContentRowHeight(30)
@HeadRowHeight(40)
@ColumnWidth(25)
public class StudentExportVo implements Serializable {

    private static final long serialVersionUID = -5809782578272943999L;

    @ExcelProperty(value = {"學(xué)生信息","學(xué)校"}, order = 1)
    //@ContentLoopMerge(eachRow = 3)
    private String school;

    @ExcelProperty(value = {"學(xué)生信息","姓名"}, order = 2)
    private String name;

    @ExcelProperty(value = {"學(xué)生信息","性別"}, order = 3)
    private String sex;

    @ExcelProperty(value = {"學(xué)生信息","年齡"}, order = 4)
    private String age;

    @ExcelProperty(value = {"學(xué)生信息","城市"}, order = 5)
    private String city;

    @ExcelProperty(value = {"學(xué)生信息","備注"}, order = 6)
    private String remarks;

}

對應(yīng)業(yè)務(wù)代碼:

@ApiOperation(value = "導(dǎo)出學(xué)生信息", notes = "導(dǎo)出學(xué)生信息")
    @PostMapping("/exportStudent")
    public void exportStudent(@RequestBody String dynamicTitle, HttpServletResponse response) {
        List<StudentExportVo> list = this.getStudentExportVos();
        try {
            String fileName = "學(xué)生信息";
            fileName = URLEncoder.encode(fileName, "UTF-8");
            response.setContentType("application/json;charset=utf-8");
            response.setCharacterEncoding("utf-8");
            response.addHeader("Pargam", "no-cache");
            response.addHeader("Cache-Control", "no-cache");
            response.setHeader("Content-Disposition", "attachment;filename=" + fileName + ".xlsx");
            ServletOutputStream output = response.getOutputStream();
            //需要合并的列
            int[] mergeColumeIndex = {0};
            // 從第二行后開始合并
            int mergeRowIndex = 2;
            //設(shè)置動態(tài)標(biāo)題
            List<List<String>> headers = this.getHeaders("學(xué)生信息" + dynamicTitle);
            // 頭的策略
            WriteCellStyle headWriteCellStyle = new WriteCellStyle();
            // 背景設(shè)置為白色
            headWriteCellStyle.setFillForegroundColor(IndexedColors.WHITE.getIndex());
            headWriteCellStyle.setHorizontalAlignment(HorizontalAlignment.CENTER);
            /*WriteFont headWriteFont = new WriteFont();
            headWriteFont.setFontHeightInPoints((short)20);
            headWriteCellStyle.setWriteFont(headWriteFont);*/

            // 內(nèi)容的策略
            WriteCellStyle contentWriteCellStyle = new WriteCellStyle();
            // 這里需要指定 FillPatternType 為FillPatternType.SOLID_FOREGROUND 不然無法顯示背景顏色.頭默認(rèn)了 FillPatternType所以可以不指定
            //contentWriteCellStyle.setFillPatternType(FillPatternType.SOLID_FOREGROUND);
            // 背景綠色
            //contentWriteCellStyle.setFillForegroundColor(IndexedColors.WHITE.getIndex());
            //設(shè)置 自動換行
            contentWriteCellStyle.setWrapped(true);
            //設(shè)置 垂直居中
            contentWriteCellStyle.setVerticalAlignment(VerticalAlignment.CENTER);
            //設(shè)置 水平居中
            contentWriteCellStyle.setHorizontalAlignment(HorizontalAlignment.CENTER);
            /*WriteFont contentWriteFont = new WriteFont();
            // 字體大小
            contentWriteFont.setFontHeightInPoints((short)20);
            contentWriteCellStyle.setWriteFont(contentWriteFont);*/
            // 這個策略是 頭是頭的樣式 內(nèi)容是內(nèi)容的樣式 其他的策略可以自己實現(xiàn)
            HorizontalCellStyleStrategy horizontalCellStyleStrategy =
                    new HorizontalCellStyleStrategy(headWriteCellStyle, contentWriteCellStyle);

            EasyExcel.write(output, StudentExportVo.class)
                    .sheet("學(xué)生信息")
                    .head(headers)
                    .registerWriteHandler(new ExcelMergeHandler(mergeRowIndex, mergeColumeIndex))
                    .registerWriteHandler(horizontalCellStyleStrategy)
//                    .registerWriteHandler(new SimpleColumnWidthStyleStrategy(30))
                    .registerWriteHandler(new AbstractColumnWidthStyleStrategy() {
                        @Override
                        protected void setColumnWidth(WriteSheetHolder writeSheetHolder, List<CellData> list, Cell cell, Head head, Integer integer, Boolean aBoolean) {
                            Sheet sheet = writeSheetHolder.getSheet();
                            int columnIndex = cell.getColumnIndex();
                            if(columnIndex == 5){
                                // 列寬100
                                sheet.setColumnWidth(columnIndex, 10000);
                            }else {
                                // 列寬50
                                sheet.setColumnWidth(columnIndex, 5000);
                            }
                            // 行高40
                            sheet.setDefaultRowHeight((short) 4000);
                        }
                    })
                    .doWrite(list);
            output.flush();
        } catch (IOException e) {
            log.error(e.getMessage(), e);
        }
    }


    private List<List<String>> getHeaders(String dynamicTitle) {
        List<List<String>> headers=new ArrayList<>();
        List<String> schoolHead=new ArrayList<>();
        schoolHead.add(dynamicTitle);
        schoolHead.add("學(xué)校");
        List<String> nameHead=new ArrayList<>();
        nameHead.add(dynamicTitle);
        nameHead.add("姓名");
        List<String> sexHead=new ArrayList<>();
        sexHead.add(dynamicTitle);
        sexHead.add("性別");
        List<String> ageHead=new ArrayList<>();
        ageHead.add(dynamicTitle);
        ageHead.add("年齡");
        List<String> cityHead=new ArrayList<>();
        cityHead.add(dynamicTitle);
        cityHead.add("城市");
        List<String> remarksHead=new ArrayList<>();
        remarksHead.add(dynamicTitle);
        remarksHead.add("備注");
        headers.add(schoolHead);
        headers.add(nameHead);
        headers.add(sexHead);
        headers.add(ageHead);
        headers.add(cityHead);
        headers.add(remarksHead);
        return headers;
    }

    //數(shù)據(jù)制造
    private List<StudentExportVo> getStudentExportVos() {
        List<StudentExportVo> list = new ArrayList<>();
        StudentExportVo v1 = new StudentExportVo();
        v1.setSchool("北京大學(xué)");
        v1.setName("張三");
        v1.setSex("男");
        v1.setAge("20");
        v1.setCity("北京");
        v1.setRemarks("無");
        list.add(v1);
        StudentExportVo v2 = new StudentExportVo();
        v2.setSchool("北京大學(xué)");
        v2.setName("李四");
        v2.setSex("男");
        v2.setAge("22");
        v2.setCity("上海");
        v2.setRemarks("無");
        list.add(v2);
        StudentExportVo v3 = new StudentExportVo();
        v3.setSchool("北京大學(xué)");
        v3.setName("王五");
        v3.setSex("女");
        v3.setAge("22");
        v3.setCity("青島");
        v3.setRemarks("無");
        list.add(v3);
        StudentExportVo v4 = new StudentExportVo();
        v4.setSchool("清華大學(xué)");
        v4.setName("趙六");
        v4.setSex("女");
        v4.setAge("21");
        v4.setCity("重慶");
        v4.setRemarks("無");
        list.add(v4);
        StudentExportVo v5 = new StudentExportVo();
        v5.setSchool("武漢大學(xué)");
        v5.setName("王強(qiáng)");
        v5.setSex("男");
        v5.setAge("24");
        v5.setCity("長沙");
        v5.setRemarks("無");
        list.add(v5);
        StudentExportVo v6 = new StudentExportVo();
        v6.setSchool("武漢大學(xué)");
        v6.setName("趙燕");
        v6.setSex("女");
        v6.setAge("21");
        v6.setCity("深圳");
        v6.setRemarks("無");
        list.add(v6);
        StudentExportVo v7 = new StudentExportVo();
        v7.setSchool("廈門大學(xué)");
        v7.setName("陸仟");
        v7.setSex("女");
        v7.setAge("21");
        v7.setCity("廣州");
        v7.setRemarks("無");
        list.add(v7);
        return list;
    }

合并單元格相同內(nèi)容處理類:ExcelMergeHandler

import com.alibaba.excel.metadata.CellData;
import com.alibaba.excel.metadata.Head;
import com.alibaba.excel.write.handler.CellWriteHandler;
import com.alibaba.excel.write.metadata.holder.WriteSheetHolder;
import com.alibaba.excel.write.metadata.holder.WriteTableHolder;
import org.apache.poi.ss.usermodel.Cell;
import org.apache.poi.ss.usermodel.CellType;
import org.apache.poi.ss.usermodel.Row;
import org.apache.poi.ss.usermodel.Sheet;
import org.apache.poi.ss.util.CellRangeAddress;

import java.util.List;
public class ExcelMergeHandler implements CellWriteHandler {
    private int[] mergeColumnIndex;
    private int mergeRowIndex;

    public ExcelMergeHandler() {
    }

    public ExcelMergeHandler(int mergeRowIndex, int[] mergeColumnIndex) {
        this.mergeRowIndex = mergeRowIndex;
        this.mergeColumnIndex = mergeColumnIndex;
    }

    @Override
    public void beforeCellCreate(WriteSheetHolder writeSheetHolder, WriteTableHolder writeTableHolder, Row row, Head head, Integer columnIndex, Integer relativeRowIndex, Boolean isHead) {

    }

    @Override
    public void afterCellCreate(WriteSheetHolder writeSheetHolder, WriteTableHolder writeTableHolder, Cell cell, Head head, Integer relativeRowIndex, Boolean isHead) {

    }

    @Override
    public void afterCellDataConverted(WriteSheetHolder writeSheetHolder, WriteTableHolder writeTableHolder, CellData cellData, Cell cell, Head head, Integer relativeRowIndex, Boolean isHead) {

    }

    @Override
    public void afterCellDispose(WriteSheetHolder writeSheetHolder, WriteTableHolder writeTableHolder, List<CellData> cellDataList, Cell cell, Head head, Integer relativeRowIndex, Boolean isHead) {

        //當(dāng)前行
        int curRowIndex = cell.getRowIndex();
        //當(dāng)前列
        int curColIndex = cell.getColumnIndex();

        if (curRowIndex > mergeRowIndex) {
            for (int i = 0; i < mergeColumnIndex.length; i++) {
                if (curColIndex == mergeColumnIndex[i]) {
                    mergeWithPrevRow(writeSheetHolder, cell, curRowIndex, curColIndex);
                    break;
                }
            }
        }
    }



 /**
     * 當(dāng)前單元格向上合并
     *
     * @param writeSheetHolder
     * @param cell             當(dāng)前單元格
     * @param curRowIndex      當(dāng)前行
     * @param curColIndex      當(dāng)前列
     */
    private void mergeWithPrevRow(WriteSheetHolder writeSheetHolder, Cell cell, int curRowIndex, int curColIndex) {
        Object curData = cell.getCellTypeEnum() == CellType.STRING ? cell.getStringCellValue() : cell.getNumericCellValue();
        Cell preCell = cell.getSheet().getRow(curRowIndex - 1).getCell(curColIndex);
        Object preData = preCell.getCellTypeEnum() == CellType.STRING ? preCell.getStringCellValue() : preCell.getNumericCellValue();
        // 將當(dāng)前單元格數(shù)據(jù)與上一個單元格數(shù)據(jù)比較
        Boolean dataBool = preData.equals(curData);
        //此處需要注意:因為我是按照工程名稱確定是否需要合并的,所以獲取每一行第二列數(shù)據(jù)和上一行第一列數(shù)據(jù)進(jìn)行比較,如果相等合并,getCell里面的值,是工程名稱所在列的下標(biāo)
        String s1 = cell.getRow().getCell(0).getStringCellValue();
        String s2 = cell.getSheet().getRow(curRowIndex - 1).getCell(0).getStringCellValue();
        /*BigDecimal d1 = new BigDecimal(cell.getRow().getCell(0).getNumericCellValue());
        BigDecimal d2 = new BigDecimal(cell.getSheet().getRow(curRowIndex - 1).getCell(0).getNumericCellValue());*/
        Boolean bool = s1.compareTo(s2) == 0 ? true:false;
        // 原始的
        // Boolean bool =  cell.getRow().getCell(1).getStringCellValue().equals(cell.getSheet().getRow(curRowIndex - 1).getCell(1).getStringCellValue());
        if (dataBool && bool) {
            Sheet sheet = writeSheetHolder.getSheet();
            List<CellRangeAddress> mergeRegions = sheet.getMergedRegions();
            boolean isMerged = false;
            for (int i = 0; i < mergeRegions.size() && !isMerged; i++) {
                CellRangeAddress cellRangeAddr = mergeRegions.get(i);
                // 若上一個單元格已經(jīng)被合并,則先移出原有的合并單元,再重新添加合并單元
                if (cellRangeAddr.isInRange(curRowIndex - 1, curColIndex)) {
                    sheet.removeMergedRegion(i);
                    cellRangeAddr.setLastRow(curRowIndex);
                    sheet.addMergedRegion(cellRangeAddr);
                    isMerged = true;
                }
            }
            // 若上一個單元格未被合并,則新增合并單元
            if (!isMerged) {
                CellRangeAddress cellRangeAddress = new CellRangeAddress(curRowIndex - 1, curRowIndex, curColIndex, curColIndex);
                sheet.addMergedRegion(cellRangeAddress);
            }
        }
    }
}

總結(jié):

1、使用自定義合并相同內(nèi)容單元格時,實體類中的注解@ContentLoopMerge需要去掉,要不然會受到影響

2、該段自定義代碼中如內(nèi)容合并、設(shè)置動態(tài)標(biāo)題、內(nèi)容、以及每個列的寬度及字體都是可以根據(jù)自定義策略來進(jìn)行設(shè)置的,具體用法可以參考代碼注釋說明,根據(jù)需要進(jìn)行使用

以上就是Java EasyExcel實現(xiàn)合并相同內(nèi)容單元格與動態(tài)標(biāo)題功能的詳細(xì)內(nèi)容,更多關(guān)于Java EasyExcel合并單元格的資料請關(guān)注腳本之家其它相關(guān)文章!

相關(guān)文章

  • Springboot使用redisson?+?自定義注解實現(xiàn)消息的發(fā)布訂閱(解決方案)

    Springboot使用redisson?+?自定義注解實現(xiàn)消息的發(fā)布訂閱(解決方案)

    Redisson是一個基于Redis的Java駐留內(nèi)存數(shù)據(jù)網(wǎng)格(In-Memory?Data?Grid)和分布式鎖框架,它提供了一系列的分布式Java對象和服務(wù),可以幫助開發(fā)者更方便地使用Redis作為數(shù)據(jù)存儲和分布式鎖的解決方案,感興趣的朋友跟隨小編一起看看吧
    2024-05-05
  • Java 數(shù)組交集的實現(xiàn)代碼

    Java 數(shù)組交集的實現(xiàn)代碼

    這篇文章主要介紹了Java 數(shù)組交集的實現(xiàn)代碼,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2019-09-09
  • jdbc中class.forname的作用

    jdbc中class.forname的作用

    這篇文章主要介紹了jdbc中class.forname的作用,使用示例說明了他作用及使用方法,大家參考使用吧
    2014-01-01
  • 利用github搭建個人maven倉庫的方法步驟

    利用github搭建個人maven倉庫的方法步驟

    這篇文章主要介紹了利用github搭建個人maven倉庫的方法步驟,小編覺得挺不錯的,現(xiàn)在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧
    2018-12-12
  • Java和MySQL數(shù)據(jù)庫中關(guān)于小數(shù)的保存問題詳析

    Java和MySQL數(shù)據(jù)庫中關(guān)于小數(shù)的保存問題詳析

    在Java和MySQL中小數(shù)的精度可能會受到限制,如float類型的小數(shù)只能精確到6-7位,double類型也只能精確到15-16位,這篇文章主要給大家介紹了關(guān)于Java和MySQL數(shù)據(jù)庫中關(guān)于小數(shù)的保存問題,需要的朋友可以參考下
    2024-01-01
  • 三道java新手入門面試題,通往自由的道路--鎖+Volatile

    三道java新手入門面試題,通往自由的道路--鎖+Volatile

    這篇文章主要為大家分享了最有價值的3道多線程面試題,涵蓋內(nèi)容全面,包括數(shù)據(jù)結(jié)構(gòu)和算法相關(guān)的題目、經(jīng)典面試編程題等,對hashCode方法的設(shè)計、垃圾收集的堆和代進(jìn)行剖析,感興趣的小伙伴們可以參考一下
    2021-07-07
  • java8?時間日期的使用與格式化示例代碼詳解

    java8?時間日期的使用與格式化示例代碼詳解

    這篇文章主要介紹了java8?時間日期的使用與格式化,本文通過示例代碼給大家介紹的非常詳細(xì),對大家的學(xué)習(xí)或工作具有一定的參考借鑒價值,需要的朋友可以參考下
    2022-06-06
  • java去除空格、標(biāo)點符號的方法實例

    java去除空格、標(biāo)點符號的方法實例

    這篇文章主要給大家介紹了關(guān)于java去除空格、標(biāo)點符號的相關(guān)資料,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2020-09-09
  • Springboot解決ajax+自定義headers的跨域請求問題

    Springboot解決ajax+自定義headers的跨域請求問題

    由于瀏覽器同源策略(同源策略,它是由Netscape提出的一個著名的安全策略,現(xiàn)在所有支持JavaScript 的瀏覽器都會使用這個策略。接下來通過本文給大家介紹Springboot如何優(yōu)雅的解決ajax+自定義headers的跨域請求 ,需要的朋友可以參考下
    2019-05-05
  • Java非阻塞I/O模型之NIO相關(guān)知識總結(jié)

    Java非阻塞I/O模型之NIO相關(guān)知識總結(jié)

    在了解NIO (Non-Block I/O) 非阻塞I/O模型之前,我們可以先了解一下原始的BIO(Block I/O) 阻塞I/O模型,NIO模型能夠以非阻塞的方式更好的利用服務(wù)器資源,需要的朋友可以參考下
    2021-05-05

最新評論