Javascript到Excel:缺乏“范围”方法的糟糕performance

考虑到您只使用Internet Explorer(在大型企业中通常是这种情况),您可以得出结论:您可能会向用户提供将HTML网格视图转换为Excel文件的可能性:此外,您只需考虑必须执行此操作只要用户要求…

从外面写表格(或数组)到Excel的第一个经验是使用Visual Basic(.net的服务器端)。 所以我写了一个类来将VB二维数组分布到一个Excel工作表中:

1)我使用的第一种方法看起来很好,顺便说一下,它非常简单:在一个循环内的行上设置一个循环,并将每个值从VB数组写入Excel工作表。 所以呢:

Dim j, k as Integer Dim Valeur as String 'let us suppose the VB 2D-array is "Tab(10,20)", containing 11 rows of 21 columns of strings 'let us suppose the upper left corner of the Excel range is line 7, column 3: For j = 0 to 10 For k = 0 to 20 Valeur = Tab(j, k) Cells(j + 7, k + 3).Value = valeur Next Next 

2)通过对上述方法进行编程,我最终意识到,虽然它简单而合乎逻辑,但这是一个不好的方法,只是一个原因: 它是很慢的! 所以我find了一个更好的方法,一次写出整个细胞的范围:

  Feuil.Range("C7:W17").Value = Tab 

第一种和第二种方法有什么区别? 那么,这两种方法都可以正常工作,但是如果你考虑一个300行20列(或6000个单元格)的表格,第一种方法所用的时间约为1分钟,而第二种方法只需要半秒钟!

所以,当谈到JavaScript时,我尝试了相同的方法:首先,打开一个Excel-ActiveX对象(当然是MS-IE),它可以访问Excel对象模型参考(http://msdn.microsoft.com/en-us/library/default.aspx)。 com / en-us / library / bb149081(v = office.12).aspx),我可以使用名为'ap'的对象中的CSV堆栈来应用第一种方法。

  // 'ap' is a Javascript object holding a table of CSV strings (natural index: 1..n) var valCell; var lim = ap.nbChamps; // 'nbChamps'= number of csv columns in 'ap' object var curLig = 6; // the datas are written to lines 7 and under for (var j = 1; j <= ap.nbelem; j++) // ap.nbelem= number of lines in 'ap' { // lines loop curLig += 1; for (var k = 1; k <= lim; k++) // NB: 'ap' uses natural index: 1 to n and not 0 to n-1 { // columns loop valCell = ap.litEnLC(j, k); // 'ap' method reading column k from line j classeur.ActiveSheet.Cells(curLig, k + 2 ).value = valCell; } } 

使用了这个方法之后,我又发现了同样的缓慢:所以,我想将第二种方法转换为javascript,如下所示:。 首先,向“ap”对象添加一个方法,将CSV堆栈转换为Javascript 2D数组。 其次,将这个2D数组写入“范围”对象,就像我在Visual Basic中一样。 所以:

  // 'zone' is the range. For example: zone= "C7:W17" var biTab = ap.pcttEnTab(); // converts CSV stack into a 2D-array classeur.ActiveSheet.Range(zone).value = biTab; 

而且,正如所料,这样做的速度要快得多,但问题在于它并不是真正的工作,因为不是将每个2D数组的值传送到Excel范围的相应单元格, 而是将整个Javascript 2D数组写入Excel范围的每个单元格!

所以问题是:如何一次写入一个Excel范围的JavaScript 2D数组?

感谢任何能给我答案的人

顺便说一下,我添加了pcttEnTab方法,以防万一有人可以用这种方法解释我的问题:

 this.pcttEnTab = function () // Array (tableau à 2 dimensions) { // convertit la pile PCTT en tableau à 2 dimensions var j, k, s; var biTab = new Array(); for (k = 0; k < this.nbelem; k++) // create a columns Array for each line { biTab[k] = new Array(); } for (j = 1; j <= this.nbelem; j++) // lines loop (natural index) { for (k = 1; k <= this.nbChamps; k++) // columns loop { s = this.litEnLC(j, k); biTab[j - 1][k - 1] = s; } } return biTab } 

看一下这篇Microsoft有趣的文章,解释ActiveSheet.Range和JavaScript数组之间的一些交互。 他们提到一个“使用SafeArray解决方法”…也许这可以帮助。

您需要将JavaScript数组转换为本地数组。 一种方法是使用Dictionary对象,请参阅http://cwestblog.com/2011/10/24/javascript-snippet-array-prototype-tovbarray

 var dict = new ActiveXObject('Scripting.Dictionary'); for (var i=0;i < 5; i++ ) dict.add(i,i); sheet.cells(1,1).resize(5, 1).value = sheet.application.Transpose(dict.items()); 

如果你写一行,则省略Transpose()