Javascript 使用jspdf创建的pdf文件太大

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/37677750/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-23 20:38:03  来源:igfitidea点击:

Pdf file size too big created using jspdf

javascripthtml5-canvasbase64jspdffusioncharts

提问by Asha Koshti

I am using jspdf for creating PDF inside browser. I am having multiple charts having svg as chart Data. For adding data to pdf I am converting svg to png using canvas and then Base64 Data using canvas.toDataURLmethod. After all this conversions size of the file created by jspdf is huge (about 50 MB). Below is the code for div of chart data and canvas.

我正在使用 jspdf 在浏览器中创建 PDF。我有多个以 svg 作为图表数据的图表。为了将数据添加到 pdf,我使用画布将 svg 转换为 png,然后使用canvas.toDataURL方法将 Base64 数据转换为 png 。毕竟由 jspdf 创建的文件的转换大小很大(大约 50 MB)。下面是图表数据和画布的 div 代码。

newdiv = document.createElement("div");
newdiv.className = "big_Con_graph big_Con_graph0";
newdiv.style.height = "0px";
newdiv.id = "big_Con_graph" + id;

below is the dimensions for SVG chart load.

下面是 SVG 图表加载的尺寸。

document.getElementById("big_Con_graph" + id).style.display = "block";
var big_chartReference = FusionCharts("big_myChartId"+id);
if(big_chartReference != null){
    big_chartReference.dispose();
}
var big_width = "1088";
var big_height = "604";

now below is the code for conversion of above graph SVG data and adding to PDF.

现在下面是转换上述图形SVG数据并添加到PDF的代码。

var elem_graph = $($('.big_Con_graph,big_Con_graph0')[count]).clone(true);
svgString = $(elem_graph).find("span").html();
var img = document.createElement('img');
var DOMURL = self.URL || self.webkitURL || self;
var svg = new Blob([svgString], {type: "image/svg+xml;charset=utf-8"});
var url = DOMURL.createObjectURL(svg);
img.onload = pdfAfterImageLoad(img,pdf,imgLoadSequence,DOMURL,totalReports,reportName);
img.src = url;

this is the code for PDFAfterImageLoad function:

这是 PDFAfterImageLoad 函数的代码:

var canvas = document.getElementById("canvas");
var ctx = canvas.getContext("2d");
ctx.drawImage(img, 0, 0);
var png = canvas.toDataURL("image/png");
pdf.addImage(png, 'PNG', leftmargin, 120, 485, 270);

I am using png, so imagequality parameter can not be used.

我使用的是 png,因此无法使用 imagequality 参数。

Can anyone help me decrease the file size?

谁能帮我减小文件大小?

回答by hkm93

You need to compress the images in the PDF's that you are generating. Try using Deflate.js and adler32cs.js and use the compress parameter in both jsPDF and addImage functions that you are using. For eg :

您需要压缩正在生成的 PDF 中的图像。尝试使用 Deflate.js 和 adler32cs.js,并在您使用的 jsPDF 和 addImage 函数中使用 compress 参数。例如:

var doc = new jsPDF('p', 'pt','a4',true);

make sure you set the last parameter as 'true' refer to : https://github.com/MrRio/jsPDF/blob/ddbfc0f0250ca908f8061a72fa057116b7613e78/jspdf.js#L146

确保将最后一个参数设置为“true”,请参阅:https: //github.com/MrRio/jsPDF/blob/ddbfc0f0250ca908f8061a72fa057116b7613e78/jspdf.js#L146

Go through it and you can clearly see that the last parameter is for enabling compression.

通过它,您可以清楚地看到最后一个参数是启用压缩。

Also use :

还使用:

pdf.addImage(png, 'PNG', leftmargin, 120, 485, 270,'','FAST');

instead of

代替

pdf.addImage(png, 'PNG', leftmargin, 120, 485, 270);

you can choose between NONE, FAST, MEDIUM and SLOW, whichever suits you best.

您可以在 NONE、FAST、MEDIUM 和 SLOW 之间进行选择,以最适合您的方式。

回答by Andrew Hudik

If you add several images to one document, use

如果您将多个图像添加到一个文档,请使用

pdf.addImage(png, 'PNG', leftmargin, 120, 485, 270, undefined,'FAST');

not

不是

pdf.addImage(png, 'PNG', leftmargin, 120, 485, 270,'','FAST');

otherwise the first image will substitute all others.

否则第一个图像将替换所有其他图像。

回答by mikemaal

In my case did not work with compress parameter. So, I resized the current image on my own with the following function:

在我的情况下, compress 参数不起作用。因此,我使用以下函数自行调整了当前图像的大小:

function resizeBase64Img(base64, width, height) {
    var canvas = document.createElement("canvas");
    canvas.width = width;
    canvas.height = height;
    var context = canvas.getContext("2d");
    var deferred = $.Deferred();
    $("<img/>").attr("src", "data:image/gif;base64," + base64).load(function() {
        context.scale(width/this.width,  height/this.height);
        context.drawImage(this, 0, 0); 
        deferred.resolve($("<img/>").attr("src", canvas.toDataURL()));               
    });
    return deferred.promise();    
}

And call it as follows:

并按如下方式调用它:

//select my image in base64
var imageStr64 = "/9j/4RiDRXhpZgAATU0AKgA...";
//resize image, add image and create the pdf
resizeBase64Img(imageStr64, 1000, 1000).then(function(newImg){
    doc.addImage($(newImg).attr('src'), 15, 90, 180,180);
    doc.save('mypdf.pdf');
});

You can play with 'width' and 'height' parameters in resizeBase64Img function in order to generate heavy pdf with better or worst image quality.

您可以在 resizeBase64Img 函数中使用 'width' 和 'height' 参数,以生成具有更好或最差图像质量的重 pdf。

回答by Daniel Rodrigues

Perfect. PDF size 90mb to 3mb with great quality.

完美的。PDF 大小为 90mb 到 3mb,质量很好。

pdf.addImage(png, 'PNG', 0, 0, 485, 270, undefined,'FAST');

pdf.addImage(png, 'PNG', 0, 0, 485, 270, undefined,'FAST');

回答by YakovL

Have you tried canvg? It's not very likely that it will decrease the filesize, but at least you can try.

你试过canvg吗?它不太可能减少文件大小,但至少您可以尝试。

See a snippet in this reply.

请参阅此回复中的一个片段。