PDF pages in wrong order - jspdf

I have this
$('#create_pdf').on('click', function () {
$('body').scrollTop(0);
createPDF();
});
//create pdf
function createPDF() {
doc = new jsPDF({
unit: 'px',
format: 'a4'
});
const pdfWidth = doc.internal.pageSize.width - 20;
current_div = current_div1;
cache_width = current_div.width();
cache_width = current_div.width();
getCanvas(document.querySelector("#thediv1")).then(function (canvas) {
var img = canvas.toDataURL("image/png", wid = canvas.width, hgt = canvas.height) ;
var hratio = hgt/wid;
const TheHeight = doc.internal.pageSize.width;
const pdfHeight = TheHeight * hratio
doc.addImage(img, 'JPEG', 10, 10, pdfWidth, pdfHeight);
doc.addPage(595, 842);
});
current_div = current_div2;
cache_width = current_div.width();
getCanvas(document.querySelector("#thediv2")).then(function (canvas) {
var img = canvas.toDataURL("image/png", wid = canvas.width, hgt = canvas.height) ;
var hratio = hgt/wid;
const TheHeight = doc.internal.pageSize.width;
const pdfHeight = TheHeight * hratio
doc.addImage(img, 'JPEG', 10, 10, pdfWidth, pdfHeight);
doc.addPage(595, 842);
});
current_div = current_div3;
cache_width = current_div.width();
getCanvas(document.querySelector("#thediv3")).then(function (canvas) {
var img = canvas.toDataURL("image/png", wid = canvas.width, hgt = canvas.height) ;
var hratio = hgt/wid;
const TheHeight = doc.internal.pageSize.width;
const pdfHeight = TheHeight * hratio
doc.addImage(img, 'JPEG', 10, 10, pdfWidth, pdfHeight);
doc.addPage(595, 842);
});
etc etc
current_div = current_div14;
cache_width = current_div.width();
getCanvas(document.querySelector("#thediv14")).then(function (canvas) {
var img = canvas.toDataURL("image/png", wid = canvas.width, hgt = canvas.height) ;
var hratio = hgt/wid;
const TheHeight = doc.internal.pageSize.width;
const pdfHeight = TheHeight * hratio
doc.addImage(img, 'JPEG', 10, 10, pdfWidth, pdfHeight);
doc.addPage(595, 842);
doc.autoPrint();
window.open(doc.output('bloburl'));
});
}
// create canvas object
function getCanvas(Link) {
current_div.width((a4[0] * 1.33333) - 80).css('max-width', 'none');
return html2canvas(Link, {
imageTimeout: 2000,
removeContainer: true
});
}
I have two problems.
I am getting all the pages but not always in the right order. Why is that and what can I do about it?
Is there a way of stopping it from writing to the original page as the width is smaller than the original so it looks terrible. The original page needs to look the same as it did before clicking the print button
Thanks

I used Dompdf in the end. I was much easier

Related

html2canvas out of memory

Good day, colleagues. I have the problem, html2canvas when generating screenshots I give the error "out of memory" in google chrome.
window.jsPDF = window.jspdf.jsPDF;
let printArea = [...document.querySelectorAll('.print:not([style*="display: none;"])')]
var doc = new jsPDF('l', 'mm', "a4");
let tasks = printArea.map(tab => html2canvas(tab, {scale:2, removeContainer: true}))
Promise.all(tasks).then(canvases =>
{
var boolAdd = false
console.log(canvases)
for (const canvas of canvases)
{
if(true == boolAdd) {
doc.addPage();
}
let imgData = canvas.toDataURL('image/jpeg', 0.6);
const pageHeight = doc.internal.pageSize.getHeight();
const imgWidth = doc.internal.pageSize.getWidth();
var imgHeight = canvas.height * imgWidth / canvas.width;
var heightLeft = imgHeight - 20;
var position = 10;
doc.addImage(imgData, 'JPEG', 20, position, imgWidth - 40, imgHeight);
heightLeft -= pageHeight;
position += heightLeft - imgHeight; // top padding for other pages
doc.addImage(imgData, 'PNG', 0, position, imgWidth, imgHeight, undefined,'FAST');
heightLeft -= pageHeight;
boolAdd = true
}
console.log("report")
doc.save( 'report.pdf');
})
how to fix the error? Or how to free up memory? Alternatively, you can offer another library if you can't make it so that there are no memory problems.
Example
https://embed.plnkr.co/plunk/Zz4iFK
700 > mb
Good day, Comrads. I solved my problem. I replaced library html2canvas on htmlToImage witch method toCanvas. –

