2012-07-25 30 views
17

He estado usando EPPlus para .net desde hace un tiempo, pero solo para la manipulación de datos simples. ¿Hay algún ejemplo en algún lugar sobre cómo usarlo para crear tablas dinámicas/gráficos? Parece que lo soporta como puedo ver la tabla dinámica en el intellisense, pero simplemente no estoy seguro de la sintaxis.Tablas/gráficos dinámicos EPPlus

Solo pude encontrar me gusta de los gráficos de tarta/barra en las muestras proporcionadas.

Respuesta

14

Aquí está el código de un pivote que he creado recientemente, tal vez sí ayuda:

DataTable table = getDataSource(); 
FileInfo fileInfo = new FileInfo(path); 
var excel = new ExcelPackage(fileInfo); 
var wsData = excel.Workbook.Worksheets.Add("Data-Worksheetname"); 
var wsPivot = excel.Workbook.Worksheets.Add("Pivot-Worksheetname"); 
wsData.Cells["A1"].LoadFromDataTable(table, true, OfficeOpenXml.Table.TableStyles.Medium6); 
if (table.Rows.Count != 0) 
{ 
    foreach (DataColumn col in table.Columns) 
    { 
     // format all dates in german format (adjust accordingly) 
     if (col.DataType == typeof(System.DateTime)) 
     { 
      var colNumber = col.Ordinal + 1; 
      var range = wsData.Cells[2, colNumber, table.Rows.Count + 1, colNumber]; 
      range.Style.Numberformat.Format = "dd.MM.yyyy"; 
     } 
    } 
} 

var dataRange = wsData.Cells[wsData.Dimension.Address.ToString()]; 
dataRange.AutoFitColumns(); 
var pivotTable = wsPivot.PivotTables.Add(wsPivot.Cells["A3"], dataRange, "Pivotname"); 
pivotTable.MultipleFieldFilters = true; 
pivotTable.RowGrandTotals = true; 
pivotTable.ColumGrandTotals = true; 
pivotTable.Compact = true; 
pivotTable.CompactData = true; 
pivotTable.GridDropZones = false; 
pivotTable.Outline = false; 
pivotTable.OutlineData = false; 
pivotTable.ShowError = true; 
pivotTable.ErrorCaption = "[error]"; 
pivotTable.ShowHeaders = true; 
pivotTable.UseAutoFormatting = true; 
pivotTable.ApplyWidthHeightFormats = true; 
pivotTable.ShowDrill = true; 
pivotTable.FirstDataCol = 3; 
pivotTable.RowHeaderCaption = "Claims"; 

var modelField = pivotTable.Fields["Model"]; 
pivotTable.PageFields.Add(modelField); 
modelField.Sort = OfficeOpenXml.Table.PivotTable.eSortType.Ascending; 

var countField = pivotTable.Fields["Claims"]; 
pivotTable.DataFields.Add(countField); 

var countryField = pivotTable.Fields["Country"]; 
pivotTable.RowFields.Add(countryField); 
var gspField = pivotTable.Fields["GSP/DRSL"]; 
pivotTable.RowFields.Add(gspField); 

var oldStatusField = pivotTable.Fields["Old Status"]; 
pivotTable.ColumnFields.Add(oldStatusField); 
var newStatusField = pivotTable.Fields["New Status"]; 
pivotTable.ColumnFields.Add(newStatusField); 

var submittedDateField = pivotTable.Fields["Claim Submitted Date"]; 
pivotTable.RowFields.Add(submittedDateField); 
submittedDateField.AddDateGrouping(OfficeOpenXml.Table.PivotTable.eDateGroupBy.Months | OfficeOpenXml.Table.PivotTable.eDateGroupBy.Days); 
var monthGroupField = pivotTable.Fields.GetDateGroupField(OfficeOpenXml.Table.PivotTable.eDateGroupBy.Months); 
monthGroupField.ShowAll = false; 
var dayGroupField = pivotTable.Fields.GetDateGroupField(OfficeOpenXml.Table.PivotTable.eDateGroupBy.Days); 
dayGroupField.ShowAll = false; 

excel.Save(); 
+0

Lo revisaré, gracias. – user1468537

+2

¿Qué efecto tienen los campos de asignación como Página, Fila, Columna y Datos? –

+0

Gran ejemplo - ¡Gracias! ¿Alguna idea de cómo establecer un formato numérico de estilo en pivotTable.DataFields? Estoy mostrando números y me gustaría aplicar el formato "#, ## 0.00". –

25

