Php 在TCPDF中使用占位符
我对creditnote进行了一些复杂的计算,第一页是总金额的摘要。 我不想做的是遍历所有条款以计算摘要,然后再次遍历它们以呈现详细视图。 那么,是否可以定义自定义占位符,以便在添加详图视图后替换? 或者,您知道不需要运行两次计算就能获得所需结果的另一种方法吗 编辑: 以下是渲染局部视图的方式:Php 在TCPDF中使用占位符,php,replace,tcpdf,placeholder,Php,Replace,Tcpdf,Placeholder,我对creditnote进行了一些复杂的计算,第一页是总金额的摘要。 我不想做的是遍历所有条款以计算摘要,然后再次遍历它们以呈现详细视图。 那么,是否可以定义自定义占位符,以便在添加详图视图后替换? 或者,您知道不需要运行两次计算就能获得所需结果的另一种方法吗 编辑: 以下是渲染局部视图的方式: foreach($this->_creditNote->provisioningClient->customers as $customer) {
foreach($this->_creditNote->provisioningClient->customers as $customer)
{
$provisions = $customer->getProvisionsByBillingPeriodSum($this->_creditNote->billingPeriod);
if((count($provisions) >= 3 && $this->y > 230) || $this->y > 250)
{
$this->AddPage();
$this->SetFillColor(240);
$this->SetDrawColor(0);
$this->SetFont('Helvetica', 'B', 10);
$this->Cell(140, 6, 'Die Provisionen im Einzelnen', 'TB', 0, 'L', 1);
$this->Cell(30, 6, "Beträge", 'TB', 1, 'R', 1);
$this->SetXY(25, $this->y-11.5);
$this->SetTextColor(170,170,170);
$this->SetFont('Helvetica', '', 7);
$this->Cell(175, 6, 'Seite ' . $this->getAliasNumPage() . ' von ' . $this->getAliasNbPages(), '', 2, 'R');
$this->SetY($this->y+6);
$this->SetFont('Helvetica', '', 9);
$this->SetTextColor(0,0,0);
}
if(count($provisions) > 0)
{
$customerData = array();
$this->SetXY(20, $this->y+1);
$this->SetFont('Helvetica', 'B', 10);
$this->Cell(140, 0, $customer->contact->name . " (" . $customer->customerNumber . ")");
//add customer
$amount = 0;
$rows = array();
foreach($provisions as $provision)
{
$text = $provision->description;
$description = "";
if($provision->period != "onetime")
{
if($provision->isPartial($this->_creditNote->billingPeriod))
$text .= ", anteilig";
$description = $provision->periodName . ", " . $provision->getRuntime($this->_creditNote->billingPeriod);
}
if($description == "")
$description = null;
$temp = array($text, $provision->isPartial($this->_creditNote->billingPeriod) ? round($provision->getPartialAmount($this->_creditNote->billingPeriod)/100, 2) : $provision->amount / 100, $description);
$amount += $temp[1];
$rows[] = $temp;
}
$this->Cell(30, 0, number_format($amount, 2, ",", ".") . " €", 0, 1, 'R');
foreach($rows as $row)
{
$this->SetXY(23, $this->y+1);
$this->SetFont('Helvetica', '', 8);
$this->Cell(137, 0, $row[0]);
$this->Cell(30, 0, number_format($row[1], 2, ",", ".") . " €", 0, 1, 'R');
if($row[2])
{
$this->SetXY(26, $this->y + 1);
$this->SetFont('Helvetica', 'I', 8);
$this->MultiCell(140, 0, $row[2], 0, 'L');
}
}
}
}
提前感谢,,
Tobias据我所知,您当前的代码如下所示:
// this will contain the computation for every orders
$orders_infos = array();
// you need $orders_infos to be already filled here, but it is done after
$total = 0;
foreach ($orders_infos as $info) {
$total += $info['total'];
}
$html = "html for the overview page: ".$total; // $total is wrong !
$pdf->writeHTML($html);
// compute infos for every order and display
foreach ($orders as $k => $order) {
$orders_infos[$k] = compute_order_infos();
$html = "html for this order page ".$orders_infos[$k]['total'];
$pdf->writeHTML($html);
}
您的问题是概览页面中的总数不正确,因为您是在事后进行计算的。更改它的简单方法是运行所有计算,然后生成结果PDF,但您说出于某种原因您不希望这样做
实现您想要的第二个最好的方法是进行一些欺骗,并跟踪要作为运行的命令列表,然后在最后运行它们,这样您可以保留当前的大部分代码组织,但之后仍会执行所有显示
$commands = array();
// this will contain the computation for every orders
$orders_infos = array();
// you need $orders_infos to be already filled here, but it is done after
$total = 0;
$commands[] = function($pdf, $orders_infos) {
foreach ($orders_infos as $info) {
$total += $info['total'];
}
$html = "html for the overview page: ".$total;
$pdf->writeHTML($html);
};
// compute infos for every order and display
foreach ($orders as $k => $order) {
$orders_infos[$k] = compute_order_infos();
$commands[] = function($pdf, $orders_infos) use ($k) {
$html = "html for this order page ".$orders_infos[$k]['total'];
$pdf->writeHTML($html);
};
}
// now run all the commands
foreach ($commands as $command) {
$command($pdf, $orders_infos);
}
所有的PDF编写命令,包括概述,都将在每次计算完成后在最后执行
一个类似但更简单的示例,以便您更好地了解其工作原理:
$arr = array();
for ($i = 0; $i < 5; $i++) {
$arr[$i] = $i;
}
$funcs = array();
foreach ($arr as $k => $v) {
$funcs[] = function($arr) use($k) {
echo $arr[$k]."\n";
};
}
foreach ($funcs as $func) {
echo "func: ";
$func($arr);
}
不久前我不得不做一个类似的任务,因此我知道重复多次是不好的 我已经创建了一个类,它将首先执行所有计算。让我们称之为“回报”类。这将迭代上个月以来收到的所有订单。然后,它将为用户创建信息
- 每份订单(删除税费等)
- 总体视图(项目数量/总税额/等)
$payoffInfo=new Payoff($arrayWithOrderInfos);
// do creation of tcpdf object include header/footer/ ...
$pdf = new TCPDF();
$pdf->setPDFVersion('1.4');
$pdf->setPrintHeader(FALSE);
$pdf->setPrintFooter(TRUE);
// create first page and set 'overall' like this ...
$pdf->SetFont('Helvetica', '', 12);
$pdf->Cell(0, 0, "Overall amount ".$payoffInfo->getItemCount() , 0, 1, 'L');
$pdf->Ln();
$pdf->SetFont('Helvetica', '', 12);
$pdf->Cell(0, 0,"Overall amount ".$payoffInfo->getOverallAmount() , 0, 1, 'L');
$pdf->Ln();
// include more Overview Informations ...
// Iterate over all single orders ...
foreach($payoffInfo->getOrders() as $item){
$html = "<p><ul>";
$html .= "<li>Item ID: ".$item['order_id']."</li>";
$html .= "<li>Item Price ".$item['price']."</li>";
$html .= "<li>Item Clear Amount ".$item['price_without_tax']."</li>";
$html .= "</ul></p>";
$pdf->writeHTML($html, TRUE, FALSE, TRUE, FALSE, 'L');
}
// Mark Items as billed or sth. else so we don't include them again next month
$payoffInfo->setItemsToStatus("billed");
$pdf->Output($yourDesiredLocation, 'F');
$payoffInfo=新的支付($arrayWithOrderInfos);
//tcpdf对象的创建是否包括页眉/页脚/。。。
$pdf=新的TCPDF();
$pdf->setPDFVersion('1.4');
$pdf->setPrintHeader(假);
$pdf->setPrintFooter(TRUE);
//创建第一页并像这样设置“总体”。。。
$pdf->SetFont('Helvetica','',12);
$pdf->Cell(0,0,“总金额”。$payoffInfo->getItemCount(),0,1,'L');
$pdf->Ln();
$pdf->SetFont('Helvetica','',12);
$pdf->Cell(0,0,“总金额”。$payoffInfo->getOverallAmount(),0,1,'L');
$pdf->Ln();
//包括更多概述信息。。。
//迭代所有单个订单。。。
foreach($payoffInfo->getOrders()作为$item){
$html=“”;
$html.=“- 项目ID:”.$Item['order\u ID']。“
”;
$html.=“- 商品价格”。$Item['Price']。”
;
$html.=“- 项目净金额”。$Item['price\u without\u tax'”
”;
$html.=“
”;
$pdf->writeHTML($html,TRUE,FALSE,TRUE,FALSE,'L');
}
//将项目标记为账单或其他内容,以便我们下个月不再包括它们
$payoffInfo->setItemsToStatus(“账单”);
$pdf->输出($yourDesiredLocation,'F');
为了减少时间并防止在服务器有高负载时生成pdf,我将其移动到“任务”(或其他任何内容)中。这个任务是每月一次(取决于你需要什么时间)的午夜工作。
此解决方案每月可处理约40万份订单,可能还可以处理更多订单
如果你想要时尚的pdf格式,可以完全按照你想要的样式设计,我今天会使用某种乳胶“界面”。因为对整个内容(包括页眉和页脚)进行样式设置要容易得多
希望这能帮助您反思您的任务。谢谢您的回答。我将在我的问题中粘贴一些代码。每个月,我都必须生成一些creditnotes,以便为有时有大量广告客户的客户提供服务。所以我不想做的是计算总结,然后把它呈现出来,然后把所有的条款都详细地呈现出来。因此,我想我可以使用占位符,就像aliasnbpages等。我也有这样的想法,即运行它并将所有需要的数据保存在数组中,以便在最后呈现它们,但我认为可能会有一种更舒适的方法:最后,我按照你的方式来做。我计算了总数,并在循环浏览这些条款时存储了它们,以便在渲染时稍后访问。太多了!虽然很遗憾,但在tcpdf中无法使用自定义占位符:(
$payoffInfo=new Payoff($arrayWithOrderInfos);
// do creation of tcpdf object include header/footer/ ...
$pdf = new TCPDF();
$pdf->setPDFVersion('1.4');
$pdf->setPrintHeader(FALSE);
$pdf->setPrintFooter(TRUE);
// create first page and set 'overall' like this ...
$pdf->SetFont('Helvetica', '', 12);
$pdf->Cell(0, 0, "Overall amount ".$payoffInfo->getItemCount() , 0, 1, 'L');
$pdf->Ln();
$pdf->SetFont('Helvetica', '', 12);
$pdf->Cell(0, 0,"Overall amount ".$payoffInfo->getOverallAmount() , 0, 1, 'L');
$pdf->Ln();
// include more Overview Informations ...
// Iterate over all single orders ...
foreach($payoffInfo->getOrders() as $item){
$html = "<p><ul>";
$html .= "<li>Item ID: ".$item['order_id']."</li>";
$html .= "<li>Item Price ".$item['price']."</li>";
$html .= "<li>Item Clear Amount ".$item['price_without_tax']."</li>";
$html .= "</ul></p>";
$pdf->writeHTML($html, TRUE, FALSE, TRUE, FALSE, 'L');
}
// Mark Items as billed or sth. else so we don't include them again next month
$payoffInfo->setItemsToStatus("billed");
$pdf->Output($yourDesiredLocation, 'F');