2015-09-22 19 views
5

Tôi đang cố gắng đặt bộ lọc trên cột. Đây là cách tôi đã làm nó trong Interop:Thêm bộ lọc tự động cụ thể vào cột

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(); 
} 

Nhưng cách duy nhất tôi có thể làm điều gì đó với AutoFilter trong EPPlus là để kích hoạt hoặc vô hiệu hóa nó, chứ không phải để lọc một cột trên một giá trị cụ thể. Something như thế này:

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

Vì vậy, những gì tôi đang cố gắng để đạt được ở đây là để lọc một file Excel rất lớn về một giá trị cụ thể và sau đó chỉ hiển thị các hàng với những giá trị đó.

+0

Những gì tôi đã hiểu là, bạn muốn excel được tạo nên chỉ có dữ liệu được lọc phải không? Ví dụ: nếu bạn có 1000 bản ghi và bộ lọc của bạn chỉ phù hợp với 50 hàng thì excel được tạo nên chỉ có 50 hàng .. Tôi có nhận được chính xác không? –

+0

cũng không chính xác một tệp mới được xuất, tệp tôi đang mở chứa hơn 1000 bản ghi. Tôi muốn áp dụng một bộ lọc trên tệp đó để nó chỉ hiển thị cho tôi 50 bản ghi và tạo vòng lặp trên các ô đó thay vì lặp qua toàn bộ tệp và kiểm tra xem mỗi ô trong vòng lặp đó có bằng projectID (project.ProjectID.Value) hay không – Edward

Trả lời

7

Nếu tôi hiểu những gì bạn đang hỏi, đó không phải là mục đích của EPPlus. Nó có nghĩa là để tạo ra các tập tin excel như là điểm cuối. Những gì bạn đang cố gắng làm dường như thực sự sử dụng Excel như công cụ phân tích của bạn.

Nếu bạn thực sự muốn áp dụng bộ lọc cho cột cho đầu ra thì bạn havet o làm điều đó theo cách thủ công vì EPPlus không thực sự áp dụng bộ lọc. Vì vậy, một cái gì đó như thế này (đã phải đối phó với điều này bản thân mình). Tuy nhiên, trách nhiệm này vẫn còn nằm trên bạn (máy phát điện) để thực hiện các phân tích - đó linq truy vấn cuối cùng trong trường hợp này:

[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(); 
    } 
} 

OUTPUT

enter image description here

Các vấn đề liên quan