5

I'm using the grid from http://ui-grid.info/ in a project. I've created a hierarchical grid, which works nicely, but when I do an export, it only exports the data from the top-level grid.

This is by design and is standard functionality for the grid, so there's no point in me putting up any example code. Any example from http://ui-grid.info/docs/#/tutorial will do.

Is there a way to export the subgrid (preferably both the main grid AND the subgrid together as they appear in the grid)?

Matt Eno
  • 687
  • 5
  • 25
  • Have you tried data-tables. https://www.datatables.net/ It is jquery based and you have loads of extensions in jq which does this. More, Data tables are very responsive. ng UI-Grid have made their lib very complicated unnecessarily. – Gary Dec 10 '15 at 11:41

3 Answers3

4

Sadly the answer is no.

As you can see here the function getData iterates through all rows and then through all columns, adding to an array of extractedFields the columns to be extracted and aggregating those in an array of extractedRows.

This means that no data, other than what's defined in gridOptions' columnDef will be read, converted and extracted.

By design, subgrid information are stored inside a property of any row entity's subGridOptions but this property is never accessed inside of the exporter feature.

The motivation behind this behaviour is that expandable grid feature is still at an alpha stage, so, supporting this in other features is not a compelling priority.

Furthermore, adding subgrid to a CSV could be quite hard to design, if we wanted to provide a general solution (for example I don't even think it would be compliant to CSV standard if you had different number of columns in the main grid and in subgrids).

That said, ui-grid is an open source project, so, if you have a working design in mind, feel free to open a discussion about it on the project gitHub page or, even better, if you can design a working (and tested) solution and create a pull request, even better!

imbalind
  • 1,182
  • 6
  • 13
  • In order to keep the exported file confirm to csv standard, maybe each grid occupies a separate csv. Main grid's cell that is composed of subgrids includes a link to the external csv file of the subgrid... just a little thought to share. – gm2008 Dec 14 '15 at 14:07
  • How do you think links could be? I sincerely cannot think of a standard way to do it – imbalind Dec 15 '15 at 16:29
2

I managed to get it working, although if I had the time I would do it a bit better than what I've done by actually creating a branch of the code and doing it properly, but given time constraints, what I've got is working nicely.

FYI, here's the way I ended up getting it to do what I wanted:

In my grid options, I turned off the CSV export options in the grid menu (because I've only implemented the changes for PDF).

I made a copy of exporter.js, named it custom.exporter.js and changed my reference to point to the new file.

In custom.exporter.js, I made a copy of the getData function and named it getGridRows. getGridRows is the same as getData, except it just returns the rows object without all the stuff that gets the columns and so on. For now, I'm coding it to work with a known set of columns, so I don't need all that.

I modified the pdfExport function to be as follows:

pdfExport: function (grid, rowTypes, colTypes) {
              var self = this;

              var exportData = self.getGridRows(grid, rowTypes, colTypes);

              var docContent = [];

              $(exportData).each(function () {
                  docContent.push(
                      {
                          table: {
                              headerRows: 1,
                              widths: [70, 80, 150, 180],
                              body: [
                                [{ text: 'Job Raised', bold: true, fillColor: 'lightgray' }, { text: 'Job Number', bold: true, fillColor: 'lightgray' }, { text: 'Client', bold: true, fillColor: 'lightgray' }, { text: 'Job Title', bold: true, fillColor: 'lightgray' }],
                                [formattedDateTime(this.entity.JobDate,false), this.entity.JobNumber, this.entity.Client, this.entity.JobTitle],
                              ]
                          }
                      });
                  var subGridContentBody = [];
                  subGridContentBody.push([{ text: 'Defect', bold: true, fillColor: 'lightgray' }, { text: 'Vendor', bold: true, fillColor: 'lightgray' }, { text: 'Status', bold: true, fillColor: 'lightgray' }, { text: 'Sign off', bold: true, fillColor: 'lightgray' }]);
                  $(this.entity.Defects).each(function () {
                      subGridContentBody.push([this.DefectName, this.DefectVendor, this.DefectStatus, '']);
                  });
                  docContent.push({
                      table: {
                          headerRows: 1,
                          widths: [159, 150, 50, 121],
                          body: subGridContentBody
                      }
                  });
                  docContent.push({ text: '', margin: 15 });
              });

              var docDefinition = {
                  content:  docContent
              }


              if (self.isIE()) {
                  self.downloadPDF(grid.options.exporterPdfFilename, docDefinition);
              } else {
                  pdfMake.createPdf(docDefinition).open();
              }
          }
Matt Eno
  • 687
  • 5
  • 25
  • Thanks for sharing this, it has proved immensely useful in attempting to implement my own ui-grid sub-grid export. – Elijah Lofgren Sep 09 '16 at 18:49
  • One thing that could be improved in the above code is using nested tables so that the table header of the parent able doesn't need to be repeated. It wasn't obvious that pdfmake had this features so I've posted info on that here: http://stackoverflow.com/questions/39454842/nested-sub-tables-with-pdfmake – Elijah Lofgren Sep 12 '16 at 16:47
0

No, there is no direct way to export subgrid. rather you can create youur own json data to generate csv file. Please check the below code

function jsonToCsvConvertor(JSONData, reportTitle) {
    //If JSONData is not an object then JSON.parse will parse the JSON string in an Object
    var arrData = typeof JSONData !== 'object' ? JSON.parse(JSONData) : JSONData,                    
        csv = '',
        row,
        key1,
        i,
        subGridData;

    //Set Report title in first row or line                    
    csv += reportTitle + '\r\n\n';

    row = '';                        
    for (key1 in arrData[0]) {                         
        if(key1 !== 'subGridOptions' && key1 !== '$$hashKey'){
            row += key1 + ',';
        }
    }                                  
    csv += row + '\r\n';

    for (i = 0; i < arrData.length; i++) {
        row = '';
        subGridData = '';                                        
        for (key1 in arrData[i]) {
            if(key1 !== 'subGridOptions' && key1 !== '$$hashKey'){
                row += '"' + arrData[i][key1] + '",';
            }
            else if(key1 === 'subGridOptions'){
                //csv += row + '\r\n';
                subGridData = writeSubGridData(arrData[i][key1].data);                                
            }                     
        }
        csv += row + '\r\n';
        csv = subGridData ? csv + subGridData + '\r\n' : csv;
    }
    if (csv === '') {
        console.log('Invalid data');
    }
    return csv;     
}
//Generates subgrid Data to exportable form
function writeSubGridData(subgridData){
    var j,
        key2,             
        csv = '',
        row = '';
    for (key2 in subgridData[0]){
        if(key2 !== '$$hashKey'){
        row += key2 + ',';  
        }                                
    }
    csv = row + '\r\n';
    for (j=0; j < subgridData.length ; j++){
        row = '';                                    
        for(key2 in subgridData[j]){
            if(key2 !== '$$hashKey'){                                
                row += '"' + subgridData[j][key2]+ '",';
            }
        }
        csv += row + '\r\n';
    }
    return csv;
}

jsonToCsvConvertor(exportData, 'New-Report');