从csv文件结构生成c#模型类

Pov*_*vas 5 c# csv

这里的目标是在输入csv文件后,一个神奇的工具将使用csv中的字段输出c#类.我们来看看例子吧.

输入myFile.csv:

Year,Make,Model
1997,Ford,E350
2000,Mercury,Cougar
Run Code Online (Sandbox Code Playgroud)

输出myFile.cs

public class myFile
{
   public string Year;
   public string Make;
   public string Model;
}
Run Code Online (Sandbox Code Playgroud)

所以,我唯一需要解决的是属性类型.之后我会使用FileHelpers这个类来读取csv文件.稍后它将映射到EntityFramework类(使用AutoMapper)并保存到数据库.

实际上,https://csv2entity.codeplex.com/看起来正在做我需要的,但它只是不起作用 - 我安装它并且在我的Visual Studio中没有任何改变,没有出现新的模板.该项目已完全死亡.打开源代码和......决定我可能只是在stackoverflow中问这个问题:)

FileHelpers只有一个简单的向导,允许您手动添加字段.但我有50个字段,这不是我最后一次需要这样做,所以这里首选自动解决方案.

我相信这个问题以前解决了很多次,有什么帮助吗?

Pov*_*vas 6

谢谢贝德福德,我接受了您的代码并添加了三点:

  • 它删除对属性名称无效的符号。例如“订单号”。将成为“ OrderNo”属性。
  • 能够添加属性和类属性。就我而言,我需要[DelimitedRecord(“,”)]和[FieldOptional()],因为我正在使用FileHelpers。
  • 有些列没有名称,因此它本身会生成名称。命名约定为Column10,Column11等。

最终代码:

public class CsvToClass
{
    public static string CSharpClassCodeFromCsvFile(string filePath, string delimiter = ",", 
        string classAttribute = "", string propertyAttribute = "")
    {
        if (string.IsNullOrWhiteSpace(propertyAttribute) == false)
            propertyAttribute += "\n\t";
        if (string.IsNullOrWhiteSpace(propertyAttribute) == false)
            classAttribute += "\n";

        string[] lines = File.ReadAllLines(filePath);
        string[] columnNames = lines.First().Split(',').Select(str => str.Trim()).ToArray();
        string[] data = lines.Skip(1).ToArray();

        string className = Path.GetFileNameWithoutExtension(filePath);
        // use StringBuilder for better performance
        string code = String.Format("{0}public class {1} {{ \n", classAttribute, className);

        for (int columnIndex = 0; columnIndex < columnNames.Length; columnIndex++)
        {
            var columnName = Regex.Replace(columnNames[columnIndex], @"[\s\.]", string.Empty, RegexOptions.IgnoreCase);
            if (string.IsNullOrEmpty(columnName))
                columnName = "Column" + (columnIndex + 1);
            code += "\t" + GetVariableDeclaration(data, columnIndex, columnName, propertyAttribute) + "\n\n";
        }

        code += "}\n";
        return code;
    }

    public static string GetVariableDeclaration(string[] data, int columnIndex, string columnName, string attribute = null)
    {
        string[] columnValues = data.Select(line => line.Split(',')[columnIndex].Trim()).ToArray();
        string typeAsString;

        if (AllDateTimeValues(columnValues))
        {
            typeAsString = "DateTime";
        }
        else if (AllIntValues(columnValues))
        {
            typeAsString = "int";
        }
        else if (AllDoubleValues(columnValues))
        {
            typeAsString = "double";
        }
        else
        {
            typeAsString = "string";
        }

        string declaration = String.Format("{0}public {1} {2} {{ get; set; }}", attribute, typeAsString, columnName);
        return declaration;
    }

    public static bool AllDoubleValues(string[] values)
    {
        double d;
        return values.All(val => double.TryParse(val, out d));
    }

    public static bool AllIntValues(string[] values)
    {
        int d;
        return values.All(val => int.TryParse(val, out d));
    }

    public static bool AllDateTimeValues(string[] values)
    {
        DateTime d;
        return values.All(val => DateTime.TryParse(val, out d));
    }

    // add other types if you need...
}
Run Code Online (Sandbox Code Playgroud)

用法示例:

class Program
{
    static void Main(string[] args)
    {
        var cSharpClass = CsvToClass.CSharpClassCodeFromCsvFile(@"YourFilePath.csv", ",", "[DelimitedRecord(\",\")]", "[FieldOptional()]");
        File.WriteAllText(@"OutPutPath.cs", cSharpClass);
    }
}
Run Code Online (Sandbox Code Playgroud)

有指向完整代码和有效示例的链接https://github.com/povilaspanavas/CsvToCSharpClass