-
Notifications
You must be signed in to change notification settings - Fork 48
Expand file tree
/
Copy pathTablesSample.cs
More file actions
194 lines (169 loc) · 9.59 KB
/
TablesSample.cs
File metadata and controls
194 lines (169 loc) · 9.59 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
using OfficeOpenXml;
using OfficeOpenXml.Drawing;
using OfficeOpenXml.Table;
using System;
using System.Data.SQLite;
using System.Drawing;
using System.Threading.Tasks;
namespace EPPlusSamples
{
/// <summary>
/// This sample demonstrates how work with Excel tables in EPPlus.
/// Tables can easily be added by many of the ExcelRange - Load methods as demonstrated in earlier samples.
/// This sample will focus on how to add and setup tables from the ExcelWorksheet.Tables collection.
/// </summary>
public static class TablesSample
{
public static async Task RunAsync(string connectionString)
{
using (var p = new ExcelPackage())
{
await CreateTableWithACalculatedColumnAsync(connectionString, p).ConfigureAwait(false);
await StyleTablesAsync(connectionString, p).ConfigureAwait(false);
await CreateTableFilterAndSlicerAsync(connectionString, p).ConfigureAwait(false);
p.SaveAs(FileUtil.GetCleanFileInfo("28-Tables.xlsx"));
}
}
/// <summary>
/// This sample creates a table with a calculated column. A totals row is added and styling is applied to some of the columns.
/// </summary>
/// <param name="connectionString">The connection string to the database</param>
/// <param name="p">The package</param>
/// <returns></returns>
private static async Task CreateTableWithACalculatedColumnAsync(string connectionString, ExcelPackage p)
{
var ws = p.Workbook.Worksheets.Add("SimpleTable");
var range = await LoadDataAsync(connectionString, ws).ConfigureAwait(false);
var tbl1=ws.Tables.Add(range, "Table1");
tbl1.ShowTotal = true;
//Format the OrderDate column and add a Count Numbers subtotal.
tbl1.Columns["OrderDate"].TotalsRowFunction = RowFunctions.CountNums;
tbl1.Columns["OrderDate"].DataStyle.NumberFormat.Format = "yyyy-MM-dd";
tbl1.Columns["OrderDate"].TotalsRowStyle.NumberFormat.Format = "#,##0";
//Format the OrderValue column and add a Sum subtotal.
tbl1.Columns["OrderValue"].TotalsRowFunction = RowFunctions.Sum;
tbl1.Columns["OrderValue"].DataStyle.NumberFormat.Format = "#,##0";
tbl1.Columns["OrderValue"].TotalsRowStyle.NumberFormat.Format = "#,##0";
//Adds a calculated formula referencing the OrderValue column within the same row.
tbl1.Columns.Add(1);
var addedcolumn = tbl1.Columns[tbl1.Columns.Count - 1];
addedcolumn.Name = "OrderValue with Tax";
addedcolumn.CalculatedColumnFormula = "Table1[[#This Row],[OrderValue]] * 110%"; //Sets the calculated formula referencing the OrderValue column within this row.
addedcolumn.TotalsRowFunction = RowFunctions.Sum;
addedcolumn.DataStyle.NumberFormat.Format = "#,##0";
addedcolumn.TotalsRowStyle.NumberFormat.Format = "#,##0";
tbl1.ShowLastColumn = true;
tbl1.Range.AutoFitColumns();
//Calculate the formulas so we get the calculated column values as well.
ws.Calculate();
//Create a data table from the table
var dataTable = tbl1.ToDataTable(x => { x.DataTableName = "DataTable1"; x.SkipNumberOfRowsEnd=2; });
//Then create a new table from the data table
var range2=ws.Cells["K1"].LoadFromDataTable(dataTable, true, TableStyles.Dark4);
var tbl2 = ws.Tables.GetFromRange(range2);
//Format the OrderDate column and add a Count Numbers subtotal.
tbl2.Columns["OrderDate"].TotalsRowFunction = RowFunctions.CountNums;
tbl2.Columns["OrderDate"].DataStyle.NumberFormat.Format = "yyyy-MM-dd";
tbl2.Columns["OrderDate"].TotalsRowStyle.NumberFormat.Format = "#,##0";
//Format the OrderValue column and add a Sum subtotal.
tbl2.Columns["OrderValue"].TotalsRowFunction = RowFunctions.Sum;
tbl2.Columns["OrderValue"].DataStyle.NumberFormat.Format = "#,##0";
tbl2.Columns["OrderValue"].TotalsRowStyle.NumberFormat.Format = "#,##0";
range2.AutoFitColumns();
}
/// <summary>
/// This sample creates a two table and a custom table style. The first table is styled using different style objects of the table.
/// The second table is styled using the custom table style
/// </summary>
/// <param name="connectionString"></param>
/// <param name="p"></param>
/// <returns></returns>
private static async Task StyleTablesAsync(string connectionString, ExcelPackage p)
{
var ws = p.Workbook.Worksheets.Add("StyleTables");
var range1 = await LoadDataAsync(connectionString, ws).ConfigureAwait(false);
SetEmailAsHyperlink(range1);
//Add the table and set some styles and properties.
var tbl1 = ws.Tables.Add(range1, "StyleTable1");
tbl1.TableStyle = TableStyles.Medium24;
tbl1.DataStyle.Font.Size = 10;
tbl1.Columns["E-Mail"].DataStyle.Font.Underline=OfficeOpenXml.Style.ExcelUnderLineType.Single;
tbl1.HeaderRowStyle.Font.Italic = true;
tbl1.ShowTotal = true;
tbl1.TotalsRowStyle.Font.Italic = true;
tbl1.Range.Style.Font.Name = "Arial";
tbl1.Range.AutoFitColumns();
//Add two rows at the end.
var addedRange = tbl1.AddRow(2);
addedRange.Offset(0, 0, 1, 1).Value = "Added Row 1";
addedRange.Offset(1, 0, 1, 1).Value = "Added Row 2";
//Add a custom formula to display number of items in the CompanyName column
tbl1.Columns[0].TotalsRowFormula= "\"Total Count is \" & SUBTOTAL(103,StyleTable1[CompanyName])";
tbl1.Columns[0].TotalsRowStyle.Font.Color.SetColor(Color.Red);
//We create a custom named style via the Workbook.Styles object. For more samples on custom styles see sample 27
var customStyleName = "EPPlus Created Style";
var customStyle = p.Workbook.Styles.CreateTableStyle(customStyleName, TableStyles.Medium13);
customStyle.HeaderRow.Style.Font.Color.SetColor(eThemeSchemeColor.Text1);
customStyle.FirstColumn.Style.Fill.BackgroundColor.SetColor(eThemeSchemeColor.Accent5);
customStyle.FirstColumn.Style.Fill.BackgroundColor.Tint=0.3;
customStyle.FirstColumn.Style.Font.Color.SetColor(eThemeSchemeColor.Text1);
var range2 = await LoadDataAsync(connectionString, ws, "K1").ConfigureAwait(false);
var tbl2 = ws.Tables.Add(range2, "StyleTable2");
//To apply the custom style we set the StyleName property to the name we choose for our style.
tbl2.StyleName = customStyleName;
tbl2.ShowFirstColumn = true;
tbl2.Range.AutoFitColumns();
}
private static void SetEmailAsHyperlink(ExcelRangeBase range)
{
for(int row=1;row<=range.Rows;row++)
{
var cell = range.Offset(row, 2,1,1);
if (cell.Value != null)
{
cell.Hyperlink = new Uri($"mailto:{cell.Value}");
}
}
}
/// <summary>
/// This sample creates a table and a slicer.
/// </summary>
/// <param name="connectionString">The connection string to the database</param>
/// <param name="p">The package</param>
/// <returns></returns>
private static async Task CreateTableFilterAndSlicerAsync(string connectionString, ExcelPackage p)
{
var ws = p.Workbook.Worksheets.Add("Slicer");
var range = await LoadDataAsync(connectionString, ws).ConfigureAwait(false);
var tbl = ws.Tables.Add(range, "FilterTable1");
tbl.TableStyle = TableStyles.Medium1;
//Add a slicer and filter on company name. A table slicer is connected to a table columns value filter.
var slicer1 = tbl.Columns[0].AddSlicer();
slicer1.FilterValues.Add("Cremin-Kihn");
slicer1.FilterValues.Add("Senger LLC");
range.AutoFitColumns();
//Apply the column filter, otherwise the slicer may be hidden when the filter is applied.
tbl.AutoFilter.ApplyFilter();
slicer1.SetPosition(2, 0, 10, 0);
//For more samples on filters and slicers see Sample 13 and 24.
}
private static async Task<ExcelRangeBase> LoadDataAsync(string connectionString, ExcelWorksheet ws, string startCell="A1")
{
ExcelRangeBase range;
//Lets connect to the sample database for some data
using (var sqlConn = new SQLiteConnection(connectionString))
{
sqlConn.Open();
using (var sqlCmd = new SQLiteCommand("select companyname as CompanyName, [name] as [Name], Email as [E-Mail], c.Country as Country, o.orderid as OrderId, orderdate as OrderDate, ordervalue as OrderValue, currency as Currency from Customer c inner join Orders o on c.CustomerId=o.CustomerId inner join SalesPerson s on o.salesPersonId = s.salesPersonId ORDER BY 1,2 desc", sqlConn))
{
using (var sqlReader = sqlCmd.ExecuteReader())
{
range = await ws.Cells[startCell].LoadFromDataReaderAsync(sqlReader, true);
}
}
sqlConn.Close();
}
return range;
}
}
}