Joh*_*ord 207 javascript jspdf
我有以下HTML代码:
<!DOCTYPE html>
<html>
<body>
<p>don't print this to pdf</p>
<div id="pdf">
<p><font size="3" color="red">print this to pdf</font></p>
</div>
</body>
</html>
Run Code Online (Sandbox Code Playgroud)
我想做的就是打印到pdf中找到的任何ID为"pdf"的div.这必须使用JavaScript完成.然后应自动下载"pdf"文档,文件名为"foobar.pdf"
我一直在使用jspdf来做这件事,但它唯一的功能是"text",它只接受字符串值.我想将HTML提交给jspdf,而不是文本.
snr*_*rlx 203
jsPDF能够使用插件.为了使其能够打印HTML,您必须包含某些插件,因此必须执行以下操作:
如果要忽略某些元素,则必须使用ID标记它们,然后可以在jsPDF的特殊元素处理程序中忽略该ID.因此,您的HTML应如下所示:
<!DOCTYPE html>
<html>
<body>
<p id="ignorePDF">don't print this to pdf</p>
<div>
<p><font size="3" color="red">print this to pdf</font></p>
</div>
</body>
</html>
Run Code Online (Sandbox Code Playgroud)
然后使用以下JavaScript代码在PopUp中打开创建的PDF:
var doc = new jsPDF();
var elementHandler = {
'#ignorePDF': function (element, renderer) {
return true;
}
};
var source = window.document.getElementsByTagName("body")[0];
doc.fromHTML(
source,
15,
15,
{
'width': 180,'elementHandlers': elementHandler
});
doc.output("dataurlnewwindow");
Run Code Online (Sandbox Code Playgroud)
对我来说,这创建了一个漂亮而整洁的PDF,其中只包括"打印到pdf"这一行.
请注意,特殊元素处理程序仅处理当前版本中的ID,这也在GitHub问题中说明.它指出:
因为匹配是针对节点树中的每个元素完成的,所以我希望尽可能快地完成匹配.在这种情况下,它意味着"只有元素ID匹配"元素ID仍然以jQuery样式"#id"完成,但并不意味着所有jQuery选择器都受支持.
因此,用'.ignorePDF'等类选择器替换'#ignorePDF'对我来说不起作用.相反,您将不得不为每个要忽略的元素添加相同的处理程序,如:
var elementHandler = {
'#ignoreElement': function (element, renderer) {
return true;
},
'#anotherIdToBeIgnored': function (element, renderer) {
return true;
}
};
Run Code Online (Sandbox Code Playgroud)
从示例中还可以说,可以选择诸如"a"或"li"的标签.对于大多数用例来说,这可能有点无限制:
我们支持特殊元素处理程序.使用jQuery样式ID选择器为ID或节点名称注册它们.("#iAmID","div","span"等)此时不支持任何其他类型的选择器(复合类).
一个非常重要的事情是你丢失了所有的样式信息(CSS).幸运的是,jsPDF可以很好地格式化h1,h2,h3等,这对我来说已经足够了.另外,它只会在文本节点中打印文本,这意味着它不会打印textareas等的值.例:
<body>
<ul>
<!-- This is printed as the element contains a textnode -->
<li>Print me!</li>
</ul>
<div>
<!-- This is not printed because jsPDF doesn't deal with the value attribute -->
<input type="textarea" value="Please print me, too!">
</div>
</body>
Run Code Online (Sandbox Code Playgroud)
小智 46
这是一个简单的解决方案.这适用于我.您可以使用javascript打印概念,并将其简单保存为pdf.
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<title></title>
<script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.8.3/jquery.min.js"></script>
<script type="text/javascript">
$("#btnPrint").live("click", function () {
var divContents = $("#dvContainer").html();
var printWindow = window.open('', '', 'height=400,width=800');
printWindow.document.write('<html><head><title>DIV Contents</title>');
printWindow.document.write('</head><body >');
printWindow.document.write(divContents);
printWindow.document.write('</body></html>');
printWindow.document.close();
printWindow.print();
});
</script>
</head>
<body>
<form id="form1">
<div id="dvContainer">
This content needs to be printed.
</div>
<input type="button" value="Print Div Contents" id="btnPrint" />
</form>
</body>
</html>
Run Code Online (Sandbox Code Playgroud)
Luk*_*kas 17
http://...domain.../path.css
。它创建单独的 HTML 文档,并且没有主要内容的上下文。这为我服务了多年:
export default function printDiv({divId, title}) {
let mywindow = window.open('', 'PRINT', 'height=650,width=900,top=100,left=150');
mywindow.document.write(`<html><head><title>${title}</title>`);
mywindow.document.write('</head><body >');
mywindow.document.write(document.getElementById(divId).innerHTML);
mywindow.document.write('</body></html>');
mywindow.document.close(); // necessary for IE >= 10
mywindow.focus(); // necessary for IE >= 10*/
mywindow.print();
mywindow.close();
return true;
}
Run Code Online (Sandbox Code Playgroud)
当然,这将打开打印对话框,用户必须知道她/他可以选择打印到 pdf 选项,以获取 pdf。可以预先选择打印机,如果用户确认可以实际打印该文件。为了避免这种情况并提供没有任何额外内容的PDF,您需要制作PDF文件。可能在服务器端。您可以使用仅带有发票的小 html 页面,并将其转换为带有无头 chrome 的 PDF 文件。使用 puppeteer 非常容易。无需安装/配置 chrome,只需安装 npm 包 puppeteer(由 chrome 团队管理)并运行它。请记住,这实际上会在没有 GUI 的情况下启动真正的 chrome,因此您需要为此配备一些 RAM 和 CPU。大多数服务器在流量足够低的情况下都可以。这是代码示例,但这必须在 BACKEND 上运行。节点。它也是缓慢的调用,它是资源密集型调用。
const puppeteer = require('puppeteer');
(async () => {
const browser = await puppeteer.launch();
const page = await browser.newPage();
await page.goto('https://your-domain.com/path-to-invoice', {
waitUntil: 'networkidle2',
});
await page.pdf({ path: 'invoice-file-path.pdf', format: 'a4' });
await browser.close();
})();
Run Code Online (Sandbox Code Playgroud)
在此处了解更多信息:https : //pptr.dev/
Mar*_*rco 16
您可以使用autoPrint()并将输出设置为'dataurlnewwindow',如下所示:
function printPDF() {
var printDoc = new jsPDF();
printDoc.fromHTML($('#pdf').get(0), 10, 10, {'width': 180});
printDoc.autoPrint();
printDoc.output("dataurlnewwindow"); // this opens a new popup, after this the PDF opens the print window view but there are browser inconsistencies with how this is handled
}
Run Code Online (Sandbox Code Playgroud)
Roh*_*rte 10
一种方法是使用 window.print() 函数。哪个不需要任何库
优点
1.不需要外部库。
2.我们也可以只打印身体的选定部分。
3.没有css冲突和js问题。
4.核心html/js功能
---只需添加以下代码
CSS到
@media print {
body * {
visibility: hidden; // part to hide at the time of print
-webkit-print-color-adjust: exact !important; // not necessary use
if colors not visible
}
#printBtn {
visibility: hidden !important; // To hide
}
#page-wrapper * {
visibility: visible; // Print only required part
text-align: left;
-webkit-print-color-adjust: exact !important;
}
}
Run Code Online (Sandbox Code Playgroud)
JS 代码 -在 btn 单击上调用 bewlow 函数
$scope.printWindow = function () {
window.print()
}
Run Code Online (Sandbox Code Playgroud)
注意:在每个 css 对象中使用 !important
例子 -
.legend {
background: #9DD2E2 !important;
}
Run Code Online (Sandbox Code Playgroud)
Noa*_*Noa 10
2022年答案:
要从 HTML 元素生成 PDF 并提示保存文件:
import { jsPDF } from "jsPDF"
function generatePDF() {
const doc = new jsPDF({ unit: 'pt' }) // create jsPDF object
const pdfElement = document.getElementById('pdf') // HTML element to be converted to PDF
doc.html(pdfElement, {
callback: (pdf) => {
pdf.save('MyPdfFile.pdf')
},
margin: 32, // optional: page margin
// optional: other HTMLOptions
})
}
Run Code Online (Sandbox Code Playgroud)
<button onclick="generatePDF()">Save PDF</button>
Run Code Online (Sandbox Code Playgroud)
...
要预览 PDF 而不打印:
doc.html(pdfElement, {
callback: (pdf) => {
const myPdfData = pdf.output('datauristring')
}
})
Run Code Online (Sandbox Code Playgroud)
<embed type="application/pdf" src={myPdfData} />
Run Code Online (Sandbox Code Playgroud)
...
更多 HTMLOptions:
https://github.com/parallax/jsPDF/blob/master/types/index.d.ts
如上所述,您应该使用jsPDF和html2canvas.我还在jsPDF的问题中找到了一个函数,它将你的pdf自动拆分成多个页面(源代码)
function makePDF() {
var quotes = document.getElementById('container-fluid');
html2canvas(quotes, {
onrendered: function(canvas) {
//! MAKE YOUR PDF
var pdf = new jsPDF('p', 'pt', 'letter');
for (var i = 0; i <= quotes.clientHeight/980; i++) {
//! This is all just html2canvas stuff
var srcImg = canvas;
var sX = 0;
var sY = 980*i; // start 980 pixels down for every new page
var sWidth = 900;
var sHeight = 980;
var dX = 0;
var dY = 0;
var dWidth = 900;
var dHeight = 980;
window.onePageCanvas = document.createElement("canvas");
onePageCanvas.setAttribute('width', 900);
onePageCanvas.setAttribute('height', 980);
var ctx = onePageCanvas.getContext('2d');
// details on this usage of this function:
// https://developer.mozilla.org/en-US/docs/Web/API/Canvas_API/Tutorial/Using_images#Slicing
ctx.drawImage(srcImg,sX,sY,sWidth,sHeight,dX,dY,dWidth,dHeight);
// document.body.appendChild(canvas);
var canvasDataURL = onePageCanvas.toDataURL("image/png", 1.0);
var width = onePageCanvas.width;
var height = onePageCanvas.clientHeight;
//! If we're on anything other than the first page,
// add another page
if (i > 0) {
pdf.addPage(612, 791); //8.5" x 11" in pts (in*72)
}
//! now we declare that we're working on that page
pdf.setPage(i+1);
//! now we add content to that page!
pdf.addImage(canvasDataURL, 'PNG', 20, 40, (width*.62), (height*.62));
}
//! after the for loop is finished running, we save the pdf.
pdf.save('test.pdf');
}
});
}
Run Code Online (Sandbox Code Playgroud)
我使用jspdf和html2canvas进行 css 渲染,并导出特定 div 的内容,因为这是我的代码
$(document).ready(function () {
let btn=$('#c-oreder-preview');
btn.text('download');
btn.on('click',()=> {
$('#c-invoice').modal('show');
setTimeout(function () {
html2canvas(document.querySelector("#c-print")).then(canvas => {
//$("#previewBeforeDownload").html(canvas);
var imgData = canvas.toDataURL("image/jpeg",1);
var pdf = new jsPDF("p", "mm", "a4");
var pageWidth = pdf.internal.pageSize.getWidth();
var pageHeight = pdf.internal.pageSize.getHeight();
var imageWidth = canvas.width;
var imageHeight = canvas.height;
var ratio = imageWidth/imageHeight >= pageWidth/pageHeight ? pageWidth/imageWidth : pageHeight/imageHeight;
//pdf = new jsPDF(this.state.orientation, undefined, format);
pdf.addImage(imgData, 'JPEG', 0, 0, imageWidth * ratio, imageHeight * ratio);
pdf.save("invoice.pdf");
//$("#previewBeforeDownload").hide();
$('#c-invoice').modal('hide');
});
},500);
});
});
Run Code Online (Sandbox Code Playgroud)
小智 7
如果您需要特定页面的可下载pdf文件,只需添加这样的按钮
<h4 onclick="window.print();"> Print </h4>
Run Code Online (Sandbox Code Playgroud)
使用window.print()打印所有页面而不仅仅是div
(我在这里找到了 Gist以及指向html-to-pdfmake包的链接,我现在最终没有使用它。)
在npm install pdfmake
保存 Gist 之后,htmlToPdf.js
我像这样使用它:
const pdfMakeX = require('pdfmake/build/pdfmake.js');
const pdfFontsX = require('pdfmake-unicode/dist/pdfmake-unicode.js');
pdfMakeX.vfs = pdfFontsX.pdfMake.vfs;
import * as pdfMake from 'pdfmake/build/pdfmake';
import htmlToPdf from './htmlToPdf.js';
var docDef = htmlToPdf(`<b>Sample</b>`);
pdfMake.createPdf({content:docDef}).download('sample.pdf');
Run Code Online (Sandbox Code Playgroud)
评论:
pdfMake
的getBuffer()
函数获取),所有这些都来自浏览器。与我尝试过的其他解决方案相比,生成的 pdf 对这种 html 来说更好。jsPDF.fromHTML()
接受的答案中建议的结果不满意,因为该解决方案很容易被我的 HTML 中的特殊字符混淆,这些特殊字符显然被解释为一种标记并完全弄乱了生成的 PDF。jsPDF.from_html()
功能,不要与接受的答案混淆)对我来说不是一种选择,因为我希望生成的 PDF 中的文本是可粘贴的,而基于画布的解决方案生成基于位图的 PDF。 归档时间: |
|
查看次数: |
701879 次 |
最近记录: |