分页导出,防止内存溢出_writesheet会内存溢出吗-程序员宅基地

技术标签: 应用  

分页导出,防止内存溢出

1.定义模板方法类

/**
 * 分页导出模板
 * <p>
 * T 为查询参数 需要有 PageNo 和 PageSize
 * R 为查询结果,导出的对象
 */
public abstract class PagingExportTemplate<T extends BasicQueryEntity, R> {
    


    protected static final Logger log = LoggerFactory.getLogger(PagingExportTemplate.class);


    /**
     * 处理查询参数的回调方法(例如校验,解析)
     * @param param
     */
    protected abstract void handleParam(T param);

    /**
     * 处理总条数的回调方法(例如最大数据限制)
     * @param total
     */
    protected abstract void handleTotal(long total,HttpServletResponse response);

    /**
     * 获取查询总数
     *
     * @param param
     * @return
     */
    protected abstract long getTotal(T param);


    /**
     * 获取一页的数据
     *
     * @param param
     * @return
     */
    protected abstract List<R> getPageData(T param);


    /**
     * 分页导出
     *
     * @param param                   查询参数
     * @param pageSize                每页的数量
     * @param response
     * @param fileName                文件名
     * @param includeColumnFiledNames 导出对象的表头字段
     * @param clazz                   导出对象类
     * @param strategy                导出策略
     */
    public void pagingExport(T param, Integer pageSize, HttpServletResponse response,
                             String fileName, Set<String> includeColumnFiledNames, Class clazz, HorizontalCellStyleStrategy strategy) {
    
        //处理查询参数的回调方法(例如校验,解析)
        handleParam(param);

        long total = getTotal(param);
        log.info("导出的数量为:{}", total);
        //处理总条数的回调方法(例如最大数据限制)
        handleTotal(total,response);

        //分页导出的总页数
        long pageNum = total % pageSize==0? (total/pageSize) : (total/pageSize)+1;

        param.setPageNo(1);
        param.setPageSize(pageSize);

        ExcelWriter excelWriter = null;
        try {
    
            response.setContentType("application/octet-stream;charset=UTF-8");
            response.setHeader("Content-Disposition", "attachment;filename*=utf-8'zh_cn'" + URLEncoder.encode(fileName, "UTF-8"));
            ServletOutputStream outputStream = response.getOutputStream();
            excelWriter = EasyExcel.write(outputStream, clazz)
                    .registerWriteHandler(strategy)
                    .includeColumnFiledNames(includeColumnFiledNames)
                    .build();
            WriteSheet writeSheet = EasyExcel.writerSheet(fileName).build();

            while (true) {
    
                log.info("开始查询第{}页:", param.getPageNo());
                List<R> dto = getPageData(param);
                log.info("完成查询第{}页:", param.getPageNo());
                param.setPageNo(param.getPageNo() + 1);
                excelWriter.write(dto, writeSheet);
                if (param.getPageNo() > pageNum ) {
    
                    break;
                }
            }
        } catch (Exception e) {
    
            log.error("导出失败:", e);
        } finally {
    
            if (excelWriter != null) {
    
                try {
    
                    excelWriter.finish();
                } catch (Exception e) {
    
                    log.error("关闭导出流失败:", e);
                }
            }
        }
    }
}


2.具体实现

@Component
public class ExamplePagingExport extends PagingExportTemplate<ExampleQuery, ExampleDTO> {
    

    @Resource
    ExampleService exampleService;

    @Override
    protected void handleParam(ExampleQuery param) {
    
        exampleService.handleQuery(param);
    }

    @Override
    protected void handleTotal(long total, HttpServletResponse response) {
    
        log.info("导出的数量为:{}", total);
    }

    @Override
    protected long getTotal(ExampleQuery param) {
    
        return exampleService.getCount(param);
    }

    @Override
    protected List<ExampleDTO> getPageData(ExampleQuery param) {
    
        return exampleService.listData(param);
    }

}

3.Service层调用

@Service
public class ExampleServiceImpl {
    
    @Resource
    ExamplePagingExport pagingExport;


    public void exportByCondition(ExampleQuery query, HttpServletResponse response) {
    
        String fileName = "文件名"+".xlsx";
        Set<String> includeColumnFiledNames = getIncludeColumnFiledNames();
        HorizontalCellStyleStrategy strategy = getCellStyleStrategy(false);
        Class<ExampleDTO> clazz = ExampleDTO.class;

        pagingExport.pagingExport(query,10000, response,fileName,includeColumnFiledNames, clazz,strategy);
    }


    private static Set<String> getIncludeColumnFiledNames() {
    
        Set<String> includeColumnFiledNames = new HashSet<String>();
        includeColumnFiledNames.add("filedA");
        includeColumnFiledNames.add("filedB");
        return includeColumnFiledNames;
    }

