JavaScript >> Javascript 文檔 >  >> Node.js

使用 PDFKit 在 Node.js 中生成 PDF 文件

簡介

PDF 格式是用於傳輸信息的最常見的文檔格式之一。在動態 Web 應用程序中,您可能需要將數據導出到文檔中,而 PDF 通常是一種流行的選擇。在本文中,我們將討論如何使用 NPM 包 pdfkit 在 NodeJS 中生成 PDF 文件 .

PDFKit 是一個用於 Node.js 的 JavaScript PDF 生成庫,它提供了一種創建多頁、可打印 PDF 文檔的簡單方法。

PDFKit 入門

讓我們創建一個項目目錄,cd 進入它並使用默認設置初始化節點項目:

$ mkdir pdfkit-project
$ cd pdfkit-project
$ npm init -y

然後,讓我們 install pdfkit

$ npm install pdfkit

要在項目中使用該模塊,我們將通過 require() 導入它 :

const PDFDocument = require('pdfkit');

使用 PDFKit 創建 PDF 文檔

要創建 PDF 文檔,我們需要導入 fs (文件系統)模塊也是如此。我們將管道 把我們PDF文件的內容變成一個fs 的可寫流來保存它。讓我們看看如何做到這一點:

const PDFDocument = require('pdfkit');
const fs = require('fs');

let pdfDoc = new PDFDocument;
pdfDoc.pipe(fs.createWriteStream('SampleDocument.pdf'));
pdfDoc.text("My Sample PDF Document");
pdfDoc.end();

首先,我們導入所需的模塊,然後,我們實例化 PDFDocument .這個實例是一個可讀流。我們會將該流通過管道傳輸到可寫流中以保存文件。

如果您不熟悉流的工作原理,請查看我們的 Node.js 流簡介。

我們正在使用 pipe() 執行此操作並保存生成的 SampleDocument.pdf 的函數 進入我們的根目錄。創建後,我們可以通過 text 向其中添加內容 功能。當然,我們要end() 流到底。

當我們運行代碼時,一個名為 SampleDocument.pdf 的 PDF 文件 在我們項目的根文件夾中創建:

$ node index.js

注意: 在嘗試覆蓋現有 PDF 文件之前,它必須是免費的。即 - 必須關閉包含該 PDF 文件的所有窗口,否則程序將拋出錯誤。

格式化PDF文件中的文本

當然,pdfkit 允許我們做的不僅僅是向文檔添加無格式文本。讓我們來看看它提供的一些功能。

定位文字

默認情況下,pdfkit 模塊跟踪應該將文本添加到文檔的位置,基本上打印對 text() 的每個調用 換行。

您可以通過添加 x 來更改當前頁面中文本的打印位置 和 您希望將文本作為參數放置到 text() 的位置的坐標 功能。

例如:

pdfDoc.text("Text positioned at (200,200)", 200, 200);

這很有用,因為它允許您微調文本的位置,特別是因為 PDF 文檔具有通用外觀,而不管它們是在什麼機器/操作系統上打開的。例如,這還允許您在其他文本上打印文本:

const PDFDocument = require('pdfkit');
const fs = require('fs');

var pdfDoc = new PDFDocument;
pdfDoc.pipe(fs.createWriteStream('SampleDocument.pdf'));

pdfDoc.text("From Mon-Sat we will have a 10% discount on selected items!", 150, 150);
pdfDoc
    .fillColor('red')
    .fontSize(17)
    .text("20%", 305, 150);

pdfDoc.end();

運行這段代碼會給我們:

文本換行和對齊

pdfkit 模塊自動換行,以便它們適合邊距之間,或者在 width 提供(在列中寫入文本時)。換句話說,lineBreak 選項是 true 默認。您可以將其更改為 false 當調用 text() 功能:

pdfDoc.text("very long text ".repeat(20), { lineBreak : false });

新頁面也會根據需要自動添加,即只要您要添加的內容不適合當前頁面的全部內容。但是,您也可以在填寫上一頁之前切換到下一頁,只需調用:

pdfDoc.addPage();

至於對齊方式,pdfkit 為我們提供了常用選項 - left (默認),right , centerjustify .請注意,使用 lineBreak 設置特定的對齊方式 設置為 false 不會起作用,即使文本可以排成一行。

