pdfkit Browser - “Uncaught ReferenceError: fs is n

2019-08-22 02:19发布

问题:

This question may be asked previously but they have no answer. I try to create a pdf file using pdfkit library with Arabic language support. So, first I downloaded a prebuilt version of pdfkit (which is assumed to work in browser) from here.

Then I wrote this code for adding an Arabic font (like in the docs)

const doc = new PDFDocument;
var text_arabic = "مرحبا مَرْحَبًا";

// Using a TrueType font (.ttf)   
doc.font('./trado.ttf')   // --> this line gives the error.
   .text(text_arabic)
   .moveDown(0.5);

The error is:

Uncaught ReferenceError: fs is not defined
at Object.fontkit.openSync (pdfkit.js:10949)
at Function.PDFFont.open (pdfkit.js:451)
at PDFDocument.font (pdfkit.js:2227)
at main.js:22

pdfkit.js from line 10949:

fontkit.openSync = function (filename, postscriptName) {
   var buffer = fs.readFileSync(filename);    / --> error
   return fontkit.create(buffer, postscriptName);
};

So, I think 'fs' belongs to node.js part with require('fs') but anyway I don't know the solution. What is the solution then? Thanks in advance!

回答1:

Here is the simple solution;

  1. Don't forget to add pre-built pdfkit.js and blob-stream.js files
  2. Copy below js code and include it in your html
  3. Put your fonts to the same place with html/js (like trado.ttf)
  4. Change the getFont(...) according to your font name

Done!

Important Notes:

  1. If you run it without any server, chrome will give CORS policy error. (See this to disable just for try)
  2. When you move your files to a server, or running in local server, there will be no CORS error.
  3. Last and most importantly, give some times to xhr.onload. Because of that we create writeToPDF() function seperately for using with a button after loading.

const doc = new PDFDocument;
const stream = doc.pipe(blobStream());

var embeddedFonts = (function() {
  var fontCollection = {};

  function getFont(name, src) {
    var xhr = new XMLHttpRequest();
    xhr.open('GET', src, true);
    xhr.responseType = "arraybuffer";
    xhr.onload = function(evt) {
      var arrayBuffer = xhr.response;

      if (arrayBuffer) {
        fontCollection[name] = new Uint8Array(arrayBuffer);
        registerEmbeddedFonts(doc, embeddedFonts);

      } else {
        error = "Error downloading font resource from " + src;
      }

    };
    xhr.send(null);
  }

  getFont("Trado", 'trado.ttf');

  return fontCollection;
}());

function registerEmbeddedFonts(doc, fontCollection) {
  doc.registerFont("Trado", fontCollection["Trado"]);
}

function writeToPDF() {
  doc.fontSize(40);
  doc.font('Trado').text('مَرْحَبًا');

  doc.end();
  stream.on('finish', function() {
    // get a blob you can do whatever you like with
    const blob = stream.toBlob('application/pdf');


    // or get a blob URL for display in the browser
    const url = stream.toBlobURL('application/pdf');
    var frame = document.getElementById("pdfFrame");

    frame.src = url;
  });
}
<script src="https://github.com/foliojs/pdfkit/releases/download/v0.8.0/pdfkit.js"></script>
<script src="https://github.com/devongovett/blob-stream/releases/download/v0.1.3/blob-stream.js"></script>


<iframe id="pdfFrame" src="" width="300" height="300"> </iframe>
<button type="button" onclick="writeToPDF();">Write to PDF</button>

<!-- This example doesn't work because of missing trado.ttf font file.
Try to run at your PC -->