【问题标题】:Using iText, generate on memory a PDF that is generated on disk instead使用 iText,在内存上生成一个在磁盘上生成的 PDF
【发布时间】:2011-01-10 05:55:30
【问题描述】:

我正在从 Java 应用程序生成 PDF。 (而且效果很好)问题是 PDF 在磁盘上生成为:

        Document documento = new Document(PageSize.A4, 25, 25, 25, 25);
        PdfWriter writer = PdfWriter.getInstance(documento, new FileOutputStream("/Users/sheldon/Desktop/Registry.pdf"));
        documento.open();

        // Put some images on the PDF
        for( byte[] imagen : imagenes )
        {
            Image hoja = Image.getInstance(imagen);
            hoja.scaleToFit(documento.getPageSize().getHeight(), documento.getPageSize().getWidth());
            documento.add(hoja);
        }

        documento.addTitle("Generated Registry!");

        documento.close();

现在,由于用户将搜索 PDF 并打印它们,我不需要将它们存储在磁盘上。我需要(如果可能)在内存中生成它们并使用命令打开(使用 acrobat 阅读器)该文档。

这可能吗?任何想法。

如果没有,有什么建议(根据您的经验)。

提前谢谢你。

编辑:

适用于标准 Java 桌面应用程序。

【问题讨论】:

  • 通过命令打开 PDF 听起来是特定于操作系统的。你的目标是什么操作系统?
  • 用于开发 Mac OS X Snow Leopard。但该应用只能在 Windows 系统上运行。

标签: java pdf-generation itext


【解决方案1】:

如果您不希望 iText 将文档生成到磁盘,那么只需执行以下操作:

Document documento = new Document(PageSize.A4, 25, 25, 25, 25);
ByteArrayOutputStream out = new ByteArrayOutputStream();
PdfWriter writer = PdfWriter.getInstance(documento, out);
(...)
return out.getBytes();

但这对您没有帮助,因为在您将其写入 Acrobat 可以访问的地方之前,Reader 无法访问它。如果您不希望它在磁盘上,则在内存磁盘中安装一个虚拟磁盘并将您的文件写入那里。如何执行此操作取决于您的操作系统。

【讨论】:

    【解决方案2】:

    为此,Acrobat 需要能够访问另一个进程 (Java) 的内存。这是不可能的。

    您可能只想将文件写入系统的临时目录。

    如果您的应用程序在 Acrobat 中打开 PDF 后仍处于打开状态,您可能需要考虑使用 File.createTempFile()File.deleteOnExit() 的组合,以便在 JVM 终止时删除文件。

    【讨论】:

    • 谢谢马特。这听起来像是要走的路。但是,一旦我创建了临时文件,有没有办法打开 acrobat 并传递该临时文件的路径,以便它直接从 Java 中打开?谢谢。
    【解决方案3】:

    是的……这很容易。您只需将内容流式传输回请求者(即通过 Servlet 中的 Response 对象)。您还需要设置标题

    'Content-type: application/pdf'
    

    您可能还想设置它以使其不在浏览器中打开

    'Content-Disposition: attachment; filename="downloaded.pdf"'
    

    【讨论】:

    • 感谢 mlathe,但这是一个桌面应用程序 :)
    • 好点 :) 但是如果有人关心如何使用网络应用程序来做到这一点!
    • 我愿意!我来这里是为了寻找这个答案,所以感谢 mlathe!
    【解决方案4】:

    我不是 JAVA 程序员,但我现在正在使用 iText,我也有同样的问题。我想如果 pdfWriter 只需要一个 outputStream,它还不如使用 java.io.ByteArrayOutputStream。那将是 new ByteArrayOutputStream() 我猜,在 JAVA 中,因为我正在使用 ColdFusion。

    对我来说,它有效。

    【讨论】:

    • 谢谢 Dominique,现在我正在使用临时目录,但我会尝试你的方法 :)
    【解决方案5】:

    要求可以是 Web 应用程序,用户可以在其中下载在运行时生成的 PDF。 File.createTempFile() 可能会为临时文件创建大量文件,而 File.deleteOnExit() 只会在 JVM 退出时调用 - 这不是理想的情况。

    在这种情况下,明智的做法是实现@behe 的建议,最后将ByteArrayOutputStream 对象写入ServletOutputStream

    ServletOutputStream servletOutputStream = httpServletResponse.getOutputStream();
    
    //get ByteArrayOutputStream from behe's code snippet
    ByteArrayOutputStream bout = (...)
    bout.writeTo(servletOutputStream);
    
    httpServletResponse.setContentType("application/octet-stream");
    httpServletResponse.setHeader("Content-Disposition", "attachment;filename=\"" + <fileName> + "\"");
    

    【讨论】:

      猜你喜欢
      • 2010-09-15
      • 1970-01-01
      • 1970-01-01
      • 2011-08-04
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-01-13
      • 1970-01-01
      相关资源
      最近更新 更多