jsPDF Corrupt PDFs?

11,925

Solution 1

I 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);

Solution 2

I used the 1.3.4 version of jsPDF and it worked

<script src="https://cdnjs.cloudflare.com/ajax/libs/jspdf/1.3.4/jspdf.min.js"></script>

Solution 3

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);
Share:
11,925
0xhughes
Author by

0xhughes

Drowning in technology!

Updated on June 04, 2022

Comments

  • 0xhughes
    0xhughes almost 2 years

    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>
    
  • 0xhughes
    0xhughes about 11 years
    Very concise, I will give this a test when I have some time after work! One question though, at the beginning you grab content from a canvas, in my scenario the pictures load are from the local machine. (A script generates the webpage and the image data for it). If I already have the DataURL defined in a span, could I simply go " var content = getElementByID("SPANID").innerHtml " ? The inner html is the toDataURL ASCII generated by the script. Thanks for the great answer, I will definitely look into your method and see how it pans out!
  • Jefferson
    Jefferson about 11 years
    I was testing your solution, but I get a pdf like name.pdf-1.part is there a way I can just get name.pdf?
  • 0xhughes
    0xhughes about 11 years
    I haven't found a way to get rid of the .part extension. I think my version of FireFox (12) just wasn't at all compatible with jsPDF. I upgraded my FireFox to version 18.0.2 and my original script worked, it still had that .part extension though. I am not sure why it does that. Must be something on the library side. It is unfortunate because i'd like to be able to offer some cross-browser compatibility for my webpage. I might have to setup my clients to use the latest FireFox I guess. There has been alit of issues submitted on the jsPDF github. Perhaps we will get a nice update!
  • 0xhughes
    0xhughes about 11 years
    @Jeff Also, I wanted to add a little bit of general purpose info. If you are looking to generate a PDF file, there was a website I read where someone manually built a PDF file with just his text editor. I haven't tried it yet, but it may be very possible to create your own little function to create some PDFs on the client side, depending on how adventurous you are and how dynamic your PDFs would be. mariomalwareanalysis.blogspot.com/2012/02/… I haven't tested his method but it might be a start if you want to get adventurous ;)
  • mtasic85
    mtasic85 about 11 years
    That .part extensions is really funky :) Do you use any extension/addon for download in FF? Can you test it in Chrome? What OS are you using?
  • Jefferson
    Jefferson about 11 years
    @mtasic85 No I don't use any extension for download, use the usal way, I use Linux.