惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

Apple Machine Learning Research
Apple Machine Learning Research
博客园 - 三生石上(FineUI控件)
雷峰网
雷峰网
WordPress大学
WordPress大学
S
SegmentFault 最新的问题
博客园 - 叶小钗
The Cloudflare Blog
T
Tailwind CSS Blog
Hugging Face - Blog
Hugging Face - Blog
让小产品的独立变现更简单 - ezindie.com
让小产品的独立变现更简单 - ezindie.com
freeCodeCamp Programming Tutorials: Python, JavaScript, Git & More
月光博客
月光博客
小众软件
小众软件
罗磊的独立博客
酷 壳 – CoolShell
酷 壳 – CoolShell
大猫的无限游戏
大猫的无限游戏
阮一峰的网络日志
阮一峰的网络日志
V
V2EX
美团技术团队
钛媒体:引领未来商业与生活新知
钛媒体:引领未来商业与生活新知
博客园 - 聂微东
量子位
OSCHINA 社区最新新闻
OSCHINA 社区最新新闻
宝玉的分享
宝玉的分享

博客园 - Eric Fine

Wii Party U 游戏简介 OracleParameter.UdtTypeName的值必须是全大写! VS2012调用64位IIS Express [Fix] Emulator Error: Could not load OpenGLES emulation library: Could not load DLL! [Fix] "Loading toolbox content from package Microsoft.VisualStudio.IDE.Toolbox.ControlInstaller.ToolboxInstallerPackage'{2C98B35-07DA-45F1-96A3-BE55D91C8D7A}'" 暗黑3 API 预览版 中兴光纤猫 F420 破解 [Fix] Blend 4 出现 Line:0 Position:0 错误 多维数组操作 诺基亚WP7手机 710/800一分钟完美越狱测试 三星WP7手机MANGO一分钟完美越狱 Silverlight 4 Binding Cheatsheet [转] 让WCF代替WSE访问需要明文UserName/Password验证的WebService 變形金剛塔防 Anti-TD Xeno Tactic 2 Medieval Rampage Mac OS X Leopard 10.5.5 安裝手记 (Dell D830) SPGridView 研究笔记 Part 3 - 分组
将DataTable导出为Excel (XML Spreadsheet).
Eric Fine · 2008-10-24 · via 博客园 - Eric Fine

前阵子公司有同事需要将搜索页面的搜索结果导出成Excel文件. 用几个不同的办法做了出来. 最后部署时发现: 用COM+组件行不通, 服务器上没装OFFICE; 用OWC也不行, 因为服务器是64位的, OWC不支持; 导出成Excel2003支持的xml, 这招最灵活, 也是一个简单可行的办法.

首先用Excel 2003新建一个空白Wookbook, 然后保存为XML Spreadsheet. 然后打开看它生成的XML代码就能了解XML Spreadsheet的基本结构了.
我先把DataTable生成XML数据, 再使用一个XLS把XML数据转换成XML Spreadsheet的结构.

using System;
using System.Collections.Generic;
using System.Data;
using System.IO;
using System.Reflection;
using System.Text;
using System.Xml;
using System.Xml.Xsl;

namespace AProject
{
    public class ExcelHelper
    {
        public static string ExportAsTempFile(DataTable dataTable, bool appendColumnNames)
        {
            if(dataTable == null)
            {
                return null;
            }

            return ExportAsTempFile(new DataTable[] { dataTable }, appendColumnNames);
        }

        public static string ExportAsTempFile(DataSet dataSet, bool appendColumnNames)
        {
            string fileName = Path.GetTempFileName();

            if(ExportFile(dataSet, fileName, appendColumnNames))
            {
                return fileName;
            }

            return null;
        }

        public static string ExportAsTempFile(DataTable[] dataTables, bool appendColumnNames)
        {
            string fileName = Path.GetTempFileName();

            if(ExportFile(dataTables, fileName, appendColumnNames))
            {
                return fileName;
            }

            return null;
        }

        public static bool ExportFile(DataTable dataTable, string fileName, bool appendColumnNames)
        {
            if(dataTable == null)
            {
                return false;
            }

            return ExportFile(new DataTable[] { dataTable }, fileName, appendColumnNames);
        }

        public static bool ExportFile(DataSet dataSet, string fileName, bool appendColumnNames)
        {
            if(dataSet == null)
            {
                return false;
            }

            DataTable[] dataTables = new DataTable[dataSet.Tables.Count];
            dataSet.Tables.CopyTo(dataTables, 0);
            return ExportFile(dataTables, fileName, appendColumnNames);
        }

        public static bool ExportFile(DataTable[] dataTables, string fileName, bool appendColumnNames)
        {
            if(dataTables == null || dataTables.Length == 0 || string.IsNullOrEmpty(fileName))
            {
                return false;
            }

            XmlDocument xmlDoc = GetXmlDataTables(dataTables, appendColumnNames);
            XmlDocument xlsDoc = TransformXml(xmlDoc);

            try
            {
                xlsDoc.Save(fileName);
                return true;
            }
            catch
            {
                return false;
            }
        }

