How to print A4 pages using CSS?

5

I currently use the mpdf library for reporting. However, in some reports I need to issue more than 400 pdf pages and this takes a lot of time and consumes a lot of server resources.

I even checked library performance issues to try to optimize it, but nothing worked mpdf Slow!

So I decided to create my reports in HTML and CSS, and I encountered some difficulties:

1 ° I'm going to be dependent on the browser's plugins and the like for printing in pdf.

2nd. My layout follows a standard pattern with a header on all pages and a table with information. So I need to know when the information fills the entire A4 sheet to create a new page and repeat the process.

I used the native PDF save in Google Chrome and CutePDF Writer to issue in pdf, but they have differences in display form; so my question is:

How do I recognize the page boundary?

How to improve print compatibility?

Procedure example.

body {
  background: rgb(204, 204, 204);
}
page {
  background: white;
  display: block;
  margin: 0 auto;
  margin-bottom: 0.5cm;
  box-shadow: 0 0 0.5cm rgba(0, 0, 0, 0.5);
}
page[size="A4"] {
  width: 21cm;
  height: 29.7cm;
}
page[size="A4"][layout="portrait"] {
  width: 29.7cm;
  height: 21cm;
}
@media print {
  body,
  page {
    margin: 0;
    box-shadow: 0;
  }
}
.header {
  padding-top: 10px;
  text-align: center;
  border: 2px solid #ddd;
}
table {
  border-collapse: collapse;
  width: 100%;
  font-size: 80%;
}
table th {
  background-color: #4caf50;
  color: white;
  text-align: center;
}
th,
td {
  border: 1px solid #ddd;
  text-align: left;
}
tr:nth-child(even) {
  background-color: #f2f2f2
}
<page size="A4">

  <div class="header">
    [nomeEmpresa]
    <br>[endereco] - [cidade] - [cep]
    <br>[cnpj] - [telefone]
    <br>
    <h3>[nomeRelatorio] -  [tipoRelatorio]</h3>
  </div>

  <table class="table">
    <thead>
      <tr>
        <th>[coluna0]</th>
        <th>[coluna1]</th>
        <th>[coluna2]</th>
        <th>[coluna3]</th>
      </tr>
    </thead>
    <tbody>
      <tr>
        <td>1</td>
        <td>Mark</td>
        <td>Otto</td>
        <td>@mdo</td>
      </tr>
      <tr>
        <td>2</td>
        <td>Jacob</td>
        <td>Thornton</td>
        <td>@fat</td>
      </tr>
      <tr>
        <td>3</td>
        <td>Larry</td>
        <td>the Bird</td>
        <td>@twitter</td>
      </tr>
    </tbody>
  </table>
</page>

<page size="A4"></page>

also in: jsfiddle

    
asked by anonymous 25.08.2016 / 15:35

2 answers

1

If you already know how many items fit per page or you want to arbitrarily designate when a page should be broken you can use the page-break-after or related page-break-before there is an element of your page, such as one. In your case, maybe, it could be the very tag

@media print {     page {page-break-after: always;} }

Source: link

References: link

    
22.09.2016 / 20:19
1

You can go to any of the alternatives below. It depends on how precise it needs to be.

Method 1

What I usually do in personal projects, which do not require much precision, is to set the font size in 12pt to html in my CSS for 100% of its size. Then convert the size of a common A4 sheet of millimeters ( 210 x 297 ) to pixels ( 793 x 1122 ). Thus, I define a% w / o of the sheet size and another% w / o of% to serve as an insulator and place the contents: each information can have its font size that will not change the dimensions of% w / o% (not the A4 letter). Add margin as needed.

I must say that works for me, especially with mono-spaced font. Here's an example:

html { font-size: 12pt; }

.folha { background-color: #ccc; padding: 0.5em; }
.a4_vertical { width: 793px; height: 1122px; }
.a4_horizontal { width: 1122px; height: 793px; }
<div id="folha-a4" class="folha a4_vertical">
   <div id="conteudo">
       Folha A4
   </div>
</div>

Method 2

If you want more accuracy, I recommend using the Paper CSS that has the MIT . To use, you basically need ...

... No <div>

  • Load style: <div>
  • Sets the paper size: <div>

... No <header>

  • Adds the paper size class (% with%)
  • Adds whether it is in landscape format ( <link rel="stylesheet" href="dist/paper.css"> ) - portrait is default
  • In the ( <style>@page { size: A5 }</style> , <body> , et cetera ) tag that will have all the contents of a sheet, add the A4 class. Each sheet is landscape different!

There are other details that can be learned as needed. There are also several examples on the site. Here is an adapted one:

<link href="https://cdnjs.cloudflare.com/ajax/libs/paper-css/0.3.0/paper.css" rel="stylesheet" />
<style>
  @page {
    size: A4
  }
</style>

<body class="A4">

  <section class="sheet padding-10mm">

    <article>Exemplo de folha A4</article>

  </section>

</body>

It's worth mentioning that you can generate PDF with electron-pdf , as the project page tells you. I think it uses less resources.

    
04.11.2017 / 03:23