Я не могу получить изображения для рендеринга в jsPDF с помощью NativeScript

#javascript #ios #nativescript #jspdf #nativescript-vue

#javascript #iOS #nativescript #jspdf #nativescript-vue

Вопрос:

Краткие сведения:

Игровая площадка: https://play.nativescript.org/?template=play-vueamp;id=pntfZDamp;v=4

Я использую NativeScript (VueJS) со следующими плагинами:

  1. nativescript-share-file
  2. jsPDF
  3. база-64

Я создаю PDF-файл при нажатии кнопки, и все в порядке, пока я не попытаюсь добавить изображение. Смотрите Здесь пример того, насколько просто это должно быть.

Если я беру свой пример изображения, который представляет собой просто черный квадрат, и base64encode использую этот отличный ресурс, и отправляю вывод по вышеупомянутой ссылке здесь, он работает нормально.

Прежде чем я перейду к своему коду, я также хочу добавить, что я console.log(...) — это моя закодированная строка, и вставить ее на вышеупомянутый сайт, и она отлично работает.

Однако я что-то упускаю, потому что изображение просто не отображается.

Вот что заставило меня начать это приключение: https://medium.com/@kumarandena/pdf-generation-in-nativescript-using-javascript-libraries-864ecf4e9a3a

Я также собираюсь включить некоторые комментарии в свой код, которые представляют собой рекомендации и дополнительные вопросы.

Вот содержание моего метода, комментарии и вопросы включены:

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

И, наконец, результат моего теста открылся после отправки его на мой MAC с телефона: PDF

Комментарии:

1. Можете ли вы поделиться примером игровой площадки, где проблема может быть воспроизведена?

2. @Manoj: play.nativescript.org/?template=play-vueamp;id=pntfZDamp;v=4

Ответ №1:

Вы записываете файл в виде обычного текста, предполагается, что вы записываете его в виде двоичных данных, как в сообщении в блоге. Использование собственного метода декодирования и запись файла в двоичный файл с writeSync помощью метода показывает изображение, как и ожидалось.

Обновленная игровая площадка

Для iOS вы должны использовать

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

это эквивалент Android

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

Комментарии:

1. Спасибо! Я знаю, что я пробовал NSData, как упоминалось в моем вопросе. Должно быть, во время попытки у меня было что-то еще не так. Ваш пример работает. Спасибо!