如何使用jsPDF将多个图像添加到PDF [英] How to add several images onto a PDF using jsPDF

查看:438
本文介绍了如何使用jsPDF将多个图像添加到PDF的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

参数链接"是图像链接的数组.

function genPDF_fromUrl(link) {
    var doc = new jsPDF();
    doc.setFontSize(40);
    doc.text(80, 25, 'MAP001');

    const rtnimg = compute(doc, link);
    console.log(rtnimg)
    Promise.all(rtnimg).then((success) => {
        doc.save("map.pdf");
    });
    console.log("Finish hello PDF!")
}
function compute(doc, link) {       
    return link.map(l => {
        let x = 0;
        let y = 0;
        x += 10;
        y += 10;
        return new Promise((resolve, reject) => {
            var genImg = new Image();
            genImg.setAttribute('crossOrigin', 'anonymous');
            genImg.src = l;
            console.log("genimg: ", genImg);

            genImg.onload = function () {   
            console.log("doc: ", doc);  
                doc.addImage(genImg, 'PNG',  x, y, 100, 100);    
            }
            resolve();
        });
    });
}

结果始终是仅带有文本"MAP001"的PDF,我不确定为什么不会显示该图像.

下面是控制台输出:

genImg:  is a img tag like < img crossorigin=​"anonymous" src=​"https:​/​/​cors.now.sh ... a link" >

rtnimg : (33) [Promise, Promise, Promise, Promise, Promise, Promise, Promise, Promise, Promise, Promise, Promise, Promise, Promise, Promise, Promise, Promise, Promise, Promise, Promise, Promise, Promise, Promise, Promise, Promise, Promise, Promise, Promise, Promise, Promise, Promise, Promise, Promise, Promise]

Finish hello PDF!

doc:  {internal: {…}, addPage: ƒ, setPage: ƒ, insertPage: ƒ, movePage: ƒ, …}

以下是我成功的尝试仅在PDF上打印图像的尝试.

function genPDF_fromUrl(link) {
        var genImg = new Image();
        genImg.setAttribute('crossOrigin', 'anonymous');
        genImg.src = link[0];

        genImg.onload = function () {    
        var doc = new jsPDF();
        doc.setFontSize(40);
        doc.text(80, 25, 'MAP001');
        doc.addImage(genImg, 'PNG',  0, 0, 100, 100);         
        doc.save("map.pdf"); 
        }      
}

似乎是"var doc = new jsPDF();"必须在onload函数中,但是我不能对多个图像执行该操作.

解决方案

您正在开始创建PDF,然后等待每个图像.我的建议不是使用这种方法,而是预加载所有图像,并在所有图像下载完毕并准备通过调用addImage函数在jsPDF中打印后等待回调.

前一段时间,我作为一个更复杂的jsPDF插件的一部分按照以下方式进行操作

function Picture(src) {
    this.src = src;
    this.img = null;
}

function Preloader() {
    this.pictures = [];
    this.onpicturesloaded = null;
}

Preloader.prototype.setPicture = function(src) {
    var id = src.split("/").pop().split(".")[0].toLowerCase();
    this.pictures[id] = new Picture(src);
    return this.pictures[id];
};

Preloader.prototype.loadPictures = function() {
    var self = this, pictures = self.pictures, n = 0;
    for(var id in pictures) {
        if(pictures.hasOwnProperty(id)) {
            var pic = self.pictures[id];
            n++;
        }
    }
    for(var id in pictures) {
        if(pictures.hasOwnProperty(id)) {
            var pic = self.pictures[id];
            var decrease = function(e) {
                if(--n == 0) {
                    self.onpicturesloaded();
                }
            }
            var img = new Image();
            img.onload = function() {
                var pic = self.pictures[this.alt];
                pic.img = this;
                decrease();
            };
            img.alt = id;
            img.src = pic.src;
        }
    }
};

我正在使用剥离的文件名作为ìd来直接获取关联的图像,因此,如果找到的话,loadPictures函数内部的double循环会有一些开销.太糟糕了,请随时将其更改为一个真实的数组,您可以在其中直接将图片计数记为pictures.length.

然后,此id在jsPDF中也用作每个图像的alias,以加快整个过程,从而将完整的图像路径存储在picture.src中.

(上面的所有东西的用法是这样(更多)):

var pl = new Preloader();
pl.setPicture("pdf/a.jpg");
pl.setPicture("pdf/b.jpg");
pl.setPicture("pdf/c.jpg");

pl.onpicturesloaded = function() {
    var doc = new jsPDF();
    var pic = pl.pictures["a"];
    doc.addImage(pic.img, "jpg", 10, 10, 100, 100, pic.img.alt, "FAST");
    // add more images, print text, and so on
    doc.save('mydocument.pdf');
};  
pl.loadPictures();

请注意,这只是jsPDF插件的即时摘录,没有我需要的某些部分,例如,可以在canvas内绘制并将图片数据即时添加到PDF. /p>

