C# 更改csv导出中的分隔符

C# 更改csv导出中的分隔符,c#,csv,delimiter,C#,Csv,Delimiter,好的,我的csv生成器基本上在工作。它有3列。姓名、职位、日期。不幸的是,现在导出有4列。姓、名、职位、日期。这是因为我从数据库中获取的名称数据是最后一个,第一个。我是否可以轻松更改此分隔符?这将是非常方便的哈哈 大多数CSV解析器将识别引号以补偿数据中的逗号 "Last, First",Admin,2010/01/01 大多数CSV解析器将识别引号以补偿数据中的逗号 "Last, First",Admin,2010/01/01 问题不在于更改分隔符(只需在代码中使用逗号将位更改为您想要使用

好的,我的csv生成器基本上在工作。它有3列。姓名、职位、日期。不幸的是,现在导出有4列。姓、名、职位、日期。这是因为我从数据库中获取的名称数据是最后一个,第一个。我是否可以轻松更改此分隔符?这将是非常方便的哈哈

大多数CSV解析器将识别引号以补偿数据中的逗号

"Last, First",Admin,2010/01/01

大多数CSV解析器将识别引号以补偿数据中的逗号

"Last, First",Admin,2010/01/01

问题不在于更改分隔符(只需在代码中使用逗号将位更改为您想要使用的任何字符),而在于以后它将无法进行互操作

你的问题是你没有正确地逃离你的领域。做一些类似于:

