I am trying to create a PDF file with JavaScript using jsPDF. I have a little test page. Basically I have a download PDF button that takes the base64 image from a span and uses that for the imgData
. I then try to addImage
that image data to the pdf and then save it. Everything seems to work, it generates the PDF and prompts for download. However when I try to look at the PDF with xpdf or Foxit reader I am told the PDF is corrupted. Am I creating this PDF incorrectly? My web page is pretty long, so I put it on Pastebin.
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
<script type="text/javascript" src="js/jquery/jquery-1.7.1.min.js"></script>
<script type="text/javascript" src="js/jquery/jquery-ui-1.8.17.custom.min.js"></script>
<script type="text/javascript" src="../jspdf.js"></script>
<script type="text/javascript" src="../libs/FileSaver.js/FileSaver.js"></script>
<script type="text/javascript" src="../libs/BlobBuilder.js/BlobBuilder.js"></script>
<script type="text/javascript" src="../jspdf.plugin.addimage.js"></script>
<script type="text/javascript" src="../jspdf.plugin.standard_fonts_metrics.js"></script>
<script type="text/javascript" src="../jspdf.plugin.split_text_to_size.js"></script>
<script type="text/javascript" src="../jspdf.plugin.from_html.js"></script>
<script type="text/javascript" src="js/basic.js"></script>
<title>Sup!</title>
<script>
function changeCan() {
var c = document.getElementById("myCanvas");
var ctx = c.getContext("2d");
ctx.fillStyle="#FF0000";
ctx.fillRect(0,0,128,128);
}
function changeCan3() {
var c = document.getElementById("myCanvas");
var ctx = c.getContext("2d");
ctx.fillStyle="#FFFFFF";
ctx.fillRect(0,0,128,128);
var image = new Image();
image.src = document.getElementById("3span").innerHTML;
ctx.drawImage(image,0,0);
}
function changeCan4() {
var imgData = document.getElementById("3span").innerHTML;
window.alert(imgData.length);
var doc = new jsPDF();
doc.addImage(imgData, 'JPEG', 15, 40, 128, 128);
doc.save('Test.pdf');
}
</script>
</head>
<body>
Yo!<hr>
<canvas id="myCanvas" width="128" height="128"></canvas><hr>
<button type="button" onClick="changeCan()">Change Me To Red!</button>
<button type="button" onClick="changeCan3()">Change Me To Span!</button>
<button type="button" onClick="changeCan4()">Download Me!</button>
<hr>
<span id="3span" style="display:none;">B64 DATA HERE</span>
</body>
</html>
I am trying to create a PDF file with JavaScript using jsPDF. I have a little test page. Basically I have a download PDF button that takes the base64 image from a span and uses that for the imgData
. I then try to addImage
that image data to the pdf and then save it. Everything seems to work, it generates the PDF and prompts for download. However when I try to look at the PDF with xpdf or Foxit reader I am told the PDF is corrupted. Am I creating this PDF incorrectly? My web page is pretty long, so I put it on Pastebin.
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
<script type="text/javascript" src="js/jquery/jquery-1.7.1.min.js"></script>
<script type="text/javascript" src="js/jquery/jquery-ui-1.8.17.custom.min.js"></script>
<script type="text/javascript" src="../jspdf.js"></script>
<script type="text/javascript" src="../libs/FileSaver.js/FileSaver.js"></script>
<script type="text/javascript" src="../libs/BlobBuilder.js/BlobBuilder.js"></script>
<script type="text/javascript" src="../jspdf.plugin.addimage.js"></script>
<script type="text/javascript" src="../jspdf.plugin.standard_fonts_metrics.js"></script>
<script type="text/javascript" src="../jspdf.plugin.split_text_to_size.js"></script>
<script type="text/javascript" src="../jspdf.plugin.from_html.js"></script>
<script type="text/javascript" src="js/basic.js"></script>
<title>Sup!</title>
<script>
function changeCan() {
var c = document.getElementById("myCanvas");
var ctx = c.getContext("2d");
ctx.fillStyle="#FF0000";
ctx.fillRect(0,0,128,128);
}
function changeCan3() {
var c = document.getElementById("myCanvas");
var ctx = c.getContext("2d");
ctx.fillStyle="#FFFFFF";
ctx.fillRect(0,0,128,128);
var image = new Image();
image.src = document.getElementById("3span").innerHTML;
ctx.drawImage(image,0,0);
}
function changeCan4() {
var imgData = document.getElementById("3span").innerHTML;
window.alert(imgData.length);
var doc = new jsPDF();
doc.addImage(imgData, 'JPEG', 15, 40, 128, 128);
doc.save('Test.pdf');
}
</script>
</head>
<body>
Yo!<hr>
<canvas id="myCanvas" width="128" height="128"></canvas><hr>
<button type="button" onClick="changeCan()">Change Me To Red!</button>
<button type="button" onClick="changeCan3()">Change Me To Span!</button>
<button type="button" onClick="changeCan4()">Download Me!</button>
<hr>
<span id="3span" style="display:none;">B64 DATA HERE</span>
</body>
</html>
Share
Improve this question
edited Jan 21, 2013 at 3:07
lmcanavals
2,3861 gold badge24 silver badges35 bronze badges
asked Jan 21, 2013 at 2:58
0xhughes0xhughes
2,7534 gold badges27 silver badges38 bronze badges
6
-
In your
3span
DIV, the innerHTML containsdata:image/jpeg;base64,
. Is it required/necessary? Just a thought, I don't know this jsPDF lib, but I am interested, I will need this pretty soon :) – JScoobyCed Commented Jan 21, 2013 at 3:06 -
Well the
data:image/jpeg;base64,
portion seems nessecary for a different part of the test page I was fooling around with, that was changing the canvas to the laughing man graphic. Also on the jsPDF web page, jspdf. , the example with the cat image shows thedata:image/jpeg;base64,
"header" if you will. @JScoobyCed So i'm not totally certain if it's needed or not, I can try to remove it quick and generate another PDF! – 0xhughes Commented Jan 21, 2013 at 3:08 -
@JScoobyCed I quick removed that chunk of info from the base64 data and both the canvas and PDF errored out. I'm not too worried about the canvas, that's just for chuckles. The PDF though did not work, here's the error FireBug spit,
getJpegSize could not find the size of the image [Break On This Error] throw new Error('getJpegSize could not find the size of the image');
I looked at the code in the .js file from his library and I can't really tell exactly what it's doing. Grabbing certain chars, getting lengths and doing some math with that info. – 0xhughes Commented Jan 21, 2013 at 3:11 -
I tried your code and all it generates in the PDF is this text:
[object Uint8Array]
. So I guess it's not corrupted but something not generated fully. Can't help more than that I need to read about jsPDF first and can't do that now. Good luck. – JScoobyCed Commented Jan 21, 2013 at 3:33 - Hey thanks for the try! That was probably the alert, use it a bit for debugging :) Good luck to you in the future as well. – 0xhughes Commented Jan 21, 2013 at 3:36
3 Answers
Reset to default 6I had similar problem, and this is how is solved it. I used Blob.js, canvas-toBlob, FileSaver. I also noticed that latest BlobBuilder.min.js is not working correcly, so I used BlobBuilder.js instead.
var content = canvas.toDataURL('image/jpeg');
var doc = new jsPDF('landscape');
doc.addImage(content, 'JPEG', 0, 0);
var data = doc.output();
var buffer = new ArrayBuffer(data.length);
var array = new Uint8Array(buffer);
for (var i = 0; i < data.length; i++) {
array[i] = data.charCodeAt(i);
}
var blob = new Blob(
[array],
{type: 'application/pdf', encoding: 'raw'}
);
saveAs(blob, filename);
I used the 1.3.4 version of jsPDF and it worked
<script src="https://cdnjs.cloudflare./ajax/libs/jspdf/1.3.4/jspdf.min.js"></script>
I had a similar problem using png image type : PDF was corrupted when opened with Adobe Reader.
Changing it to jpeg resolved it !
// Before : Corrupted PDF file when opened with Adobe Reader
var imgData = canvas.toDataURL('image/png');
var doc = new jsPDF('p', 'mm');
doc.addImage(imgData, 'png', 0, 0, 210, 295);
// After : Working
var imgData = canvas.toDataURL('image/jpeg');
var doc = new jsPDF('p', 'mm');
doc.addImage(imgData, 'jpeg', 0, 0, 210, 295);