Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/333.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/7/python-2.7/5.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 在列上添加特定的自动筛选_C#_Excel_Epplus_Autofilter - Fatal编程技术网

C# 在列上添加特定的自动筛选

C# 在列上添加特定的自动筛选,c#,excel,epplus,autofilter,C#,Excel,Epplus,Autofilter,我正在尝试在列上设置筛选器。我在Interop中就是这样做的: private void CheckMasterFile(string path) { var xlApp = new Excel.Application(); var xlWorkbook = xlApp.Workbooks.Open(path); Excel._Worksheet xlWorksheet = xlWorkbook.Sheets[1]; foreach (var project i

我正在尝试在列上设置筛选器。我在Interop中就是这样做的:

private void CheckMasterFile(string path) {
    var xlApp = new Excel.Application();
    var xlWorkbook = xlApp.Workbooks.Open(path);
    Excel._Worksheet xlWorksheet = xlWorkbook.Sheets[1];

    foreach (var project in projects) {
        if (string.IsNullOrEmpty(project.ProjectID.Value)) {
            continue;
        }

        var xlRange = xlWorksheet.UsedRange;
        if (xlWorksheet.AutoFilter != null) {
            xlWorksheet.AutoFilterMode = false;
        }
        xlRange.AutoFilter(Field: 2, Criteria1: project.ProjectID.Value);
        var result = xlRange.SpecialCells(Excel.XlCellType.xlCellTypeVisible, Type.Missing);//only shows filtered values
        double sum = 0;

        foreach (Excel.Range row in result.Rows) {
            if (row.Cells[2, 2].Value2() != null) {
                if (!NOT_ALLOWED_RUBRIQUES.Contains((string)row.Cells[2, 8].Value2())) {//check if rubrique is allowed or not
                    //finish method
                }
            }
        }
    }
    xlWorkbook.Close(SaveChanges: false);
    xlApp.Quit();
}
但我在EPPlus中使用autofilter的唯一方法是启用或禁用它,而不是根据特定值筛选列。 大概是这样的:

sheet.Cells["A RANGE HERE"].AutoFilter = true;

因此,我试图在这里实现的是根据特定值过滤一个巨大的Excel文件,然后只显示带有这些值的行。

如果我理解您的要求,这不是EPPlus的意图。这意味着生成excel文件作为端点。您试图做的似乎实际上是使用Excel作为您的分析工具

如果您真的想将筛选器应用到列以进行输出,那么您就不必手动执行此操作,因为EPPlus并不是本机应用筛选器的。所以像这样的事情(我必须自己处理)。但是,您(生成器)仍有责任实际执行分析-在本例中,最后一次
linq
查询:

