23 文字样式定制:字体、间距与文本渲染模式
引入
合同标题、金额与风险提示需要清晰的视觉层级;同一份文档里,中文正文、英文副标题和紧凑表格对字体、间距的要求又各不相同。jquick-pdf 的 style3.txt 已验证一批文本样式属性,本文以“授信审批摘要”为例,串起字体、字号、颜色、字符间距、单词间距与文本渲染模式的配置方法。
环境与依赖见第 21 篇。中文项目可按 README 引入 jquick-pdf-font 获取内置 CJK 字体。
核心讲解
字体、字号与颜色
font:字体类型,取值为枚举风格的大写标识,如font:HELVETICA。fontFamilyNames:字体家族名称,逗号分隔多个候选,如fontFamilyNames:Helvetica,Arial;前面的名称不可用时向后回退。fontSize:字号,直接写数值,如fontSize:24。fontColor:字体颜色,取颜色名、#RRGGBB、rgb()/rgba()。
字号建立层级,颜色用于区分语义(正文深灰、警示红),两者配合比单靠加粗更稳定。注意 fontSize 与尺寸类属性不同,直接写数值而不带单位;font、fontFamilyNames 两者可以只用一个,也可以并列,实际生效的字体以运行环境能提供的字形为准。
字符间距与单词间距
characterSpacing 调整字符间距,wordSpacing 调整单词间距,二者不是同一概念:
characterSpacing:作用于字符之间,对中文同样有效。中文没有空格分词,要让标题“疏排”只能用这个属性。wordSpacing:作用于空格分隔的单词之间,对连续中文基本无效果。splitCharacters:characterSpacing的别名,两种写法等价。
渲染模式与装饰
textRenderingMode 控制文本渲染模式(填充、描边、裁剪等),与 strokeColor、strokeWidth 配合可做出描边字效果。装饰属性包括 bold、italic、underline、lineThrough,取值形态为布尔样式(bold:true)。fontKerning 控制是否启用字距调整,例如 fontKerning:yes。
需要强调:textRenderingMode 的数值不应简单等同于 CSS 或 Canvas 的取值标准,实际效果以生成后的 PDF 为准。
完整示例
import com.github.paohaijiao.executor.JQuickPdfFactory;
import java.nio.file.Files;
import java.nio.file.Paths;
public class TextStyleDemo {
public static void main(String[] args) throws Exception {
String template = "<pdf><body>"
// 标题:字号建立层级 + 深色
+ "<h1 style=\"fontSize:24;fontColor:#1f2937\">'授信审批摘要'</h1>"
// 英文副标题:字体候选 + 字符间距
+ "<p style=\"fontFamilyNames:Helvetica,Arial;fontSize:14;characterSpacing:1\">'Customer Risk Summary'</p>"
// 风险提示:颜色 + 描边
+ "<p style=\"fontSize:18;fontColor:red;strokeColor:#7f1d1d;strokeWidth:1\">'高风险:需要人工复核'</p>"
// 中文正文:wordSpacing 对连续中文影响有限,仅作对照
+ "<p style=\"fontSize:12;wordSpacing:2\">'收入稳定,近十二个月无逾期记录。'</p>"
+ "</body></pdf>";
byte[] pdf = new JQuickPdfFactory().executeContent(template);
Files.write(Paths.get("text-style-report.pdf"), pdf);
}
}
动态字段可用 bind / bindAll 注入模板。文本字面量必须放在单引号内;含逗号或空格的复杂 style 值按示例用引号包裹。
效果如下
关键细节
字体回退与中文显示
fontFamilyNames 是候选列表,名称不存在时发生回退,回退到不含中文字形的字体时中文会显示方框。中文文档应通过 jquick-pdf-font 或已注册字体提供 CJK 字形,具体字体名称以已安装/已注册字体为准。字体决定换行宽度,同一段文本在不同字体环境下断行位置不同,必须用目标运行环境验证。
间距的副作用
间距是布局输入的一部分。characterSpacing 过大会让标题和表格列超宽,触发换行或溢出;wordSpacing 若被误用在中文上,不仅没有效果,还会让预期的排版调整落空。调整间距后要重新检查宽度相关样式与分页。
描边与装饰的取舍
描边宽度过大会覆盖字形影响可读性,小字号上尤其明显;bold、italic、underline、lineThrough 与颜色、字号组合时,样式数量要克制,同一文档保持少量层级比堆叠效果更易维护。
字体宽度与分页
字体不只影响外观,也决定每行容纳的字符数和总行数,进而决定分页位置。依赖字体宽度做精确版面(例如在固定高度的块里塞入固定文案)时,换字体或换运行环境可能直接导致溢出,应留出余量并用目标环境回归。字体资源、布局宽度和可读性要一起验收。
数值与单位
fontSize、characterSpacing、wordSpacing、strokeWidth 等文本相关属性在已验证示例中直接写数值、不跟单位;而 margin*、padding* 等尺寸属性按 px、pt、mm、cm、in 写单位。单位混用是常见的排版偏差来源,改动前先确认属性属于哪一类。
属性命名
驼峰与连字符属性名互为别名,例如 fontSize 与 font-size、characterSpacing 与 character-spacing。同一项目内保持一种写法即可,混用会增加排查成本。
实战说明
步骤
- 先用字号建立标题层级,再设置颜色。
- 英文内容通过
fontFamilyNames提供候选字体。 - 需要疏排的标题用
characterSpacing调整字符间距。 - 风险提示使用
fontColor配strokeColor/strokeWidth。 - 执行
executeContent并写出 PDF。
验证与结果预期
- 标题、英文副标题、中文正文是否形成清晰层级。
- 中文是否出现方框,出现即字体未命中。
- 调整后的标题是否与预期等宽,是否挤占相邻元素。
- 风险行的描边是否影响字形识别。
- 换行位置在目标环境是否稳定。
- 同一段文案在目标部署环境的字体差异下是否仍保持一致。
异常排查
- 中文方框:确认
jquick-pdf-font已引入或字体已注册,再确认fontFamilyNames中的名称真实存在。 - 间距无效:核对是否写错对象,中文疏排应使用
characterSpacing。 - 渲染模式无效果:检查
strokeColor、strokeWidth是否同时给了值。 - 版面被撑宽:回看间距值是否过大。
生产注意事项
固定字体资源与版本,启动时做字体自检;为标题、正文、警告建立少量主题样式;导出后抽样检查中文文本与页数。大量文本不要逐字拼接,模板保持可读;字体资源、布局宽度与可读性应一起验收。
主题样式的最小集合
把标题、正文、警示固化为少量组合——每类各自一套 fontSize 加 fontColor,必要时再叠加一个装饰属性——新增内容时只从这些组合中选择,不临时发明新写法。组合数量越多,改动字体或间距后的回归成本越高;同时控制同一段文本上生效的样式属性数量,也有助于定位排版异常。
适用场景
合同、票据、风控报告和标签是典型场景。bold、italic、underline、lineThrough 可以与颜色、字号组合使用,但同一文档的层级数量应保持克制。
总结
文字样式由四组属性构成:字体与颜色(font、fontFamilyNames、fontSize、fontColor)、间距(characterSpacing / splitCharacters 与 wordSpacing)、渲染模式(textRenderingMode、strokeColor、strokeWidth)和装饰(bold、italic、underline、lineThrough)。其中中文疏排只能用字符间距,wordSpacing 对连续中文基本无效果。
常见误区是假定字体名称一定存在,或用间距去修版面却忽略它对宽度和分页的连带影响。字体回退规则取决于运行环境,中文项目应显式提供字体资源。
版本基线:jquick-pdfx 4.0.0、JDK 8+,升级前请核对 README_zh.md 的版本对照表;更多示例见 GitHub 仓库。