证书生成器项目:PDF无内容问题及基于pdf-lib的实现需求问询
证书生成器PDF无内容问题解决指南
问题根源
- 核心逻辑文件
index.js被注释,未执行任何PDF生成代码 - 使用PNG作为模板,但
pdf-lib基于PDF文档操作,需将PNG转为PDF页面背景 - 缺少字体加载、文本绘制的关键实现逻辑
1. 修复HTML结构
取消index.js的注释,确保核心逻辑文件被加载,同时替换FileSaver为CDN链接避免模块加载问题:
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8" /> <meta name="viewport" content="width=device-width, initial-scale=1.0" /> <title>Certificate Generator</title> <link href="styles.css" rel="stylesheet" /> <script src="https://unpkg.com/pdf-lib/dist/pdf-lib.js"></script> <script src="https://cdn.jsdelivr.net/npm/file-saver@2.0.5/dist/FileSaver.min.js"></script> </head> <body> <section> <div class="container"> <img src="https://codedamn.com/assets/images/red-logo.png" width="75" alt="codedamn logo" /> <p>Get your certificate of</p> <h1>Project Certificate Generator</h1> <p class="name-text">Enter Your Name</p> <input type="text" id="participant-name" placeholder="Steve" /> <button id="proceed">Generate Certificate</button> </div> </section> </body> <script src="index.js"></script> </html>
2. 编写核心生成逻辑(index.js)
严格按照需求的7步实现:
const { PDFDocument, rgb, StandardFonts } = PDFLib; document.getElementById('proceed').addEventListener('click', async () => { const participantName = document.getElementById('participant-name').value.trim(); if (!participantName) { alert('请输入姓名'); return; } try { // 1. 从文件系统获取证书模板(确保模板在项目根目录) const templateResponse = await fetch('./证书模板.png'); const templatePngBytes = await templateResponse.arrayBuffer(); // 2. 创建并初始化PDFDocument对象 const pdfDoc = await PDFDocument.create(); // 将PNG模板转为PDF页面 const pngImage = await pdfDoc.embedPng(templatePngBytes); const pageWidth = pngImage.width; const pageHeight = pngImage.height; const page = pdfDoc.addPage([pageWidth, pageHeight]); // 绘制PNG作为页面背景 page.drawImage(pngImage, { x: 0, y: 0, width: pageWidth, height: pageHeight, }); // 3. 加载字体(使用内置粗体Helvetica,也可替换为自定义字体) const font = await pdfDoc.embedFont(StandardFonts.HelveticaBold); // 4. 字体已通过embedFont完成嵌入 // 5. 在证书空白区域插入文本(需根据实际模板调整坐标和字号) const fontSize = 36; // 居中计算X坐标,Y坐标需根据模板空白位置微调 const textX = pageWidth / 2 - font.widthOfTextAtSize(participantName, fontSize) / 2; const textY = pageHeight / 2 + 20; page.drawText(participantName, { x: textX, y: textY, size: fontSize, font: font, color: rgb(0, 0, 0), }); // 6. 保存PDF为字节数组 const pdfBytes = await pdfDoc.save(); // 7. 创建文件并触发下载 const pdfFile = new Blob([pdfBytes], { type: 'application/pdf' }); saveAs(pdfFile, `${participantName}_证书.pdf`); } catch (error) { console.error('生成PDF失败:', error); alert('生成证书失败,请检查控制台日志'); } });
关键注意事项
- 模板路径:确保
证书模板.png放在项目根目录,否则需调整fetch的路径 - 坐标微调:
textX和textY需要根据你的证书模板空白区域实际位置调整,可通过打印pageWidth/pageHeight测试定位 - 自定义字体:如果需要使用特定字体,替换内置字体为本地字体加载逻辑:
const fontResponse = await fetch('./你的字体文件.ttf'); const fontBytes = await fontResponse.arrayBuffer(); const font = await pdfDoc.embedFont(fontBytes); - 本地运行:直接打开HTML文件可能存在CORS问题,建议用本地服务器(如VS Code的Live Server)运行项目
内容的提问来源于stack exchange,提问作者Abijith
相关产品推荐
相关产品推荐

