概述
许多文档格式都与字体紧密绑定。例如,当用户向 DOCX 文档中添加文本时,这段文本总是具有某种已定义的字体。有些文档格式通常会将字体数据嵌入到文档文件本身中,比如 PDF。但其他格式,如 Office 系列格式,通常依赖于操作系统中已安装的字体。
字体格式也有很多。例如,绝大多数已安装的字体以 TTF(TrueType) 和 OTF(OpenType) 格式呈现。Office Open XML 文档还支持 EOT(Embedded OpenType) 格式。而在 Web 上,最常用的格式是 WOFF 和 WOFF2。
目录
获取所有使用的字体
在字体相关的场景中,最有用的功能是列出并返回它们。GroupDocs.Viewer 提供了一个专用方法 GetAllFonts() —— 当文档被加载到 Viewer 类的实例中时,调用此方法即可获取文档中使用的所有字体列表。返回的列表中,每个字体都以实现了 IFontInfo 接口的对象形式呈现。该接口包含每种可能字体的通用属性:族名、样式、格式以及二进制内容。
特定格式族(如 WordProcessing、Spreadsheet、Presentation 和 PDF)都有各自对 IFontInfo 的实现;这些实现提供了针对相应格式族的更多专有数据。例如,WordProcessingFontInfo、PresentationFontInfo 和 PdfFontInfo 类型包含 IsEmbedded 布尔属性——用于指示该字体是嵌入在已加载文档主体中,还是已安装在操作系统中。SpreadsheetFontInfo 类型则包含大量电子表格专用的字体信息:颜色、是否加下划线或删除线等。WordProcessingFontInfo 可能还包含备用族名,诸如此类。
下面给出一个简短示例:
using GroupDocs.Viewer;
// ...
const string filename = "sample.docx";
string inputPath = "\full\path\" + filename;
using (Viewer viewer = new Viewer(inputPath))
{
Fonts.IFontInfo[] allFonts = viewer.GetAllFonts();
Console.WriteLine("{0} fonts found in the '{1}' document", allFonts.Length, filename);
foreach (Fonts.IFontInfo font in allFonts)
{
Console.WriteLine("Font '{0}' of '{1}' style has {2} bytes and is of '{3}' format",
font.FamilyName,
font.Style,
font.Content.Length,
font.Format);
}
}
请注意,字体提取仅支持 WordProcessing、Spreadsheet、Presentation 和 PDF 这几类格式;对于其他文档格式,GetAllFonts() 方法将返回空数组。
处理缺失的字体
一种常见情形是:文档最初在作者机器上创建并使用了某种字体 “AAA”,随后在 客户机器上使用 GroupDocs.Viewer 进行处理,而该机器缺少字体 “AAA”。此时 GroupDocs.Viewer 会尝试 替代该字体,使用一套复杂的字体替代规则:它会分析文档的元数据、缺失字体的备用名称、文档设置、操作系统设置、系统已安装的所有字体等。最终,如果操作系统“非常干净”,即根本没有任何已安装字体,GroupDocs.Viewer 将使用嵌入在 GroupDocs.Viewer 程序集中(DLL)的字体作为最后的补救。例如,对于 WordProcessing 系列格式,GroupDocs.Viewer 内部存储了免费字体 “Fanwood”。
当前,GroupDocs.Viewer 在文档 渲染期间(调用 Viewer.View() 方法时)静默执行 字体替代 操作——不会产生任何消息或事件来告知哪些字体缺失、被替代为哪种字体、以及具体针对哪个文档。实现此类通知功能相当困难,因为很难确定应以何种形式、何种内容提供通知,以及客户端应如何利用这些信息。
不过,GroupDocs.Viewer 为用户提供了两种解决方案:手动 指定 缺失字体,或手动 替代 缺失字体。
指定缺失的字体
如果用户一开始就知道某个文档使用了字体 “AAA”,并且知道目标机器上没有安装该字体,同时手头拥有该字体 “AAA”的二进制内容,则可以在调用 Viewer.View() 方法之前 指定 该字体。
要指定一个或多个未在目标操作系统中安装的自定义字体,用户需要 添加自定义字体来源。字体来源 实际上是一个文件夹,里面存放一个或多个字体文件。对应的类是 FolderFontSource。随后通过 FontSettings 类的 SetFontSources() 方法将 字体来源 添加到 GroupDocs.Viewer。
下面的代码片段演示了这一过程。假设 “sample.docx” 文档使用了罕见字体 “AAA.ttf”,该字体未安装在目标操作系统中。用户将 “AAA.ttf” 放入 "C:\custom_fonts" 文件夹,然后创建指向该文件夹的 FolderFontSource 实例。随后将该实例传递给 FontSettings 静态类,最后将 “sample.docx” 渲染为 HTML。结果,在生成的 HTML 文档中会使用 “AAA” 字体。
using GroupDocs.Viewer;
using GroupDocs.Viewer.Options;
using GroupDocs.Viewer.Fonts;
// ...
// 指定字体来源。
FolderFontSource fontSource =
new FolderFontSource(@"C:\custom_fonts", SearchOption.TopFolderOnly);
FontSettings.SetFontSources(fontSource);
using (Viewer viewer = new Viewer("sample.docx"))
{
// 创建 HTML 文件。
HtmlViewOptions viewOptions = HtmlViewOptions.ForEmbeddedResources();
viewer.View(viewOptions);
}
替换缺失的字体
如果用户一开始就知道某个文档使用了字体 “AAA”,并且知道目标机器上没有该字体,但手头 没有 该字体的二进制内容,则可以指定另一种字体 “BBB”,让它在渲染时 代替 缺失的 “AAA”。与前一种情况不同,这需要通过 视图选项 来实现,然后将这些选项传递给 Viewer.View() 方法。
此选项称为 DefaultFontName,它是抽象类 BaseViewOptions 中声明的字符串属性,因此对所有渲染选项均通用:HtmlViewerOptions、PdfViewOptions、PngViewOptions、以及 JpgViewOptions。
当指定此选项后,GroupDocs.Viewer 在渲染时会使用该字体来替代所有不可用的字体。例如,文档包含非英文字符的字体时,指定默认字体名称可确保 GroupDocs.Viewer 用具有相同字符集的字体来替换任何缺失的字体。当然,DefaultFontName 所指的字体必须已安装在执行渲染的操作系统上。
以下代码片段演示了如何设置默认字体名称:
using GroupDocs.Viewer;
using GroupDocs.Viewer.Options;
// ...
using (Viewer viewer = new Viewer("sample.pptx"))
{
// 创建用于渲染 HTML 文档(带嵌入资源)的选项。
HtmlViewOptions viewOptions = HtmlViewOptions.ForEmbeddedResources();
// 在选项中指定默认字体名称。
viewOptions.DefaultFontName = "Courier New";
// 将输入 PPTX 渲染为输出 HTML。
viewer.View(viewOptions);
}
在 HTML 中排除字体
将文档渲染为 HTML 格式时,GroupDocs.Viewer 默认会把所有使用的字体导出到 HTML 文档中。这保证了即使观看设备上缺少相应字体,也能正确显示。字体可以作为外部资源(HtmlViewOptions.ForExternalResources)存储,亦或通过 data URI scheme 结合 base64 编码直接嵌入到 HTML 标记中(HtmlViewOptions.ForEmbeddedResources)。几乎所有自身支持字体的文档格式都支持导出字体到 HTML:Microsoft Office(除 Excel 外)、OpenDocument、电子邮件、PDF、电子书等。
然而,有时该功能并非所需。实际上,嵌入字体会显著增大生成的 HTML 文档体积。如果目标机器或设备已经预装了所有使用的字体,浏览器完全可以直接使用系统字体。
为满足此类需求,GroupDocs.Viewer 提供了 排除字体 的能力,可通过两种方式实现:排除所有字体 或 仅排除特定字体。
这两种方式均通过 HtmlViewOptions 类的不同属性来控制:
ExcludeFonts是一个布尔标记,启用后(true)会禁止将任何使用的字体导出到生成的 HTML 文档中,默认值为false(未禁用)。FontsToExclude是一个字符串列表,每个元素表示一个需要从生成的 HTML 文档中排除的字体名称。默认情况下列表为空——不排除任何字体。请注意,仅当ExcludeFonts为false时此属性才会生效。
下面的两个代码片段分别演示了这两种可能性:第一个使用 ExcludeFonts,第二个使用 FontsToExclude。
using GroupDocs.Viewer;
using GroupDocs.Viewer.Options;
// ...
using (Viewer viewer = new Viewer("sample.docx"))
{
// 创建 HTML 文件。
var viewOptions = HtmlViewOptions.ForEmbeddedResources();
viewOptions.ExcludeFonts = true;
viewer.View(viewOptions);
}
using GroupDocs.Viewer;
using GroupDocs.Viewer.Options;
// ...
using (Viewer viewer = new Viewer("presentation.pptx"))
{
// 创建 HTML 文件。
var viewOptions = HtmlViewOptions.ForEmbeddedResources();
viewOptions.FontsToExclude.Add("Times New Roman"); // 排除 Times New Roman 字体。
viewOptions.FontsToExclude.Add("Arial"); // 排除 Arial 字体。
viewer.View(viewOptions);
}
结论
GroupDocs.Viewer 的核心定位是将各种格式的文档渲染为常见的“可查看”格式——HTML、PDF、JPEG 和 PNG。近期我们在字体处理方面新增了多项实用功能,帮助用户查看和检查使用的字体、调节字体导出行为以及自定义字体替代策略。
另请参阅
获取免费试用版
您可以从 releases.groupdocs.com 下载 GroupDocs.Viewer for .NET 的免费试用版。也可以通过此处获取临时许可证,以无限制地试用全部功能和特性。