如何创建和显示PDF文件

分享于 

11分钟阅读

ionic

 

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

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

生成 pdf

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

所有 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  
相关文章