【问题标题】:JFreeChart not showing in generated Spring MVC and iText PDFJFreeChart 未在生成的 Spring MVC 和 iText PDF 中显示
【发布时间】:2014-02-20 16:59:36
【问题描述】:

我在问题“Append PDF at the available space of another PDF file”之前问过,我已经成功地制作了一个 PDF,将原生 iText 和 JFreeChart 合并在一页中。

我使用教程“Spring Web MVC with PDF View Example (using iText 5.x)”将此设置合并到我的 Spring MVC 应用程序中。

我了解使用 Spring 的 AbstractView 并反过来实现为

@Override
protected void buildPdfDocument(Map<String, Object> map, Document document,
        PdfWriter pdfWriter, HttpServletRequest request,
        HttpServletResponse response) throws Exception {

    // do iText and JFreeCharts

}

并且 JFreeChart 实例需要将现有的 PDF 文件插入其中,如“Creating an iText pdf with embedded JFreeChart”所示:

// get the direct pdf content
PdfContentByte dc = docWriter.getDirectContent();

// get a pdf template from the direct content
PdfTemplate tp = dc.createTemplate(width, height);

// create an AWT renderer from the pdf template
Graphics2D g2 = tp.createGraphics(width, height, new DefaultFontMapper() );
Rectangle2D r2D = new Rectangle2D.Double(0,0, width,height);
chart.draw(g2,r2D,null);
g2.dispose();

// add the rendered pdf template to the direct content
// you will have to play around with this because the chart is absolutely positioned.
// 38 is just a typical left margin
// docWriter.getVerticalPosition(true) will approximate the position that the content above the chart ended
dc.addTemplate(tp, 38, docWriter.getVerticalPosition(true)-height);

我现在的问题是,每当我调用扩展 AbstractView 的方法(请参阅第二个链接)时,它会在插入 JFreeChart 之前显示 PDF,而不是带有生成图表的那个。我没有遇到任何错误,但我想知道是否有解决此问题的方法。

我只希望用户使用 JFreeChart 查看 PDF,就像 Spring MVC 中的普通 PDF 实现一样。

如您所见,我只是按照上面的教程将它们结合起来。他们在一个单独的项目中完美地工作,但是当我与 Spring 合并时,JFreeChart 没有显示,特别是显示了错误的 PDF 文件。


我知道我可以使用 JFreeChart 调用生成的 PDF 并通过放置指向正确文件的链接来稍微拦截查看,但我对这种设置寄予厚望,因为这将是使用这三种技术的便捷方式完全没有服务器中文件 I/O 的麻烦(我遇到了麻烦)。


下面是我使用的“Spring Web MVC with PDF View Example (using iText 5.x)”中AbstractITextPdfView 类的sn-p。

谁能告诉我如何将打开的 PDF 文件指向带有图表的文件,即buildPdfDocument() 内的文件?

@Override
protected void renderMergedOutputModel(Map<String, Object> model,
        HttpServletRequest request, HttpServletResponse response)
        throws Exception {
    // IE workaround: write into byte array first.
    ByteArrayOutputStream baos = createTemporaryOutputStream();

    // Apply preferences and build metadata.
    Document document = newDocument();
    PdfWriter writer = newWriter(document, baos);
    prepareWriter(model, writer, request);
    buildPdfMetadata(model, document, request);

    // Build PDF document.
    document.open();
    buildPdfDocument(model, document, writer, request, response);
    document.close();

    // Flush to HTTP response.
    writeToResponse(response, baos);
}

更新

我截获了ByteArrayOutputStream,方法是在JFreeChart“附加”到iText PDF 之后保存到一个文件中。

