问题
I am creating an image with html2canvas and with jsPDF with Angular4. I want to place this image on page 1 of a 2 page generated pdf.
But it seems that the line,
doc.save('test.pdf');
needs to be inside the function just after htm2canvas()
. Because if I place it outside this it will not include the image in the pdf.
generatePDF(){
var doc = new jsPDF();
doc.text(50,90,this.problems.length.toString());
doc.text(50,100,'page 1')
doc.addPage();
doc.text(50,100,'page 2')
html2canvas(document.getElementById('graph')).then(function(canvas) {
var img = canvas.toDataURL("image/png");
doc.addImage(img, 'JPEG', 100, 100);
doc.save('test.pdf');
});
// doc.save('test.pdf');//fails to add image to pdf
}
I can't place the addPage()
after the html2canvas()
, because when html2canvas
is called that generates the pdf and nothing after it will be included.
Seems the only way is to put the jsPDF
inside the html2canvas()
like this,
generatePDF(){
html2canvas(document.getElementById('graph')).then(function(canvas) {
var doc = new jsPDF();
doc.text(50,100,'page 1')
var img = canvas.toDataURL("image/png");
doc.addImage(img, 'JPEG', 100, 100);
doc.addPage();
doc.text(50,100,'page 2')
doc.save('test.pdf');
});
This does work.
But then the problem is that I can't use a variable from outside, when inside html2canvas()
, like this.
generatePDF(){
console.log("outside: this.problem.length = " + this.problems.length);// works
html2canvas(document.getElementById('graph')).then(function(canvas) {
console.log("inside: this.problem.length = " + this.problems.length);// not working!!!
var doc = new jsPDF();
doc.text(50,100,'page 1');
var img = canvas.toDataURL("image/png");
doc.addImage(img, 'JPEG', 100, 100);
doc.addPage();
doc.text(50,100,'page 2')
doc.save('test.pdf');
});
// doc.save('test.pdf');//fails to add image to pdf
}
package.json has the types for html2canvas and jspdf:
...
"@types/html2canvas": "^0.5.35",
"@types/jspdf": "^1.1.31",
"@types/lodash": "^4.14.74",
"html2canvas": "^0.5.0-beta4",
"jspdf": "^1.3.5",
...
The full code is here on github, with the relevant code commented out at the bottom of app.component.ts
on line 428.
Possible solution here.
回答1:
Of course you can access that variable. The problem is that each function
creates its own scope and defines this
as a link to its own context, so the html2canvas then-callback's this
is not the same as generatePDF function's this
. This is a part of basic paradigm of javascript as a functional language.
The simplest solution is to save the context in a local variable:
generatePDF() {
var self = this;
console.log("outside: self.problem.length = " + self.problems.length);
html2canvas(document.getElementById('graph')).then(function(canvas) {
console.log("inside: self.problem.length = " + self.problems.length);
// ...
});
// ...
}
Another option is to use ES arrow function (in case of ES6 is appropriate for your project; and I guess it's so due to Angular 4) because the arrow function saves the parent context:
generatePDF(){
console.log("outside: this.problem.length = " + this.problems.length);
html2canvas(document.getElementById('graph')).then((canvas) => {
console.log("inside: this.problem.length = " + this.problems.length);
// ...
});
// ...
}
Not sure if it's all the story, but hope this helps!
回答2:
This function is asynchronous:
html2canvas(document.getElementById('graph'))
You can have access to the generated image only inside the callback function. If are going to use html2canvas to generate images, then all your pdf-related code must be inside the callback. It's really what you already did. If you're going to need another images in pdf, you'll have more nested callbacks and this line doc.save('test.pdf');
must be inside the last one.
来源:https://stackoverflow.com/questions/46286820/getting-image-on-page-1-of-2-page-pdf