如何将外部CSS文件传入PDFMake的styles属性,替代手动定义样式
pdfmake 本身并不支持直接在 styles 属性中传入本地 CSS 文件路径的用法,你可以通过「读取CSS内容→解析CSS规则→转换为pdfmake兼容的样式格式」的流程实现需求,具体实现方案如下:
实现步骤
- 第一步:读取外部CSS文件的文本内容,Node.js环境可使用
fs模块读取,浏览器环境可通过fetch请求获取。 - 第二步:使用CSS解析库将CSS文本解析为抽象语法树(AST),提取所有选择器和对应的样式规则。
- 第三步:将CSS属性映射为pdfmake支持的样式属性,比如
font-size映射为fontSize、text-align映射为alignment等,最终生成符合pdfmake要求的styles对象。 - 第四步:调用
htmlToPdfmake时开启useClass和useId参数,保证HTML中的class、id能正确关联到转换后的样式。
代码示例(Node.js环境)
首先安装所需依赖:
npm install css html-to-pdfmake pdfmake
核心实现代码:
const fs = require('fs'); const css = require('css'); const htmlToPdfmake = require('html-to-pdfmake'); // CSS属性到pdfmake样式的映射表 const cssPropMap = { 'font-size': 'fontSize', 'text-align': 'alignment', 'color': 'color', 'background-color': 'background', 'line-height': 'lineHeight', 'margin-top': 'marginTop', 'margin-bottom': 'marginBottom', 'margin-left': 'marginLeft', 'margin-right': 'marginRight', 'font-weight': (val) => val === 'bold' ? ['bold', true] : null, 'font-style': (val) => val === 'italic' ? ['italics', true] : null } // 转换CSS文本为pdfmake兼容的styles对象 function convertCssToPdfStyles(cssText) { const parsedCss = css.parse(cssText); const styles = {}; parsedCss.stylesheet.rules.forEach(rule => { if (rule.type !== 'rule') return; rule.selectors.forEach(selector => { // 提取class、id作为style的key let styleKey = selector.trim(); if (styleKey.startsWith('.')) styleKey = styleKey.slice(1); if (styleKey.startsWith('#')) styleKey = styleKey.slice(1); if (!styles[styleKey]) styles[styleKey] = {}; // 处理每个样式声明 rule.declarations.forEach(decl => { if (decl.type !== 'declaration') return; const mapper = cssPropMap[decl.property]; if (!mapper) return; const value = decl.value.trim(); if (typeof mapper === 'function') { const res = mapper(value); if (res) styles[styleKey][res[0]] = res[1]; } else { // 单位转换:px默认转pt,可根据需求调整 let processedVal = value; if (value.endsWith('px')) processedVal = parseFloat(value) * 0.75; if (value.endsWith('pt')) processedVal = parseFloat(value); styles[styleKey][mapper] = processedVal; } }) }) }) return styles; } // 读取CSS文件并转换 const cssContent = fs.readFileSync('./styles/style.css', 'utf8'); const pdfStyles = convertCssToPdfStyles(cssContent); // 最终的文档定义 const documentDefinition = { pageSize: "A4", pageOrientation: "portrait", footer: footer, header: header, content: [ { text: htmlToPdfmake(documentBody, { window: window, useClass: true, // 开启class样式关联 useId: true // 开启id样式关联 }), }, ], styles: pdfStyles }
注意事项
- 该方案仅支持处理单class、单id、单标签类型的CSS选择器,复杂选择器(后代选择器、伪类、属性选择器等)需要额外扩展转换逻辑。
- 可根据自身业务需求扩展
cssPropMap映射表,补充更多CSS属性的转换规则。 - 浏览器环境下将
fs.readFileSync读取CSS的逻辑替换为fetch请求获取CSS文本即可,其余逻辑通用。
内容的提问来源于stack exchange,提问作者Dzsonah
相关产品推荐
相关产品推荐

