Files
XplorePlane/XP.ReportEngine/Services/EncodingResolver.cs
T
QI Mingxuan d72b583319 [XP.ReportEngine] 新增 TXT/CSV/Excel 三种报告输出格式支持;Excel (.xlsx) 报告生成器,基于 ClosedXML,支持结构化生成和模板填充两种模式; 新增 XplorePlane_ReportTemplate.xlsx:Excel 报告模板文件。
[XP.ReportEngine] 模型与配置扩展:ReportOutputFormat 枚举:新增 Excel=1, Csv=2, Txt=3(显式序号,向后兼容);新增多格式相关配置加载。
2026-07-01 11:31:41 +08:00

109 lines
5.6 KiB
C#
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
using System;
using System.Text;
using XP.Common.Logging.Interfaces;
namespace XP.ReportEngine.Services
{
/// <summary>
/// 文本编码解析器 | Text encoding resolver
/// 为 TXT/CSV 报告生成器提供统一的编码解析逻辑(需求 5)
/// Provides unified encoding resolution logic for TXT/CSV report generators (Requirement 5)
/// </summary>
/// <remarks>
/// 设计为静态帮助类,便于 TxtReportGenerator / CsvReportGenerator(或其公共基类 TextReportGeneratorBase)复用。
/// Designed as a static helper so TxtReportGenerator / CsvReportGenerator (or their base class
/// TextReportGeneratorBase) can reuse the same encoding resolution logic.
///
/// 注意:GB2312/GBK 在 .NET 8 中需先注册 CodePagesEncodingProvider 才可用,
/// 该注册由 ReportEngineModule 在初始化阶段幂等完成。
/// Note: GB2312/GBK require CodePagesEncodingProvider to be registered on .NET 8;
/// that registration is performed idempotently by ReportEngineModule during initialization.
/// </remarks>
internal static class EncodingResolver
{
/// <summary>
/// 记录代码页编码提供程序是否已注册,保证幂等注册 | Tracks whether the code page encoding provider has been registered, to keep registration idempotent
/// </summary>
private static bool _codePagesProviderRegistered;
/// <summary>
/// 用于注册操作的同步锁 | Synchronization lock for the registration operation
/// </summary>
private static readonly object _registerLock = new object();
/// <summary>
/// 幂等注册代码页编码提供程序 | Idempotently register the code page encoding provider
/// 多次调用仅实际注册一次,使 GB2312/GBK 等代码页编码在 .NET 8 中可用。
/// Multiple calls register only once, enabling code page encodings such as GB2312/GBK on .NET 8.
/// </summary>
public static void EnsureCodePagesRegistered()
{
if (_codePagesProviderRegistered)
{
return;
}
lock (_registerLock)
{
if (_codePagesProviderRegistered)
{
return;
}
// 注册代码页编码提供程序(重复调用 RegisterProvider 是安全的)| Register code page encoding provider (calling RegisterProvider repeatedly is safe)
Encoding.RegisterProvider(CodePagesEncodingProvider.Instance);
_codePagesProviderRegistered = true;
}
}
/// <summary>
/// 根据配置字符串解析文本编码 | Resolve text encoding from the configuration string
/// 支持的取值(不区分大小写)| Supported values (case-insensitive):
/// Utf8Bom(默认)→ UTF-8 with BOM(起始字节 EF BB BF| UTF-8 with BOM (leading bytes EF BB BF)
/// Utf8 → UTF-8 without BOM | UTF-8 without BOM
/// GB2312 → GB2312 代码页编码 | GB2312 code page encoding
/// GBK → GBK 代码页编码 | GBK code page encoding
/// 无效或不受支持的取值将回退到 UTF-8 with BOM 并记录 Warn 日志(需求 5.4)
/// Invalid or unsupported values fall back to UTF-8 with BOM and a Warn log is recorded (Requirement 5.4)
/// </summary>
/// <param name="textEncoding">编码配置字符串(来自 ReportConfig.TextEncoding| Encoding config string (from ReportConfig.TextEncoding)</param>
/// <param name="logger">日志服务,用于记录无效配置的 Warn 日志(可为 null| Logger service for warning on invalid config (may be null)</param>
/// <returns>解析后的编码实例 | Resolved encoding instance</returns>
public static Encoding Resolve(string textEncoding, ILoggerService logger)
{
// 确保代码页编码提供程序已注册,使 GB2312/GBK 可用 | Ensure code page provider is registered so GB2312/GBK are available
EnsureCodePagesRegistered();
var normalized = textEncoding?.Trim();
switch (normalized?.ToUpperInvariant())
{
case null:
case "":
case "UTF8BOM":
// 默认 UTF-8 with BOM(需求 5.1/5.2| Default UTF-8 with BOM (Requirements 5.1/5.2)
return new UTF8Encoding(encoderShouldEmitUTF8Identifier: true);
case "UTF8":
// UTF-8 without BOM(需求 5.3| UTF-8 without BOM (Requirement 5.3)
return new UTF8Encoding(encoderShouldEmitUTF8Identifier: false);
case "GB2312":
// GB2312 代码页编码(需求 5.3| GB2312 code page encoding (Requirement 5.3)
return Encoding.GetEncoding("GB2312");
case "GBK":
// GBK 代码页编码(需求 5.3| GBK code page encoding (Requirement 5.3)
return Encoding.GetEncoding("GBK");
default:
// 无效配置:回退默认编码并记录 Warn 日志(需求 5.4| Invalid config: fall back to default encoding and log Warn (Requirement 5.4)
logger?.Warn(
"无效的文本编码配置: {Value},已回退使用 UTF-8 with BOM | Invalid text encoding config: {Value}, fell back to UTF-8 with BOM",
textEncoding);
return new UTF8Encoding(encoderShouldEmitUTF8Identifier: true);
}
}
}
}