简体   繁体   English

通过具有 SVG 的 jsPDF 将 HTML Div 转换为 PDF

[英]Convert HTML Div to PDF via jsPDF that has SVG

I am trying to convert a html div to pdf using jsPDF .我正在尝试使用jsPDF将 html div 转换为 pdf 。 With in my div I have a svg file with background image where user can draw rectangle, line, text etc. I am using d3.js for drawing.在我的 div 中,我有一个带有背景图像的svg文件,用户可以在其中绘制矩形、线条、文本等。我​​使用d3.js进行绘图。 Now I want to save my div with all drawing to pdf but it only converting my text to pdf.现在我想将我的 div 与所有绘图保存为 pdf,但它只会将我的文本转换为 pdf。 My js code is我的js代码是

   function htmlToPdf() {
  console.log("--------------- with in demoFromHTML");
  var pdf = new jsPDF('p', 'pt', 'letter');
  // source can be HTML-formatted string, or a reference
  // to an actual DOM element from which the text will be scraped.
  source = $('svg.plancontainer')[0];

  // we support special element handlers. Register them with jQuery-style
  // ID selector for either ID or node name. ("#iAmID", "div", "span" etc.)
  // There is no support for any other type of selectors
  // (class, of compound) at this time.
  specialElementHandlers = {
    // element with id of "bypass" - jQuery style selector
    '#bypassme': function (element, renderer) {
      // true = "handled elsewhere, bypass text extraction"
      return true
    }
  };
  margins = {
    top: 80,
    bottom: 60,
    left: 40,
    width: 522
  };
  // all coords and widths are in jsPDF instance's declared units
  // 'inches' in this case
  pdf.fromHTML(
    source, // HTML string or DOM elem ref.
    margins.left, // x coord
    margins.top, { // y coord
      'width': margins.width, // max width of content on PDF
      'elementHandlers': specialElementHandlers
    },

    function (dispose) {
      // dispose: object with X, Y of the last line add to the PDF
      //          this allow the insertion of new lines after html
      // pdf.autoPrint();
      pdf.output('dataurlnewwindow');
    }, margins
  );
}

and cdn is <script src="https://cdnjs.cloudflare.com/ajax/libs/jspdf/1.3.2/jspdf.debug.js"></script>和 cdn 是<script src="https://cdnjs.cloudflare.com/ajax/libs/jspdf/1.3.2/jspdf.debug.js"></script>

It print PRINT AREA instead of my image and text with out svg drawing.它打印PRINT AREA而不是我的image和文本,没有svg绘图。

It is my sample div's preview that I want to convert to pdf这是我想转换为 pdf 的示例 div 预览在此处输入图片说明 I did not get any specific informatin that specify where it is possible using jsPDF or not.我没有得到任何具体的信息来指定可以使用jsPDF

Now my questions are现在我的问题是

  • Is it possible using jsPDF or any other js library ?是否可以使用jsPDF或任何其他 js 库?

  • If possible, would you please suggest me?如果可以,请给我推荐一下好吗?

Any kind of help are appreciated.任何形式的帮助表示赞赏。 Thanks.谢谢。

I am sharing my solution that may help someone.我正在分享我的解决方案,可能会对某人有所帮助。 I could not manage print svg directly using jspdf instead what I have done is first convert svg to image using https://github.com/exupero/saveSvgAsPng then use that image to create pdf.我无法直接使用jspdf管理打印svg而是首先使用https://github.com/exupero/saveSvgAsPngsvg转换为图像,然后使用该图像创建 pdf。 Below is my code下面是我的代码

Get base64 image uri using svgAsPngUri method of saveSvgAsPng and pass that image through callback function获取base64 image uri使用svgAsPngUri saveSvgAsPng的方法,并通过回调函数传递图像

svgAsPngUri(#svgObj, options, function (uri, options) {
        pdf(uri, options.pdf)
    });

where I am getting image uri as uri .我在哪里得到image uri作为uri With in my pdf function I am using this uri to make pdf在我的pdf函数中,我使用这个uri来制作 pdf

function pdf(b64Image, options) {
    console.log("--------------- passing options is ", JSON.stringify(options, null, 4));
    var image = new Image();
    image.src = b64Image;
    console.log('--------- pdf options' + JSON.stringify(options, null, 4));
    var pdf = new jsPDF(options.orientation, null, options.format);

    margins = {
        top: 20,
        bottom: 20,
        left: 20,
        right: 20
    };

    var pdfWidth = pdf.internal.pageSize.width;
    var pdfHeight = pdf.internal.pageSize.height;
    var footer_height = options.f_height || 30;
    var htmlPageRightOffset = 0;

    var outerRacBorder = 2;
    var imageDrawableHeight = pdfHeight - margins.top - margins.bottom - footer_height - outerRacBorder;
    var imageDrawableWidth = pdfWidth - margins.left - margins.right - outerRacBorder;

    footer = {
        top: margins.top + imageDrawableHeight + outerRacBorder + 10,
        bottom: 20,
        left: margins.left,
        right: 20,
        width: 100,
        height: 25,
    };

    company_text_position = {
        x: footer.left+2,
        y: footer.top + 6
    };
    site_text_position = {
        x: company_text_position.x,
        y: company_text_position.y + 6
    };
    floor_plan_text_position = {
        x: site_text_position.x,
        y: site_text_position.y + 6
    };
    logo_text_position = {
        x: pdfWidth - margins.left - 55,
        y: pdfHeight - margins.bottom - 4
    };
    logo_image_position = {
        x: logo_text_position.x +35,
        y: logo_text_position.y - 4
    };
    /*
     Image drawing on pdf
     */
    imageSize = calculateAspectRatioFit(image.width, image.height, imageDrawableWidth, imageDrawableHeight);
    pdf.addImage(image, 'JPEG', margins.left + 2, margins.top + 2, imageSize.width, imageSize.height);

    /*
     Outer rectangle
     */
    pdf.rect(margins.left, margins.top, imageDrawableWidth + outerRacBorder, imageDrawableHeight + outerRacBorder);

    // pdf.rect(margins.left, imageSize.height + 10, drawableWidth, (drawableWidth - imageSize.height));

    pdf.rect(footer.left, footer.top, footer.width, footer.height);
    console.log(footer.left);
    console.log(footer.company_x);

    var footer_data = getFooterInfo();
    pdf.text("Company: " + footer_data.client, company_text_position.x, company_text_position.y);
    pdf.text("Site: " + footer_data.site, site_text_position.x, site_text_position.y);
    pdf.text("Floor Plan: " + footer_data.floor_plan, floor_plan_text_position.x, floor_plan_text_position.y);

    pdf.text("Powered by: ", logo_text_position.x, logo_text_position.y);

    var logo = new Image();
    logo.src = $('#logo_image').val();
    console.log(logo);
    logoSize = calculateAspectRatioFit(logo.width, logo.height, 20, 10);
    pdf.addImage(logo, 'JPEG', logo_image_position.x, logo_image_position.y, logoSize.width, logoSize.height);

    pdf.autoPrint();
    pdf.save(options.name + '.pdf');
}


