【问题标题】:How to generate PDF from dynamically loading data with AngularJS?如何使用AngularJS从动态加载数据中生成PDF?
【发布时间】:2017-07-23 20:58:11
【问题描述】:

我创建了一个类似 ERP 的系统,使用 Node.JS 作为后端,AngularJS 作为前端。我需要打印发票。所以我需要以 PDF 格式下载发票。我用引导 CSS 设计了整个 Invoice,格式很好。我有一个解决方案来打印它。这是代码。

$scope.downloadQuotation = function () {
        html2canvas(document.getElementById('printQuotation'), {
            onrendered: function (canvas) {
                var data = canvas.toDataURL();
                var docDefinition = {
                    content: [{
                        image: data,
                        width: 540
                    }]
                };
                pdfMake.createPdf(docDefinition).download("Quotation_'" + $scope.selectedQuotation.id + "'.pdf");
            }
        });
    };

我正在使用 'html2canvas' 和 pdfMake 来生成此 PDF。 'printQuotation' 是该 HTML 发票的 div 名称。有一个项目表加载了动态数据和一些其他信息。只是普通发票。

此解决方案有时可以正常工作。但是当显示尺寸改变时,我只得到一个空白的 PDF。问题是如果发票不适合在用户的机器(笔记本电脑)上显示,我们会​​得到一个空白的 PDF。所以请帮我解决这个问题。

实际上我不需要这种方式。任何解决方案。客户端或服务器端。我的服务器是 NodeJs,我看到了很多解决方案并尝试过。但不为我工作。这是我需要转换为 PDF 的 HTML 页面。

<div class="widgets">
<button class="btn btn-success" ng-click="printQuotation()">Print Quotation</button>
<button class="btn btn-info" ng-click="downloadQuotation()">Download Quotation</button>
<a class="btn btn-warning" href="#/quotation/add">Create New Quotation</a>
<a class="btn btn-primary" href="#/quotation/view">Back to View All</a>
<br><br>
<div class="row" ba-panel id="printQuotation">
    <div style="min-width: 871px;overflow-x: scroll">
        <div class="">
            <hr>
            <div class="row">
                <div class="col-lg-6">
                    <p style="font-size: 18px;"><b>Quotation No : {{selectedQuotation.id}}</b></p>
                </div>
                <div class="col-lg-6" style="text-align: right">
                    <p style="font-size: 18px;"><b>Date : {{selectedQuotation.date | date:'yyyy-MM-dd'}}</b></p>
                </div>
            </div>
            <div class="row">
                <div class="col-lg-6">
                    <p style="font-size: 18px;"><b>Mr / Messrs : {{selectedQuotation.customer_name}}</b></p>
                    <p style="font-size: 18px;">We have pleasure in submitting our offer for the following items
                        :</p>
                </div>
            </div>
            <div class="row">
                <div class="col-lg-6">
                    <p style="font-size: 18px;"><b>Pump No : : {{selectedQuotation.pump_no}}</b></p>
                </div>
            </div>
            <div class="row">
                <div class="col-lg-6">
                    <p style="font-size: 18px;"><b>Se No : {{selectedQuotation.se_no}}</b></p>
                </div>
                <div class="col-lg-6" style="text-align: right">
                    <p style="font-size: 18px;"><b>Type : {{selectedQuotation.type}}</b></p>
                </div>
            </div>
            <br><br>
            <table class="table table-hover">
                <thead>
                <tr class="black-muted-bg">
                    <th style="font-size: 18px;">ID</th>
                    <th style="font-size: 18px;">Description</th>
                    <th style="font-size: 18px;">Qty</th>
                    <th style="font-size: 18px;">Unit Rate (R.O)</th>
                    <th style="font-size: 18px;">Amount (R.O)</th>
                </tr>
                </thead>
                <tbody>
                <tr ng-repeat="item in selectedQuotationItems" class="no-top-border">
                    <td style="font-size: 18px;">{{item.item_id}}</td>
                    <td style="font-size: 18px;">{{item.item_name}}</td>
                    <td style="font-size: 18px;">{{item.qty}}</td>
                    <td style="font-size: 18px;">{{item.unit_rate | currency:"":2}}</td>
                    <td style="font-size: 18px;">{{item.qty * item.unit_rate | currency:"":2}}</td>
                </tr>
                </tbody>
            </table>
            <hr>
            <div class="row">
                <div class="col-lg-6">
                    <p style="font-size: 18px;"><b>Note : {{selectedQuotation.remark}}</b></p>
                </div>
                <div class="col-lg-6" style="text-align: right">
                    <p style="font-size: 18px;"><b>Total Amount : {{selectedQuotation.total_amount |
                        currency:"":2}}</b></p>
                </div>
            </div>
            <div class="row">
                <div class="col-lg-6">

                </div>
                <div class="col-lg-6" style="text-align: right">
                    <p style="font-size: 18px;"><b>Discount : {{selectedQuotation.discount | currency:"":2}}</b></p>
                </div>
            </div>
            <div class="row">
                <div class="col-lg-6">

                </div>
                <div class="col-lg-6" style="text-align: right">
                    <p style="font-size: 18px;"><b>Net Amount : {{selectedQuotation.net_amount | currency:"":2}}</b>
                    </p>
                </div>
            </div>
            <hr>
            <div class="row">
                <div class="col-lg-6">
                    <h3>PATROL INJECTOR SERVICES</h3>
                    <P style="font-size: 18px;">Specialist in all kinds of Diesel lnjection Pump & lnjectors</P>
                    <br>
                    <p>Prepared by : ................................</p>
                </div>
                <div class="col-lg-6" style="text-align: right">
                    <h3>For MUSCAT DIESEL PUMP SERVICES</h3>
                    <br>
                    <p style="font-size: 18px;">Authorized by : ................................</p>
                </div>
            </div>
        </div>
    </div>
