pdfMake中文文档(机器翻译)

*引用自2018.12.27版本的github README.md, 但现在是29号了,作者update了一个非常清晰的文档,不过还是把老版本放出来让大家看看吧。

pdfMake

同步滚动:关

pdfmake ![Build Status] [travis_img] ![GitHub] [github_img] ![npm] [npm_img] ![Bower] [bower_img] ![Packagist] [packagist_img] ![CDNJS] [cdnjs_img]

客户端/服务器端使用纯JavaScript进行PDF打印

看看游乐场和例子。

特征

  • 换行,
  • 文本对齐(左,右,居中,对齐),
  • 编号和项目符号列表,
  • 表和列
    • 自动/固定/星号宽度,
    • col-spans和row-span,
    • 在分页时自动重复标题,
  • 图像和矢量图形,
  • 方便的造型和风格继承,
  • 页眉和页脚:
    • 静态或动态内容,
    • 访问当前页码和页数,
  • 背景层,
  • 页面尺寸和方向,
  • 利润,
  • 自定义分页符,
  • 字体嵌入,
  • 支持复杂的多级(嵌套)结构,
  • 目录,
  • 打开/打印/下载生成的PDF的辅助方法,
  • 设置PDF元数据(例如作者,主题)。

入门

本文档将向您介绍pdfmake的基础知识,并向您展示如何在浏览器中创建PDF文件。如果您对服务器端打印感兴趣,请查看示例文件夹。

要从默认配置开始,您应该包含两个文件:

  • pdfmake.min.js
  • vfs_fonts.js - 默认字体定义(它包含Roboto,但您可以使用自定义字体)



  
  my first pdfmake example
  
  


...

您可以使用npm(服务器端和客户端)获取这两个文件:

npm install pdfmake

  • 用于服务器端 require('pdfmake');
  • 供客户端使用require('pdfmake/build/pdfmake.js');require('pdfmake/build/vfs_fonts.js');

或凉亭(客户端):

bower install pdfmake

或者直接从存储库中的构建目录中复制它们。否则,您始终可以从源构建它。

支持的浏览器

看问题。

文档定义对象

pdfmake遵循声明性方法。这基本上意味着,你永远不会有手动计算位置,或者使用命令,如:writeText(text, x, y)moveDown等等,你将与其他很多图书馆。

要掌握的最基本的概念是文档定义对象,它可以简单到:

var docDefinition = { content: 'This is an sample PDF printed with pdfMake' };

或变得相当复杂(具有多级表,图像,列表,段落,边距,样式等...)。

只要您拥有document-definition-object,就可以创建并下载/打开/打印PDF了:

pdfMake.createPdf(docDefinition).download();

pdfMake.createPdf(docDefinition).open();

pdfMake.createPdf(docDefinition).print();

详见下一章。

下载PDF

pdfMake.createPdf(docDefinition).download();

参数:

  • defaultFileName (可选) - 文件名
  • cb (可选) - 回调函数
  • options (可选的)

在新窗口中打开PDF

pdfMake.createPdf(docDefinition).open();

参数:

  • options (可选的)
  • win (可选) - 窗口(异步操作时)

只能使用元数据title属性定义名称(请参阅文档元数据)。

异步示例:

$scope.generatePdf = function() {
  // create the window before the callback
  var win = window.open('', '_blank');
  $http.post('/someUrl', data).then(function(response) {
    // pass the "win" argument
    pdfMake.createPdf(docDefinition).open({}, win);
  });
};

在同一个窗口中打开:

pdfMake.createPdf(docDefinition).open({}, window);

打印PDF

pdfMake.createPdf(docDefinition).print();

参数:

  • options (可选的)
  • win (可选) - 窗口(异步操作时)

异步示例:

$scope.generatePdf = function() {
  // create the window before the callback
  var win = window.open('', '_blank');
  $http.post('/someUrl', data).then(function(response) {
    // pass the "win" argument
    pdfMake.createPdf(docDefinition).print({}, win);
  });
};

在同一窗口打印:

pdfMake.createPdf(docDefinition).print({}, window);

