| /*  | 
 |  * You may amend and distribute as you like, but don't remove this header! | 
 |  *  | 
 |  * EPPlus provides server-side generation of Excel 2007 spreadsheets. | 
 |  * See http://www.codeplex.com/EPPlus for details. | 
 |  *  | 
 |  * All rights reserved. | 
 |  *  | 
 |  * EPPlus is an Open Source project provided under the  | 
 |  * GNU General Public License (GPL) as published by the  | 
 |  * Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | 
 |  *  | 
 |  * The GNU General Public License can be viewed at http://www.opensource.org/licenses/gpl-license.php | 
 |  * If you unfamiliar with this license or have questions about it, here is an http://www.gnu.org/licenses/gpl-faq.html | 
 |  *  | 
 |  * The code for this project may be used and redistributed by any means PROVIDING it is  | 
 |  * not sold for profit without the author's written consent, and providing that this notice  | 
 |  * and the author's name and all copyright notices remain intact. | 
 |  *  | 
 |  * All code and executables are provided "as is" with no warranty either express or implied.  | 
 |  * The author accepts no liability for any damage or loss of business that this product may cause. | 
 |  * | 
 |  *  Code change notes: | 
 |  *  | 
 |  * Author							Change						Date | 
 |  * ****************************************************************************** | 
 |  * Jan Källman                      Added       		        2011-04-18 | 
 |  *******************************************************************************/ | 
 | using System; | 
 | using System.Collections.Generic; | 
 | using System.Linq; | 
 | using System.Text; | 
 | using System.IO; | 
 | using OfficeOpenXml; | 
 | using System.Data.SqlClient; | 
 | using OfficeOpenXml.Table.PivotTable; | 
 | using OfficeOpenXml.Drawing.Chart; | 
 | namespace EPPlusSamples | 
 | { | 
 |     /// <summary> | 
 |     /// This class shows how to use pivottables  | 
 |     /// </summary> | 
 |     public static class Sample12 | 
 |     { | 
 |         public class SalesDTO | 
 |         { | 
 |             public string Title { get; set; }             | 
 |             public string FirstName { get; set; } | 
 |             public string MiddleName { get; set; } | 
 |             public string LastName { get; set; } | 
 |             public string Name | 
 |             { | 
 |                 get | 
 |                 { | 
 |                     return string.IsNullOrEmpty(MiddleName) ? FirstName + " " + LastName : FirstName + " " + MiddleName + " " + LastName; | 
 |                 } | 
 |             } | 
 |             public DateTime OrderDate { get; set; } | 
 |             public decimal SubTotal { get; set; } | 
 |             public decimal Tax { get; set; } | 
 |             public decimal Freight { get; set; } | 
 |             public decimal Total | 
 |             { | 
 |                 get | 
 |                 { | 
 |                     return SubTotal + Tax + Freight; | 
 |                 } | 
 |             } | 
 |         } | 
 |         public static string RunSample12(string sqlServerName, DirectoryInfo outputDir) | 
 |         { | 
 |             var list = new List<SalesDTO>(); | 
 |             if (sqlServerName == "") | 
 |             { | 
 |                 list = GetRandomData(); | 
 |             } | 
 |             else | 
 |             { | 
 |                 list = GetDataFromSQL(sqlServerName); | 
 |             } | 
 |  | 
 |             string file = outputDir.FullName + @"\sample12.xlsx"; | 
 |             if (File.Exists(file)) File.Delete(file); | 
 |             FileInfo newFile = new FileInfo(file); | 
 |  | 
 |             using (ExcelPackage pck = new ExcelPackage(newFile)) | 
 |             { | 
 |                 // get the handle to the existing worksheet | 
 |                 var wsData = pck.Workbook.Worksheets.Add("SalesData"); | 
 |  | 
 |                 var dataRange = wsData.Cells["A1"].LoadFromCollection( | 
 |                     from s in list  | 
 |                     orderby s.LastName, s.FirstName  | 
 |                     select s,  | 
 |                    true, OfficeOpenXml.Table.TableStyles.Medium2);                 | 
 |                  | 
 |                 wsData.Cells[2, 6, dataRange.End.Row, 6].Style.Numberformat.Format = "mm-dd-yy"; | 
 |                 wsData.Cells[2, 7, dataRange.End.Row, 11].Style.Numberformat.Format = "#,##0"; | 
 |                  | 
 |                 dataRange.AutoFitColumns(); | 
 |  | 
 |                 var wsPivot = pck.Workbook.Worksheets.Add("PivotSimple"); | 
 |                 var pivotTable1 = wsPivot.PivotTables.Add(wsPivot.Cells["A1"], dataRange, "PerEmploee"); | 
 |  | 
 |                 pivotTable1.RowFields.Add(pivotTable1.Fields[4]); | 
 |                 var dataField = pivotTable1.DataFields.Add(pivotTable1.Fields[6]); | 
 |                 dataField.Format="#,##0"; | 
 |                 pivotTable1.DataOnRows = true; | 
 |  | 
 |                 var chart = wsPivot.Drawings.AddChart("PivotChart", eChartType.Pie, pivotTable1); | 
 |                 chart.SetPosition(1, 0, 4, 0); | 
 |                 chart.SetSize(600, 400); | 
 |                      | 
 |                 var wsPivot2 = pck.Workbook.Worksheets.Add("PivotDateGrp"); | 
 |                 var pivotTable2 = wsPivot2.PivotTables.Add(wsPivot2.Cells["A3"], dataRange, "PerEmploeeAndQuarter"); | 
 |  | 
 |                 pivotTable2.RowFields.Add(pivotTable2.Fields["Name"]); | 
 |                  | 
 |                 //Add a rowfield | 
 |                 var rowField = pivotTable2.RowFields.Add(pivotTable2.Fields["OrderDate"]); | 
 |                 //This is a date field so we want to group by Years and quaters. This will create one additional field for years. | 
 |                 rowField.AddDateGrouping(eDateGroupBy.Years | eDateGroupBy.Quarters); | 
 |                 //Get the Quaters field and change the texts | 
 |                 var quaterField = pivotTable2.Fields.GetDateGroupField(eDateGroupBy.Quarters); | 
 |                 quaterField.Items[0].Text = "<"; //Values below min date, but we use auto so its not used | 
 |                 quaterField.Items[1].Text = "Q1"; | 
 |                 quaterField.Items[2].Text = "Q2"; | 
 |                 quaterField.Items[3].Text = "Q3"; | 
 |                 quaterField.Items[4].Text = "Q4"; | 
 |                 quaterField.Items[5].Text = ">"; //Values above max date, but we use auto so its not used | 
 |                  | 
 |                 //Add a pagefield | 
 |                 var pageField = pivotTable2.PageFields.Add(pivotTable2.Fields["Title"]); | 
 |                  | 
 |                 //Add the data fields and format them | 
 |                 dataField = pivotTable2.DataFields.Add(pivotTable2.Fields["SubTotal"]); | 
 |                 dataField.Format = "#,##0"; | 
 |                 dataField = pivotTable2.DataFields.Add(pivotTable2.Fields["Tax"]); | 
 |                 dataField.Format = "#,##0"; | 
 |                 dataField = pivotTable2.DataFields.Add(pivotTable2.Fields["Freight"]); | 
 |                 dataField.Format = "#,##0"; | 
 |                  | 
 |                 //We want the datafields to appear in columns | 
 |                 pivotTable2.DataOnRows = false; | 
 |  | 
 |                 pck.Save(); | 
 |             } | 
 |             return file; | 
 |         } | 
 |  | 
 |         private static List<SalesDTO> GetRandomData() | 
 |         { | 
 |             List<SalesDTO> ret = new List<SalesDTO>(); | 
 |             var firstNames = new string[] {"John", "Gunnar", "Karl", "Alice"}; | 
 |             var lastNames = new string[] {"Smith", "Johansson", "Lindeman"}; | 
 |             Random r = new Random(); | 
 |             for (int i = 0; i < 500; i++) | 
 |             { | 
 |                 ret.Add( | 
 |                     new SalesDTO() | 
 |                     { | 
 |                         FirstName = firstNames[r.Next(4)], | 
 |                         LastName = lastNames[r.Next(3)], | 
 |                         OrderDate = new DateTime(2002, 1, 1).AddDays(r.Next(1000)), | 
 |                         Title="Sales Representative", | 
 |                         SubTotal = r.Next(100, 10000), | 
 |                         Tax = 0, | 
 |                         Freight = 0 | 
 |                     }); | 
 |             } | 
 |             return ret; | 
 |         } | 
 |  | 
 |         private static List<SalesDTO> GetDataFromSQL(string sqlServerName) | 
 |         { | 
 |             string connectionStr = string.Format(@"server={0};database=AdventureWorks;Integrated Security=true;", sqlServerName); | 
 |             var ret = new List<SalesDTO>(); | 
 |             // lets connect to the AdventureWorks sample database for some data | 
 |             using (SqlConnection sqlConn = new SqlConnection(connectionStr)) | 
 |             { | 
 |                 sqlConn.Open(); | 
 |                 using (SqlCommand sqlCmd = new SqlCommand("select h.Title, FirstName, MiddleName, LastName, SubTotal, OrderDate, TaxAmt, Freight, TotalDue  from Sales.SalesOrderHeader s inner join HumanResources.Employee h on s.SalesPersonID = h.EmployeeID inner join Person.Contact c on c.ContactID = h.ContactID order by LastName, FirstName, MiddleName;", sqlConn)) | 
 |                 { | 
 |                     using (SqlDataReader sqlReader = sqlCmd.ExecuteReader()) | 
 |                     { | 
 |                         //Get the data and fill rows 5 onwards | 
 |                         while (sqlReader.Read()) | 
 |                         { | 
 |                             ret.Add(new SalesDTO | 
 |                             { | 
 |                                 Title = sqlReader["Title"].ToString(), | 
 |                                 FirstName=sqlReader["FirstName"].ToString(), | 
 |                                 MiddleName=sqlReader["MiddleName"].ToString(), | 
 |                                 LastName=sqlReader["LastName"].ToString(), | 
 |                                 OrderDate = (DateTime)sqlReader["OrderDate"], | 
 |                                 SubTotal = (decimal)sqlReader["SubTotal"], | 
 |                                 Tax=(decimal)sqlReader["TaxAmt"], | 
 |                                 Freight=(decimal)sqlReader["Freight"] | 
 |                             }); | 
 |                         } | 
 |                     } | 
 |                 } | 
 |             } | 
 |             return ret; | 
 |         } | 
 |     } | 
 | } |