Can't get export datagrid to csv

6592
12
Jump to solution
02-26-2015 10:30 AM
MayJeff
Occasional Contributor

I read different threads here for export datagrid to csv.

http://www.javaexperience.com/dojo-export-data-from-grid/

http://livedocs.dojotoolkit.org/dojox/grid/EnhancedGrid/plugins/Exporter

Here is my modified JSfiddle: Edit fiddle - JSFiddle

I think the url setting got problem therefore can't get it to export to csv.  I also created a file called ExportGrid.html.  Can someone help me take a look.  I put files here: C:\inetpub\wwwroot\Exportdata\index.html or C:\inetpub\wwwroot\Exportdata]ExportGrid.html

Thank you.

0 Kudos
1 Solution

Accepted Solutions
RobertScheitlin__GISP
MVP Emeritus

May Jeff,

  OK, I found the issue and have switched to dojo/request/iframe as dojo/io/iframe is depreciated. I am also attaching a updated ashx file that now uses POST instead of GET as eventually you would have run into an issue with the amount of rows you were converting. I have tested this and you can download the .csv as many time as you want.

<!DOCTYPE html>
<html>

<head>
  <meta http-equiv="Content-Type" content="text/html; charset=utf-8">
  <!--The viewport meta tag is used to improve the presentation and behavior of the samples
      on iOS devices-->
  <meta name="viewport" content="initial-scale=1, maximum-scale=1,user-scalable=no">
  <title>Export the DataGrid to CSV / Print </title>

  <link rel="stylesheet" href="http://js.arcgis.com/3.10/js/dojo/dijit/themes/claro/claro.css">
  <link rel="stylesheet" href="http://js.arcgis.com/3.10/js/dojo/dojox/grid/resources/Grid.css">
  <link rel="stylesheet" href="http://js.arcgis.com/3.10/js/dojo/dojox/grid/resources/claroGrid.css">
  <link rel="stylesheet" href="http://js.arcgis.com/3.10/js/esri/css/esri.css">
  <style>
    html,
    body {
      height: 100%;
      width: 100%;
      margin: 0;
      padding: 0;
    }
  </style>
  <script src="http://js.arcgis.com/3.10/"></script>
  <script>
    require([
        "esri/map",
        "esri/tasks/FindTask",
        "esri/tasks/FindParameters",
        "esri/symbols/SimpleMarkerSymbol",
        "esri/symbols/SimpleLineSymbol",
        "esri/symbols/SimpleFillSymbol",
        "dojo/request/iframe",
        "esri/Color",
        "dojo/on",
        "dojo/dom",
        "dijit/registry",
        "dojo/_base/array",
        "dojo/_base/connect",
        "dojox/grid/DataGrid",
        "dojo/data/ItemFileReadStore",
        "dijit/form/Button",
        "dojo/parser",
        "dojo/store/Memory",
        "dojo/data/ItemFileWriteStore",
        "dgrid/OnDemandGrid",
        "dojox/grid/EnhancedGrid",
        "dojox/grid/enhanced/plugins/exporter/CSVWriter",
        "dojox/grid/enhanced/plugins/Printer",
        "dgrid/Selection",
        "dojo/_base/declare",
        "dijit/layout/BorderContainer",
        "dijit/layout/ContentPane",
        "dojo/domReady!"
      ], function (
        Map, FindTask, FindParameters, SimpleMarkerSymbol, SimpleLineSymbol, SimpleFillSymbol, iframe,
        Color, on, dom, registry, arrayUtils, connect, DataGrid, ItemFileReadStore, Button, parser, Memory,
        ItemFileWriteStore, Grid, EnhancedGrid, CSVWriter, Printer, Selection, declare, BorderContainer, ContentPane

    ) {
      var findTask, findParams;
      var map, center, zoom;
      var grid, store, dfd;

      parser.parse();

      registry.byId("search").on("click", doFind);
      registry.byId("clear").on("click", clear);

      center = [-83.266, 42.568];
      zoom = 11;
      map = new esri.Map("map", {
        basemap: "streets",
        center: center,
        zoom: zoom
      });

      //Create Find Task using the URL of the map service to search
      findTask = new FindTask("http://sampleserver1.arcgisonline.com/ArcGIS/rest/services/TaxParcel/TaxParcelQuery/MapServer/");

      map.on("load", function () {
        //Create the find parameters
        findParams = new FindParameters();
        findParams.returnGeometry = true;
        findParams.layerIds = [0];
        findParams.searchFields = ["OWNERNME1", "OWNERNME2"];
        findParams.outSpatialReference = map.spatialReference;
        console.log("find sr: ", findParams.outSpatialReference);
      });

      function doFind() {
        //Set the search text to the value in the box
        findParams.searchText = dom.byId("ownerName").value;
        findTask.execute(findParams, showResults);
      }

      function showResults(results) {
        //This function works with an array of FindResult that the task returns
        map.graphics.clear();
        var symbol = new SimpleFillSymbol(
          SimpleFillSymbol.STYLE_SOLID,
          new SimpleLineSymbol(SimpleLineSymbol.STYLE_SOLID, new Color([98, 194, 204]), 2),
          new Color([98, 194, 204, 0.5])
        );

        //create array of attributes
        var items = arrayUtils.map(results, function (result) {
          var graphic = result.feature;
          graphic.setSymbol(symbol);
          map.graphics.add(graphic);
          return result.feature.attributes;
        });

        //Create data object to be used in store
        var data = {
          identifier: "PARCELID", //This field needs to have unique values
          label: "PARCELID", //Name field for display. Not pertinent to a grid but may be used elsewhere.
          items: items
        };

        //Create data store and bind to grid.
        store = new ItemFileReadStore({
          data: data
        });
        grid = registry.byId("grid");
        grid.setStore(store);
        grid.on("rowclick", onRowClickHandler);

        //Zoom back to the initial map extent
        map.centerAndZoom(center, zoom);
      }

      //Zoom to the parcel when the user clicks a row
      function onRowClickHandler(evt) {
        var clickedTaxLotId = evt.grid.getItem(evt.rowIndex).PARCELID;
        var selectedTaxLot = arrayUtils.filter(map.graphics.graphics, function (graphic) {
          return ((graphic.attributes) && graphic.attributes.PARCELID === clickedTaxLotId);
        });
        if (selectedTaxLot.length) {
          map.setExtent(selectedTaxLot[0].geometry.getExtent(), true);
        }
      }

      on(dojo.byId("exportAll"), "click", function () {
        var fileName = dom.byId("ownerName").value.replace(' ', '_');
        grid.exportGrid("csv", function (str) {
          if(dfd){
            dfd.cancel();
          }
          dfd = iframe.post("/HttpHandlers/CSVHandler.ashx", {
            preventCache: true,
            data: {data: str},
            query: {filename: fileName + '.csv'}
          });
        });
      });

      //dojo Methods
      on(dojo.byId("printAll"), "click", function () {
        grid.printGrid({
          title: "Print Grid",
          cssFiles: []
        });
      });

      function clear() {
        var newStore = new dojo.data.ItemFileReadStore({
          data: {
            identifier: "",
            items: []
          }
        });
        var grid = dijit.byId("grid");
        grid.setStore(newStore);
      }

    });
  </script>
