Java中iText库BaseFont.createFont()字体设置详解

5 次阅读

iText是Java生态中应用非常广泛的PDF处理库,开发者经常使用它完成PDF生成、表格绘制、图片嵌入以及文字排版等功能。在实际项目中,字体设置往往是PDF开发中的重点问题,尤其是中文、日文、韩文等非Latin字符的显示。如果字体配置不正确,很容易出现乱码、方框字符或者生成的PDF无法正常打开等问题。

BaseFont.createFont()是iText中用于创建PDF字体对象的核心方法,掌握它的参数含义和使用方式,对于解决PDF字体兼容问题非常重要。

BaseFont.createFont()方法简介

在iText中,BaseFont代表PDF底层字体资源。通过它可以加载系统字体、内置字体以及自定义字体文件,然后将字体应用到Font对象中,最终用于PDF内容生成。

常见方法定义如下:

Java
public static BaseFont createFont(
    String name,
    String encoding,
    boolean embedded
) throws DocumentException, IOException

三个核心参数分别表示:

  • name:字体名称或者字体文件路径

  • encoding:字体编码方式

  • embedded:是否将字体嵌入PDF文件

例如:

Java
BaseFont baseFont = BaseFont.createFont(
    "STSong-Light",
    "UniGB-UCS2-H",
    BaseFont.NOT_EMBEDDED
);

该代码创建了一个支持中文显示的字体对象。


createFont()三个参数详细解析

1. 字体名称 name 参数

name参数决定iText加载哪一种字体。

它既可以是PDF标准字体名称,也可以是本地字体文件路径。

使用PDF内置字体

iText提供了一些标准字体,例如:

Java
BaseFont.createFont(
    BaseFont.HELVETICA,
    BaseFont.WINANSI,
    BaseFont.NOT_EMBEDDED
);

常见内置字体:

字体名称说明
HELVETICA无衬线字体
TIMES_ROMAN衬线字体
COURIER等宽字体
SYMBOL符号字体
ZAPFDINGBATS特殊符号字体

这些字体通常只适合英文和部分西欧字符,不适合中文。


使用Windows系统字体

如果PDF需要显示中文,通常需要加载字体文件。

例如:

Java
String fontPath = "C:/Windows/Fonts/simsun.ttc";

BaseFont bf = BaseFont.createFont(
    fontPath,
    BaseFont.IDENTITY_H,
    BaseFont.EMBEDDED
);

这里加载的是Windows宋体字体。

常见字体文件:

  • simsun.ttc:宋体

  • simhei.ttf:黑体

  • msyh.ttf:微软雅黑

  • simkai.ttf:楷体

Linux环境中则需要指定服务器上的字体路径,例如:

Java
/usr/share/fonts/truetype/wqy/wqy-zenhei.ttc

encoding编码方式详解

字体编码是PDF显示文字的关键因素。

常见编码方式如下:

1. WINANSI

Java
BaseFont.WINANSI

主要用于英文、西欧语言。

例如:

Java
BaseFont.createFont(
    BaseFont.HELVETICA,
    BaseFont.WINANSI,
    false
);

不支持中文。


2. UniGB-UCS2-H

这是iText处理中日韩文字时最常使用的编码。

示例:

Java
BaseFont.createFont(
    "STSong-Light",
    "UniGB-UCS2-H",
    false
);

特点:

  • 支持简体中文

  • 不需要嵌入字体

  • PDF文件体积较小

适合普通中文PDF生成场景。


3. Identity-H

Identity-H是一种Unicode水平编码方式。

示例:

Java
BaseFont.createFont(
    "C:/fonts/msyh.ttf",
    BaseFont.IDENTITY_H,
    BaseFont.EMBEDDED
);

特点:

  • 支持完整Unicode字符

  • 适合中文、生僻字、多语言环境

  • 推荐搭配真实字体文件使用

目前企业项目中生成国际化PDF时,Identity-H使用非常普遍。


embedded参数是否应该开启

第三个参数决定字体是否嵌入PDF。

不嵌入字体

Java
BaseFont.NOT_EMBEDDED

优点:

  • PDF文件较小

  • 创建速度较快

缺点:

  • 打开PDF的设备必须安装对应字体

  • 跨平台容易出现字体替换

例如:

Java
BaseFont.createFont(
    "STSong-Light",
    "UniGB-UCS2-H",
    BaseFont.NOT_EMBEDDED
);

适合内部系统使用。


嵌入字体

Java
BaseFont.EMBEDDED

优点:

  • PDF携带字体文件

  • 任意电脑打开都能正确显示

  • 不依赖操作系统字体

缺点:

  • PDF体积增加

示例:

Java
BaseFont.createFont(
    "C:/Windows/Fonts/simhei.ttf",
    BaseFont.IDENTITY_H,
    BaseFont.EMBEDDED
);

