PDFKit - 自定义字体 - fs.readFileSync不是一个函数

时间:2014-10-15 21:50:45

标签: javascript node.js pdfkit

我正在使用PDFKit作为应用程序。我只是在浏览器的HTML文件中使用它,使用Javascript(没有Node.js)。

我从GitHub下载了PDFKit:https://github.com/devongovett/pdfkit/releases

以及Blob Stream:https://github.com/devongovett/blob-stream

我正在尝试按照这样的文档包含自定义字体:

doc.registerFont('Custom Font', 'fonts/GOODDP__.TTF');
doc.font('Custom Font').fontSize(fontSize).text($("#text1").val(), xPos, yPos, configObj);

但我总是得到这个错误:

 fs.readFileSync is not a function

这是有道理的,因为fs.readFileSync是node.js的一部分,我没有使用它。但是,文档中的示例说这可以在浏览器中使用。

我知道还有一个Browserify选项,但我不确定在这种情况下如何或如果有帮助

6 个答案:

答案 0 :(得分:6)

你必须使用ArrayBuffer:

        var oReq = new XMLHttpRequest();
        oReq.open("GET", "css/fonts/Open_Sans/OpenSans-Regular.ttf", true);
        oReq.responseType = "arraybuffer";

        oReq.onload = function(oEvent) {
            var arrayBuffer = oReq.response; // Note: not oReq.responseText

            if (arrayBuffer) {
                PdfExporter.doc.registerFont('OpenSans', arrayBuffer)
            }
        };

        oReq.send(null);

答案 1 :(得分:3)

您似乎必须使用Browserify来实现此功能,并且使用预编译的PDFKit.js不会为任何Node.js特定功能剪切它。

答案 2 :(得分:2)

这是我加载自定义unicode字体的步骤。

  1. 使用默认值创建package.json:

npm初始化-y

  1. 安装fontkit

npm install fontkit

  1. 全局安装browserify(以防您没有browserify)

npm install -g browserify

  1. 创建一个空文件并将其命名为compile.js(或任何您喜欢的名称)

  2. 将以下代码粘贴到compile.js中

    fontkit = require("fontkit");
    const fontName = "OpenSans-Regular";
    const fontPath = fontName + ".ttf";
    
    fetch(fontPath)
        .then(res => res.arrayBuffer())
        .then(fontBlob => {
            const customFont = fontkit.create(new Buffer(fontBlob)).stream.buffer;
            const doc = new PDFDocument({});
            const stream = doc.pipe(blobStream());
            doc.registerFont(fontName, customFont);
            doc.fontSize(14);
            doc.font(fontName)
            .fillColor("black")
                .text(
                    "Custom unicode font loaded. Ω is the 24th and last letter of the Greek alphabet.",
                    50,
                    50,
                    { width: 800, align: "left" }
                );
            doc.end();
            stream.on("finish", function() {
                const blob = stream.toBlob("application/pdf");
                const iframe = document.querySelector("iframe");
                iframe.src = stream.toBlobURL("application/pdf");
            });
        });
    

    要加载其他字体,只需更改fontName值。上面的代码假定一个名为OpenSans-Regular.ttf的字体文件与compile.js存在于同一目录中。您可以将fontPath更改为所需的任何路径或URL。

  3. 运行以下命令(在终端或命令提示符下)以创建自定义版本的fontkit。

浏览器浏览compile.js -o fontkit.js

  1. 您可以删除compile.js文件。不再需要。您还可以删除node_modules目录以及package.json。 (如果您不使用其他软件包,而仅是为了创建自定义版本的fontkit)

  2. 创建一个index.html文件并粘贴以下内容:

    <!DOCTYPE html>
    <html lang="en">
    
    <head>
        <title>Custom Font</title>
        <meta charset="UTF-8">
        <meta name="viewport" content="width=device-width, initial-scale=1">
    </head>
    
    <body>
        <iframe id="frame1" width="100%" height="500px"></iframe>
    </body>
    
    <script src="pdfkit.js"></script>
    <script src="blob-stream.js"></script>
    <script src="fontkit.js"></script>
    
    </html>
    
  3. 这是浏览器中index.html的屏幕截图:

enter image description here

答案 3 :(得分:1)

我也遇到了这个问题而Andrea的答案只是解决方案的一部分。您实际上需要调整pdfkit.js文件。但首先你需要做Andrea做的事情:

var myImage;
var oReq = new XMLHttpRequest();
oReq.open("GET", "myimage.jpg", true);
oReq.responseType = "arraybuffer";
oReq.onload = function(oEvent) 
{
    myImage = oReq.response; //image as an arraybuffer
    makePDF();
};
oReq.send(null)

//then use myImage like normal:
doc.image(myImage);

正如我所说,你需要调整pdfkit.js文件。在第2888行:

PDFImage.open = function(src, label) {
    var data, match;
    if (Buffer.isBuffer(src)) {
        data = src;
    } else {
        //START NEW
        if (src instanceof ArrayBuffer) {
            data = new Buffer(new Uint8Array(src), 'object');
        } else
        //END NEW
        if (match = /^data:.+;base64,(.*)$/.exec(src)) {
            data = new Buffer(match[1], 'base64');
        } else {
            data = fs.readFileSync(src);
            if (!data) {
                return;
            }
        }
    }

确保您还包含blob-stream.js。我在// START NEW之后添加了一个额外的选项来处理来自XMLHttpRequests的数组缓冲区。

我不知道这是否是最佳解决方案,但它确实有效。

答案 4 :(得分:1)

这对我有用:

async function makePDF() {
   const font = await fetch('./fonts/arial.ttf')
   const arrayBuffer = await font.arrayBuffer()

   doc.registerFont('Arial', arrayBuffer)

   doc.font('Arial').text('Hello World!')
}

答案 5 :(得分:0)

我在 Node 中为 PDFKit 使用自定义字体:

const FileSystem = require('fs')

const path = require('path')

const fontDBCartoonShout = FileSystem.readFileSync(path.resolve(__dirname, '../resources/typefaces/BD_Cartoon_Shout.ttf'))
pdfDoc.registerFont('BD Cartoon Shout', fontDBCartoonShout)