获取oss的pdf文件,返回文件输出流

获取oss的pdf文件,返回文件输出流

需求:oss上存储生成的pdf文件,通过存储的key,返回对应的PDF文件输出流

实现: 后端Java提供获取pdf文件的输出流,前端vue将文件流另存为PDF文件


接口代码实现:

import java.io.BufferedInputStream;
import java.io.InputStream;
import java.util.Objects;

import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletResponse;

import org.apache.commons.lang.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.aliyun.oss.model.OSSObject;
import com.sisensing.cgm.common.core.utils.ErrUtil;
import com.sisensing.cgm.system.domain.dto.ReportQueryDTO;
import com.sisensing.cgm.system.service.ICgmDownloadService;

import cn.hutool.core.io.IoUtil;
import org.springframework.stereotype.Service;

......

private static final Logger LOGGER = LoggerFactory.getLogger(CgmDownloadServiceServiceImpl.class);

    @Override
    public void getReportFileStream(ReportQueryDTO reportQueryDTO, HttpServletResponse response) {
        // 报告尚未生成pdf报告
        ErrUtil.throwIfTrue(StringUtils.isEmpty(reportQueryDTO.getPdfKey()), REPORT_HAS_NOT_PDF,
            String.format("pdfKey不允许为空"));
        OSSObject ossObject = this.getServiceFactory().getOssService().downloadOssFile(reportQueryDTO.getPdfKey());
        ServletOutputStream out = null;
        if (Objects.nonNull(ossObject)) {
            InputStream inputStream = ossObject.getObjectContent();
            BufferedInputStream bis = new BufferedInputStream(inputStream);
            int buffer = 1024 * 10;
            byte[] data = new byte[buffer];
            try {
                response.setContentType("application/pdf");
                // 文件名可以任意指定
                long timeId = System.currentTimeMillis();
                response.setHeader("Content-Disposition", "attachment;fileName=" + timeId + ".pdf");
                int read;
                out = response.getOutputStream();
                while ((read = bis.read(data)) != -1) {
                    out.write(data, 0, read);
                }
                out.flush();
            } catch (Exception ex) {
                IoUtil.close(out);
                LOGGER.error("下载PDF报告失败", ex);
                ErrUtil.throwNow(GET_REPORT_STREAM_FAIL, String.format("pdfKey为[%s]", reportQueryDTO.getPdfKey()));
            } finally {
                IoUtil.close(ossObject);
            }
        }
    }
    
    ......

     @Autowired
    private OSSClient ossClient;

    @Autowired
    private OSSProperties ossProperties;
    
    /**
     * 下载oss存储的文件对象
     *
     * @param key
     * @return
     */
    public OSSObject downloadOssFile(String key) {
        return ossClient.getObject(ossProperties.getBucketName(), key);
    }


ps: 因为前端页面请求的方式是POST,若使用以下的方式将文件输出流保存

/**下载操作 */
    handleDownload(row) {
      if (row.pdfKey) {//已生成pdf
          const param = { pdfKey : row.pdfKey};
        getReportStream(param).then(res => {
          if(!res) return
          let url = window.URL.createObjectURL(new Blob([res]), { type: 'application/pdf' })
          let link = document.createElement('a')
          link.style.display = 'none'
          link.href = url
          link.setAttribute('download', `xxxx报告.pdf`)
          document.body.appendChild(link)
          link.click()
          document.body.removeChild(link)
          URL.revokeObjectURL(link.href) //释放URL对象
        })
      } else {
        this.$message('报告正在生成中请稍后')
      }
    }



//获取报告文件输出流
export function getReportStream(data) {
  return request({
    url: `xxx/xxx/pdf/stream`,
    method: 'post',
    data: data,
    responseType: 'blob',
  })
}


实现效果截图:

① blob返回的文件输出流,console打印

获取oss的pdf文件,返回文件输出流_第1张图片

② swagger接口请求返回结果

获取oss的pdf文件,返回文件输出流_第2张图片

③ 下载的前端入口

④ 下载成功的pdf文件,在浏览器的左下角显示对应的文件

你可能感兴趣的:(获取oss的pdf文件,返回文件输出流)