就像 lineBreak , align 通過將包含鍵值對的對像傳遞給 text() 來設置參數 功能。讓我們看一些對齊示例:

const PDFDocument = require('pdfkit');
const fs = require('fs');

var pdfDoc = new PDFDocument;
pdfDoc.pipe(fs.createWriteStream('text_alignment.pdf'));

pdfDoc.text("This text is left aligned", { align: 'left'})
pdfDoc.text("This text is at the center", { align: 'center'})
pdfDoc.text("This text is right aligned", { align: 'right'})
pdfDoc.text("This text needs to be slightly longer so that we can see that justification actually works as intended", { align: 'justify'})

pdfDoc.end();

運行上面的代碼會給我們一個如下所示的 PDF:

樣式文本

pdfkit 模塊還提供了可用於設置 PDF 文檔中文本樣式的選項。我們將看看一些更重要的樣式選項,您可以在 PDF 指南中找到完整的選項列表。

我們可以將不同的選項作為鍵值對傳遞給 text() 函數,並在調用 text() 之前鏈接其他幾個函數 完全沒有。

一個非常重要的要注意的是,鍊式函數,例如 fillColor() (以及後來的 font() , fontSize() 等)將影響所有 通話後的文字:

免費電子書:Git Essentials

查看我們的 Git 學習實踐指南,其中包含最佳實踐、行業認可的標準以及隨附的備忘單。停止谷歌搜索 Git 命令並真正學習 它!

const PDFDocument = require('pdfkit');
const fs = require('fs');

var pdfDoc = new PDFDocument;
pdfDoc.pipe(fs.createWriteStream('text_styling.pdf'));

pdfDoc
    .fillColor('blue')
    .text("This is a link", { link: 'https://pdfkit.org/docs/guide.pdf', underline: true });
pdfDoc
    .fillColor('black')
    .text("This text is underlined", { underline: true });
pdfDoc.text("This text is italicized", { oblique: true });
pdfDoc.text("This text is striked-through", { strike: true });

pdfDoc.end();

運行這段代碼會生成一個PDF文件,內容如下:

在段落中間更改樣式稍微複雜一些,因為鏈接多個 text() 默認情況下,函數在每個之後添加一個新行。我們可以通過設置 lineBreak 來避免這種情況 第一個 text() 的選項 調用 false

const PDFDocument = require('pdfkit');
const fs = require('fs');

var pdfDoc = new PDFDocument;
pdfDoc.pipe(fs.createWriteStream('text_styling2.pdf'));

pdfDoc
    .fillColor('blue')
    .text("This text is blue and italicized", {oblique : true, lineBreak : false})
    .fillColor('red')
    .text(" This text is red");

pdfDoc.end();

這會給我們想要的結果:

創建列表

要在 PDF 文檔中添加項目列表,PDFDocument 實例有一個 list() 接收字符串項數組(或字符串嵌套數組)並將它們顯示為項目符號列表的函數:

const PDFDocument = require('pdfkit');
const fs = require('fs');

let pdfDoc = new PDFDocument;
pdfDoc.pipe(fs.createWriteStream('lists.pdf'));

let myArrayOfItems = ['Item 1', 'Item 2', 'Item 3', 'Item 4'];

pdfDoc.list(myArrayOfItems);
// Move down a bit to provide space between lists
pdfDoc.moveDown(0.5);

let innerList = ['Nested Item 1', 'Nested Item 2'];
let nestedArrayOfItems = ['Example of a nested list', innerList];

pdfDoc.list(nestedArrayOfItems);

pdfDoc.end();

這給了我們:

字體

PDFKit 帶有 14 種標準字體,可用於 PDF 文檔。這些字體中的任何一種都可以傳遞給 font() PDFDocument的功能 類,並與 text() 鏈接 :

pdfDoc.font('Times-Roman').text('A text in Times Roman')

您還可以通過將字體文件的路徑作為參數傳遞給 font() 來添加其他字體 函數,以及您想要的特定字體的名稱,以防文件具有字體集合。或者,您可以為新字體命名,以便可以通過該名稱而不是文件路徑訪問它:

