使用easyexcel生成动态头,实时生成头写入,加对应的列

news/2024/7/21 7:35:07 标签: java, easyexcel, excel

测试类

参考链接:动态头,实时生成头写入

java">package org.springblade.modules.api.controller;

import com.alibaba.excel.EasyExcel;
import com.alibaba.excel.metadata.Sheet;
import com.alibaba.excel.write.metadata.style.WriteCellStyle;
import com.alibaba.excel.write.style.HorizontalCellStyleStrategy;
import com.alibaba.excel.write.style.column.LongestMatchColumnWidthStyleStrategy;
import org.apache.commons.collections4.ListUtils;
import org.springblade.modules.api.utils.ExcelMergeUtil;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;

public class Test {
    public static void main(String[] args) {
        // 写法1
        String fileName = "F:\\machine" + "\\noModelWrite" + System.currentTimeMillis() + ".xlsx";

        //头部样式
        WriteCellStyle headWriteCellStyle = ExcelMergeUtil.getHeadWriteCellStyle();
        //内容样式
        WriteCellStyle contentWriteCellStyle = ExcelMergeUtil.getContentWriteCellStyle();

        HorizontalCellStyleStrategy horizontalCellStyleStrategy =
                new HorizontalCellStyleStrategy(headWriteCellStyle, contentWriteCellStyle);

        EasyExcel.write(fileName)
                //自定义头部数据
                .head(head())
                //头部和内容策略
                .registerWriteHandler(horizontalCellStyleStrategy)
                //自动列宽
                .registerWriteHandler(new LongestMatchColumnWidthStyleStrategy())
                //sheet显示的名字
                .autoCloseStream(Boolean.TRUE).sheet("ss")
                //对应的列数据
                .doWrite(dataList());
    }

    /**
     * 自定义头部
     *
     * @return
     */
    private static List<List<String>> head() {
        //两排说明油两个头
        List<List<String>> list = new ArrayList<>();
        List<String> head0 = new ArrayList<>();
        head0.add("测试头");
        head0.add("字符串" + System.currentTimeMillis());
        List<String> head1 = new ArrayList<>();
        head1.add("测试头");
        head1.add("数字" + System.currentTimeMillis());
        List<String> head2 = new ArrayList<>();
        head2.add("测试头");
        head2.add("日期" + System.currentTimeMillis());
        list.add(head0);
        list.add(head1);
        list.add(head2);
        return list;
    }

    /**
     * 对应数据
     *
     * @return
     */
    private static List<List<Object>> dataList() {
        List<List<Object>> list = new ArrayList<>();
        //数据量的集合,说明有十条数据,可以自己根据获取到的集合定义
        for (int i = 0; i < 10; i++) {
            List<Object> data = new ArrayList<>();
            data.add("字符串" + i);
            data.add(0.56);
            data.add(new Date());
            list.add(data);
        }
        return list;
    }


}

工具类

java">package org.springblade.modules.api.utils;

import com.alibaba.excel.EasyExcel;
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 com.alibaba.excel.write.metadata.style.WriteCellStyle;
import com.alibaba.excel.write.metadata.style.WriteFont;
import com.alibaba.excel.write.style.HorizontalCellStyleStrategy;
import org.apache.poi.ss.usermodel.*;
import org.apache.poi.ss.util.CellRangeAddress;
import org.springblade.modules.api.vo.PlotBaseExcelVO;

import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.net.URLEncoder;
import java.util.List;

public class ExcelMergeUtil implements CellWriteHandler {
    private int[] mergeColumnIndex;
    private int mergeRowIndex;

    public ExcelMergeUtil() {
    }

