czwartek, 27 września 2012

Odczyt danych z pliku Excel

Oto moja autorska metoda odczytu danych z pliku excel, umożliwia ona :
  • odczyt z pliku xlsx bez konieczności posiadania zainstalowanego porgramu Microsoft Excel
  • jest nieporównywalnie szybsza i wygodniejsza od innych znanych mi metod (a prawdopodobnie znam je wszystkie)
  • obsługuje duże pliki xlsx (mechanizmy oparte na połączeniach COM mają z tym problem)

Potrzebna jest biblioteka EPPlus która w swojej standardowej postaci znajduje się pod adresem http://epplus.codeplex.com. Aby użyć tej biblioteki w połączeniu z Dynamics AX 2009 wymagała ona pewnych zmian (standardowa biblioteka używa pewnych składni języka C# z którą DAX sobie nie radzi).

Poprawiona przeze mnie wersja biblioteki znajduje się pod adresem AX_EPPlus.zip (kod źródłowy zostanie opublikowany niedługo).


Przykład użycia :
Bibliotekę dodajemy do referencji w Dynamics AX 2009 (po stronie klienta).

  
static void SBR_ReadFromExcelFile(Args _args)
{
    OfficeOpenXml.ExcelPackage      package;
    OfficeOpenXml.ExcelWorkbook     workBook;
    OfficeOpenXml.ExcelWorksheets   workSheets;
    OfficeOpenXml.ExcelWorksheet    workSheet;
    System.IO.FileInfo              file;
    CLRObject                       clrException;
    int                             i;
    CustAccount                     custAccount;
    Amount                          amount;
    ;
    try {
        file = new  System.IO.FileInfo("c:\\temp\\a.xlsx");
        package = new OfficeOpenXml.ExcelPackage(file);

        workBook    = package.get_Workbook();
        workSheets  = workBook.get_Worksheets();
        // read from first sheet
        workSheet   = workSheets.get_Item(1);

        i = 1;
        while(!CLRInterop::isNull(worksheet.AxGetValue(i,1)))
        {
            custAccount = worksheet.AxGetValue(i,1);

            // if cell is empty NULL value will be returned
            if (!CLRInterop::isNull(worksheet.AxGetValue(i,2)))
            {
                // read value from excel file
                amount = worksheet.AxGetValue(i,2);
            } else {
                // set default value for empty cell
                amount = 0;
            }

            print custAccount, '  ', amount;

            i++;
        }
        Box::info(strFmt('Done. %1 rows readed.');
    }
    catch( Exception::CLRError )
    {
        clrException    =   CLRInterop::getLastException();
        if( clrException )
        {
            info( CLRInterop::getAnyTypeForObject( clrException.get_Message() ) );
        }
    }
    catch( Exception::Internal )
    {
        clrException    =   CLRInterop::getLastException();
        if( clrException )
        {
            info( CLRInterop::getAnyTypeForObject( clrException.get_Message() ) );
        }
    }
}