将PDF作为URL数据放入您自己的页面

const pdfDocGenerator = pdfMake.createPdf(docDefinition);
pdfDocGenerator.getDataUrl((dataUrl) => {
    const targetElement = document.querySelector('#iframeContainer');
    const iframe = document.createElement('iframe');
    iframe.src = dataUrl;
    targetElement.appendChild(iframe);
});

参数:

  • cb - 回调函数
  • options (可选的)

获取PDF作为base64数据

const pdfDocGenerator = pdfMake.createPdf(docDefinition);
pdfDocGenerator.getBase64((data) => {
    alert(data);
});

参数:

  • cb - 回调函数
  • options (可选的)

获取PDF作为缓冲区

const pdfDocGenerator = pdfMake.createPdf(docDefinition);
pdfDocGenerator.getBuffer((buffer) => {
    // ...
});

参数:

  • cb - 回调函数
  • options (可选的)

获取PDF格式的Blob

const pdfDocGenerator = pdfMake.createPdf(docDefinition);
pdfDocGenerator.getBlob((blob) => {
    // ...
});

参数:

  • cb - 回调函数
  • options (可选的)

使用javascript框架

var pdfMake = require('pdfmake/build/pdfmake.js');
var pdfFonts = require('pdfmake/build/vfs_fonts.js');
pdfMake.vfs = pdfFonts.pdfMake.vfs;

要么

import pdfMake from "pdfmake/build/pdfmake";
import pdfFonts from "pdfmake/build/vfs_fonts";
pdfMake.vfs = pdfFonts.pdfMake.vfs;

对于Ionic和Angular,请参阅问题。

如果抛出了无法读取未定义错误的属性“TYPED_ARRAY_SUPPORT”,请将其添加到webpack配置:

exclude: [ /node_modules/, /pdfmake.js$/ ]

(见问题)

单位

所有数字均以点(pt)为单位(有时标记为PDF / PostScript点)。

服务器端

查看示例和dev-playground服务器脚本

造型

pdfmake可以设置任何段落或其部分的样式:

var docDefinition = {
  content: [
    // if you don't need styles, you can use a simple string to define a paragraph
    'This is a standard paragraph, using default style',

    // using a { text: '...' } object lets you set styling properties
    { text: 'This paragraph will have a bigger font', fontSize: 15 },

    // if you set the value of text to an array instead of a string, you'll be able
    // to style any part individually
    {
      text: [
        'This paragraph is defined as an array of elements to make it possible to ',
        { text: 'restyle part of it and make it bigger ', fontSize: 15 },
        'than the rest.'
      ]
    }
  ]
};

风格词典

也可以定义可重用样式的字典:

var docDefinition = {
  content: [
    { text: 'This is a header', style: 'header' },
    'No styling here, this is a standard paragraph',
    { text: 'Another text', style: 'anotherStyle' },
    { text: 'Multiple styles applied', style: [ 'header', 'anotherStyle' ] }
  ],

  styles: {
    header: {
      fontSize: 22,
      bold: true
    },
    anotherStyle: {
      italics: true,
      alignment: 'right'
    }
  }
};

要更深入地了解pdfmake中的样式,样式继承和本地样式覆盖,请在操场中检查STYLES1,STYLES2和STYLES3示例。

默认样式

并且还可以定义默认样式:

var docDefinition = {
  content: [
    'Text styled by default style'
  ],

  defaultStyle: {
    fontSize: 15,
    bold: true
  }
};

默认情况下,段落呈现为垂直堆栈元素(一个在另一个下面)。但是,可以将可用空间划分为列。

var docDefinition = {
  content: [
    'This paragraph fills full width, as there are no columns. Next paragraph however consists of three columns',
    {
      columns: [
        {
          // auto-sized columns have their widths based on their content
          width: 'auto',
          text: 'First column'
        },
        {
          // star-sized columns fill the remaining space
          // if there's more than one star-column, available width is divided equally
          width: '*',
          text: 'Second column'
        },
        {
          // fixed width
          width: 100,
          text: 'Third column'
        },
        {
          // % width
          width: '20%',
          text: 'Fourth column'
        }
      ],
      // optional space between columns
      columnGap: 10
    },
    'This paragraph goes below all columns and has full width'
  ]
};

