EPPlusKażdy kto pracuje z aplikacją biznesową lubi gdy dane wyświetlone na monitorze mogą być wyeksportowane do PDF czy Excela.Ostatnio w pracy musiałem napisać taki kod wraz z obsługą kolejności kolumn i ich widoczności co było dużo trudniejsze.Do rozwiązani problemu postanowiłem użyć czego innego niż “Microsoft.ReportViewer”.

Użyłem więc biblioteki “EPPlus”. Jest to bardzo popularna biblioteka.

Posiada ona dużo opcji jeśli chodzi o manipulacje arkuszami kalkulacyjnymi Excela 2007 i wyżej. Mogę nawet umieścić kod VB.NET wewnątrz wygenerowanego pliku Excel. Biblioteka nie jest doskonała i nie ma przykładowo obsługi kasowania i kopiowania kolumn. Twórca tej biblioteki mówi, że ze względu na strukturę tworzenia obiektów reprezentujących komórki arkusza kalkulacyjnego aplikacja z taką funkcjonalnością  działała by bardzo wolno.

Utworzenie pliku Excel bez żadnych udziwnień jest bardzo łatwe. Zwłaszcza jeśli chcesz wyświetlić wszystkie właściwości, które posiada klasa w takie samej kolejności jak są one zapisane w pliku klasy.

Bibliotekę EPPlus najłatwiej zainstalować poprzez NuGet-a.

 NuGet

Utworzyłem prostą encję symbolizującą grę komputerową.

public class Game
{
    public string Name { get; set; }
    public decimal Price { get; set; }
    public int SellAmount { get; set; }
}

Utworzyłem statyczną klasę, która przy użyciu metody “ExportToExcel” wyeksportuje kolekcję nie zależnie od jej typu. Metoda ta także kasuje istniejący plik jeśli został on już utworzony oraz zmienia nazwę rozszerzenia pliku na “.xlsx” jeśli jest ona inna bądź jej nie ma.

public static class CreateExcelFile<T>
{
    public static void ExportToExcel(IEnumerable<T> employees, DirectoryInfo outputDir, string fileName)
    {
        fileName = FixFileNameExcel(fileName);

        FileInfo f = new FileInfo(outputDir.FullName + @"\" + fileName);
        DeleteFileIfExist(f);
        using (var excelFile = new ExcelPackage(f))
        {
            var worksheet = excelFile.Workbook.Worksheets.Add("Games");
            worksheet.Cells["A1"].LoadFromCollection(Collection: employees, PrintHeaders: true);
            worksheet.Cells.AutoFitColumns(0);
            excelFile.Save();
        }
    }

    public static FileInfo DeleteFileIfExist(FileInfo newFile)
    {
        if (newFile.Exists)
        {
            newFile.Delete();  // ensures we create a new workbook
            newFile = new FileInfo(newFile.FullName);
        }
        return newFile;
    }

    public static string FixFileNameExcel(string fileName)
    {
        if (Path.HasExtension(fileName))
        {
            string ext = Path.GetExtension(fileName);

            if (ext != ".xlsx")
            {
                fileName = Path.GetFileNameWithoutExtension(fileName) + ".xlsx";
            }
        }
        else
        {
            fileName += ".xlsx";
        }

        return fileName;
    }
}

Metoda w celu utworzeniu pliku wykonuje następujące czynności.

  • Tworzy obiekt “ExcelPackage”
  • Tworzy arkusz kalkulacyjny o nazwie “Games”.
  • Referuje się do pierwszej komórki w arkuszu (“A1”) i w niej wywołuje metodę “LoadFromCollection”. Wewnątrz biblioteki przy pomocy refleksji EEPlus skanuje właściwości klasy i umieszcza ich wartości w arkuszu.
  • Używając metody “AutoFitColumns” dostosowuje rozmiar kolumn do wartości jakie one przechowują.
  • Zapisuje plik Excel

public static void ExportToExcel(IEnumerable<T> employees, DirectoryInfo outputDir, string fileName)
{
    fileName = FixFileNameExcel(fileName);

    FileInfo f = new FileInfo(outputDir.FullName + @"\" + fileName);
    DeleteFileIfExist(f);
    using (var excelFile = new ExcelPackage(f))
    {
        var worksheet = excelFile.Workbook.Worksheets.Add("Games");
        worksheet.Cells["A1"].LoadFromCollection(Collection: employees, PrintHeaders: true);
        worksheet.Cells.AutoFitColumns(0);
        excelFile.Save();
    }
}

Użycie metody i klasy w aplikacji konsolowej wygląda tak.

class Program
{
    static void Main(string[] args)
    {
        DirectoryInfo outputDir = new DirectoryInfo(@"d:\Samples\EPPlus\");

        if (!outputDir.Exists)
            outputDir.Create();

        CreateExcelFile<Game>.ExportToExcel(CreateCollection(), outputDir, "Games");

        Console.WriteLine("File Created");
        Console.ReadKey();

    }

    public static List<Game> CreateCollection()
    {
        List<Game> list = new List<Game>();

        list.Add(new Game() { Name = "Mortal Kombat",Price = 120,SellAmount=120853});
        list.Add(new Game() { Name = "Asura Wrath", Price = 90, SellAmount = 90045 });
        list.Add(new Game() { Name = "X-COM", Price = 210, SellAmount = 117651 });
        list.Add(new Game() { Name = "DMC", Price = 210, SellAmount = 81123 });

        return list;
    }
}

Tyle jeśli chodzi o prosty przykład. Sprawa oczywiście trochę się komplikuje gdy chcemy stworzyć plik Excel z określonymi wytycznymi.