EasyExcel导出工具类

目录

工具类

头部实体类(要和工具类在同一个module或项目下)

日期转换器


工具类

/**
 * 导出Excel工具类
 */
public class EasyExcelUtil<T> {

    /**
     * 单sheet(Map写入)
     * @param response 响应对象
     * @param headList 头部集合
     * @param dataList 数据集合
     */
    public static void write(HttpServletResponse response, List<ExcelHead> headList, List<Map<String, Object>> dataList) throws IOException {
        ExcelWriterBuilder writerBuilder = EasyExcel.write();
        writerBuilder.file(response.getOutputStream());
        writerBuilder.excelType(ExcelTypeEnum.XLSX);
        //日期转换器
        TimestampStringConverter converter = new TimestampStringConverter();
        writerBuilder.registerConverter(converter).registerWriteHandler(new ColumnWidthStyleStrategy())
                .head(convertHead(headList)).sheet("sheet1")
                .doWrite(convertData(headList, dataList));
    }

    /**
     * 多sheet(Map写入)
     * @param response 响应对象
     * @param headMap 头部Map数据
     * @param dataMap 数据Map数据
     * @param sheetMap sheet Map数据
     */
    public static void multipleWrite(HttpServletResponse response
            , Map<String,List<ExcelHead>> headMap
            , Map<String,List<Map<String, Object>>> dataMap
            , Map<String,String> sheetMap) throws IOException {
        //日期转换器
        TimestampStringConverter converter = new TimestampStringConverter();
        ExcelWriter excelWriter = EasyExcel.write()
                .registerConverter(converter)
                .registerWriteHandler(new ColumnWidthStyleStrategy())
                .file(response.getOutputStream())
                .excelType(ExcelTypeEnum.XLSX).autoCloseStream(true).build();
        int i = 0;
        for (Map.Entry<String,List<ExcelHead>> entry : headMap.entrySet()) {
            WriteSheet writeSheet = EasyExcel
                    .writerSheet(i++, sheetMap.get(entry.getKey()))
                    .head(convertHead(entry.getValue())).build();
            excelWriter.write(convertData(entry.getValue(), dataMap.get(entry.getKey())), writeSheet);
        }
        excelWriter.finish();
    }

    /**
     * 实体写入
     * @param response 响应对象
     * @param sheetName sheet名称
     * @param c 实体类
     * @param list 实体数据
     */
    public static <T> void writeSheet(HttpServletResponse response, String sheetName, Class<T> c, List<T> list) throws IOException {
        EasyExcel.write(response.getOutputStream(), c).sheet(sheetName).doWrite(list);
    }

    /**
     * 读取并存储到实体
     * @param fileName 路径地址
     * @param sheetName sheet名称
     * @param c 实体类
     */
    public static <T> List<T> read(String fileName, String sheetName, Class c) {
        List<T> list = new ArrayList();
        EasyExcel.read(fileName, c, new ReadListener<T>() {
            @Override
            public void invoke(T o, AnalysisContext analysisContext) {
                list.add(o);
            }
            @Override
            public void doAfterAllAnalysed(AnalysisContext analysisContext) {

            }
        }).sheet(sheetName).doRead();
        return list;
    }

    /**
     * 读取并存储到实体
     * @param fileName 路径地址
     * @param sheetNo 指定sheet
     */
    public static Map<String,Object> readToMap(String fileName, Integer sheetNo) {
        Map<String,Object> result = new HashMap<>();
        List<Map<String,Object>> dataList = new ArrayList();
        //头部map
        Map<String,String> headMap = new HashMap<>();
        //头部拼音map
        Map<String,String> pinyinMap = new HashMap<>();
        EasyExcel.read(fileName,new AnalysisEventListener<Map<Integer, Object>>() {
            @Override
            public void invoke(Map<Integer, Object> data, AnalysisContext context) {
                Map<String,Object> map = new HashMap<>();
                for (Integer key : data.keySet()) {
                    if(key!=null && data.get(key)!=null) {
                        map.put("field_" + key.toString(), data.get(key));
                    }
                }
                dataList.add(map);
            }
            @Override
            public void doAfterAllAnalysed(AnalysisContext analysisContext) {
            }
            @Override
            public void invokeHead(Map<Integer, ReadCellData<?>> head, AnalysisContext context) {
                for (Integer key : head.keySet()) {
                    if(key!=null && head.get(key)!=null && StringUtils.isNotBlank(head.get(key).getStringValue())) {
                        headMap.put("field_" + key.toString(), head.get(key).getStringValue());
                        pinyinMap.put("field_" + key.toString(), Pinyin4jUtils.getPinYinHeadChar(head.get(key).getStringValue()));
                    }
                }
            }
        }).sheet(sheetNo).headRowNumber(1).doRead();
        result.put("headMap",headMap);
        result.put("pinyinMap",pinyinMap);
        result.put("dataList",dataList);
        result.put("count",dataList.size());
        return result;
    }

