You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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回调来处理单元格颜色:

  1. 删除header配置里的renderer属性
  2. 在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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.08 17:07:48