Bug in Excel export?

Bug in Excel export?

daveslabdaveslab Posts: 40Questions: 14Answers: 0

I recently upgraded to the latest releases of Datatables, Editor, and a few other plugins and I noticed now that I get an error when I try to programmatically export to an Excel file:

datatables.js:38395 Uncaught TypeError: Cannot read property 'toString' of null
    at _excelColWidth (datatables.js:38395)
    at _Api.action (datatables.js:39015)
    at action (datatables.js:35096)
    at HTMLAnchorElement.<anonymous> (datatables.js:35111)
    at HTMLAnchorElement.dispatch (jquery.js:4435)
    at HTMLAnchorElement.elemData.handle (jquery.js:4121)
    at Object.trigger (jquery.js:4350)
    at HTMLAnchorElement.<anonymous> (jquery.js:4901)
    at Function.each (jquery.js:374)
    at jQuery.fn.init.each (jquery.js:139)

The code that triggers the export is:

myDT.button('0-0').trigger();

where the buttons config is this:

//...
      buttons: [
        { extend: 'collection',
          text: 'Export',
          buttons: [
            { extend: 'excel',
              exportOptions: {
                orthogonal: 'export',
              }
            },
            'csv',
          ]
        },
      ]
//...

The list of all my custom Datatables download build is: JSZip 2.5.0, Moment 2.13.0, jQuery Mask 1.13.4, Select2 4.0.1, DataTables 1.10.13, Buttons 1.2.4, Column visibility 1.2.4, Flash export 1.2.4, HTML5 export 1.2.4, ColReorder 1.3.2, Editor 1.6.1, Field type - Display 1.5.6, Field type - Mask 1.5.6, Select 1.2.0

This question has accepted answers - jump to:

Answers

  • allanallan Posts: 61,744Questions: 1Answers: 10,111 Site admin

    Can you link to the page showing the issue so I can take a look please? It will be something related to the data in the table and I'd need to know what that data is to be able to replicate the issue and resolve it.

    Allan

  • daveslabdaveslab Posts: 40Questions: 14Answers: 0

    Unfortunately, I cannot link to the page because it's on an internal project that I don't have the right to make public. I can try to give you a JS export of the data. Here's the data in JSON for a table with two rows that has the bug:

    [
    {"id":22045,"type":"AbonneDonnees","abonne_id":22046,"abonne_fichier_id":22045,"fichier_id":1,"est_du_meme_fichier":true,"titre_id":87,"prenom":"David A","nom":"Smith","particule":null,"societe":"Instituto Cristi Rege Sommo Sacerdote","lieu":null,"adresse":"Via di Grici","code_postal":"50065","ville":"Sieci","pays_id":105,"statut":"Normal"},
    {"id":22053,"type":"AbonneDonnees","abonne_id":22052,"abonne_fichier_id":22053,"fichier_id":1,"est_du_meme_fichier":true,"titre_id":189,"prenom":"David","nom":"Smith","particule":"du","societe":null,"lieu":null,"adresse":null,"code_postal":"12345","ville":"Fleuve-sur-chose","pays_id":72,"statut":"Prospection"}
    ]
    
  • daveslabdaveslab Posts: 40Questions: 14Answers: 0
    edited January 2017

    Oh please excuse me, it was dumb of me not to mention where the bogue is in the DataTables code. It's on the 9th line of the function _excelColWidth. The line looks like this:

    str = data.body[i][col].toString();
    

    It seems like it fails when the data in a given cell is null and not empty string. May I suggest an improvement to something like the following (it's what I've done in my local copy of DataTables) ? It works now after I made this change.

    str = (data.body[i][col] || '').toString();
    
  • allanallan Posts: 61,744Questions: 1Answers: 10,111 Site admin
    Answer ✓

    That looks just about perfect - the only catch would be false since false.toString() === "false". With the above that would be replaced with an empty string.

    How about the following?:

            var point = data.body[i][col];
            str = point !== null && point !== undefined ?
                point.toString() :
                '';
    

    Allan

  • daveslabdaveslab Posts: 40Questions: 14Answers: 0

    Looks good to me. Rant-y side note: it's a real shame in JS (AFAIK) that you cannot do something as simple as:

    str = hasProperty(point, 'toString') ? point.toString() : '';
    

    Because that's really what you're going for and semantically it makes more sense. You wanna know if point has a method toString and if so, call it. sigh.

  • allanallan Posts: 61,744Questions: 1Answers: 10,111 Site admin
    Answer ✓

    Yup! Completely agree. I went around a few twists with typeof etc before I decided to just go with the above.

    Fix committed here. The nightly will rebuild with the change shortly (5 minutes) and it will be in the next release.

    Thanks for this!
    Allan

  • daveslabdaveslab Posts: 40Questions: 14Answers: 0

    Awesome, thanks Allan!

This discussion has been closed.