    /**
     * 读取表头并存储到实体
     * @param fileName 路径地址
     * @param sheetNo 指定sheet
     */
    public static Map<String,Object> readToMapHead(String fileName, Integer sheetNo) {
        Map<String,Object> result = new HashMap<>();
        //头部map
        Map<String,String> headMap = new HashMap<>();
        //头部拼音map
        Map<String,String> pinyinMap = new HashMap<>();
        EasyExcel.read(fileName,new AnalysisEventListener<Map<Integer, Object>>() {
            @Override
            public void invoke(Map<Integer, Object> data, AnalysisContext context) {
            }
            @Override
            public void doAfterAllAnalysed(AnalysisContext analysisContext) {
            }
            @Override
            public void invokeHead(Map<Integer, ReadCellData<?>> head, AnalysisContext context) {
                for (Integer key : head.keySet()) {
                    if(key!=null && head.get(key)!=null && StringUtils.isNotBlank(head.get(key).getStringValue())) {
                        headMap.put("field_" + key.toString(), head.get(key).getStringValue());
                        pinyinMap.put("field_" + key.toString(), Pinyin4jUtils.getPinYinHeadChar(head.get(key).getStringValue()));
                    }
                }
            }
        }).sheet(sheetNo).headRowNumber(1).doRead();
        result.put("headMap",headMap);
        result.put("pinyinMap",pinyinMap);
        return result;
    }

    /**
     * 头部转换
     * @param headList 头部集合
     */
    private static List<List<String>> convertHead(List<ExcelHead> headList) {
        List<List<String>> list = new ArrayList<>();
        for (ExcelHead head : headList) {
            list.add(Lists.newArrayList(head.getTitle()));
        }
        //沒有搞清楚head的参数为List<List<String>>,用List<String>就OK了
        return list;
    }

    /**
     * 数据转换
     * @param headList 头部集合
     * @param dataList 数据集合
     */
    private static List<List<Object>> convertData(List<ExcelHead> headList, List<Map<String, Object>> dataList) {
        List<List<Object>> result = new ArrayList();
        //对dataList转为easyExcel的数据格式
        for (Map<String, Object> data : dataList) {
            List<Object> row = new ArrayList();
            for (ExcelHead h : headList) {
                Object o = data.get(h.getFieldName());
                //需要对null的处理,比如age的null,要转为-1
                row.add(handler(o, h.getNullValue()));
            }
            result.add(row);
        }
        return result;
    }

    /**
     * 空值处理
     * @param o 数值
     * @param nullValue 空值置换
     */
    private static Object handler(Object o, Object nullValue) {
        return o != null ? o : nullValue;
    }
}

头部实体类(要和工具类在同一个module或项目下)

/**
 * Excel头部实体
 */
public class ExcelHead<T> {

    private String fieldName;

    private String title;

    private T nullValue;

    public ExcelHead(String fieldName, String title) {
        this.fieldName = fieldName;
        this.title = title;
    }

    public ExcelHead(String fieldName, String title, T nullValue) {
        this.fieldName = fieldName;
        this.title = title;
        this.nullValue = nullValue;
    }

    public String getFieldName() {
        return fieldName;
    }

    public void setFieldName(String fieldName) {
        this.fieldName = fieldName;
    }

    public String getTitle() {
        return title;
    }

    public void setTitle(String title) {
        this.title = title;
    }

    public T getNullValue() {
        return nullValue;
    }

    public void setNullValue(T nullValue) {
        this.nullValue = nullValue;
    }
}

注意:真正导出表格的是ExcelWriterSheetBuilder类中的方法,前面只是封装,这个是真正导出用到的;这个类是EasyExcel自带的。

日期转换器

/**
 * 日期转换器
 */
public class TimestampStringConverter implements Converter<Timestamp> {

    @Override
    public Class<?> supportJavaTypeKey() {
        return Timestamp.class;
    }

    @Override
    public CellDataTypeEnum supportExcelTypeKey() {
        return CellDataTypeEnum.STRING;
    }

