198 lines
8.0 KiB
C#
198 lines
8.0 KiB
C#
using System;
|
||
using System.Collections.Generic;
|
||
using System.IO;
|
||
|
||
namespace XP.ReportEngine.Configs
|
||
{
|
||
/// <summary>
|
||
/// 报告引擎配置模型 | Report engine configuration model
|
||
/// </summary>
|
||
public class ReportConfig
|
||
{
|
||
/// <summary>
|
||
/// 报告输出文件夹路径 | Report output directory path
|
||
/// </summary>
|
||
public string OutputDirectory { get; set; } = Path.Combine(
|
||
Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments),
|
||
"XplorePlane", "Reports");
|
||
|
||
/// <summary>
|
||
/// 报告模板文件路径(相对或绝对)| Report template file path (relative or absolute)
|
||
/// </summary>
|
||
public string TemplatePath { get; set; } = @"Templates\StandardReportTemplate.json";
|
||
|
||
/// <summary>
|
||
/// 输出文件名模式,支持占位符 | Output file name pattern, supports placeholders
|
||
/// 支持的占位符 | Supported placeholders:
|
||
/// {ReportId} - 报告编号(如 RPT-20250512-001)
|
||
/// {CncProgram} - CNC 程序名称
|
||
/// {ProductName} - 产品名称
|
||
/// {ProductCode} - 产品类型码
|
||
/// {WorkpieceSN} - 工件 SN 码
|
||
/// {DeviceId} - 检测设备编号(本机)
|
||
/// {MachineId} - 生产机台号
|
||
/// {Date} - 日期(yyyyMMdd)
|
||
/// {Time} - 时间(HHmmss)
|
||
/// {Result} - 综合检测结论(Pass/Fail)
|
||
/// </summary>
|
||
public string FileNamePattern { get; set; } = "{ReportId}";
|
||
|
||
/// <summary>
|
||
/// 文件名重复时是否自动累加序号 | Whether to auto-increment suffix when file name duplicates
|
||
/// true: 重复时生成 filename(1).pdf, filename(2).pdf ...
|
||
/// false: 直接覆盖同名文件
|
||
/// </summary>
|
||
public bool AutoIncrementOnDuplicate { get; set; } = true;
|
||
|
||
/// <summary>
|
||
/// 生成后是否自动打开 PDF 阅读器 | Whether to auto-open PDF viewer after generation
|
||
/// </summary>
|
||
public bool AutoOpenAfterGenerate { get; set; } = false;
|
||
|
||
/// <summary>
|
||
/// 默认页面尺寸 | Default page size
|
||
/// </summary>
|
||
public string DefaultPageSize { get; set; } = "A4";
|
||
|
||
/// <summary>
|
||
/// 默认页面方向(Portrait / Landscape)| Default page orientation
|
||
/// </summary>
|
||
public string DefaultOrientation { get; set; } = "Portrait";
|
||
|
||
/// <summary>
|
||
/// 默认上边距(mm)| Default top margin (mm)
|
||
/// </summary>
|
||
public float MarginTop { get; set; } = 20f;
|
||
|
||
/// <summary>
|
||
/// 默认下边距(mm)| Default bottom margin (mm)
|
||
/// </summary>
|
||
public float MarginBottom { get; set; } = 20f;
|
||
|
||
/// <summary>
|
||
/// 默认左边距(mm)| Default left margin (mm)
|
||
/// </summary>
|
||
public float MarginLeft { get; set; } = 20f;
|
||
|
||
/// <summary>
|
||
/// 默认右边距(mm)| Default right margin (mm)
|
||
/// </summary>
|
||
public float MarginRight { get; set; } = 20f;
|
||
|
||
/// <summary>
|
||
/// 报告中显示的公司名称 | Company name displayed in report
|
||
/// </summary>
|
||
public string CompanyName { get; set; } = "海克斯康制造智能技术(青岛)有限公司";
|
||
|
||
/// <summary>
|
||
/// 公司 Logo 图片路径(可选,为空则不显示)| Company logo image path (optional, empty means no logo)
|
||
/// </summary>
|
||
public string CompanyLogo { get; set; } = string.Empty;
|
||
|
||
/// <summary>
|
||
/// 报告中显示的软件名称 | Software name displayed in report
|
||
/// </summary>
|
||
public string SoftwareName { get; set; } = "XplorePlane";
|
||
|
||
/// <summary>
|
||
/// 软件 Logo 图片路径(可选,为空则不显示)| Software logo image path (optional, empty means no logo)
|
||
/// </summary>
|
||
public string SoftwareLogo { get; set; } = string.Empty;
|
||
|
||
/// <summary>
|
||
/// 获取解析后的模板绝对路径 | Get resolved absolute template path
|
||
/// 如果 TemplatePath 是相对路径,则基于应用程序目录解析
|
||
/// If TemplatePath is relative, resolves based on application directory
|
||
/// </summary>
|
||
public string GetResolvedTemplatePath()
|
||
{
|
||
if (Path.IsPathRooted(TemplatePath))
|
||
{
|
||
return TemplatePath;
|
||
}
|
||
return Path.Combine(AppDomain.CurrentDomain.BaseDirectory, TemplatePath);
|
||
}
|
||
|
||
/// <summary>
|
||
/// 根据文件名模式和上下文参数生成实际文件名 | Generate actual file name based on pattern and context parameters
|
||
/// </summary>
|
||
/// <param name="parameters">占位符参数字典 | Placeholder parameter dictionary</param>
|
||
/// <returns>生成的文件名(不含扩展名)| Generated file name (without extension)</returns>
|
||
public string ResolveFileName(Dictionary<string, string> parameters)
|
||
{
|
||
var fileName = FileNamePattern;
|
||
|
||
// 替换所有已知占位符 | Replace all known placeholders
|
||
if (parameters != null)
|
||
{
|
||
foreach (var kvp in parameters)
|
||
{
|
||
fileName = fileName.Replace($"{{{kvp.Key}}}", SanitizeFileName(kvp.Value ?? ""));
|
||
}
|
||
}
|
||
|
||
// 替换日期和时间(始终可用)| Replace date and time (always available)
|
||
fileName = fileName.Replace("{Date}", DateTime.Now.ToString("yyyyMMdd"));
|
||
fileName = fileName.Replace("{Time}", DateTime.Now.ToString("HHmmss"));
|
||
|
||
// 清理未被替换的占位符(替换为空)| Clean up unreplaced placeholders
|
||
fileName = System.Text.RegularExpressions.Regex.Replace(fileName, @"\{[^}]+\}", "");
|
||
|
||
// 移除连续的分隔符 | Remove consecutive separators
|
||
fileName = System.Text.RegularExpressions.Regex.Replace(fileName, @"[_\-]{2,}", "_");
|
||
fileName = fileName.Trim('_', '-');
|
||
|
||
return string.IsNullOrWhiteSpace(fileName) ? "Report" : fileName;
|
||
}
|
||
|
||
/// <summary>
|
||
/// 解析最终输出文件完整路径(含重复累加逻辑)| Resolve final output file full path (with duplicate increment logic)
|
||
/// </summary>
|
||
/// <param name="parameters">占位符参数字典 | Placeholder parameter dictionary</param>
|
||
/// <param name="extension">文件扩展名(含点号,如 ".pdf")| File extension (with dot, e.g. ".pdf")</param>
|
||
/// <returns>最终输出文件完整路径 | Final output file full path</returns>
|
||
public string ResolveOutputFilePath(Dictionary<string, string> parameters, string extension = ".pdf")
|
||
{
|
||
var baseName = ResolveFileName(parameters);
|
||
var outputDir = OutputDirectory;
|
||
|
||
// 确保输出目录存在 | Ensure output directory exists
|
||
if (!Directory.Exists(outputDir))
|
||
{
|
||
Directory.CreateDirectory(outputDir);
|
||
}
|
||
|
||
var filePath = Path.Combine(outputDir, baseName + extension);
|
||
|
||
// 重复累加逻辑 | Duplicate increment logic
|
||
if (AutoIncrementOnDuplicate && File.Exists(filePath))
|
||
{
|
||
int counter = 1;
|
||
string newPath;
|
||
do
|
||
{
|
||
newPath = Path.Combine(outputDir, $"{baseName}({counter}){extension}");
|
||
counter++;
|
||
} while (File.Exists(newPath));
|
||
|
||
filePath = newPath;
|
||
}
|
||
|
||
return filePath;
|
||
}
|
||
|
||
/// <summary>
|
||
/// 清理文件名中的非法字符 | Sanitize illegal characters in file name
|
||
/// </summary>
|
||
private static string SanitizeFileName(string name)
|
||
{
|
||
var invalidChars = Path.GetInvalidFileNameChars();
|
||
foreach (var c in invalidChars)
|
||
{
|
||
name = name.Replace(c, '_');
|
||
}
|
||
return name;
|
||
}
|
||
}
|
||
}
|