2016-07-06 10 views
0

Ich habe ein Problem beim Versuch, eine HTML-Zeichenfolge in CSV-Format zu konvertieren, so dass ich dann ein neues CSV-Blob-Objekt erstellen und öffnen Sie das von einer Webseite in IE & Edge.Konvertieren einer HTML-Zeichenfolge in CSV-Format mit JavaScript

Ich habe eine Funktion gefunden, um ein Tabellenobjekt in das CSV-Format zu konvertieren, aber leider muss ich eine Zeichenfolge übergeben, nicht das Objekt. Hier

ist das Tabellenobjekt zu csv-Methode:

function (table) { 

       var slice = Array.prototype.slice; 

       return slice.call(table.rows).map(function (row) { 
        return slice.call(row.cells).map(function (cell) { 
         return '"t"'.replace("t", cell.textContent); 
        }).join(","); 
       }).join("\r\n"); 

      } 

Das Problem ist das, was ich will im csv angezeigt werden muss, bevor die Anzeige formatiert werden. Wenn ich also nur das Tabellenobjekt nehme, wie es auf der Seite erscheint, wird der CSV viel mehr Daten enthalten als benötigt. Wenn auf die Schaltfläche zum Exportieren geklickt wird, habe ich eine Methode, die die Tabelle formatiert und eine HTML-Zeichenfolge der Tabelle zurückgibt, die als CSV angezeigt werden soll. Aber ich weiß nicht, wie man diese Zeichenfolge in CSV-Format konvertiert und finde kein Beispiel dafür.

> Bearbeiten 1

HTML-String, der als csv in Chrome/Firefox gerendert wird

