Skip to content

Commit

Permalink
tune
Browse files Browse the repository at this point in the history
  • Loading branch information
mustaddon committed Nov 7, 2021
1 parent 301aaa4 commit c8ee931
Showing 1 changed file with 64 additions and 62 deletions.
126 changes: 64 additions & 62 deletions ArrayToExcel/ArrayToExcel.cs
Original file line number Diff line number Diff line change
Expand Up @@ -17,63 +17,61 @@ public static byte[] CreateExcel<T>(IEnumerable<T> items, Action<SchemaBuilder<T
{
var builder = new SchemaBuilder<T>(items);
schema?.Invoke(builder);
return _createExcel(new[] { builder.Schema }.Concat(builder.Childs));
return CreateExcel(new[] { builder.Schema }.Concat(builder.Childs));
}

static byte[] _createExcel(IEnumerable<SheetSchema> sheetSchemas)
static byte[] CreateExcel(IEnumerable<SheetSchema> sheetSchemas)
{
using (var ms = new MemoryStream())
using var ms = new MemoryStream();
using (var document = SpreadsheetDocument.Create(ms, SpreadsheetDocumentType.Workbook))
{
using (var document = SpreadsheetDocument.Create(ms, SpreadsheetDocumentType.Workbook))
{
var workbookpart = document.AddWorkbookPart();
workbookpart.Workbook = new Workbook();
var workbookpart = document.AddWorkbookPart();
workbookpart.Workbook = new Workbook();

var sheets = workbookpart.Workbook.AppendChild(new Sheets());

var sheets = document.WorkbookPart.Workbook.AppendChild(new Sheets());
AddStyles(workbookpart);

_addStyles(document);
var sheetId = 1u;

var sheetId = 1u;
foreach (var sheetSchema in sheetSchemas)
{
var worksheetPart = workbookpart.AddNewPart<WorksheetPart>();
worksheetPart.Worksheet = new Worksheet();

foreach (var sheetSchema in sheetSchemas)
sheets.Append(new Sheet()
{
var worksheetPart = workbookpart.AddNewPart<WorksheetPart>();
worksheetPart.Worksheet = new Worksheet();

sheets.Append(new Sheet()
{
Id = document.WorkbookPart.GetIdOfPart(worksheetPart),
SheetId = sheetId++,
Name = _normSheetName(sheetSchema.SheetName),
});

if (sheetSchema.Columns.Count > 0)
{
var cols = worksheetPart.Worksheet.AppendChild(new Columns());
cols.Append(sheetSchema.Columns.Select((x, i) => new Column() { Min = (uint)(i + 1), Max = (uint)(i + 1), Width = x.Width, CustomWidth = true, BestFit = true }));

var rows = _getRows(sheetSchema.Items, sheetSchema.Columns);
var sheetData = worksheetPart.Worksheet.AppendChild(new SheetData());
sheetData.Append(rows);

worksheetPart.Worksheet.Append(new AutoFilter() { Reference = $"A1:{_getColReference(sheetSchema.Columns.Count - 1)}{rows.Length}" });
}
}
Id = workbookpart.GetIdOfPart(worksheetPart),
SheetId = sheetId++,
Name = NormSheetName(sheetSchema.SheetName),
});

workbookpart.Workbook.Save();
if (sheetSchema.Columns.Count > 0)
{
var cols = worksheetPart.Worksheet.AppendChild(new Columns());
cols.Append(sheetSchema.Columns.Select((x, i) => new Column() { Min = (uint)(i + 1), Max = (uint)(i + 1), Width = x.Width, CustomWidth = true, BestFit = true }));

var rows = GetRows(sheetSchema.Items, sheetSchema.Columns);
var sheetData = worksheetPart.Worksheet.AppendChild(new SheetData());
sheetData.Append(rows);

worksheetPart.Worksheet.Append(new AutoFilter() { Reference = $"A1:{GetColReference(sheetSchema.Columns.Count - 1)}{rows.Length}" });
}
}
return ms.ToArray();

workbookpart.Workbook.Save();
}
return ms.ToArray();
}

static string _normSheetName(string value)
static string NormSheetName(string value)
{
return value.Length > 31 ? value.Substring(0, 28) + "..." : value;
}

static void _addStyles(SpreadsheetDocument document)
static void AddStyles(WorkbookPart workbookPart)
{
var stylesPart = document.WorkbookPart.AddNewPart<WorkbookStylesPart>();
var stylesPart = workbookPart.AddNewPart<WorkbookStylesPart>();
stylesPart.Stylesheet = new Stylesheet();

// fonts
Expand All @@ -88,9 +86,13 @@ static void _addStyles(SpreadsheetDocument document)
stylesPart.Stylesheet.Fills = new Fills();
stylesPart.Stylesheet.Fills.AppendChild(new Fill { PatternFill = new PatternFill { PatternType = PatternValues.None } }); // required, reserved by Excel
stylesPart.Stylesheet.Fills.AppendChild(new Fill { PatternFill = new PatternFill { PatternType = PatternValues.Gray125 } }); // required, reserved by Excel
var fill2 = stylesPart.Stylesheet.Fills.AppendChild(new Fill { PatternFill = new PatternFill() { PatternType = PatternValues.Solid } });
fill2.PatternFill.ForegroundColor = new ForegroundColor { Rgb = HexBinaryValue.FromString("FF4F81BD") };
fill2.PatternFill.BackgroundColor = new BackgroundColor { Indexed = 64 };
stylesPart.Stylesheet.Fills.AppendChild(new Fill {
PatternFill = new PatternFill() {
PatternType = PatternValues.Solid,
ForegroundColor = new ForegroundColor { Rgb = HexBinaryValue.FromString("FF4F81BD") },
BackgroundColor = new BackgroundColor { Indexed = 64 },
},
});
stylesPart.Stylesheet.Fills.Count = (uint)stylesPart.Stylesheet.Fills.ChildElements.Count;

// borders
Expand Down Expand Up @@ -120,13 +122,13 @@ static void _addStyles(SpreadsheetDocument document)
stylesPart.Stylesheet.Save();
}

static Row[] _getRows(IEnumerable items, List<ColumnSchema> columns)
static Row[] GetRows(IEnumerable items, List<ColumnSchema> columns)
{
var rows = new List<Row>();

var headerCells = columns.Select((x, i) => new Cell
{
CellReference = _getColReference(i),
CellReference = GetColReference(i),
CellValue = new CellValue(x.Name),
DataType = CellValues.String,
StyleIndex = 1,
Expand All @@ -140,60 +142,60 @@ static Row[] _getRows(IEnumerable items, List<ColumnSchema> columns)
foreach (var item in items)
{
var row = new Row() { RowIndex = (uint)i++ };
var cells = columns.Select((x, i) => _getCell(headerCells[i].CellReference, x.Value?.Invoke(item))).ToArray();
var cells = columns.Select((x, i) => GetCell(headerCells[i].CellReference, x.Value?.Invoke(item))).ToArray();
row.Append(cells);
rows.Add(row);
}
return rows.ToArray();
}

static Cell _getCell(string reference, object? value)
static Cell GetCell(string? reference, object? value)
{
var dataType = _getCellType(value);
var dataType = GetCellType(value);
return new Cell
{
CellReference = reference,
CellValue = _getCellValue(value),
CellValue = GetCellValue(value),
DataType = dataType,
StyleIndex = dataType == CellValues.Date ? 2 : 0u,
};
}

static CellValue _getCellValue(object? value)
static CellValue GetCellValue(object? value)
{
if (value == null) return new CellValue();
if (value == null) return new ();

var type = value.GetType();

if (type == typeof(bool))
return new CellValue((bool)value ? "1" : "0");
return new ((bool)value ? "1" : "0");

if (type == typeof(DateTime))
return new CellValue(((DateTime)value).ToString("s", _cultureInfo));
return new (((DateTime)value).ToString("s", _cultureInfo));

if (type == typeof(DateTimeOffset))
return new CellValue(((DateTimeOffset)value).ToString("s", _cultureInfo));
return new (((DateTimeOffset)value).ToString("s", _cultureInfo));

if (type == typeof(double))
return new CellValue(((double)value).ToString(_cultureInfo));
return new (((double)value).ToString(_cultureInfo));

if (type == typeof(decimal))
return new CellValue(((decimal)value).ToString(_cultureInfo));
return new (((decimal)value).ToString(_cultureInfo));

if (type == typeof(float))
return new CellValue(((float)value).ToString(_cultureInfo));
return new (((float)value).ToString(_cultureInfo));

return new CellValue(_removeInvalidXmlChars(value.ToString()));
return new (RemoveInvalidXmlChars(value.ToString()));
}

static string _removeInvalidXmlChars(string text)
static string RemoveInvalidXmlChars(string text)
{
return string.IsNullOrEmpty(text) ? text
: new Regex(@"(?<![\uD800-\uDBFF])[\uDC00-\uDFFF]|[\uD800-\uDBFF](?![\uDC00-\uDFFF])|[\x00-\x08\x0B\x0C\x0E-\x1F\x7F-\x9F\uFEFF\uFFFE\uFFFF]", RegexOptions.Compiled)
.Replace(text, string.Empty);
}

static CellValues _getCellType(object? value)
static CellValues GetCellType(object? value)
{
var type = value?.GetType() ?? typeof(object);

Expand All @@ -209,7 +211,7 @@ static CellValues _getCellType(object? value)
return CellValues.String;
}

static string _getColReference(int index)
static string GetColReference(int index)
{
var result = new List<char>();
while (index >= _digits.Length)
Expand All @@ -223,7 +225,7 @@ static string _getColReference(int index)
return new string(result.ToArray());
}

static HashSet<Type> _numericTypes = new HashSet<Type>
static readonly HashSet<Type> _numericTypes = new ()
{
typeof(short),
typeof(ushort),
Expand All @@ -236,8 +238,8 @@ static string _getColReference(int index)
typeof(float),
};

static CultureInfo _cultureInfo = CultureInfo.GetCultureInfo("en-US");
static readonly CultureInfo _cultureInfo = CultureInfo.GetCultureInfo("en-US");

static string _digits = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
static readonly string _digits = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
}
}

0 comments on commit c8ee931

Please sign in to comment.