{"id":23734389,"url":"https://github.com/fmazzant/tinycsv","last_synced_at":"2025-10-15T03:35:29.493Z","repository":{"id":36965154,"uuid":"482477489","full_name":"fmazzant/TinyCsv","owner":"fmazzant","description":"TinyCsv is a .NET library to read and write CSV data in an easy way. ","archived":false,"fork":false,"pushed_at":"2025-03-17T17:23:34.000Z","size":1245,"stargazers_count":2,"open_issues_count":0,"forks_count":0,"subscribers_count":1,"default_branch":"master","last_synced_at":"2025-10-10T11:44:35.190Z","etag":null,"topics":["c-sharp","csv","csv-export","csv-files","csv-import","csv-parser","export","import"],"latest_commit_sha":null,"homepage":"","language":"C#","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/fmazzant.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE.md","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":"SECURITY.md","support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2022-04-17T09:14:42.000Z","updated_at":"2025-03-18T15:10:48.000Z","dependencies_parsed_at":"2024-12-31T05:45:45.882Z","dependency_job_id":"db21bcdf-37d8-4577-b0dd-34430ff9606a","html_url":"https://github.com/fmazzant/TinyCsv","commit_stats":{"total_commits":372,"total_committers":2,"mean_commits":186.0,"dds":"0.19354838709677424","last_synced_commit":"dd89c0ea8cb6702cd8649f0338ba1cfa970eaab5"},"previous_names":[],"tags_count":23,"template":false,"template_full_name":null,"purl":"pkg:github/fmazzant/TinyCsv","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/fmazzant%2FTinyCsv","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/fmazzant%2FTinyCsv/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/fmazzant%2FTinyCsv/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/fmazzant%2FTinyCsv/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/fmazzant","download_url":"https://codeload.github.com/fmazzant/TinyCsv/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/fmazzant%2FTinyCsv/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":279043436,"owners_count":26091457,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","status":"online","status_checked_at":"2025-10-15T02:00:07.814Z","response_time":56,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["c-sharp","csv","csv-export","csv-files","csv-import","csv-parser","export","import"],"created_at":"2024-12-31T05:45:32.852Z","updated_at":"2025-10-15T03:35:29.475Z","avatar_url":"https://github.com/fmazzant.png","language":"C#","funding_links":[],"categories":[],"sub_categories":[],"readme":"\n# TinyCsv\n\nTinyCsv is a .NET library to read and write CSV data in an easy way.\n\nTo use it in your project, add the Mafe.TinyCsv NuGet package to your project.\n\n[![Nuget](https://img.shields.io/nuget/v/Mafe.TinyCsv?style=flat-square)](https://www.nuget.org/packages/Mafe.TinyCsv/2.2.1)\n![Nuget](https://img.shields.io/nuget/dt/Mafe.TinyCsv?style=flat-square)\n\nIt is available an AspNetCore extension:\n\n[![Nuget](https://img.shields.io/nuget/v/Mafe.TinyCsv.AspNetCore?style=flat-square)](https://www.nuget.org/packages/Mafe.TinyCsv.AspNetCore/1.0.0)\n![Nuget](https://img.shields.io/nuget/dt/Mafe.TinyCsv.AspNetCore?style=flat-square)\n\nDefine the model that you want to use, like this:\n\n```c#\npublic class Model\n{\n    public int Id { get; set; }\n    public string Name { get; set; }\n    public decimal Price { get; set; }\n    public DateTime CreatedOn { get; set; }\n    public string TextBase64 { get; set; }\n}\n```\n\nNow, it is necessary to define the TinyCSV options, like this:\n\n```c#\nvar csv = new TinyCsv\u003cModel\u003e(options =\u003e\n{\n    // Options\n    options.HasHeaderRecord = true;\n    options.Delimiter = \";\";\n    options.RowsToSkip = 0;\n    options.SkipRow = (row, idx) =\u003e string.IsNullOrWhiteSpace(row) || row.StartsWith(\"#\");\n    options.TrimData = true;\n    options.AllowRowEnclosedInDoubleQuotesValues = true;\n    options.EnableHandlers = false;\n    options.ValidateColumnCount = true;\n\n    // Columns\n    options.Columns.AddColumn(m =\u003e m.Id);\n    options.Columns.AddColumn(m =\u003e m.Name);\n    options.Columns.AddColumn(m =\u003e m.Price);\n    options.Columns.AddColumn(m =\u003e m.CreatedOn, \"dd/MM/yyyy\");\n    options.Columns.AddColumn(m =\u003e m.TextBase64, new Base64Converter());\n});\n```\n\nThe options defines that the file has the header in first row and the delimier char is \";\", furthermore there are defined some columns.\nRowsToSkip and SkipRow are used to skip the first rows of the file.\nTrimData is used to remove the white spaces from the data.\n\n## Custom Value Converter\n\nIt is possible to define a custom converter for a column, like this:\n\n```c#\npublic class Base64Converter : IValueConverter\n{\n    public string Convert(object value, object parameter, IFormatProvider provider) \n        =\u003e Base64Encode($\"{value}\");\n\n    public object ConvertBack(string value, Type targetType, object parameter, IFormatProvider provider) \n        =\u003e Base64Decode(value);\n\n    private string Base64Encode(string plainText)\n    {\n        var plainTextBytes = System.Text.Encoding.UTF8.GetBytes(plainText);\n        return System.Convert.ToBase64String(plainTextBytes);\n    }\n\n    private string Base64Decode(string base64EncodedData)\n    {\n        var base64EncodedBytes = System.Convert.FromBase64String(base64EncodedData);\n        return System.Text.Encoding.UTF8.GetString(base64EncodedBytes);\n    }\n}\n```\n\nBase64Converter is used to convert the data column to a base64 string and vice versa for TextBase64 column.\n\nA column is defined with the model's property only. The library get or set the value in automatically.\n\n## Read\n\nTo read a csv file is only necessary invoke the load method, like this:\n\n```c#\nvar models = csv.LoadFromFile(\"file.csv\");\nforeach(var model in models){\n    // processing\n}\n```\n\nor you can to use the asynchronously method, like this:\n\n```c#\nvar models = await csv.LoadFromFileAsync(\"file.csv\");\nawait foreach(var model in models){\n    // processing\n}\n```\n\nfor NET5_0_OR_GREATER or NETSTANDARD2_1_OR_GREATER, like this:\n\n```c#\nvar models = await csv.LoadFromFileAsync(\"file.csv\").ToListAsync();\n```\n\nThe load method returns a collection of Model type items and takes as argument the file's path.\n\n## Write\n\nTo write a csv file is only necessary invoke the Save method, like this:\n\n```c#\ncsv.Save(\"file_export.csv\", models);\n```\n\nor you can to use the asynchronously method, like this:\n\n```c#\nawait csv.SaveAsync(\"file_export.csv\", models);\n```\n\nThe save method takes the file's path and a collection of Model type.\nThe method saves the file.\n\n## Event handlers\n\nIt's possible to define event handlers for the events of the library, like this:\n\n```c#\noptions.Handlers.Read.RowHeader += (s, e) =\u003e Console.WriteLine($\"Row header: {e.RowHeader}\");\noptions.Handlers.Read.RowReading += (s, e) =\u003e Console.WriteLine($\"{e.Index}-{e.Row}\");\noptions.Handlers.Read.RowRead += (s, e) =\u003e Console.WriteLine($\"{e.Index}-{e.Model}\");\n```\n\nand the write handlers are:\n\n```c#\noptions.Handlers.Write.RowHeader += (s, e) =\u003e Console.WriteLine($\"Row header: {e.RowHeader}\");\noptions.Handlers.Write.RowWriting += (s, e) =\u003e Console.WriteLine($\"{e.Index} - {e.Model}\");\noptions.Handlers.Write.RowWrittin += (s, e) =\u003e Console.WriteLine($\"{e.Index} - {e.Row}\");\n```\n\nThe handlers are enabled if the option \"EnableHandlers\" is set true value, like this:\n\n```c#\nvar csv = new TinyCsv\u003cModel\u003e(options =\u003e\n{\n    // Options\n    // ...\n    options.EnableHandlers = true;\n    //...\n\n    // Columns\n    // ...\n});\n```\n## Using attributes in the model definition\n\nYou can use, in alternative way, the attributes in the model definition, like this:\n\n```c#\n[Delimiter(\";\")]\n[RowsToSkip(0)]\n[SkipRow(typeof(CustomSkipRow))]\n[TrimData(true)]\n[ValidateColumnCount(true)]\n[HasHeaderRecord(true)]\npublic class AttributeModel\n{\n    [Column]\n    public int Id { get; set; }\n\n    [Column]\n    public string Name { get; set; }\n\n    [Column]\n    public decimal Price { get; set; }\n\n    [Column(format: \"dd/MM/yyyy\")]\n    public DateTime CreatedOn { get; set; }\n\n    [Column(converter: typeof(Base64Converter))]\n    public string TextBase64 { get; set; }\n\n    public override string ToString()\n    {\n        return $\"ToString: {Id}, {Name}, {Price}, {CreatedOn}, {TextBase64}\";\n    }\n}\n\nclass CustomSkipRow : ISkipRow\n{\n    public Func\u003cstring, int, bool\u003e SkipRow { get; } = (row, idx) =\u003e string.IsNullOrWhiteSpace(row) || row.StartsWith(\"#\");\n}\n\nclass Base64Converter : IValueConverter {\n    ...\n}\n\n```\n\nand you can use it, like this\n\n```c#\n var csv = new TinyCsv\u003cAttributeModel\u003e();\n```\n\n## Performance\n\n![alt TinyCsv Performance](benchmark/images/performance.png)\n\n\n## TinyCsv.AspNetCore Extensions\n\nIs available the Mafe.TinyCsv.Extensions library to use the TinyCsv in your project and it is downloadable in the NuGet package.\n\n[![Nuget](https://img.shields.io/nuget/v/Mafe.TinyCsv.AspNetCore?style=flat-square)](https://www.nuget.org/packages/Mafe.TinyCsv.AspNetCore/1.0.0)\n![Nuget](https://img.shields.io/nuget/dt/Mafe.TinyCsv.AspNetCore?style=flat-square)\n\nIt's possible to use the extensions methods in your project, like this:\n\n```c#\nvar builder = WebApplication.CreateBuilder(args);\n\nbuilder.Services.AddTinyCsv\u003cModel1\u003e(\"Model1\", options =\u003e\n{\n    // Options\n    options.HasHeaderRecord = true;\n    options.Delimiter = \";\";\n    options.SkipRow = (row, idx) =\u003e string.IsNullOrWhiteSpace(row) || row.StartsWith(\"#\");\n   \n    // columns\n    options.Columns.AddColumn(m =\u003e m.Id);\n    options.Columns.AddColumn(m =\u003e m.Name);\n    options.Columns.AddColumn(m =\u003e m.Price);\n});\n\nvar app = builder.Build();\n\napp.MapGet(\"/csv1\", [AllowAnonymous] async (ITinyCsvFactory tinyCsvFactory) =\u003e\n{\n    var tinyCsv = tinyCsvFactory.Get\u003cModel1\u003e(\"Model1\");\n    var result = await tinyCsv.LoadFromFileAsync(\"model1.csv\");\n    Console.WriteLine($\"{result?.Count()}\");\n    return result;\n});\n\napp.MapGet(\"/csv2\", [AllowAnonymous] async (ITinyCsvFactory tinyCsvFactory) =\u003e\n{\n    var tinyCsv = tinyCsvFactory.Create\u003cModel2\u003e(options =\u003e\n    {\n        options.HasHeaderRecord = true;\n        options.Delimiter = \";\";\n        options.SkipRow = (row, idx) =\u003e string.IsNullOrWhiteSpace(row) || row.StartsWith(\"#\");\n        options.Columns.AddColumn(m =\u003e m.Id);\n        options.Columns.AddColumn(m =\u003e m.Name);\n    });\n    var result = await tinyCsv.LoadFromFileAsync(\"model2.csv\");\n    Console.WriteLine($\"{result?.Count()}\");\n    return result;\n});\n\napp.Run();\n```\n\nThe AddTinyCsv method extension takes the name of the model (the name is a unique key)\nand the options. The method defines a TinyCsv instance.\n\nThe specific model is retriving with the Get method, like this:\n\n```c#\nvar tinyCsv = tinyCsvFactory.Get\u003cModel1\u003e(\"Model1\");\n```\n\nThe library is very very simple to use.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ffmazzant%2Ftinycsv","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Ffmazzant%2Ftinycsv","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ffmazzant%2Ftinycsv/lists"}