using QuestPDF.Fluent; using QuestPDF.Helpers; using QuestPDF.Infrastructure; using System.Runtime.InteropServices; using Microsoft.Extensions.Logging; namespace YD_Event.Application.Certificate; /// /// 证书字体助手 - 可靠的中文字体处理 /// public static class CertificateFontHelper { private static bool _fontConfigured = false; private static readonly object _lock = new(); private static string _selectedFont = null; /// /// 配置 QuestPDF 中文字体 /// public static void ConfigureFonts(ILogger logger) { if (_fontConfigured) return; lock (_lock) { if (_fontConfigured) return; try { logger.LogInformation("开始配置 QuestPDF 中文字体..."); // 设置许可证 QuestPDF.Settings.License = LicenseType.Community; // 检测并选择中文字体 _selectedFont = FindAvailableChineseFont(logger); if (!string.IsNullOrEmpty(_selectedFont)) { logger.LogInformation($"成功选中中文字体: {_selectedFont}"); } else { logger.LogWarning("未找到中文字体,将使用默认字体"); } _fontConfigured = true; logger.LogInformation("QuestPDF 字体配置完成"); } catch (Exception ex) { logger.LogError(ex, "配置字体时出错"); } } } /// /// 查找可用的中文字体 /// private static string FindAvailableChineseFont(ILogger logger) { var fontList = GetFontCandidates(); foreach (var font in fontList) { try { logger.LogDebug($"尝试字体: {font}"); if (TestFont(font)) { logger.LogInformation($"字体可用: {font}"); return font; } } catch (Exception ex) { logger.LogDebug(ex, $"字体测试失败: {font}"); } } return null; } /// /// 获取字体候选列表(按优先级排序) /// private static string[] GetFontCandidates() { if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows)) { return new[] { "Microsoft YaHei", // 微软雅黑 "SimHei", // 黑体 "SimSun", // 宋体 "Microsoft YaHei UI", "Segoe UI", "Arial Unicode MS" }; } else if (RuntimeInformation.IsOSPlatform(OSPlatform.Linux)) { return new[] { "WenQuanYi Zen Hei", "WenQuanYi Micro Hei", "Noto Sans CJK SC", "Noto Sans SC", "DejaVu Sans", "Droid Sans Fallback" }; } else { return new[] { "PingFang SC", // macOS "Heiti SC", "STSong", "Arial Unicode MS" }; } } /// /// 测试字体是否可用 /// private static bool TestFont(string fontName) { try { using var stream = new MemoryStream(); Document.Create(container => { container.Page(page => { page.DefaultTextStyle(x => x.FontFamily(fontName)); page.Content().Text("测试中文 Test"); }); }).GeneratePdf(stream); return stream.Length > 0; } catch { return false; } } /// /// 获取选中的字体 /// public static string GetSelectedFont() { return _selectedFont; } /// /// 应用字体到文本样式 /// public static TextStyle ApplyFont(TextStyle style) { if (!string.IsNullOrEmpty(_selectedFont)) { try { return style.FontFamily(_selectedFont); } catch { // 如果字体应用失败,使用默认字体 } } return style; } }