0

格式化从 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();
    }

}
4

1 回答 1

2

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

而不是有两个循环,你应该只有一个输出的循环

  • 一双”
  • 一个值
  • 环境.新线

对于每次迭代。

假设columns并且data有相同的键,那可能看起来像

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.Valueord.Value包含逗号,则需要用双引号将该单元格的输出括起来。
  • 如果 If pair.Valueord.Value包含逗号并且还包含双引号,则必须将双引号加倍以将其转义。

例子:

小史密斯

必须输出

“小史密斯”

“史密斯”史密斯,JR

必须输出

"""Smitty""小史密斯"

更新

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

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

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

如果您不能使用密钥将正确的数据对与正确的数据相关联,您如何建立这种关联?

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

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

关于 var 关键字

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

关于处置资源

你的线路

write.Dispose();

是有风险的。如果您的任何代码在到达该行之前抛出异常,它将永远不会运行并且写入将不会被释放。最好像这样使用 using关键字:

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

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

try
{
    StreamWriter write = new StreamWriter("c:/temp/testoutputprofile.csv");
    // Your code here
}
finally
{
    write.Dispose();
}
于 2013-01-11T00:16:00.933 回答