</div>
<button class="btn btn-success" ng-click="printQuotation()">Print Quotation</button>
<button class="btn btn-info" ng-click="downloadQuotation()">Download Quotation</button>
<a class="btn btn-warning" href="#/quotation/add">Create New Quotation</a>
<a class="btn btn-primary" href="#/quotation/view">Back to View All</a>

检查下面的 div。我需要将该 div 中的所有内容转换为 PDF。

<div class="row" ba-panel id="printQuotation">

有什么建议吗?请提供示例代码或类似的东西。确实卡了一段时间,根本没有解决办法。

【问题讨论】:

  • 你试过PDFKit吗?不要依赖客户端生成 PDF。从服务器端执行此操作
  • 我试过了兄弟。不好。我只是按照一些例子。可以给我发一份更好的吗?
  • @harish2704 是否可以从服务器获取数据并在 PDFKit 中显示为表格?我需要创建/生成完整的发票。这可能吗?
  • 据我所知,PDFKit 是最好的选择。如果您可以分享您尝试过的示例,我可以检查
  • @harish2704 嗨,我只想创建这个。 faceinfotech.com/ReportDemo.pdf 请检查这个并让我知道一种可能的方法来做到这一点。在顶部,我们必须为他们的信头和徽标留出 3 英寸。有两种格式。他们有预先印好的文件。所有数据都通过 MySQL 数据库和项目表加载

标签: javascript html css angularjs pdf


【解决方案1】:

我在 GitHub 上为你制作了一个原型,你可以在这里找到: https://github.com/Geexteam/proto-node-pdf

它使用包:html-pdfhandlebars 作为基础。
祝你好运!

【讨论】:

  • 非常感谢 :) 我会试试这个并告诉你。你真好。
  • 您的解决方案有效。我只需要做一些小改动。通过 for 循环加载项目。像那样。 :) 非常感谢。
  • 无论如何我们可以使用 Jade 做到这一点吗?我的意思是在 Jade 中创建模板并填充所有字段和表格?
【解决方案2】:

以下解决方案使用 AWS lambda 和带有 NodeJS 的无服务器框架。

有一个名为 serverless-chrome 的 github 库与您正在寻找的功能很接近。

它适用于 AWS lambda 和 nodejs。它使用无服务器 chrome 访问您的网站并截取屏幕截图或将整个网站保存为 PDF 文件并显示 PDF 文件。部署非常简单,并且使用了无服务器框架。我在客户的 AWS 账户上部署了 github 库。

这是部署后获得的演示链接。

https://1wphj1kzch.execute-api.ap-southeast-1.amazonaws.com/dev/pdf?url=http://www.gmail.com

http://www.gmail.com 替换为您选择的网站链接。它等待网站完全加载,然后截取屏幕截图。您可以部署它并使用上面生成的链接截取屏幕截图并保存它们,或者您可以使用另一个 lambda 函数并将 pdf 保存到 AWS 上的 S3 存储桶中。

如果您是 AWS 新手,那么您每月可以免费获得 400,000 次 lambda 执行。

【讨论】:

    猜你喜欢
    • 2019-10-10
    • 2015-04-18
    • 2011-12-18
    • 1970-01-01
    • 2015-12-23
    • 2011-04-21
    • 1970-01-01
    • 1970-01-01
    • 2013-04-13
    相关资源
    最近更新 更多