考虑到您只使用Internet Explorer(在大型企业中通常是这样),您得出的结论是,您可以为用户提供将HTML网格视图转换为Excel文件的可能性:此外,您只需考虑到,只要用户要求,您就必须这样做…
我第一次从外部将表(或数组)写入Excel是使用Visual Basic(.net的服务器端)
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) 在编程了上面的方法后,我最终意识到,尽管它简单而合乎逻辑,但它是一个糟糕的方法,原因只有一个:它非常慢所以我找到了一个更好的方法,包括一次写入整个单元格范围:
Feuil.Range("C7:W17").Value = Tab
第一种方法和第二种方法有什么区别?好吧,这两种方法都能正常工作,但如果你考虑一个由300行20列(或6000个单元格)组成的表,第一种方法所需的时间大约为1分钟,而第二种方法只需半秒!
因此,当谈到JavaScript时,我尝试了同样的方法:首先,打开一个Excel ActiveX对象(当然是在MS-IE中),它可以访问Excel对象模型引用(http://msdn.microsoft.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++) // N.B: '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数组写入"range"对象中,就像我在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范围的相应单元格,而是在Excel范围的每个单元格中写入整个Javascript 2D数组
所以问题是:如何一次将Javascript 2D数组写入Excel范围?
感谢任何能给我答案的人。。。
顺便说一句,我添加了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
}
您需要将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()。
看看微软的这篇有趣的文章,它解释了ActiveSheet.Range
和JavaScript数组之间的一些交互。他们提到了"使用SafeArray
的解决方法"。。。也许这会有所帮助。