alasql exportierte Excel-Formel funktioniert nicht

Dec 23 2020

Auf meiner HTML-Seite verwende ich den folgenden Code, um eine Excel-Datei zu erstellen und herunterzuladen. Ich erstelle diese dynamische Datei mit vielen Formeln.

let db = new alasql.Database('TEMPDB');
db.exec('create table tempexcel(A string,B string, c string)');
db.exec('insert into tempexcel("5","6","=A1+B1")');
db.exec('select * INTO XLSX("tempex.xlsx",{headers:false})  from tempexcel');

Dieser Code funktioniert gut, um Excel zu generieren. Wenn ich jedoch den Excel-Inhalt für die C1-Zelle öffne, ist = A1 + B1. Wenn ich die Eingabetaste drücke, wird der Wert ausgewertet. Ich möchte diese Werte für alle Zellen auswerten. Kannst du bitte eine Anleitung geben, ob ich etwas in Excel oder in der Alasql-API ändern muss?

Antworten

1 RobinMackenzie Dec 23 2020 at 20:12

Zum:

db.exec('create table tempexcel(A string,B string, c string)');

Überprüfen Sie die Datentypen für alasql gibt es nichts für zB xlfunctionso stringist die beste Wahl für die Spalte c.

Das Problem muss also in alasql selbst liegen, das eine Bibliothek namens xlsx für die Erstellung von Excel-Arbeitsmappen nutzt. Siehe hier in der prepareSheet-Funktion :

for (var j = 0; j < dataLength; j++) {
    columns.forEach(function(col, idx) {
        var cell = {v: data[j][col.columnid]};
        if (typeof data[j][col.columnid] == 'number') {
            cell.t = 'n';
        } else if (typeof data[j][col.columnid] == 'string') {
            cell.t = 's';
        } else if (typeof data[j][col.columnid] == 'boolean') {
            cell.t = 'b';
        } else if (typeof data[j][col.columnid] == 'object') {
            if (data[j][col.columnid] instanceof Date) {
                cell.t = 'd';
            }
        }
        cells[alasql.utils.xlsnc(col0 + idx) + '' + i] = cell;
    });
    i++;
}

Es gibt nichts zu überprüfen, ob die Zelle als Formel gekennzeichnet werden soll und nur Zahlen, Zeichenfolgen, Boolesche Werte und Datumsangaben berücksichtigt (einigermaßen konsistent mit der Dokumentation der Datentypen).

In der XLSX-Bibliothek ist es einfach, eine Zelle als Formel zu kennzeichnen . Wir können das also auf den Alasql-Code anwenden, z

for (var j = 0; j < dataLength; j++) {
    columns.forEach(function (col, idx) {
        var isFormula = false; 
        var d = data[j][col.columnid];
        var cell;
        if (typeof d == 'string') {
            isFormula = d.substr(0, 1) == '=';
        }
        if (!isFormula) {
            cell = {v: data[j][col.columnid]};
            if (typeof data[j][col.columnid] == 'number') {
                cell.t = 'n';
            } else if (typeof data[j][col.columnid] == 'string') {
                cell.t = 's';
            } else if (typeof data[j][col.columnid] == 'boolean') {
                cell.t = 'b';
            } else if (typeof data[j][col.columnid] == 'object') {
                if (data[j][col.columnid] instanceof Date) {
                    cell.t = 'd';
                }
            }   
        } else {
            cell = {f: d.substr(1, d.length - 1)};
        }           
        cells[alasql.utils.xlsnc(col0 + idx) + '' + i] = cell;
    });
    i++;
}

Wenn der Wert eine Zeichenfolge ist und mit beginnt, =teilen Sie XLSX mit, dass die Ausgabe so erfolgen soll, dass Excel weiß, dass es sich um eine Formel handelt (und entfernen Sie die =). Ansonsten machen Sie einfach das, was alasql bereits macht. Das ist übrigens ein ungetesteter, schlecht implementierter Hack - aber meiner Meinung nach die Antwort auf Ihre Frage.

Wenn Sie das in die alasql.fs.jsDatei in node_modules hacken, funktioniert Ihr ursprünglicher Code genau so, wie Sie es erwarten.

Ich habe mir erlaubt, im alasql-Projekt ein Thema darüber anzusprechen.