需要一些帮助才能将数据从csv文件上传到数据库。数据库(当然)有预先指定的列名,我想让用户选择CSV文件中的哪些列转到数据库中的哪些列。
查看代码:
@using (Html.BeginForm("Index", "Upload", FormMethod.Post, new { @enctype = "multipart/form-data" }))
{
<input type="file" name="FileUpload" style="margin-left:40px;cursor:pointer;" />
<br />
<input type="submit" style="margin-left:40px;cursor:pointer;" id="upload" value="Upload" />
}
控制器:
[HttpPost]
public ActionResult UploadFile(HttpPostedFileBase FileUpload)
{
// Set up DataTable place holder
DataTable dt = new DataTable();
string fileName = Path.GetFileName(FileUpload.FileName);
string path = Path.Combine(Server.MapPath("~/App_Data/uploads"), fileName);
FileUpload.SaveAs(path);
dt = ProcessCSV(path);
return view(dt);}
private static DataTable ProcessCSV(string fileName)
{
//Set up our variables
string Feedback = string.Empty;
string line = string.Empty;
string[] strArray;
DataTable dt = new DataTable();
DataRow row;
// work out where we should split on comma, but not in a sentence
Regex r = new Regex(",(?=(?:[^\"]*\"[^\"]*\")*(?![^\"]*\"))");
//Set the filename in to our stream
StreamReader sr = new StreamReader(fileName);
//Read the first line and split the string at , with our regular expression in to an array
line = sr.ReadLine();
strArray = r.Split(line);
//For each item in the new split array, dynamically builds our Data columns. Save us having to worry about it.
Array.ForEach(strArray, s => dt.Columns.Add(new DataColumn()));
//Read each line in the CVS file until it’s empty
while ((line = sr.ReadLine()) != null)
{
row = dt.NewRow();
//add our current value to our data row
row.ItemArray = r.Split(line);
dt.Rows.Add(row);
}
//Tidy Streameader up
sr.Dispose();
//return a the new DataTable
return dt;
}
所以我设法将文件上传到服务器,将数据从csv文件读入数据表。现在我只需要将数据库列与数据库中的列名列表一起返回给用户,然后用户可以选择应该进入的列。
我现在需要一个以新形式显示列名的视图。这是我真正需要帮助的地方,不知道如何将导入的CSV中的列名称传递回视图,然后将选定的列名称传递回控制器。
@model System.Data.DataTable
@using System.Data;
<h2>Columns to include</h2>
@using (Html.BeginForm())
<table>
<thead>
<tr>
<th>Column name</th>
<th>Select database column name</th>
</tr>
</thead>
<tbody>
@foreach (DataColumn col in Model.Columns)
{
<tr>
<td>
@col.ColumnName
</td>
<td>
</td>
</tr>
}
</tbody>
</table>
我希望最终能够使用这样的东西
SqlBulkCopyColumnMapping ColFirstName = new SqlBulkCopyColumnMapping("Column1", "Firstname");
SqlBulkCopyColumnMapping ColLastName = new SqlBulkCopyColumnMapping("Column2", "Surname");
SqlBulkCopyColumnMapping ColDOB = new SqlBulkCopyColumnMapping("Column3", "Dateofbirth");
copy.ColumnMappings.Add(ColFirstName);
copy.ColumnMappings.Add(ColLastName);
copy.ColumnMappings.Add(ColDOB);
答案 0 :(得分:0)
public class ColumsViewModel
{
public string[] SelectedNames { get; set; }
public IEnumerable<SelectListItem> Names { get; set; }
}
扩展您的公共ActionResult UploadFile
var model = new SearchViewModel();
var names = dt.Columns.Select(x => new SelectListItem
{
Value = x.ColumnName,
Text = x.ColumnName
}).ToList();
model.Names = names;
return View(model);
在视图中替换@foreach:
@model namespace.ViewModels.ColumsViewModel
@using (Html.BeginForm("SelectedColumns", "Home", FormMethod.Post))
{
@Html.ListBoxFor(m => m.SelectedNames, Model.Names, new Dictionary<string, object> { { "size", "15" } })
}
使用CTRL +鼠标单击选择多个值。
创建行动:
[HttpPost]
public ActionResult SelectedColumns(ColumsViewModel model)
{
//you will have your selected columns in model.SelectedNames
//now you can do what you need with them
}
可能有一些拼写错误,因为我没有用VS进行实际测试,所以你可以修复它。重要的是抓住这个想法。