Poi excel多线程导出

Apache POI是Apache提供给java来实现对office文件的读写的一套api

  • Api地址
  • jar包下载
  • 代码

Api地址

讲导出之前,首先把Apache POI的api地址贴一下,点击这里查看

jar包下载

jar包可以从apache poi官网下载

代码

框架 struts+hibernate
这边不提供真实数据,

Action

首先要定义以下四个参数,和他们的get,set方法

// 导出的文件的输出流
private InputStream zipFile;
// 文件的下载名
private String zipFileName;
// 页面判断excelzip是否成功
private static boolean state;
private static final String REGISTER_EXPORT_NAME="申请单查询结果";
public InputStream getZipFile() {
        return zipFile;
    }

    public void setZipFile(InputStream zipFile) {
        this.zipFile = zipFile;
    }

    public String getZipFileName() {
        String fileName = REGISTER_EXPORT_NAME+"导出.zip";
        try {
            this.zipFileName = new String(fileName.getBytes(), "ISO8859-1");
        } catch (Exception e) {
        }
        return zipFileName;
    }

    public void setZipFileName(String zipFileName) {
        this.zipFileName = zipFileName;
    }

    public static boolean isState() {
        return state;
    }

    public static void setState(boolean state) {
        RegisterSearchAction.state = state;
    }

因为打包时间较长,前端页面有遮罩层来阻止用户进行其他操作,当操作完成,通过ajax请求后台,获得true结果,则遮罩层消失

    /**
     * 判断excel生成打包是否成功
     * 
     * @return
     */
    public String exportState() {
        ActionContext ac = ActionContext.getContext();
        HttpServletResponse response = (HttpServletResponse) ac.get(StrutsStatics.HTTP_RESPONSE);
        response.setCharacterEncoding("utf-8");
        Gson json = new Gson();
        String result = json.toJson(state);
        try {
            response.getWriter().write(result);
        } catch (IOException e) {
            e.printStackTrace();
        }
        return null;
    }

