239 lines
8.7 KiB
C#

using System;
using System.Collections.Generic;
using System.Data;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using DocumentFormat.OpenXml;
using DocumentFormat.OpenXml.Packaging;
using DocumentFormat.OpenXml.Spreadsheet;
using Font = DocumentFormat.OpenXml.Spreadsheet.Font;
using X14 = DocumentFormat.OpenXml.Office2010.Excel;
using X15 = DocumentFormat.OpenXml.Office2013.Excel;
using X18 = DocumentFormat.OpenXml.Office2021.Excel;
namespace PlaylistManager
{
internal class XLSX
{
internal static void Serialize(string filename, DataTable table)
{
if (table == null) throw new Exception("Data was empty");
using (SpreadsheetDocument document = SpreadsheetDocument.Create(filename, SpreadsheetDocumentType.Workbook))
{
FillDocument(document, table);
}
}
internal static string Serialize(DataTable table)
{
if (table == null) throw new Exception("Data was empty");
MemoryStream ms = new MemoryStream();
using (SpreadsheetDocument document = SpreadsheetDocument.Create(ms, SpreadsheetDocumentType.Workbook))
{
FillDocument(document, table);
}
ms.Seek(0, SeekOrigin.Begin);
return Encoding.UTF8.GetString(ms.ToArray());
}
private static SpreadsheetDocument FillDocument(SpreadsheetDocument document, DataTable table)
{
// Create Content
SheetData sheetData = new SheetData();
Row xlrow = new Row();
foreach (DataColumn col in table.Columns)
{
xlrow.Append(CreateCell(col.ColumnName, 2U));
}
sheetData.Append(xlrow);
foreach (DataRow row in table.Rows)
{
xlrow = new Row();
foreach (DataColumn col in table.Columns)
{
xlrow.Append(CreateCell(row[col.ColumnName], col.DataType));
}
sheetData.Append(xlrow);
}
// Generate WorksheetPart Content
Worksheet worksheet1 = new Worksheet() { MCAttributes = new MarkupCompatibilityAttributes() { Ignorable = "x14ac" } };
worksheet1.AddNamespaceDeclaration("r", "http://schemas.openxmlformats.org/officeDocument/2006/relationships");
worksheet1.AddNamespaceDeclaration("mc", "http://schemas.openxmlformats.org/markup-compatibility/2006");
worksheet1.AddNamespaceDeclaration("x14ac", "http://schemas.microsoft.com/office/spreadsheetml/2009/9/ac");
worksheet1.Append(sheetData);
WorkbookPart workbookPart1 = document.AddWorkbookPart();
workbookPart1.Workbook = new Workbook();
workbookPart1.Workbook.Sheets = new Sheets(new Sheet() { Name = "Sheet1", SheetId = (UInt32Value)1U, Id = "rId1" });
WorkbookStylesPart workbookStylesPart1 = workbookPart1.AddNewPart<WorkbookStylesPart>("rId3");
workbookStylesPart1.Stylesheet = CreateStylesheet();
WorksheetPart worksheetPart1 = workbookPart1.AddNewPart<WorksheetPart>("rId1");
worksheetPart1.Worksheet = worksheet1;
document.Save();
return document;
}
private static Cell CreateCell(string Text, uint StyleIndex = 0U)
{
return CreateCell(Text, typeof(string), StyleIndex);
}
private static Cell CreateCell(object? value, Type type, uint StyleIndex = 0U)
{
Cell cell = new Cell();
cell.StyleIndex = StyleIndex;
if (value == null || value == DBNull.Value)
{
cell.DataType = CellValues.String;
cell.CellValue = new CellValue("");
}
else if (type == typeof(int) || type == typeof(uint))
{
cell.DataType = CellValues.Number;
cell.CellValue = new CellValue((int)value);
}
else if (type == typeof(float) || type == typeof(double))
{
cell.DataType = CellValues.Number;
cell.CellValue = new CellValue((double)value);
}
else if (type == typeof(decimal))
{
cell.DataType = CellValues.Number;
cell.CellValue = new CellValue((decimal)value);
}
else if (type == typeof(bool) || type == typeof(Boolean))
{
cell.DataType = CellValues.Boolean;
cell.CellValue = new CellValue((bool)value);
}
else if (type == typeof(DateTime) || type == typeof(DateOnly) || type == typeof(TimeOnly))
{
cell.StyleIndex = 1U; // Style mit passendem Numberformat
cell.DataType = CellValues.Date;
cell.CellValue = new CellValue(((DateTime)value));
}
else if (type == typeof(DateTimeOffset))
{
cell.DataType = CellValues.Date;
cell.CellValue = new CellValue((DateTimeOffset)value);
}
else if (type == typeof(string) || type == typeof(String))
{
cell.DataType = CellValues.String;
cell.CellValue = new CellValue((string)value);
}
else
{
throw new NotSupportedException($"Unsupported Column type: {type}");
}
return cell;
}
private static Stylesheet CreateStylesheet()
{
uint iExcelIndex = 164;
Stylesheet stylesheet = new Stylesheet();
stylesheet.Fonts = new Fonts(
new Font()
{
Color = new() { Theme = (UInt32Value)1U },
FontSize = new() { Val = 11D },
FontName = new() { Val = "Calibri" },
FontFamilyNumbering = new() { Val = 2 },
FontScheme = new FontScheme() { Val = FontSchemeValues.Minor },
},
new Font()
{
Bold = new(),
Color = new() { Theme = (UInt32Value)1U },
FontSize = new() { Val = 11D },
FontName = new() { Val = "Calibri" },
FontFamilyNumbering = new() { Val = 2 },
FontScheme = new FontScheme() { Val = FontSchemeValues.Minor },
}
)
{ KnownFonts = true };
stylesheet.Fills = new Fills(new Fill());// { Count = (UInt32Value)0U };
stylesheet.Borders = new Borders(new Border());
// ---- CELL STYLE FORMATS ----
NumberingFormat nfDateTime = new NumberingFormat()
{
NumberFormatId = iExcelIndex++,
FormatCode = StringValue.FromString("yyyy-MM-dd HH:mm:ss"),
};
stylesheet.NumberingFormats = new NumberingFormats(nfDateTime);
stylesheet.CellStyleFormats = new CellStyleFormats(
new CellFormat()
{
NumberFormatId = (UInt32Value)0U,
FontId = (UInt32Value)0U,
BorderId = (UInt32Value)0U,
}
);
// ---- CELL FORMATS ----
// NumberFormatID: https://github.com/closedxml/closedxml/wiki/NumberFormatId-Lookup-Table
stylesheet.CellFormats = new CellFormats(
new CellFormat()
{
NumberFormatId = (UInt32Value)0U,
FontId = (UInt32Value)0U,
BorderId = (UInt32Value)0U,
FormatId = (UInt32Value)0U
},
// Mit Datumsformat
new CellFormat()
{
NumberFormatId = nfDateTime.NumberFormatId,
FontId = (UInt32Value)0U,
BorderId = (UInt32Value)0U,
FormatId = (UInt32Value)0U
},
// Bold (Header)
new CellFormat()
{
NumberFormatId = (UInt32Value)0U,
FontId = (UInt32Value)1U,
BorderId = (UInt32Value)0U,
FormatId = (UInt32Value)0U,
ApplyFont = true
}
); ;
stylesheet.CellStyles = new CellStyles(
new CellStyle()
{
Name = "Normal",
FormatId = (UInt32Value)0U,
BuiltinId = (UInt32Value)0U
}
);
return stylesheet;
}
}
}