pdfDoc.registerFont('Name of the font', '/file_path', 'specific_font_name_in_case_of_a_collection')

調用 font() 可以與其他函數鏈接,就像在 fillColor() 中一樣 例子。

您還可以使用 fontSize() 設置字體大小 功能。我們來看一些例子:

const PDFDocument = require('pdfkit');
const fs = require('fs');

let pdfDoc = new PDFDocument;
pdfDoc.pipe(fs.createWriteStream('fonts.pdf'));

pdfDoc.font('ZapfDingbats').text('This is a symbolic font.');
pdfDoc.font('Times-Roman').fontSize(25).fillColor('blue').text('You can set a color for any font');
pdfDoc.font('Courier').fontSize(5).fillColor('black').text('Some text to demonstrate.');

pdfDoc.end();

運行它會給我們以下 PDF 作為輸出:

添加圖片

您可能想要添加到 PDF 文件中的另一個常見內容是圖像。您可以撥打image() 文檔實例上的函數並傳遞要包含的圖像的路徑或 URI。

您還可以通過將包含鍵值對的對像作為參數傳遞給 image() 來設置圖像的寬度、高度、水平和垂直對齊等選項 功能。默認情況下,圖片會以其原始大小加載。

如果你設置 widthheight - 圖像將被拉伸以適應指定的參數。如果省略其中之一,則圖像將根據提供的參數按比例縮放:

const PDFDocument = require('pdfkit');
const fs = require('fs');

let pdfDoc = new PDFDocument;
pdfDoc.pipe(fs.createWriteStream('images.pdf'));

pdfDoc.text('By default, the image is loaded in its full size:')
pdfDoc.image('raspberries.jpg');

pdfDoc.moveDown(0.5)
pdfDoc.text('Scaled to fit width and height')
pdfDoc.image('raspberries.jpg', {width: 150, height: 150});

pdfDoc.moveDown(0.5)
pdfDoc.text('Scaled to fit width')
pdfDoc.image('raspberries.jpg', {width: 150});

pdfDoc.end();

運行這段代碼會給我們:

您還可以通過提供 scale 來縮放圖像 因素。此外,您可以提供 fitcover 數組,其中圖像將被縮放以分別適合提供的矩形或覆蓋它。如果您確實提供了 fitcover 數組,也可以設置水平對齊方式(align ) 和垂直對齊 (valign ):

const PDFDocument = require('pdfkit');
const fs = require('fs');

let pdfDoc = new PDFDocument;
pdfDoc.pipe(fs.createWriteStream('images.pdf'));

pdfDoc.text('Scaled by a factor, keeps the original proportions:')
pdfDoc.image('raspberries.jpg', {scale: 0.75});

pdfDoc.moveDown(0.5)
pdfDoc.text('Fit with horizontal alignment:')
pdfDoc.image('raspberries.jpg', {fit: [400, 150], align: 'center'});

pdfDoc.end();

這會給我們:

結論

在本文中,我們了解瞭如何使用 PDFKit 在 Node.js 中生成 PDF 文件。我們已經探索了一些可用於格式化文本的選項以及如何將圖像添加到我們的文件中。該庫包含大量文檔,涵蓋了在 Node.js 應用程序中創建 PDF 文件的更多內容。


Tutorial JavaScript 教程
  1. 使用代碼學習負載平衡。

  2. JavaScript 函數組合:有什麼大不了的?

  3. [代碼 2020 出現] 第 6 天分步教程(TypeScript)

  4. 使用 Angular 材質在 Angular 13 中構建模態/對話框

  5. 無服務器後端 MVP

  6. 掌握 Javascript 的路線圖

  7. XML 到 JSON 轉換器

  1. 從 javascript 調用 java servlet

  2. 使用 TDD 創建 React 組件

  3. 如何使用 Webpack 5 - 安裝教程

  4. 代碼的出現 - 第 2 天

  5. 為 Netlify CMS 創建自定義小部件

  6. 與 Firebase 反應:Firestore 設置

  7. 你可能應該學習 TypeScript

  1. 在 React 中使用 Formik 創建表單

  2. 一個功能三個應用程序

  3. 製作 Flickr 驅動的幻燈片

  4. 將 CircleCI 與工作服集成為您的下一個節點項目。