[TestMethod]
public void AutoFilter_Test()
{
    //http://stackoverflow.com/questions/32723483/adding-a-specific-autofilter-on-a-column

    //Throw in some data
    var datatable = new DataTable("tblData");
    datatable.Columns.AddRange(new[] { new DataColumn("Col1", typeof(int)), new DataColumn("Col2", typeof(int)), new DataColumn("Col3", typeof(object)) });

    for (var i = 0; i < 10; i++)
    {
        var row = datatable.NewRow(); row[0] = i; row[1] = i * 10;row[2] = Path.GetRandomFileName();
        datatable.Rows.Add(row);
    }

    //Create a test file
    var fi = new FileInfo(@"c:\temp\autofilter.xlsx");
    if (fi.Exists)
        fi.Delete();

    using (var pck = new ExcelPackage(fi))
    {
        var worksheet = pck.Workbook.Worksheets.Add("Sheet1");
        worksheet.Cells.LoadFromDataTable(datatable, true);

        var range = worksheet.Cells["A1:C10"];
        range.AutoFilter = true;

        pck.Save();
    }

    //Needed prior save in order for the XML to be generated
    using (var pck = new ExcelPackage(fi))
    {
        var worksheet = pck.Workbook.Worksheets.First();

        //Get reference to the worksheet xml for proper namespace
        var xdoc = worksheet.WorksheetXml;
        var nsm = new XmlNamespaceManager(xdoc.NameTable);
        nsm.AddNamespace("default", xdoc.DocumentElement.NamespaceURI);

        //Create the filters themselves
        var filter1 = xdoc.CreateNode(XmlNodeType.Element, "filter", xdoc.DocumentElement.NamespaceURI);
        var att = xdoc.CreateAttribute("val");
        att.Value = "40";
        filter1.Attributes.Append(att);

        var filter2 = xdoc.CreateNode(XmlNodeType.Element, "filter", xdoc.DocumentElement.NamespaceURI);
        att = xdoc.CreateAttribute("val");
        att.Value = "50";
        filter2.Attributes.Append(att);

        //Add filters to the collection
        var filters = xdoc.CreateNode(XmlNodeType.Element, "filters", xdoc.DocumentElement.NamespaceURI);
        filters.AppendChild(filter1);
        filters.AppendChild(filter2);

        //Create the parent filter container
        var filterColumn = xdoc.CreateNode(XmlNodeType.Element, "filterColumn", xdoc.DocumentElement.NamespaceURI);
        att = xdoc.CreateAttribute("colId");
        att.Value = "1";
        filterColumn.Attributes.Append(att);
        filterColumn.AppendChild(filters);

        //Now add it to the autoFilters node
        var autoFilter = xdoc.SelectSingleNode("/default:worksheet/default:autoFilter", nsm);
        autoFilter.AppendChild(filterColumn);

        //Have to manually hide rows based on criteria
        worksheet.Cells
            .Where(cell =>
                cell.Address.StartsWith("B") 
                && cell.Value is double 
                && (double) cell.Value != 40d 
                && (double) cell.Value != 50d)
            .Select(cell => cell.Start.Row)
            .ToList()
            .ForEach(r => worksheet.Row(r).Hidden = true);

        pck.Save();
    }
}
[TestMethod]
公共无效自动筛选测试()
{
//http://stackoverflow.com/questions/32723483/adding-a-specific-autofilter-on-a-column
//加入一些数据
var数据表=新数据表(“tblData”);
datatable.Columns.AddRange(new[]{new DataColumn(“Col1”,typeof(int)),new DataColumn(“Col2”,typeof(int)),new DataColumn(“Col3”,typeof(object))});
对于(变量i=0;i<10;i++)
{
var row=datatable.NewRow();row[0]=i;row[1]=i*10;row[2]=Path.GetRandomFileName();
datatable.Rows.Add(行);
}
//创建一个测试文件
var fi=new FileInfo(@“c:\temp\autofilter.xlsx”);
如果(fi.存在)
fi.删除();
使用(var pck=新的ExcelPackage(fi))
{
var工作表=pck.工作簿.Worksheets.Add(“表1”);
工作表.Cells.LoadFromDataTable(datatable,true);
变量范围=工作表单元格[“A1:C10”];
range.AutoFilter=true;
pck.Save();
}
//需要先保存,才能生成XML
使用(var pck=新的ExcelPackage(fi))
{
var worksheet=pck.Workbook.Worksheets.First();
//获取对工作表xml的引用以获得适当的命名空间
var xdoc=worksheet.WorksheetXml;
var nsm=新的XmlNamespaceManager(xdoc.NameTable);
nsm.AddNamespace(“默认”,xdoc.DocumentElement.NamespaceURI);
//自己创建过滤器
var filter1=xdoc.CreateNode(XmlNodeType.Element,“filter”,xdoc.DocumentElement.NamespaceURI);
var att=xdoc.CreateAttribute(“val”);
附件值=“40”;
filter1.Attributes.Append(att);
var filter2=xdoc.CreateNode(XmlNodeType.Element,“filter”,xdoc.DocumentElement.NamespaceURI);
att=xdoc.CreateAttribute(“val”);
附件值=“50”;
filter2.Attributes.Append(att);
//向集合中添加筛选器
var filters=xdoc.CreateNode(XmlNodeType.Element,“filters”,xdoc.DocumentElement.NamespaceURI);
filters.AppendChild(filter1);
filters.AppendChild(filter2);
//创建父过滤器容器
var filterColumn=xdoc.CreateNode(XmlNodeType.Element,“filterColumn”,xdoc.DocumentElement.NamespaceURI);
att=xdoc.CreateAttribute(“colId”);
附件Value=“1”;
filterColumn.Attributes.Append(att);
filterColumn.AppendChild(过滤器);
//现在将其添加到“自动过滤器”节点
var autoFilter=xdoc.SelectSingleNode(“/default:worksheet/default:autoFilter”,nsm);
autoFilter.AppendChild(filterColumn);
//必须根据条件手动隐藏行
工作表.单元格
。其中(单元格=>
单元格。地址。起始带(“B”)
&&单元格。值是两倍
&&(双)单元值!=40d
&&(双)单元值!=50d)
.Select(cell=>cell.Start.Row)
托利斯先生()
.ForEach(r=>sheet.Row(r).Hidden=true);
pck.Save();
}
}
输出


我的理解是,您希望生成的excel只包含过滤后的数据,对吗?例如:如果您有1000条记录,并且您的筛选器只匹配50行,那么生成的excel应该只有50行。。我得到的正确吗?不完全是一个新的输出文件,我打开的文件包含1000多条记录。我想在该文件上应用一个过滤器,这样它将只显示50条记录,并在这些单元格上循环,而不是在整个文件中循环,并检查循环中的每个单元格是否等于projectID(project.projectID.Value)