2011-11-03 40 views
0

我有这个功能实施解析员工细节,同样我将不得不解析销售,客户等,因为我需要创建2个更多的功能。该代码将在所有的功能被重复仅是差通用解析器设计

  • 功能
  • 实例化适当的对象的返回类型
  • 细胞读取

是否有任何方式来移动所述重复代码到一个类,并配置它,使我重用它?

public List<Employee> ParseEmployee(string filePath) 
     { 
      Application _excelApp = null; 
      Workbooks workBooks = null; 
      Workbook workBook = null; 
      Sheets wSheets = null; 
      Worksheet wSheet = null; 
      Range xlRange = null; 
      Range xlRowRange = null; 
      Range xlcolRange = null; 
      List<Employee> empLst= new List<Employee>(); 
      try 
      { 

       _excelApp = new Application(); 

       workBooks = _excelApp.Workbooks; 
       workBook = workBooks.Open(filePath, Type.Missing, Type.Missing, Type.Missing, Type.Missing, 
                 Type.Missing, Type.Missing, Type.Missing, Type.Missing, 
                 Type.Missing, Type.Missing, Type.Missing, Type.Missing, 
                 Type.Missing, Type.Missing); 


       wSheets = (Sheets)workBook.Sheets; 
       wSheet = (Worksheet)wSheets.get_Item(1); 


       xlRange = wSheet.UsedRange; 
       xlRowRange = xlRange.Rows; 
       xlcolRange = xlRange.Columns; 

       int rowCount = xlRowRange.Count; 
       int colCount = xlcolRange.Count; 

       for (int i = 2; i <= rowCount; i++) 
       { 

        Range cell1 = xlRange.Cells[i, 1] as Range; 
        Range cell2 = xlRange.Cells[i, 2] as Range; 
        Range cell3 = xlRange.Cells[i, 3] as Range; 

        object val1 = cell1.Value2; 
        object val2 = cell2.Value2; 
        object val3 = cell3.Value2; 

        Employee emp = new Employee(); 

        emp.FirstName = val1.ToString(); 
        emp.LastName = val2.ToString(); 
        emp.EmpID = val3.ToString(); 

        empLst.Add(emp); 

        Marshal.ReleaseComObject(cell1); 
        Marshal.ReleaseComObject(cell2); 
        Marshal.ReleaseComObject(cell3); 
       } 

      } 
      catch (Exception exp) 
      { 
      } 
      finally 
      { 
       GC.Collect(); 
       GC.WaitForPendingFinalizers(); 

       workBook.Close(false, Type.Missing, Type.Missing);     
       _excelApp.Quit(); 


       Marshal.ReleaseComObject(xlRowRange); 
       Marshal.ReleaseComObject(xlRange); 
       Marshal.ReleaseComObject(xlcolRange); 
       Marshal.ReleaseComObject(wSheet); 
       Marshal.ReleaseComObject(wSheets);     
       Marshal.ReleaseComObject(workBook); 
       Marshal.ReleaseComObject(workBooks); 

       Marshal.ReleaseComObject(_excelApp); 

      } 


      return empLst; 
     } 

回答

0

我已经重新分解我的代码是这样的

class ExcelParser : IDisposable 
{ 
    bool disposed = false; 
    Application _excelApp = null; 
    Workbooks workBooks = null; 
    Workbook workBook = null; 
    Sheets wSheets = null; 
    Worksheet wSheet = null; 
    Range xlRange = null; 
    Range xlRowRange = null; 
    Range xlcolRange = null; 

    public bool Load(string filePath) 
    { 
     bool bFlag = true; 
     try 
     { 
      _excelApp = new Application(); 

      workBooks = _excelApp.Workbooks; 
      workBook = workBooks.Open(filePath, Type.Missing, Type.Missing, Type.Missing, Type.Missing, 
                Type.Missing, Type.Missing, Type.Missing, Type.Missing, 
                Type.Missing, Type.Missing, Type.Missing, Type.Missing, 
                Type.Missing, Type.Missing); 

      wSheets = (Sheets)workBook.Sheets; 
      wSheet = (Worksheet)wSheets.get_Item(1); 

      xlRange = wSheet.UsedRange; 
      xlRowRange = xlRange.Rows; 
      xlcolRange = xlRange.Columns; 
     } 
     catch (Exception exp) 
     { 
      throw; 
     } 

     return bFlag; 
    } 

    public int GetRowCount() 
    { 
     int rowCount = 0; 
     if(xlRowRange != null) 
      rowCount = xlRowRange.Count; 

     return rowCount; 
    } 

    public string GetValue(int rowIndex, int colIndex) 
    { 
     string value = ""; 
     Range cell = null; 
     try 
     { 
      cell = xlRange.Cells[rowIndex, colIndex] as Range; 
      object val = cell.Value2; 
      value = val.ToString();     
     } 
     catch (Exception exp) 
     { 
     } 
     finally 
     { 
      Marshal.ReleaseComObject(cell); 
     } 

     return value; 
    } 