列内容不限于简单文本。它实际上可以包含任何有效的pdfmake元素。一定要查看游乐场中的COLUMNS示例。

从概念上讲,表与列类似。但是,它们可以具有跨越多个列/行的标题,边框和单元格。

var docDefinition = {
  content: [
    {
      layout: 'lightHorizontalLines', // optional
      table: {
        // headers are automatically repeated if the table spans over multiple pages
        // you can declare how many rows should be treated as headers
        headerRows: 1,
        widths: [ '*', 'auto', 100, '*' ],

        body: [
          [ 'First', 'Second', 'Third', 'The last one' ],
          [ 'Value 1', 'Value 2', 'Value 3', 'Value 4' ],
          [ { text: 'Bold value', bold: true }, 'Val 2', 'Val 3', 'Val 4' ]
        ]
      }
    }
  ]
};

自己的表格布局

必须在调用之前定义自己的表布局pdfMake.createPdf(docDefinition)

pdfMake.tableLayouts = {
  exampleLayout: {
    hLineWidth: function (i, node) {
      if (i === 0 || i === node.table.body.length) {
        return 0;
      }
      return (i === node.table.headerRows) ? 2 : 1;
    },
    vLineWidth: function (i) {
      return 0;
    },
    hLineColor: function (i) {
      return i === 1 ? 'black' : '#aaa';
    },
    paddingLeft: function (i) {
      return i === 0 ? 0 : 8;
    },
    paddingRight: function (i, node) {
      return (i === node.table.widths.length - 1) ? 0 : 8;
    }
  }
};

// download the PDF
pdfMake.createPdf(docDefinition).download();

或者,您可以直接传递tableLayouts createPdf而不更改全局值:

pdfMake.createPdf(docDefinition, tableLayouts).download();

// The full signature of createPdf looks like this.
// tableLayouts, fonts and vfs are all optional - falsy values will cause
// pdfMake.tableLayouts, pdfMake.fonts or pdfMake.vfs to be used.
pdfMake.createPdf(docDefinition, tableLayouts, fonts, vfs)

所有与表相关的概念都包含在操场上的TABLES示例中。

清单

pdfMake支持编号和项目符号列表:

var docDefinition = {
  content: [
    'Bulleted list example:',
    {
      // to treat a paragraph as a bulleted list, set an array of items under the ul key
      ul: [
        'Item 1',
        'Item 2',
        'Item 3',
        { text: 'Item 4', bold: true },
      ]
    },

    'Numbered list example:',
    {
      // for numbered lists set the ol key
      ol: [
        'Item 1',
        'Item 2',
        'Item 3'
      ]
    }
  ]
};

页眉和页脚

pdfmake中的页眉和页脚可以是:静态动态

他们使用相同的语法:

var docDefinition = {
  header: 'simple text',

  footer: {
    columns: [
      'Left part',
      { text: 'Right part', alignment: 'right' }
    ]
  },

  content: (...)
};

对于动态生成的内容(包括页码,页数和页面大小),您可以将函数传递给页眉或页脚:

var docDefinition = {
  footer: function(currentPage, pageCount) { return currentPage.toString() + ' of ' + pageCount; },
  header: function(currentPage, pageCount, pageSize) {
    // you can apply any logic and return any valid pdfmake element

    return [
      { text: 'simple text', alignment: (currentPage % 2) ? 'left' : 'right' },
      { canvas: [ { type: 'rect', x: 170, y: 32, w: pageSize.width - 170, h: 40 } ] }
    ]
  },
  (...)
};

背景层

背景图层将添加到每个页面上。

var docDefinition = {
  background: 'simple text',

  content: (...)
};

它也可以包含任何其他对象(图像,表格,......)或动态生成:

var docDefinition = {
  background: function(currentPage, pageSize) {
    return `page ${currentPage} with size ${pageSize.width} x ${pageSize.height}`
  },

  content: (...)
};

