我需要从一些Excel工作表中读取数据。 excel表中的数据已经过格式化,我可以通过这种方法获得所需的数据。
这就是我在做的事情:
using (var conn = new OleDbConnection(strBld.ToString()))
{
conn.Open();
IEnumerable<IDictionary<string, object>> excelDataRaw =
conn.Query("select * from [Curves$A:IT]").
Cast<IDictionary<string, object>>();
int i = 0;
string previousKey = null;
var curve = new List<IEnumerable<object>>();
var excelData = new Dictionary<string, IDictionary<object, object>>();
//var excelData = new Dictionary<string, IDictionary<string, decimal>>();
foreach (var key in excelDataRaw.Select(dictionary => dictionary.Keys).
ElementAt(i))
{
string key1 = key;
// gets the data from one column within the excel file
curve.Add(excelDataRaw.Select(col => col[key1]).
Where(row => row != null).ToList());
if (i % 2 == 0)
{
// store the column header
previousKey = key;
}
if (i % 2 == 1)
{
// merge the data from the first column (keys)
// with the data from the second column (values)
IEnumerable<object> keys = curve[i - 1];
IEnumerable<object> values = curve[i];
// cast works but than you can't zip the lists together
//IEnumerable<string> keys = curve[i - 1].Cast<string>();
//IEnumerable<decimal> values = curve[i].Cast<decimal>();
// zip them together on their index
var dic = keys.Zip(values, (k, v) => new { k, v }).
ToDictionary(x => x.k, x => x.v);
if (previousKey != null)
{
if (!excelData.ContainsKey(previousKey))
{
excelData.Add(previousKey, dic);
}
}
}
++i;
}
}
我从excel文件中提取所有数据(excelDataRaw)。然后我选择所有属于一个列表(曲线)的数据,并将两个彼此属于一个列表组合成一个字典(dic)。最终结果是一个字典(excelData),它包含excel文件中的列头作为键(previousKey),以及与此列相关的数据作为字典(dic)。
我想从
转换字典(excelData)Dictionary<string, IDictionary<object, object>>
进入
Dictionary<string, IDictionary<string, decimal>>
但我无法将对象转换为字符串或小数,并且在将每个列表转换为所需类型后,我无法将列表压缩在一起以获取字典(dic)。有谁知道如何达到预期的结果(类型)?
答案 0 :(得分:1)
ExcelDataRaw
属于Dictionary<string, IDictionary<object, object>>
类型,因此需要IDictionary<object, object>
作为值。您无法将Dictionary<string,decimal>
转换为IDictionary<object,object>
,因为IDictionary不是协变接口 - 请参阅http://msdn.microsoft.com/en-us/library/dd469487.aspx。
解决方案是将ExcelDataRaw
的类型更改为Dictionary<string, IDictionary<string, decimal>>
或保持原样,并且在尝试使用该字典中的值时,将这些值转换为正确的类型:
foreach(var kv in ExcelDataRaw)
{
Dictionary<string,decimal> convertedValue=kv.Value.ToDictionary(x=>(string)x.Key,x=>(decimal)x.Value);
// or convert it even further down the road
string lookup = "abc";
decimal v = (decimal)kv.Value[lookup];
}
答案 1 :(得分:0)
我找到了一个解决方案,我一定忽略了昨天的明显。一个良好的睡眠之夜有时会有所帮助:)。
IEnumerable<object> keys = curve[i - 1];
IEnumerable<object> values =
curve[i].Where(content => decimal.TryParse(content.ToString(), out num));
Dictionary<string, decimal> dic =
keys.Zip(values, (k, v) => new { k, v }).ToDictionary(
x => (string)x.k, x => decimal.Parse(x.v.ToString()));
if (previousKey != null)
{
if (!excelData.ContainsKey(previousKey))
{
excelData.Add(previousKey, dic);
}
}