SPRBRN
SPRBRN

Reputation: 2462

Dompdf: Use different footer per section or page

When the example code below (copied from here and changed a bit) is processed using dompdf, it generates a five page PDF with three sections and a header and footer. Section 1 and 3 have two pages.

The document should have a different footer for each section. In this example code the footer is different for the first page of each section, but doet not display on the second (and later) pages of section 1 and 3.

If I use one footer-div outside the sections and remove the other footers, then the footer continues over all pages.

How can I get the footer to display on the second pages as well?

HTML structure is not fixed to this example, as long as I get working code.

NB: if this can be solved using a different library, I'm open to that, but I prefer a dompdf solution.

<!DOCTYPE HTML PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xml:lang="en" xmlns="http://www.w3.org/1999/xhtml" lang="en">
<head>
<meta http-equiv="content-type" content="text/html; charset=UTF-8" />

<title>Header and Footer example</title>
<style type="text/css">

@page {
    margin: 2cm;
}

body {
  font-family: sans-serif;
    margin: 0.5cm 0;
    text-align: justify;
}

#header,
#footer {
  position: fixed;
  left: 0;
    right: 0;
    color: #aaa;
    font-size: 0.9em;
}

#header {
  top: 0;
    border-bottom: 0.1pt solid #aaa;
}

#footer {
  bottom: 0;
  border-top: 0.1pt solid #aaa;
}

#header table,
#footer table {
    width: 100%;
    border-collapse: collapse;
    border: none;
}

#header td,
#footer td {
  padding: 0;
    width: 50%;
}

.page-number {
  text-align: center;
}

.page-number:before {
  content: "Page " counter(page);
}

hr {
  page-break-after: always;
  border: 0;
}

</style>

</head>

<body>

<div id="header">
    <div class="page-number"></div>
</div>

<div class="section section1">
<div id="footer">
    Footer example 1
</div>
<h2>Section 1</h2>

<p>
    <img src="images/dompdf_simple.png" style="float: right; margin: 0.5em;" />
Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Sed non
risus. Suspendisse lectus tortor, dignissim sit amet, adipiscing nec,
ultricies sed, dolor. Cras elementum ultrices diam. Maecenas ligula
massa, varius a, semper congue, euismod non, mi. Proin porttitor, orci
nec nonummy molestie, enim est eleifend mi, non fermentum diam nisl sit
amet erat. Duis semper. Duis arcu massa, scelerisque vitae, consequat
in, pretium a, enim. Pellentesque congue. Ut in risus volutpat libero
pharetra tempor. Cras vestibulum bibendum augue. Praesent egestas leo
in pede. Praesent blandit odio eu enim. Pellentesque sed dui ut augue
blandit sodales. Vestibulum ante ipsum primis in faucibus orci luctus
et ultrices posuere cubilia Curae; Aliquam nibh. Mauris ac mauris sed
pede pellentesque fermentum. Maecenas adipiscing ante non diam sodales
hendrerit.</p>
<p>
    <img src="images/dompdf_simple.png" style="float: right; margin: 0.5em;" />
Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Sed non
risus. Suspendisse lectus tortor, dignissim sit amet, adipiscing nec,
ultricies sed, dolor. Cras elementum ultrices diam. Maecenas ligula
massa, varius a, semper congue, euismod non, mi. Proin porttitor, orci
nec nonummy molestie, enim est eleifend mi, non fermentum diam nisl sit
amet erat. Duis semper. Duis arcu massa, scelerisque vitae, consequat
in, pretium a, enim. Pellentesque congue. Ut in risus volutpat libero
pharetra tempor. Cras vestibulum bibendum augue. Praesent egestas leo
in pede. Praesent blandit odio eu enim. Pellentesque sed dui ut augue
blandit sodales. Vestibulum ante ipsum primis in faucibus orci luctus
et ultrices posuere cubilia Curae; Aliquam nibh. Mauris ac mauris sed
pede pellentesque fermentum. Maecenas adipiscing ante non diam sodales
hendrerit.</p>
<p>
    <img src="images/dompdf_simple.png" style="float: right; margin: 0.5em;" />
Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Sed non
risus. Suspendisse lectus tortor, dignissim sit amet, adipiscing nec,
ultricies sed, dolor. Cras elementum ultrices diam. Maecenas ligula
massa, varius a, semper congue, euismod non, mi. Proin porttitor, orci
nec nonummy molestie, enim est eleifend mi, non fermentum diam nisl sit
amet erat. Duis semper. Duis arcu massa, scelerisque vitae, consequat
in, pretium a, enim. Pellentesque congue. Ut in risus volutpat libero
pharetra tempor. Cras vestibulum bibendum augue. Praesent egestas leo
in pede. Praesent blandit odio eu enim. Pellentesque sed dui ut augue
blandit sodales. Vestibulum ante ipsum primis in faucibus orci luctus
et ultrices posuere cubilia Curae; Aliquam nibh. Mauris ac mauris sed
pede pellentesque fermentum. Maecenas adipiscing ante non diam sodales
hendrerit.</p>
<p>
    <img src="images/dompdf_simple.png" style="float: right; margin: 0.5em;" />
Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Sed non
risus. Suspendisse lectus tortor, dignissim sit amet, adipiscing nec,
ultricies sed, dolor. Cras elementum ultrices diam. Maecenas ligula
massa, varius a, semper congue, euismod non, mi. Proin porttitor, orci
nec nonummy molestie, enim est eleifend mi, non fermentum diam nisl sit
amet erat. Duis semper. Duis arcu massa, scelerisque vitae, consequat
in, pretium a, enim. Pellentesque congue. Ut in risus volutpat libero
pharetra tempor. Cras vestibulum bibendum augue. Praesent egestas leo
in pede. Praesent blandit odio eu enim. Pellentesque sed dui ut augue
blandit sodales. Vestibulum ante ipsum primis in faucibus orci luctus
et ultrices posuere cubilia Curae; Aliquam nibh. Mauris ac mauris sed
pede pellentesque fermentum. Maecenas adipiscing ante non diam sodales
hendrerit.</p>
</div><!-- div.section1 -->
<hr/>

