PDF 生成模板编辑器
开源可视化 PDF 生成引擎,支持自定义模板,并提供面向开发者的 API,灵活构建文档生成流程。
ComPDF SDK 可以读取设备中已安装的字体字族及其样式,并生成可用于注释、表单、水印、页眉页脚、贝茨码等场景的字体 PsName。 本章重点说明三件事:如何理解字族与样式、如何获取可用字体,以及如何导入自定义字体。
Font Family(字族)
字族是字体的系列名称,用于表示一组设计风格一致的字体集合。
例如,Helvetica 是一个字体字族,该字族下可能包含多种样式:
这些字体在整体风格上保持一致,但在字重或倾斜程度上有所区别。
Font Style(样式)
样式用于区分同一字族中的具体变体,例如 Regular、Bold、Italic。
PsName
PsName 是 SDK 用于设置字体的最终名称。通常需要先拿到字族和样式,再通过 CPDFTextAttribute.FontNameHelper.obtainFontName() 生成对应的 PsName。
如果您要为注释或表单设置字体,通常按以下顺序操作:
CPDFFontName 对象。CPDFFontName 中获取该字族支持的样式列表(Font Style)。PsName。PsName 为注释、表单等功能设置字体。下面的示例演示如何获取一个可直接使用的 PsName。实际项目中,您也可以将 fontList 和 fontStyles 展示到界面上,让用户自行选择字体。
public String getFontPsName() {
List<CPDFFontName> fontList = CPDFFont.getFontName();
if (fontList.isEmpty()) {
return null;
}
CPDFFontName fontName = fontList.get(0);
List<String> fontStyles = fontName.getStyleName();
if (fontStyles.isEmpty()) {
return null;
}
return CPDFTextAttribute.FontNameHelper.obtainFontName(
fontName.getFamilyName(),
fontStyles.get(0)
);
}fun getFontPsName(): String? {
val fontName = CPDFFont.getFontName().firstOrNull() ?: return null
val styleName = fontName.styleName.firstOrNull() ?: return null
return CPDFTextAttribute.FontNameHelper.obtainFontName(
fontName.familyName,
styleName
)
}拿到 PsName 后,可按对应功能对象的 API 设置字体。例如:
CPDFFreetextAnnotation.setFreetextDa(new CPDFTextAttribute(psName, fontSize, fontColor))。CPDFListboxWidget.setFontName(psName)。PsName。默认情况下,SDK 使用设备系统中已安装的字体。由于不同地区、不同设备的系统字体集可能存在差异,您可以通过字体导入接口扩展可用字体。
在开始前,请先确认:
.ttf 或 .otf。CPDFSdk.setImportFontDir() 会在 CPDFSdk.init() 之前调用。CPDFSdk.init(),以确保字体目录先完成配置。下面的示例使用 Demo 中的 CFileUtils.copyAssetsDirToPhone() 将 assets/extraFonts 复制到应用私有目录。如果您的项目没有这个工具类,请使用自己的文件复制逻辑完成相同步骤。
// 将 assets 中的字体复制到应用存储目录
String fontDir = new File(getFilesDir(), "extraFonts/").getAbsolutePath();
CFileUtils.copyAssetsDirToPhone(
this,
"extraFonts",
getFilesDir().getAbsolutePath()
);
// 是否同时加载系统字体
boolean addSysFont = true;
// 设置字体导入目录
CPDFSdk.setImportFontDir(fontDir, addSysFont);
// 初始化 SDK
CPDFSdk.init(this, "your license key", true);// 将 assets 中的字体复制到应用存储目录
val fontDir = File(filesDir, "extraFonts/").absolutePath
CFileUtils.copyAssetsDirToPhone(
this,
"extraFonts",
filesDir.absolutePath
)
// 是否同时加载系统字体
val addSysFont = true
// 设置字体导入目录
CPDFSdk.setImportFontDir(fontDir, addSysFont)
// 初始化 SDK
CPDFSdk.init(this, "your license key", true)注意 字体导入目录必须在 SDK 初始化之前设置,否则当前初始化流程不会加载该目录中的字体。
在 SDK 初始化完成后,您仍可通过 CPDFDocument.setImportFontDir() 动态更新当前使用的字体目录。
操作步骤:
CPDFDocument.setImportFontDir(fontDir, addSysFont) 更新当前字体来源。CPDFFont.getFontName(),获取最新的可用字体列表。String fontDir = new File(getFilesDir(), "extraFonts2/").getAbsolutePath();
CFileUtils.copyAssetsDirToPhone(
this,
"extraFonts2",
getFilesDir().getAbsolutePath()
);
boolean addSysFont = true;
// 更新字体目录
CPDFDocument.setImportFontDir(fontDir, addSysFont);val fontDir = File(filesDir, "extraFonts2/").absolutePath
CFileUtils.copyAssetsDirToPhone(
this,
"extraFonts2",
filesDir.absolutePath
)
val addSysFont = true
// 更新字体目录
CPDFDocument.setImportFontDir(fontDir, addSysFont)注意 重新指定字体目录后,之前已设置的字体目录会被清除,仅保留当前指定目录中的字体。
更新完成后,您可以按上一节的流程重新生成 PsName,并将其应用到对应功能对象。