He producido una solución similar de respuesta de Tim. En primer lugar, he definido una interfaz sencilla que utilizo como parte de mis métodos de exportación:

public interface IPivotTableCreator 
{ 
    void CreatePivotTable(
     OfficeOpenXml.ExcelPackage pkg, // reference to the destination book 
     string tableName,    // "tab" name used to generate names for related items 
     string pivotRangeName);   // Named range in the Workbook refers to data 
} 

Entonces implementado una clase simple que mantenga los valores de las variables y el código de procedimiento para hacer el trabajo:

public class SimplePivotTable : IPivotTableCreator 
{ 
    List<string> _GroupByColumns; 
    List<string> _SummaryColumns; 
    /// <summary> 
    /// Constructor 
    /// </summary> 
    public SimplePivotTable(string[] groupByColumns, string[] summaryColumns) 
    { 
     _GroupByColumns = new List<string>(groupByColumns); 
     _SummaryColumns = new List<string>(summaryColumns); 
    } 

    /// <summary> 
    /// Call-back handler that builds simple PivatTable in Excel 
    /// http://stackoverflow.com/questions/11650080/epplus-pivot-tables-charts 
    /// </summary> 
    public void CreatePivotTable(OfficeOpenXml.ExcelPackage pkg, string tableName, string pivotRangeName) 
    { 
     string pageName = "Pivot-" + tableName.Replace(" ", ""); 
     var wsPivot = pkg.Workbook.Worksheets.Add(pageName); 
     pkg.Workbook.Worksheets.MoveBefore(PageName, tableName); 

     var dataRange = pkg.Workbook./*Worksheets[tableName].*/Names[pivotRangeName]; 
     var pivotTable = wsPivot.PivotTables.Add(wsPivot.Cells["C3"], dataRange, "Pivot_" + tableName.Replace(" ", "")); 
     pivotTable.ShowHeaders = true; 
     pivotTable.UseAutoFormatting = true; 
     pivotTable.ApplyWidthHeightFormats = true; 
     pivotTable.ShowDrill = true; 
     pivotTable.FirstHeaderRow = 1; // first row has headers 
     pivotTable.FirstDataCol = 1; // first col of data 
     pivotTable.FirstDataRow = 2; // first row of data 

     foreach (string row in _GroupByColumns) 
     { 
      var field = pivotTable.Fields[row]; 
      pivotTable.RowFields.Add(field); 
      field.Sort = eSortType.Ascending; 
     } 

     foreach (string column in _SummaryColumns) 
     { 
      var field = pivotTable.Fields[column]; 
      ExcelPivotTableDataField result = pivotTable.DataFields.Add(field); 
     } 

     pivotTable.DataOnRows = false; 
    } 
} 

a continuación, se crea una instancia de mi clase SimplePivotTable creador:

IPivotTableCreator ptCreator = new SimplePivotTable(
    new string[] { "OrganizationTitle", "GroupingTitle", "DetailTitle" }, /* collapsible rows */ 
    new string[] { "Baseline", "Increase", "Decrease", "NetChange", "CurrentCount"}); /* summary columns */ 

tengo una tercera clase que actualmente expone unos seis métodos diferentes para tener una sola o más conjuntos de datos (usua lly List objects) y convierta cada uno de los conjuntos de datos en una hoja de trabajo de datos con un rango con nombre para los datos. Ahora, estoy adaptando esos métodos de exportación para permitirme generar Pivot Tables para cualquiera o todos esos métodos de exportación. lo único que hacen algo como esto:

OfficeOpenXml.ExcelPackage pkg = new ExcelPackage(); 
ExportCollectionToExcel(pkg, tableName, dataset); // Create worksheet filled with data 
                // Creates a NamedRange of data 
ptCreator.CreatePivotTable(pkg, tableName, GetPivotRangeName(tableName)); 

Mediante el uso de una interfaz, dejo más oportunidades abiertas (creo) para generar, por ejemplo, una tabla dinámica diferente para varias hojas. Mi clase básica SimplePivotTable acaba de usarse para una sola tabla con algunas suposiciones específicas, pero no sería difícil poner los datos de configuración en un diccionario con los nombres de la Tabla.

Espero que ayude a alguien.

+0

Cuando uso su código (ligeramente modificado), la edición de un campo c bloquea el Excel? Consulte mi publicación aquí: http://epplus.codeplex.com/workitem/14798 –

+0

¿Sabe cómo cambiar la Alineación Horizontal de las celdas en la tabla dinámica? Deseo centrarlos, pero las funciones normales de las hojas de cálculo no parecen funcionar en las celdas de la tabla dinámica. – kadzu