<div class="section section2">
<div id="footer">
    Footer example 2
</div>
<h2>Section 2</h2>

<p>
  <img src="images/goldengate.jpg" style="float: left; padding: 0.5em;" width="180"  />
    Ut velit mauris, egestas sed, gravida nec, ornare ut, mi. Aenean ut
orci vel massa suscipit pulvinar. Nulla sollicitudin. Fusce varius,
ligula non tempus aliquam, nunc turpis ullamcorper nibh, in tempus
sapien eros vitae ligula. Pellentesque rhoncus nunc et augue. Integer
id felis. Curabitur aliquet pellentesque diam. Integer quis metus vitae
elit lobortis egestas. Lorem ipsum dolor sit amet, consectetuer
adipiscing elit. Morbi vel erat non mauris convallis vehicula. Nulla et
sapien. Integer tortor tellus, aliquam faucibus, convallis id, congue
eu, quam. Mauris ullamcorper felis vitae erat. Proin feugiat, augue non
elementum posuere, metus purus iaculis lectus, et tristique ligula
justo vitae magna. Morbi vel erat non mauris convallis vehicula. Nulla et
sapien. Integer tortor tellus, aliquam faucibus, convallis id, congue
eu, quam. Mauris ullamcorper felis vitae erat. Proin feugiat, augue non
elementum posuere, metus purus iaculis lectus, et tristique ligula
justo vitae magna.</p>
</div><!-- div.section2 -->
<hr/>
<div class="section section3">
<div id="footer">
    Footer example 3
</div>
<h2>Section 3</h2>

<!-- yeah, we'll have to do better for inline floating elements -->
<p><span style="float: left; font-size: 4em; width: 0.7em; height: 0.9em; line-height: 1;">A</span>liquam convallis sollicitudin purus. Praesent aliquam, enim at
fermentum mollis, ligula massa adipiscing nisl, ac euismod nibh nisl eu
lectus. Fusce vulputate sem at sapien. Vivamus leo. Aliquam euismod
libero eu enim. Nulla nec felis sed leo placerat imperdiet. Aenean
suscipit nulla in justo. Suspendisse cursus rutrum augue. Nulla
tincidunt tincidunt mi. Curabitur iaculis, lorem vel rhoncus faucibus,
felis magna fermentum augue, et ultricies lacus lorem varius purus.
Curabitur eu amet.</p>

<p>Aliquam convallis sollicitudin purus. Praesent aliquam, enim at
fermentum mollis, ligula massa adipiscing nisl, ac euismod nibh nisl eu
lectus. Fusce vulputate sem at sapien. Vivamus leo. Aliquam euismod
libero eu enim. Nulla nec felis sed leo placerat imperdiet. Aenean
suscipit nulla in justo. Suspendisse cursus rutrum augue. Nulla
tincidunt tincidunt mi. Curabitur iaculis, lorem vel rhoncus faucibus,
felis magna fermentum augue, et ultricies lacus lorem varius purus.
Curabitur eu amet.</p>

<p>Aliquam convallis sollicitudin purus. Praesent aliquam, enim at
fermentum mollis, ligula massa adipiscing nisl, ac euismod nibh nisl eu
lectus. Fusce vulputate sem at sapien. Vivamus leo. Aliquam euismod
libero eu enim. Nulla nec felis sed leo placerat imperdiet. Aenean
suscipit nulla in justo. Suspendisse cursus rutrum augue. Nulla
tincidunt tincidunt mi. Curabitur iaculis, lorem vel rhoncus faucibus,
felis magna fermentum augue, et ultricies lacus lorem varius purus.
Curabitur eu amet.</p>

