使用ClosedXML通过SQL Server作业生成Excel时遇字体找不到问题
本地通过SQL Server作业的C#脚本任务使用ClosedXML生成Excel文件时出现错误,作业以具备本地管理员权限的服务账户运行,报错信息如下:
"Unable to find font Tahoma or fallback font Microsoft Sans Serif. Install missing fonts or specify a different fallback font through 'LoadOptions.DefaultGraphicEngine = new DefaultGraphicEngine("Fallback font name")'."
已确认Tahoma和Microsoft Sans Serif字体存在于C:\Windows\Fonts目录,但在Visual Studio中使用个人账户运行相同代码可成功生成Excel,无任何报错。所有生成操作均为本地执行,无远程调用。
已尝试的解决方法:
- 在代码中添加
LoadOptions.DefaultGraphicEngine = new DefaultGraphicEngine("Fallback font name"),指定的 fallback 字体存在于@"%SYSTEMROOT%\Fonts",@"%APPDATA%\Microsoft\Windows\Fonts",@"%LOCALAPPDATA%\Microsoft\Windows\Fonts"目录中 - 将Tahoma和Microsoft Sans Serif字体复制到上述目录
- 检查服务账户和个人账户的权限配置,未发现拒绝权限
- 分别使用服务账户和个人账户运行SQL Server作业
直接加载字体文件
绕过系统字体检索机制,直接指定字体文件的绝对路径加载,避免账户权限导致的读取问题:var fontPath = @"C:\Windows\Fonts\tahoma.ttf"; var fontCollection = new SixLabors.Fonts.FontCollection(); fontCollection.Install(fontPath); ClosedXML.Excel.LoadOptions.DefaultGraphicEngine = new ClosedXML.Excel.DefaultGraphicEngine(fontCollection.Get("Tahoma"));确认服务账户的字体目录权限
给服务账户添加对C:\Windows\Fonts目录的读取和执行权限,确保账户能访问字体文件。部分场景下,管理员权限可能不包含字体目录的隐性访问权限。嵌入字体资源到项目
将Tahoma字体文件作为嵌入式资源加入项目,从资源流加载字体,完全脱离系统字体依赖:using (var stream = System.Reflection.Assembly.GetExecutingAssembly().GetManifestResourceStream("YourProjectNamespace.tahoma.ttf")) { var fontCollection = new SixLabors.Fonts.FontCollection(); fontCollection.Install(stream); ClosedXML.Excel.LoadOptions.DefaultGraphicEngine = new ClosedXML.Excel.DefaultGraphicEngine(fontCollection.Get("Tahoma")); }注意替换
YourProjectNamespace为实际的项目命名空间,并确保字体文件的嵌入资源属性已设置。验证服务账户的字体可见性
使用服务账户登录系统,打开命令提示符执行dir C:\Windows\Fonts\tahoma*,确认能正常列出字体文件。如果无法看到,将字体复制到服务账户的用户字体目录(如C:\Users\[ServiceAccountName]\AppData\Local\Microsoft\Windows\Fonts)。更新依赖库版本
旧版本的ClosedXML和SixLabors.Fonts可能存在系统字体检索的兼容性问题,更新到最新稳定版本,可能修复权限场景下的字体识别bug。
内容的提问来源于stack exchange,提问作者user4829648

