Distribution_GL Initialization
This commit is contained in:
@@ -0,0 +1,46 @@
|
||||
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;
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user