1+ using System ;
2+ using System . Collections . Generic ;
3+ using System . Globalization ;
4+ using System . IO ;
5+ using System . Linq ;
6+ using CsvHelper ;
7+ using CsvHelper . Configuration ;
8+ using FileExporter . Dtos ;
9+ using FileExporter . Helpers ;
10+ using FileExporter . Rules ;
11+
12+ namespace FileExporter . Exporters ;
13+
14+ internal static class CsvExporter
15+ {
16+ public static ExportFile Export < T > ( IEnumerable < T > data , ExportRule < T > rule )
17+ where T : class
18+ {
19+ ArgumentNullException . ThrowIfNull ( data ) ;
20+
21+ ArgumentNullException . ThrowIfNull ( rule ) ;
22+
23+ var columns = BuildColumns ( rule ) ;
24+ var baseName = rule . FileName ;
25+ var fileName = NamingHelper . EnsureExtension ( baseName , MimeTypes . Csv . Extension ) ;
26+
27+ using var ms = new MemoryStream ( ) ;
28+ using ( var writer = new StreamWriter ( ms , new System . Text . UTF8Encoding ( true ) , leaveOpen : true ) )
29+ {
30+ var config = new CsvConfiguration ( CultureInfo . InvariantCulture )
31+ {
32+ HasHeaderRecord = true
33+ } ;
34+
35+ using var csv = new CsvWriter ( writer , config ) ;
36+
37+ foreach ( var column in columns )
38+ {
39+ csv . WriteField ( column . Rule . ColumnName ) ;
40+ }
41+
42+ csv . NextRecord ( ) ;
43+
44+ foreach ( var item in data )
45+ {
46+ foreach ( var column in columns )
47+ {
48+ var raw = column . Property . GetValue ( item ) ;
49+ var formatted = ValueFormatter . FormatForCsv ( raw , column . Rule , CultureInfo . InvariantCulture ) ;
50+ csv . WriteField ( formatted ) ;
51+ }
52+
53+ csv . NextRecord ( ) ;
54+ }
55+ }
56+
57+ var bytes = ms . ToArray ( ) ;
58+
59+ if ( bytes . Length < ExportLimits . ZipThresholdBytes )
60+ {
61+ return new ExportFile ( fileName , MimeTypes . Csv , bytes ) ;
62+ }
63+
64+ var zipped = ZipHelper . CreateZip ( fileName ,
65+ MimeTypes . Csv ,
66+ new List < byte [ ] >
67+ {
68+ bytes
69+ } ) ;
70+ return zipped ;
71+ }
72+
73+ private static List < ExportColumn > BuildColumns < T > ( ExportRule < T > rule )
74+ where T : class
75+ {
76+ var modelType = typeof ( T ) ;
77+ var properties = modelType
78+ . GetProperties ( )
79+ . ToDictionary ( p => p . Name , p => p , StringComparer . Ordinal ) ;
80+
81+ var columns = new List < ExportColumn > ( ) ;
82+
83+ foreach ( var r in rule . Rules )
84+ {
85+ if ( ! properties . TryGetValue ( r . PropertyName , out var property ) )
86+ {
87+ continue ;
88+ }
89+
90+ columns . Add ( new ExportColumn
91+ {
92+ Property = property ,
93+ Rule = r
94+ } ) ;
95+ }
96+
97+ return columns ;
98+ }
99+ }
0 commit comments