Skip to content

Commit

Permalink
Ondersteuning voor printen naar PDF dankzij de jsPDF library.
Browse files Browse the repository at this point in the history
  • Loading branch information
igoethal committed Oct 6, 2024
1 parent f222673 commit 866b1e7
Show file tree
Hide file tree
Showing 14 changed files with 696 additions and 19 deletions.
3 changes: 2 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ We refer to the online version if you whish to use this tool in a production set

=== L I C E N S E ===

Copyright (C) 2019-2023 Ivan Goethals
Copyright (C) 2019-2024 Ivan Goethals

This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
Expand All @@ -32,6 +32,7 @@ Licenses for embedded content

- This program uses the Pako.js entropy coding library. Pako is released under an MIT license by Andrey Tupitsin and Vitaly Puzrin. For more information on Pako and the full license text, please visit https://github.com/nodeca/pako
- Pako implements ZLib in javascript. Zlib is released under the ZLIB License. See https://www.zlib.net/zlib_license.html
- This program uses the jsPDF library to transform SVG images into PDF files. See license.html for the full jsPDF license text.

=== History ===

Expand Down
2 changes: 1 addition & 1 deletion builddate.js
Original file line number Diff line number Diff line change
@@ -1 +1 @@
var CONF_builddate="20241005-205608"
var CONF_builddate="20241006-230147"
25 changes: 20 additions & 5 deletions eendraadschema.js

Large diffs are not rendered by default.

2 changes: 2 additions & 0 deletions index.html
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@
<script src="prop/prop_scripts.js"></script>
<script src="builddate.js"></script>
<script src="pako/pako.min.js"></script>
<script src="jsPDF/jspdf.umd.min.js"></script>
<script src="jsPDF/print.js"></script>
<link rel="stylesheet" href="css/styles.css">
<title>Eendraadschema online tekenen</title>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8"/>
Expand Down
398 changes: 398 additions & 0 deletions jsPDF/jspdf.umd.min.js

Large diffs are not rendered by default.

1 change: 1 addition & 0 deletions jsPDF/jspdf.umd.min.js.map

Large diffs are not rendered by default.

