如何创建和显示PDF文件

分享于 

12分钟阅读

ionic

  繁體

我们将使用JavaScript库PDF.js 创建和显示PDF文件。 我将解释为什么我选择了这些库,然后我们将创建一个简单的PDF文本和表格中的。

你可以在我的Github上找到本教程的源代码。

生成 pdf

我查看了在JavaScript中生成PDF文件的3个不同库:

jsPDFpdfkitpdfmake

所有 3库都允许你通过添加页面。文本和图像以编程方式创建PDF文件。

下面是每个图书馆必须提供的简要概述。

jsPDF

基本文本样式( 字体,颜色,字体大小) 绘制基本形状( 圆形。rectangle 。三角形。直线) 将HTML呈现为 PDF,但不支持 CSS

参见 jsPDF网站例如。

pdfkit

绘制矢量图形 高级文本布局( 分栏,分页符,自定义字体等)

有关pdfkit功能的示例,请参阅文档作为生成的PDF指南

pdfmake

建立在pdfkit之上 在JSON中定义文档布局 支持表格之外的表格

参见 pdfmake游乐场示例。

我选择了 pdfmake,然后尝试了它,我很高兴能继续使用它。

显示 PDF

我以为它只在InAppBrowser上打开PDF就很简单,但不幸的是,它只在iOS上工作,而在安卓上不需要收费。 如果文件打开 inside 而不是使用 第三方 聚会应用程序,那就很好了。

我点击之后,发现了 PDF.js,它是由Mozilla制作的,它在 Firefox 中被用作默认的PDF查看器。

PDF.js 最酷的是,你可以完全自定义你希望查看器的外观,还包括一个默认查看器。

好了,这已经足够介绍了,对吧? 让我们写一些代码 !

我们要构建什么?

让我们构建一个具有按钮的应用程序,当你点击它时,将在模式对话框中生成一个发票 pdf 。

App Screenshot

为了使本教程简短明了,我们只使用一些随机的数据,使用 chance.js 。 你可以从用户输入或者服务中获得这些数据。

设置项目

首先创建一个新的ionic应用。


$ ionic start ionic-tutorial-pdf blank

接下来,我们需要安装我们将要使用的库。


$ bower install pdfmake angular-pdf chance --save

你可以看到,我们将使用角的指令。 这个指令使用 PDF.js 显示 pdf,所以我们不必自己编写所有代码。

请确保将指令以为单位插入到 app.js 。


angular.module('starter', ['ionic', 'pdf']) 

将以下行添加到 index.html:

 
 
 
 
 

 
 

 
 
 
 

创建用户界面

首先,在启动应用程序时显示的第一个视图中添加一个创建发票 button 。


 
 
 
 

PDF Tutorial

 
 

我们还将为模式对话框添加模板。

 
 

现在让我们看看的invoice.service.js 和我们将要构建的。

创建发票服务

InvoiceService 将负责创建我们的发票PDF并以Uint8Array格式返回它。 这里 array 将在控制器的后面传递,以便在 pdf.js. 中显示


angular.module('starter').factory('InvoiceService', ['$q', InvoiceService]);

function InvoiceService($q) { 
 function createPdf(invoice) {
 return $q(function(resolve, reject) {
 var dd = createDocumentDefinition(invoice);
 var pdf = pdfMake.createPdf(dd);

 pdf.getBase64(function (output) {
 resolve(base64ToUint8Array(output));
 });
 });
 }

 return {
 createPdf: createPdf
 }; 
}

function base64ToUint8Array(base64) { 
 var raw = atob(base64);
 var uint8Array = new Uint8Array(raw.length);
 for (var i = 0; i <raw.length; i++) {
 uint8Array[i] = raw.charCodeAt(i);
 }
 return uint8Array;
}

创建文档定义

文档定义只是一个大JSON对象,它定义了PDF的内容和样式。

以下是 createDocumentDefinition 函数的实现:


