前端实现pdf内容合成
发表于:2024-06-21 |

前言

我之前不是搞了前端的打印吗,使用哪个 printJs 的,现在新需求又来了,让我一起打印俩个 pdf 文件,emm,这不是等于要我前端把 pdf 内容合并吗,我的老天爷,还好,办法总比困难多,因为 printJs 是接受多张图片打印或者单个 pdf 打印的,因此这个合成就有了两种实现的路子,第一种,把 pdf 变成图片,拼起来打印,第二个,真实合成 pdf。这里我把这两种方法都介绍一下。

合成 pdf 二进制流

先讲一下这个,这个的方法就是真的合成 pdf 用的,需要使用 pdf-lib 这个库

安装

1
npm i pdf-lib

使用

因为我下载下来的是 blob 类型的,所以大概代码如下,将blob使用FileReader读取变成二进制的ArrayBuffer格式

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
import { PDFDocument } from "pdf-lib";
import PrintJs from "print-js";
// 创建一个新的空白PDF文档
const mergedPdfDoc = await PDFDocument.create();
for(let blob of blobs){
// 获取PDF文件的二进制数据,将blob转成arrayBuffer
const reader = new FileReader()

reader.onload = async function(e) {
// 将获取到的PDF文件添加到新的文档中
const pdfDoc = await PDFDocument.load(e.target!.result as ArrayBuffer);
// 如果单个PDF为多页,则要一页一页往新建的PDF中添加
const copiedPages = await mergedPdfDoc.copyPages(pdfDoc, pdfDoc.getPageIndices());
copiedPages.forEach(page => mergedPdfDoc.addPage(page));
// 将合并后的PDF保存为Blob对象
const mergedPdfBytes = await mergedPdfDoc.save();
const mergedPdfBlob = new Blob([mergedPdfBytes], { type: 'application/pdf' });
mergedUrl=window.URL.createObjectURL(mergedPdfBlob)
// 这里如果把showModal变成true,会一直有遮罩层,所以我去掉了
PrintJs({
printable: mergedUrl,
type: "pdf",
showModal: false,
modalMessage: "正在生成pdf文件,请稍等...",
});
window.URL.revokeObjectURL(mergedUrl);
pdfDownVisible.value = false;
}
reader.readAsArrayBuffer(blob)
}

将pdf变成多张图片

安装

这里需要使用pdfjs

使用

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
import * as pdfjsLib from 'pdfjs-dist';
/**
* pdf文件转图片
* @param pdfUrl 文件路径
*/
export async function convertPdfToImage(pdfUrl) {
const pdf = await pdfjsLib.getDocument(pdfUrl).promise;
const canvas = document.createElement('canvas');
const context = canvas.getContext('2d');
const imageArr = [];

// 循环遍历每一页pdf,将其转成图片
for (let i = 1; i <= pdf._pdfInfo.numPages; i++) {
// 获取pdf页
const page = await pdf.getPage(i);
// 获取页的尺寸
const viewport = page.getViewport({ scale: 2 });
// 设置canvas的尺寸
canvas.width = viewport.width;
canvas.height = viewport.height;
// 将pdf页渲染到canvas上
await page.render({ canvasContext: context, viewport: viewport }).promise;

imageArr.push(canvas.toDataURL('image/png'));
}

return imageArr;
}

结语

好了,本篇文章就到这里,更多内容敬请期待,债见~

上一篇:
【可视化学习】71-从入门到放弃WebGL(八)
下一篇:
window.atob的使用问题