    public ExcelMergeUtil(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) {

        //当前行
        int curRowIndex = cell.getRowIndex();
        //当前列
        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;
                }
            }
        }
    }


    /**
     * 当前单元格向上合并
     *
     * @param writeSheetHolder
     * @param cell             当前单元格
     * @param curRowIndex      当前行
     * @param curColIndex      当前列
     */
    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();
        // 将当前单元格数据与上一个单元格数据比较
        Boolean dataBool = preData.equals(curData);
        //此处需要注意:因为我是按照主体名称确定是否需要合并的,所以获取每一行第二列数据和上一行第一列数据进行比较,如果相等合并,getCell里面的值,是主体名称所在列的下标,不能大于需要合并列数组的第一个下标
        Boolean bool = cell.getRow().getCell(0).getStringCellValue().equals(cell.getSheet().getRow(curRowIndex - 1).getCell(0).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);
                // 若上一个单元格已经被合并,则先移出原有的合并单元,再重新添加合并单元
                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);
            }
        }
    }

    /**
     * 头部样式
     *
     * @return
     */
    public static WriteCellStyle getHeadWriteCellStyle() {
        // 这里需要设置不关闭流
        WriteCellStyle headWriteCellStyle = new WriteCellStyle();
        //设置背景颜色
        headWriteCellStyle.setFillForegroundColor(IndexedColors.GREY_25_PERCENT.getIndex());
        //设置头字体
        WriteFont headWriteFont = new WriteFont();
        //字体大小
        headWriteFont.setFontHeightInPoints((short) 13);
        //是否加粗
        headWriteFont.setBold(true);
        headWriteCellStyle.setWriteFont(headWriteFont);
        //设置头居中
        headWriteCellStyle.setHorizontalAlignment(HorizontalAlignment.CENTER);
        return headWriteCellStyle;
    }

    /**
     * 内容样式
     *
     * @return
     */
    public static WriteCellStyle getContentWriteCellStyle() {
        //内容策略
        WriteCellStyle contentWriteCellStyle = new WriteCellStyle();
        //设置 水平居中
        contentWriteCellStyle.setHorizontalAlignment(HorizontalAlignment.CENTER);
        //自动换行
        contentWriteCellStyle.setWrapped(true);
        //垂直居中
        contentWriteCellStyle.setVerticalAlignment(VerticalAlignment.CENTER);
        //设置左边框
        contentWriteCellStyle.setBorderLeft(BorderStyle.THIN);
        //设置右边框
        contentWriteCellStyle.setBorderRight(BorderStyle.THIN);
        //设置上边框
        contentWriteCellStyle.setBorderTop(BorderStyle.THIN);
        //设置下边框
        contentWriteCellStyle.setBorderBottom(BorderStyle.THIN);
        return contentWriteCellStyle;
    }

    /**
     * 合并单元格导出excel工具
     *
     * @param response         响应头
     * @param fileName         文件名称
     * @param lsit             需要导出的数据
     * @param data             对应的excel导出类
     * @param mergeColumeIndex 需要合并的下标
     * @param mergeRowIndex    从第几行开始合并
     * @throws IOException
     */
    public static void exportExcel(HttpServletResponse response, String fileName, List lsit, Class data, int[] mergeColumeIndex, int mergeRowIndex) throws IOException {
        response.setContentType("application/vnd.ms-excel");
        response.setCharacterEncoding("utf-8");
        // 这里URLEncoder.encode可以防止中文乱码 当然和excel>easyexcel没有关系
        String fileNamePath = URLEncoder.encode(fileName + System.currentTimeMillis(), "UTF-8");
        response.setHeader("Content-disposition", "attachment;filename=" + fileNamePath + ".xlsx");
        // 调用合并单元格工具类,此工具类是根据工程名称相同则合并后面数据
        ExcelMergeUtil excelFillCellMergeStrategy = new ExcelMergeUtil(mergeRowIndex, mergeColumeIndex);

        //头部样式
        WriteCellStyle headWriteCellStyle = ExcelMergeUtil.getHeadWriteCellStyle();
        //内容样式
        WriteCellStyle contentWriteCellStyle = ExcelMergeUtil.getContentWriteCellStyle();

        HorizontalCellStyleStrategy horizontalCellStyleStrategy =
                new HorizontalCellStyleStrategy(headWriteCellStyle, contentWriteCellStyle);

        EasyExcel.write(response.getOutputStream(), data)
                .registerWriteHandler(horizontalCellStyleStrategy)
                .registerWriteHandler(excelFillCellMergeStrategy)
                //sheet显示的名字
                .autoCloseStream(Boolean.TRUE).sheet(fileName)
                .doWrite(lsit);
    }
}




