读取数据时 CSV 中不需要的额外新行

Unwanted extra new row in CSV when reading data

我正在尝试从 excel 电子表格中读取数据并将其放入 csv 文件中。我正在使用 ToCSV() 扩展 (https://extensionmethod.net/csharp/list-string/datareader-to-csv)。为了删除任何换行符,我添加了删除“\n”以删除所有额外的换行符,但这只解决了 90% 的数据的问题。还有什么我应该从原始字符串中删除以确保没有多余的行吗?

public static List<string> ToCSV(this IDataReader dataReader, bool includeHeaderAsFirstRow, string separator)
        {
            List<string> csvRows = new List<string>();
            StringBuilder sb = null;

            if (includeHeaderAsFirstRow)
            {
                sb = new StringBuilder();
                for (int index = 0; index < dataReader.FieldCount; index++)
                {
                    if (dataReader.GetName(index) != null)
                        sb.Append(dataReader.GetName(index));

                    if (index < dataReader.FieldCount - 1)
                        sb.Append(separator);
                }
                csvRows.Add(sb.ToString());
            }

            while (dataReader.Read())
            {
                sb = new StringBuilder();
                for (int index = 0; index < dataReader.FieldCount - 1; index++)
                {
                    if (!dataReader.IsDBNull(index))
                    {
                        string value = dataReader.GetValue(index).ToString();
                        if (dataReader.GetFieldType(index) == typeof(String))
                        {
                            //if newline character is used in value, ensure each are replaced.
                            if (value.IndexOf("\n") >= 0)
                                value = value.Replace("\n", "");
                            
                            //If double quotes are used in value, ensure each are replaced but 2.
                            if (value.IndexOf("\"") >= 0)
                                value = value.Replace("\"", "\"\"");

                            //If separtor are is in value, ensure it is put in double quotes.
                            if (value.IndexOf(separator) >= 0)
                                value = "\"" + value + "\"";

                            if (value.IndexOf("CR LF") >= 0)
                                value = value.Replace("CR LF", "");

                            if (value.IndexOf("LF") >= 0)
                                value = value.Replace("LF", "");

                        }
                        sb.Append(value);
                    }

                    if (index < dataReader.FieldCount - 1)
                        sb.Append(separator);
                }

                if (!dataReader.IsDBNull(dataReader.FieldCount - 1))
                    sb.Append(dataReader.GetValue(dataReader.FieldCount - 1).ToString().Replace(separator, " "));

                csvRows.Add(sb.ToString());
            }
            dataReader.Close();
            sb = null;
            return csvRows;
        }
    }

用空字符串替换 \r 和 \n 会消除换行符。但是,我看到您已将“CR LF”和“LF”替换为空字符串。这实际上会替换其中包含“LF”或“CR LF”的任何文本,而不是特殊字符(Carriage Return 和 Line Feed)。

正如 LearnerMantis 所说,您正在替换实际的“CR”和“LF”字符串,而不是特殊字符。

如果您的程序正在读取来自同一环境的文件,您可以使用 System.Environment.NewLine 常量。

循环的内部代码将变为:

string value = dataReader.GetValue(index).ToString();
if (dataReader.GetFieldType(index) == typeof(String))
{
    value = value.Replace(System.Environment.NewLine, "");
}
sb.Append(value);

如果你想管理来自不同环境的文件,那么你可以像这样直接使用Replace函数:

string replaceWith = "";
string value = dataReader.GetValue(index).ToString();
if (dataReader.GetFieldType(index) == typeof(String))
{
    value = value.Replace("\r\n", replaceWith).Replace("\n", replaceWith).Replace("\r", replaceWith);
}
sb.Append(value);

如果您愿意,也可以使用 Regex.Replace

value = Regex.Replace(value, @"\r\n?|\n", "");