更改 csv 导出中的分隔符

发布于 2024-09-15 14:56:44 字数 128 浏览 4 评论 0原文

好的,我的 csv 生成器基本上可以工作了。它有 3 列。姓名、职位、日期。不幸的是,现在导出有 4 列。姓氏、名字、职位、日期。这是因为我从数据库中获取的名称数据是“最后”、“第一”。无论如何,我可以轻松更改此分隔符吗?这样就很方便了哈哈。

Okay I have my csv builder essentially working. it has 3 columns. Name, Position, Date. Unfortunately right now the export has 4 columns. Last name, First name, position, date. This is because the data I get out of my data base for the name goes Last, First. Is there anyway I can easily change this delimiter? This would be very convenient haha.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

娇柔作态 2024-09-22 14:56:44

我不得不这样做好几次,最好的办法就是把你的名字包起来。这确实意味着您必须单独处理它(某种程度上)。

根据我在您的问题中读到的内容,您正在从具有三列的数据库中提取值:Name(LName,FName)、Position日期。所以你的 SQL 语句看起来像这样:SELECT Name, Position, [Date] FROM Table WHERE ... 并且你可能在某处有一个数据读取器。

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

//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 之间的逗号。

I've had to do this several times, and your best bet is to wrap your name. This does mean you'll have to handle it separately (sort of).

Based on what I'm reading in your question, you're pulling values from a DB that has three columns: Name (LName, FName), Position, and Date. So your SQL Statement looks something like: SELECT Name, Position, [Date] FROM Table WHERE ... And you probably have a data reader somewhere.

Based on those assumptions, I'd do this:

//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.
    }
}

This will allow you to create a Pipe Delimited file (instead of CSV) and avoid having to escape commas.

If you must have csv, change that last string.Format to

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

which will escape the commas between LastName and FirstName.

过度放纵 2024-09-22 14:56:44

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

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

Most CSV parsers will recognize quotes to compensate for commas in the data.

"Last, First",Admin,2010/01/01
被你宠の有点坏 2024-09-22 14:56:44

问题不在于更改分隔符(您只需将代码中带有逗号的位更改为您想要使用的任何字符),但之后它不会具有互操作性。

你的问题是你没有正确地逃离你的领域。执行类似以下操作:

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);
    }
}

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

The problem isn't changing the delimiter (you just change the bit in your code with a comma to be whatever character you want to use) but that it won't be as interoperable afterwards.

Your problem is that you are not correctly escapeing your fields. Do something like:

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);
    }
}

and the bit in WriteItem that quotes the item when there is a ", or newline present will deal with your "Last, First" format.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文