我搜索了很多,但无法解决这个问题。我用iText生成PDF文件。如果我使用FileOutputStream一切都很好但是当我尝试使用ServletOutputStream时,图像不会出现在PDF文件中。
当我用文本编辑器打开PDF文件时,我看到那里有“???”非常。这意味着正在削减字节。这就像尝试使用JSP的二进制文件。但我使用的是JSF,Tomcat 6.0,Spring 3.0和Richfaces。
以下是使用ServletOutputStream生成PDF并导致问题的代码
public static void saveChartToPDF(JFreeChart chart, String fileName, HttpServletResponse response) throws Exception { ByteArrayOutputStream baos = new ByteArrayOutputStream(); Document document = new Document(); document.addCreationDate(); document.setPageSize(PageSize.A4.rotate()); PdfWriter writer = PdfWriter.getInstance(document, baos); document.open(); PdfContentByte cb = writer.getDirectContent(); PdfTemplate tp = cb.createTemplate(300, 300); Graphics2D g2 = tp.createGraphics(300, 300, new DefaultFontMapper()); Rectangle2D r2D = new Rectangle2D.Double(0, 0, 300, 300); chart.draw(g2, r2D, null); g2.dispose(); cb.addTemplate(tp, 0, 0); document.close(); response.setContentType("application/pdf"); response.setHeader("Expires", "0"); response.setHeader("Cache-Control", "must-revalidate, post-check=0, pre-check=0"); response.setHeader("Pragma", "public"); response.setHeader("Content-disposition", "attachment;filename=" + fileName + ".pdf"); response.setContentLength(baos.size()); ServletOutputStream out = response.getOutputStream(); baos.writeTo(out); out.flush();
这里的代码可以正常使用FileOutputStream()
public static void saveChartToPDF(JFreeChart chart, String fileName, HttpServletResponse response) throws Exception { Document document = new Document(); document.addCreationDate(); document.setPageSize(PageSize.A4.rotate()); PdfWriter writer = PdfWriter.getInstance(document, new FileOutputStream("c:/test1.pdf")); document.open(); PdfContentByte cb = writer.getDirectContent(); PdfTemplate tp = cb.createTemplate(300, 300); Graphics2D g2 = tp.createGraphics(300, 300, new DefaultFontMapper()); Rectangle2D r2D = new Rectangle2D.Double(0, 0, 300, 300); chart.draw(g2, r2D, null); g2.dispose(); cb.addTemplate(tp, 0, 0); document.close();
我找不到为什么字节被削减了。
非常感谢你的帮助,
答案 0 :(得分:2)
在JSF中完全掌握回复时,您需要确保调用
response.reset();
在设置标题之前,很可能已经在响应中设置/写入了某些内容(通常是某种自定义Filter
)。
您还需要确保拨打
out.close();
而不是out.flush()
以防止之后将任何其他字节写入响应主体。
最后,在JSF中你需要调用
FacesContext.getCurrentInstance().responseComplete();
防止JSF将请求/响应转发给视图(呈现响应)。