Skip to content

Commit da9b517

Browse files
authored
feat: Enhance IDataReader export with DynamicColumnFirst and Custom Formatting Delegate (#700)
* Add DynamicColumnFirst in config; * Handle DynamicColumnFirst value assign; Modify DynamicColumns ignore case; * Handle CustomFormatter logic;
1 parent d72312e commit da9b517

File tree

6 files changed

+70
-5
lines changed

6 files changed

+70
-5
lines changed

src/MiniExcel/Attributes/ExcelColumnAttribute.cs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,8 @@ public enum ColumnType { Value, Formula }
5757
public class DynamicExcelColumn : ExcelColumnAttribute
5858
{
5959
public string Key { get; set; }
60+
61+
public Func<object, string> CustomFormatter { get; set; }
6062

6163
public DynamicExcelColumn(string key)
6264
{

src/MiniExcel/IConfiguration.cs

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,5 +10,10 @@ public abstract class Configuration : IConfiguration
1010
public DynamicExcelColumn[] DynamicColumns { get; set; }
1111
public int BufferSize { get; set; } = 1024 * 512;
1212
public bool FastMode { get; set; } = false;
13+
14+
/// <summary>
15+
/// When exporting using DataReader, the data not in DynamicColumn will be filtered.
16+
/// </summary>
17+
public bool DynamicColumnFirst { get; set; } = false;
1318
}
1419
}

src/MiniExcel/OpenXml/ExcelOpenXmlSheetWriter.Async.cs

Lines changed: 46 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -117,8 +117,25 @@ private async Task GenerateSheetByIDataReaderAsync(MiniExcelAsyncStreamWriter wr
117117
for (var i = 0; i < reader.FieldCount; i++)
118118
{
119119
var columnName = reader.GetName(i);
120-
var prop = GetColumnInfosFromDynamicConfiguration(columnName);
121-
props.Add(prop);
120+
121+
if (!_configuration.DynamicColumnFirst)
122+
{
123+
var prop = GetColumnInfosFromDynamicConfiguration(columnName);
124+
props.Add(prop);
125+
continue;
126+
}
127+
128+
if (_configuration
129+
.DynamicColumns
130+
.Any(a => string.Equals(
131+
a.Key,
132+
columnName,
133+
StringComparison.OrdinalIgnoreCase)))
134+
135+
{
136+
var prop = GetColumnInfosFromDynamicConfiguration(columnName);
137+
props.Add(prop);
138+
}
122139
}
123140
maxColumnIndex = props.Count;
124141

@@ -149,7 +166,18 @@ private async Task GenerateSheetByIDataReaderAsync(MiniExcelAsyncStreamWriter wr
149166
var xIndex = 1;
150167
for (int i = 0; i < fieldCount; i++)
151168
{
152-
var cellValue = reader.GetValue(i);
169+
object cellValue;
170+
171+
if (_configuration.DynamicColumnFirst)
172+
{
173+
var columnIndex = reader.GetOrdinal(props[i].Key.ToString());
174+
cellValue = reader.GetValue(columnIndex);
175+
}
176+
else
177+
{
178+
cellValue = reader.GetValue(i);
179+
}
180+
153181
await WriteCellAsync(writer, yIndex, xIndex, cellValue, props[i], widths);
154182
xIndex++;
155183
}
@@ -534,7 +562,21 @@ private async Task WriteCellAsync(MiniExcelAsyncStreamWriter writer, int rowInde
534562
var columnType = p.ExcelColumnType;
535563

536564
/*Prefix and suffix blank space will lost after SaveAs #294*/
537-
var preserveSpace = cellValue != null && (cellValue.StartsWith(" ", StringComparison.Ordinal) || cellValue.EndsWith(" ", StringComparison.Ordinal));
565+
var preserveSpace = cellValue != null && (cellValue.StartsWith(" ", StringComparison.Ordinal) ||
566+
cellValue.EndsWith(" ", StringComparison.Ordinal));
567+
568+
if (p.CustomFormatter != null)
569+
{
570+
try
571+
{
572+
cellValue = p.CustomFormatter(cellValue);
573+
}
574+
catch (Exception e)
575+
{
576+
//ignored
577+
}
578+
}
579+
538580
await writer.WriteAsync(WorksheetXml.Cell(columnReference, dataType, styleIndex, cellValue, preserveSpace: preserveSpace, columnType: columnType));
539581
widthCollection?.AdjustWidth(cellIndex, cellValue);
540582
}

src/MiniExcel/OpenXml/ExcelOpenXmlSheetWriter.DefaultOpenXml.cs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -192,7 +192,7 @@ private ExcelColumnInfo GetColumnInfosFromDynamicConfiguration(string columnName
192192
if (_configuration.DynamicColumns == null || _configuration.DynamicColumns.Length <= 0)
193193
return prop;
194194

195-
var dynamicColumn = _configuration.DynamicColumns.SingleOrDefault(_ => _.Key == columnName);
195+
var dynamicColumn = _configuration.DynamicColumns.SingleOrDefault(_ => string.Equals(_.Key , columnName,StringComparison.OrdinalIgnoreCase));
196196
if (dynamicColumn == null || dynamicColumn.Ignore)
197197
{
198198
return prop;
@@ -203,6 +203,7 @@ private ExcelColumnInfo GetColumnInfosFromDynamicConfiguration(string columnName
203203
prop.ExcelColumnType = dynamicColumn.Type;
204204
prop.ExcelColumnIndex = dynamicColumn.Index;
205205
prop.ExcelColumnWidth = dynamicColumn.Width;
206+
prop.CustomFormatter = dynamicColumn.CustomFormatter;
206207
//prop.ExcludeNullableType = item2[key]?.GetType();
207208

208209
if (dynamicColumn.Format != null)

src/MiniExcel/OpenXml/ExcelOpenXmlSheetWriter.cs

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -570,6 +570,19 @@ private void WriteCell(MiniExcelStreamWriter writer, int rowIndex, int cellIndex
570570
var styleIndex = tuple.Item1; // https://learn.microsoft.com/en-us/dotnet/api/documentformat.openxml.spreadsheet.cell?view=openxml-3.0.1
571571
var dataType = tuple.Item2; // https://learn.microsoft.com/en-us/dotnet/api/documentformat.openxml.spreadsheet.cellvalues?view=openxml-3.0.1
572572
var cellValue = tuple.Item3;
573+
574+
if (columnInfo?.CustomFormatter != null)
575+
{
576+
try
577+
{
578+
cellValue = columnInfo.CustomFormatter(cellValue);
579+
}
580+
catch (Exception e)
581+
{
582+
//ignored
583+
}
584+
}
585+
573586
var columnType = columnInfo?.ExcelColumnType ?? ColumnType.Value;
574587

575588
/*Prefix and suffix blank space will lost after SaveAs #294*/

src/MiniExcel/Utils/CustomPropertyHelper.cs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@ internal class ExcelColumnInfo
2525
public bool ExcelIgnore { get; internal set; }
2626
public int ExcelFormatId { get; internal set; }
2727
public ColumnType ExcelColumnType { get; internal set; }
28+
public Func<object, string> CustomFormatter { get; set; }
2829
}
2930

3031
internal class ExcellSheetInfo
@@ -310,6 +311,7 @@ internal static void SetDictionaryColumnInfo(List<ExcelColumnInfo> _props, objec
310311
isIgnore = dynamicColumn.Ignore;
311312
p.ExcelColumnWidth = dynamicColumn.Width;
312313
p.ExcelColumnType = dynamicColumn.Type;
314+
p.CustomFormatter = dynamicColumn.CustomFormatter;
313315
}
314316
}
315317
if (!isIgnore)

0 commit comments

Comments
 (0)