</head>

<body class="claro">
  <div data-dojo-type="dijit/layout/BorderContainer" data-dojo-props="design:'headline'" style="width:100%;height:100%;margin:0;">
    <div data-dojo-type="dijit/layout/ContentPane" data-dojo-props="region:'top'" style="height:30px;">
      Owner name:
      <input type="text" id="ownerName" size="60" value="Katz" />
      <button id="search" data-dojo-type="dijit/form/Button" type="button">Search</button>
      <button id="clear" data-dojo-type="dijit/form/Button" type="button">Clear</button>
      <button id="exportAll" data-dojo-type="dijit/form/Button" type="button">Export all to CSV</button>
      <button id="printAll" data-dojo-type="dijit/form/Button" type="button">Print All</button>
    </div>
    <div id="map" data-dojo-props="region:'center'" data-dojo-type="dijit/layout/ContentPane" style="border:1px solid #000;"></div>
    <div data-dojo-type="dijit/layout/ContentPane" data-dojo-props="region:'bottom'" style="height:150px;">
      <table data-dojo-type="dojox/grid/EnhancedGrid" data-dojo-id="grid" id="grid" data-dojo-props="rowsPerPage:'5', rowSelector:'20px', plugins:{printer: true, exporter: true}">
        <thead>
          <tr>
            <th field="PARCELID">Parcel ID</th>
            <th field="OWNERNME1">Owner 1</th>
            <th field="OWNERNME2">Owner 2</th>
            <th field="RESYRBLT ">Year Built</th>
            <th field="SITEADDRESS" width="100%">Address</th>
          </tr>
        </thead>
      </table>
    </div>
  </div>
</body>
</html>

View solution in original post

12 Replies
MayJeff
Occasional Contributor

I updated the jsfiddle: Edit fiddle - JSFiddle

I only able to export the file first time if I save a file "ExportGrid.cvs" under Exportdata folder before perform the search.

Can someone give me some ideas how to export to csv?

Thanks for your time.

0 Kudos
RobertScheitlin__GISP
MVP Emeritus

May Jeff,

  The first thing you should always do is check that your requires and your variable list right after the requires match. You have several require/variables out of order (which is very common for you...). If you can grasp this basic AMD programming concept then your life will be much easier.

The link you posted are good starts to exporting your grid to a CSV but you don't seem to be fully reading these links. in your code you are using the concept in the first link to use an iframe to send the csv data to but did you understand that the author is using a a Java servlet to allow the creation of the csv file on the server and then that is being sent to the iframe?

“/ExportGrid” is the URL which is a servlet handling the file download

I also see an issue where you have the printer plugin enabled in the Enhanced grid but not the exporter.

plugins:{printer: true, exporter: true}

Here is your latest fiddle with my corrections. But until you create some server side code for actually generating a true csv file and then returning it to the client to download all you are going to get is an alert and textarea with the csv string like you have in your code currently.

<!DOCTYPE html>
<html>

