node獲取指定目錄下全部文件的內容生成PDF

有個需求場景是須要把某個目錄下的全部指定文件的內容生成pdf,由於是前端開發,因此就用node來幹活
首先是pdf的包是用pdfkit, 這裏有兩個坑,第一個是生成的文件中可能會有系統沒法識別的換行和空格,會被替換成莫名其妙的符號,所以在拼接完內容後,要使用 str.replace(/rn|r/g, 'n')
進行過濾,第二個坑是中文字符會亂碼,所以要引入中文ttf,例如
doc.font('./msyh.ttf') ;
接下來是獲取全部文件內容,在一開始我是判斷文件的長度來識別是否結束,可是文件獲取是異步,遞歸的時候同時進行這麼多讀取操做,如何才能判斷全部異步操做都已經結束了呢,答案就是咱們的Promise.all啦
首先咱們將fs模塊的幾個要用到方法promiseify化,也就是咱們能夠將異步操做包裝在promise函數中,因爲文件操做的回調函數也是做爲參數傳入(萬能的JS),因此咱們只要獲取到arguments中的callback函數,而且根據成功或者失敗去resolve或reject就行啦,
那麼Promise.all是用來幹嗎呢?
Promise.all 接收一個 promise 對象的數組做爲參數,當這個數組裏的全部 promise 對象所有變爲resolve或 有 reject 狀態出現的時候,它纔會去調用 .then 方法,它們是併發執行的。也就是說咱們並行執行的全部文件讀取操做,能夠用Promise.all來解決啦!前端

const fs = require('fs')
const yargs = require('yargs')
const PDF = require('pdfkit')
const readdir = promisify(fs.readdir);
const stat = promisify(fs.stat);
const readFile = promisify(fs.readFile);
const doc = new PDF();

function uuid(times = 10) {
    let g = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789',
        str = '';
    let len = g.length;
    for (let i = 0; i < times; i++) {
        str += g[Math.round((Math.random() * (len - 1)))];
    }
    return str;
}
let { path = '', name = uuid(), fileType = '' } = yargs.argv || {};
let str = '';

fileType = (fileType.split(',') || []).filter(item => item !== '')

function promisify(fn) {
    return function() {
        let args = Array.from(arguments);
        return new Promise(function(resolve, reject) {
            args.push(function(err, result) {
                if (err) {
                    reject(err);
                } else {
                    resolve(result);
                }
            });
            fn.apply(null, args);
        });
    }
}

function readDirRecur(file, callback) {
    return readdir(file).then(function(files) {
        files = files.map(function(filename) {
            let fullPath = `${file}/${filename}`;
            return stat(fullPath).then(function(stats) {
                let limmit = fileType.length ? fileType.find(item => filename.includes(`.${item}`)) : true;
                if (stats.isDirectory()) {
                    return readDirRecur(fullPath, callback);
                } else if (limmit) {
                    return readFile(fullPath, 'utf8').then(function(data) {
                        callback(filename, data, fullPath);
                    });
                }
            })
        });
        return Promise.all(files);
    });
}
if (!path) return false;
readDirRecur(path, function(filename, data, fullPath) {
    str += data;
}).then(function() {
    str = str.replace(/\r\n|\r/g, '\n');
    doc.pipe(fs.createWriteStream(`${name}.pdf`))
    doc.fontSize(10);
    doc.font('./msyh.ttf');
    doc.text(str, 50, 50);
    doc.end()
}).catch(function(err) {
    console.log(err);
});
相關文章
相關標籤/搜索