如何将由换行符和逗号分隔的字符串转换为 C# 中的 DataTable
How to convert string separated by new line and comma to DataTable in C#
我有这样的字符串:
"Product,Price,Condition
Cd,13,New
Book,9,Used
"
这是这样传递的:
"Product,Price,Condition\r\Cd,13,New\r\nBook,9,Used"
如何将其转换为 DataTable?
尝试使用这个辅助函数来完成:
DataTable dataTable = new DataTable();
bool columnsAdded = false;
foreach (string row in data.Split(new string[] { "\r\n" }, StringSplitOptions.None))
{
DataRow dataRow = dataTable.NewRow();
foreach (string cell in row.Split(','))
{
string[] keyValue = cell.Split('~');
if (!columnsAdded)
{
DataColumn dataColumn = new DataColumn(keyValue[0]);
dataTable.Columns.Add(dataColumn);
}
dataRow[keyValue[0]] = keyValue[1];
}
columnsAdded = true;
dataTable.Rows.Add(dataRow);
}
return dataTable;
但是我没有得到 "connecting cells with appropriate columns" 部分 - 我的细胞在 string[] keyValue = cell.Split('~');
中没有 ~
并且我显然在 DataColumn dataColumn = new DataColumn(keyValue[0]);
[= 处得到了 IndexOutOfRange 16=]
您可以在一次调用中将给定的字符串拆分为扁平的字符串数组。然后您可以遍历数组并填充对象列表。
那部分是可选的,因为您可以立即填充 DataTable
但我认为在处理 DataTable
.[=16= 时使用强类型对象更容易(更易于维护) ]
string input = "Product,Price,Condition\r\nCd,13,New\r\nBook,9,Used";
string[] deconstructedInput = input.Split(new string[] { "\r\n", "," }, StringSplitOptions.None);
List<Product> products = new List<Product>();
for (int i = 3; i < deconstructedInput.Length; i += 3)
{
products.Add(new Product
{
Name = deconstructedInput[i],
Price = Decimal.Parse(deconstructedInput[i + 1]),
Condition = deconstructedInput[i + 2]
});
}
public class Product
{
public string Name { get; set; }
public decimal Price { get; set; }
public string Condition { get; set; }
}
因此,products
集合包含 2 个对象,您可以轻松地对其进行迭代并填充您的 DataTable
。
注意:这需要进一步检查以避免可能的运行时异常,而且它不是动态的。这意味着,如果您有不同结构的输入,它将不起作用。
DataTable dataTable = new DataTable();
dataTable.Columns.Add(new DataColumn(nameof(Product.Name)));
dataTable.Columns.Add(new DataColumn(nameof(Product.Price)));
dataTable.Columns.Add(new DataColumn(nameof(Product.Condition)));
foreach (var product in products)
{
var row = dataTable.NewRow();
row[nameof(Product.Name)] = product.Name;
row[nameof(Product.Price)] = product.Price;
row[nameof(Product.Condition)] = product.Condition;
dataTable.Rows.Add(row);
}
您可以使用 Linq 轻松做到这一点(实际上 Nuget 上有 LinqToCSV,也许您会更喜欢它):
void Main()
{
string data = @"Product,Price,Condition
Cd,13,New
Book,9,Used
";
var table = ToTable(data);
Form f = new Form();
var dgv = new DataGridView { Dock = DockStyle.Fill, DataSource = table };
f.Controls.Add(dgv);
f.Show();
}
private DataTable ToTable(string CSV)
{
DataTable dataTable = new DataTable();
var lines = CSV.Split(new char[] { '\n' }, StringSplitOptions.RemoveEmptyEntries);
foreach (var colname in lines[0].Split(','))
{
dataTable.Columns.Add(new DataColumn(colname));
}
foreach (var row in lines.Where((r, i) => i > 0))
{
dataTable.Rows.Add(row.Split(','));
}
return dataTable;
}
根据你的实现,我给你写了代码,我没有测试过。但是你可以使用这个概念。
DataRow dataRow = dataTable.NewRow();
int i = 0;
foreach (string cell in row.Split(','))
{
if (!columnsAdded)
{
DataColumn dataColumn = new DataColumn(cell);
dataTable.Columns.Add(dataColumn);
}
else
{
dataRow[i] = cell;
}
i++;
}
if(columnsAdded)
{
dataTable.Rows.Add(dataRow);
}
columnsAdded = true;
我有这样的字符串:
"Product,Price,Condition
Cd,13,New
Book,9,Used
"
这是这样传递的:
"Product,Price,Condition\r\Cd,13,New\r\nBook,9,Used"
如何将其转换为 DataTable?
尝试使用这个辅助函数来完成:
DataTable dataTable = new DataTable();
bool columnsAdded = false;
foreach (string row in data.Split(new string[] { "\r\n" }, StringSplitOptions.None))
{
DataRow dataRow = dataTable.NewRow();
foreach (string cell in row.Split(','))
{
string[] keyValue = cell.Split('~');
if (!columnsAdded)
{
DataColumn dataColumn = new DataColumn(keyValue[0]);
dataTable.Columns.Add(dataColumn);
}
dataRow[keyValue[0]] = keyValue[1];
}
columnsAdded = true;
dataTable.Rows.Add(dataRow);
}
return dataTable;
但是我没有得到 "connecting cells with appropriate columns" 部分 - 我的细胞在 string[] keyValue = cell.Split('~');
中没有 ~
并且我显然在 DataColumn dataColumn = new DataColumn(keyValue[0]);
[= 处得到了 IndexOutOfRange 16=]
您可以在一次调用中将给定的字符串拆分为扁平的字符串数组。然后您可以遍历数组并填充对象列表。
那部分是可选的,因为您可以立即填充 DataTable
但我认为在处理 DataTable
.[=16= 时使用强类型对象更容易(更易于维护) ]
string input = "Product,Price,Condition\r\nCd,13,New\r\nBook,9,Used";
string[] deconstructedInput = input.Split(new string[] { "\r\n", "," }, StringSplitOptions.None);
List<Product> products = new List<Product>();
for (int i = 3; i < deconstructedInput.Length; i += 3)
{
products.Add(new Product
{
Name = deconstructedInput[i],
Price = Decimal.Parse(deconstructedInput[i + 1]),
Condition = deconstructedInput[i + 2]
});
}
public class Product
{
public string Name { get; set; }
public decimal Price { get; set; }
public string Condition { get; set; }
}
因此,products
集合包含 2 个对象,您可以轻松地对其进行迭代并填充您的 DataTable
。
注意:这需要进一步检查以避免可能的运行时异常,而且它不是动态的。这意味着,如果您有不同结构的输入,它将不起作用。
DataTable dataTable = new DataTable();
dataTable.Columns.Add(new DataColumn(nameof(Product.Name)));
dataTable.Columns.Add(new DataColumn(nameof(Product.Price)));
dataTable.Columns.Add(new DataColumn(nameof(Product.Condition)));
foreach (var product in products)
{
var row = dataTable.NewRow();
row[nameof(Product.Name)] = product.Name;
row[nameof(Product.Price)] = product.Price;
row[nameof(Product.Condition)] = product.Condition;
dataTable.Rows.Add(row);
}
您可以使用 Linq 轻松做到这一点(实际上 Nuget 上有 LinqToCSV,也许您会更喜欢它):
void Main()
{
string data = @"Product,Price,Condition
Cd,13,New
Book,9,Used
";
var table = ToTable(data);
Form f = new Form();
var dgv = new DataGridView { Dock = DockStyle.Fill, DataSource = table };
f.Controls.Add(dgv);
f.Show();
}
private DataTable ToTable(string CSV)
{
DataTable dataTable = new DataTable();
var lines = CSV.Split(new char[] { '\n' }, StringSplitOptions.RemoveEmptyEntries);
foreach (var colname in lines[0].Split(','))
{
dataTable.Columns.Add(new DataColumn(colname));
}
foreach (var row in lines.Where((r, i) => i > 0))
{
dataTable.Rows.Add(row.Split(','));
}
return dataTable;
}
根据你的实现,我给你写了代码,我没有测试过。但是你可以使用这个概念。
DataRow dataRow = dataTable.NewRow();
int i = 0;
foreach (string cell in row.Split(','))
{
if (!columnsAdded)
{
DataColumn dataColumn = new DataColumn(cell);
dataTable.Columns.Add(dataColumn);
}
else
{
dataRow[i] = cell;
}
i++;
}
if(columnsAdded)
{
dataTable.Rows.Add(dataRow);
}
columnsAdded = true;