生成大型 pdf 文件,但主内存中没有内容

2024-01-31

我正在使用 iText 生成 pdf 格式的非常大的表格。 生成这些表而不是将整个内容存储在内存中的最佳方法是什么? 如果我只是将 for 循环中的以下大小增加到一百万,我就会耗尽内存,是否有比将整个内容都存储在内存中更好的方法来流式传输它

我看到了这个帖子如何以最小的内存占用直接将大内容流式传输为 PDF? https://stackoverflow.com/questions/51491522/how-to-directly-stream-large-content-to-pdf-with-minimal-memory-footprint但我想知道使用什么 iText api。

示例代码:

import java.io.FileOutputStream;
import java.io.IOException;
import java.util.Date;

import com.itextpdf.text.Document;
import com.itextpdf.text.DocumentException;
import com.itextpdf.text.Element;
import com.itextpdf.text.Font;
import com.itextpdf.text.Font.FontFamily;
import com.itextpdf.text.Phrase;
import com.itextpdf.text.pdf.PdfPCell;
import com.itextpdf.text.pdf.PdfPTable;
import com.itextpdf.text.pdf.PdfWriter;

public class SimpleTable11 {
public final static String DEST = "/Users/.../Documents/test23.pdf";

public static void main(String[] args) throws IOException, DocumentException {
    new SimpleTable11().createPdf(DEST);
}

public void createPdf(String dest) throws IOException, DocumentException {

    System.out.println(new Date());
    Document document = new Document();
    PdfWriter.getInstance(document, new FileOutputStream(DEST));
    document.open();
    PdfPTable table = new PdfPTable(23);
    table.setWidths(new int[] { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 });
    table.setWidthPercentage(100);
    table.addCell(createCell("Account", 2, 1, Element.ALIGN_JUSTIFIED));
    table.addCell(createCell("Org Id", 2, 1, Element.ALIGN_LEFT));
    table.addCell(createCell("Contract Number", 2, 1, Element.ALIGN_LEFT));
    table.addCell(createCell("Transaction Type", 2, 1, Element.ALIGN_LEFT));
    table.addCell(createCell("Transaction Number", 2, 1, Element.ALIGN_LEFT));
    table.addCell(createCell("Transaction Date", 2, 1, Element.ALIGN_LEFT));
    table.addCell(createCell("Start Date", 2, 1, Element.ALIGN_LEFT));
    table.addCell(createCell("End Date", 2, 1, Element.ALIGN_LEFT));
    table.addCell(createCell("Billing Reference", 2, 1, Element.ALIGN_LEFT));
    table.addCell(createCell("Line Description", 2, 1, Element.ALIGN_LEFT));
    table.addCell(createCell("Product Name", 2, 1, Element.ALIGN_LEFT));
    table.addCell(createCell("Related Invoices", 2, 1, Element.ALIGN_LEFT));
    table.addCell(createCell("Monthly Unit Price", 2, 1, Element.ALIGN_LEFT));
    table.addCell(createCell("quantity", 2, 1, Element.ALIGN_LEFT));
    table.addCell(createCell("Total Line Tax", 2, 1, Element.ALIGN_LEFT));
    table.addCell(createCell("Total Price", 2, 1, Element.ALIGN_LEFT));
    table.addCell(createCell("Exchange Rate", 2, 1, Element.ALIGN_LEFT));
    table.addCell(createCell("Taxable", 2, 1, Element.ALIGN_LEFT));
    table.addCell(createCell("Vat Rate", 2, 1, Element.ALIGN_LEFT));
    table.addCell(createCell("VAT", 2, 1, Element.ALIGN_LEFT));
    table.addCell(createCell("Taxable", 2, 1, Element.ALIGN_LEFT));
    table.addCell(createCell("VAT", 2, 1, Element.ALIGN_LEFT));
    table.addCell(createCell("Total Price", 2, 1, Element.ALIGN_LEFT));

    String[] data = { "44445555", "123456", "0105567", "INV", "123456", "10/10/2018", "11/15/2018", "11/20/2050",
            "SO-0000000000-Mento", "Marketing Product", "Marketing Product ", "Marketing Product",
            "Marketing Product", "0.00", "12.56", "300.00", "0.566667345", "12.54", "10.00%", "12.56", "7.58",
            "7.27", "176.67" };
    for (int i = 0; i < 20000; i++) {
        for (int j = 0; j < data.length; j++) {
            table.addCell(createCell(data[j], 1, 1, Element.ALIGN_LEFT));
        }
    }
    document.add(table);
    document.close();
    System.out.println(new Date());
}

public PdfPCell createCell(String content, float borderWidth, int colspan, int alignment) {
    Font font = new Font(FontFamily.HELVETICA, 4, Font.NORMAL);
    PdfPCell cell = new PdfPCell(new Phrase(content, font));
    cell.setBorderWidth(borderWidth);
    cell.setColspan(colspan);
    cell.setHorizontalAlignment(alignment);
    return cell;
}

}


