使用 dompdf 创建多个 PDF 文件
Creating multiple PDF files with dompdf
我正在编写一个脚本来检查数据库和 returns 帐户开始日期在特定日期的客户的每一行。如果客户是在指定日期创建的,那么客户行将传递给我的函数,以根据数据库中的客户信息创建 PDF。
问题
我想出的为每个客户创建一个 PDF 的唯一方法是遍历数据并创建 PDF。这样做时我遇到了一个问题。
1. 仅创建第一个用户的 PDF。第二个没有发生任何事情。
Unable to stream PDF: headers already sent
在浏览器中显示并下载第一个 PDF。但是出于测试目的,应该在数据库中创建两个客户。我将数据回显到浏览器,两位客户都出现了。所以我知道数据存在并且在 运行 时间存在。
例子
// create instance of customer's that need to be created
$a = new SelectTempOne;
// obtain response from customers in database that have met timing requirement
$response = $a->selectUserForOne();
// loop through each row in the results and handle then pass to the pdf creation string
foreach($response as $i => $row) {
// statically typing template string to render email address of user
$temp1 = '
<!DOCTYPE html>
<html>
<head>
<title>Template 1</title>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<link rel="stylesheet" type="text/css" media="screen" href="pdf-templates/temp1/temp1.css" />
</head>
<body>
<div id="pdf_header">
<table>
<tr>
<td>'.$response[$i]['email'].'</td>
</tr>
</table>
</div>
</body>
</html>
';
// pass html to dompdf object
$dompdf->loadHtml($temp1);
// set option for the paper size and orientation
$dompdf->setPaper('A4', 'letter');
// Render the HTML as PDF
$dompdf->render();
//save the file to the server
$output = $dompdf->output();
file_put_contents('pdf/'.$response[$i]['email'].'.pdf', $output);
// Output the generated PDF to Browser
$dompdf->stream();
exit;
} // end of the for loop
?>
这一行是我添加客户电子邮件的地方,
<td>'.$response[$i]['email'].'</td>
问题
当我遍历从数据库返回的行时,我需要做什么才能创建动态数量的 PDF?
* 更新 *
Fatal error: Uncaught Dompdf\Exception: No block-level parent found.
Not good. in
/Users/wuno/Dropbox/google/devops/htdocs/tracker/login/dompdf/src/Positioner/Inline.php:45
Stack trace: #0
/Users/wuno/Dropbox/google/devops/htdocs/tracker/login/dompdf/src/FrameDecorator/AbstractFrameDecorator.php(872):
Dompdf\Positioner\Inline->position(Object(Dompdf\FrameDecorator\Inline))
1 /Users/wuno/Dropbox/google/devops/htdocs/tracker/login/dompdf/src/FrameReflower/Inline.php(51):
Dompdf\FrameDecorator\AbstractFrameDecorator->position() #2
/Users/wuno/Dropbox/google/devops/htdocs/tracker/login/dompdf/src/FrameDecorator/AbstractFrameDecorator.php(893):
Dompdf\FrameReflower\Inline->reflow(NULL) #3
/Users/wuno/Dropbox/google/devops/htdocs/tracker/login/dompdf/src/FrameReflower/Page.php(141):
Dompdf\FrameDecorator\AbstractFrameDecorator->reflow() #4
/Users/wuno/Dropbox/google/devops/htdocs/tracker/login/dompdf/src/FrameDecorator/AbstractFrameDecorator.php(893):
Dompdf\FrameReflower\Page->reflow(NULL) #5
/Users/wuno/Dropbox/google/devop in
/Users/wuno/Dropbox/google/devops/htdocs/tracker/login/dompdf/src/Positioner/Inline.php
on line 45
Web 浏览器通过请求文档来工作。您不能期望能够向用户提供多个文档。您只需调用 $dompdf->stream();
一次即可。您的选择:动态创建带有单独链接的列表页面、创建多页 PDF 或将 PDF 压缩在一起。
编辑:好的,根据您的评论,您实际上并不想显示 PDF。此外,我又看了一下,您的循环中有一个退出语句。这不会 运行 不止一次。另外,当你的代码中有大块文本时,使用 heredoc strings 是个好主意,所以我已经这样做了。
<?php
// create instance of customer's that need to be created
$a = new SelectTempOne;
// obtain response from customers in database that have met timing requirement
$response = $a->selectUserForOne();
// loop through each row in the results and handle then pass to the pdf creation string
foreach($response as $i => $row) {
// statically typing template string to render email address of user
$temp1 = <<< HTML
<!DOCTYPE html>
<html>
<head>
<title>Template 1</title>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<link rel="stylesheet" type="text/css" media="screen" href="pdf-templates/temp1/temp1.css" />
</head>
<body>
<div id="pdf_header">
<table>
<tr>
<td>$row[email]</td>
</tr>
</table>
</div>
</body>
</html>
HTML;
// pass html to dompdf object
$dompdf->loadHtml($temp1);
// set option for the paper size and orientation
$dompdf->setPaper('A4', 'letter');
// Render the HTML as PDF
$dompdf->render();
//save the file to the server
$output = $dompdf->output();
file_put_contents("pdf/$row[email].pdf", $output);
} // end of the for loop
?>
Dompdf 一次只允许处理一个文件。这是因为一旦 pdf 生成并显示在浏览器中,循环过程就会被终止,这就是循环仅在第一次运行的原因。如果你想一次性生成多个pdf文件,你必须将文件保存在服务器中,然后在AJAX内部使用JavaScript for-loop,并在后台将文件一个一个地传递。这不会终止循环进程,因为 AJAX 在后台运行。
我正在编写一个脚本来检查数据库和 returns 帐户开始日期在特定日期的客户的每一行。如果客户是在指定日期创建的,那么客户行将传递给我的函数,以根据数据库中的客户信息创建 PDF。
问题
我想出的为每个客户创建一个 PDF 的唯一方法是遍历数据并创建 PDF。这样做时我遇到了一个问题。
1. 仅创建第一个用户的 PDF。第二个没有发生任何事情。
Unable to stream PDF: headers already sent
在浏览器中显示并下载第一个 PDF。但是出于测试目的,应该在数据库中创建两个客户。我将数据回显到浏览器,两位客户都出现了。所以我知道数据存在并且在 运行 时间存在。
例子
// create instance of customer's that need to be created
$a = new SelectTempOne;
// obtain response from customers in database that have met timing requirement
$response = $a->selectUserForOne();
// loop through each row in the results and handle then pass to the pdf creation string
foreach($response as $i => $row) {
// statically typing template string to render email address of user
$temp1 = '
<!DOCTYPE html>
<html>
<head>
<title>Template 1</title>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<link rel="stylesheet" type="text/css" media="screen" href="pdf-templates/temp1/temp1.css" />
</head>
<body>
<div id="pdf_header">
<table>
<tr>
<td>'.$response[$i]['email'].'</td>
</tr>
</table>
</div>
</body>
</html>
';
// pass html to dompdf object
$dompdf->loadHtml($temp1);
// set option for the paper size and orientation
$dompdf->setPaper('A4', 'letter');
// Render the HTML as PDF
$dompdf->render();
//save the file to the server
$output = $dompdf->output();
file_put_contents('pdf/'.$response[$i]['email'].'.pdf', $output);
// Output the generated PDF to Browser
$dompdf->stream();
exit;
} // end of the for loop
?>
这一行是我添加客户电子邮件的地方,
<td>'.$response[$i]['email'].'</td>
问题
当我遍历从数据库返回的行时,我需要做什么才能创建动态数量的 PDF?
* 更新 *
Fatal error: Uncaught Dompdf\Exception: No block-level parent found. Not good. in /Users/wuno/Dropbox/google/devops/htdocs/tracker/login/dompdf/src/Positioner/Inline.php:45 Stack trace: #0 /Users/wuno/Dropbox/google/devops/htdocs/tracker/login/dompdf/src/FrameDecorator/AbstractFrameDecorator.php(872): Dompdf\Positioner\Inline->position(Object(Dompdf\FrameDecorator\Inline))
1 /Users/wuno/Dropbox/google/devops/htdocs/tracker/login/dompdf/src/FrameReflower/Inline.php(51):
Dompdf\FrameDecorator\AbstractFrameDecorator->position() #2 /Users/wuno/Dropbox/google/devops/htdocs/tracker/login/dompdf/src/FrameDecorator/AbstractFrameDecorator.php(893): Dompdf\FrameReflower\Inline->reflow(NULL) #3 /Users/wuno/Dropbox/google/devops/htdocs/tracker/login/dompdf/src/FrameReflower/Page.php(141): Dompdf\FrameDecorator\AbstractFrameDecorator->reflow() #4 /Users/wuno/Dropbox/google/devops/htdocs/tracker/login/dompdf/src/FrameDecorator/AbstractFrameDecorator.php(893): Dompdf\FrameReflower\Page->reflow(NULL) #5 /Users/wuno/Dropbox/google/devop in /Users/wuno/Dropbox/google/devops/htdocs/tracker/login/dompdf/src/Positioner/Inline.php on line 45
Web 浏览器通过请求文档来工作。您不能期望能够向用户提供多个文档。您只需调用 $dompdf->stream();
一次即可。您的选择:动态创建带有单独链接的列表页面、创建多页 PDF 或将 PDF 压缩在一起。
编辑:好的,根据您的评论,您实际上并不想显示 PDF。此外,我又看了一下,您的循环中有一个退出语句。这不会 运行 不止一次。另外,当你的代码中有大块文本时,使用 heredoc strings 是个好主意,所以我已经这样做了。
<?php
// create instance of customer's that need to be created
$a = new SelectTempOne;
// obtain response from customers in database that have met timing requirement
$response = $a->selectUserForOne();
// loop through each row in the results and handle then pass to the pdf creation string
foreach($response as $i => $row) {
// statically typing template string to render email address of user
$temp1 = <<< HTML
<!DOCTYPE html>
<html>
<head>
<title>Template 1</title>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<link rel="stylesheet" type="text/css" media="screen" href="pdf-templates/temp1/temp1.css" />
</head>
<body>
<div id="pdf_header">
<table>
<tr>
<td>$row[email]</td>
</tr>
</table>
</div>
</body>
</html>
HTML;
// pass html to dompdf object
$dompdf->loadHtml($temp1);
// set option for the paper size and orientation
$dompdf->setPaper('A4', 'letter');
// Render the HTML as PDF
$dompdf->render();
//save the file to the server
$output = $dompdf->output();
file_put_contents("pdf/$row[email].pdf", $output);
} // end of the for loop
?>
Dompdf 一次只允许处理一个文件。这是因为一旦 pdf 生成并显示在浏览器中,循环过程就会被终止,这就是循环仅在第一次运行的原因。如果你想一次性生成多个pdf文件,你必须将文件保存在服务器中,然后在AJAX内部使用JavaScript for-loop,并在后台将文件一个一个地传递。这不会终止循环进程,因为 AJAX 在后台运行。