<head>
  <meta http-equiv="Content-Type" content="text/html; charset=utf-8">
  <!--The viewport meta tag is used to improve the presentation and behavior of the samples
      on iOS devices-->
  <meta name="viewport" content="initial-scale=1, maximum-scale=1,user-scalable=no">
  <title>Export the DataGrid to CSV / Print </title>

  <link rel="stylesheet" href="http://js.arcgis.com/3.10/js/dojo/dijit/themes/claro/claro.css">
  <link rel="stylesheet" href="http://js.arcgis.com/3.10/js/dojo/dojox/grid/resources/Grid.css">
  <link rel="stylesheet" href="http://js.arcgis.com/3.10/js/dojo/dojox/grid/resources/claroGrid.css">
  <link rel="stylesheet" href="http://js.arcgis.com/3.10/js/esri/css/esri.css">
  <style>
    html,
    body {
      height: 100%;
      width: 100%;
      margin: 0;
      padding: 0;
    }
  </style>
  <script src="http://js.arcgis.com/3.10/"></script>
  <script>
    require([
        "esri/map",
        "esri/tasks/FindTask",
        "esri/tasks/FindParameters",
        "esri/symbols/SimpleMarkerSymbol",
        "esri/symbols/SimpleLineSymbol",
        "esri/symbols/SimpleFillSymbol",
        "dojo/io/iframe",
        "esri/Color",
        "dojo/on",
        "dojo/dom",
        "dijit/registry",
        "dojo/_base/array",
        "dojo/_base/connect",
        "dojox/grid/DataGrid",
        "dojo/data/ItemFileReadStore",
        "dijit/form/Button",
        "dojo/parser",
        "dojo/store/Memory",
        "dojo/data/ItemFileWriteStore",
        "dgrid/OnDemandGrid",
        "dojox/grid/EnhancedGrid",
        "dojox/grid/enhanced/plugins/exporter/CSVWriter",
        "dojox/grid/enhanced/plugins/Printer",
        "dgrid/Selection",
        "dojo/_base/declare",
        "dijit/layout/BorderContainer",
        "dijit/layout/ContentPane",
        "dojo/domReady!"
      ], function (
        Map, FindTask, FindParameters, SimpleMarkerSymbol, SimpleLineSymbol, SimpleFillSymbol, ioIframe,
        Color, on, dom, registry, arrayUtils, connect, DataGrid, ItemFileReadStore, Button, parser, Memory,
        ItemFileWriteStore, Grid, EnhancedGrid, CSVWriter, Printer, Selection, declare, BorderContainer, ContentPane

    ) {
      var findTask, findParams;
      var map, center, zoom;
      var grid, store;

      parser.parse();

      registry.byId("search").on("click", doFind);

      center = [-83.266, 42.568];
      zoom = 11;
      map = new esri.Map("map", {
        basemap: "streets",
        center: center,
        zoom: zoom
      });

      //Create Find Task using the URL of the map service to search
      findTask = new FindTask("http://sampleserver1.arcgisonline.com/ArcGIS/rest/services/TaxParcel/TaxParcelQuery/MapServer/");

      map.on("load", function () {
        //Create the find parameters
        findParams = new FindParameters();
        findParams.returnGeometry = true;
        findParams.layerIds = [0];
        findParams.searchFields = ["OWNERNME1", "OWNERNME2"];
        findParams.outSpatialReference = map.spatialReference;
        console.log("find sr: ", findParams.outSpatialReference);
      });

      function doFind() {
        //Set the search text to the value in the box
        findParams.searchText = dom.byId("ownerName").value;
        findTask.execute(findParams, showResults);
      }

      function showResults(results) {
        //This function works with an array of FindResult that the task returns
        map.graphics.clear();
        var symbol = new SimpleFillSymbol(
          SimpleFillSymbol.STYLE_SOLID,
          new SimpleLineSymbol(SimpleLineSymbol.STYLE_SOLID, new Color([98, 194, 204]), 2),
          new Color([98, 194, 204, 0.5])
        );

        //create array of attributes
        var items = arrayUtils.map(results, function (result) {
          var graphic = result.feature;
          graphic.setSymbol(symbol);
          map.graphics.add(graphic);
          return result.feature.attributes;
        });

        //Create data object to be used in store
        var data = {
          identifier: "PARCELID", //This field needs to have unique values
          label: "PARCELID", //Name field for display. Not pertinent to a grid but may be used elsewhere.
          items: items
        };

        //Create data store and bind to grid.
        store = new ItemFileReadStore({
          data: data
        });
        grid = registry.byId("grid");
        grid.setStore(store);
        grid.on("rowclick", onRowClickHandler);

        //Zoom back to the initial map extent
        map.centerAndZoom(center, zoom);
      }

      //Zoom to the parcel when the user clicks a row
      function onRowClickHandler(evt) {
        var clickedTaxLotId = evt.grid.getItem(evt.rowIndex).PARCELID;
        var selectedTaxLot = arrayUtils.filter(map.graphics.graphics, function (graphic) {
          return ((graphic.attributes) && graphic.attributes.PARCELID === clickedTaxLotId);
        });
        if (selectedTaxLot.length) {
          map.setExtent(selectedTaxLot[0].geometry.getExtent(), true);
        }
      }

      on(dojo.byId("exportAll"), "click", function () {

        grid.exportGrid("csv", function (str) {
          ioIframe.create('exportFrame', '', '');
          ioIframe._currentDfd = null;
          ioIframe.send({
            url: "/ExportGrid.csv",
            content: {data: str}
          });
          alert(str);
          document.getElementById("output").value = str;
        });
      });



      //dojo Methods
      on(dojo.byId("printAll"), "click", function () {
        grid.printGrid({
          title: "Print Grid",
          cssFiles: []
        });
      });

      function clear() {
        var newStore = new dojo.data.ItemFileReadStore({
          data: {
            identifier: "",
            items: []
          }
        });
        var grid = dijit.byId("grid");
        grid.setStore(newStore);
      }

    });
  </script>
