MPDF只打印不到450条记录


mpdf prints only less than 450 records

我使用mpdf生成pdf,但mpdf仅在记录小于450时才有效。如果记录超过450,那么我得到一个错误

 Out of memory (allocated 1792802816) (tried to allocate 261904 bytes) in C:'..'mpdf'classes'cssmgr.php on line 17742

请提供一个更好的解决方案。我的代码在这里

ini_set('max_execution_time',360000);
set_time_limit(360000) ;
ignore_user_abort(true) ;
foreach($violations1 as $val)
        {   
            $exportpdf .= '<tr>';
                $exportpdf .= '<td  width="100" >'.$val['street_number'].'</td>';
                $exportpdf .= '<td  width="120" >'.$val['street_name'].'</td>';
                $exportpdf .= '<td  width="155" >'.$val['city'].'</td>';
                $exportpdf .= '<td  width="175"  >'.$val['zip'].'</td>';
                $exportpdf .= '<td  width="160" >'.$val['country'].'</td>';
            $exportpdf .= '</tr>';      
        }       
    $exportpdf .= '</table>';
$exportpdf = preg_replace('/>'s+</', "><", $exportpdf);
include("mpdf/mpdf.php");   
$mpdf=new mPDF('c','A4-L','','',32,25,34,18,16,13);
$mpdf->SetDisplayMode('fullpage');
$mpdf->list_indent_first_level = 0; 
$stylesheet = file_get_contents('mpdf/mpdf.css');
$mpdf->WriteHTML($stylesheet,1);
$mpdf->setFooter('Page {PAGENO}') ;
$mpdf->WriteHTML('<html><body>'.$exportpdf.'</body></html>');
$mpdf->Output('rec.pdf','D');
exit;

是的,我已经找到了解决方案,您必须添加这些行

$mpdf->cacheTables = true;
$mpdf->simpleTables=true;
$mpdf->packTableData=true;

和它的工作为我至少5000条记录

您必须在php.ini中增加memory_limit

在mpdf上,您可以选择禁用"漂亮的表边界",这是一个显著增加内存使用的功能。

$mpdf->simpleTables = true;

然而,我发现有时这是不够的。在这种情况下,我所做的是一旦我将所有html赋值给一个变量,然后将我不再需要的任何其他变量设置为false/null。例如,在这种情况下,你有一个数据数组$violations1,但在构建html并将其分配给$exportpdf之后,$violations1变量变得非常无用。

还有一个选项:

$mpdf->packTableData = true;
我试过了,但收效甚微。如果你有一个SQL数据对象/数组太大(特别是使用ORM和大量记录),或者如果你使用Smarty来渲染ui,那么在构建html之后刷新这些大变量会更好。

当然,系统中有更多的内存是一件好事。但是,如果您不能将ini_set('memory_limit','256M')添加到系统中,那么使用这个小mpdf技巧就可以很好地完成工作。

只是添加我的故事,以防有人落在这个结果上(PHP 7.2.10)。当我开始为我正在处理的项目运行一些负载测试时,我遇到了相同的情况。

在我的情况下,我无法在耗尽内存的128 MB之前生成超过51个PDF。

我能够通过在每次迭代后使用gc_collect_cycles()显式调用PHP的GC来克服这个问题,没有明显的性能影响:

  • http://php.net/manual/en/function.gc-collect-cycles.php

在添加了对上述函数的调用之后,在我决定停止它之前,脚本已经愉快地生成了2000多个PDF。

接下来我要做的是不要每次迭代都调用gc_collect_cycles(),而是在运行时获取一些关于内存使用的数据,并触发与之相关的GC。

同时,您应该确保代码没有泄漏,因为在这种情况下,您将不处理原因,而只是掩盖结果。

在我看来,增加内存只能作为最后的手段,因为它可能无法解决问题,但只会使您在耗尽资源之前生成更多的PDF。