Merge pull request '2162-print_pdf_puppeteer' (#335) from 2162-print_pdf_puppeteer into dev
gitea/salix/pipeline/head This commit looks good Details

Reviewed-on: #335
Reviewed-by: Bernat Exposito <bernat@verdnatura.es>
This commit is contained in:
Joan Sanchez 2020-07-09 07:26:41 +00:00
commit bdc37e7fc1
21 changed files with 147 additions and 183 deletions

View File

@ -157,22 +157,6 @@ table {
border-spacing: 0; border-spacing: 0;
} }
/**
* Prevent page break fix
*/
tbody {
page-break-inside: avoid;
break-inside: avoid;
display: block;
width: 100%
}
thead, tbody tr {
table-layout: fixed;
display: table;
width: 100%;
}
.row-oriented, .column-oriented { .row-oriented, .column-oriented {
text-align: left; text-align: left;
width: 100% width: 100%
@ -188,6 +172,7 @@ thead, tbody tr {
} }
.column-oriented thead { .column-oriented thead {
display: table-header-group;
background-color: #e5e5e5 background-color: #e5e5e5
} }
@ -197,18 +182,24 @@ thead, tbody tr {
background-color: #e5e5e5 background-color: #e5e5e5
} }
.column-oriented tfoot {
display: table-row-group;
page-break-inside: avoid;
break-inside: avoid;
}
.column-oriented tbody { .column-oriented tbody {
border-bottom: 1px solid #DDD; border-bottom: 1px solid #DDD;
} }
.column-oriented tfoot {
border-top: 2px solid #808080;
}
.column-oriented tfoot tr:first-child td { .column-oriented tfoot tr:first-child td {
padding-top: 20px !important; padding-top: 20px !important;
} }
.column-oriented tfoot tr:first-child {
border-top: 2px solid #808080;
}
.column-oriented .description { .column-oriented .description {
font-size: 0.8em font-size: 0.8em
} }

View File

@ -3,12 +3,12 @@
* *
*/ */
body { body {
zoom: 0.53 zoom: 0.70;
} }
.title { .title {
margin-bottom: 20px; margin-bottom: 20px;
font-weight: 100; font-weight: 100;
margin-top: 0; font-size: 2em;
font-size: 2em margin-top: 0
} }

View File

@ -13,10 +13,14 @@
}, },
"pdf": { "pdf": {
"format": "A4", "format": "A4",
"border": "1.5cm", "margin": {
"footer": { "top": "1.5cm",
"height": "55px" "right": "1.5cm",
} "bottom": "3cm",
"left": "1.5cm"
},
"displayHeaderFooter": true,
"printBackground": true
}, },
"mysql": { "mysql": {
"host": "localhost", "host": "localhost",

View File

@ -1,11 +1,13 @@
footer { .footer {
font-family: "Roboto", "Helvetica", "Arial", sans-serif; font-family: "Roboto", "Helvetica", "Arial", sans-serif;
font-size: 0.55em; margin-left: 2cm;
margin-right: 2cm;
font-size: 10px;
color: #555; color: #555;
zoom: 0.65 zoom: 0.65
} }
footer, footer p { .footer p {
text-align: center text-align: center
} }
@ -13,12 +15,20 @@ p.privacy {
font-size: 0.8em font-size: 0.8em
} }
footer .page { .footer .page {
border-bottom: 2px solid #CCC; border-bottom: 2px solid #CCC;
padding-bottom: 2px padding-bottom: 2px
} }
footer .page > section { .page .centerText {
text-align: center
}
.page .pageCount {
text-align: right
}
.footer .page > div {
display: inline-block; display: inline-block;
width: 33% width: 33%
} }

View File

@ -1,4 +1,4 @@
numPages: Page {{page}} of {{pages}} numPages: Page <span class="pageNumber"></span> of <span class="totalPages"></span>
law: law:
privacy: 'In compliance with the provisions of Organic Law 15/1999, on the privacy: 'In compliance with the provisions of Organic Law 15/1999, on the
Protection of Personal Data, we inform you that the personal data you provide Protection of Personal Data, we inform you that the personal data you provide

View File

@ -1,4 +1,4 @@
numPages: Página {{page}} de {{pages}} numPages: Página <span class="pageNumber"></span> de <span class="totalPages"></span>
law: law:
privacy: En cumplimiento de lo dispuesto en la Ley Orgánica 15/1999, de Protección privacy: En cumplimiento de lo dispuesto en la Ley Orgánica 15/1999, de Protección
de Datos de Carácter Personal, le comunicamos que los datos personales que facilite de Datos de Carácter Personal, le comunicamos que los datos personales que facilite

View File

@ -1,4 +1,4 @@
numPages: Page {{page}} de {{pages}} numPages: Page <span class="pageNumber"></span> de <span class="totalPages"></span>
law: law:
privacy: Conformément aux dispositions de la loi organique 15/1999 sur la protection privacy: Conformément aux dispositions de la loi organique 15/1999 sur la protection
des données personnelles, nous vous informons que les données personnelles que des données personnelles, nous vous informons que les données personnelles que

View File

@ -1,4 +1,4 @@
numPages: Página {{page}} de {{pages}} numPages: Página <span class="pageNumber"></span> de <span class="totalPages"></span>
law: law:
privacy: Em cumprimento do disposto na lei Orgânica 15/1999, de Protecção de Dados privacy: Em cumprimento do disposto na lei Orgânica 15/1999, de Protecção de Dados
de Carácter Pessoal, comunicamos que os dados pessoais que facilite se incluirão de Carácter Pessoal, comunicamos que os dados pessoais que facilite se incluirão

View File

@ -1,9 +1,11 @@
<footer> <div>
<section class="page"> <div class="footer">
<section v-if="leftText">{{leftText}}</section> <div class="page">
<section v-if="centerText" class="uppercase">{{centerText}}</section> <div class="leftText" v-if="leftText">{{leftText}}</div>
<section class="number">{{$t('numPages')}}</section> <div class="centerText" v-if="centerText" class="uppercase">{{centerText}}</div>
</section> <div class="pageCount" v-html="$t('numPages')"></div>
<p class="phytosanitary" v-if="showPhytosanitary">{{phytosanitary}}</p> </div>
<p class="privacy" v-html="$t('law.privacy')"></p> <p class="phytosanitary" v-if="showPhytosanitary">{{phytosanitary}}</p>
</footer> <p class="privacy" v-html="$t('law.privacy')"></p>
</div>
</div>

View File

@ -4,7 +4,7 @@ header {
padding-bottom: 10px; padding-bottom: 10px;
margin-bottom: 20px; margin-bottom: 20px;
text-align: center; text-align: center;
font-size: 0.55em; font-size: 12px;
color: #555 color: #555
} }

