Skip to content

Commit

Permalink
ClosedXML 依賴版本補上 TableThemeShader,新增錯誤處理範例
Browse files Browse the repository at this point in the history
  • Loading branch information
maxzh1999tw committed Dec 10, 2023
1 parent c70b3f8 commit 811890c
Show file tree
Hide file tree
Showing 5 changed files with 201 additions and 3 deletions.
1 change: 0 additions & 1 deletion Excely.ClosedXML/Shaders/ErrorMarkShader.cs
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,6 @@ public class ErrorMarkShader : XlsxShaderBase
public XLColor TextColor { get; set; } = XLColor.Red;

/// <param name="errorCells">匯入錯誤資料</param>
/// <param name="author">Comment 作者(不得為空)</param>
public ErrorMarkShader(Dictionary<CellLocation, string> errorCells)
{
CellErrors = errorCells;
Expand Down
100 changes: 100 additions & 0 deletions Excely.ClosedXML/Shaders/TableThemeShader.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,100 @@
using ClosedXML.Excel;
using System.Drawing;

namespace Excely.ClosedXML.Shaders
{
/// <summary>
/// 將一段範圍內的儲存格視為表格,並為其套上表格造型。
/// </summary>
public class TableThemeShader : XlsxShaderBase
{
/// <summary>
/// 表格左上角的儲存格座標。
/// </summary>
public CellLocation StartCell { get; set; } = new(0, 0);

/// <summary>
/// 表頭高度。
/// </summary>
public int SchemaHeight { get; set; } = 1;

/// <summary>
/// 表格寬度。
/// </summary>
public int TableWidth { get; set; }

/// <summary>
/// 表格高度。
/// </summary>
public int TableHeight { get; set; }

/// <summary>
/// 表格主題。
/// </summary>
public TableTheme Theme { get; set; } = TableTheme.Default;

public TableThemeShader() { }

/// <param name="tableWidth">表格寬度(0為自適應)</param>
/// <param name="tableHeight">表格高度(0為自適應)</param>
public TableThemeShader(int tableWidth, int tableHeight)
{
TableWidth = tableWidth;
TableHeight = tableHeight;
}

protected override void ExcuteOnWorksheet(IXLWorksheet worksheet)
{
var tableWidth = TableWidth;
if(TableWidth == 0)
{
tableWidth = worksheet.LastColumnUsed().ColumnNumber();
}

var tableHeight = TableHeight;
if (TableHeight == 0)
{
tableHeight = worksheet.LastRowUsed().RowNumber();
}

// 設定標題的背景色和文字色
var header = worksheet.Range(StartCell.Row + 1, StartCell.Column + 1, StartCell.Row + SchemaHeight, StartCell.Column + tableWidth);
header.Style.Fill.BackgroundColor = XLColor.FromColor(Theme.HeaderBackgroundColor);
header.Style.Font.FontColor = XLColor.FromColor(Theme.HeaderTextColor);
header.Style.Font.Bold = true;

// 給整個表格設定邊框色
var table = worksheet.Range(StartCell.Row + 1, StartCell.Column + 1, StartCell.Row + tableHeight, StartCell.Column + tableWidth);
table.Style.Border.OutsideBorder = table.Style.Border.InsideBorder = XLBorderStyleValues.Thin;
table.Style.Border.OutsideBorderColor = table.Style.Border.InsideBorderColor = XLColor.FromColor(Theme.BorderColor);
}
}

/// <summary>
/// 用於表達表格主題的結構。
/// </summary>
public struct TableTheme
{
/// <summary>
/// 表頭背景色。
/// </summary>
public Color HeaderBackgroundColor { get; set; }

/// <summary>
/// 表頭文字顏色。
/// </summary>
public Color HeaderTextColor { get; set; }

/// <summary>
/// 邊框顏色。
/// </summary>
public Color BorderColor { get; set; }

public static TableTheme Default => new()
{
HeaderBackgroundColor = Color.FromArgb(68, 114, 196),
HeaderTextColor = Color.White,
BorderColor = Color.FromArgb(68, 114, 196),
};
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@ public static void Demo()
PropertyValueSettingPolicy = (p, value) => p.Name switch
{
nameof(SimpleClass.DateTimeField) => value != null ? DateTime.Parse(value.ToString()) : null,
nameof(SimpleClass.BoolField) => value != null ? value == "" : null,
nameof(SimpleClass.BoolField) => value != null ? value?.ToString() == "" : null,
_ => value
},
};
Expand Down
99 changes: 99 additions & 0 deletions Excely.Example.Console/Exemples/XlsxImportErrorHandlingExemple.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,99 @@
using ClosedXML.Excel;
using Excely.ClosedXML.Shaders;
using Excely.ClosedXML.Workflows;
using Excely.Example.Console.Models;
using Excely.Example.Console.Utilities;
using Excely.Shaders;
using Excely.TableConverters;
using Excely.TableFactories;
using Excely.Workflows;

namespace Excely.Example.Console.Exemples
{
internal class XlsxImportErrorHandlingExemple
{
private static IEnumerable<SimpleClass> GetList()
{
return new List<SimpleClass>()
{
new SimpleClass()
{
Id = 1,
StringField = "比較長的文字欄位111111111111111111",
DateTimeField = DateTime.Now,
BoolField = true,
},
new SimpleClass()
{
Id = 2,
StringField = "比較長的文字欄位222222222222222222",
DateTimeField = DateTime.Now,
BoolField = false,
},
};
}

private static XLWorkbook GetExampleWorkbook()
{
var list = GetList();
var exportOption = new ClassListTableFactoryOptions<SimpleClass>
{
PropertyNamePolicy = p => p.GetDisplayName(),
CustomValuePolicy = (p, obj) => p.Name switch
{
// 故意設定錯誤的日期格式
nameof(SimpleClass.DateTimeField) => obj.DateTimeField?.ToString("yyyy/yyyy/dd"),
nameof(SimpleClass.BoolField) => obj.BoolField == null ? null : (obj.BoolField.Value ? "" : ""),
_ => p.GetValue(obj)
},
};

var shaders = new IShader[]
{
new SchemaFilterShader(),
new CellFittingShader(),
};

var exporter = ExcelyExporter.FromClassList(exportOption, shaders);
return exporter.ToExcel(list);
}

public static void Demo()
{
using var excel = GetExampleWorkbook();
var worksheet = excel.Worksheets.First();
var importer = new XlsxImporter();
var errorDict = new Dictionary<CellLocation, string>();

var importOption = new ClassListTableConverterOptions<SimpleClass>
{
PropertyNamePolicy = p => p.GetDisplayName(),
PropertyValueSettingPolicy = (p, value) => p.Name switch
{
nameof(SimpleClass.BoolField) => value != null ? value?.ToString() == "" : null,
_ => value
},
ErrorHandlingPolicy = (cellLocation, obj, p, value, ex) =>
{
switch (p.Name)
{
case nameof(SimpleClass.DateTimeField):
errorDict.Add(cellLocation, "錯誤的日期格式");
break;
default:
errorDict.Add(cellLocation, ex.Message);
break;
};
return true;
}
};

var importedList = importer.ToClassList(worksheet, importOption);
new ErrorMarkShader(errorDict).Excute(worksheet);
new CellFittingShader().Excute(worksheet);
new SchemaFilterShader().Excute(worksheet);
new TableThemeShader().Excute(worksheet);
excel.SaveAs("XlsxImportErrorHandlingExemple.xlsx");
}
}
}
2 changes: 1 addition & 1 deletion Excely.Example.Console/Program.cs
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
using Excely.Example.Console.Exemples;

SimpleClassListToXlsxExemple.Demo();
XlsxImportErrorHandlingExemple.Demo();

0 comments on commit 811890c

Please sign in to comment.