我使用使用C#和ASP.NET MVC4开发的应用程序从CSV文件填充MySQL中的表。我在加载CSV文件时遇到问题。
我正在阅读CSV文件,填写DataTable,对正则表达式进行验证并最终插入MySql数据库。大。
问题在于CSV文件中的数据格式。看起来当我读取Csv文件时,c#不区分字符串和双重。
当我用分隔符加载数字(双打)时,"。"或","该方法无法识别cvs文件的内容。
我已经审核了区域设置和语言中的格式,但没有得到解决方案。
请允许我解释一下,
从视图中加载,我有点喜欢。
//Here I can choose a Csv File and print the content
@model Pharmtech.Models.myModule.FilesModel
<div>
@using (Html.BeginForm("UploadFile", "myModule", FormMethod.Post,
new { enctype = "multipart/form-data" }))
{
<h3>Choose a Csv File</h3>
<input type="file" name="file" />
<input type="submit" value="Cargar">
}
<p>@TempData["Messages"]</p>
当提交激活 ActionResult UploadFile
时 [HttpPost]
public ActionResult UploadFile(HttpPostedFileBase file)
{
FilesModel model = new FilesModel();
DataTable dt;
//Check if file is not null
if (file != null)
{
//Built the path
string path = DateTime.Now.ToShortDateString().Replace("/", "-")
+ (file.FileName).ToLower();
//Check File Extension
if (model.FileCsv(path))
{
file.SaveAs(Server.MapPath("~/App_Data/" + path));
dt = model.getDataTableFromCsvFile(Server.MapPath("~/App_Data/"), path);
//Check if dt it's not empty
if (dt.Rows.Count > 0)
{
//Save in TempData["Messages"] the dt content
if (model.printDataTableFromCsv(dt))
{
TempData["Messages"] = model.AllData;
}
}
else TempData["Messages"] = "Csv File is Empty";
}else TempData["Messages"] = "File it's not Csv File";
}else TempData["Messages"] = "Please upload a Csv File";
return RedirectToAction("Load");
}
我在 FilesModel 模型
中编写了一些方法验证Csv文件扩展名
public bool FileCsv(string fileName)
{
string ext = Path.GetExtension(fileName);
switch (ext.ToLower())
{
case ".csv": return true;
default: return false;
}
}
从CSV文件中获取DataTable
//Get DataTable from Csv File
public DataTable getDataTableFromCsvFile(String path, String file)
{
//Quit double spaces
System.IO.File.WriteAllText(path + file, Regex.Replace
(System.IO.File.ReadAllText(path + file), " ", " "));
//Defining connection
string connectionStringCsv = @"Provider=Microsoft.Jet.OLEDB.4.0;Data Source=" +
path + ";Extended Properties='text;HDR=Yes;FMT=Delimited'";
DataTable dt = new DataTable();
try
{
OleDbConnection objConn = new OleDbConnection(connectionStringCsv);
objConn.Open();
OleDbCommand objCmdSelect
= new OleDbCommand("select * from [" + file + "]", objConn);
OleDbDataAdapter objAdapter = new OleDbDataAdapter();
objAdapter.SelectCommand = objCmdSelect;
objAdapter.Fill(dt);
objConn.Close();
}
catch (Exception ex)
{
//Do something
}
return dt;
}
最后打印DataTable内容
public string AllData;
public bool printDataTableFromCsv(DataTable masterCsv)
{
AllData = "";
int row = 0;
//Check if DataTable it's not emtpy
if (masterCsv.Rows.Count > 0)
{
//Going through DataTable and print rows
foreach (DataRow rows in masterCsv.Rows)
{
AllData += "Row: " + row
+ "=" + rows["DATA"].ToString() + ". ";
row++;
}
}
if (row != 0) { return true; }
else { return false; }
}
一些例子:
输入1,文件内容
//DATA
//30.33
//20.45
//Output is 1
//I get: "Row: 0=3033. Row: 1=2045"
//**Is to say, remove the "."
输入2,文件内容
//DATA
//20.33
//Hello World
//Output is
//Row: 0=2033.Row: 1=.
//**Is to say, remove the letters
输入3,当文件内容
时 //DATA
//20.33
//Hello World
//This is, a problem
//Output is
//Row: 0=20.33.Row: 1=Hello World.Row: 2=This is, a problem.
我猜错误在于读取csv,C#尝试为DataTable的列分配一种数据
有时,我选择一个只有两倍打印的csv文件&#34; File Empty&#34; 我试过.csv和.csv MS-DOS
有人知道我做错了什么吗? 谢谢你的帮助
答案 0 :(得分:1)
我猜错误在于读取csv,C#尝试为DataTable的列分配一种数据
如果您的列具有混合数据类型,或者包含可以作为不同数据类型读取的数据(即“4-4-97”,可以是日期或字符串),则应使用imex
切换你的连接字符串。
"Provider=Microsoft.Jet.OLEDB.4.0;Data Source=" + someVariablePath + ";Extended Properties=\"text;HDR=Yes;FMT=Delimited;IMEX=1;\"";
或者使用模式文件并获得对数据读取方式的更多控制。请注意,如果切换到较新的数据访问组件(Provider=Microsoft.ACE.OLEDB.12.0
),则IMEX
开关无效,如果您希望控制数据类型,则必须使用模式文件。
[myfile.txt]
Format=CSVDelimited
ColNameHeader=True
MaxScanRows=5
并不是C#尝试定义类型,它是做出该决定的数据驱动程序,并告诉您的代码将要发生什么。驱动程序读取第一行n
并定义类型。然后通过n
行传递一个不再与该类型相匹配的值。
col1
1
2
3
4
5
a
7
true
9
上面的列可能会产生问题。根据前5条记录,我们正在处理int
。因此,在进行列定义时,该列被视为int
。从那时起,您的代码期望看到该列中的数字。但是在记录6中,有一个字符串。记录8可以是string
或bool
。数据驱动程序并不在意,但是当您在需要数字时为"a"
提供类似的代码时,代码会执行此操作。
答案 1 :(得分:0)
部分解决方案引用双引号内的CSV值(这样,JET会将所有读取值视为字符串),然后从C#中解析它们。
经过多次尝试解决并评估负载消耗时间后,我决定不使用Jet.OLEDB
我认为有更合适的方法,例如使用LINQ。
我还发现了这两个项目:
Sebastian LorienA portable and Efficient parse for float files
让我分享这个答案,帮助我找到解决方案:
How to read a CSV file into a .NET Datatable
非常感谢