NestJS使用pdfkit-table实现温度值超范围变色失败求助
NestJS中pdfkit-table温度值范围变色失效问题
问题说明
在NestJS项目里用pdfkit-table生成PDF时,想要让数据库返回的temperature字段值在低于18℃或高于22℃时显示红色,正常范围显示指定颜色。参考文档「Example Table 2」配置了renderer属性后,PDF里的温度值直接显示成<span style = "color:red">15</span>这类HTML标签文本,完全没实现颜色渲染效果。
配置的renderer代码片段
headers: [ { label:"Temperature (°C)", property:'temperature', align: 'center', valign: 'center', headerColor: HeaderColor, renderer: (value) => { const temperature = parseFloat(value); if (temperature < 18 || temperature > 22) { return `<span style = "color:red;">${value}</span>`; } else { return `<span style="color: ${DataColor};">${value}</span>` } } }, ]
完整相关代码
const PDFDocument = require('pdfkit-table'); async generatePDF(initialDate: string, endDate: string):Promise<Buffer>{ const pdfBuffer: Buffer = await new Promise( async resolve => { const doc = new PDFDocument({ size: "letter", bufferPages: true, autoFirstPage: false, layout : 'landscape' }); let pageNumber = 0; doc.on('pageAdded', () =>{ pageNumber++; doc.font('Helvetica').fontSize(10); doc.text( "Pag. "+ pageNumber, (doc.page.width - 125), (doc.page.height - 40), { width: 100, align: 'center', lineBreak: false } ); }); const tablePrimary1 = await this.unitService.findUnitByRangeDatesForPDF(initialDate, endDate, 'Primary 1'); let HeaderColor = "#0e0bab" let DataColor = "#0e0bab" const Primary = { title: { label: "Table", fontSize: 12}, // subtitle: "Query date range: "+ initialDate + " to " + endDate, divider: { header: { disabled: false, width: 2, opacity: 1 }, horizontal: { disabled: false, width: 0.5, opacity: 0.5 }, }, headers: [ { label:"Temperature (°C)", property:'temperature', align: 'center', valign: 'center', headerColor: HeaderColor, renderer: (value) => { const temperature = parseFloat(value); if (temperature < 18 || temperature > 22) { return `<span style = "color:red;">${value}</span>`; } else { return `<span style="color: ${DataColor};">${value}</span>` } } }, ], datas: [], rows: tablePrimary1, }; doc.addPage(); doc.font('Helvetica-Bold').fontSize(12); doc.text("Register of Temperatures",(doc.page.width * 0.5 - 175)); doc.text('',30,60); doc.table(Primary, { width: 750, prepareHeader: () => doc.font("Helvetica-Bold").fontSize(6), prepareRow: (row, indexColumn, indexRow, rectRow, rectCell) => doc.font("Helvetica").fontSize(6), }); const buffer = []; doc.on('data', buffer.push.bind(buffer)); doc.on('end', () => { const data = Buffer.concat(buffer); resolve(data); }); doc.end() }); return pdfBuffer; }
解决方法
pdfkit-table的renderer不支持解析HTML标签,它基于PDFKit原生API工作,正确的做法是用prepareRow回调来处理单元格颜色:
- 删除header配置里的
renderer属性 - 在
prepareRow中定位temperature列,根据值范围设置文本颜色
修改后的关键代码:
// 移除headers中的renderer配置 headers: [ { label:"Temperature (°C)", property:'temperature', align: 'center', valign: 'center', headerColor: HeaderColor }, ], // 调整table的prepareRow配置 doc.table(Primary, { width: 750, prepareHeader: () => doc.font("Helvetica-Bold").fontSize(6).fill(HeaderColor), prepareRow: (row, indexColumn, indexRow, rectRow, rectCell) => { doc.font("Helvetica").fontSize(6); // 假设temperature是第一列,根据实际列索引调整indexColumn的值 if (indexColumn === 0) { const tempValue = parseFloat(row.temperature); if (tempValue < 18 || tempValue > 22) { doc.fillColor('red'); } else { doc.fillColor(DataColor); } } else { // 其他列恢复默认颜色 doc.fillColor(DataColor); } }, });
补充说明
prepareRow会在每个单元格渲染前触发,通过indexColumn可以精准定位目标列- 用PDFKit原生的
fillColor方法设置文本颜色,这是框架支持的标准方式 - 非目标列要重置颜色,避免影响其他单元格的文本显示
内容的提问来源于stack exchange,提问作者Unodetantosluises
相关产品推荐
相关产品推荐