因此,我相信可以进一步简化并简化它,但是无论如何,您都可以理解.

Argument 'link' is an array of images' links.

function genPDF_fromUrl(link) {
    var doc = new jsPDF();
    doc.setFontSize(40);
    doc.text(80, 25, 'MAP001');

    const rtnimg = compute(doc, link);
    console.log(rtnimg)
    Promise.all(rtnimg).then((success) => {
        doc.save("map.pdf");
    });
    console.log("Finish hello PDF!")
}
function compute(doc, link) {       
    return link.map(l => {
        let x = 0;
        let y = 0;
        x += 10;
        y += 10;
        return new Promise((resolve, reject) => {
            var genImg = new Image();
            genImg.setAttribute('crossOrigin', 'anonymous');
            genImg.src = l;
            console.log("genimg: ", genImg);

            genImg.onload = function () {   
            console.log("doc: ", doc);  
                doc.addImage(genImg, 'PNG',  x, y, 100, 100);    
            }
            resolve();
        });
    });
}

The result is always a PDF with only text 'MAP001', I am not sure why the image would not be shown.

Below is the console output:

genImg:  is a img tag like < img crossorigin=​"anonymous" src=​"https:​/​/​cors.now.sh ... a link" >

rtnimg : (33) [Promise, Promise, Promise, Promise, Promise, Promise, Promise, Promise, Promise, Promise, Promise, Promise, Promise, Promise, Promise, Promise, Promise, Promise, Promise, Promise, Promise, Promise, Promise, Promise, Promise, Promise, Promise, Promise, Promise, Promise, Promise, Promise, Promise]

Finish hello PDF!

doc:  {internal: {…}, addPage: ƒ, setPage: ƒ, insertPage: ƒ, movePage: ƒ, …}

Below is my successful attempt of printing only a image on PDF.

function genPDF_fromUrl(link) {
        var genImg = new Image();
        genImg.setAttribute('crossOrigin', 'anonymous');
        genImg.src = link[0];

        genImg.onload = function () {    
        var doc = new jsPDF();
        doc.setFontSize(40);
        doc.text(80, 25, 'MAP001');
        doc.addImage(genImg, 'PNG',  0, 0, 100, 100);         
        doc.save("map.pdf"); 
        }      
}

Seem like "var doc = new jsPDF();" has to be in onload function but I cannot do that for multiple images.

解决方案

You are starting the PDF creation, and then waiting for each image. Instead of doing such way, my proposal is to preload all images and wait for a callback when all images have been downloaded and are ready to print in jsPDF by invoking the addImage function.

I did it in following way some time ago, as a part of a more complex jsPDF plugin

function Picture(src) {
    this.src = src;
    this.img = null;
}

function Preloader() {
    this.pictures = [];
    this.onpicturesloaded = null;
}

Preloader.prototype.setPicture = function(src) {
    var id = src.split("/").pop().split(".")[0].toLowerCase();
    this.pictures[id] = new Picture(src);
    return this.pictures[id];
};

Preloader.prototype.loadPictures = function() {
    var self = this, pictures = self.pictures, n = 0;
    for(var id in pictures) {
        if(pictures.hasOwnProperty(id)) {
            var pic = self.pictures[id];
            n++;
        }
    }
    for(var id in pictures) {
        if(pictures.hasOwnProperty(id)) {
            var pic = self.pictures[id];
            var decrease = function(e) {
                if(--n == 0) {
                    self.onpicturesloaded();
                }
            }
            var img = new Image();
            img.onload = function() {
                var pic = self.pictures[this.alt];
                pic.img = this;
                decrease();
            };
            img.alt = id;
            img.src = pic.src;
        }
    }
};

I'm using the stripped filename as ìd to get directly the associated image, for that reason there is this slightly overhead of the double loop inside the loadPictures function, if you find this too bad, feel free to change it to a true array, where you can get directly the picture count as pictures.length.

This id is then also used in jsPDF as alias for each image, to speed up the whole process, whereby the full image path is stored instead in picture.src.

This is (more pr less) the usage of all that stuff above:

var pl = new Preloader();
pl.setPicture("pdf/a.jpg");
pl.setPicture("pdf/b.jpg");
pl.setPicture("pdf/c.jpg");

pl.onpicturesloaded = function() {
    var doc = new jsPDF();
    var pic = pl.pictures["a"];
    doc.addImage(pic.img, "jpg", 10, 10, 100, 100, pic.img.alt, "FAST");
    // add more images, print text, and so on
    doc.save('mydocument.pdf');
};  
pl.loadPictures();

Please note, this is just an extract on-the-fly of that jsPDF plugin, without some parts which i needed for example, to draw inside a canvas and add on the fly the picture data to the PDF.

So, I am sure this can be further simplified and stripped down, but anyway, you can get the idea.

这篇关于如何使用jsPDF将多个图像添加到PDF的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