使用jspdf创建的Pdf文件大小太大

时间:2016-06-07 11:10:04

标签: javascript html5-canvas base64 jspdf fusioncharts

我正在使用jspdf在浏览器中创建PDF。我有多个图表有svg作为图表数据。为了向pdf添加数据,我使用canvas将svg转换为png,然后使用canvas.toDataURL方法将Base64 Data转换为p64。在所有这些转换之后,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;

下面是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";

现在下面是转换上图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;

这是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);

我正在使用png,因此无法使用imagequality参数。

有人可以帮我减小文件大小吗?

6 个答案:

答案 0 :(得分:35)

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

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

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

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

也可以使用:

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

而不是

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

您可以选择NONE,FAST,MEDIUM和SLOW,以最适合您的方式。

答案 1 :(得分:12)

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

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

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

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

答案 2 :(得分:1)

完美。 PDF大小在90mb到3mb之间,质量很高。

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

答案 3 :(得分:0)

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

查看this reply中的摘要。

答案 4 :(得分:0)

在我的情况下,没有使用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();    
}

并按如下方式调用:

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

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

答案 5 :(得分:0)

我已经尝试了 compress 参数并按照建议传递了compression:'MEDIUM' toe addImage 方法,但什么也没发生

对我有用的是将画布转换为 DataUrl base64 字符串并传递压缩值

pdf.addImage({ imageData: canvas.toDataURL('image/jpeg', 0.6),format: 'JPEG', x: 2, y: 100, width: newImageWidth, height: newImageHeight});

通过这种方式,图像在添加到 PDF 之前会被压缩