边距

pdfMake中的任何元素都可以有一个余量:

(...)
// margin: [left, top, right, bottom]
{ text: 'sample', margin: [ 5, 2, 10, 20 ] },

// margin: [horizontal, vertical]
{ text: 'another text', margin: [5, 2] },

// margin: equalLeftTopRightBottom
{ text: 'last one', margin: 5 }
(...)

堆栈的段落

你现在可能已经想到了(从例子中),如果你将content键设置为一个数组,那么文档就会变成一堆段落。

您经常会在嵌套元素中重用此结构,如下例所示:

var docDefinition = {
  content: [
    'paragraph 1',
    'paragraph 2',
    {
      columns: [
        'first column is a simple text',
        [
          // second column consists of paragraphs
          'paragraph A',
          'paragraph B',
          'these paragraphs will be rendered one below another inside the column'
        ]
      ]
    }
  ]
};

数组的问题是您无法向其添加样式属性(例如,更改fontSize)。

好消息是 - array只是pdfMake for {stack:[]}的一个快捷方式,所以如果你想重新整理整个堆栈,你可以使用扩展定义:

var docDefinition = {
  content: [
    'paragraph 1',
    'paragraph 2',
    {
      columns: [
        'first column is a simple text',
        {
          stack: [
            // second column consists of paragraphs
            'paragraph A',
            'paragraph B',
            'these paragraphs will be rendered one below another inside the column'
          ],
          fontSize: 15
        }
      ]
    }
  ]
};

图片

这很简单。只需使用{ image: '...' }节点类型。

支持JPEG和PNG格式。

var docDefinition = {
  content: [
    {
      // you'll most often use dataURI images on the browser side
      // if no width/height/fit is provided, the original size will be used
      image: 'data:image/jpeg;base64,...encodedContent...'
    },
    {
      // if you specify width, image will scale proportionally
      image: 'data:image/jpeg;base64,...encodedContent...',
      width: 150
    },
    {
      // if you specify both width and height - image will be stretched
      image: 'data:image/jpeg;base64,...encodedContent...',
      width: 150,
      height: 150
    },
    {
      // you can also fit the image inside a rectangle
      image: 'data:image/jpeg;base64,...encodedContent...',
      fit: [100, 100]
    },
    {
      // if you reuse the same image in multiple nodes,
      // you should put it to to images dictionary and reference it by name
      image: 'mySuperImage'
    },
    {
      // under NodeJS (or in case you use virtual file system provided by pdfmake)
      // you can also pass file names here
      image: 'myImageDictionary/image1.jpg'
    }
  ],

  images: {
    mySuperImage: 'data:image/jpeg;base64,...content...'
  }
};

链接

要添加外部或内部链接,请使用以下语法:

{text: 'google', link: 'http://google.com'}
{text:'Go to page 2', linkToPage: 2}

目录

var docDefinition = {
  content: [
    {
      toc: {
        // id: 'mainToc'  // optional
        title: {text: 'INDEX', style: 'header'}
      }
    },
    {
      text: 'This is a header',
      style: 'header',
      tocItem: true, // or tocItem: 'mainToc' if is used id in toc
      // or tocItem: ['mainToc', 'subToc'] for multiple tocs
    }
  ]
}

页面尺寸,方向和边距

var docDefinition = {
  // a string or { width: number, height: number }
  pageSize: 'A5',

  // by default we use portrait, you can change it to landscape if you wish
  pageOrientation: 'landscape',

  // [left, top, right, bottom] or [horizontal, vertical] or just a number for equal margins
  pageMargins: [ 40, 60, 40, 60 ],
};

如果设置pageSize为字符串,则可以使用以下值之一:

  • '4A0','2A0','A0','A1','A2','A3','A4','A5','A6','A7','A8','A9','A10 ”,
  • 'B0','B1','B2','B3','B4','B5','B6','B7','B8','B9','B10',
  • 'C0','C1','C2','C3','C4','C5','C6','C7','C8','C9','C10',
  • 'RA0','RA1','RA2','RA3','RA4',
  • 'SRA0','SRA1','SRA2','SRA3','SRA4',
  • '执行','FOLIO','法律','信','TABLOID'