</head>

<body class="claro">
  <div data-dojo-type="dijit/layout/BorderContainer" data-dojo-props="design:'headline'" style="width:100%;height:100%;margin:0;">
    <div data-dojo-type="dijit/layout/ContentPane" data-dojo-props="region:'top'" style="height:80px;">
      Owner name:
      <input type="text" id="ownerName" size="60" value="Katz" />
      <button id="search" data-dojo-type="dijit.form.Button" type="button" data-dojo-attach-point="button">Search
      </button>
      <button id="clear" data-dojo-type="dijit.form.Button" type="button" data-dojo-attach-point="button">Clear
      </button>
      <button id="exportAll" data-dojo-type="dijit.form.Button" type="button">Export all to CSV</button>
      <button id="printAll" data-dojo-type="dijit.form.Button" type="button">Print All</button>
    </div>
    <div id="map" data-dojo-props="region:'center'" data-dojo-type="dijit/layout/ContentPane" style="border:1px solid #000;"></div>
    <div data-dojo-type="dijit/layout/ContentPane" data-dojo-props="region:'bottom'" style="height:150px;">
      <table data-dojo-type="dojox/grid/EnhancedGrid" data-dojo-id="grid" id="grid" data-dojo-props="rowsPerPage:'5', rowSelector:'20px', plugins:{printer: true, exporter: true}">
        <thead>
          <tr>
            <th field="PARCELID">Parcel ID</th>
            <th field="OWNERNME1">Owner 1</th>
            <th field="OWNERNME2">Owner 2</th>
            <th field="RESYRBLT ">Year Built</th>
            <th field="SITEADDRESS" width="100%">Address</th>
          </tr>
        </thead>
      </table>
      <textarea id="output" style="width: 560px;height: 680px;" />
    </div>
  </div>
</body>
</html>
0 Kudos
RobertScheitlin__GISP
MVP Emeritus

May Jeff,

Attached I have the CSVHandler.ashx code that you can add to your web server.

The steps are simple

  1. Unzip the attached file and place in a new folder your create under "c:\inetpub\wwwroot\" called "HttpHandlers"
  2. In IIS Manager right click on "Default Web Site" and choose "Add Application"
  3. for the Alias type "HttpHandlers"
  4. for Physical path browse to "c:\inetpub\wwwroot\HttpHandlers"
  5. click OK
  6. Now you can add some simple code in your js app like this:

     grid.exportGrid("csv", function (str) {  
        ioIframe.create('exportFrame', '', '');  
        ioIframe._currentDfd = null;  
        ioIframe.send({ 
          url: "/HttpHandlers/CSVHandler.ashx",  
            content: {data: str, filename: 'MyExport.csv'}  
        }); 
     }); 

Notice the url is /HttpHandlers/CSVHandler.ashx

the content contains your csv str and the desired output file name for the download.

MayJeff
Occasional Contributor

Robert,

Thank you so much for taking your time for this thread.  I update the js code and also follow your steps for setting up the server site.

Still got a small issue.  When I run a search by "Katz", I able to export the csv file on the first time and MyExport.csv showed up.  Then if I perform a search sometimes else like "Allen" then got the message like this "

GET http://myserver.com/HttpHandlers/CSVHandler.ashx?data=Parcel%20…20G%20Allen%22%2CNull%2C1957%2C%2273...& 404 (Not Found)".  Therefore, export works on the first time to download the csv file if perform the search by "Katz" and not working on second try.

Do you think is server site setting issue?

0 Kudos
RobertScheitlin__GISP
MVP Emeritus

May Jeff,

  OK, I found the issue and have switched to dojo/request/iframe as dojo/io/iframe is depreciated. I am also attaching a updated ashx file that now uses POST instead of GET as eventually you would have run into an issue with the amount of rows you were converting. I have tested this and you can download the .csv as many time as you want.

<!DOCTYPE html>
<html>

