alasql dışa aktarılan excel formülü çalışmıyor

Dec 23 2020

Html sayfamda, excel dosyasını oluşturmak ve indirmek için aşağıdaki kodu kullanıyorum. Bu dinamik dosyayı birçok formülle oluşturuyorum.

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');

Bu kod, excel oluşturmak için sorunsuz çalışıyor. Fakat C1 hücresi için excel içeriğini açtığımda = A1 + B1 Eğer üzerine enter tuşuna basarsam değeri değerlendirecektir. Bu değerleri tüm hücreler için değerlendirmek istiyorum. lütfen rehberlik eder misiniz excel'de veya alasql API'de bir şeyi değiştirmem gerekir mi?

Yanıtlar

1 RobinMackenzie Dec 23 2020 at 20:12

İçin:

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

Denetleme veri türlerini alasql gibi, için bir şey yok xlfunctionbu yüzden stringsütun için en iyi bahistir c.

Bu nedenle, sorun, Excel çalışma kitabı oluşturmak için xlsx adlı bir kitaplığı kullanan alasql'ın kendi içinde olmalıdır. PreparSheet işlevinde buraya bakın :

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++;
}

Hücrenin formül olarak işaretlenmesi gerekip gerekmediğini kontrol edecek hiçbir şey yoktur ve yalnızca sayıları, dizeleri, boole'ları ve tarihleri ​​dikkate alır (veri türleri belgeleriyle makul ölçüde tutarlıdır).

XLSX kitaplığında, bir hücreyi formül olarak işaretlemek kolaydır . Böylece bunu alasql koduna uygulayabiliriz, örneğin

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++;
}

Değer bir dizeyse ve ile başlıyorsa, =XLSX'e Excel'in bunun bir formül olduğunu bildiği bir şekilde çıktı vermesini söyleyin (ve kesip atın =). Aksi takdirde, alasql'in halihazırda yaptığını yapın. Bu arada bu test edilmemiş, kötü uygulanmış bir hack - ama IMHO sorunuzun cevabı.

Bunu alasql.fs.jsnode_modules'deki dosyaya kırarsanız, orijinal kodunuz beklediğiniz gibi çalışacaktır.

Alasql projesinde bu konuyu gündeme getirme özgürlüğünü aldım.