@Override
protected void renderMergedOutputModel(Map<String, Object> model,
        HttpServletRequest request, HttpServletResponse response)
        throws Exception {
    // IE workaround: write into byte array first.
    ByteArrayOutputStream baos = createTemporaryOutputStream();

    // Apply preferences and build metadata.
    Document document = newDocument();
    PdfWriter pdfWriter = newWriter(document, baos);
    prepareWriter(model, pdfWriter, request);
    buildPdfMetadata(model, document, request);

    // Build PDF document.
    document.open();
    buildPdfDocument(model, document, pdfWriter, request, response);
    document.close();

    FileOutputStream fos = null;
    try {
        fos = new FileOutputStream(new File("D:/MUST-HAVE-CHART.pdf"));
        baos.writeTo(fos);
    } catch (IOException ioe) {
        // Handle exception here
        ioe.printStackTrace();
    } finally {
        fos.close();
    }
    System.out.println(baos.toString());

    // Flush to HTTP response.
    writeToResponse(response, baos);
}

MUST-HAVE-CHART.PDF没有图表,和Spring MVC创建后提供的一样。然而,带有图表的那个被保存在其他地方,如代码所示:

@Override
protected void buildPdfDocument(Map<String, Object> map, Document document,
        PdfWriter pdfWriter, HttpServletRequest request,
        HttpServletResponse response) throws Exception {

    logger.info("Start of PDF creation");

    Domain domain = (Domain) map.get("domain");

    ServletContext servletContext = request.getSession()
            .getServletContext();
    File servletTempDir = (File) servletContext
            .getAttribute("javax.servlet.context.tempdir");

    if (servletTempDir == null)
        throw new IllegalStateException(
                "Container does not provide a temp dir");

    File targetFile = new File(servletTempDir, NAME_FILE);

    pdfWriter = PdfWriter.getInstance(document, new FileOutputStream(
            targetFile));

    logger.info("PDF file path: " + targetFile.getAbsolutePath().toString());

    document.open();

    PdfBuilder.assemble(document, pdfWriter, domain);

    document.close();
    pdfWriter.close();

    logger.info("End of PDF creation");

    map.put("file", targetFile.getAbsolutePath().toString());
}

正确的保存在javax.servlet.context.tempdirC:/tomcat/work/Catalina/localhost/my_spring_app/pdf_file.pdf 中。

如何使后者显示在屏幕上???

【问题讨论】:

    标签: java spring pdf itext jfreechart


    【解决方案1】:

    我遇到了同样的问题。 我使用以下代码解决了它,现在正在下载文件而不是呈现新的 pfd-view 页面(我更喜欢这个)。

    protected final void renderMergedOutputModel(Map<String, Object> model, 
               HttpServletRequest request, HttpServletResponse response) throws Exception {
    
        // IE workaround: write into byte array first.
        ByteArrayOutputStream baos = createTemporaryOutputStream();
    
        // Apply preferences and build metadata.
        Document document = newDocument();
        PdfWriter writer = newWriter(document, baos);
        prepareWriter(model, writer, request);
        buildPdfMetadata(model, document, request);
    
        // Build PDF document.
        document.open();
        buildPdfDocument(model, document, writer, request, response);
        document.close();
    
        //Custom code start 
        String filestorePath = "/var/www/xxx/xxxxx/";
        String downloadfileNm = "DeliveryNote.pdf";
        String filePath = filestorePath+downloadfileNm;
        URL url = new URL("file:"+filePath);
        File file = new File(url.toURI());
        if (file.exists()) {
            response.setContentLength(new Long(file.length()).intValue());
            response.setHeader("Content-Disposition", "attachment; filename="+downloadfileNm);
            FileCopyUtils.copy(new FileInputStream(file), response.getOutputStream());      
        }
        //Custom code end
    
        // Flush to HTTP response.
        //writeToResponse(response, baos);
    
    }
    

    【讨论】:

      猜你喜欢
      • 2023-04-04
      • 1970-01-01
      • 2016-03-20
      • 1970-01-01
      • 2013-03-16
      • 1970-01-01
      • 1970-01-01
      • 2019-07-20
      • 1970-01-01
      相关资源
      最近更新 更多