http://www.niftyadmin.cn/n/5444071.html

相关文章

【原创】RockyLinux8.6编译安装Redis7.2.4,非常详细!

前言 RockyLinux8.6貌似比CentOS7.9少了一些必要的库&#xff0c;还有就是存在版本冲突&#xff0c;导致它去编译Redis7.2.4比CentOS7.9麻烦多了&#xff0c;踩了好多坑&#xff0c;终于算是编译成功了&#xff0c;下面就来介绍一下如何编译成功的 上传源码包 首先去Redis官…

elk7.11.2离线安装

elk与jdk自行搜索下载 package(离线安装包)目录&#xff1a;/home/elk-pak /home/jdk8-pak 安装目录&#xff1a;/usr/local/ jdk8安装 最好查看一下是否存在原服务器自带openJDK rpm -qa|grep java # 有就执行下边卸载命令 无拉倒 rpm -e --nodeps jdk-xxx# 解压jdk8安装包…

力扣日记3.21【贪心算法篇】45. 跳跃游戏 II

力扣日记&#xff1a;【贪心算法篇】45. 跳跃游戏 II 日期&#xff1a;2024.3.21 参考&#xff1a;代码随想录、力扣 45. 跳跃游戏 II 题目描述 难度&#xff1a;中等 给定一个长度为 n 的 0 索引整数数组 nums。初始位置为 nums[0]。 每个元素 nums[i] 表示从索引 i 向前跳转…

STM32关于使用定时器触发ADC转换的理解

以STM32 ADC的常规通道为例&#xff08;注入通道类似&#xff09;&#xff1a; 如上图&#xff0c;STM32 ADC的常规通道可以由以上6个信号触发任何一个&#xff0c;我们以使用TIM2_CH2触发ADC1&#xff0c;独立模式&#xff0c;每次仅测一条通道&#xff0c;则ADC的配置如下&am…

【统计学】独立同分布

1. 概念 独立同分布是统计学中的一个重要概念&#xff0c;指的是在概率论和统计学中常见的一种假设&#xff0c;即一组随机变量之间相互独立&#xff0c;并且具有相同的概率分布。 具体来说&#xff0c;如果一组随机变量 {X₁, X₂, …, Xₙ} 是相互独立的&#xff0c;意味着…

翻硬币游戏的解

题目背景 小明正在玩一个“翻硬币”的游戏。 题目描述 桌上放着排成一排的若干硬币。我们用 * 表示正面&#xff0c;用 o 表示反面&#xff08;是小写字母&#xff0c;不是零&#xff09;&#xff0c;比如可能情形是 **oo***oooo&#xff0c;如果同时翻转左边的两个硬币&…

【LVGL-开关部件】

LVGL-开关部件 ■ LVGL-开关部件■ 开关部件&#xff1a;指示器打开的颜色■ 开关部件&#xff1a;不可修改■ 开关部件&#xff1a;获取开关状态■ 开关部件&#xff1a;示例一&#xff1a;制冷,制暖,开关 ■ LVGL-开关部件 ■ 开关部件&#xff1a;指示器打开的颜色 ■ 开关部…

前端知识图谱大全

文章目录 前端知识图谱基础技能CSS预处理器 框架与库状态管理 跨端开发服务器端渲染&#xff08;SSR&#xff09;响应式设计和交叉设备兼容性 微前端音视频与直播技术前端工程化版本控制性能优化计算机网络基础浏览器工作原理前端安全现代API 数据结构和算法团队协作与项目管理…