<table id='excel_tbl'><tr><td>Name</td><td>Time allowed</td><td>Best score</td><td>Attempts</td></tr><tr><td> 
            <a class="ng-binding" id="assess_inst_fdd4ddec-9985-4def-9148-b5cd56ee77e6_875650db-4934-40dc-9e30-81c57c3472de" href="#" ng-click="itShowStudent(oPerson.PersonKey, oPerson.RefName)">Michelle27, Michelle27</a> 
           </td><td> 
            <div class="ng-hide" aria-hidden="true" ng-show="oPerson.MaxMins >= 0.0"> 
             <it-time class="it-time ng-isolate-scope" seconds="-60" precise="true"><div class="time-info-text"><!-- ngIf: seconds < 60 && bPrecise --><div class="ng-scope" ng-if="seconds < 60 &amp;&amp; bPrecise"><span class="large ng-binding">0</span><!-- ngIf: itGetSeconds(seconds) == 1 --><!-- ngIf: itGetSeconds(seconds) != 1 --><span class="small ng-binding ng-scope" ng-if="itGetSeconds(seconds) != 1">secs</span><!-- end ngIf: itGetSeconds(seconds) != 1 --></div><!-- end ngIf: seconds < 60 && bPrecise --><!-- ngIf: seconds == 0 && !bPrecise && bUseNone --><!-- ngIf: seconds == 0 && !bPrecise && !bUseNone --><!-- ngIf: seconds > 0 && seconds < 60 && !bPrecise --><!-- ngIf: seconds >= 60 --></div></it-time> 
            </div> 
           </td><td> 
            <div class="ng-binding" aria-hidden="false" ng-show="oPerson.BestScore >= 0.0"> 
             33% 
            </div> 
           </td><td> 
            <div class="ng-binding" aria-hidden="false" ng-show="oPerson.Attempts > 0"> 
             1 
            </div> 
           </td></tr><tr><td> 
            <a class="ng-binding" id="assess_inst_f588c82b-7eef-422c-8125-e8d8118ed549_875650db-4934-40dc-9e30-81c57c3472de" href="#" ng-click="itShowStudent(oPerson.PersonKey, oPerson.RefName)">[email protected], [email protected]</a> 
           </td><td> 
            <div class="ng-hide" aria-hidden="true" ng-show="oPerson.MaxMins >= 0.0"> 
             <it-time class="it-time ng-isolate-scope" seconds="-60" precise="true"><div class="time-info-text"><!-- ngIf: seconds < 60 && bPrecise --><div class="ng-scope" ng-if="seconds < 60 &amp;&amp; bPrecise"><span class="large ng-binding">0</span><!-- ngIf: itGetSeconds(seconds) == 1 --><!-- ngIf: itGetSeconds(seconds) != 1 --><span class="small ng-binding ng-scope" ng-if="itGetSeconds(seconds) != 1">secs</span><!-- end ngIf: itGetSeconds(seconds) != 1 --></div><!-- end ngIf: seconds < 60 && bPrecise --><!-- ngIf: seconds == 0 && !bPrecise && bUseNone --><!-- ngIf: seconds == 0 && !bPrecise && !bUseNone --><!-- ngIf: seconds > 0 && seconds < 60 && !bPrecise --><!-- ngIf: seconds >= 60 --></div></it-time> 
            </div> 
           </td><td> 
            <div class="ng-binding" aria-hidden="false" ng-show="oPerson.BestScore >= 0.0"> 
             100% 
            </div> 
           </td><td> 
            <div class="ng-binding" aria-hidden="false" ng-show="oPerson.Attempts > 0"> 
             18 
            </div> 
           </td></tr><tr><td> 
            <a class="ng-binding" id="assess_inst_a820d6e4-1e68-4265-9580-f053cf09cb11_875650db-4934-40dc-9e30-81c57c3472de" href="#" ng-click="itShowStudent(oPerson.PersonKey, oPerson.RefName)">Michelle35, Michelle35</a> 
           </td><td> 
            <div class="ng-hide" aria-hidden="true" ng-show="oPerson.MaxMins >= 0.0"> 
             <it-time class="it-time ng-isolate-scope" seconds="-60" precise="true"><div class="time-info-text"><!-- ngIf: seconds < 60 && bPrecise --><div class="ng-scope" ng-if="seconds < 60 &amp;&amp; bPrecise"><span class="large ng-binding">0</span><!-- ngIf: itGetSeconds(seconds) == 1 --><!-- ngIf: itGetSeconds(seconds) != 1 --><span class="small ng-binding ng-scope" ng-if="itGetSeconds(seconds) != 1">secs</span><!-- end ngIf: itGetSeconds(seconds) != 1 --></div><!-- end ngIf: seconds < 60 && bPrecise --><!-- ngIf: seconds == 0 && !bPrecise && bUseNone --><!-- ngIf: seconds == 0 && !bPrecise && !bUseNone --><!-- ngIf: seconds > 0 && seconds < 60 && !bPrecise --><!-- ngIf: seconds >= 60 --></div></it-time> 
            </div> 
           </td><td> 
            <div class="ng-binding" aria-hidden="false" ng-show="oPerson.BestScore >= 0.0"> 
             100% 
            </div> 
           </td><td> 
            <div class="ng-binding" aria-hidden="false" ng-show="oPerson.Attempts > 0"> 
             4 
            </div> 
           </td></tr></table> 

Die obige Zeichenfolge geben wird

document.open("txt/html", "replace"); 
        iframe.document.write(sHTML); 

wenn Chrome/Firefox und gerendert wie folgt:

enter image description here

Ich kann document.open nicht mit Edge arbeiten, also verwende ich den Blob-Ansatz.

var csv = $scope.tbl2csv(oTable[0]); 
        // Create a CSV Blob 
        var blob = new Blob([ csv ], { type: "text/csv"}); 


        if (navigator.msSaveOrOpenBlob) { 
         // Works for Internet Explorer and Microsoft Edge 
         navigator.msSaveOrOpenBlob(blob, "Assessment.csv"); 
        } 

