0

我的应用程序正在使用互操作库读取 excel 文件数据。我的代码如下。

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

在上面我可以使用每个行索引和列索引来获取数据。但是我想使用列名而不是列索引来读取列数据。如何做到这一点。

4

2 回答 2

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() 使用它“按名称”返回给定行中的值。如果未找到该列,则返回问号。

于 2012-12-29T01:35:29.790 回答
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)

但这并没有真正给你带来任何优势,而不是你目前的做法。我使用它的原因是为了报告目的将循环计数器转换为列名,所以如果你需要它来做类似的事情,那么它可能是有意义的。

于 2012-12-27T18:43:52.587 回答