导出word,以下为导出单个和zip的两种格式。

CountDownLatch运用
CountDownLatch和ExecutorService 线程池cachedThreadPool.submit

1、CountDownLatch 概念

CountDownLatch可以使一个获多个线程等待其他线程各自执行完毕后再执行。

CountDownLatch 定义了一个计数器,和一个阻塞队列, 当计数器的值递减为0之前,阻塞队列里面的线程处于挂起状态,当计数器递减到0时会唤醒阻塞队列所有线程,这里的计数器是一个标志,可以表示一个任务一个线程,也可以表示一个倒计时器,
CountDownLatch可以解决那些一个或者多个线程在执行之前必须依赖于某些必要的前提业务先执行的场景。

点击查看代码

    @Override
    public void batchExportWord(PreDefenceApplyDto preDefenceApplyDto) {
        SystemUserInfo loginUser = AuthorityUtil.getLoginUser();
        if (loginUser == null || StringUtils.isBlank(loginUser.getUserId())) {
            throw new ServiceException(SimpleErrorCode.UserNotLogin);
        }
        if(StringUtils.isBlank(preDefenceApplyDto.getGrade())){
            throw new ServiceException(301,"请选择年级");
        }
        String grade = preDefenceApplyDto.getGrade();
        List<String> collegeIds = preDefenceApplyDto.getCollegeIds();
        String majorId = preDefenceApplyDto.getMajorId();

        // 查询学生论文结果
        List<String> studentIds = preDefenceApplyMapper.selectHasResStu(grade,collegeIds,majorId);
        if(CollectionUtils.isEmpty(studentIds)){
            throw new ServiceException(302,"暂无审核通过的学生可导出");
        }
        //学校名称
        String schoolName = publicMapper.querySchoolName();

        FileOutputStream fileOutputStream = null;
        FileInputStream fileInputStream = null;
        BufferedInputStream bufferedInputStream = null;

        String downloadName = "情况表.zip";
        response.setContentType("application/zip;charset=utf-8");
        response.setHeader("Content-Disposition", "attachment;filename=" + Encodes.urlEncode(downloadName));
        String realPath = request.getSession().getServletContext().getRealPath("");

        try (
                OutputStream outputStream = response.getOutputStream();
                // 压缩流
                ZipOutputStream zos = new ZipOutputStream(outputStream)){

                ExecutorService cachedThreadPool = Executors.newFixedThreadPool(studentIds.size());
                CountDownLatch latch = new CountDownLatch(studentIds.size());
                for(String stuId : studentIds){
                    cachedThreadPool.submit(() -> {
                        try {
                            zipPreWord(  bufferedInputStream, zos,
                                    stuId, schoolName ,realPath);
                        } catch (IOException e) {
                            e.printStackTrace();
                        }
                        latch.countDown();
                    });
                }
                cachedThreadPool.shutdown();
                try {
                    latch.await();
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
        } catch (IOException e) {
            e.printStackTrace();
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            try {
                if (bufferedInputStream != null) {
                    bufferedInputStream.close();
                }
                if (fileInputStream != null) {
                    fileInputStream.close();
                }
                if (fileOutputStream != null) {
                    fileOutputStream.close();
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }
    public void zipPreWord( BufferedInputStream bufferedInputStream,ZipOutputStream zos,
                           String studentId,String schoolName ,String realPath) throws IOException {


        byte[] buffer = new byte[1024];
        int len = 0;

        PreDefenceApplyVo preDefenceApplyVo = preDefenceApplyMapper.resultQuery(studentId);
        String fileName =studentId+preDefenceApplyVo.getStudentName();
        fileName=fileName.replaceAll("/", "-")+"情况表.doc";
        String filePath = realPath + File.separator + fileName;

        File outFile = new File(filePath );

        Configuration configuration = new Configuration(Configuration.getVersion());
        configuration.setDefaultEncoding("UTF-8");
        configuration.setClassForTemplateLoading(this.getClass(), "/templates");

        Template template = null;
        try {
            template = configuration.getTemplate(schoolName + "情况表2.ftl"); 
        } catch (IOException e) {
            log.error("context", e);
            throw new ServiceException(SimpleErrorCode.ExecFailure);
        }

        Map<String, Object> params = new HashMap<>();
        params.put("preDefenceApplyVo", preDefenceApplyVo);
        params.put("schoolName", schoolName);
        try {
            BufferedWriter out = new BufferedWriter(new OutputStreamWriter(new FileOutputStream(outFile)));

            template.process(params, out);
        } catch (TemplateException e) {
            e.printStackTrace();
        }


        ZipEntry zipEntry = new ZipEntry(fileName);
        bufferedInputStream = new BufferedInputStream( new FileInputStream(outFile));
        zos.putNextEntry(zipEntry);
        while ((len = bufferedInputStream.read(buffer)) != -1) {
            zos.write(buffer, 0, len);
        }

    }
    @Override
    public void exportWord(PreDefenceApplyDto preDefenceApplyDto) {
        SystemUserInfo loginUser = AuthorityUtil.getLoginUser();
        if (loginUser == null) {
            throw new ServiceException(SimpleErrorCode.UserNotLogin);
        }
        String studentId = loginUser.getUserId();
        if (preDefenceApplyDto != null && StringUtils.isNotBlank(preDefenceApplyDto.getStudentId())) {
            studentId = preDefenceApplyDto.getStudentId();
        }
        //学校名称
        String schoolName = publicMapper.querySchoolName();

        PreDefenceApplyVo preDefenceApplyVo = preDefenceApplyMapper.resultQuery(studentId);

        String fileName = schoolName + "情况表.doc";
        response.setContentType("multipart/form-data");
        response.setHeader("Content-Disposition", "attachment;fileName=" + stringToUnicode(fileName));

        String filePath = request.getSession().getServletContext().getRealPath("/");


        OutputStream outputStream = null;
        try {
            outputStream = response.getOutputStream();
        } catch (IOException e) {
            e.printStackTrace();
        }

        Configuration configuration = new Configuration(Configuration.getVersion());
        configuration.setDefaultEncoding("UTF-8");
        configuration.setClassForTemplateLoading(this.getClass(), "/templates");

        Template template = null;
        try {
            template = configuration.getTemplate(schoolName + "情况表2.ftl"); 
        } catch (IOException e) {
            log.error("context", e);
            throw new ServiceException(SimpleErrorCode.ExecFailure);
        }

        Map<String, Object> params = new HashMap<>();
        params.put("preDefenceApplyVo", preDefenceApplyVo);
        params.put("schoolName", schoolName);

        File outFile = new File(filePath + "/" + fileName);
        byte[] buffer = new byte[1024];
        int len = 0;
        BufferedInputStream bufferedInputStream = null;
        try {

            BufferedWriter out = new BufferedWriter(new OutputStreamWriter(new FileOutputStream(outFile)));

            try {
                template.process(params, out);
            } catch (TemplateException e) {
                e.printStackTrace();
            }
            FileInputStream fileInputStream = new FileInputStream(outFile);
            bufferedInputStream = new BufferedInputStream(fileInputStream);
            while ((len = bufferedInputStream.read(buffer)) != -1) {
                outputStream.write(buffer, 0, len);
            }

            out.close();
            fileInputStream.close();
            bufferedInputStream.close();
        } catch (IOException e) {
            e.printStackTrace();
        }finally {
            if (outFile.exists()) {
                if (!outFile.delete()) {
                    log.info("删除失败!");
                }
            }
        }

    }