使用Javascript从HTML中的div生成PDF

349

I have the following html code:

<!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>

我想做的就是将id为“pdf”的div中的内容打印成pdf格式。这必须使用JavaScript完成。然后,“pdf”文档应自动下载,文件名为“foobar.pdf”。
我一直在使用jspdf来完成这个任务,但它只有一个“text”函数,只接受字符串值。我想提交HTML给jspdf,而不是文本。

1
如上所述,我不想使用“text”函数。我想要使用HTML。您的链接仅处理纯文本而不是HTML。 - John Crawford
5
jsPDF确实有一个fromHTML函数;请参考"http://mrrio.github.io/jsPDF/"上的“HTML渲染器”示例。 - mg1075
18个回答

3
我能够将动态创建的表格从一个 div 中传递给 jsPDF 进行打印。
$(document).ready(function() {

        $("#pdfDiv").click(function() {

    var pdf = new jsPDF('p','pt','letter');
    var specialElementHandlers = {
    '#rentalListCan': function (element, renderer) {
        return true;
        }
    };

    pdf.addHTML($('#rentalListCan').first(), function() {
        pdf.save("caravan.pdf");
    });
    });
});

在Chrome和Firefox上运行良好...但在IE上格式会出现问题。

我还包含了以下内容:

<script src="js/jspdf.js"></script>
    <script src="js/jspdf.plugin.from_html.js"></script>
    <script src="js/jspdf.plugin.addhtml.js"></script>
    <script src="//mrrio.github.io/jsPDF/dist/jspdf.debug.js"></script>
    <script src="http://html2canvas.hertzen.com/build/html2canvas.js"></script>
    <script type="text/javascript" src="./libs/FileSaver.js/FileSaver.js"></script>
    <script type="text/javascript" src="./libs/Blob.js/Blob.js"></script>
    <script type="text/javascript" src="./libs/deflate.js"></script>
    <script type="text/javascript" src="./libs/adler32cs.js/adler32cs.js"></script>

    <script type="text/javascript" src="js/jspdf.plugin.addimage.js"></script>
    <script type="text/javascript" src="js/jspdf.plugin.sillysvgrenderer.js"></script>
    <script type="text/javascript" src="js/jspdf.plugin.split_text_to_size.js"></script>
    <script type="text/javascript" src="js/jspdf.plugin.standard_fonts_metrics.js"></script>

2
请您提供一个示例,说明如何传递HTML。 - Erum
但是你的代码是 <script src="http://html2canvas.hertzen.com/build/html2canvas.js"></script>,这意味着它需要互联网连接? - Erum
2
@Erum,你可以下载这个文件。 - Eduardo Cuomo

1
如果您想导出表格,可以查看Shield UI Grid小部件提供的此导出示例
通过扩展配置来完成,如下所示:
...
exportOptions: {
    proxy: "/filesaver/save",
    pdf: {
        fileName: "shieldui-export",
        author: "John Smith",
        dataSource: {
            data: gridData
        },
        readDataSource: true,
        header: {
            cells: [
                { field: "id", title: "ID", width: 50 },
                { field: "name", title: "Person Name", width: 100 },
                { field: "company", title: "Company Name", width: 100 },
                { field: "email", title: "Email Address" }
            ]
        }
    }
}
...

“导出为PDF”功能导致生成了一个空的PDF文档。” - Richard Nalezynski
可能是您端上的配置有误... 如果需要,可以使用shieldui标签发布问题。 - Vladimir Georgiev

1

以下方法对我的情况很有效。

隐藏页面的其他部分,例如以下示例。

@media print{
    body{
        -webkit-print-color-adjust: exact; // if you want to enable graphics
        color-adjust: exact !important; // if you want to enable graphics
        print-color-adjust: exact !important; // if you want to enable graphics
       
        * {
            visibility: hidden;
            margin:0;
            padding:0
        }
        .print_area, .print_area *{
            visibility: visible;
        }
        .print_area{
            margin: 0;
            align: center;
        }
        .pageBreak { 
           page-break-before : always; // If you want to skip next page
           page-break-inside: avoid;  // If you want to skip next page
         }
      }
    @page {
        size: A4; margin:0mm; // set page layout
        background-color: #fff;
    }
}

使用 JavaScript 的打印函数来打印执行结果。
<button onclick="window.print()">Print</button>

1

对于html2canvas的渲染不满意以及pdfMake过时的WebKit版本缺乏现代CSS3/JS和打印特定CSS支持,这里有一个理论解决方案,它是无头浏览器,可以忠实地渲染页面,支持分页、边距、不同的页面尺寸,并且可以自动化。您甚至可以将WebGL渲染成PDF。

您可以在chrome_devtools协议上运行printToPDF命令:

printToPDF({
  printBackground: false,
  pageWidth: 8.5,
  pageHeight: 11,
  transferMode: "ReturnAsStream" // or ReturnAsBase64
})