<p>Aliquam convallis sollicitudin purus. Praesent aliquam, enim at
fermentum mollis, ligula massa adipiscing nisl, ac euismod nibh nisl eu
lectus. Fusce vulputate sem at sapien. Vivamus leo. Aliquam euismod
libero eu enim. Nulla nec felis sed leo placerat imperdiet. Aenean
suscipit nulla in justo. Suspendisse cursus rutrum augue. Nulla
tincidunt tincidunt mi. Curabitur iaculis, lorem vel rhoncus faucibus,
felis magna fermentum augue, et ultricies lacus lorem varius purus.
Curabitur eu amet.</p>

<p>Aliquam convallis sollicitudin purus. Praesent aliquam, enim at
fermentum mollis, ligula massa adipiscing nisl, ac euismod nibh nisl eu
lectus. Fusce vulputate sem at sapien. Vivamus leo. Aliquam euismod
libero eu enim. Nulla nec felis sed leo placerat imperdiet. Aenean
suscipit nulla in justo. Suspendisse cursus rutrum augue. Nulla
tincidunt tincidunt mi. Curabitur iaculis, lorem vel rhoncus faucibus,
felis magna fermentum augue, et ultricies lacus lorem varius purus.
Curabitur eu amet.</p>

<p>Aliquam convallis sollicitudin purus. Praesent aliquam, enim at
fermentum mollis, ligula massa adipiscing nisl, ac euismod nibh nisl eu
lectus. Fusce vulputate sem at sapien. Vivamus leo. Aliquam euismod
libero eu enim. Nulla nec felis sed leo placerat imperdiet. Aenean
suscipit nulla in justo. Suspendisse cursus rutrum augue. Nulla
tincidunt tincidunt mi. Curabitur iaculis, lorem vel rhoncus faucibus,
felis magna fermentum augue, et ultricies lacus lorem varius purus.
Curabitur eu amet.</p>

<p>Aliquam convallis sollicitudin purus. Praesent aliquam, enim at
fermentum mollis, ligula massa adipiscing nisl, ac euismod nibh nisl eu
lectus. Fusce vulputate sem at sapien. Vivamus leo. Aliquam euismod
libero eu enim. Nulla nec felis sed leo placerat imperdiet. Aenean
suscipit nulla in justo. Suspendisse cursus rutrum augue. Nulla
tincidunt tincidunt mi. Curabitur iaculis, lorem vel rhoncus faucibus,
felis magna fermentum augue, et ultricies lacus lorem varius purus.
Curabitur eu amet.</p>

<p>Aliquam convallis sollicitudin purus. Praesent aliquam, enim at
fermentum mollis, ligula massa adipiscing nisl, ac euismod nibh nisl eu
lectus. Fusce vulputate sem at sapien. Vivamus leo. Aliquam euismod
libero eu enim. Nulla nec felis sed leo placerat imperdiet. Aenean
suscipit nulla in justo. Suspendisse cursus rutrum augue. Nulla
tincidunt tincidunt mi. Curabitur iaculis, lorem vel rhoncus faucibus,
felis magna fermentum augue, et ultricies lacus lorem varius purus.
Curabitur eu amet.</p>

<p>Aliquam convallis sollicitudin purus. Praesent aliquam, enim at
fermentum mollis, ligula massa adipiscing nisl, ac euismod nibh nisl eu
lectus. Fusce vulputate sem at sapien. Vivamus leo. Aliquam euismod
libero eu enim. Nulla nec felis sed leo placerat imperdiet. Aenean
suscipit nulla in justo. Suspendisse cursus rutrum augue. Nulla
tincidunt tincidunt mi. Curabitur iaculis, lorem vel rhoncus faucibus,
felis magna fermentum augue, et ultricies lacus lorem varius purus.
Curabitur eu amet.</p>

<p>Aliquam convallis sollicitudin purus. Praesent aliquam, enim at
fermentum mollis, ligula massa adipiscing nisl, ac euismod nibh nisl eu
lectus. Fusce vulputate sem at sapien. Vivamus leo. Aliquam euismod
libero eu enim. Nulla nec felis sed leo placerat imperdiet. Aenean
suscipit nulla in justo. Suspendisse cursus rutrum augue. Nulla
tincidunt tincidunt mi. Curabitur iaculis, lorem vel rhoncus faucibus,
felis magna fermentum augue, et ultricies lacus lorem varius purus.
Curabitur eu amet.</p>
</div><!-- div.section3 -->

