2015-09-22 9 views
5

पर एक विशिष्ट ऑटोफिल्टर जोड़ना मैं कॉलम पर फ़िल्टर सेट करने का प्रयास कर रहा हूं। इस तरह से मैं इंटरॉप में यह किया है:कॉलम

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 में स्वत: फ़िल्टर के साथ कुछ कर सकते हैं सक्षम या अक्षम करने के लिए, एक विशिष्ट मूल्य पर एक कॉलम फिल्टर करने के लिए नहीं है। कुछ इस तरह:

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

तो क्या मैं यहाँ प्राप्त करने के लिए कोशिश कर रहा हूँ एक विशिष्ट मूल्य पर भारी Excel फ़ाइल फिल्टर करने के लिए और उसके बाद ही उन मूल्यों के साथ पंक्तियों को दिखाने के लिए है।

+0

मैं क्या समझ लिया है है, तो आप चाहते हैं कि जेनरेट किए गए एक्सेल में केवल फ़िल्टर किए गए डेटा सही हों? पूर्व के लिए: यदि आपके पास 1000 रिकॉर्ड हैं और आपका फ़िल्टर केवल 50 पंक्तियों से मेल खाता है तो उत्पन्न एक्सेल में केवल 50 पंक्तियां होनी चाहिए .. क्या मैं इसे सही तरीके से प्राप्त कर रहा हूं? –

+0

अच्छी तरह से एक नई आउटपुट फ़ाइल नहीं है, जिस फ़ाइल में मैं खोल रहा हूं वह 1000 से अधिक रिकॉर्ड हैं। मैं उस फ़ाइल पर एक फ़िल्टर लागू करना चाहता हूं, इसलिए यह केवल मुझे 50 रिकॉर्ड दिखाएगा और पूरी फाइल के माध्यम से लूपिंग के बजाय उन कोशिकाओं पर लूप बनायेगा और जांच करेगा कि उस लूप में प्रत्येक सेल प्रोजेक्ट आईडी (project.ProjectID.Value) के बराबर है या नहीं। – Edward

उत्तर

7

यदि मैं समझता हूं कि आप क्या पूछ रहे हैं, तो यह ईपीप्लस का इरादा नहीं है। यह एक्सेल फ़ाइल को एंडपॉइंट के रूप में उत्पन्न करने के लिए है। आप जो करने का प्रयास कर रहे हैं वह वास्तव में आपके विश्लेषण टूल के रूप में एक्सेल का उपयोग कर रहा है।

यदि आप वास्तव में आउटपुट के लिए कॉलम पर फ़िल्टर लागू करना चाहते हैं तो आप इसे मैन्युअल रूप से करते हैं क्योंकि 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(); 
    } 
} 

आउटपुट

enter image description here