Dieser Rand arbeitet, wie der Export der Tabelle csv Öffnung in Excel erforderlich, das Problem ist, dass das Objekt Tabelle im CSV-Format konvertiert wird nicht das gleiche wie die HTML-Zeichenfolge, die von Chrome gemacht wird/Feuerfuchs. Also meine Anforderung ist es, eine Möglichkeit zu finden, diese Zeichenfolge in das CSV-Format zu konvertieren.

+0

Die einzige korrekte Möglichkeit, HTML zu behandeln, besteht darin, es an einen HTML-Parser zu senden. Du weißt, was du von dort machen kannst. –

+0

Und nein, das ist kein CSV-Generator, obwohl es die meiste Zeit gültige CSV erzeugt. –

+0

@ JanDvorak thk für die Antwort. Leider habe ich keine Ahnung, was ich tun soll, um meine HTML-Zeichenfolge (welche die Tabelle ist, die ich als CSV anzeigen möchte) in das CSV-Format zu bekommen. Irgendwelche Vorschläge sehr geschätzt. –

Antwort

0

Nun, ich habe eine Lösung (nicht perfekt, mit allen Mitteln), die funktioniert. Ich habe die Tabelle, die ich in csv konvertieren muss, zur html-Seite hinzugefügt, mit einer Anzeige von "none". Auf diese Weise steht es bei Bedarf der tbl2csv-Methode zur Verfügung. Diese Methode verwendet ein einfaches HTML-Tabellenobjekt als Eingabe und konvertiert es in das CSV-Format.

function (table) { 

      var slice = Array.prototype.slice; 

      return slice.call(table.rows).map(function (row) { 
        return slice.call(row.cells).map(function (cell) { 
         return '"t"'.replace("t", cell.textContent); 
        }).join(","); 
       }).join("\r\n"); 

      } 

Hier ist der clientseitigen Aufruf der obigen Methode:

if (edge >= 0) { 

        var oTbl = document.querySelector("#edge_excel_tbl"); 
        var csv = $scope.tbl2csv(oTbl); 
        // Create a CSV Blob 
        var blob = new Blob([ csv ], { type: "text/csv"}); 

        // Determine which approach to take for the download 
        if (navigator.msSaveOrOpenBlob) { 
         // Works for Internet Explorer and Microsoft Edge 

         //Get Assessment File Name 
         navigator.msSaveOrOpenBlob(blob, "Assessment.csv"); 
        } 

Hier ist der HTML ich selbst zu der Seite hinzugefügt.

    <table id="edge_excel_tbl" style="display: none;" > 
         <thead> 
          <tr> 
           <!--<td></td>--> 
           <td>{{itGetString("instructor", "People_Name", "Name")}}</td> 
           <td>{{itGetString("instructor", "Assess_TimeAvail", "Time allowed")}}</td> 
           <td>{{itGetString("instructor", "Assess_BestScore", "Best score")}}</td> 
           <td>{{itGetString("instructor", "Assess_Attempts", "Attempts")}}</td> 
          </tr> 
         </thead> 
         <tbody> 
          <tr ng-repeat="oPerson in itGetGroupAssessmentDetails().Done"> 
           <td>{{oPerson.RefName}}</td> 
           <td><it-time class="it-time" precise="true" seconds="{{oPerson.MaxMins * 60.0}}"></it-time></td> 
           <td>{{itGetRoundedScore(oPerson.BestScore)}}%</td> 
           <td>{{oPerson.Attempts}}</td> 
         </tbody> 
        </table> 

        <!-- End of Edge Table for Excel Export --> 

Es ist nicht die flexibelste Ansatz, aber es funktioniert in Rand im Hinblick auf eine CSV-doc liefern (in Excel in diesem Fall geöffnet), die für alle anderen Browsern übereinstimmt. Die andere Alternative bestand darin, eine tbl2csv-Methode zu schreiben, die eine HTML-Zeichenfolge als Eingabe verwendete und diese in csv formatierte. Das wäre viel komplexer und zeitaufwendiger gewesen.

Verwandte Themen