对于合同、发票、报告等正式文件,通常建议开启字体嵌入。


中文PDF生成完整示例

下面是一个常见的中文PDF创建示例:

Java
import com.itextpdf.text.*;
import com.itextpdf.text.pdf.*;

import java.io.FileOutputStream;

public class PdfFontDemo {

    public static void main(String[] args) throws Exception {

        Document document = new Document();

        PdfWriter.getInstance(
            document,
            new FileOutputStream("test.pdf")
        );

        document.open();

        BaseFont baseFont = BaseFont.createFont(
            "C:/Windows/Fonts/simhei.ttf",
            BaseFont.IDENTITY_H,
            BaseFont.EMBEDDED
        );

        Font font = new Font(baseFont, 12);

        Paragraph paragraph =
            new Paragraph("这是使用iText生成的中文PDF文件", font);

        document.add(paragraph);

        document.close();
    }
}

生成后的PDF可以正常显示中文内容。


STSong-Light与本地字体文件的区别

很多开发者会遇到:

Java
BaseFont.createFont(
    "STSong-Light",
    "UniGB-UCS2-H",
    false
);

和:

Java
BaseFont.createFont(
    "simhei.ttf",
    BaseFont.IDENTITY_H,
    true
);

两种写法有什么区别。

STSong-Light方式

特点:

  • 使用PDF内置CJK字体

  • 文件体积小

  • 配置简单

缺点:

  • 字体样式固定

  • 部分特殊字符支持有限

适用于:

  • 普通中文文本

  • 简单报表

  • 数据导出


本地字体方式

特点:

  • 字体样式完全可控

  • 支持更多字符

  • 显示效果更稳定

缺点:

  • PDF体积增加

  • 需要管理字体文件

适用于:

  • 企业文档

  • 电子合同

  • 多语言系统


常见字体设置错误及解决方案

问题一:中文显示为方框

原因:

  • 使用Helvetica等西文字体

  • 编码设置错误

  • 未加载中文字体

错误:

Java
BaseFont.createFont(
    BaseFont.HELVETICA,
    BaseFont.WINANSI,
    false
);

解决:

Java
BaseFont.createFont(
    "simhei.ttf",
    BaseFont.IDENTITY_H,
    BaseFont.EMBEDDED
);

问题二:服务器运行正常,本地打开乱码

原因:

PDF没有嵌入字体,而打开环境没有对应字体。

解决:

开启字体嵌入:

Java
BaseFont.EMBEDDED

问题三:Linux服务器生成PDF乱码

原因:

Linux系统默认没有Windows字体。

解决方案:

  1. 上传字体文件到服务器

  2. 指定绝对路径

  3. 使用Identity-H编码

例如:

Java
BaseFont.createFont(
    "/opt/fonts/simhei.ttf",
    BaseFont.IDENTITY_H,
    BaseFont.EMBEDDED
);

iText 5和iText 7字体设置区别

需要注意的是,BaseFont.createFont()主要属于iText 5版本。

iText 7中字体管理方式进行了调整。

示例:

Java
PdfFont font =
PdfFontFactory.createFont(
    "C:/Windows/Fonts/simhei.ttf",
    PdfEncodings.IDENTITY_H
);

虽然API不同,但核心思想一致:

  • 指定字体文件

  • 设置Unicode编码

  • 根据需求决定是否嵌入

如果项目使用新版iText,应优先采用iText 7推荐方式。


企业项目中的字体配置建议

在实际开发中,建议根据业务场景选择字体策略:

普通数据报表

推荐:

Java
STSong-Light + UniGB-UCS2-H

优点:

  • 简单

  • 文件小

  • 生成速度快


合同、票据、正式文件

推荐:

Java
真实字体文件 + Identity-H + EMBEDDED

优点:

  • 显示一致

  • 不依赖客户端环境

  • 避免法律文档字体异常


多语言PDF

推荐:

  • 使用Unicode字体

  • 使用Identity-H

  • 嵌入字体文件

例如:

  • 思源黑体

  • Noto Sans系列字体

这些字体覆盖范围广,更适合国际化系统。


总结

BaseFont.createFont()是iText生成PDF时控制字体显示的重要入口。正确理解name、encoding和embedded三个参数,可以有效解决中文乱码、字体缺失以及跨平台显示异常等问题。

对于简单中文PDF,可以选择STSong-Light + UniGB-UCS2-H方案;对于企业级应用、合同文件以及多语言场景,更推荐使用真实字体文件配合IDENTITY_H编码,并开启字体嵌入。

掌握iText字体配置机制,不仅能够提升PDF生成质量,也能避免项目上线后因为字体兼容问题产生的大量维护成本。