如何为DataTable指定列的多值字段添加逗号分隔符以适配CSV导出
我在应用中编写了CloneTable函数用来克隆原始DataTable,添加新列后生成新的DataTable,原函数代码如下:
private static DataTable CloneTable(DataTable originalTable, DataTable newTable, DataTable targetTable, string addedColumn, string columnToExtract, bool multipleConditions = false, string secondColumnName = null, string secondColumnConditon= null) { newTable = originalTable.Clone(); newTable.Columns.Add(addedColumn); foreach (DataRow row in originalTable.Rows) { DataRow[] rowsTarget; if (multipleConditions == false) { rowsTarget = targetTable.Select(string.Format("ItemId='{0}'", Convert.ToString(row["ItemId"]))); } else { rowsTarget = targetTable.Select(string.Format("ItemId='{0}' AND {1} ='{2}'", Convert.ToString(row["ItemId"]), secondColumnName, secondColumnConditon)); } if (rowsTarget != null && rowsTarget.Length > 0) { string data = rowsTarget[0][columnToExtract].ToString(); var lst = row.ItemArray.ToList(); lst.Add(data); newTable.Rows.Add(lst.ToArray()); } else { string data = ""; var lst = row.ItemArray.ToList(); lst.Add(data); newTable.Rows.Add(lst.ToArray()); ErrorLogging.ErrorList.Add(new ErrorLogging() { ErrorType = "Warning", Relation = "Database- to do with column: " + addedColumn , Message = "Data not found for document with the itemId: " + row["ItemId"] }); } } return newTable; }
该函数运行正常,不过DataTable的数据来自SQL查询,部分行的单个字段会包含多个值,比如Language列的某个字段值为English French German。我想要将这类多值用逗号分隔,最终生成的DataTable会导出为CSV文件,当前导出的CSV中Language列的多个单词之间没有逗号分隔,我期望实现的效果是多个单词之间用逗号分隔。
第一次尝试错误
我尝试修改rowsTarget非空分支的代码,但修改后会影响所有其他列,不符合需求,错误尝试代码如下:
if (rowsTarget != null && rowsTarget.Length > 0) { string data = rowsTarget[0][columnToExtract].ToString(); var lst = row.ItemArray.ToList(); lst.Add(data); string test = string.Join(",", lst); foreach (DataColumn column in newTable.Columns) { if (column.ColumnName == "Language") { Console.WriteLine("test"); newTable.Rows.Add(test.ToArray()); } } newTable.Rows.Add(lst.ToArray()); }
错误原因:该写法会把整行数据拼接成一个字符串,再强制拆成字符数组写入行,既会重复插入行,也会破坏原有列的结构。
第二次尝试错误
我又尝试生成DataTable后遍历处理Language列,运行后逗号被加在每个字符后面,而非每个单词后面,错误尝试代码如下:
foreach (DataRow newRow in itemsTable.Rows) { object cellData = newRow["Language"]; string test = string.Join(",", cellData.ToString().ToArray()); Console.WriteLine(test); }
错误原因:cellData.ToString().ToArray()会把字符串拆分为单个字符的数组,string.Join自然会在每个字符之间插入逗号,不符合按单词拆分的需求。
提供两种可选方案,都只会修改指定的Language列,不会影响其他列数据:
方案1:在CloneTable生成新表的阶段处理
如果需要处理的是原始表自带的Language列,修改rowsTarget非空分支的代码即可:
if (rowsTarget != null && rowsTarget.Length > 0) { string data = rowsTarget[0][columnToExtract].ToString(); var lst = row.ItemArray.ToList(); // 新增Language列处理逻辑 int langColIndex = originalTable.Columns.IndexOf("Language"); if (langColIndex >= 0 && lst[langColIndex] != DBNull.Value) { string originalLang = lst[langColIndex].ToString(); // 按空格拆分,过滤连续空格产生的空值后用逗号拼接 lst[langColIndex] = string.Join(",", originalLang.Split(new[] {' '}, StringSplitOptions.RemoveEmptyEntries)); } lst.Add(data); newTable.Rows.Add(lst.ToArray()); }
如果需要处理的是新增的列,只需要在string data = rowsTarget[0][columnToExtract].ToString();之后加判断处理data的值即可。
方案2:生成完整DataTable后统一处理
修正第二次的写法,直接遍历修改目标列的值:
foreach (DataRow newRow in itemsTable.Rows) { // 跳过空值行 if (newRow["Language"] == DBNull.Value || string.IsNullOrWhiteSpace(newRow["Language"].ToString())) { continue; } string originalLang = newRow["Language"].ToString(); // 按空格拆分、过滤空值后用逗号拼接 string processedLang = string.Join(",", originalLang.Split(new[] {' '}, StringSplitOptions.RemoveEmptyEntries)); // 把处理后的值写回原单元格 newRow["Language"] = processedLang; }
内容的提问来源于stack exchange,提问作者lross15

