我如何创build一个计算EPPlus中的值的DataField?

我正在将Excel Interop数据透视表代码移植到EPPlus。 我在生成一个计算的字段值的一个关键点。 在Excel Interop中,我可以这样做:

pvt.AddDataField(pvt.PivotFields("TotalQty"), "Total Packages", XlConsolidationFunction.xlSum).NumberFormat = "###,##0"; pvt.AddDataField(pvt.PivotFields("TotalPrice"), "Total Purchases", XlConsolidationFunction.xlSum).NumberFormat = "$#,##0.00"; PivotField avg = pvt.CalculatedFields().Add("Average Price", "=TotalPrice/TotalQty", true); avg.Orientation = XlPivotFieldOrientation.xlDataField; avg.NumberFormat = "$###0.00"; 

用此数据透视表上的“平均价格”值显示TotalPrice除以TotalQty的值。

但是如何在EPPlus中做到这一点? 我可以像这样创build“普通的香草”数据字段:

 var totQtyField = pivotTable.Fields["TotalQty"]; pivotTable.DataFields.Add(totQtyField); var totPriceField = pivotTable.Fields["TotalPrice"]; pivotTable.DataFields.Add(totPriceField); 

…但是当谈到计算价值时,我很困惑。 我的出发点是这样一个在线的例子:

 pivotTable.DataFields.Add(pivotTable.Fields["AvgPrice"]).Function = OfficeOpenXml.Table.PivotTable.DataFieldFunctions.Sum(); 

所以我尝试了以下,但没有一个是正确的:

 pivotTable.DataFields.Add(pivotTable.Fields["AvgPrice"]).Function = OfficeOpenXml.Table.PivotTable.DataFieldFunctions.Average(totPriceField, totQtyField); pivotTable.DataFields.Add(pivotTable.Fields["AvgPrice"]).Function = "TotalPrice/TotalQty"; pivotTable.DataFields.Add(pivotTable.Fields["AvgPrice"]) = "TotalPrice/TotalQty"; pivotTable.DataFields.Add(pivotTable.Fields["AvgPrice"]) = totPriceField / totQtyField; pivotTable.DataFields.Add(pivotTable.Fields["AvgPrice"]).Function = OfficeOpenXml.Table.PivotTable. DataFieldFunctions.Product(totPriceField/totQtyField); 

这些连环都没有编译。 我需要做什么调整,或者我需要采取什么全新的方法?

UPDATE

我可以计算出这些数值,并把它们放在数据表上,并用这种方式来引用它。 但这真的是唯一/最好的方法吗?

更新2

我这样做(直接添加到包含数据透视表的源数据的工作表):

 var avgCell = rawDataWorksheet.Cells[_lastRowAddedRawData + 1, 9]; if ((TotalPrice < 0.0M) || (Quantity < 1)) { avgCell.Value = 0.0; } else { avgCell.Value = TotalPrice / Quantity; } var prcntgCell = rawDataWorksheet.Cells[_lastRowAddedRawData + 1, 10]; if ((TotalPrice < 0.0M) || (MonthYear == String.Empty)) { prcntgCell.Value = 0.0; } else { prcntgCell.Value = GetPercentageOfItemForMonthYear(TotalPrice, MonthYear); } private double GetPercentageOfItemForMonthYear(decimal totPrice, strin monthYear) { decimal totalForMonthYear = monthlySales[monthYear]; double prcntg = GetPercentageOfItem(totPrice, totalForMonthYear); return prcntg; } private double GetPercentageOfItem(decimal portionOfTotal, decimal grandTotal) { if ((portionOfTotal <= 0.0M) || (grandTotal <= 0.0M)) { return 0.0; } if (portionOfTotal == grandTotal) { return 100.0; } double d = Convert.ToDouble(portionOfTotal) / Convert.ToDouble(grandTotal) * 100; return Math.Round(d, 2); } 

…但仍然想知道在创build数据透视表时如何使用计算的字段完成。

EPPlus当前不支持数据透视表中的计算字段。 我使用了以下解决方法:

 using System.Linq; using System.Xml; using OfficeOpenXml.Table.PivotTable; using ReflectionMagic; public static ExcelPivotTableField AddCalculatedField(this ExcelPivotTable pivotTable, string calcFieldName, string formula) { var dynamicPivotTable = pivotTable.AsDynamic(); var maxIndex = pivotTable.Fields.Max(f => f.Index); const string schemaMain = @"http://schemas.openxmlformats.org/spreadsheetml/2006/main"; var cacheTopNode = dynamicPivotTable.CacheDefinition.CacheDefinitionXml.SelectSingleNode("//d:cacheFields", dynamicPivotTable.NameSpaceManager); cacheTopNode.SetAttribute("count", (int.Parse(cacheTopNode.GetAttribute("count")) + 1).ToString()); var cacheFieldNode = dynamicPivotTable.CacheDefinition.CacheDefinitionXml.CreateElement("cacheField", schemaMain); cacheFieldNode.SetAttribute("name", calcFieldName); cacheFieldNode.SetAttribute("databaseField", "0"); cacheFieldNode.SetAttribute("formula", formula); cacheFieldNode.SetAttribute("numFmtId", "0"); cacheTopNode.AppendChild(cacheFieldNode); var topNode = dynamicPivotTable.PivotTableXml.SelectSingleNode("//d:pivotFields", dynamicPivotTable.NameSpaceManager); topNode.SetAttribute("count", (int.Parse(topNode.GetAttribute("count")) + 1).ToString()); XmlElement fieldNode = dynamicPivotTable.PivotTableXml.CreateElement("pivotField", schemaMain); fieldNode.SetAttribute("compact", "0"); fieldNode.SetAttribute("outline", "0"); fieldNode.SetAttribute("showAll", "0"); fieldNode.SetAttribute("defaultSubtotal", "0"); topNode.AppendChild(fieldNode); var excelPivotTableFieldType = typeof(ExcelPivotTableField).AsDynamicType(); var excelPivotTableField = excelPivotTableFieldType.New((XmlNamespaceManager)dynamicPivotTable.NameSpaceManager, fieldNode, (ExcelPivotTable)dynamicPivotTable, maxIndex + 1, maxIndex + 1); excelPivotTableField.SetCacheFieldNode(cacheFieldNode); dynamicPivotTable.Fields.AddInternal(excelPivotTableField); return pivotTable.Fields.First(f => f.Name == calcFieldName); } 

用法示例:

 var calc1 = pivotTable.AddCalculatedField("Calc1", "BCol*BCol"); var dataField = pivotTable.DataFields.Add(calc1); dataField.Function = DataFieldFunctions.Sum; dataField.Name = "Override Name";