wtorek, 13 stycznia 2015

C# - Parsowanie pliku CSV

Witajcie.
Czasem, może zajść potrzeba odczytania zawartości pliku csv (comma separated values)
czyli jest to plik, który ma zawartość rozdzieloną przecinkami bądź średnikami.
Taki plik jeśli otworzymy jakimkolwiek edytorem tekstu zobaczymy właśnie
dane rozdzielone wspomnianymi znakami.

Przykład:
ID;Imie;Nazwisko;NazwaFirmy;Adres
1;Janek;Kowalski;
ACME;USA;
2;Malgosia;Kowalska;
ACME2;Polska;
3;Kubus;Puchatek;
Lasek;GB;
4;Papa;Serf;
Smerfolandia;Smerfolas;
5;Gargus;Gargamel;
Dom;KoloLasuSmerfow;


Jest to zawartość, pliku jaki sobie przygotowałem a który odczytamy. Jak widać
plik zawiera nagłówek, czyli dla nas będą to nazwy kolumn.

Ok. Stwórzmy projekt winformsowy, ponieważ dla lepszego zobrazowania
dane wrzucimy do kontrolki DataGridView.
Do projektu dodamy dwie klasy. Pierwszą nazwijmy "Employee" a  drugą
"ParseFile"

Klasa Employee:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace ParseCSVfile
{
    public class Employee
    {
        public string ID { get; set; }
        public string Imie { get; set; }
        public string Nazwisko { get; set; }
        public string NazwaFirmy { get; set; }
        public string Adres { get; set; }
    }
}

W klasie dodajemy pięć właściwości zgodnie z tym jaki mamy nagłówek w pliku csv

Klasa ParseFile:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.IO;

namespace ParseCSVfile
{
    public class ParseFile
    {
        private string sciezka;

        public ParseFile(string sciezka)
        {
            this.sciezka = sciezka;
        }


        public List OdczytajPlik()
        {
            try
            {
                List listaWyjsciowa = new List();
                string[] dane = File.ReadAllLines(sciezka).Skip(1).ToArray();


                List daneZPliku = new List();
                for (int i = 0; i < dane.Length; i += 2)
                {
                    daneZPliku.Add(String.Format("{0}{1}", dane[i], dane[i + 1]));
                }


                foreach (string wiersz in daneZPliku)
                {
                    string[] wierszRozbity = wiersz.Split(';');
                    listaWyjsciowa.Add(new Employee
                    {
                        ID = wierszRozbity[0],
                        Imie = wierszRozbity[1],
                        Nazwisko = wierszRozbity[2],
                        NazwaFirmy = wierszRozbity[3],
                        Adres = wierszRozbity[4],

                    });
                }
                return listaWyjsciowa;
            }
            catch (Exception ex)
            {
                throw new Exception(ex.Message);
            }
            
        }
    }
}

Zacznijmy od góry. Stworzyliśmy prywatne pole w którym będziemy przetrzymywali
ścieżkę do pliku csv. Dalej widzimy konstruktor klasy, który jako parametr
przyjmuje ścieżkę do pliku a string ten jest zapisywany do pola z którego skorzysta
dalej metoda odczytująca i parsująca dane.
Następnie widzimy publiczną metodę OdczytajPlik(). Metoda zwraca listę typu Employee.
Dalej tworzymy nową listę "listaWyjściowa" typu Employee do której zapiszemy nasze
dane wyjściowe. w kolejnej linii odczytujemy zawartość całego pliku, przy czym
pomijamy pierwszy wiersz, który nie jest nam do niczego już potrzebny.
Teraz uwaga. Aby było trudniej to plik tak spreparowałem aby dane były rozbite na
dwa wiersze. I teraz w pętli for jedziemy pętlą co drugi wiersz i sklejamy stringi ze sobą.
Myślę, że to w kodzie ładnie widać. Teraz nasze dane mają postać listy tablicy stringów
List<string[]>, czyli należy teraz po kolekcji przejechać się np: pętlą foreach
po kolekcji daneZPliku i wyłuskamy po kolei każdy string rozbity średnikiem.
Po działaniu metody Split() dostaniemy tablicę stringów - czyli w sumie wyjdzie ich
w każdym wierszu po 5 sztuk :). Teraz do listy wyjściowej dodajemy indeksy.
Na końcu zwracamy listę.

Teraz w głównej formie dodajemy kontrolkę DataGridView i np: możemy dodać
button.



using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;

namespace ParseCSVfile
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
        }

        private void button1_Click(object sender, EventArgs e)
        {
            ParseFile dane = new ParseFile(@"c:\Users\Documents\1.csv");
            

            dataGridView1.DataSource = dane.OdczytajPlik();
        }
    }
}
W zdarzeniu buttona tworzymy nowy obiekt typu ParseFile i podajemy ścieżkę
do pliku csv. Dalej nasz obiekt będzie posiadał metodę OdczytajPlik(), którą
dopiero co stworzyliśmy. Kontrolka DataGridView posiada własciwość DataSource
gdzie podamy nasze źródło danych.

Rezultat w gridzie.


I to by było na koniec. Powodzenia w parsowaniu plików csv.

czwartek, 8 stycznia 2015

C# - odczyt pliku XML do DataGridView

Witajcie!
Chciałbym pokazać najprostszy sposób odczytania zawartości pliku xml
do kontrolki DataGridView.
Już nie będę pokazywał jak stworzyć projekt i dodać kontrolkę :).
Przejdę od razu do kodu. Jest to dosłownie 3 linijki kodu.
Ściągnąłem sobie dla wygody gdzieś z czeluści internetu przykładowy plik
xml i jego dla przykładu odczytałem.


using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;

namespace XMLReader
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
        }

        private void Form1_Load(object sender, EventArgs e)
        {
            DataSet ds = new DataSet();
            ds.ReadXml(@"c:\VS_ProjektyTestowe\XMLReader\XMLReader\cd_catalog.xml");
            dataGridView1.DataSource = ds.Tables[0];
        }
    }
}

Jak widać nie kłamałem:)
 No i efekt w gridzie:

I to by było na tyle:)