[英]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/saveSvgAsPng将svg
转换为图像,然后使用该图像创建 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.