OpenProject PDF 导出样式定制完全指南:YAML 样式文件格式、验证与实战配置
【免费下载链接】openprojectOpenProject is the leading open source project management software for product, project and portfolio management. A powerful Jira alternative with agile planning, issue tracking, roadmaps, Gantt charts, time tracking, collaboration features, and more. Available on premises or in the cloud. ⭐ Star us on GitHub项目地址: https://gitcode.com/GitHub_Trending/op/openproject
本文是 OpenProject 系统管理员的 PDF 导出样式(PDF Export Styling)配置指南,围绕docs/system-admin-guide/design/pdf-export-styles/目录下的官方文档展开。它系统讲解 OpenProject PDF 导出样式文件(YAML)的格式规范、顶层配置结构、通用属性体系(字体、边框、内边距、外边距、单元格对齐等)、单位制以及内置校验脚本的用法。读完本文,你将能够独立定位每种导出模板对应的样式文件,读懂并修改其 YAML 配置,并通过官方校验脚本验证修改的合法性,从而定制出符合企业品牌规范的工作包、报告、甘特图、工时表与会议 PDF 导出。
概述:PDF 导出样式文件与导出模板的对应关系
OpenProject 的 PDF 导出功能采用YAML 样式文件来驱动页面渲染样式。这些文件随 OpenProject 安装包一起分发,每个样式文件对应一种或多种 PDF 导出模板,对应关系如下表(源自 pdf-export-styles/README.md):
| YAML 样式文件 | 对应 PDF 导出模板 |
|---|---|
attributes-and-description/standard.yml | 单一 PDF 导出模板 “Attributes and description”(属性与描述) |
report/standard.yml | PDF 导出模板 “Report”(报告)、“Overview table”(总览表格)与 “Gantt”(甘特图) |
timesheet/standard.yml | Cost 模块的工时表(Timesheet)PDF 导出 |
仓库中实际存在这些样式文件。以工作包相关的导出为例,可以找到:
- app/models/work_package/pdf_export/wp/standard.yml:对应 “Attributes and description” 模板;
- app/models/work_package/pdf_export/report/standard.yml:对应 “Report”、“Overview table” 与 “Gantt” 模板;
- app/models/projects/exports/pdf_export/standard.yml:项目相关导出的样式文件。
[!IMPORTANT] 上述样式文件已包含在你的 OpenProject 安装中。由于 OpenProject 升级时可能覆盖这些文件,修改前后请务必做好备份。官方文档同时提到,管理员配置界面(admin section)正在规划中,可关注 OpenProject 社区工作包跟踪进展。
修改样式后,需要重启 OpenProject 服务器才能生效。官方还提供了一个校验脚本,用来检查修改后的样式文件是否合法:
bundle exec script/pdf_export/validate_styles该脚本位于 script/pdf_export/validate_styles,其核心逻辑是:读取 script/pdf_export/styles.yml 中登记的各样式条目,逐个加载其schema.json与standard.yml,并调用MarkdownToPDF::StyleValidation的validate_schema!进行校验,校验通过会输出Valid: <path>/standard.yml:
config["styles"].each do |entry| validate_styles(entry, root) end def validate_styles(entry, root) puts "Validating #{entry['name']} styles" schema = JSON::load_file(File.join(root, entry["path"], "schema.json")) styles_file = File.join(root, entry["path"], "standard.yml") styles = YAML.load_file(styles_file) validate_schema!(styles, schema) puts "Valid: #{styles_file}" end样式的最小单元:一个最简单的例子
官方文档给出的最小样式示例如下:
border: color: d3dee3 height: 1px其中color是十六进制颜色码(RRGGBB 格式,不带#前缀),height是边框高度(单位为像素)。虽然实际样式文件远不止于此,但这个例子点明了整个样式体系的两大要素:十六进制颜色值与带单位的长度值。
通用属性体系:所有样式文件共用的构建块
四个导出模板的样式文档(attributes-and-description、report、timesheet、meeting)共享一套高度复用的属性组。掌握这些通用属性,就能读懂任何一张样式文件。
字体属性(Font properties)
几乎所有样式块都支持字体属性,官方示例:
font: OpenSans size: 10 character_spacing: 0 styles: [] color: '000000' leading: 2| 键 | 说明 | 数据类型 |
|---|---|---|
font | 字体名称 | string |
size | 字号,>= 0的数字并可带单位,如10mm、10 | number 或 string |
character_spacing | 字符间距,>= 0并可带单位 | number 或 string |
leading | 行距(leading),>= 0并可带单位 | number 或 string |
color | 文字颜色,RRGGBB 格式,如F0F0F0 | string |
styles | 字型数组,合法值:bold、italic、underline、strikethrough、superscript、subscript | array of string |
边框属性(Border Properties)
用于设置元素边框,官方示例覆盖了分边设置能力:
border_color: F000FF border_color_top: 000FFF border_color_bottom: FFF000 no_border_left: true no_border_right: true border_width: 0.25mm border_width_left: 0.5mm border_width_right: 0.5mm| 键 | 说明 | 数据类型 |
|---|---|---|
border_width/border_width_left/border_width_top/border_width_right/border_width_bottom | 全部 / 左 / 上 / 右 / 下 边框宽度,如10mm、10 | number 或 string |
border_color/border_color_left/border_color_top/border_color_right/border_color_bottom | 全部 / 各边边框颜色,RRGGBB | string |
no_border/no_border_left/no_border_top/no_border_right/no_border_bottom | 关闭全部 / 各边边框 | boolean |
内边距属性(Padding Properties)与外边距属性(Margin Properties)
两者结构完全对称,均支持整体与分边设置。内边距示例:
padding: 10mm padding_top: 15mm外边距示例:
margin: 10mm margin_top: 15mm| 键 | 说明 | 数据类型 |
|---|---|---|
padding/padding_left/padding_right/padding_top/padding_bottom | 全部 / 各边内边距 | number 或 string |
margin/margin_left/margin_right/margin_top/margin_bottom | 全部 / 各边外边距 | number 或 string |
单元格对齐属性(Cell alignment properties)
用于设置表格单元格的水平与垂直对齐:
align: center valign: middle| 键 | 说明 | 数据类型 |
|---|---|---|
align | 水平对齐,合法值:left、center、right | string |
valign | 垂直对齐,合法值:top、center、middle、bottom | string |
单位制(Units)
所有长度/数值类属性都支持带单位写法。官方文档明确列出的可用单位为:
mm(毫米)、cm(厘米)、dm(分米)、m(米);in(英寸)、ft(英尺)、yr(码);pt(PostScript 点,未写单位时的默认单位)。
例如size: 10等价于size: 10pt,而border_width: 0.25mm则使用毫米。
模板一:工作包 “Attributes and description” 导出样式
对应文档 attributes-and-description/README.md,实际样式文件为 app/models/work_package/pdf_export/wp/standard.yml。该模板面向工作包详细页的 PDF 导出,顶层键如下:
| 顶层键 | 说明 | 数据类型 |
|---|---|---|
page | 页面基础设置,见“页面设置” | object |
page_logo | 页眉中的 Logo 图片样式 | object |
page_header/page_footer | 页眉 / 页脚样式 | object |
page_heading | 页面主标题样式 | object |
work_package | 工作包区块样式 | object |
wp_table | 相关表格(表单配置)样式 | object |
inline_error/inline_hint | 行内错误 / 提示消息的字体样式 | object(字体属性) |
页面设置(Page settings)
page: page_size: EXECUTIVE margin_top: 60 margin_bottom: 60 margin_left: 36 margin_right: 36 page_break_threshold: 200 link_color: 175A8E| 键 | 说明 | 数据类型 |
|---|---|---|
link_color | 可点击链接的颜色,RRGGBB | string |
page_layout | 页面方向,合法值:portrait、landscape | string |
page_size | 纸张尺寸,合法值涵盖EXECUTIVE、TABLOID、LETTER、LEGAL、FOLIO、A0~A10、B0~B10、C0~C10、RA0~RA4、SRA0~SRA4、4A0、2A0 | string |
page_break_threshold | 分页阈值:当新章节开始且剩余空间小于该阈值时强制新起一页,如10mm、10 | number 或 string |
| 默认字体设置 | 复用字体属性 | 字体属性 |
| 页面边距 | 复用外边距属性 | 外边距属性 |
页眉、页脚、页眉 Logo 与页面标题
page_header: align: left offset: 20 size: 8 page_footer: offset: -30 size: 8 page_logo: height: 20 align: right page_heading: size: 14 styles: - bold margin_bottom: 10page_header.align合法值:left、center、right;offset为相对页面顶部的偏移(可为负数,如-30)。page_footer.offset为相对页面底部的偏移(可为负);spacing为不同页脚之间的最小间距。page_logo支持height(Logo 图片高度)、align、offset(相对页面顶部的偏移)。page_heading复用字体属性与外边距属性。
工作包区块(Work package)
work_package: margin_bottom: 20 subject: {} subject_level_1: {} subject_level_2: {} subject_level_3: {} attributes_table: {} markdown_label: {} markdown_margin: {} markdown: {}| 键 | 说明 | 数据类型 |
|---|---|---|
subject | 工作包主题标题样式 | object |
subject_level_1/subject_level_2/subject_level_x | 各级别工作包主题标题样式(用于层级展示) | object |
attributes_table | 工作包属性表格样式 | object |
attributes_group | 工作包属性组标签标题样式 | object |
markdown_label | 描述与长文本自定义字段的标签标题 | object |
markdown_margin | 描述与长文本自定义字段的外边距 | object |
markdown | 工作包描述与长文本自定义字段内容的 Markdown 样式 | object |
工作包主题与属性表格
subject: size: 10 styles: - bold margin_bottom: 10 subject_level_1: size: 14 styles: - bold subject_level_2: size: 13 styles: - bold subject_level_3: size: 12 styles: - bold属性表格(attributes_table)示例——注意cell(属性值单元格)与cell_label(属性标签单元格)可分别定制:
attributes_table: margin_bottom: 10 cell: size: 9 color: '000000' padding_left: 5 padding_right: 5 padding_top: 0 padding_bottom: 5 border_color: 4B4B4B border_width: 0.25 cell_label: styles: - bold属性组标签(attributes_group)与 Markdown 标签(markdown_label)结构类似:
attributes_group: size: 12 styles: - bold margin_top: 2 margin_bottom: 4Markdown 样式体系(Markdown Styling)
工作包描述与长文本自定义字段的 Markdown 内容支持细粒度定制,骨架如下:
markdown: font: {} header: {} header_1: {} header_2: {} header_3: {} paragraph: {} unordered_list: {} unordered_list_point: {} ordered_list: {} ordered_list_point: {} task_list: {} task_list_point: {} link: {} code: {} blockquote: {} codeblock: {} table: {}各子键对应的样式块:
font、paragraph(正文段落)、code(行内代码)、codeblock(代码块)、blockquote(引用块)、link(可点击链接):复用字体属性,codeblock与blockquote额外支持background_color、内边距、外边距、边框属性;header/header_1/header_2/header_x:Markdown 各级标题,header为各级默认样式,用header_x覆盖第x级,示例:header: styles: - bold padding_top: 2mm padding_bottom: 2mm header_1: size: 14 styles: - bold - italic header_2: size: 12 styles: - boldtable(带表头的 Markdown 表格)、html_table(HTML 表格)、headless_table(无表头或表头为空的表格):均支持auto_width(true时列宽自适应内容,false时等宽分布)、header(表头单元格样式)、cell(单元格样式),并复用外边距与边框属性:table: auto_width: true header: background_color: F0F0F0 no_repeating: true size: 12 cell: background_color: 000FFF size: 10unordered_list/unordered_list_x(无序列表)与unordered_list_point/unordered_list_point_x(列表项):unordered_list支持spacing(列表项间距)与内边距;列表项支持sign(项目符号字符)与spacing:unordered_list: spacing: 1.5mm padding_top: 2mm padding_bottom: 2mm unordered_list_point: sign: "•" spacing: 0.75mmordered_list/ordered_list_point:ordered_list支持spacing与point_inline(为true时不缩进段落文本,而是把序号并入首段);列表项支持template(自定义前缀,如(<number>))、list_style_type(合法值decimal、lower-latin、lower-roman、upper-latin、upper-roman)、spanning(用最大序号的宽度作为缩进量)、spacing。注意alphabetical已标记为deprecated,请改用list_style_type:ordered_list: spacing: 2mm point_inline: false ordered_list_point: template: "<number>." list_style_type: decimal spacing: 0.75mm spanning: truetask_list_point(任务清单项):支持checked(已勾选符号,如"☑")、unchecked(未勾选符号,如"☐")、spacing;image(Markdown 图片):支持max_width(图片最大宽度)、align(left、center、right)、caption(图注样式,支持align与字体属性)以及外边距:image: max_width: 50mm margin: 2mm margin_bottom: 3mm align: center caption: align: center size: 8hrule(水平分割线):支持line_width(线宽)与外边距;alerts(带样式的引用块):包含NOTE、TIP、WARNING、IMPORTANT、CAUTION五个键,每个都是一个alert样式块:ALERT: alert_color: f4f9ff border_color: f4f9ff border_width: 2 no_border_right: true no_border_left: false no_border_bottom: true no_border_top: truealert支持background_color、alert_color(RRGGBB),并复用字体、边框、内边距、外边距属性。blockquote示例(左侧强调边框的引用块):blockquote: background_color: f4f9ff size: 14 styles: - italic color: 0f3b66 border_color: b8d6f4 border_width: 1 no_border_right: true no_border_left: false no_border_bottom: true no_border_top: true
工作包表格(wp_table)
该模板还支持工作包总览相关表格的样式:
overview: group_heading: {} table: {}其中group_heading(启用分组时组标签的样式)与table(总览表格样式)结构与下一节的 “Overview” 一致。
模板二:Report / Overview table / Gantt 导出样式
对应文档 report/README.md,实际样式文件为 app/models/work_package/pdf_export/report/standard.yml。它在上一模板的基础上,额外增加了**封面页(cover)与目录(toc)**的样式,顶层键为:
| 顶层键 | 说明 | 数据类型 |
|---|---|---|
page/page_logo/page_header/page_footer/page_heading | 同“Attributes and description”模板 | object |
work_package | 工作包区块样式 | object |
toc | 报告导出的目录样式 | object |
cover | 报告导出的封面页样式 | object |
wp_table | PDF 表格导出的总览样式 | object |
目录样式(Table of content)
toc: subject_indent: 4 indent_mode: stairs margin_top: 10 margin_bottom: 20 item: size: 9 color: '000000' margin_bottom: 4 item_level_1: size: 10 styles: - bold margin_top: 4 margin_bottom: 4 item_level_2: size: 10| 键 | 说明 | 数据类型 |
|---|---|---|
subject_indent | 各级目录的缩进宽度,如10mm、10 | number 或 string |
indent_mode | 缩进模式:flat(不缩进)、stairs(逐级缩进)、third_level(仅第 3 级缩进) | string |
item | 各级目录项的默认样式;用item_level_x覆盖第x级 | object(字体 + 外边距属性) |
封面页(Cover page)
cover: header: {} footer: {} hero: {}cover_header(封面页眉):支持logo_height(Logo 高度)、spacing(Logo 与页眉文字最小间距)、offset(相对页面顶部偏移)、border(封面页眉分隔线)与字体属性:header: logo_height: 25 border: {}分隔线(
cover_header_border)示例:border: color: d3dee3 height: 1 offset: 6cover_footer(封面页脚):支持offset(相对页面底部偏移,如20)与字体属性:footer: offset: 20 size: 10 color: 064e80cover_hero(封面底部 Hero 横幅):支持padding_right、padding_top,以及四个内容块title(第一块)、heading(主块)、dates(日期块,工时表模板亦有)、subheading(最后一块):header: padding_right: 150 padding_top: 120 title: {} heading: {} subheading: {}各内容块支持
max_height(块最大高度)、spacing(与前一块/后一块的最小间距)与字体属性:title: max_height: 30 spacing: 10 font: SpaceMono size: 10 color: 414d5f heading: spacing: 10 size: 32 color: 414d5f styles: - bold subheading: max_height: 30 size: 10 color: 414d5f styles: - italic dates: max_height: 20 size: 32 color: 414d5f styles: - bold
总览表格(Overview / wp_table)
overview: group_heading: {} table: {}总览表格示例:
table: subject_indent: 0 margin_bottom: 20 cell: size: 9 color: '000000' padding: 5 cell_header: size: 9 styles: - bold cell_sums: size: 8 styles: - bold| 键 | 说明 | 数据类型 |
|---|---|---|
subject_indent | 按工作包层级在主题单元格中缩进 | number 或 string |
cell | 值单元格样式 | object(表格单元格) |
cell_header | 表头单元格样式 | object(表格单元格) |
cell_sums | 汇总单元格样式 | object(表格单元格) |
group_heading(分组标签)示例:
group_heading: size: 11 styles: - bold margin_bottom: 10模板三:Cost 模块工时表(Timesheet)导出样式
对应文档 timesheet/README.md,样式文件位于 Cost/Reporting 模块内(文档中引用的路径为modules/reporting/app/workers/cost_query/pdf/standard.yml)。该模板聚焦于工时表的页面级与封面级样式,顶层键为:page、page_logo、page_header、page_footer、page_heading、cover(其结构与上一模板的封面页完全一致,包含 header / footer / hero 及其 title、heading、dates、subheading 各块)。工时表模板不包含 Markdown 与表格总览相关的样式键,说明其导出内容以结构化数据为主。
模板四:会议(Meeting)导出样式
对应文档 meeting/README.md,样式文件位于 Meeting 模块内(文档中引用的路径为modules/meeting/app/workers/meetings/pdf/standard.yml)。会议 PDF 导出除了页面级与封面级样式外,还有一组会议专属的样式键:
| 顶层键 | 说明 | 数据类型 |
|---|---|---|
page/page_logo/page_header/page_footer/page_heading/page_subtitle | 页面级样式(page_subtitle复用页面标题样式) | object |
cover | 封面页样式 | object |
notes | 议程项备注(Agenda item notes)样式 | object |
outcome | 议程项结论(Agenda item outcome)样式 | object |
heading | 会议导出标题(Heading)样式 | object |
agenda_item | 议程项样式 | object |
agenda_section | 议程章节样式 | object |
participants | 参与者表格样式 | object |
attachments | 附件表格样式 | object |
议程项(agenda_item)与议程章节(agenda_section)
agenda_item: {}| 键 | 说明 | 数据类型 |
|---|---|---|
title_cell | 议程项标题表格单元格样式 | object(表格单元格) |
title/subtitle | 标题 / 副标题字体样式 | object(字体属性) |
title_margin | 标题外边距 | object(外边距属性) |
indent | 议程项备注的缩进宽度,如10mm、10 | number 或 string |
hr | 议程项之间的水平分隔线 | object |
agenda_section结构类似(title_cell、title、subtitle、title_margins)。
议程项备注(notes)与结论(outcome)
notes: markdown_margin: {} markdown: {} outcome: indent: 15 markdown_margin: {} markdown: {}markdown复用前文所述 Markdown 样式体系;markdown_margin为备注/结论的 Markdown 内容外边距(如margin_bottom: 16)。outcome还支持title(结论标题)与symbol(结论符号)的字体样式。
标题(heading)与分隔线
heading: size: 12 styles: - bold margin_bottom: 10heading.hr为“标题前水平分隔线”(border: { color: 6E7781, height: 1.5 });agenda_item.hr为“议程项之间水平分隔线”(border: { color: D0D7DE, height: 1 })。
参与者与附件表格
两者结构对称:
margin_bottom: 12 cell: size: 10 padding_left: 0 no_border: trueparticipants额外支持status(参与者状态文本的字体样式);attachments.cell为附件名称单元格样式。两者均复用外边距属性与表格单元格属性。
实战:从“读懂配置”到“改出企业风格”
综合以上四类模板与通用属性组,你可以用统一的心智模型去修改任意样式文件:
- 定位文件:根据导出模板类型,找到对应的
standard.yml(工作包属性与描述、报告/总览/甘特图样式在app/models/work_package/pdf_export/下,工时表与会议样式分别在 Cost/Reporting 与 Meeting 模块内); - 先备份:复制一份原始
standard.yml,避免 OpenProject 升级或误操作造成样式丢失; - 按需修改:页面级样式改
page.*(纸张、方向、边距、分页阈值、链接色),品牌化改page_logo(Logo 高度与对齐)与page_heading,正文排版改markdown.*,表格观感改*_table/table.cell/table.header; - 校验配置:运行
bundle exec script/pdf_export/validate_styles,脚本会读取 script/pdf_export/styles.yml 登记的所有样式条目并逐一与schema.json比对,输出Valid: ...或报错; - 重启生效:重启 OpenProject 服务器后重新导出 PDF 检查效果。
一个综合示例(工作包 “Attributes and description” 模板的局部定制),展示了颜色(RRGGBB)、单位(mm)、分边边框与各属性组的组合用法:
page: page_size: A4 page_layout: portrait margin_top: 20mm margin_bottom: 20mm margin_left: 15mm margin_right: 15mm page_break_threshold: 30mm link_color: 175A8E page_logo: height: 12mm align: right page_heading: size: 18 styles: - bold color: 0f3b66 margin_bottom: 10 work_package: subject: size: 14 styles: - bold color: 0f3b66 attributes_table: cell: size: 9 border_color: d3dee3 border_width: 0.25 padding_left: 5 padding_right: 5 padding_top: 0 padding_bottom: 5 cell_label: styles: - bold background_color: F0F0F0 markdown: paragraph: align: justify padding_bottom: 2mm code: font: Consolas color: '880000' codeblock: background_color: F5F5F5 font: Consolas size: 8 padding: 3mm margin_top: 2mm margin_bottom: 2mm unordered_list_point: sign: "•" spacing: 0.75mm table: auto_width: true header: background_color: F0F0F0 no_repeating: true size: 12 cell: size: 10小结与延伸阅读
OpenProject 的 PDF 导出样式体系具有三个鲜明特点:统一的属性组(字体、边框、内边距、外边距、对齐)让不同模板的配置语法保持一致;分层的样式键(页面级 → 区块级 → 元素级,如header_x、subject_level_x、item_level_x)支持细粒度的覆盖;schema 驱动的校验(schema.json+validate_styles)保证了修改的可靠性。
如需进一步研究,可在当前仓库中继续查阅:
- 主文档:docs/system-admin-guide/design/pdf-export-styles/README.md
- 各模板样式规范:attributes-and-description、report、timesheet、meeting
- 校验脚本与样式清单:script/pdf_export/validate_styles、script/pdf_export/styles.yml
- 实际样式文件:app/models/work_package/pdf_export/wp/standard.yml、app/models/work_package/pdf_export/report/standard.yml、app/models/projects/exports/pdf_export/standard.yml
【免费下载链接】openprojectOpenProject is the leading open source project management software for product, project and portfolio management. A powerful Jira alternative with agile planning, issue tracking, roadmaps, Gantt charts, time tracking, collaboration features, and more. Available on premises or in the cloud. ⭐ Star us on GitHub项目地址: https://gitcode.com/GitHub_Trending/op/openproject
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考