<head>
  <meta http-equiv="Content-Type" content="text/html; charset=utf-8">
  <!--The viewport meta tag is used to improve the presentation and behavior of the samples
      on iOS devices-->
  <meta name="viewport" content="initial-scale=1, maximum-scale=1,user-scalable=no">
  <title>Export the DataGrid to CSV / Print </title>

  <link rel="stylesheet" href="http://js.arcgis.com/3.10/js/dojo/dijit/themes/claro/claro.css">
  <link rel="stylesheet" href="http://js.arcgis.com/3.10/js/dojo/dojox/grid/resources/Grid.css">
  <link rel="stylesheet" href="http://js.arcgis.com/3.10/js/dojo/dojox/grid/resources/claroGrid.css">
  <link rel="stylesheet" href="http://js.arcgis.com/3.10/js/esri/css/esri.css">
  <style>
    html,
    body {
      height: 100%;
      width: 100%;
      margin: 0;
      padding: 0;
    }
  </style>
  <script src="http://js.arcgis.com/3.10/"></script>
  <script>
    require([
        "esri/map",
        "esri/tasks/FindTask",
        "esri/tasks/FindParameters",
        "esri/symbols/SimpleMarkerSymbol",
        "esri/symbols/SimpleLineSymbol",
        "esri/symbols/SimpleFillSymbol",
        "dojo/request/iframe",
        "esri/Color",
        "dojo/on",
        "dojo/dom",
        "dijit/registry",
        "dojo/_base/array",
        "dojo/_base/connect",
        "dojox/grid/DataGrid",
        "dojo/data/ItemFileReadStore",
        "dijit/form/Button",
        "dojo/parser",
        "dojo/store/Memory",
        "dojo/data/ItemFileWriteStore",
        "dgrid/OnDemandGrid",
        "dojox/grid/EnhancedGrid",
        "dojox/grid/enhanced/plugins/exporter/CSVWriter",
        "dojox/grid/enhanced/plugins/Printer",
        "dgrid/Selection",
        "dojo/_base/declare",
        "dijit/layout/BorderContainer",
        "dijit/layout/ContentPane",
        "dojo/domReady!"
      ], function (
        Map, FindTask, FindParameters, SimpleMarkerSymbol, SimpleLineSymbol, SimpleFillSymbol, iframe,
        Color, on, dom, registry, arrayUtils, connect, DataGrid, ItemFileReadStore, Button, parser, Memory,
        ItemFileWriteStore, Grid, EnhancedGrid, CSVWriter, Printer, Selection, declare, BorderContainer, ContentPane

    ) {
      var findTask, findParams;
      var map, center, zoom;
      var grid, store, dfd;

      parser.parse();

      registry.byId("search").on("click", doFind);
      registry.byId("clear").on("click", clear);

      center = [-83.266, 42.568];
      zoom = 11;
      map = new esri.Map("map", {
        basemap: "streets",
        center: center,
        zoom: zoom
      });

      //Create Find Task using the URL of the map service to search
      findTask = new FindTask("http://sampleserver1.arcgisonline.com/ArcGIS/rest/services/TaxParcel/TaxParcelQuery/MapServer/");

      map.on("load", function () {
        //Create the find parameters
        findParams = new FindParameters();
        findParams.returnGeometry = true;
        findParams.layerIds = [0];
        findParams.searchFields = ["OWNERNME1", "OWNERNME2"];
        findParams.outSpatialReference = map.spatialReference;
        console.log("find sr: ", findParams.outSpatialReference);
      });

      function doFind() {
        //Set the search text to the value in the box
        findParams.searchText = dom.byId("ownerName").value;
        findTask.execute(findParams, showResults);
      }

      function showResults(results) {
        //This function works with an array of FindResult that the task returns
        map.graphics.clear();
        var symbol = new SimpleFillSymbol(
          SimpleFillSymbol.STYLE_SOLID,
          new SimpleLineSymbol(SimpleLineSymbol.STYLE_SOLID, new Color([98, 194, 204]), 2),
          new Color([98, 194, 204, 0.5])
        );

        //create array of attributes
        var items = arrayUtils.map(results, function (result) {
          var graphic = result.feature;
          graphic.setSymbol(symbol);
          map.graphics.add(graphic);
          return result.feature.attributes;
        });

        //Create data object to be used in store
        var data = {
          identifier: "PARCELID", //This field needs to have unique values
          label: "PARCELID", //Name field for display. Not pertinent to a grid but may be used elsewhere.
          items: items
        };

        //Create data store and bind to grid.
        store = new ItemFileReadStore({
          data: data
        });
        grid = registry.byId("grid");
        grid.setStore(store);
        grid.on("rowclick", onRowClickHandler);

        //Zoom back to the initial map extent
        map.centerAndZoom(center, zoom);
      }

      //Zoom to the parcel when the user clicks a row
      function onRowClickHandler(evt) {
        var clickedTaxLotId = evt.grid.getItem(evt.rowIndex).PARCELID;
        var selectedTaxLot = arrayUtils.filter(map.graphics.graphics, function (graphic) {
          return ((graphic.attributes) && graphic.attributes.PARCELID === clickedTaxLotId);
        });
        if (selectedTaxLot.length) {
          map.setExtent(selectedTaxLot[0].geometry.getExtent(), true);
        }
      }

      on(dojo.byId("exportAll"), "click", function () {
        var fileName = dom.byId("ownerName").value.replace(' ', '_');
        grid.exportGrid("csv", function (str) {
          if(dfd){
            dfd.cancel();
          }
          dfd = iframe.post("/HttpHandlers/CSVHandler.ashx", {
            preventCache: true,
            data: {data: str},
            query: {filename: fileName + '.csv'}
          });
        });
      });

      //dojo Methods
      on(dojo.byId("printAll"), "click", function () {
        grid.printGrid({
          title: "Print Grid",
          cssFiles: []
        });
      });

      function clear() {
        var newStore = new dojo.data.ItemFileReadStore({
          data: {
            identifier: "",
            items: []
          }
        });
        var grid = dijit.byId("grid");
        grid.setStore(newStore);
      }

    });
  </script>
</head>

