groups)
+ {
+ var sb = new StringBuilder();
+
+ sb.AppendLine("""
+
+
+
+
+
+ SharePoint Duplicate Detection Report
+
+
+
+
+ Duplicate Detection Report
+ """);
+
+ sb.AppendLine($"{groups.Count:N0} duplicate group(s) found.
");
+
+ for (int i = 0; i < groups.Count; i++)
+ {
+ var g = groups[i];
+ int count = g.Items.Count;
+ string badgeClass = "badge-dup";
+
+ sb.AppendLine($"""
+
+
+
+
+
+
+ | # |
+ Library |
+ Path |
+ Size |
+ Created |
+ Modified |
+
+
+
+ """);
+
+ for (int j = 0; j < g.Items.Count; j++)
+ {
+ var item = g.Items[j];
+ string size = item.SizeBytes.HasValue ? FormatSize(item.SizeBytes.Value) : string.Empty;
+ string created = item.Created.HasValue ? item.Created.Value.ToString("yyyy-MM-dd") : string.Empty;
+ string modified = item.Modified.HasValue ? item.Modified.Value.ToString("yyyy-MM-dd") : string.Empty;
+
+ sb.AppendLine($"""
+
+ | {j + 1} |
+ {H(item.Library)} |
+ {H(item.Path)} |
+ {size} |
+ {created} |
+ {modified} |
+
+ """);
+ }
+
+ sb.AppendLine("""
+
+
+
+
+ """);
+ }
+
+ sb.AppendLine($"Generated: {DateTime.Now:yyyy-MM-dd HH:mm}
");
+ sb.AppendLine("");
+
+ return sb.ToString();
+ }
public async Task WriteAsync(IReadOnlyList groups, string filePath, CancellationToken ct)
{
var html = BuildHtml(groups);
- await System.IO.File.WriteAllTextAsync(filePath, html, System.Text.Encoding.UTF8, ct);
+ await System.IO.File.WriteAllTextAsync(filePath, html, Encoding.UTF8, ct);
+ }
+
+ private static string H(string value) =>
+ System.Net.WebUtility.HtmlEncode(value ?? string.Empty);
+
+ private static string FormatSize(long bytes)
+ {
+ if (bytes >= 1_073_741_824L) return $"{bytes / 1_073_741_824.0:F2} GB";
+ if (bytes >= 1_048_576L) return $"{bytes / 1_048_576.0:F2} MB";
+ if (bytes >= 1024L) return $"{bytes / 1024.0:F2} KB";
+ return $"{bytes} B";
}
}