如何在Spring Web应用中实现浏览器端PDF文件在线展示
Spring Web应用浏览器在线展示PDF实现方案
一、后端接口修正
你原有代码存在两处影响预览的问题:
- 请求方法为POST,无法直接通过浏览器地址栏/超链接访问触发预览
setContentDispositionFormData方法会覆盖你之前设置的inline属性,强制浏览器下载文件而非预览
修正后的后端代码如下:
import org.springframework.http.HttpHeaders; import org.springframework.http.HttpStatus; import org.springframework.http.MediaType; import org.springframework.http.ResponseEntity; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestMethod; import java.nio.charset.StandardCharsets; import java.nio.file.Files; import java.nio.file.Path; import java.nio.file.Paths; import java.net.URLEncoder; // 请求方法改为GET,适配浏览器直接访问场景 @RequestMapping(value="/getPdf", method=RequestMethod.GET) public ResponseEntity<byte[]> getPDF1() { String PATH_FILE = "C:\\Users\\rohit\\Downloads\\pdf_view\\sample.pdf"; Path path = Paths.get(PATH_FILE); byte[] pdfContents = null; try { pdfContents = Files.readAllBytes(path); } catch (IOException e) { e.printStackTrace(); // 实际业务可补充404/错误响应逻辑 return new ResponseEntity<>(HttpStatus.NOT_FOUND); } HttpHeaders headers = new HttpHeaders(); headers.setContentType(MediaType.APPLICATION_PDF); String filename = "pdf1.pdf"; // 仅保留inline配置,告知浏览器直接预览而非下载 headers.add("Content-Disposition", "inline; filename=" + URLEncoder.encode(filename, StandardCharsets.UTF_8)); headers.setCacheControl("must-revalidate, post-check=0, pre-check=0"); return new ResponseEntity<>(pdfContents, headers, HttpStatus.OK); }
注意:如果你的业务场景必须使用POST请求,保留原POST配置即可,按下文POST适配方案处理前端逻辑
二、前端预览实现
方案1:新标签页独立预览(最简单)
直接在页面添加超链接,点击后自动唤起浏览器内置PDF预览能力:
<a href="/getPdf" target="_blank">点击查看PDF文档</a>
方案2:嵌入当前网页内预览
可以用<embed>或<iframe>标签将PDF直接嵌入当前页面的指定位置:
<!-- 嵌入当前页面指定区域 --> <embed src="/getPdf" type="application/pdf" width="100%" height="800px">
必须使用POST请求的适配方案
如果后端保留POST请求,前端需要先请求blob流生成临时地址再预览:
// 以axios为例 axios.post('/getPdf', {/* 你的请求参数 */}, { responseType: 'blob' // 必须指定响应类型为blob }).then(res => { // 生成PDF临时访问地址 const pdfBlob = new Blob([res.data], {type: 'application/pdf'}) const pdfUrl = window.URL.createObjectURL(pdfBlob) // 可选1:新标签打开预览 window.open(pdfUrl) // 可选2:嵌入当前页面 // document.getElementById('pdf-container').innerHTML = `<embed src="${pdfUrl}" type="application/pdf" width="100%" height="800px">` })
三、优化建议
如果PDF文件体积较大,不建议使用Files.readAllBytes一次性读取全量字节,会占用大量堆内存,可改为流式输出降低内存消耗。
内容的提问来源于stack exchange,提问作者code1024
相关产品推荐
相关产品推荐

