CsvHelper – praca z plikami csv

Wprowadzenie

Tworząc aplikację, wcześniej czy później będziemy musieli zaimportować lub wyeksportować jakieś dane. Jednym z formatów, który prawdopodobnie będziemy musieli obsłużyć, będzie plik csv. Można taki import lub eksport zrobić ręcznie, korzystając z takich metod klasy string, jak Join lub Split. Z drugiej strony możemy skorzystać z czegoś gotowego. W swoich projektach, gdy mam pracować z plikami csv, wykorzystuję bibliotekę CsvHelper (https://joshclose.github.io/CsvHelper/), którą chcę Ci pokazać w tym wpisie.

Eksport list produktów

Przygotowałem dwie klasy, które będziemy chcieli wyeksportować do pliku csv i później zaimportować z powrotem do aplikacji. Pierwszą klasą będzie Product, która zawiera w sobie właściwość typu Category:

W testowej aplikacji skorzystałem z biblioteki Bogus, aby wygenerować 5 testowych kategorii oraz 10 produktów:

W wynikowym pliku będziemy chcieli zapisać cztery kolumny: ID produktu, nazwa produktu, ID kategorii oraz nazwę kategorii. Zobaczmy, jak można to zrobić z wykorzystaniem CsvHelper.

Po zainstalowaniu pakietu CsvHelper (https://www.nuget.org/packages/CsvHelper/) możemy skorzystać z klasy CsvWritter, którą budujemy na ogół na podstawie jakiejś klasy dziedziczącej po TextWriter. W przykładzie użyjemy klasy StreamWriter, która zapisze dane do pliku. CsvWriter zawiera szereg metod, które możemy wykorzystać i które zapisują pojedyncze obiekty lub całe ich kolekcje:

Metoda WriteRecords zapisuje kolekcje przekazanych obiektów, czyli to, czego potrzebujemy w naszym przykładzie.

W wyniku działania powyższej metody w pliku products.csv pojawi się coś takiego (oczywiście z racji użycia biblioteki Bogus dane są losowe podczas każdego uruchomienia testowej aplikacji):

Jak widać, wygenerowane dane w tym momencie są dalekie od tego, czego potrzebujemy. Dzieje się tak głównie przez to, że próbujemy wygenerować plik csv dla dwóch powiązanych klas. W takiej sytuacji biblioteka zapisuje w pliku wszystkie właściwości z obu klas pod ich nazwami (bez żadnych przedrostków), w związku z czym dostaliśmy kolumny o takich samych nazwach, ale innym znaczeniu i wartościach.

W przypadku gdybyśmy generowali plik dla płaskiego obiektu, takiego problemu by nie było. Ale z drugiej strony ta sytuacja pozwoli mi pokazać dodatkowe możliwości CsvHelper. 🙂

Konfigurowanie eksportu oraz importu

W CsvHelper możemy konfigurować działanie biblioteki. W takiej sytuacji jak nasza, możemy przekazać informacje dotyczące tego, w jaki sposób należy wygenerować plik z danymi. Robi się to poprzez dodanie klasy mapowań, w której definiujemy to, w jaki sposób należy wyeksportować lub zaimportować dane dla konkretnego typu.

Klasa mapowań w przykładzie wygląda tak:

Dziedziczy ona po klasie ClassMap z biblioteki. Jest generyczna i jako parametru oczekuje typu, dla którego będziemy konfigurować mapowanie (w przykładzie dla klasy Product). Następnie w konstruktorze klasy definiujemy mapowania.

Metoda AutoMap służy do dodania domyślnej logiki mapowań. W przypadku gdy korzystamy z klas mapowań, musimy określić wszystkie właściwości, które mają zostać wyeksportowane. Na ogół robi się tak, że na początku importujemy domyślne mapowania za pomocą metody AutoMap i później te mapowania zmieniamy.

Użycie metody AutoMap może być istotne w sytuacji, gdy chcemy, aby po dodaniu nowej właściwości do klasy Product również sama ta klasa została wyeksportowana. Gdybyśmy nie skorzystali z metody AutoMap, wtedy ręcznie musielibyśmy dodać mapowanie dla tej nowej właściwości.

Z drugiej strony nie skorzystamy z metody AutoMap, gdy chcemy zawsze mieć te same skonfigurowane właściwości, bez nowo dodanych do klasy.

Za pomocą metody Map definiujemy reguły mapowania dla właściwości przekazanej w formie wyrażenia lambda. W przykładzie użyłem dwóch metod:

  • Name – określa nazwę kolumny w pliku – tutaj zmieniłem nazwę dla właściwości z danymi kategorii
  • Ignore – służy do ignorowania właściwości podczas eksportu oraz importu – w przykładzie ignorujemy właściwość IsActive.

Biblioteka udostępnia jeszcze kilka innych metod, których możemy użyć podczas definiowania mapowań.

Po dodaniu klasy mapowań trzeba jeszcze przekazać ją do writera, aby wykorzystał ją podczas eksportu danych. Robi się to za pomocą metody RegisterClassMap przed zapisaniem danych do pliku:

Darmowy kurs Visual Studio

Pracując z setkami programistów, zauważyłem, że większość osób nie pracuje efektywnie w Visual Studio. W skrajnych przypadkach korzystali z kopiowania z wykorzystaniem menu Edit. Wiem, że to dziwne, ale naprawdę niektórzy tak pracują. Dlatego postanowiłem stworzyć kurs Visual Studio – aby pomóc koleżankom i kolegom w efektywniejszej pracy.

Przygotowałem 20 lekcji e-mail, w których pokażę Ci, w jaki sposób pracować efektywniej i szybciej w Visual Studio. Poznasz dodatki, bez których nie wyobrażam sobie pracy w tym IDE.

Po więcej informacji zapraszam na dedykowaną stronę kursu: Darmowy Kurs Visual Studio.

Quiz C#

Ostatnio przygotowałem również quiz C#, w którym możesz sprawdzić swoją wiedzę. Podejmiesz wyzwanie?

Import produktów

Import danych z pliku za pomocą biblioteki CsvHelper jest równie łatwy, jak eksport danych. Proces importu jest bardzo podobny, tylko zamiast klas writer korzystamy z klas reader. Najlepiej od razu zobaczyć, jak wygląda kod importu:

W pierwszej kolejności tworzymy instancję klasy StreamReader, która odczytuje dane z pliku. Następnie CsvReader, który sparsuje dane z pliku do obiektów. Również tutaj możemy korzystać z klas mapowań, tak jak to było przy eksporcie. W tym przypadku import wczyta te same dane, które zostały wcześniej wyeksportowane.

Przykład

Na githubie (https://github.com/danielplawgo/CsvHelperTest) znajduje się przykład do tego wpisu. Jest to prosta aplikacja konsolowa, która po wygenerowaniu danych zapisuje je do pliku csv. Następnie je odczytuje i wyświetla na konsoli.

Podsumowanie

CsvHelper bardzo ułatwia importowanie oraz eksportowanie danych w formacie csv. W dosłownie kliku linijkach kodu możemy obsłużyć kod za to odpowiedzialny. Możliwość konfigurowania sposobu pracy biblioteki powoduje, że w tym momencie jest to mój numer 1, gdy muszę pracować z plikami csv.

A jak Ty sobie z tym radzisz?

1 thought on “CsvHelper – praca z plikami csv

Dodaj komentarz

Twój adres email nie zostanie opublikowany. Pola, których wypełnienie jest wymagane, są oznaczone symbolem *