    private static HorizontalCellStyleStrategy getCellStyleStrategy(boolean isSchedule) {
    
        // 3、合成样式策略
        return new HorizontalCellStyleStrategy(getHeadWriteCellStyle(), getContentWriteCellStyle(isSchedule));
    }

    private static WriteCellStyle getHeadWriteCellStyle() {
    
        // 1、头的策略
        WriteCellStyle headWriteCellStyle = new WriteCellStyle();
        // 设置头背景色
        headWriteCellStyle.setFillForegroundColor(IndexedColors.WHITE.getIndex());
        // 设置字体
        WriteFont headWriteFont = new WriteFont();
        headWriteFont.setFontHeightInPoints((short) 11);
        headWriteFont.setBold(true);
        headWriteCellStyle.setWriteFont(headWriteFont);
        // 设置边框
        headWriteCellStyle.setBorderTop(BorderStyle.THIN);
        headWriteCellStyle.setBorderLeft(BorderStyle.THIN);
        headWriteCellStyle.setBorderRight(BorderStyle.THIN);
        headWriteCellStyle.setBorderBottom(BorderStyle.THIN);
        // 设置内容位置
        headWriteCellStyle.setHorizontalAlignment(HorizontalAlignment.CENTER);
        headWriteCellStyle.setVerticalAlignment(VerticalAlignment.CENTER);
        return headWriteCellStyle;
    }

    private static WriteCellStyle getContentWriteCellStyle(boolean isSchedule) {
    
        // 2、内容的策略
        WriteCellStyle contentWriteCellStyle = new WriteCellStyle();
        // 这里需要指定 FillPatternType 为FillPatternType.SOLID_FOREGROUND 不然无法显示背景颜色。头默认了 FillPatternType所以可以不指定
        contentWriteCellStyle.setFillPatternType(FillPatternType.SOLID_FOREGROUND);
        // 设置内容背景色
        contentWriteCellStyle.setFillForegroundColor(IndexedColors.WHITE.getIndex());
        // 设置字体
        WriteFont contentWriteFont = new WriteFont();
        if (isSchedule) {
    
            contentWriteFont.setFontHeightInPoints((short) 11);
            contentWriteFont.setBold(true);
        } else {
    
            contentWriteFont.setFontHeightInPoints((short) 10);
        }
        contentWriteCellStyle.setWriteFont(contentWriteFont);
        // 设置边框
        contentWriteCellStyle.setBorderTop(BorderStyle.THIN);
        contentWriteCellStyle.setBorderLeft(BorderStyle.THIN);
        contentWriteCellStyle.setBorderRight(BorderStyle.THIN);
        contentWriteCellStyle.setBorderBottom(BorderStyle.THIN);
        // 设置内容位置
        contentWriteCellStyle.setHorizontalAlignment(HorizontalAlignment.CENTER);
        contentWriteCellStyle.setVerticalAlignment(VerticalAlignment.CENTER);

        //设置单元格为文本格式
        HSSFWorkbook demoWorkBook = new HSSFWorkbook();
        HSSFDataFormat format = demoWorkBook.createDataFormat();
        contentWriteCellStyle.setDataFormat(format.getFormat("@"));
        return contentWriteCellStyle;
    }
}
版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/qq_41738264/article/details/115063972

智能推荐

jQuery.fn.extend()方法_jquery fn.extend-程序员宅基地

文章浏览阅读176次。jQuery.fn.extend()方法 实例添加两个方法到jQuery原型($.fn)&lt;label&gt;&lt;input type="checkbox" name="foo"&gt; Foo&lt;/label&gt; &lt;label&gt;&lt;input type="checkbox" name="bar"&gt_jquery fn.extend

1-STM32物联网开发WIFI(ESP8266)+GPRS(Air202)系统方案微信小程序篇(域名备案)_stm32域名访问-程序员宅基地

文章浏览阅读320次。如果自己的域名有没备案使用域名访问http的时候会报错微信小程序如果要发布,也需要有备案过的云服务器和域名我的不能详细写了,因为已经备案过了,展示的信息不一样了,我拷贝过来别人写的 <ignore_js_op> 再往下,就根据提示让你填,你就填就..._stm32域名访问

如何做到iphone数据恢复_iphone格式化后数据还能恢复吗-程序员宅基地

文章浏览阅读3.4k次。近期小编我收到不少用户咨询误删除了苹果手机数据之后,应该如何恢复到问题。要知道,苹果手机最经典的就是他的ios系统,这套系统比较闭合,什么都是自成体系。所以有时候也让很多朋友担心,万一iphone数据丢失了,itun1youmeilaide及备份,该怎么办才好呢?安卓手机能用的数据恢复办法,苹果也能用么?一般来说,选择专业数据恢复技术苹果iphone手机数据恢复软件:http://ww_iphone格式化后数据还能恢复吗

反射如何打破封装性_打破产品建议的复杂性-程序员宅基地

