using System.IO; using System.Text; using SharepointToolbox.Core.Models; namespace SharepointToolbox.Services.Export; /// /// Exports SearchResult list to a UTF-8 BOM CSV file. /// Header matches the column order in SearchHtmlExportService for consistency. /// public class SearchCsvExportService { public string BuildCsv(IReadOnlyList results) { var sb = new StringBuilder(); // Header sb.AppendLine("File Name,Extension,Path,Created,Created By,Modified,Modified By,Size (bytes)"); foreach (var r in results) { sb.AppendLine(string.Join(",", Csv(IfEmpty(System.IO.Path.GetFileName(r.Path), r.Title)), Csv(r.FileExtension), Csv(r.Path), r.Created.HasValue ? Csv(r.Created.Value.ToString("yyyy-MM-dd")) : string.Empty, Csv(r.Author), r.LastModified.HasValue ? Csv(r.LastModified.Value.ToString("yyyy-MM-dd")) : string.Empty, Csv(r.ModifiedBy), r.SizeBytes.ToString())); } return sb.ToString(); } public async Task WriteAsync(IReadOnlyList results, string filePath, CancellationToken ct) { var csv = BuildCsv(results); await System.IO.File.WriteAllTextAsync(filePath, csv, new UTF8Encoding(encoderShouldEmitUTF8Identifier: true), ct); } private static string Csv(string value) { if (string.IsNullOrEmpty(value)) return string.Empty; if (value.Contains(',') || value.Contains('"') || value.Contains('\n')) return $"\"{value.Replace("\"", "\"\"")}\""; return value; } private static string IfEmpty(string? value, string fallback = "") => string.IsNullOrEmpty(value) ? fallback : value!; }