Node.js实现文本与pdf相互转换的代码详解
作者:Heo
在IT行业中,文档格式转换是日常工作中的常见需求,Word与PDF是两种广泛应用的文档格式,它们各有优势,但有时需要相互转换以满足特定场景的需求,本篇将详细讲解如何使用Node.js实现文本与pdf相互转换,需要的朋友可以参考下
pdf 转文本
主要使用 pdf-parse 这个库,直接识别提取我们 pdf 文件中的文字。
const express = require("express"); const fs = require("fs"); const PDFParser = require("pdf-parse"); const cors = require("cors"); const pdfFilePath = "./xxx_实习生.pdf"; const app = express(); // 解决跨域问题 app.use(cors()); app.use(express.static(__dirname)); app.use(express.json()); app.post("/form2pdf", (req, res) => { console.log(req.body); const str = ""; // 1. 读取pdf文件 fs.readFile(pdfFilePath, (err, pdfBuffer) => { if (err) { console.log(err); return; } PDFParser(pdfBuffer).then((pdfData) => { const pages = pdfData.text.split("\n\n"); console.log(pages); let str; for (let i = 1; i < pages.length; i++) str = str + pages[i]; console.log(str); }); }); }); app.listen(3000, () => { console.log("Server is running on port 3000"); });
文本转 pdf
主要使用 pdfkit 这个库将文本转为pdf文件。
const express = require("express"); const fs = require("fs"); const cors = require("cors"); const PDFDocument = require("pdfkit"); const app = express(); // 解决跨域问题 app.use(cors()); app.use(express.static(__dirname)); app.use(express.json()); app.post("/form2pdf", (req, res) => { console.log(req.body); const str = ""; // 使用 pdfkit 生成pdf // 创建 PDF 文档 const doc = new PDFDocument({ margin: 50, // 控制上下左右留白 }); // 输出到文件 // 如果有同名的 直接覆盖 doc.pipe(fs.createWriteStream("output.pdf")); // ========== Header ========== function addHeader(doc) { doc.fontSize(20).text(req.body.name, { align: "center" }).moveDown(); doc .moveTo(50, doc.y) // 从左边开始画横线 .lineTo(550, doc.y) // 到右边 .stroke(); doc.moveDown(); } // ========== Footer ========== function addFooter(doc) { const range = doc.bufferedPageRange(); // 所有页 for (let i = range.start; i < range.start + range.count; i++) { doc.switchToPage(i); doc .fontSize(10) .fillColor("gray") .text(`第 ${i + 1} 页`, 0, doc.page.height - 50, { align: "center", }); } } // ========== Body ========== function addBody(doc) { doc.fontSize(12); doc.text(req.body.name + " " + req.body.sex + " " + req.body.age, { align: "left", lineGap: 4, }); } // 添加内容 addHeader(doc); addBody(doc); // 结束前添加 footer(多页也有效) doc.end(); doc.on("end", () => { addFooter(doc); }); // 把后端的pdf地址返回给前端 res.json({ code: 200, data: "http://localhost:3000/output.pdf", }); res.send("PDF generated successfully!"); }); app.listen(3000, () => { console.log("Server is running on port 3000"); });
浏览器缓存引发的小问题
之前自己写 demo,遇到一个小问题,可能刚刚入门的小白一时找不到原因,特此记录下:
- 后端生成pdf文件,但是名称都相同(而且由于前端通过 iframe 渲染 pdf 的url 地址,url 地址也相同)
- 尽管内容不同,但是浏览器发现相同的名称pdf(静态文件),会继续使用缓存,导致后端pdf虽然重新覆盖生成,但是前端浏览器中的 iframe 渲染的 pdf 还是旧的(缓存中的)。
解决方法是:
<iframe :src="url" width="100%" height="1200px"></iframe> const onSubmit = () => { axios.post("http://localhost:3000/form2pdf", form).then((res) => { url.value = res.data.data + "?t=" + Date.now(); console.log(url); }); };
添加一个时间戳来阻止浏览器继续使用缓存,以保证每次重新请求都可以渲染最新的pdf 文件数据。
- 浏览器为什么会缓存 PDF?
静态资源(如 PDF、图片、JS、CSS)默认会被浏览器缓存。
这是因为 Express 的 express.static()
中间件会自动为静态资源设置缓存相关的 HTTP 头(如 Cache-Control
),让浏览器下次访问同样的 URL 时直接用本地缓存,加快加载速度、减少服务器压力。
只要 URL 一样,且没有特殊的禁止缓存设置,浏览器就会优先用缓存。
如果在 /form2pdf
路由里加了:
res.setHeader("Cache-Control", 'no-store');
但这个 header 只作用于 /form2pdf
这个接口的响应,对 output.pdf
这个静态文件的响应没有影响。output.pdf
的响应是由 express.static(__dirname)
处理的,和接口响应头无关。
- 为什么加参数能解决?
当你访问 output.pdf?t=xxx
时,浏览器认为这是一个全新的资源(即使实际文件一样),所以会重新请求服务器,不会用缓存。
- 如何让静态 PDF 不被缓存?
可以让 Express 静态资源响应时加上禁止缓存的 header:
app.use(express.static(__dirname, { setHeaders: (res, path) => { if (path.endsWith('.pdf')) { res.setHeader('Cache-Control', 'no-store'); } } }));
这样浏览器每次都会重新请求 PDF 文件。
到此这篇关于Node.js实现文本与pdf相互转换的代码详解的文章就介绍到这了,更多相关Node.js文本与pdf互转内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!