user1447679
user1447679

Reputation: 3270

I can't get images to render within jsPDF using NativeScript

Summary:

Playground: https://play.nativescript.org/?template=play-vue&id=pntfZD&v=4

I'm using NativeScript (VueJS) with the following plugins:

  1. nativescript-share-file
  2. jsPDF
  3. base-64

I'm generating a PDF on button click, and all is fine until I attempt to add an image. See here for an example of how easy this is supposed to be.

If I take my example image, which is just a black square and base64encode it using this great resource and drop the output into aforementioned link here it works fine.

Before I get to my code I also want to add that I'm console.log(...) my encoded string and paste that into the aforementioned site and it works fine.

However, I'm missing something, because the image simply isn't showing up.

Here's what got me started in this adventure: https://medium.com/@kumarandena/pdf-generation-in-nativescript-using-javascript-libraries-864ecf4e9a3a

I'm also going to include some comments in my code which represent guidance and further questions.

Here's the content of my method, comments and questions included:

const image = new imageSourceModule.ImageSource();
image.fromFile("~/images/test.jpg").then(function(src) {
// The "reallylong==" base64 value below is what I validated as working
// on that demo site and even hard coded it to be sure

var imgData = "data:image/jpeg;base64,/reallylong==";
var doc = new jsPDF();
doc.setFontSize(40);
doc.text(35, 25, "Hello, world!");

// Here is my function that I hope to ultimately work
//doc.addImage("data:image/jpeg;base64," + image.toBase64String("jpg"), 'JPEG', 15, 40, 500, 500);                      

// Here is the hard coded one from above
doc.addImage(imgData, "JPEG", 15, 40, 180, 160);

// This gets me the raw data that I'm going to save to file
var datauristring = doc.output("datauristring").split(",")[1];

const documents = fs.knownFolders.documents();
const folder = documents.getFolder("testFolder");
const file = folder.getFile("testFile.pdf");
const data = base64.decode(datauristring);

// For this data, I have tried various methods of encoding, decoding
// using NSString, NSFile I think. I'm posting my question with the code in its current state.

file.writeText(data)
  .then(result => {
    console.log("result", result);
    // result is always undefined but the PDF does save with text

    // I'm not sure why this is needed, but it fails otherwise.
    // More specifically, the share file dialogue opens but fails if I for example try to save the file somewhere. App doesn't crash, but iOS rejects it
    // I would expect the promise to resolve and a timeout not needed
    setTimeout(function() {
        var shareFile = new ShareFile();
            shareFile.open({
                path: fs.path.join(documents.path + "/testFolder", "testFile.pdf"),
                intentTitle: "Open text file with:",
                rect: {
                    x: 110,
                    y: 110,
                    width: 0,
                    height: 0
                },
                options: false,
                animated: true
            });
        }, 2000);
    }).catch(err => {
         // This is never reached
         console.log(err);
    });
});

And finally, the output of my test opened after sending it to my MAC from phone: pdf

Upvotes: 0

Views: 519

Answers (1)

Manoj
Manoj

Reputation: 21908

You are writing the file as plain text, you are suppose to write it as binary data as in the blog post. Using the native decode method and writing the file as binary with writeSync method shows the image as expected.

Updated Playground

For iOS, you should use

let data = NSData.alloc().initWithBase64EncodedStringOptions(datauristring, 0);

it's the Android equivalent of

let data = android.util.Base64.decode(datauristring, android.util.Base64.DEFAULT);

Upvotes: 2

Related Questions