private void WriteItem<T>(StreamWriter sr, T item)
{
    string itemString = item.ToString();
    if(itemString.IndexOfAny('"', ',', '\n', '\r') != -1)//skip test and always escape for different speed/filesize optimisation
    {
        sr.Write('"');
        sr.Write(itemString.Replace("\"", "\"\""));
        sr.Write('"');
    }
    else
        sr.Write(itemString);
}
private void WriteLine<T>(StreamWriter sr, IEnumerable<T> line)
{
    bool first = true;
    foreach(T item in line)
    {
        if(!first)
            sr.Write(',');
        first = false;
        WriteItem(sr, item);
    }
}
private void WriteCSV<T>(StreamWriter sr, IEnumerable<IEnumerable<T>> allLines)
{
    bool first = true;
    foreach(IEnumerable<T> line in allLines)
    {
        if(!first)
            sr.Write('\n');
        first = false;
        WriteLine(sr, line);
    }
}
private void WriteItem(StreamWriter sr,T项)
{
string itemString=item.ToString();
if(itemString.IndexOfAny(“,”,“,“,”\n',“\r')!=-1)//跳过测试并始终转义以获得不同的速度/文件大小优化
{
高级文书主任(“”);
sr.Write(itemString.Replace(“\”,“\”);
高级文书主任(“”);
}
其他的
sr.Write(itemString);
}
专用无效写入线(StreamWriter sr,IEnumerable行)
{
bool first=true;
foreach(T行中的项目)
{
如果(!第一个)
高级写字(“,”);
第一个=假;
书面材料(sr,项目);
}
}
私有void WriteCSV(StreamWriter sr,IEnumerable allLines)
{
bool first=true;
foreach(所有行中的IEnumerable行)
{
如果(!第一个)
sr.Write('\n');
第一个=假;
写线(sr,行);
}
}

当出现“,”或换行符时,WriteItem中引用项的位将处理“Last,First”格式。

问题不在于更改分隔符(您只需将代码中的逗号位更改为您想要使用的任何字符),而在于以后它将无法进行互操作

您的问题是您没有正确地逃离字段。请执行以下操作:

private void WriteItem<T>(StreamWriter sr, T item)
{
    string itemString = item.ToString();
    if(itemString.IndexOfAny('"', ',', '\n', '\r') != -1)//skip test and always escape for different speed/filesize optimisation
    {
        sr.Write('"');
        sr.Write(itemString.Replace("\"", "\"\""));
        sr.Write('"');
    }
    else
        sr.Write(itemString);
}
private void WriteLine<T>(StreamWriter sr, IEnumerable<T> line)
{
    bool first = true;
    foreach(T item in line)
    {
        if(!first)
            sr.Write(',');
        first = false;
        WriteItem(sr, item);
    }
}
private void WriteCSV<T>(StreamWriter sr, IEnumerable<IEnumerable<T>> allLines)
{
    bool first = true;
    foreach(IEnumerable<T> line in allLines)
    {
        if(!first)
            sr.Write('\n');
        first = false;
        WriteLine(sr, line);
    }
}
private void WriteItem(StreamWriter sr,T项)
{
string itemString=item.ToString();
if(itemString.IndexOfAny(“,”,“,“,”\n',“\r')!=-1)//跳过测试并始终转义以获得不同的速度/文件大小优化
{
高级文书主任(“”);
sr.Write(itemString.Replace(“\”,“\”);
高级文书主任(“”);
}
其他的
sr.Write(itemString);
}
专用无效写入线(StreamWriter sr,IEnumerable行)
{
bool first=true;
foreach(T行中的项目)
{
如果(!第一个)
高级写字(“,”);
第一个=假;
书面材料(sr,项目);
}
}
私有void WriteCSV(StreamWriter sr,IEnumerable allLines)
{
bool first=true;
foreach(所有行中的IEnumerable行)
{
如果(!第一个)
sr.Write('\n');
第一个=假;
写线(sr,行);
}
}

当出现“,”或换行符时,在WriteItem中引用项目的位将处理“最后,第一”格式。

我已经多次这样做了,你最好的选择是将你的名字包装起来。这意味着你必须单独处理(某种程度上)

根据我在你的问题中读到的内容,你正在从一个有三列的数据库中提取值:
Name
(LName,FName)、
Position
Date
。所以您的SQL语句看起来像:
从表中选择名称、位置、[Date],其中…
,您可能在某处有一个数据读取器

基于这些假设,我会这样做:

//SQL Connection and SQL Command have been created separately as _conn and _cmd
using(SqlDataReader _read = _cmd.ExecuteReader())
{
    string name = "";
    string position = "";
    string date = "";

    while(_read.Read()) //don't really do this, make sure you're checking for nulls and such
    {
       name = _read.GetString(0);
       position = _read.GetString(1);
       date = _read.GetString(2);

       AddLineToLines(string.Format("{0}|{1}|{2}", name, position, date));
          //AddLineToLines is a call to add to your list of lines so you can 
          // write your file.
    }
}
这将允许您创建管道分隔文件(而不是CSV)并避免转义逗号

如果您必须拥有csv,请将最后一个
string.Format
更改为

string.Format("\"{0}\",{1},{2}", name, position, date)

这将跳过LastName和FirstName之间的逗号。

我已经做了好几次了,你最好还是把你的名字包起来。这意味着你必须单独处理(某种程度上)

根据我在你的问题中读到的内容,你正在从一个有三列的数据库中提取值:
Name
(LName,FName)、
Position
Date
。所以您的SQL语句看起来像:
从表中选择名称、位置、[Date],其中…
,您可能在某处有一个数据读取器

基于这些假设,我会这样做:

//SQL Connection and SQL Command have been created separately as _conn and _cmd
using(SqlDataReader _read = _cmd.ExecuteReader())
{
    string name = "";
    string position = "";
    string date = "";

    while(_read.Read()) //don't really do this, make sure you're checking for nulls and such
    {
       name = _read.GetString(0);
       position = _read.GetString(1);
       date = _read.GetString(2);

       AddLineToLines(string.Format("{0}|{1}|{2}", name, position, date));
          //AddLineToLines is a call to add to your list of lines so you can 
          // write your file.
    }
}
这将允许您创建管道分隔文件(而不是CSV)并避免转义逗号

如果您必须拥有csv,请将最后一个
string.Format
更改为

string.Format("\"{0}\",{1},{2}", name, position, date)

这将转义LastName和FirstName之间的逗号。

您自己构建文件吗?逐行创建文件。因此,基本上,当标题后面有3列时,这很糟糕……我开始得到Smith | John | Position | Date而不是Smith,John | Position | Date……这让我发疯了!你在自己构建文件吗?一行一行地创建文件。因此,基本上,当标题后面有3列时,这很糟糕……我开始得到Smith | John | Position | Date而不是Smith,John | Position | Date……这让我发疯了!现在我正在这样做:dataString+=string.Concat(rep.body[x][y],“,”);基本上,这个数组会遍历并填充数据……我只希望能将每个数组都用引号括起来@汤姆,如果你要这样连接,它最好是相当小的。经过大约5或6个项目后,您肯定至少可以使用StringBuilder。如果您使用基于StreamWriter的解决方案,那么您可以传入StringWriter以获取字符串,但也可以在以后的网页上用于其他用途,因此它提供了最大的灵活性。@Tom:您真的需要重新发明轮子吗?这里有两个您可以使用的工作示例:现在我正在这样做:dataString+=string.Concat(rep.body[x][y],“,”);基本上,这个数组会遍历并填充数据……我只希望能将每个数组都用引号括起来@汤姆,如果你要去的话,它最好很小