/**
 * Conserve aspect ratio of the orignal region. Useful when shrinking/enlarging
 * images to fit into a certain area.
 *
 * @param {Number} srcWidth Source area width
 * @param {Number} srcHeight Source area height
 * @param {Number} maxWidth Fittable area maximum available width
 * @param {Number} maxHeight Fittable area maximum available height
 * @return {Object} { width, heigth }
 *
 */
function calculateAspectRatioFit(srcWidth, srcHeight, maxWidth, maxHeight) {
    if(srcHeight == 0 || srcWidth == 0){
      return {width: maxWidth, height: maxHeight};
    }

    var ratio = [maxWidth / srcWidth, maxHeight / srcHeight];
    ratio = Math.min(ratio[0], ratio[1]);

    return {width: srcWidth * ratio, height: srcHeight * ratio};
}

function getFooterInfo() {
    var elem = $('.entityselbin .h4');
    var info = {};
    info.client = elem[0].innerHTML;
    info.site = elem[1].innerHTML;
    info.floor_plan = elem[2].innerHTML;
    return info;
}

You can directly write the SVG to PDF with the latest canvg_context2d method mention in the example您可以使用示例中提到的最新canvg_context2d方法直接将 SVG 写入 PDF

https://github.com/MrRio/jsPDF/blob/master/examples/canvg_context2d/bar_graph_with_text_and_lines.html https://github.com/MrRio/jsPDF/blob/master/examples/canvg_context2d/bar_graph_with_text_and_lines.html

This works for most of the svg contents.这适用于大多数 svg 内容。

Below is the working example of above question.以下是上述问题的工作示例。

Need to include these three file refernece需要包含这三个文件引用

$.getScript(" https://cdnjs.cloudflare.com/ajax/libs/html2canvas/0.4.1/html2canvas.js "), $.getScript(" https://cdnjs.cloudflare.com/ajax/libs/jspdf/1.0.272/jspdf.debug.js "), $.getScript(" https://cdnjs.cloudflare.com/ajax/libs/canvg/1.5/canvg.min.js ") $.getScript(" https://cdnjs.cloudflare.com/ajax/libs/html2canvas/0.4.1/html2canvas.js "), $.getScript(" https://cdnjs.cloudflare.com/ajax/libs/ jspdf/1.0.272/jspdf.debug.js "), $.getScript(" https://cdnjs.cloudflare.com/ajax/libs/canvg/1.5/canvg.min.js ")

function createPDF() {

    var svg = '';
// Provide the SVG parent div id

    if (document.getElementById("ChartId") != null) {
        svg = document.getElementById("ChartId").innerHTML;
    }

    if (svg)
        svg = svg.replace(/\r?\n|\r/g, '').trim();

    var pdfData = $('#htmlContainer');//main html div


    html2canvas(pdfData, {
        onrendered: function(canvas) {

            var contentWidth = canvas.width;
            var contentHeight = canvas.height;

            //The height of the canvas which one pdf page can show;
            var pageHeight = contentWidth / 592.28 * 841.89;
            //the height of canvas that haven't render to pdf
            var leftHeight = contentHeight;
            //addImage y-axial offset
            var position = 0;
            //a4 format [595.28,841.89]       
            var imgWidth = 595.28;
            var imgHeight = 592.28 / contentWidth * contentHeight;

            var ctx = canvas.getContext('2d');


            canvg(canvas, svg, {
                offsetX: 10,
                offsetY: 660,
                ignoreMouse: true,
                ignoreAnimation: true,
                ignoreClear: true,
                ignoreDimensions: true
            });

            var pageData = new Image();
            pageData = canvas.toDataURL('image/jpeg', 1.0);


            var pdf = new jsPDF('l', 'pt', 'a4', true);

            if (leftHeight < pageHeight) {
                pdf.addImage(pageData, 'JPEG', 100, 20, imgWidth, imgHeight);

            } else {
                console.log('page 2');
                while (leftHeight > 0) {
                    pdf.addImage(pageData, 'JPEG', 0, position, imgWidth, imgHeight)
                    leftHeight -= pageHeight;
                    position -= 841.89;
                    //avoid blank page
                    if (leftHeight > 0) {
                        pdf.addPage();
                    }
                }
            }
            pdf.save('Test.pdf');
        }
    });
}

Hope this will be helpful.希望这会有所帮助。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM