93 lines
3.4 KiB
C#
93 lines
3.4 KiB
C#
using CsvHelper;
|
||
using CsvHelper.Configuration;
|
||
using FATrace.Com;
|
||
using FATrace.OEMApp.Model;
|
||
using NLog;
|
||
using System.Globalization;
|
||
using System.Text;
|
||
|
||
namespace FATrace.OEMApp.Services
|
||
{
|
||
public class CsvService
|
||
{
|
||
private static readonly Logger _logger = LogManager.GetCurrentClassLogger();
|
||
public CsvService()
|
||
{
|
||
RawUseCsvPath = ConfigHelper.GetValue("RawUseCsvPath");
|
||
}
|
||
|
||
/// <summary>
|
||
/// 原料使用信息CSV文件路径
|
||
/// </summary>
|
||
public string RawUseCsvPath { get; set; }
|
||
|
||
/// <summary>
|
||
/// 将一条原料使用记录导出为单独CSV文件(包含表头)
|
||
/// 文件保存目录来自 RawUseCsvPath;文件名包含时间戳与内袋二维码(若有)
|
||
/// </summary>
|
||
/// <param name="data">原料使用记录</param>
|
||
/// <returns>生成的CSV完整路径</returns>
|
||
/// <exception cref="ArgumentNullException">当 data 为空时抛出</exception>
|
||
/// <exception cref="InvalidOperationException">当 RawUseCsvPath 未配置时抛出</exception>
|
||
/// <exception cref="IOException">当写入文件失败时抛出</exception>
|
||
public string ExportSingle(RawUseCsvDto data)
|
||
{
|
||
if (data == null) throw new ArgumentNullException(nameof(data));
|
||
|
||
if (string.IsNullOrWhiteSpace(RawUseCsvPath))
|
||
{
|
||
const string msg = "RawUseCsvPath 未配置,无法导出CSV。";
|
||
_logger.Error(msg);
|
||
throw new InvalidOperationException(msg);
|
||
}
|
||
|
||
try
|
||
{
|
||
// 确保目录存在
|
||
Directory.CreateDirectory(RawUseCsvPath);
|
||
|
||
// 构建安全文件名:时间戳_内袋二维码.csv(若二维码为空则用RawUse代替)
|
||
var safeCode = SanitizeFileName(string.IsNullOrWhiteSpace(data.InBagCode) ? "RawUse" : data.InBagCode!.Trim());
|
||
var fileName = $"{safeCode}.csv";
|
||
var fullPath = Path.Combine(RawUseCsvPath, fileName);
|
||
|
||
var config = new CsvConfiguration(CultureInfo.InvariantCulture)
|
||
{
|
||
HasHeaderRecord = true,
|
||
};
|
||
|
||
using (var writer = new StreamWriter(fullPath, false, new UTF8Encoding(encoderShouldEmitUTF8Identifier: true)))
|
||
using (var csv = new CsvWriter(writer, config))
|
||
{
|
||
csv.Context.RegisterClassMap<RawUseCsvDtoMap>();
|
||
|
||
csv.WriteHeader<RawUseCsvDto>();
|
||
csv.NextRecord();
|
||
csv.WriteRecord(data);
|
||
csv.NextRecord();
|
||
}
|
||
|
||
_logger.Info($"CSV 导出成功: {fullPath}");
|
||
return fullPath;
|
||
}
|
||
catch (Exception ex)
|
||
{
|
||
_logger.Error(ex, "导出原料使用CSV失败。");
|
||
throw new IOException("导出原料使用CSV失败。", ex);
|
||
}
|
||
}
|
||
|
||
private static string SanitizeFileName(string name)
|
||
{
|
||
var invalid = Path.GetInvalidFileNameChars();
|
||
var sb = new StringBuilder(name.Length);
|
||
foreach (var ch in name)
|
||
{
|
||
sb.Append(invalid.Contains(ch) ? '_' : ch);
|
||
}
|
||
var result = sb.ToString();
|
||
return string.IsNullOrWhiteSpace(result) ? "RawUse" : result;
|
||
}
|
||
}
|
||
}
|