CSV格式问题

时间:2013-01-11 00:11:24

标签: c# csv streamwriter

格式化从C#代码创建的CSV时出现问题。在记事本文件中,输出垂直向下滚动一行(下面结构中显示的值在一行中输出。还有一行数字直接出现在结构值的下方,但数字应该在旁边的新行中结构)。当我在excel中打开时,它是一个类似的故事,只有结构的输出应该是它应该是的位置,但是数字行直接出现在结构值的下方,但是如果有意义则在右边一行,并且数字应该直接出现在它们旁边相应的结构值。我正在使用的代码如下。

以下是我正在使用的词典的结构。

public enum Genders
{
    Male,
    Female,
    Other,
    UnknownorDeclined,
}

public enum Ages
{
    Upto15Years,
    Between16to17Years,
    Between18to24Years,
    Between25to34Years,
    Between35to44Years,
    Between45to54Years,
    Between55to64Years,
    Between65to74Years,
    Between75to84Years,
    EightyFiveandOver,
    UnavailableorDeclined,
}

使用streamwriter和stringbuilder进行输出的csv文件。

public void CSVProfileCreate<T>(Dictionary<T, string> columns, Dictionary<T, int> data)
{
        StreamWriter write = new StreamWriter("c:/temp/testoutputprofile.csv");
        StringBuilder output = new StringBuilder();
        foreach (var pair in columns)
        {
            //output.Append(pair.Key);
            //output.Append(",");
            output.Append(pair.Value);
            output.Append(",");
            output.Append(Environment.NewLine);
        }

        foreach (var d in data)
        {
            //output.Append(pair.Key);
            output.Append(",");
            output.Append(d.Value);
            output.Append(Environment.NewLine);
        }

        write.Write(output);
        write.Dispose();
}

最后是将字典输入csv创建者的方法。

    public void RunReport()
    {
        CSVProfileCreate(genderKeys, genderValues);
        CSVProfileCreate(ageKeys, ageValues);
    }

有什么想法吗?

更新

我通过这样做来修复它:

    public void CSVProfileCreate<T>(Dictionary<T, string> columns, Dictionary<T, int> data)
    {
        StreamWriter write = new StreamWriter("c:/temp/testoutputprofile.csv");
        StringBuilder output = new StringBuilder();

        IEnumerable<string> col = columns.Values.AsEnumerable();
        IEnumerable<int> dat = data.Values.AsEnumerable();

        for (int i = 0; i < col.Count(); i++)
        {
            output.Append(col.ElementAt(i));
            output.Append(",");
            output.Append(dat.ElementAt(i));
            output.Append(",");
            output.Append(Environment.NewLine);
        }

        write.Write(output);
        write.Dispose();
    }

}

1 个答案:

答案 0 :(得分:2)

在输出的每个值之后编写Environment.NewLine。

您应该只有一个输出

的循环,而不是有两个循环
  • “对”
  • Environment.NewLine

每次迭代。

假设columnsdata具有相同的键,则可能类似于

foreach (T key in columns.Keys)
{
    pair = columns[key];
    d = data[key];
    output.Append(pair.Value);
    output.Append(",");
    output.Append(d.Value);
    output.Append(Environment.NewLine);
}

注意两个并发症:

  • 如果pair.Valued.Value包含逗号,则需要用双引号括住该单元格的输出。
  • 如果pair.Valued.Value包含逗号并且还包含双引号,则必须将双引号加倍才能使其退出。

示例:

  

Smith,Jr

必须输出

  

“史密斯,小”

  “Smitty”Smith,Jr

必须输出

  

“”“Smitty”“史密斯,小”

<强>更新

根据您对密钥的评论......

  

出于枚举的目的,字典中的每个项都被视为表示值及其键的KeyValuePair结构。返回项目的顺序未定义。

http://msdn.microsoft.com/en-us/library/xfhwa508.aspx

如果您无法使用密钥将正确的数据对与正确的数据相关联, 如何进行关联?

如果您正在迭代字典并且它们恰好按照您希望的顺序排列,那么这可能是未定义的行为,可能会随着下一个.NET Service Pack而改变。

你需要一些可靠的东西来将这对与正确的数据联系起来。

关于var关键字

var 不是一种类型,而是一种快捷方式,使您无需写出整个类型。如果您愿意,可以使用 var ,但实际类型分别为KeyValuePair<T, string>KeyValuePair<T, int>。您可以看到,如果您使用鼠标在Visual Studio中编写 var 并将鼠标悬停在该关键字上。

关于处理资源

你的行

write.Dispose();

风险很大。如果您的任何代码在到达该行之前抛出异常,它将永远不会运行,并且不会处理 write 。最好使用使用关键字,如下所示:

using (StreamWriter write = new StreamWriter("c:/temp/testoutputprofile.csv"))
{
    // Your code here
}

using 的范围结束时(在关联的}之后),无论是否抛出异常,都会自动调用write.Dispose()。这与

相同,但更短
try
{
    StreamWriter write = new StreamWriter("c:/temp/testoutputprofile.csv");
    // Your code here
}
finally
{
    write.Dispose();
}