View File

@ -1,5 +1,5 @@
const fs = require('fs'); const fs = require('fs');
const pdf = require('html-pdf'); const puppeteer = require('puppeteer');
const path = require('path'); const path = require('path');
const config = require('./config'); const config = require('./config');
const Component = require('./component'); const Component = require('./component');
@ -20,18 +20,36 @@ class Report extends Component {
async toPdfStream() { async toPdfStream() {
const template = await this.render(); const template = await this.render();
let options = config.pdf; const defaultOptions = Object.assign({}, config.pdf);
const optionsPath = `${this.path}/options.json`; const optionsPath = `${this.path}/options.json`;
const fullPath = path.resolve(__dirname, optionsPath); const fullPath = path.resolve(__dirname, optionsPath);
let options = defaultOptions;
if (fs.existsSync(fullPath)) if (fs.existsSync(fullPath))
options = Object.assign(options, require(optionsPath)); options = require(optionsPath);
return new Promise(resolve => { const browser = await puppeteer.launch({headless: true});
pdf.create(template, options).toStream((err, stream) => { const page = await browser.newPage();
resolve(stream); await page.setContent(template);
});
}); const element = await page.$('#pageFooter');
let footer = '\n';
if (element) {
footer = await page.evaluate(el => {
const html = el.innerHTML;
el.remove();
return html;
}, element);
}
options.headerTemplate = '\n';
options.footerTemplate = footer;
const buffer = await page.pdf(options);
await browser.close();
return buffer;
} }
} }

View File

@ -10,8 +10,7 @@ module.exports = app => {
res.setHeader('Content-type', 'application/pdf'); res.setHeader('Content-type', 'application/pdf');
res.setHeader('Content-Disposition', `inline; filename="${fileName}"`); res.setHeader('Content-Disposition', `inline; filename="${fileName}"`);
res.end(stream);
stream.pipe(res);
} catch (error) { } catch (error) {
next(error); next(error);
} }

View File

@ -6,11 +6,7 @@
<tr> <tr>
<td> <td>
<!-- Header block --> <!-- Header block -->
<div class="grid-row"> <report-header v-bind="$props"></report-header>
<div class="grid-block">
<report-header v-bind="$props"></report-header>
</div>
</div>
<!-- Block --> <!-- Block -->
<div class="grid-row"> <div class="grid-row">
<div class="grid-block"> <div class="grid-block">
@ -93,15 +89,11 @@
</div> </div>
</div> </div>
<!-- Footer block --> <!-- Footer block -->
<div class="grid-row"> <report-footer id="pageFooter"
<div class="grid-block"> v-bind:left-text="$t('client', [client.id])"
<report-footer id="pageFooter" v-bind:center-text="client.socialName"
v-bind:left-text="$t('client', [client.id])" v-bind="$props">
v-bind:center-text="client.socialName" </report-footer>
v-bind="$props">
</report-footer>
</div>
</div>
</td> </td>
</tr> </tr>
</tbody> </tbody>

