Click here to Skip to main content
15,881,715 members
Articles / Productivity Apps and Services / Microsoft Office / Microsoft Excel
Tip/Trick

I am writing another data import from the file and again I have to do the same validation or.. I will use this!

Rate me:
Please Sign up or sign in to vote.
4.20/5 (12 votes)
14 Oct 2017CPOL2 min read 25.7K   20   9
Nice solution for easy load data from files with extensions: .csv, .xls, .xlsx

Introduction

I'm writing data import that supports several file formats. I'm testing some libraries. I did not find one that would work properly on all the required formats. Do you have such experiences? So I have good news for you! This tool will solve your problems! -> Fileo (http://fileo.even-simpler.com)

Background

In many projects, one of the features is to import data from files. This process usually looks like this: we load the data from some file, validate and correct data we process.

Developers often have different opinions as to which library is better for loading data from a file. But is that the most important thing? What if the import needed to support different types of files? For example: .csv, .xls, .xlsx.

In my opinion, it does not matter how we load the data but what we will do with them next. That's why I came up with the idea to develop a solution that will allow us to forget about how to load data from file into memory and focus on data processing.

Using the Code

The best way to see how to use this library is to analyze the Fileo.Tests project included in solution Fileo. There are some examples here.

How to use it?

  1. Create a class with information about imported file structure. Specify the types of the individual columns and set information about validations. For example:
    C#
    internal class Test1ImportFileStructure : ImportFileStructureBase
    {
        private readonly string[] _dateTimeFormats = { "dd/MM/yyyy"};
        private readonly CultureInfo _cultureInfo = new CultureInfo("en-GB");
        private const string CustomRegularExpression = "^(Y|N)+$";
    
        public override IList Columns => new List
        {
            Column.CreateIdentityStringColumn(Test1Columns.Col1String, 0, 5),
            Column.CreateStringColumn(Test1Columns.Col2StringNull, 1, false, 5),
            Column.CreateIntColumn(Test1Columns.Col3Int, 2, true),
            Column.CreateIntColumn(Test1Columns.Col4IntNull, 3, false, -90, 90),
            Column.CreateDateTimeColumn(Test1Columns.Col5DateTime, 4, true, _dateTimeFormats),
            Column.CreateDateTimeColumn(Test1Columns.Col6DateTimeNull, 5, false, _dateTimeFormats),
            Column.CreateDecimalColumn(Test1Columns.Col7Decimal, 6, true, _cultureInfo, 0, 10),
            Column.CreateDecimalColumn(Test1Columns.Col8DecimalNull, 7, false, _cultureInfo, 0, 100),
            Column.CreateBoolColumn(Test1Columns.Col9Bool, 8, true),
            Column.CreateBoolColumn(Test1Columns.Col10BoolNull, 9, false),
            Column.CreateStringColumn(Test1Columns.Col11Email, 10, true, 100, RegexValidation.Email),
            Column.CreateStringColumnWithCustomRegex(Test1Columns.Col12CustomRegex, 11, 
                                    true, 1, CustomRegularExpression),
        };
  2. Create a class which will represent one row from file. For example:
    C#
    public class Test1ImportResult
    {
        public string Col1String { get; set; }
        public string Col2StringNull { get; set; }
        public int Col3Int { get; set; }
        public int? Col4IntNull { get; set; }
        public DateTime Col5DateTime { get; set; }
        public DateTime? Col6DateTimeNull { get; set; }
        public decimal Col7Decimal { get; set; }
        public decimal? Col8DecimalNull { get; set; }
        public bool Col9Bool { get; set; }
        public bool? Col10BoolNull { get; set; }
        public string Col11Email { get; set; }
        public string Col12CustomRegex { get; set; }
    }    
  3. Create a generic class which will represent all imported data. For example:
    C#
    public class ImportResult< T>
    {
        public IList< string> Errors { get; }
        public bool HasErrors { get { return !Errors.IsNullOrEmpty() && Errors.Any(); } }
        public IList< T> Objects { get; private set; }
    
        public ImportResult(IList< T> objects, IList< string> errors)
        {
            Objects = objects;
            Errors = errors;
        }
    }
  4. Create a class which will parse data from file to your class (from point 2). For example:
    C#
    internal class Test1Import
    {
        private readonly Table _fileDataInternal;
    
        public Test1Import(Table fileData)
        {
            _fileDataInternal = fileData;
            Validate();
        }
    
        public ImportResult< Test1ImportResult> Import()
        {
            var objects = _fileDataInternal.CorrectRows.Select(row => new Test1ImportResult
            {
                Col1String = row.GetStringValue(Test1Columns.Col1String, true),
                Col2StringNull = row.GetStringValue(Test1Columns.Col2StringNull, false),
                Col3Int = row.GetIntValue(Test1Columns.Col3Int),
                Col4IntNull = row.GetNullableIntValue(Test1Columns.Col4IntNull),
                Col5DateTime = row.GetDateValue(Test1Columns.Col5DateTime),
                Col6DateTimeNull = row.GetNullableDateValue(Test1Columns.Col6DateTimeNull),
                Col7Decimal = row.GetDecimalValue(Test1Columns.Col7Decimal),
                Col8DecimalNull = row.GetNullableDecimalValue(Test1Columns.Col8DecimalNull),
                Col9Bool = row.GetBoolValue(Test1Columns.Col9Bool),
                Col10BoolNull = row.GetNullableBoolValue(Test1Columns.Col10BoolNull),
                Col11Email = row.GetStringValue(Test1Columns.Col11Email, true),
                Col12CustomRegex = row.GetStringValue(Test1Columns.Col12CustomRegex, true)
            }).ToList();
    
            var result = new ImportResult< Test1ImportResult>(objects, _fileDataInternal.GetErrors());
            return result;
        }
    
        private void Validate()
        {
            if (_fileDataInternal == null)
            {
                throw new ArgumentNullException("fileData");
            }
        }
    } 
  5. Create a class which will have methods which will use Fileo to parse file (.csv, .xls, .xlsx) to your class.
    C#
    public static class Imports
    {
        public static ImportResult< Test1ImportResult> 
        ImportTest1(HttpPostedFileBase httpPostedFileBase)
        {
            var fileData = ImporterHelper.ImportFromFile
                           (httpPostedFileBase, new Test1ImportFileStructure());
            var venuesImport = new Test1Import(fileData);
            return venuesImport.Import();
        }
    }
  6. Call your methods (from point 5) and you get your data.

Summary

Fileo will greatly simplify the process of data validation because supports many common types of validation. This allows you to focus only on the custom cases.

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)


Written By
Poland Poland
This member has not yet provided a Biography. Assume it's interesting and varied, and probably something to do with programming.

Comments and Discussions

 
QuestionInteresting idea Pin
Michael Ecklin6-Jun-17 10:50
Michael Ecklin6-Jun-17 10:50 
AnswerRe: Interesting idea Pin
Krzysiek Wiśniewski6-Jun-17 19:23
Krzysiek Wiśniewski6-Jun-17 19:23 
GeneralMy vote of 2 Pin
Аslam Iqbal30-May-17 23:45
professionalАslam Iqbal30-May-17 23:45 
GeneralRe: My vote of 2 Pin
Krzysiek Wiśniewski31-May-17 4:47
Krzysiek Wiśniewski31-May-17 4:47 
GeneralRe: My vote of 2 Pin
Аslam Iqbal31-May-17 4:54
professionalАslam Iqbal31-May-17 4:54 
GeneralRe: My vote of 2 Pin
Krzysiek Wiśniewski31-May-17 6:11
Krzysiek Wiśniewski31-May-17 6:11 
GeneralRe: My vote of 2 Pin
Аslam Iqbal31-May-17 6:36
professionalАslam Iqbal31-May-17 6:36 
GeneralRe: My vote of 2 Pin
Ehsan Sajjad23-Jun-17 10:22
professionalEhsan Sajjad23-Jun-17 10:22 
GeneralRe: My vote of 2 Pin
Krzysiek Wiśniewski25-Jun-17 21:23
Krzysiek Wiśniewski25-Jun-17 21:23 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Praise Praise    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.