导出采用流的形式导出

    /**
     * 导出Excel
     * 
     * @return
     * @throws Exception 
     */
    public String reportExport() throws Exception {
        state = false;
        init();
        getZipFileName();
        if(cond == null){
            cond = new RegisterCondition();
        }

        Calendar calendar = new GregorianCalendar();
        Date sDate = null;
        Date eDate = null;
        if(cond.getEndTime() != null){
            Date end = cond.getEndTime();
            calendar.setTime(end);
            calendar.add(Calendar.SECOND, 86399);
            end = calendar.getTime();
            eDate = end;
        } 

        if(cond.getStartTime() != null){
            Date strat = cond.getStartTime();
            calendar.setTime(strat);
            calendar.add(Calendar.SECOND, -1);
            strat = calendar.getTime();
            sDate = strat;
        }

        if(model == null){
            model = new PageModel<>();
        }
        LoginVO login = getLoginInSession();
        File zip = new File(zipFileName);
        List<String> fileNames = regServ.toExcel(REGISTER_EXPORT_NAME, login, cond, sDate, eDate);
        File file[] = new File[fileNames.size()];
        for (int i = 0; i < fileNames.size(); i++) {
            file[i] = new File(fileNames.get(i));
        }
        try {
            createZip(file, zip);
        } catch (IOException e) {
            e.printStackTrace();
        }
        FileInputStream in;
        ByteArrayOutputStream output = new ByteArrayOutputStream();
        try {
            in = new FileInputStream(zip);
            byte[] buff = new byte[4096];
            int len;

            while ((len = in.read(buff)) > 0) {
                output.write(buff, 0, len);
                byte[] ba = output.toByteArray();
                zipFile = new ByteArrayInputStream(ba);
            }
            in.close();
            zip.delete();
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            try {
                output.flush();
                output.close();
                SimpleDateFormat sdf = new SimpleDateFormat(
                        "yyyy-MM-dd HH:mm:ss");
                LogVO log = new LogVO(YesOrNo.YES, getLoginInSession(),LogType.WEB, REGISTER_EXPORT_NAME+"导出", login.getLoginName()+ sdf.format(new Date())+REGISTER_EXPORT_NAME+"导出");
                BossLogServer.getInstance().log(log);
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
        state = true;
        return "record_export";
    }

因为导出数据较大,都在一个excel里面可能会导致报错,所以这边导出使用分表,同时打包的形式输出

    /**
     * 将文件压缩成zip
     * 
     * @param srcfile
     * @param zipFile
     * @throws IOException
     */
    public void createZip(File[] srcfile, File zipFile) throws IOException {
        if (zipFile.exists()) {
            // 根据抽象路径创建一个新的空文件
            zipFile.createNewFile();
        }
        ZipOutputStream out = new ZipOutputStream(new FileOutputStream(zipFile));
        for (int i = 0; i < srcfile.length; i++) {
            File tempFile = srcfile[i];
            FileInputStream in = new FileInputStream(tempFile);
            // 创建子文件
            out.putNextEntry(new ZipEntry(srcfile[i].getName()));
            byte[] buff = new byte[1024];
            int len;
            while ((len = in.read(buff)) > 0) {
                out.write(buff, 0, len);
            }
            out.closeEntry();
            in.close();
            tempFile.delete();
        }
        out.close();
    }

Server

因为生成速度较慢,这边生成excel采用多线程线程池导出的形式

/**
     * 信息导出
     * @throws Exception 
     */
    @Override
    public List<String> toExcel(String appName, LoginVO login, RegisterCondition cond, Date sartDate, Date endDate) throws Exception {
        PageModel<VRegisterQuery> model = new PageModel<VRegisterQuery>();
        model.setPageSize(10000);
        model = query(cond, model, login, sartDate, endDate);
        int pageNum = model.getTotalRecords() / model.getPageSize() + 1;
        List<String> fileNames = new ArrayList<String>();
        // 创建线程池
        ExecutorService pool = Executors.newCachedThreadPool();
        // 计数器
        CountDownLatch doneSignal = new CountDownLatch(pageNum);
        for (int i = 0; i < pageNum; i++) {
            pool.submit(new ExcelRunnable(doneSignal, fileNames, i, appName, cond, model, login, sartDate, endDate));
        }
        // 等待线程执行
        doneSignal.await();
        pool.shutdown();
        return fileNames;
    }

    /**
     * 使row线程安全
     * @param sheet
     * @param rownum
     * @return
     */
    private static synchronized HSSFRow getRow(HSSFSheet sheet, int rownum) {  
        return sheet.createRow(rownum);
    }  

    /**
     * 生成excel线程
     * @author tuchunwei
     *
     */
    private class ExcelRunnable implements Runnable {

        private final CountDownLatch doneSignal;
        private String appName;
        private RegisterCondition cond;
        private PageModel<VRegisterQuery> model;
        private LoginVO login;
        private Date sartDate;
        private Date endDate;
        private int i;
        private List<String> fileNames;

        public ExcelRunnable(CountDownLatch doneSignal, List<String> fileNames, int i, String appName, RegisterCondition cond,
                PageModel<VRegisterQuery> model, LoginVO login, Date sartDate, Date endDate) {
            this.i = i;
            this.appName = appName;
            this.cond = cond;
            this.model = model;
            this.login = login;
            this.sartDate = sartDate;
            this.endDate = endDate;
            this.fileNames = fileNames;
            this.doneSignal = doneSignal;
        }

        @Override
        public void run() {
            // 得到报表标题和sheet页标题
            String title = appName + "导出";
            String sheetName = appName + "导出";
            String fileName = appName + "表" + (i + 1) + ".xls";
            model.setPageNo(i + 1);
            // 得到第二行的所有标题,及各属性
            String headers[] = { "时间", "名称", "应用名称", "证书类型(机构/用户)", "有效期", "证书策略", 
                    "收费策略", "业务类型", "状态", "证书序列号", "介质序列号" };
            model = exportQuery(cond, model, login, sartDate, endDate);
            HSSFWorkbook book = null;
            try {
                book = createExcel(model, cond, title, headers, sheetName);
            } catch (ParseException e2) {
                e2.printStackTrace();
            }
            FileOutputStream output = null;
            try {
                output = new FileOutputStream(fileName);
                fileNames.add(fileName);
            } catch (FileNotFoundException e1) {
                e1.printStackTrace();
            }
            try {
                book.write(output);
                output.flush();
                output.close();
            } catch (IOException e) {
                e.printStackTrace();
            } finally {
                // 线程计数-1
                doneSignal.countDown();
            }
        }
    }
    /**
     * excel
     */
    public HSSFWorkbook createExcel(PageModel<VRegisterQuery> model, RegisterCondition cond, String title, String headers[], String sheetName) throws ParseException {
        HSSFRow row;
        HSSFCell cell;
        // 创建工作簿对象
        HSSFWorkbook hssfWorkBook = new HSSFWorkbook();
        // 创建 sheet 页,页名称
        HSSFSheet sheet = hssfWorkBook.createSheet();
        hssfWorkBook.setSheetName(0, sheetName);

        // 设置列宽
        this.setSheetColumnWidth(sheet);
        // 创建行 创建单元格,为单元格填充值,第一行为标题,合并单元格
        row = getRow(sheet,0);
        row.setHeightInPoints(40);
        cell = row.createCell(0);
        cell.setCellValue(title);
        cell.setCellStyle(getTitleStyle(hssfWorkBook));
        sheet.addMergedRegion(new CellRangeAddress(0, (short) 0, 0, (short)(headers.length-1)));
        HSSFCellStyle filterStyle = getFilterStyle(hssfWorkBook);
        row = getRow(sheet,1);
        row.setHeightInPoints(25);
        cell = row.createCell(0);
        StringBuffer buffer = new StringBuffer();
        buffer.append("时间:");
        if(cond.getStartTime()!=null && cond.getEndTime()!=null){
            SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
            buffer.append(sdf.format(cond.getStartTime()) + " 至 " + sdf.format(cond.getEndTime()));
        } else if(cond.getStartTime()!=null && cond.getEndTime()==null){
            SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
            buffer.append(sdf.format(cond.getStartTime()) + " 至 今");
        } else if(cond.getStartTime()==null && cond.getEndTime()!=null){
            SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
            buffer.append("截止到 "+sdf.format(cond.getStartTime()));
        } else if(cond.getStartTime()==null && cond.getEndTime()==null){
            buffer.append("所有");
        }
        buffer.append(" 应用:");
        if(StringUtils.isNotBlank(cond.getAppId())){
            TbApp app = getAppById(cond.getAppId());
            buffer.append(app.getName());
        }else{
            buffer.append("所有");
        }
        buffer.append(" 证书策略:");
        if(StringUtils.isNotBlank(cond.getCertPolicy())){
            TbCertPolicy policy = getPolicyById(cond.getCertPolicy());
                buffer.append(policy.getName());
        }else{
            buffer.append("所有");
        }
        buffer.append(" 收费策略:");
        if(StringUtils.isNotBlank(cond.getFeeScale())){
            TbAppFeeScale feeScale = getFeeScalesById(cond.getFeeScale());
            buffer.append(feeScale.getFeeName());
        }else{
            buffer.append("所有");
        }
        cell.setCellValue(buffer.toString());
        cell.setCellStyle(filterStyle);
        sheet.addMergedRegion(new CellRangeAddress(1, (short) 1, 0, (short)(headers.length-1)));

        HSSFCellStyle styleContext = getContextStyle(hssfWorkBook);
        // 产生表格第二行: 属性行
        row = getRow(sheet,2);
        row.setHeightInPoints(18);
        for (int i = 0; i < headers.length; i++) {
            cell = row.createCell(i);
            cell.setCellStyle(getHeaderStyle(hssfWorkBook));
            cell.setCellValue(headers[i]);
        }
        for (int i = 0; i < model.getList().size(); i++) {
            row = getRow(sheet,(short) (i + 3));
            row.setHeightInPoints(18);
            //更新时间
            cell = row.createCell(0);
            if (model.getList().get(i).getModifyTime()==null) {
                cell.setCellValue("");
            } else {
                SimpleDateFormat sdf = new SimpleDateFormat("yyyy/MM/dd HH:mm");
                cell.setCellValue(sdf.format(model.getList().get(i).getModifyTime()));
            }
            cell.setCellStyle(styleContext);
            //证书名称
            cell = row.createCell(1);
            if (StringUtils.isBlank(model.getList().get(i).getSubscriberName())) {
                cell.setCellValue("");
            } else {
                cell.setCellValue(model.getList().get(i).getSubscriberName());
            }
            cell.setCellStyle(styleContext);
            //应用名称
            cell = row.createCell(2);
            if (StringUtils.isBlank(model.getList().get(i).getAppName())) {
                cell.setCellValue("");
            } else {
                cell.setCellValue(model.getList().get(i).getAppName());
            }
            //证书类型(机构/用户)
            cell = row.createCell(3);
            if (model.getList().get(i).getCertType() == null) {
                cell.setCellValue("");
            } else {
                cell.setCellValue(CertificateType.toEnum(model.getList().get(i).getCertType()).getDesc());
            }
            cell.setCellStyle(styleContext);
            //有效期
            cell = row.createCell(4);
            String validity = getCertValidity(model.getList().get(i).getPolicyId(), model.getList().get(i).getFeeScaleId(), model.getList().get(i).getBizType());
            if (StringUtils.isBlank(validity)) {
                cell.setCellValue("");
            } else {
                cell.setCellValue(validity);
            }
            //证书策略
            cell = row.createCell(5);
            if (StringUtils.isBlank(model.getList().get(i).getPolicyId())) {
                cell.setCellValue("");
            } else {
                TbCertPolicy policy = getPolicyById(model.getList().get(i).getPolicyId());
                if(policy!=null){
                    cell.setCellValue(policy.getName());
                }
            }
            //收费策略
            cell = row.createCell(6);
            if (StringUtils.isBlank(model.getList().get(i).getFeeScaleId())) {
                cell.setCellValue("");
            } else {
                TbAppFeeScale feeScale = getFeeScalesById(model.getList().get(i).getFeeScaleId());
                if(feeScale!=null){
                    cell.setCellValue(feeScale.getFeeName());
                }
            }
            //业务类型
            cell = row.createCell(7);
            Integer bizType = model.getList().get(i).getBizType();
            if (bizType == null) {
                cell.setCellValue("");
            } else {
                cell.setCellValue(BizType.toEnum(bizType).getDesc());
            }
            //状态
            cell = row.createCell(8);
            Integer status = model.getList().get(i).getStatus();
            if (bizType == null) {
                cell.setCellValue("");
            } else {
                cell.setCellValue(RegisterStatusType.toEnum(status).getDesc());
            }
            //证书序列号
            cell = row.createCell(9);
            if (StringUtils.isBlank(model.getList().get(i).getCertSn())) {
                cell.setCellValue("");
            } else {
                cell.setCellValue(model.getList().get(i).getCertSn());
            }
            //介质编号
            cell = row.createCell(10);
            if (StringUtils.isBlank(model.getList().get(i).getKeySn())) {
                cell.setCellValue("");
            } else {
                System.out.println(model.getList().get(i).getKeySn());
                cell.setCellValue(model.getList().get(i).getKeySn());
            }
        }
        return hssfWorkBook;
    }

excel配置

    /**
     * 设置列宽
     * @param sheet
     */
    public void setSheetColumnWidth(HSSFSheet sheet) {
        sheet.setColumnWidth(0, 5000);
        sheet.setColumnWidth(1, 8000);
        sheet.setColumnWidth(2, 5000);
        sheet.setColumnWidth(3, 5000);
        sheet.setColumnWidth(4, 3000);
        sheet.setColumnWidth(5, 8000);
        sheet.setColumnWidth(6, 10000);
        sheet.setColumnWidth(7, 3000);
        sheet.setColumnWidth(8, 3000);
        sheet.setColumnWidth(9, 5000);
        sheet.setColumnWidth(10, 5000);
        sheet.setColumnWidth(11, 2000);
        sheet.setColumnWidth(12, 2000);
        sheet.setColumnWidth(13, 2000);
        sheet.setColumnWidth(14, 2000);
        sheet.setColumnWidth(15, 2000);
        sheet.setColumnWidth(16, 2000);
        sheet.setColumnWidth(17, 2000);
        sheet.setColumnWidth(18, 2000);
        sheet.setColumnWidth(19, 2000);
        sheet.setColumnWidth(20, 2000);
        sheet.setColumnWidth(21, 2000);
        sheet.setColumnWidth(22, 2000);
        sheet.setColumnWidth(23, 2000);
    }

    /**
     * 第二行样式
     * @param workbook
     * @return
     */
    public HSSFCellStyle getHeaderStyle(HSSFWorkbook workbook) {
        HSSFCellStyle style = workbook.createCellStyle();
        // 设置这些样式
        style.setBorderBottom(HSSFCellStyle.BORDER_MEDIUM);
        style.setBorderLeft(HSSFCellStyle.BORDER_MEDIUM);
        style.setBorderRight(HSSFCellStyle.BORDER_MEDIUM);
        style.setBorderTop(HSSFCellStyle.BORDER_MEDIUM);
        style.setAlignment(HSSFCellStyle.ALIGN_LEFT);
        style.setVerticalAlignment(HSSFCellStyle.VERTICAL_CENTER);// 垂直居中
        // 边框颜色
        style.setTopBorderColor(HSSFColor.VIOLET.index);
        style.setBottomBorderColor(HSSFColor.VIOLET.index);
        style.setLeftBorderColor(HSSFColor.VIOLET.index);
        style.setRightBorderColor(HSSFColor.VIOLET.index);

        return style;
    }

    /**
     * 标题样式
     * @param workbook
     * @return
     */
    public HSSFCellStyle getTitleStyle(HSSFWorkbook workbook) {
        HSSFCellStyle style = workbook.createCellStyle();
        style.setAlignment(HSSFCellStyle.ALIGN_CENTER); // 字体居中
        style.setVerticalAlignment(HSSFCellStyle.VERTICAL_CENTER);// 垂直居中
        HSSFFont font = workbook.createFont();
        font.setFontName("宋体");
        font.setFontHeightInPoints((short) 16);
        font.setBoldweight(HSSFFont.BOLDWEIGHT_BOLD);// 加粗
        style.setFont(font);
        return style;
    }

    /**
     * 正文样式
     * @param workbook
     * @return
     */
    public HSSFCellStyle getContextStyle(HSSFWorkbook workbook) {
        HSSFCellStyle style = workbook.createCellStyle();
        style.setAlignment(HSSFCellStyle.ALIGN_LEFT);
        style.setVerticalAlignment(HSSFCellStyle.VERTICAL_CENTER);// 垂直居中
        return style;
    }
    /**
     * 筛选条件样式
     * @param workbook
     * @return
     */
    public HSSFCellStyle getFilterStyle(HSSFWorkbook workbook) {
        HSSFCellStyle style = workbook.createCellStyle();
        style.setAlignment(HSSFCellStyle.ALIGN_CENTER); // 字体居中
        style.setVerticalAlignment(HSSFCellStyle.VERTICAL_CENTER);// 垂直居中
        HSSFFont font = workbook.createFont();
        font.setFontName("宋体");
        font.setFontHeightInPoints((short) 12);
        style.setFont(font);
        return style;
    }
    @Override
    public PageModel<VRegisterQuery> exportQuery(RegisterCondition cond,
            PageModel<VRegisterQuery> model, LoginVO login, Date sartDate, Date endDate) {
        Session session = BossSessionFactory.getSession();
        Transaction t = session.beginTransaction();
        try {
            IAppDao appDao = new AppDao(session);
            List<TbApp> apps = appDao.getApps(login);
            if (apps != null && apps.size() > 0) {
                IRegisterDao regDao = new RegisterDao(session);
                model = regDao.query(cond, model, apps, sartDate, endDate);
            } else {
                model.setList(null);
            }
            t.commit();
        } finally {
            session.close();
        }
        return model;
    }

dao

dao层这边不提供代码,自己把数据封装成一个PageModel,以类似分页的形式,分表

package zjca.common.web;

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

import zjca.common.config.CommonReadOnlyConfig;


public class PageModel<E> {
    /*
     * 显示的页数
     * 分页显示格式: 1 ... 3 4 5 6 7 ...9
     * */
    private static final int PAGES = 5;

    public PageModel(){
        this(CommonReadOnlyConfig.getInstance().defaultPageSize);
//      this(1);
    }

    public PageModel(int pageSize){
        this.totalRecords = 0;
        this.pageSize = pageSize;
        this.pageNo = 1;
    }

    // 结果集
    private List<E> list;
    // 查询记录数
    private int totalRecords;
    // 每页多少条数据
    private int pageSize;
    // 第几页
    private int pageNo;
    //排序列名
    private String orderColumn;
    //是否顺序排列
    private boolean isAsc;

    /**
     * 总页数
     * 
     * @return
     */
    public int getTotalPages() {
        return (totalRecords + pageSize - 1) / pageSize;
    }

    /**
     * 取得首页
     * 
     * @return
     */
    public int getTopPageNo() {
        return 1;
    }

    public List<E> getList() {
        return list;
    }

    public void setList(List<E> list) {
        this.list = list;
    }

    public int getTotalRecords() {
        return totalRecords;
    }

    public void setTotalRecords(int totalRecords) {
        this.totalRecords = totalRecords;
    }

    public int getPageSize() {
        return pageSize;
    }

    public void setPageSize(int pageSize) {
        this.pageSize = pageSize;
    }

    public int getPageNo() {
        return pageNo;
    }

    public void setPageNo(int pageNo) {
        this.pageNo = pageNo;
    }

    public int getFirstResult(){
        return (pageNo - 1) * pageSize;
    }

    /**
     * 获取分页
     * */
    public List<Integer> getPages(){
        List<Integer> list = new ArrayList<>();
        int totalPage = getTotalPages();
        if(totalPage < PAGES){
            for(int i = 1; i <= totalPage; i++){
                list.add(i);
            }
        } else {
            int range = PAGES / 2;
            int tmp = pageNo - range ;
            if(isShowFrontPoint()){
                while(range > 0 ){
                    list.add(tmp);
                    tmp ++;
                    range --;
                }
            } else {
                tmp = 1;
                while(tmp < pageNo){
                    list.add(tmp);
                    tmp ++;
                }
            }
            list.add(pageNo);

            if(isShowEndPoint()){
                range = PAGES / 2;
                tmp = pageNo + 1;
                while(range > 0){
                    list.add(tmp);
                    tmp ++;
                    range -- ;
                }
            } else {
                tmp = pageNo + 1;
                while(tmp <= totalPage){
                    list.add(tmp);
                    tmp ++;
                }
            }
        }
        return list;
    }

    public int getPrePage(){
        int tmp = pageNo - 1;
        if(tmp < getTopPageNo()){
            tmp = getTopPageNo();
        }
        return tmp;
    }

    public int getNextPage(){
        int tmp = pageNo + 1;
        if(tmp > getTotalPages()){
            tmp = getTotalPages();
        }
        return tmp;
    }

    /**
     * 是否显示前面的省略号
     * */
    public boolean isShowFrontPoint(){
        int range = PAGES / 2;
        int totalPage = getTotalPages();
        int tmp = pageNo - range  - 1;
        if(tmp > 0 && totalPage > 4){
            return true;
        } else {
            return false;
        }
    }

    /**
     * 是否显示后端的省略号
     * */
    public boolean isShowEndPoint(){
        int range = PAGES / 2;
        int totalPage = getTotalPages();
        int tmp = pageNo + range + 1 ;
        if(totalPage <= tmp){
            return false;
        } else {
            return true;
        }
    }

    /**
     * 当前页是否为首页
     * */
    public boolean isFirstPage(){
        if(pageNo == getTopPageNo()){
            return true;
        } else {
            return false;
        }
    }

    public boolean isLastpage(){
        if(pageNo == getTotalPages()){
            return true;
        } else {
            return false;
        }
    }

    public String getOrderColumn() {
        return orderColumn;
    }

    public void setOrderColumn(String orderColumn) {
        this.orderColumn = orderColumn;
    }

    public boolean isAsc() {
        return isAsc;
    }

    public void setAsc(boolean isAsc) {
        this.isAsc = isAsc;
    }
}

struts文件配置

<action name="search/*" method="{1}" class="zjca.certificate.web.action.RegisterSearchAction">
    <result name="reg_list">/WEB-INF/page/cert/reg_list.jsp</result>
    <result name="record_export" type="stream">
        <param name="contentType">application/x-zip-compressed</param>
        <param name="contentDisposition">attachment;filename="${zipFileName}"</param>
        <param name="bufferSize">4096</param>
        <param name="inputName">zipFile</param>
    </result>
</action>

Jsp页面请求


function exportExport(target){
        $.fn.jqLoading({ height: 100, width: 240, text: "正在加载中,请耐心等待...." });
        $('.J_cert_app').css('border','2px solid #dadada');
        $(target).css('border','2px solid #32a5e7');
        /* document.getElementById("reportExport").action="cert/export/reportExport.htm";
        document.getElementById("reportExport").submit(); */
        var timer = setInterval(function getState(){
        //判断是否生成excel成功
        $.ajax({
            url:"cert/ent/exportState.htm",
            type:"POST",
            data:"",
            datatype:"String",
            success:function (data){
                    if(data == "true"){
                        $.fn.jqLoading("destroy");
                        clearInterval(timer);
                    }
                }
            });
        },100);
        document.getElementById("search").action="cert/ent/reportExport.htm";
        document.getElementById("search").submit();
    }
  • 5
    点赞
  • 35
    收藏
    觉得还不错? 一键收藏
  • 11
    评论
Java POI提供了一种多线程导出Excel的方式,可以提高导出效率。 以下是一个简单的示例代码: ```java public class ExcelExportThread extends Thread { private Workbook workbook; private OutputStream outputStream; public ExcelExportThread(Workbook workbook, OutputStream outputStream) { this.workbook = workbook; this.outputStream = outputStream; } @Override public void run() { try { workbook.write(outputStream); } catch (IOException e) { e.printStackTrace(); } finally { try { outputStream.close(); } catch (IOException e) { e.printStackTrace(); } } } } public class ExcelExporter { public static void export(List<List<Object>> dataList, int sheetSize, OutputStream outputStream) { Workbook workbook = new XSSFWorkbook(); int dataSize = dataList.size(); int sheetNum = dataSize % sheetSize == 0 ? dataSize / sheetSize : dataSize / sheetSize + 1; CountDownLatch latch = new CountDownLatch(sheetNum); for (int i = 0; i < sheetNum; i++) { int start = i * sheetSize; int end = Math.min(start + sheetSize, dataSize); List<List<Object>> subList = dataList.subList(start, end); ExcelExportThread thread = new ExcelExportThread(createSheet(workbook, subList), outputStream); thread.start(); thread.setUncaughtExceptionHandler((t, e) -> { // 异常处理 }); thread.setContextClassLoader(null); thread.setName("ExcelExportThread-" + i); thread.setPriority(Thread.NORM_PRIORITY); thread.setDaemon(false); thread.start(); } try { latch.await(); } catch (InterruptedException e) { e.printStackTrace(); } } private static Sheet createSheet(Workbook workbook, List<List<Object>> dataList) { Sheet sheet = workbook.createSheet(); int rowIndex = 0; for (List<Object> rowData : dataList) { Row row = sheet.createRow(rowIndex++); int colIndex = 0; for (Object cellData : rowData) { Cell cell = row.createCell(colIndex++); cell.setCellValue(cellData.toString()); } } return sheet; } } ``` 该示例中,ExcelExporter类提供了一个静态方法export,用于导出Excel。该方法接收三个参数:数据列表、每个Sheet的最大行数、输出流。 export方法首先创建一个新的Workbook实例,然后根据每个Sheet的最大行数将数据列表拆分为多个子列表,并创建ExcelExportThread实例进行导出。每个ExcelExportThread实例会创建一个Sheet,并将数据写入Sheet中。多个线程同时导出,提高了导出效率。 在ExcelExportThread的run方法中,使用Workbook的write方法将数据写入输出流,导出Excel文件。导出完成后,关闭输出流。 在示例中,使用了CountDownLatch来等待所有线程导出完成。如果线程中出现异常,可以在ExcelExportThread的setUncaughtExceptionHandler方法中进行处理。其他线程属性设置可以根据实际情况进行调整。 需要注意的是,由于多线程导出Excel可能会占用大量的内存和CPU资源,可能会导致系统负载过高,因此需要根据实际情况进行调整。同时,多线程导出Excel也可能会导致导出结果的顺序发生变化,需要注意处理。
评论 11
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值