LinqToExcel C# 自动将 CSV 值转换为 DATETIME
LinqToExcel C# Automatically casting CSV values to DATETIME
我目前正在使用 LinqToExcel 来解析有效的 CSV 文件,但是当我到达特定列(不是日期)时,它会自动转换为日期时间变量。示例:
2/010/114
将被选为
cc = "2/10/0114 12:00:00 AM"
这是我使用的代码:
var csv = new ExcelQueryFactory(filepath);
var records = from c in csv.Worksheet(0)
let rows = new
{
cc = c[9].ToString(),
}
select rows;
我也尝试过以最原始的格式获取结果,但遇到了同样的问题:
var rawrecords = from c in csv.Worksheet()
select c;
这是设计使然吗?还是我做错了什么?如何确保保留原始字符串?好像有点奇怪的设计..
我以前没有使用过 Linq2Excel,但根据他们 GitHub 上的示例使用信息,我认为以下应该有效:
var csv = new ExcelQueryFactory(filepath);
var records = from c in csv.Worksheet(0)
let rows = new
{
cc = c[9].Cast<string>(),
}
select rows;
更新
在 LinqPad 中尝试此代码后,我可以确认它不起作用,那是因为似乎没有任何方法可以强制它将该单元格解释为字符串,它看起来像 DateTime 所以它就是这样解释的。
我能看到让它做你想做的唯一方法是引用这些值,例如:
A,B
12,"2/010/114"
这会强制它正确读入。
简而言之,我想知道您是否真的需要 LinqToExcel 的复杂性,并且是否可以自己手动读取文件?
示例Reader
我整理了以下非常简单和 hacky reader:
void Main()
{
var reader = new CsvReader();
reader.Read(@"C:\users\clint\desktop\test.csv", 10, 5);
reader.GetDataAtPosition(1,1).Dump();
reader.GetDataAtPosition(2,2).Dump();
reader.GetDataAtPosition(2,2, s => s.Split('/')).Dump();
}
// Define other methods and classes here
public class CsvReader
{
private string[,] _data;
// Take a file, and estimated col and row counts (over-inflate these if needed to ensure the file can be read)
public void Read(string file, int cols, int rows)
{
_data = new string[rows,cols];
GC.Collect(2);
var line = 0;
var col = 0;
using (var stream = new FileStream(file, FileMode.Open, FileAccess.Read, FileShare.Read))
{
using (var reader = new StreamReader(stream))
{
while (!reader.EndOfStream)
{
var lineIn = reader.ReadLine();
var inQuotes = false;
var thisCellRaw = "";
foreach (var ch in lineIn.TrimStart().TrimEnd())
{
if (ch == '"')
{
inQuotes = !inQuotes;
continue;
}
if (ch == ',' && !inQuotes)
{
_data[line, col] = thisCellRaw;
thisCellRaw = "";
col++;
continue;
}
thisCellRaw += ch;
}
if (!string.IsNullOrEmpty(thisCellRaw))
{
_data[line, col] = thisCellRaw;
}
line++;
col = 0;
}
}
}
}
public string GetDataAtPosition(int row, int col)
{
return GetDataAtPosition<string>(row,col);
}
public T GetDataAtPosition<T>(int row, int col, Func<string,T> transform = null)
{
row = row - 1;
col = col - 1;
var item = _data[row,col];
if (item == null) throw new KeyNotFoundException("No data at that position");
return (transform ?? ((s) => (T)Convert.ChangeType(item, typeof(T))))(item);
}
}
它不是最有效的,不应该在生产代码中使用而不进行一些认真的清理和错误处理,但这应该有助于您实现目标;您甚至可以使用某种形式的推理,例如int.TryParse
测试是否应将某些内容视为 int 等
我目前正在使用 LinqToExcel 来解析有效的 CSV 文件,但是当我到达特定列(不是日期)时,它会自动转换为日期时间变量。示例:
2/010/114
将被选为
cc = "2/10/0114 12:00:00 AM"
这是我使用的代码:
var csv = new ExcelQueryFactory(filepath);
var records = from c in csv.Worksheet(0)
let rows = new
{
cc = c[9].ToString(),
}
select rows;
我也尝试过以最原始的格式获取结果,但遇到了同样的问题:
var rawrecords = from c in csv.Worksheet()
select c;
这是设计使然吗?还是我做错了什么?如何确保保留原始字符串?好像有点奇怪的设计..
我以前没有使用过 Linq2Excel,但根据他们 GitHub 上的示例使用信息,我认为以下应该有效:
var csv = new ExcelQueryFactory(filepath);
var records = from c in csv.Worksheet(0)
let rows = new
{
cc = c[9].Cast<string>(),
}
select rows;
更新
在 LinqPad 中尝试此代码后,我可以确认它不起作用,那是因为似乎没有任何方法可以强制它将该单元格解释为字符串,它看起来像 DateTime 所以它就是这样解释的。
我能看到让它做你想做的唯一方法是引用这些值,例如:
A,B
12,"2/010/114"
这会强制它正确读入。
简而言之,我想知道您是否真的需要 LinqToExcel 的复杂性,并且是否可以自己手动读取文件?
示例Reader
我整理了以下非常简单和 hacky reader:
void Main()
{
var reader = new CsvReader();
reader.Read(@"C:\users\clint\desktop\test.csv", 10, 5);
reader.GetDataAtPosition(1,1).Dump();
reader.GetDataAtPosition(2,2).Dump();
reader.GetDataAtPosition(2,2, s => s.Split('/')).Dump();
}
// Define other methods and classes here
public class CsvReader
{
private string[,] _data;
// Take a file, and estimated col and row counts (over-inflate these if needed to ensure the file can be read)
public void Read(string file, int cols, int rows)
{
_data = new string[rows,cols];
GC.Collect(2);
var line = 0;
var col = 0;
using (var stream = new FileStream(file, FileMode.Open, FileAccess.Read, FileShare.Read))
{
using (var reader = new StreamReader(stream))
{
while (!reader.EndOfStream)
{
var lineIn = reader.ReadLine();
var inQuotes = false;
var thisCellRaw = "";
foreach (var ch in lineIn.TrimStart().TrimEnd())
{
if (ch == '"')
{
inQuotes = !inQuotes;
continue;
}
if (ch == ',' && !inQuotes)
{
_data[line, col] = thisCellRaw;
thisCellRaw = "";
col++;
continue;
}
thisCellRaw += ch;
}
if (!string.IsNullOrEmpty(thisCellRaw))
{
_data[line, col] = thisCellRaw;
}
line++;
col = 0;
}
}
}
}
public string GetDataAtPosition(int row, int col)
{
return GetDataAtPosition<string>(row,col);
}
public T GetDataAtPosition<T>(int row, int col, Func<string,T> transform = null)
{
row = row - 1;
col = col - 1;
var item = _data[row,col];
if (item == null) throw new KeyNotFoundException("No data at that position");
return (transform ?? ((s) => (T)Convert.ChangeType(item, typeof(T))))(item);
}
}
它不是最有效的,不应该在生产代码中使用而不进行一些认真的清理和错误处理,但这应该有助于您实现目标;您甚至可以使用某种形式的推理,例如int.TryParse
测试是否应将某些内容视为 int 等