Размер файла Pdf слишком большой, созданный с помощью jspdf

Я использую jspdf для создания PDF внутри браузера. У меня есть несколько диаграмм, имеющих svg как данные диаграммы. Для добавления данных в pdf я конвертирую svg в png, используя canvas, а затем Base64 Data с использованием метода canvas.toDataURL. После всего этого размера конверсий файл, созданный jspdf, огромен (около 50 МБ). Ниже приведен код для данных диаграммы и холста.

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, поэтому параметр изображения не может быть использован.

Может ли кто-нибудь помочь мне уменьшить размер файла?

Ответ 1

Вам нужно сжать изображения в PDF, который вы генерируете. Попробуйте использовать Deflate.js и adler32cs.js и используйте параметр compress в функциях jsPDF и addImage, которые вы используете. Например:

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, в зависимости от того, что вам больше подходит.

Ответ 2

Если вы добавили несколько изображений в один документ, используйте

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

не

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

в противном случае первое изображение заменит все остальные.

Ответ 3

Вы пробовали canvg? Не очень вероятно, что это уменьшит размер файла, но по крайней мере вы можете попробовать.

См. фрагмент в этом ответе.

Ответ 4

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

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

Вы можете поиграть с параметрами 'width' и 'height' в функции resizeBase64Img, чтобы создать тяжелый PDF с лучшим или худшим качеством изображения.