</body></html>

Upvotes: 0

Views: 832

Answers (1)

BrianS
BrianS

Reputation: 13914

There appears to be some bugginess around rendering a fixed-position element that's contained inside another element.

That being said, this can work ... sort of. Because of the way dompdf renders a document fixed position elements render starting on the page where they are encountered (this may change in the future, watch issue #491). Also, PDFs are rendered in layers with later elements layered on top of earlier elements. So with your structure each section footer is rendered on top of the previous footer.

The only problem is that the previous footers will show through unless you block them out. Which you can easily do by adding a background color. It's a bit ugly structurally in the PDF because by the end of the document because all the footers will be on the page, but visually it should appear how you want.

So you need to do a few things:

  1. Move the footers outside the section DIVs.
  2. Give the footers a background color so that underlying footers are hidden.
  3. You should really use classes instead of IDs to avoid any HTML parsing issues (IDs are supposed to be unique).

For example:

<html>
<head>
<meta http-equiv="content-type" content="text/html; charset=UTF-8" />

<title>Header and Footer example</title>
<style type="text/css">

@page {
    margin: 2cm;
}

body {
  font-family: sans-serif;
    margin: 0.5cm 0;
    text-align: justify;
}

.header,
.footer {
  position: fixed;
  left: 0;
    right: 0;
    color: #aaa;
    font-size: 0.9em;
}

.header {
  top: 0;
    border-bottom: 0.1pt solid #aaa;
}

.footer {
  bottom: 0;
  border-top: 0.1pt solid #aaa;
  background-color: white;
}

.page-number {
  text-align: center;
}

.page-number:before {
  content: "Page " counter(page);
}

.section {
  page-break-after: always;
}

</style>

</head>

<body>

<div class="header">
    <div class="page-number"></div>
</div>

<div class="footer">
    Footer example 1
</div>

<div class="section section1">
<h2>Section 1</h2>

<!-- section content -->
</div>


<div id="footer2" class="footer footer2">
    Footer example 2
</div>

<div class="section section2">
<h2>Section 2</h2>

<!-- section content -->
</div>

</body></html>

Except this doesn't work as well as I thought it would. The above sample does work if your sections are only a single page, but not if any section prior to the last is more than one page. In that situation the second and subsequent pages of a section will have the footer of the last section. So even the current quirkiness related to document processing is buggy. :/

Still it's possible to do, but you'll have to use inline script to achieve it. Overall your code can be similar, but you have to add some script and additional structure around your footer.

<html>
<head>
<meta http-equiv="content-type" content="text/html; charset=UTF-8" />

<title>Header and Footer example</title>
<style type="text/css">

@page {
    margin: 2cm;
}

body {
  font-family: sans-serif;
    margin: 0.5cm 0;
    text-align: justify;
}

/* positioning */

.header,
.footer-positioner {
  left: 0;
    right: 0;
}

.header {
  position: fixed;
  top: 0;
}

.footer-positioner {
  position: absolute;
  bottom: 0;
}


/* styling */

.header,
.footer {
    background-color: white;
    color: #aaa;
    font-size: 0.9em;
}

.header {
    border-bottom: 0.1pt solid #aaa;
}

.footer {
  border-top: 0.1pt solid #aaa;
  background-color: white;
}

.page-number {
  text-align: center;
}

.page-number:before {
  content: "Page " counter(page);
}

.section {
  page-break-before: always;
}
.section:first-child {
  page-break-before: auto;
}

</style>

</head>

<body>

<div class="header">
    <div class="page-number"></div>
</div>

<div class="section section1">

  <div class="footer-positioner">
    <script type="text/php">
    $GLOBALS['section'] = $pdf->open_object();
    </script>
      <div class="footer">
        Footer example 1
      </div>
    <script type="text/php">
    $pdf->close_object();
    $pdf->add_object($GLOBALS['section'], 'all');
    </script>
  </div>

  <h2>Section 1</h2>

  <!-- section content -->

  <script type="text/php">
  $pdf->stop_object($GLOBALS['section']);
  </script>

</div>


<div class="section section2">

  <div class="footer-positioner">
    <script type="text/php">
    $GLOBALS['section'] = $pdf->open_object();
    </script>
      <div class="footer">
        Footer example 2
      </div>
    <script type="text/php">
    $pdf->close_object();
    $pdf->add_object($GLOBALS['section'], 'all');
    </script>
  </div>

  <h2>Section 2</h2>

  <!-- section content -->

  <script type="text/php">
  $pdf->stop_object($GLOBALS['section']);
  </script>

</div>

</body></html>

Note: the white background is still necessary because you can't add an object and stop it on the same page. So footers from any one-page sections will still show up on the first page of the following section.

Upvotes: 1

Related Questions