解决Java下载文件过大时,报下载超时错误(.pdf,.xlsx,...)

【Java端】实现过程(需要三个接口):

        1、创建文件(临时文件);

        2、监听文件(监听:文件是否创建成功;是否创建完成);

        3、下载文件。

1、创建文件(临时文件)

//创建文件
public String createFile() {
        //建议使用当前用户
        String id = "能够全局获取的唯一的值";
        //文件名称
        String fileName = "xxx_" + DateUtils.dateTimeNow();
        //用于监听文件是否生成完成
        redisCache.setCacheObject(id, "false", 1, TimeUnit.HOURS);
        redisCache.setCacheObject(id+ "downloadFile", fileName, 1, TimeUnit.HOURS);
        //开启新的线程,用于制作文件
        CompletableFuture.runAsync(() -> {
            try {
                creatPrintPDF(fileName);
            } catch (Exception e) {
                //文件制作失败
                redisCache.setCacheObject(id, "true", 1, TimeUnit.HOURS);
                redisCache.setCacheObject(id+ "errMessage", 
                  ExceptionUtil.getRootErrorMessage(e), 1, TimeUnit.HOURS);
            } finally {
                //文件创建成功后,删除缓存中文件名称
                redisCache.deleteObject(id+ "downloadFile");
            }
        });
        //返回文件名称+扩展名
        return fileName + ".xxx";
    }

//创建文件
private void creatPrintPDF(String fileName) {
        try {
            // 1.新建document对象
            Document document = new Document(PageSize.A4.rotate());// 建立一个Document对象
            File file = new File("D:\\files\\" + fileName + ".pdf");
            // 2.建立一个书写器(Writer)与document对象关联
            PdfWriter writer = PdfWriter.getInstance(document, new FileOutputStream(file));
            // 3.打开文档
            document.open();
            Paragraph paragraphs22 = new Paragraph();
            PdfPTable tables3v = new PdfPTable(new float[]{2f, 3, 3.5f, 2, 3, 1.5f, 3, 5, 2.5f, 4});
            tables3v.setHorizontalAlignment(Element.ALIGN_LEFT);
            tables3v.setWidthPercentage(100);
            tables3v.addCell(new Phrase(new Chunk("标题1 ", keyfont)));
            tables3v.addCell(new Phrase(new Chunk("标题1", keyfont)));
            tables3v.addCell(new Phrase(new Chunk("标题1", keyfont)));
            tables3v.addCell(new Phrase(new Chunk("标题1", keyfont)));
            tables3v.addCell(new Phrase(new Chunk("标题1", keyfont)));
            tables3v.addCell(new Phrase(new Chunk("标题1", keyfont)));
            tables3v.addCell(new Phrase(new Chunk("标题1", keyfont)));
            tables3v.addCell(new Phrase(new Chunk("标题1", keyfont)));
            tables3v.addCell(new Phrase(new Chunk("标题1", keyfont)));
            tables3v.addCell(new Phrase(new Chunk("标题1", keyfont)));
            for (int i=0;i<200000;i++){
                tables3v.setHorizontalAlignment(Element.ALIGN_LEFT);
                tables3v.setWidthPercentage(100);
                tables3v.addCell(new Phrase(new Chunk("1 ", keyfont)));
                tables3v.addCell(new Phrase(new Chunk("2", keyfont)));
                tables3v.addCell(new Phrase(new Chunk("i+3", keyfont)));
                tables3v.addCell(new Phrase(new Chunk("i+3", keyfont)));
                tables3v.addCell(new Phrase(new Chunk("i+3", keyfont)));
                tables3v.addCell(new Phrase(new Chunk("i+3", keyfont)));
                tables3v.addCell(new Phrase(new Chunk("i+3", keyfont)));
                tables3v.addCell(new Phrase(new Chunk("i+1", keyfont)));
                tables3v.addCell(new Phrase(new Chunk("i+2", keyfont)));
                tables3v.addCell(new Phrase(new Chunk("i+1", keyfont)));
            }
            paragraphs22.add(tables3v);
            document.add(paragraphs22);
            document.newPage();
            // 5.关闭文档
            document.close();
        } catch (Exception e) {
            throw new ServiceException("文件创建失败", 500);
        }
    }

2、监听文件(监听:文件是否创建成功;是否创建完成)   

//监听文件
public boolean listeningFile() {
        //获取唯一值(建议使用用户)
        String id= "能够全局获取的唯一值";
        //redisCache.getCacheObject(id)=true时,文件创建失败
        if ("true".equals(redisCache.getCacheObject(id))) {
            //清空Redis缓存值
            redisCache.deleteObject(id);
            //抛出异常
            throw new ServiceException(redisCache.getCacheObject(id+ "errMessage"), 500);
        }
        //文件正在创建中(redisCache.getCacheObject(id)=false)
        if ("false".equals(redisCache.getCacheObject(id)) 
               && redisCache.hasKey(id+ "downloadFile")) {
            return false;
        }
        //文件创建成功
        return true;
    }

   3.1、下载文件

//下载文件
public void dowmloadFile(String fileName,HttpServletResponse response) {
        //使用封装方法下载文件
        fileUploadUtils.downLoadFileUtil(fileName, response);
    }

3.2、文件下载通用方法

 /**
   * 下载文件
   *
   * @param fileName 文件名
   * @param response 响应
   */
public void downLoadFileUtil(String fileName, HttpServletResponse response) {
        //判断文件是否存在
        if (!new File(downloadUrl + fileName).exists()) {
            throw new ServiceException(fileName + "文件不存在!");
        }
        BufferedInputStream bis = null;
        BufferedOutputStream bos = null;
        try {
            bis = new BufferedInputStream(new FileInputStream(downloadUrl + fileName));
            response.setContentType("text/html;charset=UTF-8");
            response.setContentType("application/octet-stream");
            response.setHeader("Content-disposition", "attachment; filename=" + 
            java.net.URLEncoder.encode(fileName, "UTF-8"));
            bos = new BufferedOutputStream(response.getOutputStream());
            byte[] buff = new byte[2048];
            int bytesRead;
            while (-1 != (bytesRead = bis.read(buff, 0, buff.length))) {
                bos.write(buff, 0, bytesRead);
            }
            bos.flush();
            bos.close();
        } catch (Exception ex) {
            throw new ServiceException(ex.getMessage());
        } finally {
            try {
                if (bis != null) {
                    bis.close();
                }
                if (bos != null) {
                    bos.close();
                }
            } catch (Exception e) {
                log.info("文件关闭异常,异常信息为:,{}", e);
                e.printStackTrace();
            }
        }
    }

【前端】

    downloadFile(row) {
      var that = this
      this.$confirm({
        title: '提示',
        content: '是否打印XXX',
        onOk() {
          return new Promise((resolve, reject) => {
            createPdfFileApi(row).then((res) => {
              if (res.code === 200) {
                // 得到文件名
                var fileName = res.msg
                var settime = setInterval(async () => {
                  let fileExist = await fileIsSuccessApi()
                  if (fileExist.code === 200 && fileExist.data) {
                    clearInterval(settime)
                    that.download('/dowmloadFile', { pp: fileName }, fileName)
                  }
                }, 1000 * 2)
              }
            })
          }).catch(() => {
            console.log('Oops errors!')
          });

        },
      })
    },

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值