利用XSL将DataSet数据转换为Excel文档

本文介绍了一种在ASP.NET项目中利用XSL转换将包含复杂格式的DataSet数据快速生成Excel文档的方法。通过创建XML模板,设置样式和公式,实现了包括锁定表头、小计和合计在内的功能。内容涵盖了XSL转换的基础知识,以及如何处理动态公式以适应不同数据量的场景。
摘要由CSDN通过智能技术生成

最近在一个ASP.NET项目的开发中有一个模块需要采用OWC控件呈现Excel样式的表格内容,表格内容比较复杂,包括锁定表头、公式、小计、合计、排序等。

以前采用客户端操作OWC实例一个单元格一个单元格的去写,那麻烦程度可想而知,于是便尝试采用新方法,利用XSL转换实现需要的功能。

经过几天一穷二白为基础的学习和摸索,总结出一点心得,还有一点疑问和未处理的问题,放在园子里,如果总结的有什么不正确的地方,还望大家指出。

我采用这种方法前,首先确认了一些限制条件的满足:

1、 在项目中可以统一使用MS Office 2003版本的OWC控件

2、 我们的客户都在使用MS Office 2003,这样这种做法也可以作为直接生成客户端Excel文档的方法

我的目标格式为以下Excel文档(部分):

 



这个表的特点是:

1、 列数固定

2、 表头锁定

3、 每个部门的费用明细数量不定

4、 小计统计各个部门所属的费用金额之和

5、 合计统计所有部门所有费用的总金额

6、 小计和合计应该设为公式,这样在修改费用明细的时候,小计和合计可以即时反映变化

首先,需要在Excel里面做好一个模板,然后另存为“XML电子表格”,模板内容如下:

 



这个模板包含了几乎所有需要的元素,包括单元格锁定、各种外观样式、行级别的公式设定(比如J4=I4-H4)、一行明细、一行小计、一行合计等一切可以在“设计时”确定的内容。

通过分析这个模板,我们观察到,完成这个模板的数据填充需要进行2层循环:

l 外层循环:需要针对每个部门进行循环,在循环之内填充每个部门的费用明细,并且为每个部门的小计进行公式设置

l 内层循环:在每个部门内,循环填充每个部门的费用明细

为了使用XSL简单起见,我们的DataSet就包含2个DataTable,第一个DataTable(命名为DepNames)包含需要填充的数据中的部门信息;第二个DataTable(命名为FeeDetail)包含所有需要填充的数据(包括部门标识和费用信息)。当然,从原则上来说,只需要第二个DataTable的数据就可以了,第一个DataTable中的数据完全可以通过XSL的某些操作得到,但是我没有查到如何通过XSL的某些操作可以达到Sql语句中类似SELECT DISTINCT SomeField FROM SomeTable的效果(那位大虾知道?),因此只能退而求其次。

DepNames表包含的信息如下:

DepCode         DepName

10101                A部门

10102                B部门

……                  ……

 

FeeDetail表包含的信息如下:

DepCode         FeeCode          ……

10101                550101     ……

10102                640101     ……

……                  ……                  ……

通过DataSet的GetXml()方法得到的XML文档格式如下:

 

< NewDataSet >
 
< DepNames >
    
< DepCode > 101010005 </ DepCode >
    
< DepName > 一个部门 </ DepName >
 
</ DepNames >
 
< DepNames >
    
< DepCode > 101010006 </ DepCode >
    
< DepName > 又一个部门 </ DepName >
 
</ DepNames >
 
< FeeDetail >
    
< DepCode > 101010005 </ DepCode >
    
< FeeCode > 66010102 </ FeeCode >
    
< FeeName > 一项费用 </ FeeName >
< ExamineAddUpMoney > 0.0000 </ ExamineAddUpMoney >
 
</ FeeDetail >
    
< FeeDetail >
    
< DepCode > 101010006 </ DepCode >
    
< FeeCode > 66010103 </ FeeCode >
    
< FeeName > 另一项费用 </ FeeName >
  
< ExamineAddUpMoney > 0.0000 </ ExamineAddUpMoney >
 
</ FeeDetail >
</ NewDataSet >



可见,得到的DataSet数据中,<NewDataSet>节点是DataSet的名称;<DepNames>节点和<FeeDetail>节点分别代表DepNames结果集的行数据和FeeDetail结果集的行数据,它们的子节点则代表每行的各列数据值。

XSL各种语法很丰富,不过通常我们只需要利用其中的一小部分就能达到我们的目的。下面我们来分析一下模板背后的XML文档格式。

Excel文件另存的XML文档,似乎很长,内容很复杂,但是,借助VS2005以及IE对XML文档中节点良好的“折叠”特性,我们可以很容易的分析出文档中的一些主要元素,另外MS也提供了MS Office 2003的XML Schema参考,对我们也有很大帮助。

我们主要需要关注XML文档中的<Worksheet ss:Name="WorksheetName">节点及其子节点,很明显,它代表Excel文档中的各个Worksheet,对于我们的文档,<Worksheet>节点中包含了一个<table>节点,样例如下:

< Table  ss:ExpandedColumnCount ="27"  ss:ExpandedRowCount ="6"  x:FullColumns ="1"
 x:FullRows
="1"  ss:DefaultColumnWidth ="54"  ss:DefaultRowHeight ="13.5" >

其中,我们主要需要关注2个属性:

l ExpandedColumnCount:代表Excel文档中的列数

l ExpandedRowCount:代表Excel文档中的行数

以上2个属性如果比文档中实际数据的行数和列数小,通常就会导致文档错误而无法用Excel打开,因此我们生成的文档,需要根据实际数据行数来更新ExpandedRowCount属性的值,或者把他们设置为一个非常大的数。

<Table>节点的子节点包括若干<Column>节点和<Row>节点,这很清楚代表表格中的行信息和列信息,对于我们这次的任务,只需要关心<Row>节点,一个简单的<Row>节点类似以下格式:

< Row >
         
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值