        private static XmlDocument GetXmlDataTables(DataTable[] dataTables, bool appendColumnNames)
        {
            if(dataTables == null)
            {
                return null;
            }

            XmlDocument xmlDoc = new XmlDocument();
            XmlElement rootNode = xmlDoc.CreateElement("DTS");
            XmlElement tableNode;
            XmlElement rowNode;
            XmlElement colNode;
            DataTable dt;

            for(int i = 0; i < dataTables.Length; i++)
            {
                dt = dataTables[i];

                if(dt == null)
                {
                    break;
                }

                if(dt.TableName.Trim() == string.Empty)
                {
                    dt.TableName = "DataTable" + i.ToString();
                }

                tableNode = xmlDoc.CreateElement("DT");
                tableNode.SetAttribute("N", dt.TableName);

                if(appendColumnNames)
                {
                    rowNode = xmlDoc.CreateElement("DR");

                    foreach(DataColumn dc in dt.Columns)
                    {
                        colNode = xmlDoc.CreateElement("DC");
                        colNode.SetAttribute("N", dc.ColumnName);
                        colNode.SetAttribute("T", "String");
                        colNode.AppendChild(xmlDoc.CreateTextNode(dc.ColumnName));
                        rowNode.AppendChild(colNode);
                    }

                    tableNode.AppendChild(rowNode);
                }


                foreach(DataRow dr in dt.Rows)
                {
                    rowNode = xmlDoc.CreateElement("DR");

                    foreach(DataColumn dc in dt.Columns)
                    {
                        colNode = xmlDoc.CreateElement("DC");
                        colNode.SetAttribute("N", dc.ColumnName);
                        colNode.SetAttribute("T", GetDataType(dc.DataType));
                        colNode.AppendChild(xmlDoc.CreateTextNode(GetTextValue(dc.DataType, dr[dc.ColumnName])));
                        rowNode.AppendChild(colNode);
                    }

                    tableNode.AppendChild(rowNode);
                }

                rootNode.AppendChild(tableNode);
            }

            xmlDoc.AppendChild(rootNode);
            return xmlDoc;
        }

        private static string GetTextValue(Type type, object value)
        {
            string text;

            if(type == typeof(DateTime))
            {
                text = ((DateTime)value).ToString("yyyy-MM-ddTHH:mm:ssZ");
            }
            else
            {
                text = value.ToString();
            }

            return text;
        }

        private static string GetDataType(Type type)
        {
            string dataType;

            if(type == typeof(string))
            {
                dataType = "String";
            }
            else if(type == typeof(DateTime))
            {
                dataType = "DateTime";
            }
            else if(type == typeof(bool))
            {
                dataType = "Boolean";
            }
            else
            {
                dataType = "Number";
            }

            return dataType;
        }

        private static XmlDocument TransformXml(XmlDocument xmlDoc)
        {
            XmlDocument xlsDoc = new XmlDocument();
            XslCompiledTransform xslt = new XslCompiledTransform();
            Assembly assembly = Assembly.GetExecutingAssembly();

            using(Stream s = assembly.GetManifestResourceStream("AProject.Resources.XmlSpreadsheet.xsl"))
            {
                if(s != null)
                {
                    xslt.Load(XmlReader.Create(s));
                    MemoryStream output = new MemoryStream();
                    XmlTextWriter xmlWriter = new XmlTextWriter(output, Encoding.UTF8);
                    xslt.Transform(xmlDoc, xmlWriter);
                    output.Position = 0;
                    xlsDoc.Load(output);
                    xlsDoc.PrependChild(xlsDoc.CreateXmlDeclaration("1.0", null, null));
                    output = null;
                }
            }

            return xlsDoc;
        }
    }
}
<?xml version="1.0" ?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:ss="urn:schemas-microsoft-com:office:spreadsheet">
    <xsl:output method='xml' version='1.0'/>
    <xsl:template match="DTS">
        <ss:Workbook >
            <ss:Styles>
                <ss:Style ss:ID="Default">
                    <ss:NumberFormat ss:Format="General"/>
                </ss:Style>
                <ss:Style ss:ID="DateTime">
                    <ss:NumberFormat ss:Format="General Date"/>
                </ss:Style>
            </ss:Styles>
            <xsl:apply-templates select="DT" />
        </ss:Workbook>
    </xsl:template>

    <xsl:template match="DT">
        <ss:Worksheet>
            <xsl:attribute  name="ss:Name">
                <xsl:value-of select="@N"/>
            </xsl:attribute>
            <ss:Table>
                <xsl:apply-templates select="DR" />
            </ss:Table>
        </ss:Worksheet>
    </xsl:template>

    <xsl:template match="DR">
        <ss:Row>
            <xsl:apply-templates select="DC" />
        </ss:Row>
    </xsl:template>

    <xsl:template match="DC">
        <ss:Cell>
            <xsl:choose>
                <xsl:when test="@T = 'DateTime'">
                    <xsl:attribute name="ss:StyleID">
                        <xsl:text>DateTime</xsl:text>
                    </xsl:attribute>
                </xsl:when>
            </xsl:choose>
            <ss:Data>
                <xsl:attribute name="ss:Type">
                    <xsl:value-of select="@T"/>
                </xsl:attribute>
                <xsl:choose>
                    <xsl:when test="@T = 'String'">
                        <xsl:text disable-output-escaping="yes">&lt;![CDATA[</xsl:text>
                        <xsl:value-of  select="."/>
                        <xsl:text disable-output-escaping="yes">]]&gt;</xsl:text>
                    </xsl:when>
                    <xsl:otherwise>
                        <xsl:value-of select="."/>
                    </xsl:otherwise>
                </xsl:choose>
            </ss:Data>
        </ss:Cell>
    </xsl:template>
</xsl:stylesheet>

参考链接: XML Spreadsheet Reference