Java使用hutool实现数据导出excel(工具类-包含字段去除)
发布日期:2022-02-09 20:39:12 浏览次数:8 分类:技术文章

本文共 4197 字,大约阅读时间需要 13 分钟。

1.导入hutool的工具包

<!--hutool官网Api地址: -->

<!--maven中央库地址: -->

    <dependency>

            <groupId>cn.hutool</groupId>
            <artifactId>hutool-all</artifactId>
            <version>5.2.5</version>
        </dependency>

2.编写工具类

import java.io.IOException;

import java.lang.reflect.Field;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

import javax.servlet.ServletOutputStream;

import javax.servlet.http.HttpServletResponse;

import org.apache.poi.ss.usermodel.Workbook;

import cn.hutool.core.collection.CollUtil;

import cn.hutool.core.date.DateUtil;
import cn.hutool.core.io.IoUtil;
import cn.hutool.log.Log;
import cn.hutool.log.LogFactory;
import cn.hutool.poi.excel.ExcelUtil;
import cn.hutool.poi.excel.ExcelWriter;
import cn.hutool.poi.excel.StyleSet;
import io.swagger.annotations.ApiModelProperty;

/**

 * @author 作者 leanolee
 * @version 创建时间:
 * @Explain 类说明:hutool实现excel导出工具类
 */
public class ExportExcelUtil {

    static final Log logger = LogFactory.get(ExportExcelUtil .class);

    /**

     * 方法说明:hutool实现excel导出工具类
     *
     * @author :leanolee
     * @创建时间:
     * @param response
     * @param clazz    导出数据的类型
     * @param list     数据集合
     * @param fileName 文件名称,自动在后面添加当前时间(yyyyMMDDHHmmss)
     * @param removeField 去除字段(不需要导出到文件中的字段)
     * @return void
     * @throws Exception
     */
    @SuppressWarnings("rawtypes")
    public static void exportMothod(HttpServletResponse response, Class clazz, List<?> list, String fileName,String[] removeField)
            throws Exception {
        if (CollUtil.isNotEmpty(list)) {
            if (!list.get(0).getClass().equals(clazz)) {
                logger.error("数据类型与传入的集合数据类型不一致!数据类型:{};集合数据类型:{}" ,clazz, list.get(0).getClass());
                throw new Exception("数据类型与传入的集合数据类型不一致!");
            } else {
                try {
                    // 获取输出构造器
                    ExcelWriter writer = ExcelUtil.getWriterWithSheet(fileName);
                    // 获取当前类字段(反射也可以使用hutool工具包里面的相关方法)
                    Field[] fields2 = clazz.getDeclaredFields();
                    // 字段名称集合
                    List<String> fieldNames = new ArrayList<>();
                    // 字段中文名称集合(ApiModelProperty注解的value值)
                    List<String> cnNames = new ArrayList<>();
                    // 时间字段的额列位置
                    for (Field field : fields2) {
                        // 设置属性
                        if (!field.isAccessible()) {
                            field.setAccessible(true);
                        }
                        // 去除序列好和id
                        String fieldName = field.getName();
                        if (!(Arrays.asList(removeField).contains(fieldName))) {
                            fieldNames.add(fieldName);
                            // 判断是否有注解Api

                            /**

                             * 此处判断需要导出的字段方式是使用的swagger的注解作为依据
                             * 如果项目中未使用swgger的注解,可以自定义注解作为依据或者能够作为判断依据的相关表示
                             * 此处除去id字段存在一定的问题,不影响的大局的情况下可以不用考虑
                             * 如果想要除去不必要的字段需要手动编写除去的相关功能
                             **/
                            boolean annotationPresent = field.isAnnotationPresent(ApiModelProperty.class);
                            if (annotationPresent) {
                                ApiModelProperty annotation = field.getAnnotation(ApiModelProperty.class);
                                // 获取注解的值作为导出的表头
                                String name = annotation.value();
                                cnNames.add(name);
                            }
                        } else {
                            //排除字段操作(如果为true,则不设置alias的字段将不被输出)
                            writer.setOnlyAlias(true);
                        }
                    }
                    // 获取表头和对应的字段
                    String[] fs = new String[fieldNames.size()];
                    String[] ns = new String[cnNames.size()];
                    // 集合转换为数组
                    String[] fields = fieldNames.toArray(fs);
                    String[] names = cnNames.toArray(ns);
                    // 设置excel表头及其对应的字段名
                    for (int i = 0; i < names.length; i++) {
                        writer.addHeaderAlias(fields[i], names[i]);
                    }

                    // 设置文本自动换行

                    Workbook workbook = writer.getWorkbook();
                    StyleSet ss = new StyleSet(workbook);
                    ss.setWrapText();
                    writer.setStyleSet(ss);

                    //文本行不自动换行注释掉上面部分的代码

                   //-------------------------------------------------------------------

                    // 一次性写出内容,使用默认样式,强制输出标题
                    writer.write(list, true);
                    // response为HttpServletResponse对象
                    response.setContentType("application/vnd.ms-excel;charset=utf-8");
                    // test.xls是弹出下载对话框的文件名,不能为中文,中文请自行编码
                    ServletOutputStream out = null;
                    try {
                       /**
                         * 如果字段的值不是太长可以不用设置列宽
                         * 设置列宽
                         * 工具类有自动的列宽,相较于默认列宽较小
                         * 显示日期时间存在显示不全而自动转换隐藏的情况(xxxxxxxxxx)
                         * 显示数据为居中显示
                         **/
                        for (int m = 0; m <= fieldNames.size(); m++) {
                            writer.setColumnWidth(m, 23);
                        }

                       /**

                         * 设置文件名称
                         * 名称加时间的方式显示方便文件在本地磁盘的查看
                         **/
                        fileName = fileName + DateUtil.format(new Date(), "YYYYMMddHHmmss");
                        // 设置请求头属性
                        response.setHeader("Content-Disposition", "attachment;filename=" + new String((fileName + ".xlsx").getBytes(), "iso-8859-1"));
                        out = response.getOutputStream();
                        // 写出到文件
                        writer.flush(out, true);
                        // 关闭writer,释放内存
                        writer.close();
                        // 此处记得关闭输出Servlet流
                        IoUtil.close(out);
                    } catch (IOException e) {
                        logger.error(e.getMessage());
                        e.printStackTrace();
                    }

                } catch (SecurityException e) {

                    logger.error(e.getMessage());
                    e.printStackTrace();
                }
            }
        } else {
            logger.error("集合数据为空!");
            throw new Exception("集合数据为空!");
        }
    }
}

 

