求基于JavaScript的证书生成器方案:读取CSV批量生成带设计图的证书
基于JavaScript的批量证书生成器实现方案
核心技术选型
根据运行场景分两种落地方案:
- 浏览器端:用
FileReader处理本地文件、Canvas完成图片与文字合成,无需后端依赖,适合轻量批量需求 - Node.js端:依赖
fs模块读写文件、node-canvas处理图像合成、csv-parser解析CSV,适合大规模批量生成
一、浏览器端实现步骤
1. 读取CSV文件
通过文件输入框获取本地CSV,用原生逻辑解析(避免引入第三方库):
const csvInput = document.getElementById('csv-input'); const templateInput = document.getElementById('template-input'); csvInput.addEventListener('change', async (e) => { const file = e.target.files[0]; if (!file) return; // 读取并解析CSV内容 const text = await file.text(); const rows = text.split('\n').filter(row => row.trim()); const headers = rows[0].split(',').map(h => h.trim()); const data = rows.slice(1).map(row => { const values = row.split(',').map(v => v.trim()); return headers.reduce((obj, header, idx) => { obj[header] = values[idx]; return obj; }, {}); }); // 解析完成后启动证书生成 await generateCertificates(data); });
2. 加载证书模板图片
async function loadTemplate() { const file = templateInput.files[0]; if (!file) throw new Error('请选择证书模板图片'); return new Promise((resolve, reject) => { const img = new Image(); img.onload = () => resolve(img); img.onerror = reject; img.src = URL.createObjectURL(file); }); }
3. 批量生成并导出证书
利用Canvas合成模板与文字,逐个生成下载链接:
async function generateCertificates(data) { const template = await loadTemplate(); const canvas = document.createElement('canvas'); const ctx = canvas.getContext('2d'); // 同步Canvas尺寸与模板一致 canvas.width = template.width; canvas.height = template.height; for (const item of data) { ctx.drawImage(template, 0, 0); // 设置字体样式(根据模板实际需求调整) ctx.font = 'bold 48px Arial'; ctx.fillStyle = '#2c3e50'; ctx.textAlign = 'center'; // 写入姓名(CSV字段需与实际表头对应) ctx.fillText(item.name, canvas.width / 2, canvas.height / 2 + 20); // 写入证书日期 ctx.fillText(item.date, canvas.width / 2, canvas.height / 2 + 80); // 触发下载 const link = document.createElement('a'); link.download = `${item.name}_证书.png`; link.href = canvas.toDataURL('image/png'); link.click(); } }
二、Node.js端实现步骤
1. 安装依赖
npm install csv-parser canvas fs-extra
2. 读取CSV数据
const fs = require('fs-extra'); const csv = require('csv-parser'); async function readCSV(filePath) { const results = []; return new Promise((resolve, reject) => { fs.createReadStream(filePath) .pipe(csv()) .on('data', (data) => results.push(data)) .on('end', () => resolve(results)) .on('error', reject); }); }
3. 加载模板并批量生成证书
const { createCanvas, loadImage, registerFont } = require('canvas'); // 注册自定义字体(如果模板需要特殊字体) registerFont('./fonts/NotoSansSC-Bold.ttf', { family: 'Noto Sans SC' }); async function generateCertificate(templatePath, data, outputPath) { const template = await loadImage(templatePath); const canvas = createCanvas(template.width, template.height); const ctx = canvas.getContext('2d'); ctx.drawImage(template, 0, 0); // 设置字体与文字位置(根据模板实际调整) ctx.font = 'bold 48px "Noto Sans SC"'; ctx.fillStyle = '#2c3e50'; ctx.textAlign = 'center'; ctx.fillText(data.name, canvas.width / 2, canvas.height / 2 + 20); ctx.fillText(data.date, canvas.width / 2, canvas.height / 2 + 80); // 保存到本地目录 const buffer = canvas.toBuffer('image/png'); await fs.writeFile(outputPath, buffer); } // 批量处理入口 async function batchGenerate() { const data = await readCSV('./data.csv'); const templatePath = './template.png'; // 确保输出目录存在 await fs.ensureDir('./output'); for (const [index, item] of data.entries()) { const outputPath = `./output/${item.name}_证书.png`; await generateCertificate(templatePath, item, outputPath); console.log(`已生成第${index+1}张证书: ${outputPath}`); } } batchGenerate().catch(err => console.error('生成失败:', err));
关键注意事项
- 文字位置校准:用PS或其他设计工具打开模板,测量文字坐标后调整
fillText的参数 - 字体兼容性:浏览器端依赖用户本地字体,Node.js端需提前注册字体文件路径
- 性能优化:浏览器端批量生成可加入
setTimeout避免卡顿;Node.js端可用p-limit控制并发数 - 格式扩展:若需生成PDF,Node.js端可搭配
pdf-lib库,将Canvas生成的图片插入PDF文档
内容的提问来源于stack exchange,提问作者Adhil Roshan
相关产品推荐
相关产品推荐

