Thursday, November 1, 2012

Exporting to Excel with Microsoft.Dynamics.AX.Fim.Spreadsheets.* classes

While looking for a way to export to Excel in batch, I investigated what they do in financial statements (LedgerBalanceSheetDimPrintExcelEngine class).

Pros:
  • It is possible to use these .NET components in batch on the server side
  • Execution is way faster than that of the SysExcel* classes

Cons:
  • It looks like it is not possible to create more columns than there are letters in the English alphabet
  • Less flexible comparing to standard SysExcel classes, so manual formatting will likely be needed in the end. 
static void AnotherWayToExportToExcel(Args _args)
{
    #define.ReadWritePermission('RW')
    #define.FileName('c:\myFile.xlsx')
    #define.ExcelColumnWidth(15)
    #define.ExcelCellFontSize("Microsoft.Dynamics.AX.Fim.Spreadsheets.CellFontSize")
    #define.Size9("Size9")    
 
    CustTable custTable;
 
    Microsoft.Dynamics.AX.Fim.Spreadsheets.Spreadsheet spreadsheet;
    Microsoft.Dynamics.AX.Fim.Spreadsheets.CellProperties cellProperties;    
    Microsoft.Dynamics.AX.Fim.Spreadsheets.ColumnProperties columnProperties;    
 
    void addColumn(str _name)
    {
        columnProperties = new Microsoft.Dynamics.AX.Fim.Spreadsheets.ColumnProperties();
        columnProperties.set_Width(#ExcelColumnWidth);
        spreadSheet.InstantiateColumn(columnProperties);
 
        cellProperties = new Microsoft.Dynamics.AX.Fim.Spreadsheets.CellProperties();
        cellProperties.set_FontSize(CLRInterop::parseClrEnum(#ExcelCellFontSize, #Size9));
        cellProperties.set_Bold(true);
 
        spreadSheet.AddStringCellToWorkbook(_name, cellProperties);
    }    
 
    new FileIOPermission(#FileName, #ReadWritePermission).assert();
 
    spreadSheet = new Microsoft.Dynamics.AX.Fim.Spreadsheets.Spreadsheet();
 
    if (!spreadSheet.CreateSpreadsheet(#FileName))
    {
        throw error(strFmt("@SYS72245", #FileName));
    }
 
    addColumn("Customer name");
    addColumn("Balance");    
 
    while select custTable
    {
        spreadSheet.MoveToNextRowInWorkbook();        
 
        cellProperties = new Microsoft.Dynamics.AX.Fim.Spreadsheets.CellProperties();
        cellProperties.set_FontSize(CLRInterop::parseClrEnum(#ExcelCellFontSize, #Size9));        
 
        spreadSheet.AddStringCellToWorkbook(custTable.name(), cellProperties);            
        spreadSheet.AddNumberCellToWorkbook(real2double(custTable.openBalanceCur()), cellProperties);                    
    }
 
    spreadSheet.WriteFile();
    spreadSheet.Dispose();
 
    CodeAccessPermission::revertAssert();    
}

Output:

7 comments:

  1. Hello, when I try this the columns were hidden, how can I solve this?
    Another thing, how can I open xlsx in Normal mode? (It's start in Page layout).

    Thanks a lot!

    ReplyDelete
  2. Did you solve how to create the spreadsheet so that it opens in Normal mode not "Page Layou"

    ReplyDelete
    Replies
    1. No, I didn't try to solve that, because there was no need.

      Delete
  3. .When I try to do i am getting error when i tried to run in batch.

    . System. NullReferenceException: Object reference not set to an instance of an object. at Dynamics. Ax.Application.

    error line "spreadSheet.InstantiateColumn(columnProperties);".help me out to go ahead with my process.

    ReplyDelete
    Replies
    1. Do you use exactly the same piece of logic as in the example, or you wrote your own code? It looks like either spreadSheet or columnProperties object is null, and you need to check which one of them is null. You can add some if-statements to your logic that would verify that all objects are instantiated properly.

      Delete
  4. Hi,
    My filepath is wrong that's y i got an error.Your code is perfect and i am facing one more issue.In the excel sheet ,when i tried to write something i am getting a msg,'the cell or chart you are trying to change is on a protected sheet".How to unprotect my sheet.

    ReplyDelete
    Replies
    1. Hi, sorry, I have never seen this message before. The original post is 6 year old, and something might have changed in Excel since then. Maybe you can workaround this by creating the file beforehand (instead of creating it with X++), and make sure the sheet is unprotected. Sorry, not sure what to do here. By this message is mentioned many times in Google.

      Delete