IText 7生成PDF生产环境空白本地正常,页数正确问题求助
解决iText7生成PDF生产环境空白但本地正常的问题
我之前踩过几乎一模一样的坑!结合你的场景(本地正常预览、生产下载后空白但页数正确),核心问题基本出在字节流未正确收尾或者响应头配置不全,下面给你分步排查和解决:
1. 先补全响应头的关键配置(最常见原因)
你的代码片段里HttpHeaders的部分没写完,生产环境下浏览器需要明确的PDF类型标识才能正确解析内容,否则会出现“页数对但内容空白”的情况。修正后的代码如下:
@GET @RequestMapping(value = "generatePDF/{id}") public ResponseEntity<byte []> getPDFInfo(@PathVariable("id") String id) throws Exception { ByteArrayOutputStream myPDFDetails = pdfService.getPDFInfo(id); // 关键:先刷新并关闭输出流,确保所有字节都写入 myPDFDetails.flush(); myPDFDetails.close(); byte[] myPDFByte = myPDFDetails.toByteArray(); HttpHeaders headers = new HttpHeaders(); // 必须设置PDF的MIME类型 headers.setContentType(MediaType.APPLICATION_PDF); // 指定下载文件名,避免浏览器预览异常 headers.setContentDispositionFormData("attachment", "document-" + id + ".pdf"); // 显式设置内容长度,防止流截断 headers.setContentLength(myPDFByte.length); // 禁用缓存,避免生产环境浏览器缓存旧的空白文件 headers.setCacheControl("no-cache, no-store, must-revalidate"); return new ResponseEntity<>(myPDFByte, headers, HttpStatus.OK); }
2. 检查iText7生成逻辑的资源释放
本地环境可能因为调试模式或JVM自动回收资源掩盖了问题,但生产环境高并发下,未正确关闭iText的核心对象会导致字节流不完整。确保你的pdfService.getPDFInfo(id)方法用try-with-resources自动释放资源:
public ByteArrayOutputStream getPDFInfo(String id) throws Exception { ByteArrayOutputStream baos = new ByteArrayOutputStream(); // try-with-resources会自动关闭PdfWriter/PdfDocument/Document,无需手动close try (PdfWriter writer = new PdfWriter(baos); PdfDocument pdfDoc = new PdfDocument(writer); Document doc = new Document(pdfDoc)) { // 你的PDF内容生成逻辑(比如添加段落、表格等) doc.add(new Paragraph("订单ID:" + id)); // 不需要手动flush,try-with-resources会确保所有内容写入流 } return baos; }
3. 排查生产环境的网关/代理问题
如果上面两步都没问题,那可能是生产环境的Nginx、API网关等配置了gzip压缩,导致PDF字节流被篡改。可以:
- 直接调用服务的IP:端口下载PDF,跳过网关,如果正常,说明网关需要对
application/pdf类型禁用gzip压缩 - 检查网关的响应头是否被篡改,比如是否添加了错误的
Content-Encoding
4. 验证浏览器缓存
生产环境浏览器可能缓存了之前的空白PDF,测试时可以给URL加随机参数(比如generatePDF/123?v=12345),或者在响应头里设置强缓存禁用(上面代码已经加了)。
内容的提问来源于stack exchange,提问作者Am Novice
相关产品推荐
相关产品推荐

