如何使用AngularJS动态加载数据生成PDF?

时间:2017-03-03 16:38:45

标签: javascript html css angularjs pdf

我创建了一个类似ERP的系统,使用Node.JS作为后端,AngularJS作为前端。我需要打印发票。所以我需要以PDF格式下载发票。我已经使用bootstrap 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">

有什么建议吗?请提供示例代码或类似的代码。真的坚持了一段时间,完全没有解决方案。

2 个答案:

答案 0 :(得分:0)

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

它使用包:@patch('sys.exit') @patch('myproject.common.helper.jsonschema.Draft4Validator') @patch('builtins.open') def test_validate_json_specifications(mock_file_open, draft_4_validator_mock, exit_mock): with pytest.raises(ValidationError): mock_file_open.return_value = {} draft_4_validator_mock = Mock() draft_4_validator_mock.side_effect = ValidationError validate_json_specifications('foo_path_to_data', 'foo_json_file_path', {}) assert draft_4_validator_mock.call_count == 1 assert draft_4_validator_mock.validate.assert_called_with({}) assert exit_mock.call_count == 1 html-pdf作为基础 祝你好运!

答案 1 :(得分:0)

以下解决方案将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函数并将pdfs保存到AWS上的S3存储桶中。

最重要的是,如果您不熟悉AWS,则每月可以免费执行40万次lambda执行。