我的应用程序是使用Interop库读取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);
}
}
在上面我可以使用每个行索引和列索引来获取数据。但是我想使用列名而不是列索引来读取列数据。如何做到这一点。
答案 0 :(得分: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)
尽管如此,这并没有给你带来任何优势。我使用它的原因是为了报告的目的将循环计数器转换为列名,所以如果你需要它,那么它可能是有意义的。
答案 1 :(得分: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()使用它来“按名称”返回给定行中的值。如果找不到列,则返回问号。