2015-03-20 1 views
2

J'utilise AngularJS avec ng-grid. Le plugin d'export CSV pour ng-grid ne fonctionne pas bien avec IE, nous avons donc construit une solution de contournement en utilisant un iframe pour récupérer les données csv et les télécharger. Toutefois, la fonction exeCommand enregistre uniquement en tant que fichier texte, même en spécifiant un suffixe de fichier .csv. Toutes les données sont dans le fichier texte, et quand il est converti en csv cela fonctionne bien, mais nous avons besoin de ce fichier à télécharger en tant que .csv dès le début.ne fonctionne pas dans IE

Je n'ai trouvé ce bug MS qui peut être la source du problème - curieux de savoir si quelqu'un peut penser à une solution: https://support.microsoft.com/en-us/kb/929863

Merci!

code en question:

function ngGridCsvExportPlugin (opts) { 
    var self = this; 
    self.grid = null; 
    self.scope = null; 
    self.init = function(scope, grid, services) { 
     self.grid = grid; 
     self.scope = scope; 
     function showDs() { 
      var keys = []; 
      // setup our map index of `field`: `displayName` 
      var keyNames = {}; 
      for (var f in grid.config.columnDefs) { keys.push(grid.config.columnDefs[f].field);} 

      // build a map of field i.e. {metric_name: "Metric Name", age: "Age"} 
      for (var f in grid.config.columnDefs) { 
       keyNames[grid.config.columnDefs[f].field] = grid.config.columnDefs[f].displayName; 
      } 
      var getCsvFileForIE = function(target) { 
       var csvData = target.attributes["data-csv"].value; 
       if (! supportsDataUri()) { 
        csvData = decodeURIComponent(csvData); 

        var iframe = document.getElementById('csvDownloadFrame'); 
        iframe = iframe.contentWindow || iframe.contentDocument; 

        csvData = 'sep=,\r\n' + csvData; 

        iframe.document.open("text/html", "replace"); 
        iframe.document.write(csvData); 
        iframe.document.close(); 
        iframe.focus(); 
        iframe.document.execCommand('SaveAs', true, 'data.csv'); 
       } else { 
        if (console && console.log) { 
         console.log('Trying to call getCsvFileForIE with non IE browser.'); 
        } 
       } 
      }; 

      var supportsDataUri = function() { 
       var isOldIE = navigator.appName === "Microsoft Internet Explorer"; 
       var isIE11 = !!navigator.userAgent.match(/Trident\/7\./); 
       return ! (isOldIE || isIE11); //Return true if not any IE 
      }; 
      var csvData = ''; 
      function csvStringify(str) { 
       if (str == null) { // we want to catch anything null-ish, hence just == not === 
        return ''; 
       } 
       if (typeof(str) === 'number') { 
        return '' + str; 
       } 
       if (typeof(str) === 'boolean') { 
        return (str ? 'TRUE' : 'FALSE') ; 
       } 
       if (typeof(str) === 'string') { 
        return str.replace(/"/g,'""'); 
       } 

       return JSON.stringify(str).replace(/"/g,'""'); 
      } 
      function swapLastCommaForNewline(str) { 
       var newStr = str.substr(0,str.length - 1); 
       return newStr + "\n"; 
      } 
      for (var k in keys) { 
       // unwrap our mapping dictionary 
       csvData += '"' + csvStringify(keyNames[keys[k]]) + '",'; 
      } 
      csvData = swapLastCommaForNewline(csvData); 
      var gridData = grid.data; 

      for (var gridRow in gridData) { 
       for (k in keys) { 
        var curCellRaw; 
        if (opts != null && opts.columnOverrides != null && opts.columnOverrides[keys[k]] != null) { 
         curCellRaw = opts.columnOverrides[keys[k]](gridData[gridRow][keys[k]]); 
        //dbogart added this to handle null cases 
        } else if (gridData[gridRow] === null) { 
         curCellRaw = ''; 
        } else { 
         curCellRaw = gridData[gridRow][keys[k]]; 
        } 
        csvData += '"' + csvStringify(curCellRaw) + '",'; 
       } 
       csvData = swapLastCommaForNewline(csvData); 
      } 
      var fp = grid.$root.find(".ng-grid-buttons"); 
      var csvDataLinkPrevious = grid.$root.find('.ng-grid-buttons .csv-data-link-span'); 
      if (csvDataLinkPrevious != null) {csvDataLinkPrevious.remove() ; } 
      var csvDataLinkHtml = "<div class='ngHeaderButton2'></div><span class=\"csv-data-link-span\">"; 
      //csvDataLinkHtml += "<a class ='exportLink' href=\"data:text/csv;charset=UTF-8,"; 
      //csvDataLinkHtml += encodeURIComponent(csvData); 
      //csvDataLinkHtml += "\" download=\"Export.csv\"><i class='fa fa-file-excel-o excel-icon'></i></a></span>" ; 
      csvDataLinkHtml += " <a "; 
      if (! supportsDataUri() ) { 
       csvDataLinkHtml += " data-csv=\""; 
       csvDataLinkHtml += encodeURIComponent(csvData); 
       csvDataLinkHtml += "\" onclick='getCsvFileForIE(this);' >"; 
      } else { 
       csvDataLinkHtml += "href=\"data:text/csv;charset=UTF-8,"; 
       csvDataLinkHtml += encodeURIComponent(csvData); 
       csvDataLinkHtml += "\" download=\"Export.csv\">"; 
      } 
      csvDataLinkHtml += "<i class='fa fa-file-excel-o excel-icon'></i></a></span>" ; //End csv-data-link-span 

      //csvDataLinkHtml += "CSV Export</a> &nbsp;&nbsp;"; 

      //csvDataLinkHtml += "</br></span>"; //End csv-data-link-span 
      fp.append(csvDataLinkHtml); 
     } 
     setTimeout(showDs, 0); 
     scope.catHashKeys = function() { 
      var hash = ''; 
      for (var idx in scope.renderedRows) { 
       hash += scope.renderedRows[idx].$$hashKey; 
      } 
      return hash; 
     }; 
     scope.$watch('catHashKeys()', showDs); 
    }; 
} 

function getCsvFileForIE(target) { 
    var csvData = target.attributes["data-csv"].value; 
    if (! supportsDataUri()) { 
     csvData = decodeURIComponent(csvData); 

     var iframe = document.getElementById('csvDownloadFrame'); 
     iframe = iframe.contentWindow || iframe.contentDocument; 

     csvData = 'sep=,\r\n' + csvData; 

     iframe.document.open("text/html", "replace"); 
     iframe.document.write(csvData); 
     iframe.document.close(); 
     iframe.focus(); 
     iframe.document.execCommand('SaveAs', true, 'data.csv'); 
    } else { 
     if (console && console.log) { 
      console.log('Trying to call getCsvFileForIE with non IE browser.'); 
     } 
    } 
}; 

function supportsDataUri() { 
    var isOldIE = navigator.appName === "Microsoft Internet Explorer"; 
    var isIE11 = !!navigator.userAgent.match(/Trident\/7\./); 
    return ! (isOldIE || isIE11); //Return true if not any IE 
}; 
+0

quelle version IE? –

+0

IE 11, Windows 7 –

+0

merci @PetrAveryanov, voulez-vous dire que je devrais remplacer l'ensemble du plugin ng-grille CSV, ou seulement les parties qui traitent avec les utilisateurs d'IE? –

Répondre

1

Cela fonctionne pour moi sur Windows 7 IE 11, voir https://stackoverflow.com/a/24417650/1198657

if (window.navigator.msSaveOrOpenBlob) { 
    blobObject = new Blob([csvData]); 
    window.navigator.msSaveOrOpenBlob(blobObject, 'Export.csv'); 
} 
0

j'avais en fait le même problème, mais après avoir regardé dans le code source ui-grille (dans le fichier ui-grid.js), j'ai trouvé que la vérification de la version de IE ne fonctionnait pas correctement

downloadFile: function (fileName, csvContent, exporterOlderExcelCompatibility) { 
     var D = document; 
     var a = D.createElement('a'); 
     var strMimeType = 'application/octet-stream;charset=utf-8'; 
     var rawFile; 
     var ieVersion; 

     //Check if IE9 or below 
     ieVersion = this.isIE(); 
     if (ieVersion && ieVersion < 10) { 
     var frame = D.createElement('iframe'); 
     document.body.appendChild(frame); 

     frame.contentWindow.document.open("text/html", "replace"); 
     frame.contentWindow.document.write('sep=,\r\n' + csvContent); 
     frame.contentWindow.document.close(); 
     frame.contentWindow.focus(); 
     frame.contentWindow.document.execCommand('SaveAs', true, fileName); 

     document.body.removeChild(frame); 
     return true; 
     } 

     // IE10+ 
     if (navigator.msSaveBlob) { 
     return navigator.msSaveOrOpenBlob(
      new Blob(
      [exporterOlderExcelCompatibility ? "\uFEFF" : '', csvContent], 
      { type: strMimeType }), 
      fileName 
     ); 
     } 

Ainsi, le ieVersion rentrait true (qui apparemment JS est inférieure à 10 ...)

Depuis que je cherchais à travailler en 11, j'ai pu commenter cela et il a bien fonctionné! Mais si vous avez besoin de travailler en dessous de 9, vous pouvez changer l'ordre de ces deux fonctions. Le code est correct sur le site ui-grid.info au 06/06/2016