如何在NestJS(Node 22.13.1)中注册jsreport 4助手?
在NestJS中集成jsreport 4注册助手失败的解决方案
问题背景
在NestJS + TypeScript环境(Node.js 22.13.1)中使用jsreport 4渲染报表页眉页脚时,注册助手遇到两类问题:
- 通过
beforeRenderListeners注册助手,模板无法识别 - 调用
this.jsreport.assets.registerHelpers提示方法未定义
注:因TypeScript无法识别@jsreport/*库类型,已手动创建.d.ts文件。
正确实现步骤
1. 正确初始化jsreport实例并加载扩展
首先要确保jsreport实例初始化时正确注册所需扩展,并配置允许加载助手文件:
import { Injectable } from '@nestjs/common'; import jsreport from '@jsreport/jsreport-core'; import handlebars from '@jsreport/jsreport-handlebars'; import chromePdf from '@jsreport/jsreport-chrome-pdf'; import pdfUtils from '@jsreport/jsreport-pdf-utils'; import assets from '@jsreport/jsreport-assets'; @Injectable() export class ReportService { private jsreportInstance: any; constructor() { this.initJsReport(); } private async initJsReport() { this.jsreportInstance = jsreport({ store: { provider: 'fs' }, extensions: { assets: { allowedFiles: ['**/*.js'] } // 允许加载js格式的助手文件 } }); // 依次加载所需扩展 this.jsreportInstance.use(handlebars()); this.jsreportInstance.use(chromePdf()); this.jsreportInstance.use(pdfUtils()); this.jsreportInstance.use(assets()); // 完成初始化 await this.jsreportInstance.init(); } }
2. 通过Handlebars扩展注册全局助手
jsreport 4中,助手注册方法属于handlebars扩展,而非assets扩展。分两种场景处理:
场景1:注册单个助手
在jsreport实例初始化完成后,直接通过Handlebars实例注册:
// 在initJsReport方法的await this.jsreportInstance.init()之后 const handlebarsExt = this.jsreportInstance.extensionsManager.getExtension('handlebars'); handlebarsExt.handlebars.registerHelper('formatDate', (date) => { return new Date(date).toLocaleDateString(); });
场景2:批量加载helpers.js中的助手
如果你的helpers.js导出多个助手对象:
// helpers.js module.exports = { formatDate: (date) => new Date(date).toLocaleDateString(), uppercase: (str) => str.toUpperCase() };
可以通过循环批量注册:
// 在initJsReport方法中 const handlebarsExt = this.jsreportInstance.extensionsManager.getExtension('handlebars'); const helpers = require('./helpers.js'); Object.entries(helpers).forEach(([name, fn]) => { handlebarsExt.handlebars.registerHelper(name, fn); });
3. 页眉/页脚的助手使用注意
如果助手用于pdf-utils的页眉/页脚模板,需确保助手是全局注册的,渲染时模板配置正确:
async generateReport() { const result = await this.jsreportInstance.render({ template: { content: '<h1>报表主内容</h1>', engine: 'handlebars', recipe: 'chrome-pdf', pdfUtils: { headerTemplate: '<div>日期:{{formatDate now}}</div>', footerTemplate: '<div>第{{pageNumber}}页,共{{totalPages}}页</div>' } }, data: { now: new Date() } }); return result.content; }
4. TypeScript类型补充
在手动创建的.d.ts文件中添加以下声明,避免类型报错:
// src/types/jsreport.d.ts declare module '@jsreport/jsreport-core' { function jsreport(options?: Record<string, any>): any; export default jsreport; } declare module '@jsreport/jsreport-handlebars' { function handlebars(options?: Record<string, any>): any; export default handlebars; } declare module '@jsreport/jsreport-chrome-pdf' { function chromePdf(options?: Record<string, any>): any; export default chromePdf; } // 按需补充其他扩展的类型声明
内容的提问来源于stack exchange,提问作者Izlia
相关产品推荐
相关产品推荐