<body class="claro">
  <div data-dojo-type="dijit/layout/BorderContainer" data-dojo-props="design:'headline'" style="width:100%;height:100%;margin:0;">
    <div data-dojo-type="dijit/layout/ContentPane" data-dojo-props="region:'top'" style="height:30px;">
      Owner name:
      <input type="text" id="ownerName" size="60" value="Katz" />
      <button id="search" data-dojo-type="dijit/form/Button" type="button">Search</button>
      <button id="clear" data-dojo-type="dijit/form/Button" type="button">Clear</button>
      <button id="exportAll" data-dojo-type="dijit/form/Button" type="button">Export all to CSV</button>
      <button id="printAll" data-dojo-type="dijit/form/Button" type="button">Print All</button>
    </div>
    <div id="map" data-dojo-props="region:'center'" data-dojo-type="dijit/layout/ContentPane" style="border:1px solid #000;"></div>
    <div data-dojo-type="dijit/layout/ContentPane" data-dojo-props="region:'bottom'" style="height:150px;">
      <table data-dojo-type="dojox/grid/EnhancedGrid" data-dojo-id="grid" id="grid" data-dojo-props="rowsPerPage:'5', rowSelector:'20px', plugins:{printer: true, exporter: true}">
        <thead>
          <tr>
            <th field="PARCELID">Parcel ID</th>
            <th field="OWNERNME1">Owner 1</th>
            <th field="OWNERNME2">Owner 2</th>
            <th field="RESYRBLT ">Year Built</th>
            <th field="SITEADDRESS" width="100%">Address</th>
          </tr>
        </thead>
      </table>
    </div>
  </div>
</body>
</html>
MayJeff
Occasional Contributor

Can't complete my task without your help.  Thank you very much.

0 Kudos
Chang-HengYang
New Contributor III

Hi May,

I am also excited that Robert solved this question. I will try to apply this solution to my application.

Hi Robert,

Thank you for your work a lot!!!

Hank

0 Kudos
JamesOsundwa
New Contributor III

Hi Robert,

I'm incorporating your solution above and seem to be having problems calling the grid object. I'm getting the error Cannot read property 'exportGrid' of undefined (see full code below). I can't seem to figure it out. Please help.

Thanks,
James.

<!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<meta name="viewport" content="initial-scale=1, maximum-scale=1,user-scalable=no"/>
<title>On Premise Account Mapping</title>
<link rel="stylesheet" href="https://js.arcgis.com/3.20/esri/themes/calcite/dijit/calcite.css">
<link rel="stylesheet" href="https://js.arcgis.com/3.20/dijit/themes/claro/claro.css">
<link rel="stylesheet" href="https://js.arcgis.com/3.20/esri/css/esri.css">
<link rel="stylesheet" href="https://js.arcgis.com/3.20/dojox/grid/resources/Grid.css">
<link rel="stylesheet" href="https://js.arcgis.com/3.20/dojox/grid/resources/claroGrid.css">

<style>
html, body, #mapDiv {
padding:0;
margin:0;
height:100%;
}
#rightPane {
padding: 0;
width:250px;
}
button {
display: block;
}
#messages {
padding-top: 40px;
}
#search {
display: block;
position: absolute;
z-index: 2;
top: 20px;
left: 74px;
}
</style>

