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构造时只支持字体英文名,而"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种字体,其他都不是免费的: