获取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打印
② swagger接口申请返回后果
③ 下载的前端入口
④ 下载胜利的pdf文件,在浏览器的左下角显示对应的文件