Multiple Grid Export to Excel

5 posts, 0 answers
  1. Brian
    Brian avatar
    7 posts
    Member since:
    Sep 2012

    Posted 05 Jan Link to this post

    I have an MVC view of 3 Kendo UI Grids, along with an Export to Excel button to export the data from the 3 grids to 3 Excel worksheets.

    The following is a sample of the page script (with column detail removed for simplicity).

    When I execute the Export button, I get a Javascript error "Unable to get property 'saveAsExcel' of undefined or null reference" at the line identified below with //##errorLine##. So for some reason the grid references can not be determined.

    What am I missing here?

    <script type="text/javascript">
        // used to sync the grid exports
        var promises = [
          $.Deferred(),
          $.Deferred(),
          $.Deferred()
        ];
    </script>
    <div style="text-align:center;">
        @(Html.Kendo().Grid(Model)
            .Name("HccWp")
            .Columns(columns =>
            {
    ...
            })
            .ClientDetailTemplateId("outOfBalanceDetailTemplate")
            .Sortable(sortable => sortable.SortMode(GridSortMode.SingleColumn).AllowUnsort(true))
            .Resizable(resizable => resizable.Columns(true))
            .AutoBind(true)
            .Events(e => e
                .DataBound(@<text>function(e) {onDataBound(e, "HccWp")}</text>)
                .ExcelExport(@<text>function(e) {e.preventDefault(); promises[0].resolve(e.workbook);}</text>)
            )
            .DataSource(dataSource => dataSource
                .Ajax()
                .Model(model =>
                {
                    ...
                })
            )
    )
    </div>
    <div style="text-align:center;">
        @(Html.Kendo().Grid(Model)
            .Name("HccPr")
            .Columns(columns =>
            {
                ...
            })
            .ClientDetailTemplateId("outOfBalanceDetailTemplate")
            .Sortable(sortable => sortable.SortMode(GridSortMode.SingleColumn).AllowUnsort(true))
            .Resizable(resizable => resizable.Columns(true))
            .AutoBind(true)
            .Events(e => e
                .DataBound(@<text>function(e) {onDataBound(e, "HccPr")}</text>)
                .ExcelExport(@<text>function(e) {e.preventDefault(); promises[1].resolve(e.workbook);}</text>)
            )
            .DataSource(dataSource => dataSource
                .Ajax()
                .Model(model =>
                {
                    ...
                })
            )
    )
    </div>
    <div style="text-align:center;">
        @(Html.Kendo().Grid(Model)
            .Name("PointWp")
            .Columns(columns =>
            {
                ...
            })
            .ClientDetailTemplateId("outOfBalanceDetailTemplate")
            .Sortable(sortable => sortable.SortMode(GridSortMode.SingleColumn).AllowUnsort(true))
            .Resizable(resizable => resizable.Columns(true))
            .AutoBind(true)
            .Events(e => e
                .DataBound(@<text>function(e) {onDataBound(e, "PointWp")}</text>)
                .ExcelExport(@<text>function(e) {e.preventDefault(); promises[2].resolve(e.workbook);}</text>)
            )
            .DataSource(dataSource => dataSource
                .Ajax()
                //.PageSize(20)
                .Model(model =>
                {
                    ...
                })
            )
    )
    </div>
    <br />
    <div>
        <button id="export" class="k-button"><span class="k-icon k-i-excel"></span>&nbsp;Export to Excel</button>
    </div>

    <script type="text/javascript">
      $("#export").click(function(e){
        // trigger export of the HccWp grid
        $("#HccWP").data("kendoGrid").saveAsExcel();  //##errorLine##
        // trigger export of the HccPr grid
        $("#HccPR").data("kendoGrid").saveAsExcel();
        // trigger export of the PointWp grid
        $("#PointWP").data("kendoGrid").saveAsExcel();
        // wait for all exports to finish
        $.when.apply(null, promises)
         .then(function (hccWpWorkbook, hccPrWorkbook, pointWpWorkbook) {

          // create a new workbook using the sheets of the 3 workbooks
          var sheets = [
            hccWpWorkbook.sheets[0],
            hccPrWorkbook.sheets[0],
            pointWpWorkbook.sheets[0]
          ];

          sheets[0].title = "HccWP";
          sheets[1].title = "HccPR";
          sheets[2].title = "PointWP";

          var workbook = new kendo.ooxml.Workbook({
            sheets: sheets
          });

          // save the new workbook
          kendo.saveAs({
            dataURI: workbook.toDataURL(),
            fileName: "BCBalancing.xlsx"
          })
        });
      });
    </script>

  2. Brian
    Brian avatar
    7 posts
    Member since:
    Sep 2012

    Posted 06 Jan Link to this post

    Is this too complex to solve? ;-)
  3. Dimiter Topalov
    Admin
    Dimiter Topalov avatar
    481 posts

    Posted 09 Jan Link to this post

    Hi Brian,

    The described reference error seems to be caused by the fact that the Grid instance is not yet created when the following line of client-side JavaScript is executed:

    $("#HccWP").data("kendoGrid").saveAsExcel();  //##errorLine##

    Wrapping the client-side JavaScript code in a $(document).ready() function should resolve the discussed issue.

    If I am missing something, or the problem persists, do not hesitate to contact us again.

    Regards,
    Dimiter Topalov
    Telerik by Progress
    Try our brand new, jQuery-free Angular 2 components built from ground-up which deliver the business app essential building blocks - a grid component, data visualization (charts) and form elements.
  4. Brian
    Brian avatar
    7 posts
    Member since:
    Sep 2012

    Posted 09 Jan in reply to Dimiter Topalov Link to this post

    Thanks for the reply. I tried that, but still get the same results. The page is fully rendered and the JavaScript code is executed by the press of the Export button. So, I don't know why the Grid instance would be null at that point.
  5. Dimiter Topalov
    Admin
    Dimiter Topalov avatar
    481 posts

    Posted 11 Jan Link to this post

    Hello Brian,

    I tried to reproduce the described issue, but the Grid reference was retrieved as expected on my end (based on this demo):

    <script src="//cdnjs.cloudflare.com/ajax/libs/jszip/2.4.0/jszip.min.js"></script>
     
    @(Html.Kendo().Grid<Kendo.Mvc.Examples.Models.ProductViewModel>()
        .Name("grid")
        .Columns(columns => {
             columns.Bound(p => p.ProductName).Width(300)
                    .ClientFooterTemplate("Total Count: #=count#")
                    .ClientGroupFooterTemplate("Count: #=count#");
             columns.Bound(p => p.UnitPrice).Width(300);
             columns.Bound(p => p.UnitsOnOrder).Width(300)
                    .ClientFooterTemplate("Average: #=average#")
                    .ClientGroupFooterTemplate("Average: #=average#");
             columns.Bound(p => p.UnitsInStock).Width(300)
                    .ClientFooterTemplate("Min: #= min # Max: #= max #")
                    .ClientGroupHeaderTemplate("Units In Stock: #= value # (Count: #= count#)");
         })
        .ToolBar(tools => tools.Excel())
        .Pageable()
        .Sortable()
        .Groupable()
        .Excel(excel => excel
            .FileName("Kendo UI Grid Export.xlsx")
            .Filterable(true)
            .ProxyURL(Url.Action("Excel_Export_Save", "Grid"))
        )
        .Reorderable(r => r.Columns(true))
        .Resizable(r => r.Columns(true))
        .ColumnMenu()
        .DataSource(dataSource => dataSource
            .Ajax()
            .PageSize(7)
            .Group(g => g.Add(p => p.UnitsInStock))
            .Aggregates(aggregates =>
            {
                aggregates.Add(p => p.UnitsInStock).Min().Max().Count();
                aggregates.Add(p => p.UnitsOnOrder).Average();
                aggregates.Add(p => p.ProductName).Count();
                aggregates.Add(p => p.UnitPrice).Sum();
            })
            .Read(read => read.Action("Excel_Export_Read", "Grid"))
        )
    )
     
    <br />
    <div>
        <button id="export" class="k-button"><span class="k-icon k-i-excel"></span> Export to Excel</button>
    </div>
     
    <script type="text/javascript">
      $("#export").click(function(e){
        $("#grid").data("kendoGrid").saveAsExcel();  //##errorLine##
      });
    </script>

    Can you please send us an isolated runnable project, where the described problem can be observed, so we can inspect it further, and try to determine what might be causing it? Thank you in advance.

    Regards,
    Dimiter Topalov
    Telerik by Progress
    Try our brand new, jQuery-free Angular 2 components built from ground-up which deliver the business app essential building blocks - a grid component, data visualization (charts) and form elements.
Back to Top