通过具有 SVG 的 jsPDF 将 HTML Div 转换为 PDF
Convert HTML Div to PDF via jsPDF that has SVG
我正在尝试使用 jsPDF
将 html div 转换为 pdf。在我的 div 中,我有一个带有背景图像的 svg
文件,用户可以在其中绘制矩形、线条、文本等。我正在使用 d3.js
进行绘图。现在我想将我的 div 和所有绘图保存为 pdf,但它只会将我的文本转换为 pdf。我的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
);
}
cdn 是 <script src="https://cdnjs.cloudflare.com/ajax/libs/jspdf/1.3.2/jspdf.debug.js"></script>
它打印 PRINT AREA
而不是我的 image
和没有 svg
绘图的文本。
这是我的示例 div 的预览,我想将其转换为 pdf
我没有得到任何具体的信息来指定在哪里可以使用 jsPDF
或不使用。
现在我的问题是
是否可以使用 jsPDF
或任何其他 js 库?
如果可以的话,请您推荐一下?
感谢任何形式的帮助。谢谢。
我正在分享我的解决方案,可能会对某人有所帮助。我无法直接使用 jspdf
管理打印 svg
,而是首先使用 https://github.com/exupero/saveSvgAsPng 将 svg
转换为图像,然后使用该图像创建 pdf。下面是我的代码
使用 saveSvgAsPng 的 svgAsPngUri
方法获取 base64 image uri
并通过回调函数
传递该图像
svgAsPngUri(#svgObj, options, function (uri, options) {
pdf(uri, options.pdf)
});
我得到 image uri
作为 uri
。在我的 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;
}
您可以使用示例中提到的最新canvg_context2d
方法直接将SVG写入PDF
这适用于大多数 svg 内容。
下面是上述问题的工作示例。
需要引用这三个文件
$.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');
}
});
}
希望这会有所帮助。
我正在尝试使用 jsPDF
将 html div 转换为 pdf。在我的 div 中,我有一个带有背景图像的 svg
文件,用户可以在其中绘制矩形、线条、文本等。我正在使用 d3.js
进行绘图。现在我想将我的 div 和所有绘图保存为 pdf,但它只会将我的文本转换为 pdf。我的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
);
}
cdn 是 <script src="https://cdnjs.cloudflare.com/ajax/libs/jspdf/1.3.2/jspdf.debug.js"></script>
它打印 PRINT AREA
而不是我的 image
和没有 svg
绘图的文本。
这是我的示例 div 的预览,我想将其转换为 pdfjsPDF
或不使用。
现在我的问题是
是否可以使用
jsPDF
或任何其他 js 库?如果可以的话,请您推荐一下?
感谢任何形式的帮助。谢谢。
我正在分享我的解决方案,可能会对某人有所帮助。我无法直接使用 jspdf
管理打印 svg
,而是首先使用 https://github.com/exupero/saveSvgAsPng 将 svg
转换为图像,然后使用该图像创建 pdf。下面是我的代码
使用 saveSvgAsPng 的 svgAsPngUri
方法获取 base64 image uri
并通过回调函数
svgAsPngUri(#svgObj, options, function (uri, options) {
pdf(uri, options.pdf)
});
我得到 image uri
作为 uri
。在我的 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;
}
您可以使用示例中提到的最新canvg_context2d
方法直接将SVG写入PDF
这适用于大多数 svg 内容。
下面是上述问题的工作示例。
需要引用这三个文件
$.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');
}
});
}
希望这会有所帮助。