【问题标题】:How to Handing EXTREMELY Large Strings in PHP When Generating a PDF生成 PDF 时如何在 PHP 中处理超大字符串
【发布时间】:2011-04-04 09:05:24
【问题描述】:

如果给定足够大的日期范围,我的报告可以生成超过 30,000 条记录。从 HTML 方面来看,这么大的结果集不是问题,因为我实现了一个分页系统,在给定时间将可查看的结果限制为 100。

一旦用户按下“获取 PDF”按钮,我的真正问题就会出现。发生这种情况时,我基本上会重新运行报告中打印数据的部分(报告本身的结果存储在“保存”表中,因此无需重新运行数据-收集逻辑),并将结果存储在名为$html 的变量中。请记住,此变量现在包含 30,000 条数据记录以及在 PDF 上正确格式化所需的 HTML。创建此 HTML 字符串后,我将其传递给 TCPDF 以尝试为用户生成 PDF 文件。然而,它并没有生成 PDF 文件,而是在没有错误消息(“正在生成 PDf...”)对话框的情况下消失了,系统就像您从未要求它做任何事情一样。

通过测试,我发现问题在于传入的$html变量的大小。如果报告在3K以下的记录,则可以正常工作。如果结束,将打印报告的 HTML 端,但不会打印 PDF。

有用信息

  • PHP 5.3
  • 用于 PDF 生成的 TCPD(也尝试过 PS2PDF)
  • 脚本内存限制:500 MB

在生成这种大小的 PDF 时,你们会如何处理这种规模的数据?

【问题讨论】:

    标签: php pdf-generation tcpdf


    【解决方案1】:

    这是我解决此问题的方法:我注意到我在 HTML 输出中的一些字符串存在一些轻微的编码问题 - 我在查询时对这些特定字符串运行了 htmlentities数据库为他们解决了问题。

    不知道这是否是导致您的问题的原因,但我的经历非常相似 - 当我尝试输出一个具有大约 80.000 行的大尺寸 HTML 表时,TCPDF 会显示页眉,但是与表无关。对于不同的数据集和不同的表结构,这种行为是相同的。

    经过多次尝试后,我开始添加自己的分页 - 每 15 行表格,我会打破页面并在下一页添加一个新表格。那时我注意到每隔一段时间我会在很多完整和正确的页面之间得到空白页。那时我意识到那些特定的数据子集一定有问题,并发现了编码问题。可能是您遇到了类似的情况,而 TCPDF 没有说明您的问题是什么。

    【讨论】:

      【解决方案2】:

      你使用的是 writeHTML 方法吗?

      我在这里查看了性能建议:http://www.tcpdf.org/performances.php

      上面写着“将大的 HTML 块分割成小块;”。

      我发现如果我的 HTML 块超过 20,000 个字符,则生成 PDF 需要 2 分钟以上。

      我只是将我的 html 拆分为块,并为每个块调用 writeHTML,它得到了显着改进。在 2 分钟之前不会生成的文件现在需要 16 秒。

      【讨论】:

        【解决方案3】:

        TCPD 似乎是 PHP 中 PDF 生成的本机实现。使用像PDFlib 这样的编译库或像htmldoc 这样的命令行应用程序可能会获得更好的性能。后者最有可能生成大型 PDF。

        另外,您是否将输出的 PDF 分成多个页面? IE。 TCPDF 是否知道获取单个 HTML 文档并将其剪切成多个页面,或者您是否生成多个 HTML 文件以将其组合成单个 PDF 文档?这也可能有所帮助。

        【讨论】:

        • 我传入一个巨大的 HTML 字符串,然后 TCPDF 将其拆分为多页 PDF。我认为问题不在于 PDF 生成器,而在于 $html 变量的大小。
        • @Levi Hackwith:这没有任何意义。 PDF 可以任意大。如果 PDF 生成器在其输入 HTML 太大时失败,那么这是生成器的问题。否则,只需减小 HTML 文件的大小并像 shamittomar 建议的那样创建许多小型 PDF。尽管大多数桌面程序在创建超过 100,000 页的 PDF 时都没有问题。
        • 那么普遍认为问题出在 TCPDF 而不是 PHP 本身吗?
        • @Levi Hackwith:除非脚本超过最大脚本执行时间或脚本内存限制,否则 PHP 不太可能出现问题。我也非常怀疑您是否需要超过 500MB 才能生成 PDF,除非每条记录本身都很大。但是您可以随时使用memory_get_peak_usage() 进行检查。
        • 得到了答案,因为他建议了整个“命令行”方法,这将是处理这个问题的最佳方法
        【解决方案4】:

        我会将 PDF 分成几部分,就像分页一样。

        1) 在每个分页的 HTML 页面上都有“获取 PDF”按钮,并且只允许从该 HTML 页面下载记录。

        2) 限制可以下载的最大记录数。如果达到最大限制,则拆分 PDF 并让用户下载多个 PDF。

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2023-03-06
          • 1970-01-01
          • 2011-08-31
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2011-10-16
          • 2023-03-29
          相关资源
          最近更新 更多