nodejs对PDF合并的几种方法

2,298 阅读1分钟

nodejs对PDF合并的几种方法

方法一 使用pdfbox.jar 对PDF进行合并

这里需要安装java环境;然后下载pdfbox.jar文件 和下面的js文件放在相同目录

/**
 * 这个是用pdfbox.jar 对PDF进行合并, 使用cmd 执行java命名
 * @param sourceFiles
 * @param outputFile
 */
const PDFMerger = async ({sourceFiles, outputFile}) => {
  makeDir(getFilenameInfoByPath(outputFile).fileDir)
  const  fileListString = sourceFiles.join(' ')
  const cmd = `java -jar ${__dirname}\\pdfbox.jar PDFMerger ${fileListString} ${outputFile}`
  console.log(cmd)
  await new Promise((resolve, reject) => {
    const spawnObj = exec(cmd);
    spawnObj.stdout.on('data', function (chunk) {
      console.log('stdout-----', chunk.toString());
    });
    spawnObj.stderr.on('data', data => {
      console.log('stderr-----', data);
    });
    spawnObj.on('exit', code => {
      console.log('exit-----: ' + code);
    })
    spawnObj.on('close', code => {
      if (code === 0) {
        console.log('成功-----' + code);
        resolve(true)
      } else {
        console.log('失败-----' + code);
        // eslint-disable-next-line prefer-promise-reject-errors
        reject(false)
      }
    })
  })
}

参考链接 https://pdfbox.apache.org/2.0/commandline.html


方法二 使用的pdf-lib 对PDF进行合并

这个需要安装npm install pdf-lib


/**
 * 合并多个PDF为一个PDF文件
 * 这个是使用的pdf-lib 对PDF进行合并
 */
const {PDFDocument} = require('pdf-lib')
const mergePDF = async ({sourceFiles,outputFile}) => {
  const pdfDoc = await PDFDocument.create()
  for(let i = 0;i<sourceFiles.length;i++) {
    const localPath = sourceFiles[i]
    const PDFItem = await PDFDocument.load(fs.readFileSync(localPath))
    for(let j = 0;j<PDFItem.getPageCount();j++) {
      const [PDFPageItem] = await pdfDoc.copyPages(PDFItem, [j])
      pdfDoc.addPage(PDFPageItem)
    }
  }
  const pdfBytes = await pdfDoc.save()
  fs.writeFileSync(outputFile, pdfBytes)

}

参考链接 https://pdf-lib.js.org/docs/api/ 参考链接 https://github.com/Hopding/pdf-lib


方法三 使用的easy-pdf-merge 对PDF进行合并

这个需要安装npm install easy-pdf-merge 这个js的底层其实和方法一是一样的,也是使用pdfbox.jar 对PDF进行合并

/**
 * 合并PDF
 * 这个是使用easy-pdf-merge 对PDF合并
 * @param sourceFiles
 * @param outputFile
 */
const easyPDFmerge = ({sourceFiles,outputFile}) => {
  const mergeUtil = require('easy-pdf-merge')
  return new Promise(resolve => {
    const startTime = new Date()
    mergeUtil(sourceFiles, outputFile, err => {
      // 合并失败
      if (err) {
        // 抛出异常
        resolve({
          status: 1,
          err
        })
      } else {
        // 合并成功
        const endTime = new Date()
        // 返回合并耗时
        resolve({
          status: 0,
          time: endTime - startTime
        })
      }
    })
  })
}

参考链接 https://github.com/karuppiah7890/easy-pdf-merge


测试

介绍以上3种方法后;对3个方法进行了测试;以下代码

const path = require('path')
// 要合并的PDF文件存放路径
const sourceFiles = [
    path.resolve(__dirname, './pdf/test1.pdf'),
    path.resolve(__dirname, './pdf/test2.pdf')
  ]
// 合并后文件的输出路径
const outputFile = path.resolve(__dirname, 'output.pdf')

// 方法一
const test1 = async () => {
  const time = Date.now()
  await PDFMerger({
    sourceFiles,
    outputFile:path.resolve(__dirname, 'output1.pdf'),
  })
  console.log(`test1耗时:${Date.now() - time}ms`)
}
test1()

// 方法二
const test2 = async () => {
  const time = Date.now()
  await mergePDF({
    sourceFiles,
    outputFile:path.resolve(__dirname, 'output2.pdf'),
  })
  console.log(`test2耗时:${Date.now() - time}ms`)
}
test2()

// 方法三
const test3 = async () => {
  const time = Date.now()
  await easyPDFmerge({
    sourceFiles,
    outputFile:path.resolve(__dirname, 'output3.pdf'),
  })
  console.log(`test3耗时:${Date.now() - time}ms`)
}
test3()

以上代码对test1.pdf和test2.pdf进行合成打印出耗时; 结果显示方法一耗时更短;且产生的文件大小比较小,pdf-lib合并后的pdf文件也变得很大。

test1耗时:1463ms
test3耗时:1519ms
test2耗时:4541ms

binDuF.png