195 changes: 195 additions & 0 deletions jsPDF/print.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,195 @@
function printPDF(svg, sizex, sizey, owner="", installer="", info="", DPI=300, page=1, maxpage=1, statuscallback) { // Defaults to A4 and 300 DPI but 600 DPI is better

paperdetails = { // All sizes in millimeters
paperwidth: 297,
paperheight: 210,

paper_margin: 10,
svg_padding: 5, //minimal size to keep below svg before the text boxes start

drawnby_box_height: 5,

owner_box_height: 30,
owner_box_width: 80
};

// ___ FUNCTION svgToPng ___
//
// Converts SVG with dimensions sizex and sizey to a PNG for use in the PDF document.
// Ensures the desired DPI is respected. Then calls function given by callback.

function svgToPng(svg, sizex, sizey, callback) {

let max_height_in_mm = paperdetails.paperheight - 2 * paperdetails.paper_margin - paperdetails.owner_box_height - paperdetails.drawnby_box_height - paperdetails.svg_padding;
let max_width_in_mm = paperdetails.paperwidth - 2 * paperdetails.paper_margin;

let max_height_in_pixels = max_height_in_mm/25.4*DPI;
let max_width_in_pixels = max_width_in_mm/25.4*DPI;

let scale = Math.min(max_height_in_pixels/sizey, max_width_in_pixels/sizex);

let scaledsvg = '<svg width="' + (sizex * scale) + '" height="' + (sizey * scale)
+ '" viewBox="0 0 ' + sizex + ' ' + sizey + '" xmlns="http://www.w3.org/2000/svg">'
+ svg + '</svg>';

const svgBlob = new Blob([scaledsvg], { type: 'image/svg+xml;charset=utf-8' });
const url = URL.createObjectURL(svgBlob);
const img = new Image();
img.onload = function() {
const canvas = document.createElement('canvas');
canvas.width = img.width;
canvas.height = img.height;
const ctx = canvas.getContext('2d');
ctx.drawImage(img, 0, 0);
const png = canvas.toDataURL('image/png');
callback(png,scale);
URL.revokeObjectURL(url);
};
img.src = url;
}

function htmlToPDFlines(doc,html) {

function htmlToUnicode(html) {
// Create a temporary element to hold the HTML
const tempElement = document.createElement('div');
tempElement.innerHTML = html;

// Replace <br> tags with \n
//tempElement.innerHTML = tempElement.innerHTML.replace(/<br>/g, "\n");

// Use the textContent property to get the Unicode string
const unicodeString = tempElement.textContent || tempElement.innerText || '';
return unicodeString;
}

let printlines = [];

lines = html.split(/<br>|<div><\/div>/);
lines = lines.map(htmlToUnicode);
for (let line of lines) {
let wrappedlines = doc.splitTextToSize(line, paperdetails.owner_box_width - 2 * 2 - 3);
printlines = printlines.concat(wrappedlines);
}

return printlines;
}

// ___ FUNCTION generatePDF ___
//
// Makes the actual PDF

function generatePDF(svg, sizex, sizey) {
const { jsPDF } = window.jspdf;
const doc = new jsPDF('landscape', 'mm', 'a4', true);

svgToPng(svg, sizex, sizey, function(png,scale) {

let canvasx = (paperdetails.paperwidth - 2*paperdetails.paper_margin);
let canvasy = (paperdetails.paperheight - 2*paperdetails.paper_margin - paperdetails.owner_box_height - paperdetails.drawnby_box_height - paperdetails.svg_padding);

if (sizex/sizey > canvasx/canvasy) { //width is leading
doc.addImage(png, 'PNG', paperdetails.paper_margin, paperdetails.paper_margin, canvasx, sizey/sizex * canvasx, undefined, 'FAST');
} else { //height is leading
doc.addImage(png, 'PNG', paperdetails.paper_margin, paperdetails.paper_margin, sizex/sizey * canvasy, canvasy, undefined, 'FAST');
}

// Set the properties to remove margins
doc.setProperties({
title: 'Eendraadschema',
subject: 'Eendraadschema',
author: 'eendraadschema.goethals-jacobs.be',
keywords: 'eendraadschema, online',
creator: 'eendraadschema.goethals-jacobs.be'
});

let pageHeight = 210;
let pageWidth = 297;
let margin = 10;

let largeRecWidth = 80;
let largeRecHeight = 30;

let drawnByHeight = 5;

doc.rect(paperdetails.paper_margin,
paperdetails.paperheight - paperdetails.paper_margin - paperdetails.drawnby_box_height,
3 * paperdetails.owner_box_width,
paperdetails.drawnby_box_height);
doc.rect(paperdetails.paper_margin,
paperdetails.paperheight - paperdetails.paper_margin - paperdetails.drawnby_box_height - paperdetails.owner_box_height,
paperdetails.owner_box_width,
paperdetails.owner_box_height);
doc.rect(paperdetails.paper_margin + paperdetails.owner_box_width,
paperdetails.paperheight - paperdetails.paper_margin - paperdetails.drawnby_box_height - paperdetails.owner_box_height,
paperdetails.owner_box_width,
paperdetails.owner_box_height);
doc.rect(paperdetails.paper_margin + 2 * paperdetails.owner_box_width,
paperdetails.paperheight - paperdetails.paper_margin - paperdetails.drawnby_box_height - paperdetails.owner_box_height,
paperdetails.owner_box_width,
paperdetails.owner_box_height);
doc.rect(paperdetails.paper_margin + 3 * paperdetails.owner_box_width,
paperdetails.paperheight - paperdetails.paper_margin - paperdetails.drawnby_box_height - paperdetails.owner_box_height,
paperdetails.paperwidth - 2 * paperdetails.paper_margin - 3 * paperdetails.owner_box_width,
paperdetails.drawnby_box_height + paperdetails.owner_box_height);

const fontSize = 8; // Set your font size
const textHeight = fontSize * 0.352778; // 1 point = 0.352778 mm

doc.setFont("helvetica", "bold");
doc.setFontSize(fontSize);

doc.text("Getekend met https://www.eendraadschema.goethals-jacobs.be",
paperdetails.paper_margin + 2, // Leave 2mm at the left of the drawn by text
paperdetails.paperheight - paperdetails.paper_margin - (paperdetails.drawnby_box_height-textHeight)/2 - textHeight/6);

doc.text('pagina. ' + page + '/' + maxpage,
paperdetails.paper_margin + 3 * paperdetails.owner_box_width + 2, //Leave 2mm at the left
paperdetails.paperheight - paperdetails.paper_margin - paperdetails.drawnby_box_height - paperdetails.owner_box_height - textHeight/6 + textHeight + 1.5 ); //Leave 1.55mm at the top

doc.text("Eendraadschema",
paperdetails.paper_margin + 3 * paperdetails.owner_box_width + 2,
paperdetails.paperheight - paperdetails.paper_margin - paperdetails.drawnby_box_height - paperdetails.owner_box_height - textHeight/6 + textHeight * (1 + 1.2) + 1.5);

doc.text(htmlToPDFlines(doc,"Erkend Organisme"),
paperdetails.paper_margin + 2,
paperdetails.paperheight - paperdetails.paper_margin - paperdetails.drawnby_box_height - paperdetails.owner_box_height - textHeight/6 + textHeight + 1.5);

doc.text(htmlToPDFlines(doc,"Plaats van de elektrische installatie"),
paperdetails.paper_margin + paperdetails.owner_box_width + 2,
paperdetails.paperheight - paperdetails.paper_margin - paperdetails.drawnby_box_height - paperdetails.owner_box_height - textHeight/6 + textHeight + 1.5);

doc.text(htmlToPDFlines(doc,"Installateur"),
paperdetails.paper_margin + (2*paperdetails.owner_box_width) + 2,
paperdetails.paperheight - paperdetails.paper_margin - paperdetails.drawnby_box_height - paperdetails.owner_box_height - textHeight/6 + textHeight + 1.5);

doc.setFont("helvetica", "normal");

doc.text(htmlToPDFlines(doc,owner).slice(0,8),
paperdetails.paper_margin + paperdetails.owner_box_width + 2 + 3,
paperdetails.paperheight - paperdetails.paper_margin - paperdetails.drawnby_box_height - paperdetails.owner_box_height - textHeight/6 + textHeight * (1+1.2) + 1.5);

doc.text(htmlToPDFlines(doc,installer).slice(0,8),
paperdetails.paper_margin + (2*paperdetails.owner_box_width) + 2 + 3,
paperdetails.paperheight - paperdetails.paper_margin - paperdetails.drawnby_box_height - paperdetails.owner_box_height - textHeight/6 + textHeight * (1+1.2) + 1.5);

let infoshorter = info.replace('https://www.eendraadschema.goethals-jacobs.be','eendraadschema');
doc.text(htmlToPDFlines(doc,infoshorter).slice(0,8),
paperdetails.paper_margin + (3*paperdetails.owner_box_width) + 2 + 3,
paperdetails.paperheight - paperdetails.paper_margin - paperdetails.drawnby_box_height - paperdetails.owner_box_height - textHeight/6 + textHeight * (1+3*1.2) + 1.5);


//--- functions that could be useful some day ---
//const textWidth = doc.getTextWidth("Page 1");
//doc.addPage();
//window.open(doc.output('bloburl'), '_blank');

doc.save("landscape_a4.pdf");
statuscallback.innerHTML = 'PDF is klaar. Kijk in uw Downloads folder indien deze niet spontaan wordt geopend.';
});
}

statuscallback.innerHTML = 'PDF wordt gegenereerd. Even geduld..';
generatePDF(svg, sizex, sizey);

}
28 changes: 27 additions & 1 deletion license.html
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
<body>
<h2>Eendraadschema tekenen</h2>
<a href="https://eendraadschema.goethals-jacobs.be/">https://eendraadschema.goethals-jacobs.be/</a>
<h3>Copyright (C) 2019-2023 Ivan Goethals GPLv3</h3>
<h3>Copyright (C) 2019-2024 Ivan Goethals GPLv3</h3>
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
Expand All @@ -22,5 +22,31 @@ <h3>Licenses for embedded content</h3>
For more information on Pako and the full license text, please visit <a href="https://github.com/nodeca/pako">https://github.com/nodeca/pako</a>
<br><br>
Pako implements ZLib in javascript. Zlib is released under the ZLIB License. See <a href="https://www.zlib.net/zlib_license.html">https://www.zlib.net/zlib_license.html</a>
<br><br>
This program uses the jsPDF library to transform SVG images into PDF files. The jsPDF license is as follows
<pre>
Copyright
(c) 2010-2021 James Hall, https://github.com/MrRio/jsPDF
(c) 2015-2021 yWorks GmbH, https://www.yworks.com/

