engine for repeating headers

This commit is contained in:
Benjamin Beganović 2020-08-26 09:02:38 +02:00
parent bba9d7dc44
commit e965aded06
4 changed files with 92 additions and 13 deletions

View File

@ -62,13 +62,13 @@ class PdfMaker
$this->updateVariables($this->data['variables']);
}
$this->processOptions();
return $this;
}
public function getCompiledHTML($final = false)
{
$this->processOptions();
if ($final) {
$html = $this->document->saveXML();

View File

@ -13,6 +13,7 @@
namespace App\Services\PdfMaker;
use DOMDocument;
use DOMDomError;
use DOMXPath;
trait PdfMakerUtilities
@ -155,14 +156,27 @@ trait PdfMakerUtilities
public function processOptions()
{
if (isset($this->options['print_css']) && $this->options['print_css']) {
if (isset($this->options['repeat_header_and_footer']) && $this->options['repeat_header_and_footer']) {
$this->insertPrintCSS();
$this->wrapIntoTable();
}
}
public function insertPrintCSS()
{
$css = '.page-header,.page-header-space{height:100px}.page-footer,.page-footer-space{height:50px}.page-footer{position:fixed;bottom:0;width:100%;border-top:1px solid #000;background:#ff0}.page-header{position:fixed;top:0;width:100%;border-bottom:1px solid #000;background:#ff0}.page{page-break-after:always}@page{margin:20mm}@media print{thead{display:table-header-group}tfoot{display:table-footer-group}button{display:none}body{margin:0}}';
$css = <<<EOT
table.page-container {
page-break-after: always;
}
thead.page-header {
display: table-header-group;
}
tfoot.page-footer {
display: table-footer-group;
}
EOT;
$css_node = $this->document->createTextNode($css);
@ -180,4 +194,67 @@ trait PdfMakerUtilities
return $head->appendChild($style_node);
}
}
public function wrapIntoTable()
{
$markup = <<<EOT
<table class="page-container" id="page-container">
<thead class="page-report">
<tr>
<th class="page-report-cell" id="repeat-header">
<!-- Repeating header goes here.. -->
</th>
</tr>
</thead>
<tfoot class="report-footer">
<tr>
<td class="report-footer-cell" id="repeat-footer">
<!-- Repeating footer goes here -->
</td>
</tr>
</tfoot>
<tbody class="report-content">
<tr>
<td class="report-content-cell" id="repeat-content">
<!-- Rest of the content goes here -->
</td>
</tr>
</tbody>
</table>
EOT;
$document = new DOMDocument();
$document->loadHTML($markup);
$table = $document->getElementById('page-container');
$this->document->getElementsByTagName('body')
->item(0)
->appendChild($this->document->importNode($table, true));
foreach ($this->data['template'] as $element) {
if ($element['id'] == 'header' || $element['id'] == 'footer') {
continue;
}
$node = $this->document->getElementById($element['id']);
$node->parentNode->removeChild($node);
$this->document->getElementById('repeat-content')->appendChild($node);
}
if ($header = $this->document->getElementById('header')) {
$header = $this->document->getElementById('header');
$header->parentNode->removeChild($header);
$this->document->getElementById('repeat-header')->appendChild($header);
}
if ($footer = $this->document->getElementById('footer')) {
$footer = $this->document->getElementById('footer');
$footer->parentNode->removeChild($footer);
$this->document->getElementById('repeat-footer')->appendChild($footer);
}
}
}

View File

@ -361,18 +361,21 @@ class PdfMakerTest extends TestCase
{
$design = new ExampleDesign();
$html = $design
->document()
->getSectionHTML('product-table');
$state = [
'template' => [],
'template' => [
'product-table' => [
'id' => 'product-table',
'elements' => [
['element' => 'p', 'content' => 'Example paragraph'],
],
],
],
'variables' => [
'labels' => [],
'values' => [],
],
'options' => [
'print_css' => true,
'repeat_header_and_footer' => true,
],
];
@ -382,8 +385,6 @@ class PdfMakerTest extends TestCase
->design(ExampleDesign::class)
->build();
exec('echo "" > storage/logs/laravel.log');
info($maker->getCompiledHTML(true));
}
}

View File

@ -2,6 +2,7 @@
<link href="https://unpkg.com/tailwindcss@^1.0/dist/tailwind.min.css" rel="stylesheet">
<body class="m-10">
<div id="header">$title</div>
<div id="header">My awesome header! $title</div>
<table id="product-table"></table>
<div id="footer">My awesome footer</div>
</body>