jsPDF使用output()时自定义TTF字体与PNG图片异常求助
问题分析与解决方案
核心问题根源
- 二进制PDF数据传输损坏:直接将
doc.output()的结果通过JSON.stringify传输,会破坏PDF的二进制结构,导致后端生成的文件异常。 - 自定义字体未嵌入PDF:注册字体时未开启嵌入选项,仅在客户端环境可用,未写入最终PDF文件。
- 图片异步加载未处理:使用DOM Image对象加载图片时,未等待加载完成就执行
addImage,导致图片数据未被嵌入PDF。
分步解决方案
1. 修复PDF二进制传输问题
放弃JSON传输,改用FormData发送Blob格式的PDF,避免二进制数据被转义:
客户端修改printAPI函数
async function printAPI(pdfBlob, printer, labelName, paper, quantity) { const formData = new FormData(); formData.append('doc', pdfBlob, 'label.pdf'); formData.append('printer', printer); formData.append('labelName', labelName); formData.append('paper', paper); formData.append('quantity', quantity); await fetch('http://127.0.0.1:3000/api/printer/print-label', { method: 'POST', body: formData }); }
生成PDF时转成Blob调用
// 替换原printAPI调用代码 const pdfBuffer = doc.output('arraybuffer'); const pdfBlob = new Blob([pdfBuffer], { type: 'application/pdf' }); printAPI(pdfBlob, printer, 'lbl_' + part.replace('.',''), this.paper, quantity);
后端接收处理(用multer简化文件上传)
const multer = require('multer'); const upload = multer({ dest: uploadDirectory }); app.post('/api/printer/print-label', upload.single('doc'), (req, res) => { const targetPath = `${uploadDirectory}/lbl_${req.body.labelName}.pdf`; fs.rename(req.file.path, targetPath, (err) => { err ? res.sendStatus(500) : res.sendStatus(200); }); });
2. 确保自定义字体嵌入PDF
注册字体时必须添加embed参数,将字体数据写入PDF:
// 补充字体注册代码(需提前将TTF转成base64) doc.addFileToVFS('fre3of9x.ttf', '你的字体base64编码内容'); doc.addFont('fre3of9x.ttf', 'fre3of9x', 'normal', 'embed'); // 关键是embed选项
3. 修复图片嵌入问题
等待图片加载完成后再添加到PDF,或直接使用base64格式嵌入:
方案一:异步加载图片
function loadImage(src) { return new Promise((resolve, reject) => { const img = new Image(); img.onload = () => resolve(img); img.onerror = reject; img.src = src; }); } // 生成PDF的函数改为异步 async function generateLabelPDF() { const img = await loadImage('/assets/bag.png'); const doc = new jsPDF(); // 此处补充你的doc初始化逻辑 doc.addImage(img,'png',this.width-2-18.54,0,18.54,5); // 后续文本、条形码生成逻辑... }
方案二:直接使用base64图片
将bag.png转成base64字符串(可通过在线工具转换),直接嵌入代码:
const bagImgBase64 = 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAA...'; doc.addImage(bagImgBase64,'png',this.width-2-18.54,0,18.54,5);
内容的提问来源于stack exchange,提问作者jam0
相关产品推荐
相关产品推荐