function createDocumentDefinition(invoice) {

 var items = invoice.Items.map(function(item) {
 return [item.Description, item.Quantity, item.Price];
 });

 var dd = {
 content: [
 { text: 'INVOICE', style: 'header'},
 { text: invoice.Date, alignment: 'right'},

 { text: 'From', style: 'subheader'},
 invoice.AddressFrom.Name,
 invoice.AddressFrom.Address,
 invoice.AddressFrom.Country, 

 { text: 'To', style: 'subheader'},
 invoice.AddressTo.Name,
 invoice.AddressTo.Address,
 invoice.AddressTo.Country, 

 { text: 'Items', style: 'subheader'},
 {
 style: 'itemsTable',
 table: {
 widths: ['*', 75, 75],
 body: [
 [ 
 { text: 'Description', style: 'itemsTableHeader' },
 { text: 'Quantity', style: 'itemsTableHeader' },
 { text: 'Price', style: 'itemsTableHeader' },
 ]
 ].concat(items)
 }
 },
 {
 style: 'totalsTable',
 table: {
 widths: ['*', 75, 75],
 body: [
 [
 '',
 'Subtotal',
 invoice.Subtotal,
 ],
 [
 '',
 'Shipping',
 invoice.Shipping,
 ],
 [
 '',
 'Total',
 invoice.Total,
 ]
 ]
 },
 layout: 'noBorders'
 },
 ],
 styles: {
 header: {
 fontSize: 20,
 bold: true,
 margin: [0, 0, 0, 10],
 alignment: 'right'
 },
 subheader: {
 fontSize: 16,
 bold: true,
 margin: [0, 20, 0, 5]
 },
 itemsTable: {
 margin: [0, 5, 0, 15]
 },
 itemsTableHeader: {
 bold: true,
 fontSize: 13,
 color: 'black'
 },
 totalsTable: {
 bold: true,
 margin: [0, 30, 0, 0]
 }
 },
 defaultStyle: {
 }
 }

 return dd;
}

可以看到,我们只是将文本的所有行添加到文档定义 content 中。 当添加文本时,我们可以完全控制文本的样式,并且可以定义 table 行和列。

我们还可以定义 styles 以便在我们的内容中引用。

如果你想在你的布局中添加不同的布局,你也可以在你的布局中复制不同的布局,并将它显示出来。

创建文档控制器

控制器负责获取虚拟数据并将它的发送到发票服务。 服务将返回 pdf,然后我们将更新 $scope.pdfUrl 值,以便 ng-pdf 指令知道要显示什么。


angular.module('starter').controller('DocumentController', ['$scope', '$ionicModal', 'InvoiceService', DocumentController]);

function DocumentController($scope, $ionicModal, InvoiceService) { 
 var vm = this;

 setDefaultsForPdfViewer($scope);

//Initialize the modal view.
 $ionicModal.fromTemplateUrl('pdf-viewer.html', {
 scope: $scope,
 animation: 'slide-in-up'
 }).then(function (modal) {
 vm.modal = modal;
 });

 vm.createInvoice = function () {
 var invoice = getDummyData();

 InvoiceService.createPdf(invoice)
. then(function(pdf) {
 var blob = new Blob([pdf], {type: 'application/pdf'});
 $scope.pdfUrl = URL.createObjectURL(blob);

//Display the modal view
 vm.modal.show();
 });
 };

//Clean up the modal view.
 $scope.$on('$destroy', function () {
 vm.modal.remove();
 });

 return vm;
} 

可以为 ng-pdf 指令设置两个默认值,比如当pdf为 loading 时应显示的文本。 below 我们也通过将它们写入控制台来处理错误,并且我们还记录了。


function setDefaultsForPdfViewer($scope) { 
 $scope.scroll = 0;
 $scope.loading = 'loading';

 $scope.onError = function (error) {
 console.error(error);
 };

 $scope.onLoad = function () {
 $scope.loading = '';
 };

 $scope.onProgress = function (progress) {
 console.log(progress);
 };
}

控制器中的最后一个函数将为我们提供虚拟数据来填充。


function getDummyData() { 
 return {
 Date: new Date().toLocaleDateString("en-IE", { year:"numeric", month:"long", day:"numeric" }),
 AddressFrom: {
 Name: chance.name(),
 Address: chance.address(),
 Country: chance.country({ full: true })
 },
 AddressTo: {
 Name: chance.name(),
 Address: chance.address(),
 Country: chance.country({ full: true })
 },
 Items: [
 { Description: 'iPhone 6S', Quantity: '1', Price: '€700' },
 { Description: 'Samsung Galaxy S6', Quantity: '2', Price: '€655' }
 ],
 Subtotal: '€2010',
 Shipping: '€6',
 Total: '€2016'
 };
}

显示 PDF

现在唯一要做的就是为浏览器编写模板。

/partials 目录中添加的文件 viewer.html 。


{{loading}}
 

pdf将显示在 上。 我现在很简单,只是显示 pdf,但是你可以添加按钮放大/放大,转到下一页。 有关如何连接这些按钮的示例,请查看文档

我们已经完成了 !

现在可以在桌面浏览器和移动设备上工作。

要在桌面浏览器上进行测试,请执行以下操作:

 
$ ionic serve

 

要在移动设备上进行测试,请执行以下操作:


$ ionic run android
$ ionic run ios

如果它不能在旧的Android设备上工作,那么应该使用 Crosswalk 。

你可以在我的Github上找到本教程的源代码。


文件  disp  PDF  ION  Ionic  文件IO  
相关文章