JSPDF leaves white background when margin added

I am using JsPDF to print dynamic resume data and i want to add margin when adding new page to pdf.
Now when resume having a background color and i add margin while generating pdf it leaves the margined area as white and rest is OK.
var data = document.getElementById('box');
html2canvas(data,{scale: 2}).then(canvas => {
var imgData = canvas.toDataURL('image/JPEG');
var imgWidth = 210;
var pageHeight = 295;
var imgHeight = canvas.height * imgWidth / canvas.width;
var heightLeft = imgHeight;
var doc = new jsPDF('p', 'mm', "a4");
var position = 1;
doc.addImage(imgData, 'JPEG', 0, position, imgWidth, imgHeight,'FAST');
heightLeft -= pageHeight;
while (heightLeft >= 0) {
position = heightLeft - imgHeight;
doc.addPage();
doc.addImage(imgData, 'JPEG', 0, position, imgWidth, imgHeight);
heightLeft -= pageHeight;
}
doc.save("Dashboard.pdf");
});
Use 'pt' instead of 'mm' as below, I hope it fixes,
var doc = new jsPDF('p', 'pt', "a4");

Html2Canvas doesn't works... the pdf shows empty

When I run the app and I click on the button, the PDF looks empty.
I was looking for by console.log() and the canvas doesn't show anything.
import { Component, OnInit } from '#angular/core';
import * as jspdf from 'jspdf';
import html2canvas from 'html2canvas';
generatePDF(){
html2canvas(document.getElementById('albaran')).then(canvas => {
// Few necessary setting options
var imgWidth = 208;
var pageHeight = 295;
var imgHeight = canvas.height * imgWidth / canvas.width;
var heightLeft = imgHeight;
const contentDataURL = canvas.toDataURL('image/png')
let pdf = new jspdf('p', 'mm', 'a4'); // A4 size page of PDF
var position = 0;
pdf.addImage(contentDataURL, 'PNG', 0, position, imgWidth, imgHeight)
pdf.save('MYPdf.pdf'); // Generated PDF
});
}
}
Finally, I have found a solution. I use jsPDF and dom-to-image libraries.
https://www.npmjs.com/package/jspdf
https://www.npmjs.com/package/dom-to-image
import * as jsPDF from 'jspdf';
import domtoimage from 'dom-to-image';
exportPdf(){
const div = document.getElementById('pdf');
const options = { background: 'white', height: 845, width: 595 };
domtoimage.toPng(div, options).then((dataUrl) => {
//Initialize JSPDF
const doc = new jsPDF('p', 'mm', 'a4');
//Add image Url to PDF
doc.addImage(dataUrl, 'PNG', 0, 0, 210, 340);
doc.save('pdfDocument.pdf');
}
}
Once you click on the button it will take time while loading an element from DOM so using setTimeout it will work.
import * as html2canvas from 'html2canvas';
import * as jspdf from 'jspdf';
generatePDF() {
setTimeout(() => {
const data = document.getElementById('printdiv');
html2canvas(data).then(canvas => {
// Few necessary setting options
const imgWidth = 208;
const pageHeight = 295;
const imgHeight = canvas.height * imgWidth / canvas.width;
let heightLeft = imgHeight;
const contentDataURL = canvas.toDataURL('image/png');
const pdf = new jspdf('p', 'mm', 'a4'); // A4 size page of PDF
let position = 0;
pdf.addImage(contentDataURL, 'PNG', 0, position, imgWidth, imgHeight);
heightLeft -= pageHeight;
// pdf.text(190, 294, '1');
let count = 1;
while (heightLeft >= 0) {
position = heightLeft - imgHeight;
pdf.addPage();
pdf.addImage(contentDataURL, 'PNG', 0, position, imgWidth, imgHeight);
// pdf.text(150, 10, 'this test meaasage');
count++;
// pdf.text(190, 294, count.toString());
heightLeft -= pageHeight;
}
const date = this.datePipe.transform(new Date(), 'dd/MM/yy');
const text = 'Created At :' + date;
pdf.setTextColor(163, 163, 163);
pdf.text(10, 290, text);
// pdf.text(190, 294, count.toString());
const currentuser = this.localstorgeservice.getCurrentUser();
const url = 'URL:' + this.document.location.href;
pdf.text(10, 280, url.toString());
pdf.text(150, 290, currentuser.userid);
pdf.save(this.bankingchannelname + '.pdf'); // Generated PDF
});
}, 700);
}
Here it is,
$(document).click(function () {
domtoimage.toPng(document.body)
.then(function (blob) {
var pdf = new jsPDF('p', 'mm', 'a4');
pdf.addImage(blob,'PNG', 0, 0, 210, 225);
pdf.save("test.pdf");
that.options.api.optionsChanged();
});
});

Center image doc.addImage jspdf

I am using html2canvas to take screenshot of my page and creating pdf of the images using jspdf. Now, my images are left aligned in the pdf document, I want it to be centered, how can I achieve it?
function pdfmaker() {
var element = $("#timesheet");
document.getElementById("message").style.display = "block";
document.getElementById("logo").style.display = "block";
var firstName = "<?php echo $fname?>";
var lastName = "<?php echo $lname ?>";
var startDate = "<?php echo $startDate?>";
var endDate = "<?php echo $endDate ?>";
html2canvas(element, {
useCORS: true,
onrendered: function(canvas) {
var imgData = canvas.toDataURL("image/png");
var imgWidth = 297; //297
var pageHeight = 297; //297
var imgHeight = canvas.height * imgWidth / canvas.width;
var heightLeft = imgHeight;
// var doc = new jsPDF('l', 'mm',[1350, 1350]);
var doc = new jsPDF('l', 'mm', [420, 297]); //420,297
var position = 5; //0
margins = {
top: 20,
bottom: 10,
left: 45,
width: 522
};
doc.addImage(imgData, 'PNG', 5, position, imgWidth, imgHeight);
heightLeft -= pageHeight;
while (heightLeft >= 5) {
position = heightLeft - imgHeight;
doc.addPage();
doc.addImage(imgData, 'PNG', 5, position, imgWidth, imgHeight);
heightLeft -= pageHeight;
}
doc.save(firstName + '_' + lastName + '_Summary_report_' + startDate + '_' + endDate + ".pdf");
}
});
document.getElementById("message").style.display = "none";
document.getElementById("logo").style.display = "none";
}
You need to define inside the addImage() method, using the coordinate parameters, see: http://raw.githack.com/MrRio/jsPDF/master/docs/module-addImage.html
This is the only way you can do it. For this, I suggest you use the following method doc.internal.pageSize.getWidth(); to calculate the excess values ​​about the image width, which will be centered.

Having trouble rendering a sphere in WebGL

I'm learning WebGL and am trying to display a sphere. No textures, just each vertex coloured, but I'm getting the following error message in Opera and Chrome:
"[.WebGLRenderingContext]GL ERROR :GL_INVALID_OPERATION : glDrawElements: attempt to access out of range vertices in attribute 1 "
I don't understand what I'm doing wrong because the code looks fine to me, but I'm obviously missing something.
Thanks!
Michael
(It is adapted from lessons 4 and 11 from http://learningwebgl.com.)
var gl;
function initGL(canvas) {
try {
gl = canvas.getContext("experimental-webgl");
gl.viewportWidth = canvas.width;
gl.viewportHeight = canvas.height;
} catch (e) {
}
if (!gl) {
alert("Could not initialise WebGL, sorry :-(");
}
}
function getShader(gl, id) {
var shaderScript = document.getElementById(id);
if (!shaderScript) {
return null;
}
var str = "";
var k = shaderScript.firstChild;
while (k) {
if (k.nodeType == 3) {
str += k.textContent;
}
k = k.nextSibling;
}
var shader;
if (shaderScript.type == "x-shader/x-fragment") {
shader = gl.createShader(gl.FRAGMENT_SHADER);
} else if (shaderScript.type == "x-shader/x-vertex") {
shader = gl.createShader(gl.VERTEX_SHADER);
} else {
return null;
}
gl.shaderSource(shader, str);
gl.compileShader(shader);
if (!gl.getShaderParameter(shader, gl.COMPILE_STATUS)) {
alert(gl.getShaderInfoLog(shader));
return null;
}
return shader;
}
var shaderProgram;
function initShaders() {
var fragmentShader = getShader(gl, "shader-fs");
var vertexShader = getShader(gl, "shader-vs");
shaderProgram = gl.createProgram();
gl.attachShader(shaderProgram, vertexShader);
gl.attachShader(shaderProgram, fragmentShader);
gl.linkProgram(shaderProgram);
if (!gl.getProgramParameter(shaderProgram, gl.LINK_STATUS)) {
alert("Could not initialise shaders");
}
gl.useProgram(shaderProgram);
shaderProgram.vertexPositionAttribute = gl.getAttribLocation(shaderProgram, "aVertexPosition");
gl.enableVertexAttribArray(shaderProgram.vertexPositionAttribute);
shaderProgram.vertexColorAttribute = gl.getAttribLocation(shaderProgram, "aVertexColor");
gl.enableVertexAttribArray(shaderProgram.vertexColorAttribute);
shaderProgram.pMatrixUniform = gl.getUniformLocation(shaderProgram, "uPMatrix");
shaderProgram.mvMatrixUniform = gl.getUniformLocation(shaderProgram, "uMVMatrix");
}
var mvMatrix = mat4.create();
var mvMatrixStack = [];
var pMatrix = mat4.create();
function mvPushMatrix() {
var copy = mat4.create();
mat4.copy(copy, mvMatrix);
mvMatrixStack.push(copy);
}
function mvPopMatrix() {
if (mvMatrixStack.length == 0) {
throw "Invalid popMatrix!";
}
mvMatrix = mvMatrixStack.pop();
}
function setMatrixUniforms() {
gl.uniformMatrix4fv(shaderProgram.pMatrixUniform, false, pMatrix);
gl.uniformMatrix4fv(shaderProgram.mvMatrixUniform, false, mvMatrix);
}
function degToRad(degrees) {
return degrees * Math.PI / 180;
}
var sphereVertexPositionBuffer;
var sphereVertexColorBuffer;
var sphereVertexIndexBuffer;
function initBuffers() {
var latitudeBands = 10;
var longitudeBands = 10;
var radius = 2;
sphereVertexPositionBuffer = gl.createBuffer();
gl.bindBuffer(gl.ARRAY_BUFFER, sphereVertexPositionBuffer);
sphereVertexColorBuffer = gl.createBuffer();
gl.bindBuffer(gl.ARRAY_BUFFER, sphereVertexColorBuffer);
sphereVertexIndexBuffer = gl.createBuffer();
gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, sphereVertexIndexBuffer);
var vertexPositionData = [];
var colors = [];
var indexData = [];
for (var latNumber=0; latNumber <= latitudeBands; latNumber++) {
var theta = latNumber * Math.PI / latitudeBands;
var sinTheta = Math.sin(theta);
var cosTheta = Math.cos(theta);
for (var longNumber=0; longNumber <= longitudeBands; longNumber++) {
var phi = longNumber * 2 * Math.PI / longitudeBands;
var sinPhi = Math.sin(phi);
var cosPhi = Math.cos(phi);
var x = cosPhi * sinTheta;
var y = cosTheta;
var z = sinPhi * sinTheta;
colors = [[1.0, 1.0, 0.3, 1.0]];
vertexPositionData.push(radius * x);
vertexPositionData.push(radius * y);
vertexPositionData.push(radius * z);
var first = (latNumber * (longitudeBands + 1)) + longNumber;
var second = first + longitudeBands + 1;
indexData.push(first);
indexData.push(second);
indexData.push(first + 1);
indexData.push(second);
indexData.push(second + 1);
indexData.push(first + 1);
}
}
var unpackedColors = [];
for (var i in colors) {
var color = colors[i];
for (var j=0; j < 4; j++) {
unpackedColors = unpackedColors.concat(color);
}
}
gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(vertexPositionData), gl.STATIC_DRAW);
sphereVertexPositionBuffer.itemSize = 3;
sphereVertexPositionBuffer.numItems = vertexPositionData.length / 3;
gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(unpackedColors), gl.STATIC_DRAW);
sphereVertexColorBuffer.itemSize = 4;
sphereVertexColorBuffer.numItems = unpackedColors.length / 4;
gl.bufferData(gl.ELEMENT_ARRAY_BUFFER, new Uint16Array(indexData), gl.STATIC_DRAW);
sphereVertexIndexBuffer.itemSize = 1;
sphereVertexIndexBuffer.numItems = indexData.length;
}
var rSphere = 0;
function drawScene() {
gl.viewport(0, 0, gl.viewportWidth, gl.viewportHeight);
gl.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT);
mat4.perspective(pMatrix, 60, gl.viewportWidth / gl.viewportHeight, 0.1, 100.0);
mat4.identity(mvMatrix);
mat4.translate(mvMatrix, mvMatrix, [0.0, 0.0, -5.0]);
mvPushMatrix();
mat4.rotate(mvMatrix, mvMatrix, degToRad(rSphere), [1, 1, 1]);
gl.bindBuffer(gl.ARRAY_BUFFER, sphereVertexPositionBuffer);
gl.vertexAttribPointer(shaderProgram.vertexPositionAttribute, sphereVertexPositionBuffer.itemSize, gl.FLOAT, false, 0, 0);
gl.bindBuffer(gl.ARRAY_BUFFER, sphereVertexColorBuffer);
gl.vertexAttribPointer(shaderProgram.vertexColorAttribute, sphereVertexColorBuffer.itemSize, gl.FLOAT, false, 0, 0);
gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, sphereVertexIndexBuffer);
setMatrixUniforms();
gl.drawElements(gl.TRIANGLES, sphereVertexIndexBuffer.numItems, gl.UNSIGNED_SHORT, 0);
mvPopMatrix();
}
var lastTime = 0;
function animate() {
var timeNow = new Date().getTime();
if (lastTime != 0) {
var elapsed = timeNow - lastTime;
rSphere -= (75 * elapsed) / 1000.0;
}
lastTime = timeNow;
}
function tick() {
requestAnimFrame(tick);
drawScene();
animate();
}
function webGLStart() {
var canvas = document.getElementById("lesson04-canvas");
initGL(canvas);
initShaders()
initBuffers();
gl.clearColor(0.0, 0.0, 0.1, 1.0);
gl.enable(gl.DEPTH_TEST);
tick();
}
I found the problem!
I included the index creation in the loops (less than or equal to):
for (var latNumber=0; latNumber <= latitudeBands; latNumber++)
for (var longNumber=0; longNumber <= longitudeBands; longNumber++)
Instead of its own loops (less than):
for (var latNumber=0; latNumber < latitudeBands; latNumber++)
for (var longNumber=0; longNumber < longitudeBands; longNumber++)

Resources