java导出excel浏览器下载,单线程VS多线程

java导出excel浏览器下载,单线程VS多线程

package com.mengyang.transactional.other.excelxssf;

import com.mengyang.transactional.other.myselfExcel.ExcelUtils;

import com.mengyang.transactional.pojo.ZhongXinDTO;

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

import org.apache.poi.xssf.streaming.SXSSFWorkbook;

import javax.servlet.http.HttpServletResponse;

import java.lang.reflect.Field;

import java.net.URLEncoder;

import java.util.Iterator;

import java.util.List;

import java.util.Objects;

import java.util.concurrent.CountDownLatch;

public class ExportExcelUtil {

复制代码
Class<T> clazz;

public ExportExcelUtil(Class<T> clazz) {
    this.clazz = clazz;
}

//单线程
public void exportExcel(HttpServletResponse response, String excelHeaer, int sheetNum, List<T> dataList) {
    SXSSFWorkbook workbook = new SXSSFWorkbook(-1);
    String fileName = "中信报表导出" + ".xlsx";
    try {
        //使用workbook对象创建样式对象
        CellStyle cellStyle = workbook.createCellStyle();
        //创建字体对象
        Font font = workbook.createFont();
        //处理表格头部信息
        String[] head = excelHeaer.split(",");
        // 得到目标目标类的所有的字段列表
        Field[] fields = clazz.getDeclaredFields();
        for (Field field : fields) {
            field.setAccessible(true);
        }
        Sheet sheet = workbook.createSheet("XXX");
        ExcelUtils.setCellStyle(sheet, cellStyle, font);

        //遍历集合中的数据
        Iterator<T> iterator = dataList.iterator();
        int currentRow = 0;
        //写入头信息
        Row row = sheet.createRow(currentRow);
        for (int i = 0; i < head.length; i++) {
            Cell cell = row.createCell(i);
            cell.setCellValue(head[i]);
            cell.setCellStyle(cellStyle);
        }
        currentRow++;
        //写入业务数据
        while (iterator.hasNext()) {
            T t = iterator.next();
            row = sheet.createRow(currentRow);
            for (int i = 0; i < fields.length; i++) {
                Cell cell = row.createCell(i);
                cell.setCellValue(String.valueOf(fields[i].get(t)));
                cell.setCellStyle(cellStyle);
            }
            currentRow++;
        }
        //下载
        response.reset();
        response.setContentType("application/octet-stream; charset=utf-8");//以流的形式对文件进行下载
        response.setHeader("Content-Disposition", "attachment; filename=" + URLEncoder.encode(fileName, "UTF-8"));//对文件名编码,防止文件名乱码
        workbook.write(response.getOutputStream());
    } catch (Exception e) {
        e.printStackTrace();
    } finally {
        //删除之前保存的临时文件
        workbook.dispose();
    }
}


public void exportExcelAndMoreThread(HttpServletResponse response, String excelHeaer, int sheetNum, List<T> dataList) {
    SXSSFWorkbook workbook = new SXSSFWorkbook(-1);
    String fileName = "中信报表导出" + ".xlsx";
    try {
        //使用workbook对象创建样式对象
        CellStyle cellStyle = workbook.createCellStyle();
        //创建字体对象
        Font font = workbook.createFont();
        //处理表格头部信息
        String[] head = excelHeaer.split(",");
        CountDownLatch countDownLatch = new CountDownLatch(sheetNum);//倒计时开关
        // 得到目标目标类的所有的字段列表
        Field[] fields = clazz.getDeclaredFields();
        for (Field field : fields) {
            field.setAccessible(true);
        }

        //遍历集合中的数据
        //Iterator<T> iterator = dataList.iterator();
        int currentRow = 0;
        if (Objects.equals(0, sheetNum)) {//单线程处理
            Sheet sheet = workbook.createSheet("XXX");
            ExcelUtils.setCellStyle(sheet, cellStyle, font);
            //遍历集合中的数据
            Iterator<T> iterator = dataList.iterator();
            //写入头信息
            Row row = sheet.createRow(currentRow);
            for (int i = 0; i < head.length; i++) {
                Cell cell = row.createCell(i);
                cell.setCellValue(head[i]);
                cell.setCellStyle(cellStyle);
            }
            currentRow++;
            //写入业务数据
            while (iterator.hasNext()) {
                T t = iterator.next();
                row = sheet.createRow(currentRow);
                for (int i = 0; i < fields.length; i++) {
                    Cell cell = row.createCell(i);
                    cell.setCellValue(String.valueOf(fields[i].get(t)));
                    cell.setCellStyle(cellStyle);
                }
                currentRow++;
            }

        } else {
            int dataCount = dataList.size();//数据的长度//如何把list集合分成对应的份数,开几条线程就相当于把数据分成几份
            int avgNum = (int) Math.floor(dataCount / sheetNum);//获得平均值
            int remainder = dataCount % sheetNum;//最后有余数  102%4 =2
            int fromIndex = 0;
            int toIndex = 0;
            for (int i = 0; i < sheetNum; i++) {
                fromIndex = i * avgNum;
                if (i == sheetNum - 1) {
                    //最后一个线程被开启
                    toIndex = (i + 1) * avgNum - 1 + remainder;
                } else {
                    toIndex = (i + 1) * avgNum - 1;
                }

                //分解数据
                List<T> data = dataList.subList(fromIndex, toIndex + 1);
                Sheet sheet1 = workbook.createSheet("项目数据" + i);
                ExcelUtils.setCellStyle(sheet1, cellStyle, font);
                new Thread(() -> {
                    Iterator<T> iterator = data.iterator();
                    int startIndex = 0;
                    Row row = sheet1.createRow(startIndex);
                    for (int j = 0; j < head.length; j++) {
                        Cell cell = row.createCell(j);
                        cell.setCellValue(head[j]);
                        cell.setCellStyle(cellStyle);
                    }
                    startIndex++;
                    while (iterator.hasNext()) {
                        T t = iterator.next();
                        row = sheet1.createRow(startIndex);
                        for (int k = 0; k < fields.length; k++) {
                            Cell cell = row.createCell(k);
                            try {
                                cell.setCellValue(String.valueOf(fields[k].get(t)));
                                cell.setCellStyle(cellStyle);
                            } catch (IllegalAccessException e) {
                                e.printStackTrace();
                            }
                        }
                        startIndex++;
                    }
                    countDownLatch.countDown();
                }, "线程" + i).start();
            }
            //告诉主线程,要等所有的线程运行完再进行Excel的导出
            countDownLatch.await();
        }
        //下载
        response.reset();
        response.setContentType("application/octet-stream; charset=utf-8");//以流的形式对文件进行下载
        response.setHeader("Content-Disposition", "attachment; filename=" + URLEncoder.encode(fileName, "UTF-8"));//对文件名编码,防止文件名乱码
        workbook.write(response.getOutputStream());
    } catch (Exception e) {
        e.printStackTrace();
    } finally {
        //删除之前保存的临时文件
        workbook.dispose();
    }
}

}

相关推荐
拼搏@32 分钟前
第十六天,7月10日,八股
java·mybatis
Sylvia-girl4 小时前
Java——抽象类
java·开发语言
Yana.nice6 小时前
Bash函数详解
开发语言·chrome·bash
Touper.7 小时前
Redis 基础详细介绍(Redis简单介绍,命令行客户端,Redis 命令,Java客户端)
java·数据库·redis
m0_535064607 小时前
C++模版编程:类模版与继承
java·jvm·c++
虾条_花吹雪8 小时前
Using Spring for Apache Pulsar:Message Production
java·ai·中间件
tomorrow.hello8 小时前
Java并发测试工具
java·开发语言·测试工具
Moso_Rx8 小时前
javaEE——synchronized关键字
java·java-ee
晓13138 小时前
JavaScript加强篇——第四章 日期对象与DOM节点(基础)
开发语言·前端·javascript
老胖闲聊8 小时前
Python I/O 库【输入输出】全面详解
开发语言·python