原理:根据Excel VBA的相关知识,对Excel COM组件中的相关对象进行引用,通过属性及方法,提取出转换成表格的相关信息,并通过Excel自身可以保存为HTML的功能分析其代码、属性样式,从而间接地得到生成的HTML。
说明:客户机器需要安装Excel软件才能正常使用。
方法:
1.获取可用数据区域的起始行、列及终止行、列。
也许你会说,我一个个开始循环,然后判断数据是否为空,也就是读到有无数据的临界点。但这样的方法不适应于多个数据区域以及起始的位置存在空的情况。
最简单的方法是使用COM组件的数据区域UsedRange以及适用于UsedRange的Areas集合,每一个Area又相当于是Range对象。对于Range对象可以获取总行数与总列数,Range对象名.Rows.Count与Range对象名.Columns.Count。起始行、列可以通过Range对象的地址来间接获取,我们可以使用Range对象名.Address得到形如“$A$1”或“$B$2:$F$8”这样的地址。前者是表示单一的单元格,后者表示一个区域以左上角与右下角的地址组成。我们可以通过分析这样的地址来得到区域的起始行与起始列,再通过总行数与总列数,知道终止行与列。
function getRow(Address)
{
//$A$5
var lastIndexOfDollar=-1;
var firstIndexOfDollar=-1;
var indexOfComma=-1;
var row;
firstIndexOfDollar=Address.indexOf('$');
lastIndexOfDollar=Address.indexOf('$',firstIndexOfDollar+1);
indexOfComma=Address.indexOf(':');
if(lastIndexOfDollar==firstIndexOfDollar) return 1;
if(indexOfComma>lastIndexOfDollar+1) row=parseInt(Address.substring(lastIndexOfDollar+1,indexOfComma));
else row=parseInt(Address.substring(lastIndexOfDollar+1));
if(isNaN(row)) return 1;
return row;
}
function getColumn(Address)
{
//$A$5
var lastIndexOfDollar=-1;
var firstIndexOfDollar=-1;
var columnMark="";
var column=0;
firstIndexOfDollar=Address.indexOf('$');
lastIndexOfDollar=Address.indexOf('$',firstIndexOfDollar+1);
if(lastIndexOfDollar==firstIndexOfDollar) return 1;
columnMark=Address.substring(1,lastIndexOfDollar).toUpperCase();
if(columnMark.length>2) return 1;
for(var index=0;index<columnMark.length;index++)
{
column=column*26+columnMark.charCodeAt(index)-64;
}
return column;
}
2.合并单元格区域的判断
我们通过上面的起始行、列与终止行、列,假设起始行、列分别为basicRow、basicColumn,终止行、列分别为endRow,endColumn。
使用循环方式得到的区域(xlsWorkBook为工作簿),通过MergeArea得到地址,如果为区域引用($..$..:$..$..)则与直接通过行列映射的地址不同。然后根据区域的行数与列数知道合并了多少行、多少列。对于列,获取数据后可以跳过合并的列数减1(for循环步长为1)。对于行,通过得到其上方单元格的地址,如果获取的地址与当前相同,说明仍然在同一合并单元格内,可跳过本次循环,进行该行其他列的读取操作。
var RangeArea=getMark(rowIndex,columnIndex);//getMark用于获取区域引用的地址
var MergeArea=xlsWorkBook.WorkSheets(sheetIndex).Range(RangeArea).MergeArea;
if(MergeArea.Address==getAddress(rowIndex,columnIndex))
{
//当前单元格为单一单元格
}
else
{
//当前单元格为拆分单元格
var mergeRowCount=MergeArea.Rows.Count;
var mergeColumnsCount=MergeArea.Columns.Count;
if(mergeRowCount>1&&rowIndex>1)
{
var upMergeArea=xlsWorkBook.WorkSheets(sheetIndex).Range(getMark(rowIndex-1,columnIndex)).MergeArea;
if(upMergeArea.Address==MergeArea.Address) continue;
}
if(mergeColumnsCount>1) columnIndex+=mergeColumnsCount-1;
}
/*根据Excel行、列,返回区域标记*/
function getMark(column,row)
{
//A...Z AA...AZ
if(row<=26)
{
return String.fromCharCode(64+row)+column.toString();
}
return String.fromCharCode(64+row/26)+String.fromCharCode(64+row%26)+column.toString();
}
/*根据Excel行、列,返回引用地址*/
function getAddress(column,row)
{
//A...Z AA...AZ
if(row<=26)
{
return "$"+String.fromCharCode(64+row)+"$"+column.toString();
}
return "$"+String.fromCharCode(64+row/26)+String.fromCharCode(64+row%26)+"$"+column.toString();
}
function getRow(Address)
{
//$A$5
var lastIndexOfDollar=-1;
var firstIndexOfDollar=-1;
var indexOfComma=-1;
var row;
firstIndexOfDollar=Address.indexOf('$');
lastIndexOfDollar=Address.indexOf('$',firstIndexOfDollar+1);
indexOfComma=Address.indexOf(':');
if(lastIndexOfDollar==firstIndexOfDollar) return 1;
if(indexOfComma>lastIndexOfDollar+1) row=parseInt(Address.substring(lastIndexOfDollar+1,indexOfComma));
else row=parseInt(Address.substring(lastIndexOfDollar+1));
if(isNaN(row)) return 1;
return row;
}
3.相关属性
名称 | VBA对应属性方法 | 对应CSS样式或标签属性 |
字体大小 | expression.Font.Size | font-size:..pt; |
字体斜体 | expression.Font.Italic | font-style:italic; |
字体粗体 | expression.Font.Bold | font-weight:700; |
字体下划线 | expression.Font.Underline | text-decoration:underline; text-underline-style:single; |
单元格背景色 | expression.Interior.ColorIndex | background:RGB颜色值 |
上边框颜色 | expression.Borders(xlEdgeTop).ColorIndex | border-top:.5pt solid RGB值; |
左边框颜色 | expression.Borders(xlEdgeLeft).ColorIndex | border-left:.5pt solid RGB值; |
右边框颜色 | expression.Borders(xlEdgeRight).ColorIndex | border-right:.5pt solid RGB值; |
下边框颜色 | expression.Borders(xlEdgeBottom).ColorIndex | border-bottom:.5pt solid RGB值; |
水平对齐 | expression.HorizontalAlignment | align=left right center |
垂直对齐 | expression.VerticalAlignment | valign=top middle bottom |
单元格宽度 | expression.Width | width:…pt |
单元格高度 | expression.Height | height:…pt |
自动换行 | expression.WrapText | <TD nowrap>(如果为True) |
4.相关常量
/*水平对齐方式*/
var xlLeft = -4131;
var xlRight = -4152;
var xlCenter = -4108;
var xlBottom = -4107 ;
var xlTop = -4160;
/*垂直对齐方式*/
var xlVAlignBottom = -4107;
var xlVAlignCenter = -4108;
var xlVAlignTop = -4160;
/*字体样式*/
var isBold=false;
var isItalic=false;
var isWrap=false;
/*下划线*/
var xlUnderlineStyleNone = -4142;
var xlUnderlineStyleSingle = 2;
var xlUnderlineStyleSingleAccounting = 4;
var xlUnderlineStyleDouble = -4119 ;
var xlUnderlineStyleDoubleAccounting = 5;
/*边框*/
var xlEdgeTop = 8;
var xlEdgeLeft = 7;
var xlEdgeRight = 10;
var xlEdgeBottom = 9;