You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何为iText7/pdfhtml设置默认字体?HTML转PDF表格字体异常排查

解决iText HtmlConverter字体不符合需求的问题

你的问题主要出在两个核心点上:

  1. 默认的DefaultFontProvider没有正确注册Verdana的粗体、斜体变体,导致遇到<b>/<i>标签时,找不到对应的Verdana字体,只能回退到系统中的其他替代字体(比如AgencyFB粗体、BookAntiqua斜体)。
  2. 直接给转换后的元素强制设置Property.FONT的方式,既无法适配HTML标签自带的字体变体需求,也没针对性地处理第二个评论中span的特殊字体要求。

下面是具体的修复方案:

1. 自定义FontProvider,确保字体变体齐全

首先创建一个自定义字体提供器,注册Verdana的所有必要变体(常规、粗体、斜体、粗斜体)以及AgencyFB,并将全局默认字体设置为Verdana,这样所有未指定字体的文本都会优先使用Verdana。

public class CustomFontProvider : DefaultFontProvider
{
    public CustomFontProvider() : base(false, false, true)
    {
        // 注册Verdana的各个字体变体(根据实际情况调整:系统字体用名称,嵌入字体用文件路径)
        AddFont("Verdana", PdfEncodings.CP1252);
        AddFont("Verdana Bold", PdfEncodings.CP1252);
        AddFont("Verdana Italic", PdfEncodings.CP1252);
        AddFont("Verdana Bold Italic", PdfEncodings.CP1252);
        
        // 注册AgencyFB字体
        AddFont("AgencyFB", PdfEncodings.CP1252);
        
        // 设置全局默认字体为Verdana
        SetDefaultFont("Verdana");
    }
}

提示:如果使用嵌入字体(而非系统已安装字体),需要将字体文件(如Verdana.ttf、VerdanaBold.ttf)添加到项目中,并在AddFont时指定正确路径,例如AddFont(@"Fonts/Verdana.ttf", PdfEncodings.CP1252)。

2. 调整HtmlConverter的转换逻辑

更新InsertHtmlCell方法,使用自定义的CustomFontProvider,同时移除直接强制设置元素字体的代码,让字体提供器自动处理默认字体逻辑:

private void InsertHtmlCell(Table table, float defaultFontSize, string comment)
{
    var cell = new Cell(1, 1);
    ConverterProperties prop = new ConverterProperties();
    
    // 绑定自定义字体提供器
    prop.SetFontProvider(new CustomFontProvider());
    // 设置全局默认字体大小
    prop.SetFontSize(defaultFontSize);
    
    var elements = HtmlConverter.ConvertToElements(comment, prop).Cast<IBlockElement>();
    foreach (var element in elements)
    {
        // 不再强制覆盖元素字体,交给FontProvider处理默认规则
        cell.Add(element);
    }
    table.AddCell(cell);
}

3. 给第二个评论的span指定特殊字体

根据需求,仅第二个示例的span使用AgencyFB,所以修改comment2的HTML,给每个span加上font-family: 'AgencyFB'的样式:

string comment2 = "&lt;div&gt;&lt;span style=\"font-size: 18px; font-family: 'AgencyFB'\"&gt;large&lt;/span&gt;&lt;div&gt;&lt;div&gt;&lt;span style=\"font-size: 11px; font-family: 'AgencyFB'\"&gt;medium&lt;/span&gt;&lt;div&gt;&lt;div&gt;&lt;span style=\"font-size: 8px; font-family: 'AgencyFB'\"&gt;small&lt;/span&gt;&lt;/div&gt;";

4. 调整主方法的调用逻辑

修改CreateDoc中调用InsertHtmlCell的代码,不再传递默认字体参数(字体逻辑已由CustomFontProvider接管):

public byte[] CreateDoc() { 
    using (MemoryStream stream = new MemoryStream()) { 
        using (PdfWriter writer = new PdfWriter(stream)) { 
            PdfDocument pdfDoc = new PdfDocument(writer); 
            Document doc = new Document(pdfDoc, PageSize.A4); 
            float fontSize = 11f; 
            Table table = new Table(1); 
            table.AddCell(new Cell().Add(new Paragraph("no Html").SetFont(PdfFontFactory.CreateRegisteredFont("Verdana", PdfEncodings.CP1252, true)).SetFontSize(fontSize))); 
            string comment1 = "&lt;div&gt;a &lt;b&gt;bold&lt;/b&gt; and an &lt;i&gt;italic&lt;/i&gt; text.&lt;/div&gt;"; 
            string comment2 = "&lt;div&gt;&lt;span style=\"font-size: 18px; font-family: 'AgencyFB'\"&gt;large&lt;/span&gt;&lt;div&gt;&lt;div&gt;&lt;span style=\"font-size: 11px; font-family: 'AgencyFB'\"&gt;medium&lt;/span&gt;&lt;div&gt;&lt;div&gt;&lt;span style=\"font-size: 8px; font-family: 'AgencyFB'\"&gt;small&lt;/span&gt;&lt;/div&gt;"; 
            InsertHtmlCell(table, fontSize, comment1); 
            InsertHtmlCell(table, fontSize, comment2); 
            doc.Add(table); 
            doc.Close(); 
            pdfDoc.Close(); 
        } 
        return stream.ToArray(); 
    } 
}

修复原理说明

  • 自定义FontProvider确保了Verdana的所有变体都能被找到,<b>会自动使用Verdana Bold,<i>会使用Verdana Italic,不会再回退到其他字体。
  • 全局默认字体设为Verdana,所以第一个评论的所有文本(普通、粗体、斜体)都会使用Verdana。
  • 第二个评论的span通过font-family样式指定使用AgencyFB,FontProvider会正确加载并应用该字体,满足你的特殊需求。

内容的提问来源于stack exchange,提问作者Penguin

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.07 07:34:09