<script src="https://js.arcgis.com/3.20/"></script>
<script>
var map,tb;
var graphic;
var currLocation;
var watchId;
require([
"esri/map",
"esri/dijit/Search",
"esri/geometry/Point",
"esri/dijit/Legend",
"esri/layers/ArcGISDynamicMapServiceLayer",
"esri/toolbars/draw",
"esri/Color",
"esri/symbols/SimpleMarkerSymbol",
"esri/symbols/SimpleLineSymbol",
"esri/symbols/SimpleFillSymbol",
"esri/symbols/PictureFillSymbol",
"esri/symbols/CartographicLineSymbol",
"esri/layers/FeatureLayer",
"esri/graphic",
"esri/tasks/query",
"esri/tasks/QueryTask",
"esri/InfoTemplate",

"dojox/grid/DataGrid",
"dojo/data/ItemFileReadStore",
"dijit/form/Button",
"dojo/store/Memory",
"dojo/data/ItemFileWriteStore",
"dgrid/OnDemandGrid",
"dojox/grid/EnhancedGrid",
"dojox/grid/enhanced/plugins/exporter/CSVWriter",
"dojox/grid/enhanced/plugins/Printer",
"dgrid/Selection",
"dojo/request/iframe",
"dojo/_base/declare",
"dojo/promise/all",
"dojo/_base/array",
"dojo/_base/connect",
"dijit/registry",

"dojo/dom",
"dojo/on",
"dojo/parser",
"dijit/layout/BorderContainer",
"dijit/layout/ContentPane",
"dijit/layout/AccordionContainer",
"dojo/domReady!"],

function (
Map,
Search,
Point,
Legend,
ArcGISDynamicMapServiceLayer,
Draw,
Color,
SimpleMarkerSymbol,
SimpleLineSymbol,
SimpleFillSymbol,
PictureFillSymbol,
CartographicLineSymbol,
FeatureLayer,
Graphic,
Query,
QueryTask,
InfoTemplate,

DataGrid,
ItemFileReadStore,
Button,
Memory,
ItemFileWriteStore,
Grid,
EnhancedGrid,
CSVWriter,
Printer,
Selection,
iframe,
declare,
All,
arrayUtils,
connect,
registry,

dom,
on,
parser) {

var grid, store, dfd;
parser.parse();

// markerSymbol is used for point and multipoint, see http://raphaeljs.com/icons/#talkq for more examples
var markerSymbol = new SimpleMarkerSymbol();
markerSymbol.setPath("M16,4.938c-7.732,0-14,4.701-14,10.5c0,1.981,0.741,3.833,2.016,5.414L2,25.272l5.613-1.44c2.339,1.316,5.237,2.106,8.387,2.106c7.732,0,14-4.701,14-10.5S23.732,4.938,16,4.938zM16.868,21.375h-1.969v-1.889h1.969V21.375zM16.772,18.094h-1.777l-0.176-8.083h2.113L16.772,18.094z");
markerSymbol.setColor(new Color("#00FFFF"));

// lineSymbol used for freehand polyline, polyline and line.
var lineSymbol = new CartographicLineSymbol(
CartographicLineSymbol.STYLE_SOLID,
new Color([255, 0, 0]), 10,
CartographicLineSymbol.CAP_ROUND,
CartographicLineSymbol.JOIN_MITER, 5);

// fill symbol used for extent, polygon and freehand polygon
var fillSymbol = new SimpleFillSymbol();


map = new Map("mapDiv", {
basemap: "gray",
center: [-118.48, 34.013],
zoom: 2
});
map.on("load", initFunc);
map.on("load", initToolbar);
//add the legend
map.on("layers-add-result", function (evt) {
var layerInfo = arrayUtils.map(evt.layers, function (layer, index) {
return {layer:layer.layer, title:layer.layer.name};
});
if (layerInfo.length > 0) {
var legendDijit = new Legend({
map: map,
layerInfos: layerInfo
}, "legendDiv");
legendDijit.startup();
}
});


var featureLayer1 = new FeatureLayer("https://maps.redbull.com/redbullgis/rest/services/Sales/BullMap/MapServer/0", {
mode: FeatureLayer.MODE_SELECTION,
infoTemplate: new InfoTemplate("MA: ${Name}", "${*}"),
outFields: ["*"]
});

var featureLayer2 = new FeatureLayer("https://maps.redbull.com/redbullgis/rest/services/Sales/BullMap/MapServer/2", {
mode: FeatureLayer.MODE_SELECTION,
infoTemplate: new InfoTemplate("NA: ${Name}", "${*}"),
outFields: ["*"]
});

var featureLayer3 = new FeatureLayer("https://maps.redbull.com/redbullgis/rest/services/Sales/BullMap/MapServer/3", {
mode: FeatureLayer.MODE_SELECTION,
infoTemplate: new InfoTemplate("DPM: ${Name}", "${*}"),
outFields: ["*"]
});

var dynamicMapServiceLayer = new ArcGISDynamicMapServiceLayer("https://maps.redbull.com/redbullgis/rest/services/Sales/BullMap/MapServer", {
//"opacity" : 0.5,
//"imageParameters" : imageParameters
});

map.addLayers([featureLayer1, featureLayer2, featureLayer3, dynamicMapServiceLayer]);


function orientationChanged() {
if(map){
map.reposition();
map.resize();
}
}

function initFunc(map) {
if( navigator.geolocation ) {
navigator.geolocation.getCurrentPosition(zoomToLocation, locationError);
watchId = navigator.geolocation.watchPosition(showLocation, locationError);
} else {
alert("Browser doesn't support Geolocation. Visit http://caniuse.com to see browser support for the Geolocation API.");
}
initToolbar;
}

function locationError(error) {
//error occurred so stop watchPosition
if( navigator.geolocation ) {
navigator.geolocation.clearWatch(watchId);
}
switch (error.code) {
case error.PERMISSION_DENIED:
alert("Location not provided");
break;

case error.POSITION_UNAVAILABLE:
alert("Current location not available");
break;

case error.TIMEOUT:
alert("Timeout");
break;

default:
alert("unknown error");
break;
}
}

function zoomToLocation(location) {
var pt = new Point(location.coords.longitude, location.coords.latitude);
AddGraphic1(pt);
map.centerAndZoom(pt, 12);
}

function showLocation(location) {
//zoom to the users location and add a graphic
var pt = new Point(location.coords.longitude, location.coords.latitude);
if ( !graphic ) {
AddGraphic1(pt);
} else { // move the graphic if it already exists
graphic.setGeometry(pt);
}
map.centerAt(pt);
}

function AddGraphic1(pt){
var symbol = new SimpleMarkerSymbol(
SimpleMarkerSymbol.STYLE_CIRCLE,
12,
new SimpleLineSymbol(
SimpleLineSymbol.STYLE_SOLID,
new Color([210, 105, 30, 0.5]),
8
),
new Color([210, 105, 30, 0.9])
);
graphic = new Graphic(pt, symbol);
map.graphics.add(graphic);
}


function initToolbar() {
tb = new Draw(map);
tb.on("draw-end", addGraphic);

// event delegation so a click handler is not
// needed for each individual button
on(dom.byId("info"), "click", function (evt) {
if (evt.target.id === "info") {
return;
}
var tool = evt.target.id.toLowerCase();
map.disableMapNavigation();
tb.activate(tool);
});
}

function addGraphic(evt) {
//deactivate the toolbar and clear existing graphics
tb.deactivate();
map.enableMapNavigation();
map.graphics.clear();

// figure out which symbol to use
var symbol;
if (evt.geometry.type === "point" || evt.geometry.type === "multipoint") {
symbol = markerSymbol;
} else if (evt.geometry.type === "line" || evt.geometry.type === "polyline") {
symbol = lineSymbol;
} else {
symbol = fillSymbol;
}

map.graphics.add(new Graphic(evt.geometry, symbol));
queryMapService(evt.geometry);
}

function queryMapService(Geom) {
var promises = [];

var query = new Query();
query.returnGeometry = false;
query.outFields = ["*"];
query.geometry = Geom;
promises.push(featureLayer1.selectFeatures(query, FeatureLayer.SELECTION_NEW));
promises.push(featureLayer2.selectFeatures(query, FeatureLayer.SELECTION_NEW));
promises.push(featureLayer3.selectFeatures(query, FeatureLayer.SELECTION_NEW));
var allPromises = new All(promises);
allPromises.then(function (r) {
showResults(r);
});
}

function showResults(results) {
var featureLayer1Message = results[0].length;
var featureLayer2Message = results[1].length;
var featureLayer3Message = results[2].length;

var count = 0;
for (var i = 0; i < results.length; i++) {
count = count + results.length;
}

dom.byId("messages").innerHTML = "Total stores selected: <b>" + count + "</b><br>  Musketeer: <b>" + featureLayer1Message + "</b><br>  National: <b>" + featureLayer2Message + "</b><br>  DP Managed: <b>" + featureLayer3Message + "</b>";

//create array of attributes
var items = arrayUtils.map(results, function (result) {
return result;
});

var allItems = [];

arrayUtils.map(items[0], function (item) {
allItems.push(item.attributes);
})

arrayUtils.map(items[1], function (item) {
allItems.push(item.attributes);
})

arrayUtils.map(items[2], function (item) {
allItems.push(item.attributes);
})

var data = {
identifier: "OBJECTID", //This field needs to have unique values
label: "OBJECTID", //Name field for display. Not pertinent to a grid but may be used elsewhere.
items: allItems
};

//Create data store and bind to grid.
store = new ItemFileReadStore({
data: data
});

var grid = registry.byId("grid");
grid.setStore(store);

}

var search = new Search({
map: map
}, "search");
search.startup();

on(dojo.byId("exportAll"), "click", function () {
var fileName = "test"; //dom.byId("grid").value.replace(' ', '_');
grid.exportGrid("csv", function (str) {
if(dfd){
dfd.cancel();
}
dfd = iframe.post("/HttpHandlers/CSVHandler.ashx", {
preventCache: true,
data: {data: str},
query: {filename: fileName + '.csv'}
});
});
});

//dojo Methods
on(dojo.byId("printAll"), "click", function () {
grid.printGrid({
title: "Print Grid",
cssFiles: []
});
});

function clear() {
var newStore = new dojo.data.ItemFileReadStore({
data: {
identifier: "",
items: []
}
});
var grid = dijit.byId("grid");
grid.setStore(newStore);
}

});
</script>
</head>