Permission is hereby granted, free of charge, to any person obtaining
a copy of this software and associated documentation files (the
"Software"), to deal in the Software without restriction, including
without limitation the rights to use, copy, modify, merge, publish,
distribute, sublicense, and/or sell copies of the Software, and to
permit persons to whom the Software is furnished to do so, subject to
the following conditions:

The above copyright notice and this permission notice shall be
included in all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
</pre>
</body>
</html>
2 changes: 1 addition & 1 deletion src/Properties.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ class Properties {
this.filename = "eendraadschema.eds";
this.owner = "Voornaam Achternaam<br>Straat 0<br>0000 gemeente<br>Tel: +32 00 00 00 00<br>GSM: +32 000 00 00 00<br>e-mail: [email protected]";;
this.installer = "idem";
this.info = "<br>EAN ...<br><br>getekend met<br>https://www.eendraadschema.goethals-jacobs.be";
this.info = "1 x 230V + N ~50 Hz";
};

setFilename(name) {
Expand Down
4 changes: 2 additions & 2 deletions src/SVGSymbols.ts
Original file line number Diff line number Diff line change
Expand Up @@ -197,8 +197,8 @@ static outputSVGSymbols() {
<use xlink:href="#arrow" x="18" y="-17" transform="rotate(90 18 -17)" />
</g>
<g id="contactdoos">
<path d="M20 0 A15 15 0 0 1 35 -15" stroke="black" fill="white" stroke-width="2" />
<path d="M20 0 A15 15 0 0 0 35 15" stroke="black" fill="white" stroke-width="2" />
<path d="M20 0 A15 15 0 0 1 35 -15" stroke="black" fill="none" stroke-width="2" />
<path d="M20 0 A15 15 0 0 0 35 15" stroke="black" fill="none" stroke-width="2" />
<line x1="0" y1="0" x2="20" y2="0" stroke="black" />
</g>
<g id="stoomoven">
Expand Down
Loading

0 comments on commit 866b1e7

Please sign in to comment.