要更改文档中的页面方向,请添加具有新页面方向的分页符。

{
  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'},
  ]
}

动态控制分页符,例如避免孤儿

pageBreakBefore可以指定一个函数,该函数可以确定是否应在节点之前插入分页符。要实现“无孤儿”规则,请使用如下定义:

var dd = {
    content: [
       {text: '1 Headline', headlineLevel: 1},
       'Some long text of variable length ...',
       {text: '2 Headline', headlineLevel: 1},
       'Some long text of variable length ...',
       {text: '3 Headline', headlineLevel: 1},
       'Some long text of variable length ...',
    ],
  pageBreakBefore: function(currentNode, followingNodesOnPage, nodesOnNextPage, previousNodesOnPage) {
     return currentNode.headlineLevel === 1 && followingNodesOnPage.length === 0;
  }
}

如果pageBreakBefore返回true,则会在之前添加分页符currentNode。当前节点附有以下信息:

{
   id: '',
   headlineLevel: '',
   text: '',
   ul: '',
   ol: '',
   table: '',
   image: '',
   qr: '',
   canvas: '',
   columns: '',
   style: '',
   pageOrientation '',
   pageNumbers: [2, 3], // The pages this element is visible on (e.g. multi-line text could be on more than one page)
   pages: 6, // the total number of pages of this document
   stack: false, // if this is an element which encapsulates multiple sub-objects
   startPosition: {
     pageNumber: 2, // the page this node starts on
     pageOrientation: 'landscape', // the orientation of this page
     left: 60, // the left position
     right: 60, // the right position
     verticalRatio: 0.2, // the ratio of space used vertically in this document (excluding margins)
     horizontalRatio: 0.0  // the ratio of space used horizontally in this document (excluding margins)
   }
}

文档元数据

PDF文档可以具有与其相关联的各种元数据,例如标题或
文档的作者。您可以通过将其添加到文档定义来添加该信息

var docDefinition = {
  info: {
    title: 'awesome Document',
    author: 'john doe',
    subject: 'subject of document',
    keywords: 'keywords for document',
  },
  content:  'This is an sample PDF printed with pdfMake'
}

标准属性:

  • title - 文档的标题
  • 作者 - 作者的姓名
  • 主题 - 文件的主题
  • keywords - 与文档关联的关键字
  • creator - 文档的创建者(默认为'pdfmake')
  • producer - 文档的制作者(默认为'pdfmake')
  • creationDate - 文档创建的日期(由pdfmake自动添加)
  • modDate - 上次修改文档的日期
  • 被困 - PDF文档中的被困标志表示文件是否被“困住”

自定义属性:

您可以添加自定义属性。属性键不包含空格。

压缩

默认情况下启用PDF压缩,compress: false用于禁用:

var docDefinition = {
  compress: false,

  content: (...)
};

从源头建立

使用npm:

git clone https://github.com/bpampuch/pdfmake.git
cd pdfmake
npm install
npm run build

使用纱线:

git clone https://github.com/bpampuch/pdfmake.git
cd pdfmake
yarn
yarn run build

快来了

嗯......让我知道你需要什么;)

目标非常简单 - 使pdfmake对人们的looooooooot很有用,并帮助构建具有打印支持的响应式HTML5应用程序。

v2的路线图上有一件事(但没有截止日期) - 使库可以破解,所以你可以编写插件来:

  • 扩展文档定义模型(使用{chart:...}之类的东西),
  • 添加语法翻译器(如提供的[...] - > {stack:[...]}
  • 在文档定义模型之上构建自定义DSL(目前这实际上是可行的)。

执照

MIT

作者

  • @bpampuch(创始人)
  • @ liborm85

pdfmake基于一个真正令人惊叹的图书馆pdfkit(归功于@devongovett)。

感谢所有贡献者。

你可能感兴趣的:(pdfMake中文文档(机器翻译))