2013-06-12 2 views
1

Я выполняю некоторые сложные вычисления для кредитного кредита, а первая страница представляет собой сводку общей суммы. То, что я не хочу делать, - это выполнить все положения, чтобы вычислить сводку, а затем снова запустить их, чтобы отобразить подробный вид. . Можно ли определить пользовательские заполнители, которые я могу заменить после добавления подробного представления? Или вы знаете другой способ добиться желаемого результата без выполнения расчетов дважды?Использовать заполнитель в TCPDF

Edit:

Это, как я сделать детальный вид:

 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

ответ

1

я должен был сделать подобную задачу некоторое время назад, и, следовательно, Знайте, что плохо повторять несколько раз.

Я создал класс, который сначала выполнит все вычисления. Назовем класс «payoff». Это приведет к повторению всех заказов, поступивших с прошлого месяца. Он будет создавать информацию для

  • каждый Зингель заказ (удаление налога/и т.д ...)
  • общий вид (сколько элементов/общая сумма налога/и т.д.).

Так это может выглядеть следующим образом

$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'); 

чтобы уменьшить количество времени, а также для предотвращения генерации PDF в то время как сервер имеет высокую нагрузку, я переехал это к «задаче» (или что-нибудь еще). Затем эту задачу вызывают один раз в месяц (в зависимости от того, какой период времени вам нужен) на работу cron в середине ночи.

Это решение отлично подходит для ~ 400 тыс. Заказов в месяц, и возможно, это может сделать намного больше.

Если вы хотите стильные pdf-файлы, которые могут быть созданы так, как вы хотите, я бы использовал какой-то интерфейс LaTeX «Интерфейс» сегодня. Потому что гораздо проще стилизовать весь контент, включая верхний и нижний колонтитулы.

Надеюсь, это поможет вам задуматься о своей задаче.

+0

На конец, я сделал это по-твоему. Я вычислил общее количество и в то же время перейдя через положения, которые я сохранил для последующего доступа при рендеринге. Большое спасибо! Хотя очень грустно, что нет возможности использовать пользовательские заполнители в tcpdf :( –

2

Насколько я понимаю, вы текущий код выглядит примерно так:

// 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-файл, но вы сказали, что по какой-то причине вы этого не хотели.

Следующим лучшим способом добиться того, что вы хотите, является обмануть немного и отслеживать список команд для запуска как closures, а затем запустить их в конце, таким образом, вы сохраняете большую часть своей текущей организации кода, но все же сохраняете делать все последующее отображение;

$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); 
} 

Displays:

$ php test.php 
func: 0 
func: 1 
func: 2 
func: 3 
func: 4 
+0

Благодарим вас за ответ. Я вставлю часть своего кода в свой вопрос. Каждый месяц я должен генерировать несколько кредитных нот для обеспечения клиентов иногда с большим количеством рекламируемых клиентов. Поэтому то, что я не хотел делать, это вычислить итоговое отображение, а затем пропустить все положения и сделать их подробно. Поэтому я подумал, что могу использовать заполнители так же, как aliasnbpages и т. Д. У меня тоже была мысль пропустить его и сохранить все необходимые данные в массивах, чтобы сделать их в конце, но я подумал, что может быть более удобный способ: D –

Смежные вопросы