我们一起探索前端生成PDF

开发 前端
pdfmake默认不支持中文,需要我们自己实现。找中文的字体文件(ttf结尾的文件)这个任务就交到我们自己手里了,并且字体文件需要支持粗体和斜体,否则字体加粗和斜体属性不生效。

 巧用pdfmake。

[[400144]]

在使用层面讲如何使用pdfmake生成现有报告,从以下几方面实现:

  • 支持中文
  • 预览页面搭建
  • 封面实现和断页
  • 页眉和页脚实现
  • pdfmake显示类型
  • 如何实现内边距
  • table无法居中显示

支持中文

pdfmake默认不支持中文,需要我们自己实现。找中文的字体文件(ttf结尾的文件)这个任务就交到我们自己手里了,并且字体文件需要支持粗体和斜体,否则字体加粗和斜体属性不生效。

把我们找到的字体文件,放入pdfmake官方github目录下examples下,执行

  1. npm run build:vfs 

它会把你放入examples下的所有字体都统一打包到build文件下的vfs_fonts.js中,然后在项目中使用:

  1. import pdfmake from "pdfmake/build/pdfmake" 
  2. const pdfFonts = require('@/assets/js/vfs_fonts.js')  
  3. pdfMake.vfs = pdfFonts  
  4. pdfMake.fonts = {  
  5.     Roboto: {  
  6.         normal: 'Roboto-Regular.ttf',  
  7.         bold: 'Roboto-Medium.ttf',  
  8.         italics: 'Roboto-Italic.ttf',  
  9.         bolditalics: 'Roboto-Italic.ttf'  
  10.     },  
  11.     微软雅黑: {  
  12.         normal: '微软雅黑.ttf',  
  13.         bold: '微软雅黑-bold.ttf',  
  14.         italics: '微软雅黑-italics.ttf',  
  15.         bolditalics: '微软雅黑-bolditalics.ttf'  
  16.     }  

使用时:

  1. var docDefinition = {  
  2.     content: [ '惊天码盗' ],  
  3.     defaultStyle: {  
  4.         fontSize: 15,  
  5.         bold: true
  6.         font:"微软雅黑" 
  7.     }  
  8. }; 

预览页面搭建

pdf预览的逻辑大都是通过iframe实现,通过getDataUrl获取url地址

  1. import pdfmake from "pdfmake/build/pdfmake" 
  2. export function previewPdf(params) { 
  3.     if(!params) return ; 
  4.     const pdfDocGenerator = pdfMake.createPdf(params);    
  5.     pdfDocGenerator.getDataUrl( dataUrl=>{ 
  6.         const targetElement = document.querySelector("#iframeContainer"); 
  7.         const pdfMakeIframe = document.querySelector("#pdfMakeKey"); 
  8.         if(pdfMakeIframe){ 
  9.             pdfMakeIframe.src = dataUrl; 
  10.         }else
  11.             const iframe = document.createElement("iframe"); 
  12.             iframe.id = 'pdfMakeKey'
  13.             iframe.src = dataUrl;  
  14.             targetElement.appendChild(iframe) 
  15.         } 
  16.     }} 

封面实现和断页

pdfmake默认是没有封面这个设置,但是提供了一个设置背景的函数,可以给每个页面设置一个背景,可以是文字背景,也可以是图片背景。

  1. const docDefinition = { 
  2.     background: function( currentPage, pageSize){ 
  3.         if(currentPage === 1){ 
  4.             return { 
  5.                 iamge: "bgCoverImgUrl"
  6.                 width: pageSize.width, 
  7.                 height: pageSize.height 
  8.             } 
  9.         } 
  10.         return null
  11.     } 
  12.     content: ["惊天码盗"

这个自动断页可以说是非常的赞,省去了你复杂的计算。如果你想某一页单独放一段文案,或者在某段文案后单独开一页,pageBreak可以帮你实现。

  1.   pageOrientation: 'portrait'
  2.   content: [ 
  3.     {text: 'Text on Portrait'}, 
  4.     {text: 'Text on Landscape', pageOrientation: 'landscape', pageBreak: 'before'}, 
  5.     {text: 'Text on Landscape 2', pageOrientation: 'portrait', pageBreak: 'after'}, 
  6.     {text: 'Text on Portrait 2'}, 
  7.   ] 

页眉和页脚

页眉和页脚的实现就太方便了。

  1. const docDefinition = { 
  2.   footer: function(currentPage, pageCount) {  
  3.         return currentPage.toString() + ' of ' + pageCount;  
  4.   }, 
  5.   header: function(currentPage, pageCount, pageSize) { 
  6.     return [{ 
  7.         columns: [ 
  8.             { 
  9.                 text:  this.headerContent.left
  10.                 alignment:  'left' 
  11.             }, 
  12.             { 
  13.                 text:  this.headerContent.middle, 
  14.                 alignment:  'center' 
  15.             }, 
  16.             { 
  17.                 text:  this.headerContent.right
  18.                 alignment:  'right' 
  19.             } 
  20.             ], 
  21.  
  22.             margin: [10, 20] 
  23.         }] 
  24.   }, 
  25.   content: ["惊天码盗"
  26. }; 

可以精准定位某个页面做一些特殊的设置。

显示类型

相对于前端来说大多显示类型都已经定型了,比如表格、文本、列表、图片等。在pdfmake中一共给我们提供了这些显示类型:

text
普通文本,需要注意的就是字体,如果所提供字体不支持,所设置的属性就不显示。同时text可以嵌套。
columns
列,平铺的列元素。在pdfmake中没有块级元素的概念,如果你想平铺两个或者多个文本(比如前面icon,后面文本),colums会满足你。每列之间的距离可以通过columnGap设置。
list
跟html标签ul或ol相同。
table
表格,唯一提供内边距属性的类型。强大到可以实现任何简单的样式,相当于display:table。但是弊端也相当明显,不能垂直居中。
image/svg
图片。
stack 栈,相当于数组[]。

内边距的实现

text文本在pdfmake中是一个块级元素(css思路定义)。无法实现内边距,单个text文本独占一行。

  1. const dd = { 
  2.     content: [ 
  3.         'First paragraph'
  4.         { text:"234", background:'red',color:"#fff",fontSize:20 }, 
  5.         'Another paragraph, this time a little bit longer to make sure, this line will be divided into at least two lines' 
  6.     ] 

在pdfmake类型中只有table可以实现内边距,那么我们就可以尝试以table的方式布局,例如

  1. const dd = { 
  2.   content: [ 
  3.     { 
  4.       margin: [0, 20], 
  5.       table: { 
  6.         body: [ 
  7.           [ 
  8.             { text: 'CONTENTS', width: 'auto', fillColor: '#e7e6e6', fontSize: 26 }, 
  9.             { text: 'Padding ', fillColor: '#58ac5b', color: '#FFF', fontSize: 26 } 
  10.           ] 
  11.         ] 
  12.       }, 
  13.       layout: { 
  14.         defaultBorder: false
  15.         paddingLeft: function (i, node) { 
  16.           if (i === 0) { 
  17.             return 10 
  18.           } 
  19.           return 20 
  20.         }, 
  21.         paddingRight: function (i, node) { 
  22.           if (i === 0) { 
  23.             return 10 
  24.           } 
  25.           return 20 
  26.         }, 
  27.         paddingTop: function (i, node) { return 10 }, 
  28.         paddingBottom: function (i, node) { return 10 } 
  29.       } 
  30.     } 
  31.   ] 

效果是:

像目录这种效果也是table做出来的:

table的缺陷

看似table可以实现任何样本组合,但是在单元格垂直居中这块,卡住了。

  1.   // style: 'tableExample'
  2.   table: { 
  3.     body: [ 
  4.       ['Column 1''Column 2The following table has nothing more than a body array,The following table has nothing more than a body array,The following table has nothing more than a body array,The following table has nothing more than a body array''Column 3'], 
  5.       ['One value goes here''Another one here''OK?'
  6.     ] 
  7.   } 

其他

目前发现不完美的一点,就是table单元格垂直居中,除了这一点,table很灵活,可以实现多级表头,嵌套表格,合并单元格,灵活定制各个单元格边框线条宽度和颜色。

同时还具备水印、加密、二维码生成、内外链接、目录生成。相比jspdf帮我们节省了很多步骤。那么我们下期聊聊jsPdf。

本文转载自微信公众号「惊天码盗」,可以通过以下二维码关注。转载本文请联系惊天码盗公众号。

 

责任编辑:武晓燕 来源: 惊天码盗
相关推荐

2024-06-07 14:54:55

2022-02-02 21:17:19

Eslint字段配置

2023-11-03 12:54:00

KAFKA探索中间件

2023-11-29 09:04:00

前端接口

2022-03-31 18:59:43

数据库InnoDBMySQL

2023-08-04 08:20:56

DockerfileDocker工具

2021-08-27 07:06:09

DubboDocker技术

2022-10-18 07:33:57

Maven构建工具

2023-08-10 08:28:46

网络编程通信

2023-06-30 08:18:51

敏捷开发模式

2021-01-12 05:08:49

DHCP协议模型

2022-05-24 08:21:16

数据安全API

2023-09-10 21:42:31

2024-02-20 21:34:16

循环GolangGo

2021-08-27 07:06:10

IOJava抽象

2022-01-17 06:59:40

Grep指令linux

2021-07-28 07:53:20

Github ActiDotnet 应用

2022-03-08 17:52:58

TCP格式IP

2021-12-29 08:27:05

ByteBuffer磁盘服务器

2024-07-05 18:00:55

点赞
收藏

51CTO技术栈公众号