    @Override
    public WriteCellData<?> convertToExcelData(Timestamp value, ExcelContentProperty contentProperty,
                                               GlobalConfiguration globalConfiguration) {
        WriteCellData cellData = new WriteCellData();
        String cellValue;
        if (contentProperty == null || contentProperty.getDateTimeFormatProperty() == null) {
            cellValue = DateUtils.format(value.toLocalDateTime(), null, globalConfiguration.getLocale());
        } else {
            cellValue = DateUtils.format(value.toLocalDateTime(), contentProperty.getDateTimeFormatProperty().getFormat(),
                    globalConfiguration.getLocale());
        }
        cellData.setType(CellDataTypeEnum.STRING);
        cellData.setStringValue(cellValue);
        cellData.setData(cellValue);
        return cellData;
    }
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mfbz.cn/a/595505.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

Burp和Proxifier抓包微信小程序

1、Burp设置代理 2、浏览器下载证书 3、安装证书 4、Proxifier设置代理 5、Proxifier设置Proxification Rule 6、Burp查看抓包数据 打开一个小程序&#xff0c;可以看到WeChatAppEx的流量先经过Proxifier&#xff0c;再经过127.0.0.1:8080到Burp

如何使用ArcGIS Pro进行选房分析

无论是研究城市规划布局还是寻找理想的住房&#xff0c;都需要综合考虑购物、医疗、教育和休闲等多方面因素&#xff0c;此时我们的GIS软件就可以派上用场了&#xff0c;这里为大家介绍一下如何使用 ArcGIS Pro 进行选房分析&#xff0c;希望能对你有所帮助。 数据来源 教程所…

性能优化 | el-table中内嵌大量el-input控件导致渲染卡顿的问题

场景 项目中有一个应用场景&#xff0c;用户需要在表单中大量使用选择框以及输入框填写数据&#xff08;每一行大概有三十几个输入框&#xff09;&#xff0c;当选择框与输入框达到一定数量的时候&#xff0c;页面会出现输入不连续、卡顿的现象&#xff0c;如下图&#xff1a;…

LoRa无线通讯入门

本文图片来自于深入浅出讲解LoRa通信技术&#xff0c;LoRa技术介绍&#xff0c;LoRa开发与应用&#xff0c;物联网学习必备知识点&#xff01;_哔哩哔哩_bilibili LoRa无线通讯 LoRa&#xff08;Long Range&#xff09;是一种低功耗广域网&#xff08;LPWAN&#xff09;技术&a…

【春招特供】Unity面试题总结 | Unity基础篇

物体发生碰撞的必要条件&#xff1f; 两个物体都必须带有碰撞器&#xff08;Collider&#xff09;&#xff0c;其中一个物体还必须带有Rigidbody刚体&#xff0c;而且必须是运动的物体带有Rigidbody脚本才能检测到碰撞。 2. Unity3d中的碰撞器和触发器的区别&#xff1f; 碰…

颠覆传统?「一束光子,两种频率」的量子纠缠!

在最新的研究中&#xff0c;科学家们开发了一种革命性的量子纠缠方式——“频域光子数路纠缠”&#xff08;frequency-domain photon number-path entanglement&#xff09;。这一量子物理学的重大进展涉及到一个创新性的工具&#xff1a;频率分束器&#xff08;frequency beam…

B2985A是德科技B2985A高阻计

181/2461/8938产品概述&#xff1a; B2985A 静电计/高阻表 描述 B2985A 静电计/高阻表是全球少有具有图形显示功能的静电计&#xff0c;可凭借 0.01 fA&#xff08;0.01 x 10-15 A&#xff09;的分辨率帮助您可靠测量弱电流&#xff0c;并可测量高达 10 PΩ&#xff08;10 x 1…

[leetcode] 62. 不同路径

文章目录 题目描述解题方法方法一&#xff1a;动态规划java代码复杂度分析 方法二&#xff1a;排列组合java代码复杂度分析 相似题目 题目描述 一个机器人位于一个 m x n 网格的左上角 &#xff08;起始点在下图中标记为 “Start” &#xff09;。 机器人每次只能向下或者向右…

毕业设计:《基于 Prometheus 和 ELK 的基础平台监控系统设计与实现》

前言 《基于 Prometheus 和 ELK 的基础平台监控系统设计与实现》&#xff0c;这是我在本科阶段的毕业设计&#xff0c;通过引入 Prometheus 和 ELK 架构实现企业对指标与日志的全方位监控。并且基于云原生&#xff0c;使用容器化持续集成部署的开发方式&#xff0c;通过 Sprin…

开源模型应用落地-CodeQwen模型小试-SQL专家测试(二)

一、前言 代码专家模型是基于人工智能的先进技术&#xff0c;它能够自动分析和理解大量的代码库&#xff0c;并从中学习常见的编码模式和最佳实践。这种模型可以提供准确而高效的代码建议&#xff0c;帮助开发人员在编写代码时避免常见的错误和陷阱。 通过学习代码专家模型&…

使用Bandzip分卷压缩文件

需求 部分文件太大&#xff0c;例如超过10G&#xff0c;就不能使用企业微信等传输&#xff0c;如果可以把一个10G的文件分割成为10个1G的文件就可以方便传输了。 实现方式 使用bandzip&#xff0c;把超过10G的文件分卷压缩成为多个小的zip文件。 把生成的多个文件放在同一目…

网红隋总揭秘:高效实施人力RPO项目的秘诀

随着企业对于招聘流程效率和专业性的追求日益提升&#xff0c;RPO(招聘流程外包)项目逐渐成为人力资源领域的热门话题。隋总凭借丰富的行业经验和独特的视角&#xff0c;分享了关于如何高效实施人力RPO项目的秘诀。 一、明确目标&#xff0c;找准定位 在启动RPO项目之前&#x…

零基础入门篇④ 初识Python(注释、编码规范、关键字...)

Python从入门到精通系列专栏面向零基础以及需要进阶的读者倾心打造,9.9元订阅即可享受付费专栏权益,一个专栏带你吃透Python,专栏分为零基础入门篇、模块篇、网络爬虫篇、Web开发篇、办公自动化篇、数据分析篇…学习不断,持续更新,火热订阅中🔥专栏订阅地址 👉Python从…

【挑战30天首通《谷粒商城》】-【第一天】01、简介-项目介绍

文章目录 课程介绍一、 项目介绍1、项目背景A、电商模式1、B2B 模式2、B2C 模式3、C2B 模式4、C2C 模式5、O2O 模式 1.2、项目架构图1.3、项目技术 & 特色1.4、项目前置要求二、分布式基础概念(略)三、环境撘建(略) one more thing 课程介绍 1.分布式基础(全栈开发篇)2.分…

UE5 audio capture 回声问题 ||在安卓上有爆鸣声

参考视频 0.基本步骤 【UE4_蓝图】录制麦克风声音/系统声音并输出保存WAV文件_ue4录音-CSDN博客 1.步骤 1.创建Sound Submix A 2. 右键新建Sound Submix B 3.把B的两个参数调为-96 4.audio capture的Base Submix&#xff0c;把前面提到的A赋值进去 5.开始录制输出和完成录制…

【Unity 协程】

Unity中的协程&#xff08;Coroutine&#xff09;是一种编程结构&#xff0c;它允许你以一种看似同步的方式编写可能需要异步执行的代码。协程特别适用于需要在一定时间后执行操作&#xff0c;或者在循环执行某段代码直到某个条件满足时的场景。 协程使用IEnumerator委托来实现…

30天精通 Δ-Σ ADC 设计

在现代电子工程和信号处理领域&#xff0c;模拟-数字转换器&#xff08;ADC&#xff09;是实现信号精确转换的核心组件。ADC技术正经历革新&#xff0c;拓展了其在多个前沿技术领域的应用范围。 **首先&#xff0c;**ADC的采样率和分辨率是衡量其性能的关键指标。随着技术工艺…

海外网安同行们面对当下的就业环境,也破防了。。。

问&#xff1a;漂亮国的安全行业就业市场怎么样&#xff1f; 答&#xff1a;初级岗位挺好找的&#xff0c;如果你有一个硕士学位并且还有10年工作经验的话。 0x00 我之前在分析海外的就业环境的时候[海外安全行业工资水平怎么样&#xff1f;]&#xff0c;一度以为外国的月亮就…

分布式光伏管理系统和一般的光伏管理系统相比有什么区别?

随着全球对可再生能源的关注度日益提高&#xff0c;光伏技术作为其中的佼佼者&#xff0c;已经得到了广泛的应用。在光伏技术中&#xff0c;管理系统扮演着至关重要的角色&#xff0c;它关乎着光伏电站的运行效率、能源产出以及运维成本等多个方面。其中&#xff0c;分布式光伏…

N9048B PXE EMI 测试接收机,1 Hz 至 44 GHz

​ _EMI_ N9048B EMI 测试接收机 1 Hz 至 44 GHz Keysight N9048B PXE 是一款符合标准的 EMI 测试接收机&#xff0c;配有射频预选器和 LNA 设计。其实时扫描&#xff08;RTS&#xff09;功能有助于您缩短总体测试时间&#xff0c;轻松执行无间隙的信号捕获和分析。 特点 …