我在没有安装excel应用程序的服务器中生成excel,因此我使用EPPlus生成Excel,在excel中有许多数据透视表。默认情况下,数据透视表的过滤器中的所有项目都被选中,但我需要特定的过滤器才能选择一个项目。有没有办法使用EPPlus?
如果没有,是否还有另一个库可以做到这一点?我需要能够搜索所有数据透视表的内容,在过滤器中搜索具有特定名称的过滤器,并在过滤器中仅选择1个项目,并为每个数据透视表指定该特定名称。 如果在C#中不可能,有没有其他方法可以在不安装Excel的情况下制作一个程序?如果有,我可以在excel完成时运行该程序。
例如,我有一个13个月的过滤器:
Jan/2017
Feb/2017
Mar/2017
Apr/2017
May/2017
Jun/2017
Jul/2017
Aug/2017
Sep/2017
Oct/2017
Nov/2017
Dec/2017
Jan/2018
在过滤器中,默认选择所有这些,我想要选择最新的一个(在本例中为Jan / 2018)。
这是我为构建数据透视表而创建的类:
public class PivotTableFactory
{
private ExcelPivotTable _pivotTable;
public void CreatePivotTable (Worksheet baseSheet, Worksheet targetSheet, string startRange, string tableName)
{
// Selecting All Range of the base Sheet
String baseAddress = "A1:" + baseSheet.EPPlusSheet.Dimension.End.Address;
ExcelRange baseRange = baseSheet.EPPlusSheet.Cells[baseAddress];
ExcelAddress startAddress = targetSheet.EPPlusSheet.Cells[startRange];
// Creating Pivot Table
_pivotTable = targetSheet.EPPlusSheet.PivotTables.Add (startAddress, baseRange, tableName);
_pivotTable.UseAutoFormatting = false;
}
public void AddFilterField(string columnName, string fieldName, eSortType sortType = eSortType.None)
{
ExcelPivotTableField dataField = _pivotTable.PageFields.Add (_pivotTable.Fields[columnName]);
dataField.Name = fieldName;
dataField.Sort = sortType;
if (columnName.Equals("MES_REFERENCIA")) selectFilterValue("MÊS", 10);
}
public void AddRowField(string columnName, string fieldName, eSortType sortType = eSortType.None)
{
ExcelPivotTableField rowField = _pivotTable.RowFields.Add (_pivotTable.Fields[columnName]);
rowField.Name = fieldName;
rowField.Sort = sortType;
}
public void AddColumnField (string columnName, string fieldName, eSortType sortType = eSortType.None)
{
ExcelPivotTableField rowField = _pivotTable.ColumnFields.Add (_pivotTable.Fields[columnName]);
rowField.Name = fieldName;
rowField.Sort = sortType;
}
public void AddValueField (string columnName, string fieldName, DataFieldFunctions func = DataFieldFunctions.Sum, string format = "")
{
ExcelPivotTableDataField dataField = _pivotTable.DataFields.Add (_pivotTable.Fields[columnName]);
dataField.Name = fieldName;
dataField.Function = func;
dataField.Format = format;
}
public void SetStyle (TableStyles style)
{
_pivotTable.TableStyle = style;
}
public void SetDataOnRows (bool dataOnRow)
{
_pivotTable.DataOnRows = dataOnRow;
}
public void SetDataCaption(string name)
{
_pivotTable.DataCaption = name;
}
public void setAutoFormating(bool value)
{
_pivotTable.UseAutoFormatting = value;
}
public void printPivotXml()
{
_pivotTable.PivotTableXml.Save("pivotsXmls\\pivotFinal.xml");
}
private int getFieldIndex(string name)
{
for (int i = 0;i < _pivotTable.Fields.Count; i++)
{
if (_pivotTable.Fields[i].Name.Equals(name)) return i;
}
return -1;
}
public void selectFilterValue(string name, int valueIndex)
{
int fieldIndex = getFieldIndex(name);
if (fieldIndex < 0) return;
XmlDocument xDoc = _pivotTable.PivotTableXml;
XmlAttribute attr = xDoc.CreateAttribute("item");
attr.Value = valueIndex.ToString();
XmlNode currentDoc = null;
foreach (XmlNode node in xDoc.ChildNodes)
{
if (node.Name.Equals("pivotTableDefinition"))
{
currentDoc = node;
break;
}
}
foreach (XmlNode node in currentDoc.ChildNodes)
{
if (node.Name.Equals("pageFields"))
{
currentDoc = node;
}
if (node.Name.Equals("pivotFields"))
{
foreach (XmlNode field in node.ChildNodes)
{
if (field.Attributes["name"] == null) continue;
if (field.Attributes["name"].Value.Equals(name))
{
XmlNode itemsNode = field.ChildNodes[0];
itemsNode.InnerXml = "";
List<string> items = new List<string>();
// Add item tags
for(int i = 0; i < 13; i++){
XmlNode createdNode = xDoc.CreateNode(XmlNodeType.Element, "item" , currentDoc.NamespaceURI);
XmlAttribute tempAttr = xDoc.CreateAttribute("x");
tempAttr.Value = i.ToString();
createdNode.Attributes.Append(tempAttr);
itemsNode.AppendChild(createdNode);
}
XmlNode createdNodeDefault = xDoc.CreateNode(XmlNodeType.Element, "item", currentDoc.NamespaceURI);
XmlAttribute tempAttrDefault = xDoc.CreateAttribute("t");
tempAttrDefault.Value = "default";
createdNodeDefault.Attributes.Append(tempAttrDefault);
itemsNode.AppendChild(createdNodeDefault);
itemsNode.Attributes["count"].Value = "14";
}
}
}
}
foreach (XmlNode node in currentDoc.ChildNodes)
{
if (node.Attributes["fld"].Value.Equals(fieldIndex.ToString()))
{
node.Attributes.InsertAfter(attr, node.Attributes["fld"]);
}
}
}
}
我创建了函数“selectFilterValue”,它尝试使用XML选择过滤器的值,但它不起作用。请忽略选择XML节点的极其粗略的方法......