PdfSharpCore 中文汉字问题处理

  PdfSharpCore是PdfSharp 的.net core版。

问题:
  使用PdfSharpCore会遇到中文乱码问题。我们首先想到的是引用自定义字体。在PdfSharp中解决方案一般代码如下:

1 System.Drawing.Text.PrivateFontCollection pfcFonts = new System.Drawing.Text.PrivateFontCollection();
2 string strFontPath = @"C:/Windows/Fonts/msyh.ttf";//字体设置为微软雅黑
3 pfcFonts.AddFontFile(strFontPath);
4 XPdfFontOptions options = new XPdfFontOptions(PdfFontEncoding.Unicode, PdfFontEmbedding.Always);
5 XFont font = new XFont(pfcFonts.Families[0], 15, XFontStyle.Regular, options);

  然而在PdfSharpCore中这样是不行的。按照代码我们应该是这样的:

1 System.Drawing.Text.PrivateFontCollection pfcFonts = new System.Drawing.Text.PrivateFontCollection();
2 string strFontPath = @"C:/Windows/Fonts/msyh.ttf";//字体设置为微软雅黑
3 pfcFonts.AddFontFile(strFontPath);
4 XPdfFontOptions options = new XPdfFontOptions(PdfFontEncoding.Unicode);
5 XFont font = new XFont(pfcFonts.Families[0].Name, 15, XFontStyle.Regular, options);

  但是这样我们始终获取不到我们指定的字体。

 

原因:

  这个问题是因为XFont构造时,会找入参的字体,如果没有找到指定字体,会找已安装ttf格式字体的第一个。而第一个往往是不支持中文的,所以需要手动指定中文字体。XFont构造代码:

1 XFont font = new XFont("字体名", 20);

"字体名"具体是什么呢?字体中文名,还是?
为了找到答案,下面贴出PdfSharpCore字体查找的部分源码:

复制代码
 1 public virtual FontResolverInfo ResolveTypeface(string familyName, bool isBold, bool isItalic)
 2 {
 3     if (InstalledFonts.Count == 0)
 4         throw new FileNotFoundException("No Fonts installed on this device!");
 5 
 6     if (InstalledFonts.TryGetValue(familyName.ToLower(), out var family))
 7     {
 8         if (isBold && isItalic)
 9         {
10             if (family.FontFiles.TryGetValue(XFontStyle.BoldItalic, out string boldItalicFile))
11                 return new FontResolverInfo(Path.GetFileName(boldItalicFile));
12         }
13         else if (isBold)
14         {
15             if (family.FontFiles.TryGetValue(XFontStyle.Bold, out string boldFile))
16                 return new FontResolverInfo(Path.GetFileName(boldFile));
17         }
18         else if (isItalic)
19         {
20             if (family.FontFiles.TryGetValue(XFontStyle.Italic, out string italicFile))
21                 return new FontResolverInfo(Path.GetFileName(italicFile));
22         }
23 
24         if (family.FontFiles.TryGetValue(XFontStyle.Regular, out string regularFile))
25             return new FontResolverInfo(Path.GetFileName(regularFile));
26 
27         return new FontResolverInfo(Path.GetFileName(family.FontFiles.First().Value));
28     }
29 
30     if (NullIfFontNotFound)
31         return null;
32 
33     string ttfFile = InstalledFonts.First().Value.FontFiles.First().Value;
34     return new FontResolverInfo(Path.GetFileName(ttfFile));
35 }
复制代码

通过以上源码,不难知道这个"字体名"是字体的英文名!

到这里,我们也就知道了为啥下面这种方式为啥找不到中文字体了。

XFont font = new XFont(pfcFonts.Families[0].Name, 15, XFontStyle.Regular, options);

   原因:XFont构造时只支持字体英文名,而"pfcFonts.Families[0].Name"获取的是字体中文名。

解决方案:

  知道原因那就好解决了,只需构造时用字体英文名就好了。

1 XFont font = new XFont("字体英文名", 20);

  这里给出2种获取英文名的途径:

  1.windos环境下获取本地已安装的ttf格式字体英文名:

复制代码
 1  public string GetWindowsFamilyName(string fontName = "方正楷体简体")
 2  {
 3      // 注意,很多字体是收费的,所以找免费的字体,没有的话正规网上下载免费字体安装
 4      // 免费字体(可商用):方正黑体(FZHei-B01S)、方正书宋(FZShuSong-Z01S)、方正仿宋(FZFangSong-Z02S)、方正楷体(FZKai-Z03S)
 5      var fontDir = Environment.ExpandEnvironmentVariables(@"%SystemRoot%\Fonts");
 6      string fontPathFile = Path.Combine($"{fontDir}\\{fontName}.ttf");
 7 
 8      FontDescription fontDescription = FontDescription.LoadDescription(fontPathFile);
 9      string fontFamilyName = fontDescription.FontFamily(CultureInfo.InvariantCulture);
10      return fontFamilyName;
11  }
复制代码

 

  2.通过网址获取:

  http://www.shangaoshuiyuan.com/前端/各字体一览表/

 

字体版权问题:

  注意:字体商用时注意版权问题。

  比如方正系列的除了4种字体,其他都不是免费的:

 

posted @   三个人的酱油  阅读(5162)  评论(8编辑  收藏  举报
编辑推荐:
· AI与.NET技术实操系列:基于图像分类模型对图像进行分类
· go语言实现终端里的倒计时
· 如何编写易于单元测试的代码
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
阅读排行:
· 25岁的心里话
· 闲置电脑爆改个人服务器(超详细) #公网映射 #Vmware虚拟网络编辑器
· 零经验选手,Compose 一天开发一款小游戏!
· 通过 API 将Deepseek响应流式内容输出到前端
· 因为Apifox不支持离线,我果断选择了Apipost!
点击右上角即可分享
微信分享提示