Как скачать HTML с SVG в формате PDF? - PullRequest
0 голосов
/ 30 марта 2019

У меня есть страница с некоторыми SVG, и я хочу сгенерировать из нее PDF. Для этой цели я использую Летающая тарелка с OpenPDF , и я преобразовал 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() и отправляя форму, я отправляю html $body_clone на сервер, где добавляется специальный шаблон для PDF, используя Mustache. Затем я очищаю html, преобразованный в xhtml с помощью jsoup, я преобразую его с помощью Flying Saucer и отправляю в ответ http.

Я получаю PDF-файл только с текстом. SVG, преобразованные в изображения, отсутствуют.

Я также добавил -Djava.protocol.handler.pkgs=org.xhtmlrenderer.protocols, как предложено в этом SO ответе , но ничего. Я подозреваю, что проблема в src изображений, например, не data:image/png, а data:image/svg+xml.

В любом случае я пытался напечатать всю страницу с помощью браузера (Firefox), распечатывая в файл в формате PDF (Lubuntu). Не только изображения показаны, но они идеально подходят. Что Lubuntu использует для печати в PDF? Можно ли использовать его как внешний конвертер? Если нет, то как это работает, и есть способ эмулировать печать в файл?

1 Ответ

0 голосов
/ 02 апреля 2019

Я использовал 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();
    });
}

В качестве альтернативы вы можете использовать хром как pdf конвертер :

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

Результат идеален.

...