巧用pdfmake。
在使用层面讲如何使用pdfmake生成现有报告,从以下几方面实现:
- 支持中文
- 预览页面搭建
- 封面实现和断页
- 页眉和页脚实现
- pdfmake显示类型
- 如何实现内边距
- table无法居中显示
支持中文
pdfmake默认不支持中文,需要我们自己实现。找中文的字体文件(ttf结尾的文件)这个任务就交到我们自己手里了,并且字体文件需要支持粗体和斜体,否则字体加粗和斜体属性不生效。
把我们找到的字体文件,放入pdfmake官方github目录下examples下,执行
- npm run build:vfs
它会把你放入examples下的所有字体都统一打包到build文件下的vfs_fonts.js中,然后在项目中使用:
- import pdfmake from "pdfmake/build/pdfmake"
- const pdfFonts = require('@/assets/js/vfs_fonts.js')
- pdfMake.vfs = pdfFonts
- pdfMake.fonts = {
- Roboto: {
- normal: 'Roboto-Regular.ttf',
- bold: 'Roboto-Medium.ttf',
- italics: 'Roboto-Italic.ttf',
- bolditalics: 'Roboto-Italic.ttf'
- },
- 微软雅黑: {
- normal: '微软雅黑.ttf',
- bold: '微软雅黑-bold.ttf',
- italics: '微软雅黑-italics.ttf',
- bolditalics: '微软雅黑-bolditalics.ttf'
- }
- }
使用时:
- var docDefinition = {
- content: [ '惊天码盗' ],
- defaultStyle: {
- fontSize: 15,
- bold: true,
- font:"微软雅黑"
- }
- };
预览页面搭建
pdf预览的逻辑大都是通过iframe实现,通过getDataUrl获取url地址
- import pdfmake from "pdfmake/build/pdfmake"
- export function previewPdf(params) {
- if(!params) return ;
- const pdfDocGenerator = pdfMake.createPdf(params);
- pdfDocGenerator.getDataUrl( dataUrl=>{
- const targetElement = document.querySelector("#iframeContainer");
- const pdfMakeIframe = document.querySelector("#pdfMakeKey");
- if(pdfMakeIframe){
- pdfMakeIframe.src = dataUrl;
- }else{
- const iframe = document.createElement("iframe");
- iframe.id = 'pdfMakeKey';
- iframe.src = dataUrl;
- targetElement.appendChild(iframe)
- }
- }}
封面实现和断页
pdfmake默认是没有封面这个设置,但是提供了一个设置背景的函数,可以给每个页面设置一个背景,可以是文字背景,也可以是图片背景。
- const docDefinition = {
- background: function( currentPage, pageSize){
- if(currentPage === 1){
- return {
- iamge: "bgCoverImgUrl",
- width: pageSize.width,
- height: pageSize.height
- }
- }
- return null;
- }
- content: ["惊天码盗"]
- }
这个自动断页可以说是非常的赞,省去了你复杂的计算。如果你想某一页单独放一段文案,或者在某段文案后单独开一页,pageBreak可以帮你实现。
- {
- pageOrientation: 'portrait',
- content: [
- {text: 'Text on Portrait'},
- {text: 'Text on Landscape', pageOrientation: 'landscape', pageBreak: 'before'},
- {text: 'Text on Landscape 2', pageOrientation: 'portrait', pageBreak: 'after'},
- {text: 'Text on Portrait 2'},
- ]
- }
页眉和页脚
页眉和页脚的实现就太方便了。
- const docDefinition = {
- footer: function(currentPage, pageCount) {
- return currentPage.toString() + ' of ' + pageCount;
- },
- header: function(currentPage, pageCount, pageSize) {
- return [{
- columns: [
- {
- text: this.headerContent.left,
- alignment: 'left'
- },
- {
- text: this.headerContent.middle,
- alignment: 'center'
- },
- {
- text: this.headerContent.right,
- alignment: 'right'
- }
- ],
- margin: [10, 20]
- }]
- },
- content: ["惊天码盗"]
- };
可以精准定位某个页面做一些特殊的设置。
显示类型
相对于前端来说大多显示类型都已经定型了,比如表格、文本、列表、图片等。在pdfmake中一共给我们提供了这些显示类型:
text |
普通文本,需要注意的就是字体,如果所提供字体不支持,所设置的属性就不显示。同时text可以嵌套。 |
columns |
列,平铺的列元素。在pdfmake中没有块级元素的概念,如果你想平铺两个或者多个文本(比如前面icon,后面文本),colums会满足你。每列之间的距离可以通过columnGap设置。 |
list |
跟html标签ul或ol相同。 |
table |
表格,唯一提供内边距属性的类型。强大到可以实现任何简单的样式,相当于display:table。但是弊端也相当明显,不能垂直居中。 |
image/svg |
图片。 |
stack | 栈,相当于数组[]。 |
内边距的实现
text文本在pdfmake中是一个块级元素(css思路定义)。无法实现内边距,单个text文本独占一行。
- const dd = {
- content: [
- 'First paragraph',
- { text:"234", background:'red',color:"#fff",fontSize:20 },
- 'Another paragraph, this time a little bit longer to make sure, this line will be divided into at least two lines'
- ]
- }
在pdfmake类型中只有table可以实现内边距,那么我们就可以尝试以table的方式布局,例如
- const dd = {
- content: [
- {
- margin: [0, 20],
- table: {
- body: [
- [
- { text: 'CONTENTS', width: 'auto', fillColor: '#e7e6e6', fontSize: 26 },
- { text: 'Padding ', fillColor: '#58ac5b', color: '#FFF', fontSize: 26 }
- ]
- ]
- },
- layout: {
- defaultBorder: false,
- paddingLeft: function (i, node) {
- if (i === 0) {
- return 10
- }
- return 20
- },
- paddingRight: function (i, node) {
- if (i === 0) {
- return 10
- }
- return 20
- },
- paddingTop: function (i, node) { return 10 },
- paddingBottom: function (i, node) { return 10 }
- }
- }
- ]
- }
效果是:
像目录这种效果也是table做出来的:
table的缺陷
看似table可以实现任何样本组合,但是在单元格垂直居中这块,卡住了。
- {
- // style: 'tableExample',
- table: {
- body: [
- ['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'],
- ['One value goes here', 'Another one here', 'OK?']
- ]
- }
- }
其他
目前发现不完美的一点,就是table单元格垂直居中,除了这一点,table很灵活,可以实现多级表头,嵌套表格,合并单元格,灵活定制各个单元格边框线条宽度和颜色。
同时还具备水印、加密、二维码生成、内外链接、目录生成。相比jspdf帮我们节省了很多步骤。那么我们下期聊聊jsPdf。
本文转载自微信公众号「惊天码盗」,可以通过以下二维码关注。转载本文请联系惊天码盗公众号。