转载地址:https://blog.csdn.net/liling192/article/details/105700485 如侵犯您的版权,请留言回复原文章的地址,我们会给您删除此文章,给您带来不便请您谅解!

上一篇:JAVA集合:HashMap原理剖析
下一篇:java 根据模板导出excel

发表评论

最新留言

感谢大佬
[***.8.128.20]2024年04月06日 18时53分22秒

关于作者

    喝酒易醉,品茶养心,人生如梦,品茶悟道,何以解忧?唯有杜康!
-- 愿君每日到此一游!

推荐文章

大疆机甲大师教育机器人Python API中文化之二:LED闪烁 2019-04-26
大疆 RoboMaster 机甲大师官方刚刚开通”机甲小 S 实验室”知乎专栏 2019-04-26
大疆机甲大师教育机器人Python API中文化之三:底盘灯效 2019-04-26
大疆机甲大师教育机器人Python API中文化之四五:云台灯效,指定序号 2019-04-26
大疆机甲大师教育机器人Python API中文化之六:关灯 2019-04-26
“中文编程”知乎专栏两岁了——山雨欲来风满楼 2019-04-26
大疆机甲大师Python API之七:做个闹钟 2019-04-26
【意外走向】大疆机甲大师Python API之八:计时——为性能测试展开1000次循环 2019-04-26
RFC#2457——Rust 语言支持非 ASCII 码标识符在 GitHub 引发的激辩(一) 2019-04-26
RFC#2457——Rust 语言选择支持非 ASCII 码标识符在 GitHub 引发的激辩(二) 2019-04-26
”为什么有这么多人执着于中文编程?”回答两千赞留念及回应 2019-04-26
【家务】盘点小孩玩具零件缺失情况 2019-04-26
开发中文 API 的一些策略 2019-04-26
从日本编程书籍《我的第一本编程书》中译版看中文例程如何扬长避短——标识符(一) 2019-04-26
中文命名标识符如何区分类型和变量 2019-04-26
编程术语成系统中文化的意义 2019-04-26
草蟒 Python 中文 API 与 IDE 支持尝鲜 2019-04-26
一种改进中文 API 可读性的方法:参数不限于在末尾 2019-04-26
中文编程开发工具的生存模式探讨 2019-04-26
写给木兰编程语言研发团队的公开信 2019-04-26