View File

@ -6,11 +6,7 @@
<tr> <tr>
<td> <td>
<!-- Header block --> <!-- Header block -->
<div class="grid-row"> <report-header v-bind="$props"></report-header>
<div class="grid-block">
<report-header v-bind="$props"></report-header>
</div>
</div>
<!-- Block --> <!-- Block -->
<div class="grid-row"> <div class="grid-row">
<div class="grid-block"> <div class="grid-block">
@ -85,15 +81,11 @@
</div> </div>
</div> </div>
<!-- Footer block --> <!-- Footer block -->
<div class="grid-row"> <report-footer id="pageFooter"
<div class="grid-block"> v-bind:left-text="$t('claim', [claimId])"
<report-footer id="pageFooter" v-bind:center-text="client.name"
v-bind:left-text="$t('claim', [claimId])" v-bind="$props">
v-bind:center-text="client.name" </report-footer>
v-bind="$props">
</report-footer>
</div>
</div>
</td> </td>
</tr> </tr>
</tbody> </tbody>

View File

@ -6,13 +6,9 @@
<tr> <tr>
<td> <td>
<!-- Header block --> <!-- Header block -->
<div class="grid-row"> <report-header v-bind="$props"
<div class="grid-block"> v-bind:company-code="ticket.companyCode">
<report-header v-bind="$props" </report-header>
v-bind:company-code="ticket.companyCode">
</report-header>
</div>
</div>
<!-- Block --> <!-- Block -->
<div class="grid-row"> <div class="grid-row">
<div class="grid-block"> <div class="grid-block">
@ -241,17 +237,13 @@
</div> </div>
</div> </div>
<!-- Footer block --> <!-- Footer block -->
<div class="grid-row"> <report-footer id="pageFooter"
<div class="grid-block"> v-bind:company-code="ticket.companyCode"
<report-footer id="pageFooter" v-bind:show-phytosanitary="true"
v-bind:company-code="ticket.companyCode" v-bind:left-text="$t('ticket', [ticket.id])"
v-bind:show-phytosanitary="true" v-bind:center-text="client.socialName"
v-bind:left-text="$t('ticket', [ticket.id])" v-bind="$props">
v-bind:center-text="client.socialName" </report-footer>
v-bind="$props">
</report-footer>
</div>
</div>
</td> </td>
</tr> </tr>
</tbody> </tbody>

View File

@ -6,11 +6,7 @@
<tr> <tr>
<td> <td>
<!-- Header block --> <!-- Header block -->
<div class="grid-row"> <report-header v-bind="$props"></report-header>
<div class="grid-block">
<report-header v-bind="$props"></report-header>
</div>
</div>
<!-- Block --> <!-- Block -->
<div class="grid-row"> <div class="grid-row">
<div class="grid-block"> <div class="grid-block">
@ -154,14 +150,10 @@
</div> </div>
</div> </div>
<!-- Footer block --> <!-- Footer block -->
<div class="grid-row"> <report-footer id="pageFooter"
<div class="grid-block"> v-bind:left-text="$t('routeId', [route.id])"
<report-footer id="pageFooter" v-bind="$props">
v-bind:left-text="$t('routeId', [route.id])" </report-footer>
v-bind="$props">
</report-footer>
</div>
</div>
</td> </td>
</tr> </tr>
</tbody> </tbody>

View File

@ -6,13 +6,9 @@
<tr> <tr>
<td> <td>
<!-- Header block --> <!-- Header block -->
<div class="grid-row"> <report-header v-bind="$props"
<div class="grid-block"> v-bind:company-code="entry.companyCode">
<report-header v-bind="$props" </report-header>
v-bind:company-code="entry.companyCode">
</report-header>
</div>
</div>
<!-- Block --> <!-- Block -->
<div class="grid-row"> <div class="grid-row">
<div class="grid-block"> <div class="grid-block">
@ -126,16 +122,12 @@
</div> </div>
</div> </div>
<!-- Footer block --> <!-- Footer block -->
<div class="grid-row"> <report-footer id="pageFooter"
<div class="grid-block"> v-bind:left-text="$t('entry', [entry.id])"
<report-footer id="pageFooter" v-bind:company-code="entry.companyCode"
v-bind:left-text="$t('entry', [entry.id])" v-bind:center-text="supplier.name"
v-bind:company-code="entry.companyCode" v-bind:="$props">
v-bind:center-text="supplier.name" </report-footer>
v-bind:="$props">
</report-footer>
</div>
</div>
</td> </td>
</tr> </tr>
</tbody> </tbody>