文章浏览阅读83次。反射如何打破封装性当前系统的真正问题(The Real Issue With the Current Sytems)With the rise of e-commerce in this era, a new frontier has opened up. It’s called product recommendations. It’s a no brainers, you recommend..._封装 复杂

NLP 文本预处理 Python 代码_python文本预处理代码csdn-程序员宅基地

文章浏览阅读1.3k次,点赞2次,收藏11次。在获得文本之后 将所有字母转换为小写或大写 目录在获得文本之后将所有字母转换为小写或大写将数字转换为单词或删除数字删除标点、重音符号和其他音调符号删除空格扩展缩写词删除停止词、稀疏词和特定词文本规范化---单词减为词干、词根或词干的过程词性标记分块是一种自然的语言过程,用于识别组成部分把句子(名词、动词、形容词等)联系起来具有离散语法意义的顺..._python文本预处理代码csdn

com.sun.mail.smtp.SMTPSendFailedException: 553 Mail from must equal authorized user_com.sun.mail.smtp.smtpsenderfailedexception: 553 m-程序员宅基地

文章浏览阅读8.6k次。com.sun.mail.smtp.SMTPSendFailedException: 553 Mail from must equal authorized user1.问题SMTP邮件发送失败异常 :553,邮件发信方必须与已认证用户相同错误来自于:使用org.springframework.mail.SimpleMailMessage发送邮件时,没有setFrom时抛出的异..._com.sun.mail.smtp.smtpsenderfailedexception: 553 mail from must equal author

随便推点

全球15个最顶级的技术类博客站点_世界顶级计算机技术网站-程序员宅基地

文章浏览阅读1.4k次。中文原文:http://publish.it168.com/2007/0525/20070525022301.shtml看自:http://www.williamlong.info/archives/919.html英文原文:http://www.computerworld.com/action/article.do?command=printArticleBasic&articleId=_世界顶级计算机技术网站

银河麒麟V10操作系统安装putty和cutecom和网络调试助手(mNetAssist)_putty软件怎么用麒麟-程序员宅基地

文章浏览阅读5.3k次。银河麒麟V10操作系统安装putty和cutecom和网络调试助手(mNetAssist)安装Puttysudo apt-get install putty安装Cutecomsudo apt-get install cutecom安装网络调试助手需要先下载安装包mNetAssist-release-amd64.debsudo dpkg -i mNetAssist-release-amd64.deb..._putty软件怎么用麒麟

电子协会 C语言 1级 1 、 计算(a+b)/c 的值_c语言(a+b)/c-程序员宅基地

文章浏览阅读243次。给定 3 个整数 a、b、c,计算表达式(a+b)/c 的值,/是整除运算。(-10,000 < a,b,c< 10,000, c 不等于 0)输入仅一行,包括三个整数 a、b、c, 数与数之间以一个空格分开。输出一行,即表达式的值。_c语言(a+b)/c

图像视频滤镜算法---颜色滤镜_图像滤镜算法-程序员宅基地

文章浏览阅读8.9k次,点赞8次,收藏39次。 承接上一篇滤镜初识,本文将介绍第一种滤镜:颜色滤镜。颜色滤镜颜色滤镜即调色滤镜,也是最常见的滤镜,任何通过调节图像像素值的亮度、对比度、饱和度、色相等等方法,得到的不同于原图像颜色的效果,都统称为颜色滤镜。我们来做一个颜色增强滤镜,以此说明,方便大家更好的理解。如下图所示,我们对一副图在PS中进行饱和度调整(饱和度提高41):那么,我们在这个过程中,算法实际上做了..._图像滤镜算法

Android Lottie使用集成_android集成copylotit-程序员宅基地

文章浏览阅读2k次。Lottie是什么 Lottie是Airbnb 开源的一个项目,我在知道了这个项目后感觉真的遇见了新大陆一样 想必android开发的程序猿们都或多或少的为动画的实现苦恼过,或者都曾认为,动画这个实现在android的代码里总感觉会消耗系统的性能,那么今天说的这个Lottie,就解决了所有的烦恼,一起来看实现方法吧!走起来!!!!!首先说一下,动画效果是由UI 或者设计通过AE来_android集成copylotit

sql语句优化之一:尽量使用索引避免全表扫描_尽量避免在 where 子句中使用 != 或者 <> 操作符,查询引用会放弃索引而进行全表扫-程序员宅基地

文章浏览阅读1.1w次,点赞4次,收藏22次。1.对查询进行优化,应尽量避免全表扫描,首先应考虑在 where 及 order by 涉及的列上建立索引。 2.应尽量避免在 where 子句中对字段进行 null 值判断,否则将导致引擎放弃使用索引而进行全表扫描,如: select id from t where num is null 可以在num上设置默认值0,确保表中num列没有null值,然后这样查询: selec_尽量避免在 where 子句中使用 != 或者 <> 操作符,查询引用会放弃索引而进行全表扫