diff --git a/NEW/src/JdeScoping.ExcelIO/Generators/FluentTableWriter.cs b/NEW/src/JdeScoping.ExcelIO/Generators/FluentTableWriter.cs
new file mode 100644
index 0000000..14636f8
--- /dev/null
+++ b/NEW/src/JdeScoping.ExcelIO/Generators/FluentTableWriter.cs
@@ -0,0 +1,145 @@
+using ClosedXML.Excel;
+using JdeScoping.ExcelIO.Formatting;
+using JdeScoping.ExcelIO.Mapping;
+
+namespace JdeScoping.ExcelIO.Generators;
+
+///
+/// Writes Excel tables using fluent mapping configuration.
+///
+public sealed class FluentTableWriter
+{
+ private readonly ExcelMapRegistry _registry;
+
+ public FluentTableWriter(ExcelMapRegistry registry)
+ {
+ _registry = registry;
+ }
+
+ ///
+ /// Writes a table to the worksheet using the registered map for type T.
+ ///
+ public IXLTable? WriteTable(
+ IXLWorksheet worksheet,
+ int startRow,
+ int startCol,
+ IEnumerable data,
+ string? tableNameOverride = null,
+ bool showHeader = false,
+ string? headerText = null)
+ {
+ var map = _registry.GetMap();
+ var columns = map.Columns;
+ var tableName = tableNameOverride ?? map.TableName ?? typeof(T).Name;
+ var header = headerText ?? map.TabName ?? string.Empty;
+
+ if (columns.Count == 0)
+ return null;
+
+ var dataList = data.ToList();
+ var baseRow = startRow;
+
+ // Write merged header if requested
+ if (showHeader && !string.IsNullOrEmpty(header))
+ {
+ var mergedHeaderRange = worksheet.Range(baseRow, startCol, baseRow, startCol + columns.Count - 1);
+ HeaderFormatter.ApplyHeaderFormat(mergedHeaderRange, header, merge: true);
+ baseRow++;
+ }
+
+ // Write column headers
+ var col = startCol;
+ foreach (var column in columns)
+ {
+ var cell = worksheet.Cell(baseRow, col);
+ HeaderFormatter.ApplyHeaderFormat(cell, column.HeaderText);
+
+ // Pre-set column formatting
+ worksheet.Column(col).Style.Alignment.WrapText = column.WrapText;
+ if (!column.AutoWidth)
+ {
+ worksheet.Column(col).Width = column.Width;
+ }
+
+ col++;
+ }
+
+ // Write data rows
+ var row = baseRow + 1;
+ foreach (var item in dataList)
+ {
+ col = startCol;
+ foreach (var column in columns)
+ {
+ var value = column.ValueGetter(item!);
+ worksheet.Cell(row, col).Value = ConvertToXlValue(value);
+ col++;
+ }
+ row++;
+ }
+
+ // Handle empty data case
+ if (dataList.Count == 0)
+ {
+ row = baseRow + 1;
+ }
+
+ // Create table range
+ var dataRange = worksheet.Range(
+ baseRow, startCol,
+ baseRow + dataList.Count, startCol + columns.Count - 1);
+
+ // Create table
+ var table = dataRange.CreateTable(tableName);
+ table.Theme = XLTableTheme.TableStyleLight18;
+ table.ShowTotalsRow = false;
+
+ // Apply column formatting
+ col = startCol;
+ var tableStartRow = table.RangeAddress.FirstAddress.RowNumber;
+ var tableEndRow = table.RangeAddress.LastAddress.RowNumber;
+
+ foreach (var column in columns)
+ {
+ // Apply number format
+ worksheet.Range(tableStartRow, col, tableEndRow, col)
+ .Style.NumberFormat.Format = column.Format;
+
+ // Apply column width
+ if (column.WrapText && !column.AutoWidth)
+ {
+ worksheet.Column(col).Width = column.Width;
+ }
+ else if (column.AutoWidth)
+ {
+ worksheet.Column(col).AdjustToContents();
+ worksheet.Column(col).Width *= Formatting.ExcelFormats.DataPaddingFactor;
+ }
+ else
+ {
+ worksheet.Column(col).Width = column.Width;
+ }
+
+ col++;
+ }
+
+ return table;
+ }
+
+ private static XLCellValue ConvertToXlValue(object? value)
+ {
+ return value switch
+ {
+ null => Blank.Value,
+ string s => s,
+ int i => i,
+ long l => l,
+ decimal d => d,
+ double dbl => dbl,
+ float f => f,
+ DateTime dt => dt,
+ bool b => b,
+ _ => value.ToString() ?? string.Empty
+ };
+ }
+}