<body class='claro'>
<div id="mainWindow" data-dojo-type="dijit.layout.BorderContainer" data-dojo-props="design:'headline',gutters:false" style="width:100%; height:100%;">
<div id="mapDiv" class="shadow roundedCorners" data-dojo-type="dijit.layout.ContentPane" data-dojo-props="region:'center'"><div class="calcite" id="search"></div></div>
<div data-dojo-type="dijit/layout/ContentPane" data-dojo-props="region:'bottom'" style="height:150px;">
<table data-dojo-type="dojox/grid/EnhancedGrid" data-dojo-id="grid" id="grid" data-dojo-props="rowsPerPage:'5', rowSelector:'20px', plugins:{printer: true, exporter: true}">
<thead>
<tr>
<th fields="StoreID,store_id" width="100px">Store ID</th>
<th fields="Name,store_name" width="150px">Name</th>
<th fields="Address,store_addr1" width="200px">Address</th>
<th fields="ACV,acv_tier_code">ACV</th>
<th fields="Priority,onprem_store_priority">Priority</th>
<th fields="Status,store_status">Status</th>
<th field="YTDTotalSUs,ts_ytd">YTD Total</th>
</tr>
</thead>
</table>
</div>
<div class="roundedCorners" data-dojo-props="region:'right'" data-dojo-type="dijit.layout.ContentPane" id="rightPane">
<div data-dojo-type="dijit.layout.AccordionContainer">
<div data-dojo-props="title:'Create Territory'" data-dojo-type="dijit.layout.ContentPane" id='graphics'>
<div id="info">
<div>
Select a shape then draw on the map to create a territory
</div><button id="Extent">Rectangle</button> <button id="Circle">Circle</button> <button id="Ellipse">Ellipse</button> <button id="FreehandPolygon">Freehand Polygon</button>
</div>
<div id="messages"></div>
<button data-dojo-type="dijit/form/Button" id="exportAll" type="button">Export all to CSV</button>
<button data-dojo-type="dijit/form/Button" id="printAll" type="button">Print All</button>
</div>
<div data-dojo-props="title:'Legend'" data-dojo-type="dijit/layout/ContentPane" id="legendPane">
<div id="legendDiv"></div>
</div>
</div>
</div>
</div>
</body>

</html>

0 Kudos
thejuskambi
Occasional Contributor III

Hello James,

You are not updating the grid variable which is define above below parser.parse(). Instead, you are creating another locale variable named grid inside the showResults function. Either you can do like Robert as mentioned or dont create a new variable like in the original sample.

 //Create data store and bind to grid.
 store = new ItemFileReadStore({
     data: data
 });
 
 grid = registry.byId("grid");
 grid.setStore(store);‍‍‍‍‍‍‍