    protected virtual void Dispose(bool disposing) 
    { 
     if (!this.disposed) 
     { // don't dispose more than once 
      if (disposing) 
      { 
       // disposing==true means you're not in the finalizer, so 
       // you can reference other objects here 
       GC.Collect(); 
       GC.WaitForPendingFinalizers(); 

       if (workBook != null) 
        workBook.Close(false, Type.Missing, Type.Missing); 

       if (_excelApp != null) 
        _excelApp.Quit(); 

       if (xlRowRange != null) 
        Marshal.ReleaseComObject(xlRowRange); 
       if (xlRange != null) 
        Marshal.ReleaseComObject(xlRange); 
       if (xlcolRange != null) 
        Marshal.ReleaseComObject(xlcolRange); 
       if (wSheet != null) 
        Marshal.ReleaseComObject(wSheet); 
       if (wSheets != null) 
        Marshal.ReleaseComObject(wSheets); 
       if (workBook != null) 
        Marshal.ReleaseComObject(workBook); 
       if (workBooks != null) 
        Marshal.ReleaseComObject(workBooks); 
       if (_excelApp != null) 
        Marshal.ReleaseComObject(_excelApp); 
      }    

     } 
     this.disposed = true; 
    } 

    public void Dispose() 
    { 
     Dispose(true); 
     GC.SuppressFinalize(this);    
    } 

    ~ExcelParser() 
    { 
     Dispose(false); 
    } 
} 

和调用代码看起来像这样

public List<Employee> Handle(string filePath) 
     { 
      List<Employee> empLst = new List<Employee>(); 

      ExcelParser exlParser = new ExcelParser(); 
      try 
      { 
       if (exlParser.Load(filePath)) 
       { 
        int rowCount = exlParser.GetRowCount(); 
        for (int i = 2; i <= rowCount; i++) 
        { 
         Employee emp = new Employee(); 

         emp.FirstName = exlParser.GetValue(i, 1); 
         emp.LastName = exlParser.GetValue(i, 2); 
         emp.EmpID  = exlParser.GetValue(i, 3); 

         empLst.Add(emp);      
        } 
       } 
      } 
      catch (Exception exp) 
      { 
      } 
      finally 
      { 
       exlParser.Dispose(); 
      } 

      return empLst; 
     } 

所以现在我可以重用我想使用的任何地方解析器。请评论这是否正确

1

我认为visitor pattern可能是一个很好的选择。您可以修改上述功能,以包含名为visitor的参数。然后您修改for循环相关数据传递给访问者对象:

for (int i = 2; i <= rowCount; i++) 
{ 
    visitor.VisitRow(xlRange.Cells, i); 
} 

visitor.VisitRow()功能将提取它需要与内部保存提取的对象的引用的数据。您将有不同的观众,一个雇主,一个用于销售,客户等

最后,你会写这样的事情:

Visitor employerVisitor = new EmployerVisitor(); 
Visitor salesVisitor = new SalesVisitor(); 

Parse("workbook-employers.xls", employerVisitor); 
Parse("workbook-sales.xls", salesVisitor); 

List<Employee> employers = employerVisitor.GetData(); 
List<Sale> sales = salesVisitor.GetData(); 
0

你可以从一个通用类公开此,沿

public class ObjectParser<T> 
{ 
    public List<T> ParseObject(string filePath, Func<Range, T> f)  
    {  
     Application _excelApp = null;  
     Workbooks workBooks = null;  
     Workbook workBook = null;  
     Sheets wSheets = null;  
     Worksheet wSheet = null;  
     Range xlRange = null;  
     Range xlRowRange = null;  
     Range xlcolRange = null;  
     List<T> lst= new List<T>();  
     try  
     {  

      _excelApp = new Application();  

      workBooks = _excelApp.Workbooks;  
      workBook = workBooks.Open(filePath, Type.Missing, Type.Missing, Type.Missing, Type.Missing,  
                Type.Missing, Type.Missing, Type.Missing, Type.Missing,  
                Type.Missing, Type.Missing, Type.Missing, Type.Missing,  
                Type.Missing, Type.Missing);  


      wSheets = (Sheets)workBook.Sheets;  
      wSheet = (Worksheet)wSheets.get_Item(1);  


      xlRange = wSheet.UsedRange;  
      xlRowRange = xlRange.Rows;  
      xlcolRange = xlRange.Columns;  

      int rowCount = xlRowRange.Count;  
      int colCount = xlcolRange.Count;  

      for (int i = 2; i <= rowCount; i++)  
      {   
       lst.Add(f(xlRange)); 
      }  

     }  
     catch (Exception exp)  
     {  
     }  
     finally  
     {  
      GC.Collect();  
      GC.WaitForPendingFinalizers();  

      workBook.Close(false, Type.Missing, Type.Missing);      
      _excelApp.Quit();  


      Marshal.ReleaseComObject(xlRowRange);  
      Marshal.ReleaseComObject(xlRange);  
      Marshal.ReleaseComObject(xlcolRange);  
      Marshal.ReleaseComObject(wSheet);  
      Marshal.ReleaseComObject(wSheets);      
      Marshal.ReleaseComObject(workBook);  
      Marshal.ReleaseComObject(workBooks);  

      Marshal.ReleaseComObject(_excelApp);  

     }  


     return lst;  
    }  
} 

要使用此:

ObjectParser<Employee> op = new ObjectParser<Employee>() 
op.Parse(filepath, r => /* insert code to handle Employee here */) 

在这里,我关心的是塔的线t一些Marshall.ReleaseComObject()调用被推送到传入的lambda表达式中,这使得它有点重。你能告诉我们更多关于Employee和其他类型之间使用的单元格的区别吗?

+0

该excell表可能有这么多,我不会加载。对于E.g:employeee sheet我可能只加载名字,姓氏和emp ID,有时我可能会加载整个表格。在客户表中,我可能只加载客户ID。它非常有活力。我只是想传递我感兴趣的列的参数,它应该自动工作。 – Jeeva