iText是Java生态中应用非常广泛的PDF处理库,开发者经常使用它完成PDF生成、表格绘制、图片嵌入以及文字排版等功能。在实际项目中,字体设置往往是PDF开发中的重点问题,尤其是中文、日文、韩文等非Latin字符的显示。如果字体配置不正确,很容易出现乱码、方框字符或者生成的PDF无法正常打开等问题。
BaseFont.createFont()是iText中用于创建PDF字体对象的核心方法,掌握它的参数含义和使用方式,对于解决PDF字体兼容问题非常重要。
BaseFont.createFont()方法简介
在iText中,BaseFont代表PDF底层字体资源。通过它可以加载系统字体、内置字体以及自定义字体文件,然后将字体应用到Font对象中,最终用于PDF内容生成。
常见方法定义如下:
Javapublic static BaseFont createFont( String name, String encoding, boolean embedded ) throws DocumentException, IOException
三个核心参数分别表示:
-
name:字体名称或者字体文件路径 -
encoding:字体编码方式 -
embedded:是否将字体嵌入PDF文件
例如:
JavaBaseFont baseFont = BaseFont.createFont( "STSong-Light", "UniGB-UCS2-H", BaseFont.NOT_EMBEDDED );
该代码创建了一个支持中文显示的字体对象。
createFont()三个参数详细解析
1. 字体名称 name 参数
name参数决定iText加载哪一种字体。
它既可以是PDF标准字体名称,也可以是本地字体文件路径。
使用PDF内置字体
iText提供了一些标准字体,例如:
JavaBaseFont.createFont( BaseFont.HELVETICA, BaseFont.WINANSI, BaseFont.NOT_EMBEDDED );
常见内置字体:
| 字体名称 | 说明 |
|---|---|
| HELVETICA | 无衬线字体 |
| TIMES_ROMAN | 衬线字体 |
| COURIER | 等宽字体 |
| SYMBOL | 符号字体 |
| ZAPFDINGBATS | 特殊符号字体 |
这些字体通常只适合英文和部分西欧字符,不适合中文。
使用Windows系统字体
如果PDF需要显示中文,通常需要加载字体文件。
例如:
JavaString 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
JavaBaseFont.WINANSI
主要用于英文、西欧语言。
例如:
JavaBaseFont.createFont( BaseFont.HELVETICA, BaseFont.WINANSI, false );
不支持中文。
2. UniGB-UCS2-H
这是iText处理中日韩文字时最常使用的编码。
示例:
JavaBaseFont.createFont( "STSong-Light", "UniGB-UCS2-H", false );
特点:
-
支持简体中文
-
不需要嵌入字体
-
PDF文件体积较小
适合普通中文PDF生成场景。
3. Identity-H
Identity-H是一种Unicode水平编码方式。
示例:
JavaBaseFont.createFont( "C:/fonts/msyh.ttf", BaseFont.IDENTITY_H, BaseFont.EMBEDDED );
特点:
-
支持完整Unicode字符
-
适合中文、生僻字、多语言环境
-
推荐搭配真实字体文件使用
目前企业项目中生成国际化PDF时,Identity-H使用非常普遍。
embedded参数是否应该开启
第三个参数决定字体是否嵌入PDF。
不嵌入字体
JavaBaseFont.NOT_EMBEDDED
优点:
-
PDF文件较小
-
创建速度较快
缺点:
-
打开PDF的设备必须安装对应字体
-
跨平台容易出现字体替换
例如:
JavaBaseFont.createFont( "STSong-Light", "UniGB-UCS2-H", BaseFont.NOT_EMBEDDED );
适合内部系统使用。
嵌入字体
JavaBaseFont.EMBEDDED
优点:
-
PDF携带字体文件
-
任意电脑打开都能正确显示
-
不依赖操作系统字体
缺点:
-
PDF体积增加
示例:
JavaBaseFont.createFont( "C:/Windows/Fonts/simhei.ttf", BaseFont.IDENTITY_H, BaseFont.EMBEDDED );
对于合同、发票、报告等正式文件,通常建议开启字体嵌入。
中文PDF生成完整示例
下面是一个常见的中文PDF创建示例:
Javaimport 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与本地字体文件的区别
很多开发者会遇到:
JavaBaseFont.createFont( "STSong-Light", "UniGB-UCS2-H", false );
和:
JavaBaseFont.createFont( "simhei.ttf", BaseFont.IDENTITY_H, true );
两种写法有什么区别。
STSong-Light方式
特点:
-
使用PDF内置CJK字体
-
文件体积小
-
配置简单
缺点:
-
字体样式固定
-
部分特殊字符支持有限
适用于:
-
普通中文文本
-
简单报表
-
数据导出
本地字体方式
特点:
-
字体样式完全可控
-
支持更多字符
-
显示效果更稳定
缺点:
-
PDF体积增加
-
需要管理字体文件
适用于:
-
企业文档
-
电子合同
-
多语言系统
常见字体设置错误及解决方案
问题一:中文显示为方框
原因:
-
使用Helvetica等西文字体
-
编码设置错误
-
未加载中文字体
错误:
JavaBaseFont.createFont( BaseFont.HELVETICA, BaseFont.WINANSI, false );
解决:
JavaBaseFont.createFont( "simhei.ttf", BaseFont.IDENTITY_H, BaseFont.EMBEDDED );
问题二:服务器运行正常,本地打开乱码
原因:
PDF没有嵌入字体,而打开环境没有对应字体。
解决:
开启字体嵌入:
JavaBaseFont.EMBEDDED
问题三:Linux服务器生成PDF乱码
原因:
Linux系统默认没有Windows字体。
解决方案:
-
上传字体文件到服务器
-
指定绝对路径
-
使用Identity-H编码
例如:
JavaBaseFont.createFont( "/opt/fonts/simhei.ttf", BaseFont.IDENTITY_H, BaseFont.EMBEDDED );
iText 5和iText 7字体设置区别
需要注意的是,BaseFont.createFont()主要属于iText 5版本。
iText 7中字体管理方式进行了调整。
示例:
JavaPdfFont font = PdfFontFactory.createFont( "C:/Windows/Fonts/simhei.ttf", PdfEncodings.IDENTITY_H );
虽然API不同,但核心思想一致:
-
指定字体文件
-
设置Unicode编码
-
根据需求决定是否嵌入
如果项目使用新版iText,应优先采用iText 7推荐方式。
企业项目中的字体配置建议
在实际开发中,建议根据业务场景选择字体策略:
普通数据报表
推荐:
JavaSTSong-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生成质量,也能避免项目上线后因为字体兼容问题产生的大量维护成本。