资源描述
javascript导出excel.docx
《javascript导出excel.docx》由会员分享,可在线阅读,更多相关《javascript导出excel.docx(9页珍藏版)》请在冰豆网上搜索。
javascript导出excel
所见即所得的Excel报表生成
(二)——从Htmltable到ExcelCell
时间:
2011-06-1420:
42来源:
未知作者:
admin点击:
104次
在上一篇文章中,已经解决了如何获取htmltable结构的问题。
在本篇文章中,我们着力于table结构的解析。
Htmltable的结构我们大家都很熟悉,那么在另一端如何构造一个结构,让Excel可以很好的接受和处理呢?
直观的看,一个完整Excel的内容是由位于各个单元
在上一篇文章中,已经解决了如何获取htmltable结构的问题。
在本篇文章中,我们着力于table结构的解析。
Htmltable的结构我们大家都很熟悉,那么在另一端如何构造一个结构,让Excel可以很好的接受和处理呢?
直观的看,一个完整Excel的内容是由位于各个单元格(Cell)中的内容组合而成的。
而每个单元格(Cell)都有相应X、Y坐标来标示其位置。
也就是说,一个Excel文件实质上就是许多Cell构成的集合,每个Cell用坐标属性确定位置,用内容属性存储内容。
基于此,我设计了最基本的Cell结构:
◆X坐标
◆Y坐标
◆合并列情况
◆合并行情况
◆内容
构成Excel的最基本的结构已经确定,下一步摆在我们面前的就是将htmltable转化为ExcelCell集合。
Htmltable中的每个td节点对应一个Excel单元格,其内容不必说,行、列的合并情况也自可由td的rowspan、colspan属性得出,转化的关键点就在于由table的trtd结构定位Excel单元格位置,即X、Y坐标。
Y坐标容易确定,即td所在tr的行数。
至于一td的X坐标,其要受到两方面因素的影响:
与该td同处一tr,但位于其之前(反映在表格视觉上即其左侧td)td的占位情况和该td所在tr的之前tr中某些td的跨行情况。
基于此种考虑,定位td的X坐标需经过两个过程的推导:
用于处理左侧td占位影响的横向推导(HorizontalDeduction)和处理之前行跨行td影响的纵向推导(VerticalDeduction)。
以下图所示table为例,展示两次推导过程。
横向推导(HorizontalDeduction)
一次横向推导(HorizontalDeduction)限定在一tr范围内。
整个过程基于递归的原理,递归模型如下:
核心代码为:
1 privateintHorizontalDeduction(HtmlNodephnTd)
2 {
3 HtmlNodehnPreviousSibling=phnTd.PreviousSibling;
4 while(hnPreviousSibling!
=null&&hnPreviousSibling.Name!
=phnTd.Name)
5 {
6 hnPreviousSibling=hnPreviousSibling.PreviousSibling;
7 }
8
9 if(hnPreviousSibling!
=null)
10 {
11 intnColSpan=hnPreviousSibling.GetAttributeValue("colspan",1);
12 returnHorizontalDeduction(hnPreviousSibling)+nColSpan;
13 }
14
15 return0;
16 }
经过横向推导,各td的X、Y坐标如下图所示:
纵向推导(VerticalDeduction)
一次纵向推导的过程可以描述为(当前推导td用A表示):
找到A之前的行tr中与A具有相同X坐标的td节点B
if(B.rowspan>(A.Y-B.Y))
{
X+=B.colspan,即A的X坐标向后推B.colspan的位置
同时,与A同处一tr但在其后边的td节点均应向后推B.colspan个位移
}
对td节点A反复执行这样的一个过程,直到确定A无需再次移动。
纵向推导核心代码为:
1boolbActedPush=false;
2
3do
4{
5 intnComparedItemIndex=-1;
6 for(intj=i-1;j>=0;j--)
7 {
8 if(plstCells[j]._nStartX==oCurrentCell._nStartX)
9 {
10 nComparedItemIndex=j;
11 break;
12 }
13 }
14
15 if(nComparedItemIndex>=0)
16 {
17 if(plstCells[nComparedItemIndex]._nRowSpan>(oCurrentCell._nStartY-plstCells[nComparedItemIndex]._nStartY))
18 {
19 oCurrentCell._nStartX+=plstCells[nComparedItemIndex]._nColSpan;
20
21 bActedPush=true;
22
23 for(intk=i+1;k24 {
25 if(plstCells[k]._nStartY==oCurrentCell._nStartY)
26 {
27 plstCells[k]._nStartX+=plstCells[nComparedItemIndex]._nColSpan;
28 }
29 }
30 }
31 else
32 {
33 bActedPush=false;
34 }
35 }
36 else
37 {
38 bActedPush=false;
39 }
40 }
41 while(bActedPush);
以示例table中的fourtd为例,其经过纵向推导过程后的坐标位置情况如下图:
关于示例代码的几点说明:
1、在示例代码中,我通过一个Config文件对生成的Excel的文件名、其内报表的内容和位置做了一些控制。
基本内容如下:
SampleExcelFile
--生成Excel的文件名-->
1
--Excel中sheet的数量-->
示例表一
--报表名称-->
1
--所在sheet的序号-->
2
--左上角X坐标-->
2
--左上角Y坐标-->
--table所在页面-->
2、在解析html的过程中,我使用了HtmlAgilityPack解析工具。
感兴趣的朋友可以研究一下。
地址是这里:
3、HtmlAgilityPack解析html的过程中,其将html标签之间的空隙也会看成是一个节点,为内容为空字符串的文本节点,这点大家应注意。
4、该示例代码基本上是一个完整的功能,并且和系统中其他模块耦合度很小。
有类似需求的朋友可以拿来直接用。
javascript导出excel(应用)
2008-03-1915:
16:
40| 分类:
雨天の技术| 标签:
|字号大中小 订阅
--TABLE中的内容是JAVASCRIPT自动生成的-->
functiontableToExcel(){
varrowNum=0;
varoXL=newActiveXObject("Excel.Application");//创建应该对象
varoWB=oXL.Workbooks.Add();//新建一个Excel工作簿
varoSheet=oWB.ActiveSheet;//指定要写入内容的工作表为活动工作表
// vartable=pageId;
// varrows=table.rows.length;
// varcolSumCols=table.rows(0).cells.length;
varbeginCol=0;
// varcols=colSumCols;
varrowSpans=1; //行合并
varcolSpans=1; //列合并
oXL.visible=true;
oWB.Worksheets
(1).Range("B4:
D4:
F4").ColumnWidth=20;
/**********表头**********************/
varexcRange=oSheet.Range(oSheet.Cells(1,1),oSheet.Cells(1,6));
excRange.Merge(true);
//获取型号等信息
varexcelName="<%=session.getAttribute("excel")%>";
excelName=chkrecName+"-"+excelName+"-技术参数";
excRange.value=excelName;
excRange.HorizontalAlignment=3;//'居中
excRange.Font.Name="黑体";
rowNum=rowNum+1;
/****************结束结果设置******************/
varobj1=document.getElementById('techTable');
rowNum=resultToExcel(rowNum,obj1,oSheet,"");
rowNum=rowNum+2;
//增加提示,不可以编辑EXCEL的批注
varexcRange2=oSheet.Range(oSheet.Cells(2,1),oSheet.Cells(2,6));
excRange2.Merge(true);
excRange2.value="提示:
务必不要编辑下面单元格中批注的内容!
否则将无法实现导入!
!
!
";
excRange2.HorizontalAlignment=2;
excRange2.Font.Name="宋体";
excRange2.Font.Size=10;
try{
oWB.SaveAs("c:
\\"+excelName+".xls");
oWB.Close;
oXL.visible=false;
oXL.Quit();
alert("文件保存成功!
已保存到C:
\\"+excelName+".xls");
}catch(e){
alert("文件保存失败!
");
}
}
functionresultToExcel(rowNum,obj,oSheet,tableTile){
if(obj==null){
returnrowNum;
}
varrows=obj.rows.length;
varcolSumCols=obj.rows(0).cells.length;
varbeginCol=0;
varcols=colSumCols;
varrowSpans=1; //行合并
varcolSpans=1; //列合并
excRange=oSheet.Range(oSheet.Cells(rowNum+1,1),oSheet.Cells(rowNum+1,colSumCols));
excRange.Merge(true);
excRange.value=tableTile;
excRange.HorizontalAlignment=3;
excRange.Font.Name="黑体";
rowNum=rowNum+1;
//寻找列数,考虑到第一行可能存在合并
for(vari=0;i vartmpcolspan=obj.rows(0).cells(i).colSpan;
if(tmpcolspan>1){
cols+=tmpcolspan-1;
}
}
//定义2维容器数据,1:
行;2:
列;值(0可以填充,1已被填充)
varcontainer=newArray(rows);
for(vari=0;i container[i]=newArray(cols);
for(j=0;j container[i][j]=0;
}
}
//将所有单元置为文本,避免非数字列被自动变成科学计数法和丢失前缀的0
oSheet.Range(oSheet.Cells(rowNum+1,1),oSheet.Cells(rowNum+rows,cols)).NumberFormat="@";
//Addobjheadersgoingcellbycell.
//varstr="";
for(i=0;i for(j=0;j //寻找开始列
for(k=j;k if(container[i][k]==0){
beginCol=k;
k=cols;//退出循环
}
}
//赋值
try{
varisHtml=obj.rows(i).cells(j).innerHTML;
varinnerText=obj.rows(i).cells(j).innerText;
//判断是否是文本框
if(isHtml.indexOf("
oSheet.Cells(i+1+rowNum,beginCol+1).value=innerText;
}else{
//str=str+"Names:
:
"+obj.rows(i).cells(j).getElementsByTagName("input")[2].name+"\n";
oSheet.Cells(i+1+rowNum,beginCol+1).AddComment(obj.rows(i).cells(j).getElementsByTagName("input")[1].id);
}
//oSheet.Cells(i+1+rowNum,beginCol+1).value=obj.rows(i).cells(j).innerText;
colSpans=obj.rows(i).cells(j).colSpan;
if(colSpans>1){
//合并
oSheet.Range(oSheet.Cells(i+1+rowNum,beginCol+1),oSheet.Cells(i+1+rowNum,beginCol+colSpans)).Merge();
}
//将当前obj位置填写到对应的容器中
for(k=0;k container[i][beginCol+k]=1;
}
rowSpans=obj.rows(i).cells(j).rowSpan;
if(rowSpans>1){//行合并
oSheet.Range(oSheet.Cells(i+1+rowNum,beginCol+1),oSheet.Cells(i+rowSpans+rowNum,beginCol+colSpans)).Merge();
//将当前obj位置填写到对应的容器中
for(k=1;k for(l=0;l container[i+k][beginCol+l]=1;
}
}
}
//如果开始列+合并列已经等于列数了,故不需要再循环htmltable
if(beginCol+colSpans>=cols)j=cols;
}catch(e){
}
}
}
//字符大小为9
oSheet.Range(oSheet.Cells(rowNum+1,1),oSheet.Cells(rowNum+rows,cols)).Font.Size=9;
//自动调整列宽
oSheet.Range(oSheet.Cells(1,1),oSheet.Cells(rowNum+rows,cols)).Columns.AutoFit();
//自动调整行高
oSheet.Range(oSheet.Cells(rowNum+1,1),oSheet.Cells(rowNum+rows,cols)).Rows.AutoFit();
//划边框
oSheet.Range(oSheet.Cells(rowNum+1,1),oSheet.Cells(rowNum+rows,cols)).Borders.LineStyle=1;
rowNum=rowNum+rows;
returnrowNum;
}
functionreadExcel()
{