使用时PdfPTable具有很多单元格的对象,您应该使用该类来实现LargeElement其记录为

/**
 * Interface implemented by Element objects that can potentially consume
 * a lot of memory. Objects implementing the LargeElement interface can
 * be added to a Document more than once. If you have invoked setComplete(false),
 * they will be added partially and the content that was added will be
 * removed until you've invoked setComplete(true);
 * @since   iText 2.0.8
 */
public interface LargeElement extends Element

IE。你应该首先使用

setComplete(false),

然后向表格中添加一些内容(例如 20 行),然后将表格添加到文档中,添加更多内容,再次将表格添加到文档中,等等...,当所有内容都添加完毕后,使用

setComplete(true)

并再次添加该表。这样,表数据不会保留在堆上,而是逐位序列化并写入写入器。


顺便说一句,还有其他 iText 类,它们实现LargeElement。如果您遇到 iText 内存消耗巨大的问题,您应该始终检查添加到您的 iText 中的对象。Document: 如果他们实施LargeElement,首先尝试将它们转发到Document如上所述,一点一点地进行。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

生成大型 pdf 文件,但主内存中没有内容 的相关文章

随机推荐

  • MVC 3 客户端比较验证

    这里发生了一些奇怪的事情 我有一个基本形式 br
  • WPF 自动调整元素大小

    当应用程序窗口调整大小时 我希望其中的元素也按比例调整大小 那可能吗 我尝试谷歌搜索 但找不到任何与此相关的内容 我的 XAML 代码
  • 使用 NodeJS 解包 PKCS#7 数据有效负载?

    我正在开发适用于 iOS 的 MDM NodeJS 服务器 在 Apple 文档中 给出了以下 ruby 代码 p7sign OpenSSL PKCS7 PKCS7 new req body store OpenSSL X509 Store
  • 国际象棋编程(无人工智能)——动作验证

    我正在尝试编写自己的国际象棋引擎 没有人工智能 我知道有国际象棋游戏入门套件 http www chessbin com page Chess Game Starer Kit aspx我观看它是为了获得灵感 但我没有注意到的是经过验证的动作
  • 如何在 docker-compose 中将主机网络与默认网络结合起来[重复]

    这个问题在这里已经有答案了 我正在构建包含两个容器的 docker compose 服务 这些容器之一 node 旨在支持自动发现机制 并且需要成为主机 LAN 的一部分 因为我需要由 LAN 路由器而不是内置的 docker 路由器处理多
  • 部署 Angular 项目错误类型 MIME (text/html)

    我尝试部署 Angular CLI 6 12 0 项目 当我将 dist 文件夹内容放在服务器上时 出现控制台错误 键入 MIME Le chargement du module l adresse http www sylvainalla
  • C# 中的多个 HTTP 请求

    我需要向不同的服务器并行发送大约 200 个 HTTP 请求并获得响应 我在 C 中使用 HttpWebRequest 类 但是 当并行处理请求时 我没有看到很好的时间改进 例如 如果一个请求需要 3 秒才能获得响应 则并行 2 个请求 6
  • 在 GithubActions CI 中安装用于 UWP 开发的 SDK?

    我正在尝试构建一些 UWP 库 但收到此错误 D a ZXing Net Xamarin ZXing Net Xamarin Source ZXing Net Mobile WindowsUniversal ZXing Net Mobile
  • matplotlib:图例标题的对齐

    在matplotlib中 如何调整图例标题 它始终居中 但我需要它与图例框左对齐 我尝试更改标题的文本艺术家的对齐方式 但没有效果 详细信息请参见以下示例 from pylab import x linspace 0 1 plot x x
  • Flutter:如何检查字符串中的字母是否相同[重复]

    这个问题在这里已经有答案了 我正在制作一个表单 供用户通过输入卖家的帐户名称和帐户类型来添加新卖家 但在将新卖家添加到firestore之前 它会检查该卖家是否存在 现在我的代码仅检查输入的名称是否与数据库中的名称非常相似 例如 数据库中有
  • Javafx Tile Pane,设置最大列数

    首先 我将解释我的目标 我想渲染一个像这样的表格 每个单元格的内容在执行时间中确定 但其大小固定为 13x13 因此 我的方法是创建一个平铺窗格 将列数设置为 13 并创建单元格 pane new TilePane pane setPadd
  • 读取多个.gz文件并识别哪一行属于哪个文件

    我正在读取多个 gz 文件以使用谷歌数据流进行处理 数据的最终目的地是BigQuery BigQuery 表对于 gz 文件内的 csv 文件中的每一列都有专用列 BQ 表中还有一个附加列 file name 它给出了该记录所属的文件名 我
  • 使用编程导航传递 props Vue.js

    我有一个 Vue 组件 有一个名为 title 的 prop 例如 完成某个操作后 我以编程方式导航到该组件 有没有办法以编程方式路由用户 同时设置 prop 值 我知道您可以创建这样的链接
  • 当 E_NOTICE 打开时,如何设置 PHP 不检查 $_GET 的未定义索引?

    当 E NOTICE 设置为 on 时 PHP 将报告数组的未定义索引 我想抑制这个错误 GET仅有的 除了预先添加每个之外 还有什么方法可以做到这一点 GET with 正确的解决方案是使用 isset 或数组键存在 https www
  • 为 Pycharm 中构建的项目运行 pyinstaller 时如何包含 venv 目录中的依赖项?

    我是 Python 和 PyCharm 新手 我在 OSX High Sierra 上运行 我在 PyCharm 中创建了一个使用 lxml 的项目 我已经安装了 lxml 4 1 1 作为项目依赖项 我可以在 myProject venv
  • 不使用其他特征文件调用的条件

    使用空手道 我想知道是否可以设置 If 条件而无需调用不同的功能文件 并且不使用 JavaScript gt 在条件中使用空手道功能文件代码块 例如应该可以做类似的事情吗 if variable 1 delay 3000 retry cli
  • Spring Data JPA 存储库中的解析和查询构建是哪个类?

    我已经在 spring 文档中阅读了这一行 Spring 数据存储库基础设施中内置的查询构建器机制 任何人都可以告诉这个查询构建器在 spring 中到底是哪个类吗 你应该看看org springframework data jpa rep
  • 嵌套对象最佳实践

    引用嵌套对象的最佳实践是什么 假设我有以下内容 class Outer private InnerA innerA getters and setters class InnerA private InnerB innerB getters
  • 我可以告诉 C# 可空引用一个方法实际上是对字段的空检查吗

    考虑以下代码 nullable enable class Foo public string Name get set public bool HasName gt Name null public void NameToUpperCase
  • 生成大型 pdf 文件,但主内存中没有内容

    我正在使用 iText 生成 pdf 格式的非常大的表格 生成这些表而不是将整个内容存储在内存中的最佳方法是什么 如果我只是将 for 循环中的以下大小增加到一百万 我就会耗尽内存 是否有比将整个内容都存储在内存中更好的方法来流式传输它 我