如何将带有 SVG 的 HTML 下载为 PDF?
How to download an HTML with SVGs as a PDF?
我有一个包含一些 SVG 的页面,我想从中生成一个 PDF。对于这个范围,我使用 ,并且我使用以下方法将 SVG 转换为图像:
var $body_clone = $('#pdf_container').clone();
var $svgs = $body_clone.find('svg');
var $svg;
var xml;
var data;
var $img;
for (var i=0; i<$svgs.length; i++) {
var $svg = $svgs.eq(i);
xml = new XMLSerializer().serializeToString($svg[0]);
data = "data:image/svg+xml;base64," + btoa(unescape(encodeURIComponent(xml)));
$img = $(new Image());
$img.attr('src', data);
$img.width($svg.outerWidth(true));
$img.height($svg.outerHeight(true));
$svg.replaceWith($img[0].outerHTML);
}
我尝试删除 clone()
和提交,它起作用了:页面中的 SVG 被替换为(丑陋的)图像。
恢复 clone()
和表单提交,我在服务器上发送 $body_clone
的 html,使用 Mustache
添加到 pdf 的临时模板中。然后我用 jsoup
清理 html 转换为 xhtml,我用 Flying Saucer 转换它并将它发送到 http 响应。
我得到的是只有文本的 pdf。转换为图像的 SVG 不存在。
我还按照 SO answer 中的建议添加了 -Djava.protocol.handler.pkgs=org.xhtmlrenderer.protocols
,但没有添加任何内容。我怀疑问题是图像的 src
不是 data:image/png
,例如,而是 data:image/svg+xml
.
无论如何,我尝试使用浏览器 (Firefox) 打印整个页面,打印为 PDF (Lubuntu) 文件。不仅显示图像,而且它们是完美的。 Lubuntu 使用什么打印成 pdf?可以作为外部转换器使用吗?如果没有,它是如何工作的,有没有办法模拟打印到文件?
我最终以这种方式使用 SaveSvgAsPng:
function downloadPdf() {
"use strict";
// get the graphics global container
var $body_clone = $('#pdf_container');
// get the SVGs
var $svgs = $('.graph_container svg');
var $svg;
var promises = [];
for (var i=0; i<$svgs.length; i++) {
$svg = $svgs.eq(i);
// convert the SVGs to images srcs
promises.push(svgAsPngUri($svg[0]));
}
$.when.apply(null, promises).then(function() {
var img_scrs = Array.prototype.slice.call(arguments);
var $img;
for (var i=0; i<$svgs.length; i++) {
$svg = $svgs.eq(i);
$img = $(new Image());
$img.attr("src", img_scrs[i]);
// substitute the SVGs with the image
$svg.replaceWith(imgs[i]);
}
var $body_clone = $('#pdf_container');
var body = $body_clone[0].outerHTML;
$('#pdfBody').val(body);
// send to the server the HTML of the container of all images
$('#pdfForm').submit();
// get all images
var $imgs = $('.graph_container img:not(.waiting)');
var $img;
for (var i=0; i<$imgs.length; i++) {
$img = $imgs.eq(i);
// replace image with empty svg
$img.replaceWith('<svg></svg>');
}
// repopulate the graphs as you did at the page load
grafic();
});
}
作为替代方案,您可以使用 chromium as pdf converter:
chromium-browser --headless --print-to-pdf=path/to/file.pdf https://example.com
或
chromium-browser --headless --print-to-pdf=path/to/file.pdf file:/path/to/file.html
结果很完美。
我有一个包含一些 SVG 的页面,我想从中生成一个 PDF。对于这个范围,我使用
var $body_clone = $('#pdf_container').clone();
var $svgs = $body_clone.find('svg');
var $svg;
var xml;
var data;
var $img;
for (var i=0; i<$svgs.length; i++) {
var $svg = $svgs.eq(i);
xml = new XMLSerializer().serializeToString($svg[0]);
data = "data:image/svg+xml;base64," + btoa(unescape(encodeURIComponent(xml)));
$img = $(new Image());
$img.attr('src', data);
$img.width($svg.outerWidth(true));
$img.height($svg.outerHeight(true));
$svg.replaceWith($img[0].outerHTML);
}
我尝试删除 clone()
和提交,它起作用了:页面中的 SVG 被替换为(丑陋的)图像。
恢复 clone()
和表单提交,我在服务器上发送 $body_clone
的 html,使用 Mustache
添加到 pdf 的临时模板中。然后我用 jsoup
清理 html 转换为 xhtml,我用 Flying Saucer 转换它并将它发送到 http 响应。
我得到的是只有文本的 pdf。转换为图像的 SVG 不存在。
我还按照 SO answer 中的建议添加了 -Djava.protocol.handler.pkgs=org.xhtmlrenderer.protocols
,但没有添加任何内容。我怀疑问题是图像的 src
不是 data:image/png
,例如,而是 data:image/svg+xml
.
无论如何,我尝试使用浏览器 (Firefox) 打印整个页面,打印为 PDF (Lubuntu) 文件。不仅显示图像,而且它们是完美的。 Lubuntu 使用什么打印成 pdf?可以作为外部转换器使用吗?如果没有,它是如何工作的,有没有办法模拟打印到文件?
我最终以这种方式使用 SaveSvgAsPng:
function downloadPdf() {
"use strict";
// get the graphics global container
var $body_clone = $('#pdf_container');
// get the SVGs
var $svgs = $('.graph_container svg');
var $svg;
var promises = [];
for (var i=0; i<$svgs.length; i++) {
$svg = $svgs.eq(i);
// convert the SVGs to images srcs
promises.push(svgAsPngUri($svg[0]));
}
$.when.apply(null, promises).then(function() {
var img_scrs = Array.prototype.slice.call(arguments);
var $img;
for (var i=0; i<$svgs.length; i++) {
$svg = $svgs.eq(i);
$img = $(new Image());
$img.attr("src", img_scrs[i]);
// substitute the SVGs with the image
$svg.replaceWith(imgs[i]);
}
var $body_clone = $('#pdf_container');
var body = $body_clone[0].outerHTML;
$('#pdfBody').val(body);
// send to the server the HTML of the container of all images
$('#pdfForm').submit();
// get all images
var $imgs = $('.graph_container img:not(.waiting)');
var $img;
for (var i=0; i<$imgs.length; i++) {
$img = $imgs.eq(i);
// replace image with empty svg
$img.replaceWith('<svg></svg>');
}
// repopulate the graphs as you did at the page load
grafic();
});
}
作为替代方案,您可以使用 chromium as pdf converter:
chromium-browser --headless --print-to-pdf=path/to/file.pdf https://example.com
或
chromium-browser --headless --print-to-pdf=path/to/file.pdf file:/path/to/file.html
结果很完美。