一种基于.NET格式精确的OFFICE文档报表生成方案

一、   概述

    由于OFFICE软件在办公软件业的垄断,Office文件格式也在报表文件格式占有相当重要的地位。在商业软件或企业开发中,我们经常会遇到生成Office报表的问题。

    解决这个问题的方法有几种:

l      利用Office Automation的方法直接生成OFFICE文档;

l      利用ADO.NET的方法对Excel文件以数据源的方式读写;

l      利用第三方法插件(Crystal Report)开发。

以上几种各有利弊,而难于达到精确的格式的要求。故根据OFFICE 2003的新特性,我设计一种基于.NET FrameworkOFFICE报表生成方法。

这种方法的优点:

l      能够支持格式较复杂的报表;

l      在执行效率也具有相当的优势;

l      使用的技术相对简单(.Net FrameworkXMLOffice Automation);

l      以后技术发展的趋势(XML技术)。

当然,这种方法也有不少的缺点:

l      不支持图表功能(在Office 12中应该得以改进);

l      没有可视化的工具编辑XSLT,使得开发流程相当耗时,尤其是对XSLT不太了解时;

l      需要对Office 2003XML格式有所了解,这点可以参照Microsoft提供的Microsoft Office 2003 XML Reference Schemas Documentation

    综上所述,本方案应该是利弊参半。所以,本文也非向大家推销此方法,旨在以解决方案的形式,给大家作个参考。

 

二、   实施

    上面对此方法作了概述,但未涉及技术实现,所以现在我想谈一下具体的实现方法。

本方案主要用到XML,要求读者对XML.NET平台上的XML操作要有一定的认识。如果对这方面有兴趣的朋友可以http://www.w3.org了解一下XMLMicrosoft发布的.NET Framework SDK文档了解一下XML.Net Framework上的应用及其操作方法。

方案流程图如下:

    对上图作一下解释:

1.         使用ADO.NET将数据以DataSet的形式从数据库中读出。代码实现如下:

string ConnectionString = @"Provider=Microsoft.Jet.OLEDB.4.0; Data Source=..\..\demo.mdb";

string CommandText = "select * from demo";

using(OleDbConnection myConnection = new OleDbConnection(ConnectionString))

{

OleDbDataAdapter myCommand = new OleDbDataAdapter(CommandText, myConnection);

DataSet ds = new DataSet();

}

2.         DataSet转化在XML文档,这步可以通过DataSet.WriteXml方法或XmlDataDocument类。代码实现如下:

ds.WriteXml(@"d:\temp.xml");//输出XML文档到硬盘

XmlDataDocument xmlDoc = new XmlDataDocument(ds);//输出XML到内存对象

3.         编写Office XMLXSLT。实现这一步的技巧,由于Office XML的代码很繁琐(动辄数千行),你可以先用Office制作模板,然后将其另存为“XML表格”,这样便可以得到大概的Office XML代码,再在其基础上修改。代码实现如下:

<?xml version="1.0" encoding="UTF-8" ?>

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns="urn:schemas-microsoft-com:office:spreadsheet"

     xmlns:o="urn:schemas-microsoft-com:office:office" xmlns:x="urn:schemas-microsoft-com:office:excel"

     xmlns:ss="urn:schemas-microsoft-com:office:spreadsheet" xmlns:html="http://www.w3.org/TR/REC-html40">

     <xsl:output method="xml" indent="yes" />

     <xsl:template match="Profile">

         <Worksheet ss:Name="档案">

              <Table>

                   <Row>

                       <Cell ss:Index="3">

                            <Data ss:Type="String">姓名:</Data>

                       </Cell>

                       <Cell>

                            <Data ss:Type="String">

                                 <xsl:value-of select="./Name" />

                            </Data>

                       </Cell>

                   </Row>

              </Table>

         </Worksheet>

     </xsl:template>

</xsl:stylesheet>

 

4.        利用.NET Framework提供XslTransform类以第一步生成的XML文档作为数据,以第3步生成的XSLT文件作为模板,生成Office 2003 XML格式的XML文件。如果您的客户用的是Office 2003或上的版本,那么生成的文档直接可以被正确地读取,否则,请接着实施下一步。代码实现如下:

XslTransform xslTran = new XslTransform();

xslTran.Load(@"\xslt_profile.xslt");

FileStream fs = null;

try

{

     fs = new FileStream(xmlFile, FileMode.OpenOrCreate);

     xslTran.Transform(xmlDoc, null, fs, null);

}

finally

{

     if(fs != null)

         fs.Close();

}

5.         利用Office 2003提供的COM操作,读入第4步生成的XML文档,然后将其另存为普通的Office文档。

Excel.Application oXL = null;

string xmlFile = "excel.xml";

string xlsFile = "excel.xsl";

Excel.Workbook oWB = null;

try

{

     oXL = new Excel.Application();

     oWB = oXL.Workbooks.Open(xmlFile, Type.Missing, Type.Missing, Type.Missing, Type.Missing,

         Type.Missing, Type.Missing, Type.Missing, Type.Missing, Type.Missing, Type.Missing, Type.Missing,

         Type.Missing,Type.Missing, Type.Missing);

 

     oWB.SaveAs(xlsFile, Excel.XlFileFormat.xlWorkbookNormal, Type.Missing, Type.Missing, Type.Missing, Type.Missing, Excel.XlSaveAsAccessMode.xlNoChange,

         Type.Missing, Type.Missing, Type.Missing, Type.Missing,Type.Missing);                  

}

finally

{

     if(oWB != null)

     {

         oWB.Close(false, Type.Missing, Type.Missing);

         System.Runtime.InteropServices.Marshal.ReleaseComObject(oWB);

     }

if(oXL != null)

     {

         oXL.Quit();

         System.Runtime.InteropServices.Marshal.ReleaseComObject(oXL);

     }

}

三、   总结

随着XML技术的发展和普及,我相信该方案可以支持更多的格式的报表生成如PDF等。如果有一个可视化的GUI工具编写XSLT,则可以减轻开发者的劳动和加快开发周期,我认为本方案也是有一定的商业价值的。 

posted on 2006-04-26 17:13  Max Yuen  阅读(440)  评论(0)    收藏  举报