Skip to content

Commit 37b9675

Browse files
committed
nuget package total modernization with breaking changes. Still not fully tested
1 parent b2cf7ed commit 37b9675

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

55 files changed

+1175
-2005
lines changed

FileExporter.sln

Lines changed: 0 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -5,8 +5,6 @@ VisualStudioVersion = 17.6.33723.286
55
MinimumVisualStudioVersion = 10.0.40219.1
66
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "FileExporter", "src\FileExporter\FileExporter.csproj", "{37F75643-3F86-437F-9C88-21AD8C84E6B1}"
77
EndProject
8-
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "FileExporter.Tests", "test\FileExporter.Tests\FileExporter.Tests.csproj", "{9828695B-4FB0-4D29-9F19-469A369DA131}"
9-
EndProject
108
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "FileExporter.Demo", "test\FileExporter.Demo\FileExporter.Demo.csproj", "{4EBD2CC6-CA15-495C-AE54-337B23152710}"
119
EndProject
1210
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution Items", "{1E6E6EA8-2623-46DA-8A61-53429EBCFE0D}"
@@ -32,10 +30,6 @@ Global
3230
{37F75643-3F86-437F-9C88-21AD8C84E6B1}.Debug|Any CPU.Build.0 = Debug|Any CPU
3331
{37F75643-3F86-437F-9C88-21AD8C84E6B1}.Release|Any CPU.ActiveCfg = Release|Any CPU
3432
{37F75643-3F86-437F-9C88-21AD8C84E6B1}.Release|Any CPU.Build.0 = Release|Any CPU
35-
{9828695B-4FB0-4D29-9F19-469A369DA131}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
36-
{9828695B-4FB0-4D29-9F19-469A369DA131}.Debug|Any CPU.Build.0 = Debug|Any CPU
37-
{9828695B-4FB0-4D29-9F19-469A369DA131}.Release|Any CPU.ActiveCfg = Release|Any CPU
38-
{9828695B-4FB0-4D29-9F19-469A369DA131}.Release|Any CPU.Build.0 = Release|Any CPU
3933
{4EBD2CC6-CA15-495C-AE54-337B23152710}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
4034
{4EBD2CC6-CA15-495C-AE54-337B23152710}.Debug|Any CPU.Build.0 = Debug|Any CPU
4135
{4EBD2CC6-CA15-495C-AE54-337B23152710}.Release|Any CPU.ActiveCfg = Release|Any CPU
@@ -50,6 +44,5 @@ Global
5044
GlobalSection(NestedProjects) = preSolution
5145
{37F75643-3F86-437F-9C88-21AD8C84E6B1} = {4459D40A-17C0-4B8D-9F8A-5CBD596EB80E}
5246
{4EBD2CC6-CA15-495C-AE54-337B23152710} = {72F33894-D89A-4D2F-B897-58F7CD1F381E}
53-
{9828695B-4FB0-4D29-9F19-469A369DA131} = {72F33894-D89A-4D2F-B897-58F7CD1F381E}
5447
EndGlobalSection
5548
EndGlobal
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
using System.Reflection;
2+
using FileExporter.Rules;
3+
4+
namespace FileExporter.Dtos;
5+
6+
internal sealed class ExportColumn
7+
{
8+
public required PropertyInfo Property { get; init; }
9+
public required IPropertyRule Rule { get; init; }
10+
}
Lines changed: 9 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,18 +1,15 @@
1-
using Microsoft.AspNetCore.Mvc;
2-
31
namespace FileExporter.Dtos;
42

5-
public class ExportFile(string name, MimeTypes mimeType, byte[] data)
3+
public sealed class ExportFile
64
{
7-
public string Name { get; set; } = name + mimeType.Extension;
8-
public MimeTypes Type { get; set; } = mimeType;
9-
public byte[] Data { get; set; } = data;
10-
11-
public FileContentResult ToFile()
5+
public ExportFile(string name, MimeTypes mimeType, byte[] content)
126
{
13-
return new FileContentResult(Data, Type)
14-
{
15-
FileDownloadName = Name
16-
};
7+
Name = name;
8+
MimeType = mimeType;
9+
Content = content;
1710
}
11+
12+
public string Name { get; }
13+
public MimeTypes MimeType { get; }
14+
public byte[] Content { get; }
1815
}

src/FileExporter/Dtos/MimeTypes.cs

Lines changed: 8 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,23 +1,22 @@
11
namespace FileExporter.Dtos;
22

3-
public class MimeTypes
3+
public sealed class MimeTypes
44
{
5-
public static readonly MimeTypes Csv = new("application/csv", ".csv");
6-
public static readonly MimeTypes Pdf = new("application/pdf", ".pdf");
5+
public static readonly MimeTypes Csv = new("text/csv", ".csv");
76

8-
public static readonly MimeTypes Xlsx = new("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet",
9-
".xlsx");
7+
public static readonly MimeTypes Xlsx =
8+
new("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet", ".xlsx");
109

1110
public static readonly MimeTypes Zip = new("application/zip", ".zip");
1211

13-
private MimeTypes(string value, string fileExtension)
12+
private MimeTypes(string value, string extension)
1413
{
1514
Value = value;
16-
Extension = fileExtension;
15+
Extension = extension;
1716
}
1817

19-
public string Value { get; init; }
20-
public string Extension { get; init; }
18+
public string Value { get; }
19+
public string Extension { get; }
2120

2221
public static implicit operator string(MimeTypes mimeType)
2322
{

src/FileExporter/Dtos/PropertyData.cs

Lines changed: 0 additions & 11 deletions
This file was deleted.
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
namespace FileExporter.Enums;
2+
3+
public enum ColumnFormatType
4+
{
5+
Default,
6+
Text,
7+
Integer,
8+
Decimal,
9+
Currency,
10+
Percentage,
11+
Date,
12+
DateTime,
13+
Boolean
14+
}
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
namespace FileExporter.Enums;
2+
3+
public enum EnumFormatMode
4+
{
5+
MixedIntAndName,
6+
Int,
7+
Name
8+
}
Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,7 @@
11
namespace FileExporter.Enums;
22

3-
public enum ExportType
3+
public enum ExportFormat
44
{
5-
Xlsx = 1,
6-
Csv = 2,
7-
Pdf = 3
5+
Csv,
6+
Xlsx
87
}

src/FileExporter/Exceptions/InvalidPropertyNameException.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,4 +2,4 @@
22

33
namespace FileExporter.Exceptions;
44

5-
public class InvalidPropertyNameException(string message) : Exception(message);
5+
public sealed class InvalidPropertyNameException(string message) : Exception(message);
Lines changed: 99 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,99 @@
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

Comments
 (0)