【问题标题】:Pdf file size too big created using jspdf使用 jspdf 创建的 Pdf 文件太大
【发布时间】:2016-10-07 06:15:33
【问题描述】:

我正在使用 jspdf 在浏览器中创建 PDF。我有多个将 svg 作为图表数据的图表。为了向 pdf 添加数据,我使用画布将 svg 转换为 png,然后使用 canvas.toDataURL 方法将 Base64 数据转换为。毕竟,由 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参数。

谁能帮我减小文件大小?

【问题讨论】:

  • 你转换成base64是因为jspdf需要吗?
  • 我没有通过单击按钮获取 svg 数据并通过画布将其转换为 png 来存储图像,因此整个过程需要 base64 数据。即使我无法将所有图形数据存储在客户端存储。
  • 我明白了。为什么你使用 png 而不是 jpeg?使用带有质量修饰符的 jpeg 会有所帮助(请参阅 developer.mozilla.org/en-US/docs/Web/API/HTMLCanvasElement/…
  • 是的,但 jpeg 与质量参数一起使用时质量也很差。即使我想用 pdf 放大和缩小,而 jpeg 是不可能的。
  • 这张图片的尺寸是多少?你能告诉我们图像包含什么/它适用于你添加的任何图像吗?你能告诉我们你用来将它添加到jspdf的代码吗? (并且你的 onload 回调以错误的方式使用,应该是一个函数引用;现在它是一个使用 onload 的结果的调用)。

标签: javascript html5-canvas base64 jspdf fusioncharts


【解决方案1】:

您需要压缩正在生成的 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 之间进行选择,以最适合您的方式。

【讨论】:

  • 这行得通。我在底部得到一条边界线 - 使用 jspdf addimag。如何删除该行
  • 反正横线没有印在纸上。
  • 我正在从自定义图形创建 pdf。我能够使用 jspdf 生成 pdf。但是网页上的图形颜色和字体颜色正在pdf上复制。 (图表中缺少框阴影效果,并且图表看起来很模糊)。我该如何解决?
  • @HemantKumar 你能提供带有 jsfiddle 的链接吗?所以我可以用解决方案指导你。实际上,图表生成的 svg 会产生问题。我们需要消除一些标签或更正它,跨度>
  • 好的。当然,我会尝试 jsfiddle 它。我会弄清楚如何在 jsfiddle 中设置它。
【解决方案2】:

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

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

不是

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

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

【讨论】:

  • 是的..这只是给出的例子,, pdf.addImage(png, 'PNG', leftmargin, 120, 485, 270, undefined,'FAST');在那个未定义的名称中,每次添加图像时都必须指定不同的名称。根据 API,它是别名名称。每个图像必须是唯一的。
  • 直接说上面的例子也将我的 4Mb PDF(11 页,每页 10 个图表)减少到 977kb。非常感谢您的提示!
【解决方案3】:

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

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

【讨论】:

  • 请详细说明您的答案,我在 OP 中看不到任何 var pdf
【解决方案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');
});

您可以在 resizeBase64Img 函数中使用“宽度”和“高度”参数来生成具有更好或最差图像质量的重型 pdf。

【讨论】:

    【解决方案5】:

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

    this reply 中查看 sn-p。

    【讨论】:

    • 是的,我已经在 IE 和 safari 浏览器中使用 canvg。但它与任何文件大小减小有关。
    【解决方案6】:

    我已经尝试了 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 之前会被压缩

    【讨论】:

      猜你喜欢
      • 2013-09-22
      • 1970-01-01
      • 2019-02-24
      • 1970-01-01
      • 1970-01-01
      • 2018-01-10
      • 2020-09-16
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多