Files

47 lines
1.7 KiB
C#

using System.Globalization;
using System.Text;
namespace General_Ledger_Service.Services.CsvDocuments
{
// Shared row-building/escaping helper for every report's CSV writer (05_LKAS_Report_PDF_Templates.md
// Section 10) - parallel to Services/PdfDocuments/ReportPageHeader.cs, one small shared piece
// reused by seven otherwise-independent writer classes, not a base class (CLAUDE.md Rule 2).
public class CsvBuilder
{
private readonly StringBuilder _sb = new();
public CsvBuilder AddRow(params object?[] values)
{
_sb.AppendLine(string.Join(",", values.Select(Escape)));
return this;
}
public byte[] Build()
{
// UTF-8 BOM so Excel (the realistic consumer of a downloaded .csv) recognizes the
// encoding instead of guessing at a locale-default codepage.
var preamble = Encoding.UTF8.GetPreamble();
var body = Encoding.UTF8.GetBytes(_sb.ToString());
var result = new byte[preamble.Length + body.Length];
preamble.CopyTo(result, 0);
body.CopyTo(result, preamble.Length);
return result;
}
private static string Escape(object? value)
{
var text = value switch
{
null => "",
decimal d => d.ToString(CultureInfo.InvariantCulture),
DateOnly d => d.ToString("yyyy-MM-dd"),
_ => value.ToString() ?? ""
};
return text.Contains(',') || text.Contains('"') || text.Contains('\n')
? $"\"{text.Replace("\"", "\"\"")}\""
: text;
}
}
}