View File

@ -1,10 +1,11 @@
{ {
"format": "A4",
"orientation": "landscape",
"width": "10.4cm", "width": "10.4cm",
"height": "4.8cm", "height": "4.8cm",
"border": "0cm", "margin": {
"footer": { "top": "0cm",
"height": "0" "right": "0cm",
} "bottom": "0cm",
"left": "0cm"
},
"printBackground": true
} }

View File

@ -6,11 +6,7 @@
<tr> <tr>
<td> <td>
<!-- Header block --> <!-- Header block -->
<div class="grid-row"> <report-header v-bind="$props"></report-header>
<div class="grid-block">
<report-header v-bind="$props"></report-header>
</div>
</div>
<!-- Block --> <!-- Block -->
<div class="grid-row"> <div class="grid-row">
<div class="grid-block"> <div class="grid-block">
@ -74,24 +70,23 @@
<tr> <tr>
<td></td> <td></td>
<td></td> <td></td>
<td class="number"><strong class="pull-left">Total</strong> {{getTotalDebtOut()}}</td> <td class="number">
<td class="number">{{getTotalDebtIn()}}</td> <strong class="pull-left">Total</strong>
<td class="number">{{totalBalance}}</td> {{getTotalDebtOut() | currency('EUR', $i18n.locale)}}
</td>
<td class="number">{{getTotalDebtIn() | currency('EUR', $i18n.locale)}}</td>
<td class="number">{{totalBalance | currency('EUR', $i18n.locale)}}</td>
</tr> </tr>
</tfoot> </tfoot>
</table> </table>
</div> </div>
</div> </div>
<!-- Footer block --> <!-- Footer block -->
<div class="grid-row"> <report-footer id="pageFooter"
<div class="grid-block"> v-bind:left-text="$t('client', [client.id])"
<report-footer id="pageFooter" v-bind:center-text="client.socialName"
v-bind:left-text="$t('client', [client.id])" v-bind="$props">
v-bind:center-text="client.socialName" </report-footer>
v-bind="$props">
</report-footer>
</div>
</div>
</td> </td>
</tr> </tr>
</tbody> </tbody>

View File

@ -6,11 +6,7 @@
<tr> <tr>
<td> <td>
<!-- Header block --> <!-- Header block -->
<div class="grid-row"> <report-header v-bind="$props"></report-header>
<div class="grid-block">
<report-header v-bind="$props"></report-header>
</div>
</div>
<!-- Block --> <!-- Block -->
<div class="grid-row"> <div class="grid-row">
<div class="grid-block"> <div class="grid-block">
@ -36,15 +32,11 @@
</div> </div>
</div> </div>
<!-- Footer block --> <!-- Footer block -->
<div class="grid-row"> <report-footer id="pageFooter"
<div class="grid-block"> v-bind:left-text="$t('client', [client.id])"
<report-footer id="pageFooter" v-bind:center-text="client.socialName"
v-bind:left-text="$t('client', [client.id])" v-bind="$props">
v-bind:center-text="client.socialName" </report-footer>
v-bind="$props">
</report-footer>
</div>
</div>
</td> </td>
</tr> </tr>
</tbody> </tbody>

View File

@ -6,11 +6,7 @@
<tr> <tr>
<td> <td>
<!-- Header block --> <!-- Header block -->
<div class="grid-row"> <report-header v-bind="$props"></report-header>
<div class="grid-block">
<report-header v-bind="$props"></report-header>
</div>
</div>
<!-- Block --> <!-- Block -->
<div class="grid-row"> <div class="grid-row">
<div class="grid-block"> <div class="grid-block">
@ -166,15 +162,11 @@
</div> </div>
</div> </div>
<!-- Footer block --> <!-- Footer block -->
<div class="grid-row"> <report-footer id="pageFooter"
<div class="grid-block"> v-bind:left-text="$t('order', [supplier.mandateCode])"
<report-footer id="pageFooter" v-bind:center-text="client.socialName"
v-bind:left-text="$t('order', [supplier.mandateCode])" v-bind="$props">
v-bind:center-text="client.socialName" </report-footer>
v-bind="$props">
</report-footer>
</div>
</div>
</td> </td>
</tr> </tr>
</tbody> </tbody>