1
这个例子运行得非常好。
<button onclick="genPDF()">Generate PDF</button>

<script src="https://cdnjs.cloudflare.com/ajax/libs/jspdf/1.5.3/jspdf.min.js"></script>
<script>
    function genPDF() {
        var doc = new jsPDF();
        doc.text(20, 20, 'Hello world!');
        doc.text(20, 30, 'This is client-side Javascript, pumping out a PDF.');
        doc.addPage();
        doc.text(20, 20, 'Do you like that?');
    
        doc.save('Test.pdf');
    }
</script>

尽管这个答案介绍了一个 js 到 pdf 的库,但是问题是从 HTML 元素的内容创建 pdf,而不是手动使用代码创建 pdf 结构。 - 123survesh

0
要将div转换为PDF,您可以使用https://grabz.it解决方案。它具有易于使用和灵活的JavaScript API,可让您捕获单个HTML元素(如div或span)的内容。
为了实现它,您需要首先获取应用程序密钥和密钥,然后下载(免费)SDK。
现在来看一个例子。
假设您有以下HTML:
<div id="features">
    <h4>Acme Camera</h4>
    <label>Price</label>$399<br />
    <label>Rating</label>4.5 out of 5
</div>
<p>Cras ut velit sed purus porttitor aliquam. Nulla tristique magna ac libero tempor, ac vestibulum felisvulput ate. Nam ut velit eget
risus porttitor tristique at ac diam. Sed nisi risus, rutrum a metus suscipit, euismod tristique nulla. Etiam venenatis rutrum risus at
blandit. In hac habitasse platea dictumst. Suspendisse potenti. Phasellus eget vehicula felis.</p>

要捕获特征ID下的内容,您需要执行以下操作:

//add the sdk
<script type="text/javascript" src="grabzit.min.js"></script>
<script type="text/javascript">
//login with your key and secret. 
GrabzIt("KEY", "SECRET").ConvertURL("http://www.example.com/my-page.html",
{"target": "#features", "format": "pdf"}).Create();
</script>

请注意target:#feature#feature是您的CSS选择器,就像前面的示例一样。 现在,当页面加载时,将在与脚本标记相同的位置创建一个图像截图,其中包含所有功能div的内容,而不包括其他内容。

还有其他配置和自定义可以对div-screenshot机制进行,请在{{link1:此处}}查看。


-1

有人尝试过这个吗?

    (function () {  
        var  
         form = $('.form'),  
         cache_width = form.width(),  
         a4 = [595.28, 841.89]; // for a4 size paper width and height  

        $('#create_pdf').on('click', function () {  
            $('body').scrollTop(0);  
            createPDF();  
        });  
        //create pdf  
        function createPDF() {  
            getCanvas().then(function (canvas) {  
                var  
                 img = canvas.toDataURL("image/png"),  
                 doc = new jsPDF({  
                     unit: 'px',  
                     format: 'a4'  
                 });  
                doc.addImage(img, 'JPEG', 20, 20);  
                doc.save('Bhavdip-html-to-pdf.pdf');  
                form.width(cache_width);  
            });  
        }  

        // create canvas object  
        function getCanvas() {  
            form.width((a4[0] * 1.33333) - 80).css('max-width', 'none');  
            return html2canvas(form, {  
                imageTimeout: 2000,  
                removeContainer: true  
            });  
        }  

    }());  

-1

快速、简单、完成任务。

** PDF 上无可点击的文本 **

  1. 使用 html2canvasdiv 进行截图。返回一个画布元素。
  2. 使用 jsPDFcanvas 元素放在 PDF 上
const handleDownloadPDF = () => {
  const domElement = document.getElementById('print');
  if (domElement) {
    html2canvas(domElement).then((canvas) => {
      const imgData = canvas.toDataURL('image/png');
      const pdf = new JSPDF();
      pdf.addImage(imgData, 'JPEG', 0, 0, pdf.internal.pageSize.getWidth(), pdf.internal.pageSize.getHeight());
      pdf.save(`${new Date().toISOString()}.pdf`);
    });
  }
};

您如果不需要,可以随时跳过PDF部分,直接将画布下载为png或jpg格式。这不需要使用jsPDF库。
const handleDownloadPng = () => {
  const domElement = document.getElementById('print');

  html2canvas(domElement).then(canvas => {
    // Convert canvas to a PNG data URL
    const pngDataUrl = canvas.toDataURL("image/png");

    // Create a download link
    const downloadLink = document.createElement("a");
    downloadLink.href = pngDataUrl;
    downloadLink.download = "div-image.png";
    downloadLink.textContent = "Download PNG";

    // Append the link and trigger a click
    document.body.appendChild(downloadLink);
    downloadLink.click();
    document.body.removeChild(downloadLink);
  });
}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接