This is a migrated thread and some comments may be shown as answers.

Multiple Grid Export to Excel

4 Answers 373 Views
Grid
This is a migrated thread and some comments may be shown as answers.
Brian
Top achievements
Rank 1
Brian asked on 05 Jan 2017, 11:09 PM

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>

4 Answers, 1 is accepted

Sort by
0
Brian
Top achievements
Rank 1
answered on 06 Jan 2017, 10:26 PM
Is this too complex to solve? ;-)
0
Dimiter Topalov
Telerik team
answered on 09 Jan 2017, 08:27 AM
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.
0
Brian
Top achievements
Rank 1
answered on 10 Jan 2017, 12:02 AM
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.
0
Dimiter Topalov
Telerik team
answered on 11 Jan 2017, 04:24 PM
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.
Tags
Grid
Asked by
Brian
Top achievements
Rank 1
Answers by
Brian
Top achievements
Rank 1
Dimiter Topalov
Telerik team
Share this question
or