2012-12-27 48 views
0

我的應用程序正在使用Interop庫讀取excel文件數據。我的代碼如下。如何按名稱訪問XLSheet列數據?

string filepath = "C:\\SAddresses.xls"; 

XLApp=new Excel.Application(); 
XLBook = XLApp.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); 
XLSheet = (Excel.Worksheet)XLBook.Worksheets.get_Item(1); 
cRange = XLSheet.UsedRange; 


for (int rowcnt = 2; rowcnt < cRange.Rows.Count; rowcnt++) 
{ 
    for (int colidx = 1; colidx < cRange.Columns.Count; colidx++) 
    { 
     colvalue+=((cRange.Cells[rowidx,colidx] as Excel.Range).Value2); 
    } 
} 

在上面,我能得到利用各行索引和列數據index.But我想用列名,而不是列index.How要做到這一點讀取列數據。

+1

你是什麼意思的專欄名稱? A,B,C?或者第一行的文字? –

+0

...我不明白 - 你將如何循環「A」「B」「C」?你能詳細說明你特別想要什麼嗎? –

+1

如果您只是在讀取數據,則可能需要考慮使用OLEDB而不是互操作服務。你可以按名稱定義參考列 - 讓我知道你是否想要一個例子。 –

回答

0

如果你只是想將數字轉換在循環入列名(這是我從你的問題讀取),那麼下面的靜態方法是我在我所有的電子表格程序的使用方法:

public static string ExcelColumnNumberToName(int columnNumber) 
{ 
    int dividend = columnNumber; 
    string columnName = string.Empty; 
    int modulo; 

    while (dividend > 0) 
    { 
     // Get the remainder of a division by 26 (we take one from the dividend as column "A" is not zero, but one). 

     modulo = (dividend - 1) % 26; 

     // Convert the remainder (plus 65 - the ASCII decimal code for "A") to a character and add it to the beginning of the string (since column names 
     // increase by adding letters to the left hand side). 

     columnName = Convert.ToChar(65 + modulo).ToString() + columnName; 

     // Set the dividend for the next iteration of the loop by removing the amount we just converted and dividing it by 26 (in effect treating it like 
     // a base-26 number and dropping it by an order of magnitude) 

     dividend = (int)((dividend - modulo)/26); 
    } 

    return columnName; 
} 

你需要調整你稍微引用單元格的方式。因此,而不是

cRange.Cells[rowidx,colidx] 

你會使用

cRange.get_Range(ExcelColumnNumberToName(colidx), rowidx) 

並沒有真正讓您對您目前如何做,但任何優勢。我使用它的原因是爲了報告目的將循環計數器轉換爲列名,所以如果你需要它的話,那麼它可能是有道理的。

0

這裏是從ExelTable類的摘錄,我一直在使用了一段時間:

class ExcelTable 
{ 
    public const int SignificantCharsInVariableName = 10; 

    private string[] columnNames = null; 
    private string[,] data = null; 

    private string[] DefineColumnNames(string[,] R) 
    { 
     string[] names = new string[R.GetLength(1)]; 

     for (int i = 0; i < R.GetLength(1); i++) 
     { 
      names[i] = R[0, i].Trim(); 
     } 

     return names; 
    } 


    public string GetValue(int row, string varName) 
    { 
     string s; 
     int col; 

     try 
     { 
      col = GetColumn(varName); 

      s = data[row, col].Trim(); 
     } 
     catch (Exception) 
     { 
      s = "???"; 
     } 

     return s; 
    } 


    private int GetColumn(string name) 
    { 
     return GetColumn(name, this.columnNames, obligatory: true); 
    } 

    private int GetColumn(string name, string[] names, bool obligatory = false) 
    { 
     string nameStart; 

     // first try perfect match 
     for (int i = 0; i < names.Length; i++) 
      if (names[i].Equals(name)) 
       return i; 

     // 2nd try to match the significant characters only 
     nameStart = name.PadRight(SignificantCharsInVariableName, ' ').Substring(0, SignificantCharsInVariableName); 
     for (int i = 0; i < names.Length; i++) 
      if (names[i].StartsWith(nameStart)) 
       return i; 

     if (obligatory) 
     { 
      throw new Exception("Undefined Excel sheet column '" + name + "'"); 
     } 

     return -1; 
    } 

} 

的數據是在一個名爲列組織。該名稱是數據數組頂部行中的第一個單元格。示例代碼試圖處理不完美的名稱匹配和其他錯誤情況。可以使用更多的巧妙集合,如Dictionary<string, int>來存儲列名和列索引之間的映射。

我的GetColumn()函數允許非必需列。它由GetValue()用來「按名稱」返回給定行中的值。如果未找到列,則將返回問題標記。