`
xufei0110
  • 浏览: 110619 次
  • 性别: Icon_minigender_1
  • 来自: 大连
社区版块
存档分类
最新评论

C# 根据模版写Excel(Com)二

    博客分类:
  • .net
阅读更多

《C# 根据模版写Excel(Com)一 》   里给出写Excel的主要类

 

这里给出2个辅助类。

这2个类用来 读Excel模版的xml描述文件

和 写入Excel的sheet 用的

 

/// <summary>
/// 根据数据结果集,修改临时文件内容
/// </summary>
/// <param name="ds">要传入到Excel的数据集</param>
/// <returns></returns>
private void writeExcelContent(Object o)
{
        try
        {
            
            ExcelObj.Visible = false;

            ExcelDescriptions a = new ExcelDescriptions();
            Hashtable templateXml = a.parseXml(templateDiscriptionFilePath);
            
            WookSheetWrite wStW = new WookSheetWrite(xSt);
            wStW.setWorksheet(o, templateXml);
        ...........
}

 就是这个 方法里 用到的 2个类

 

首先是读Excel模版的xml描述文件的类

using System;
using System.Data;
using System.Configuration;
using System.Linq;
using System.Xml.Linq;
using System.Xml;
using System.Collections.Generic;
using System.Collections;
using System.Reflection;

/// <summary>
/// 解析Excel模版对应的xml描述文件
/// </summary>
public class ExcelDescriptions
{
                         
    /// <summary>
    /// 解析模版描述文件到 Hashtable
    /// </summary>
    /// <param name="descriptionFilePath">解析模版描述文件 全名</param>
    /// <returns>包含模版描述文件信息的
    ///     Hashtable: key:字段名 或 类名,
    ///               value:对应模版文件坐标(例如:A1), 或 一个Hashtable
    ///          当key为类名时, value:为一个Hashtable;
    ///     这个关系 最多为二层
    /// </returns>
    public Hashtable parseXml(string descriptionFileName)
    {
        Hashtable templateXml = new Hashtable();
        XmlDocument xmlDoc = new XmlDocument();
        
        try{
            //xmlDoc.Load(AppDomain.CurrentDomain.BaseDirectory + "xml/Template1.xml");
            xmlDoc.Load(descriptionFileName);
        } catch(Exception ex){               
            throw new Exception("没有找到模版描述文件");
        }

        //每个 Excel模版对应一个 描述文件 table节点 是唯一的
        XmlNode xn = xmlDoc.SelectSingleNode("table");
        XmlNodeList xnl = xn.ChildNodes;
        
        //因为只有2层 所以就直接写在这里了
        foreach (XmlNode xnf in xnl)
        {
            XmlElement xeOuter = (XmlElement)xnf;
            
            //map 的key为 字段名, 或类名;
            //      value为 对应的模版的单元格的 坐标. 例如:A1
            if (xeOuter.HasChildNodes)
            {
                //内层 Hashtable
                //Hashtable: key:字段名
                //          value:对应模版文件坐标(例如:A1),
                //内层Hashtable 不可以再 包含Hashtable
                Hashtable templateXmlInner = new Hashtable();
                XmlNodeList xnlInner = xeOuter.ChildNodes;
                foreach (XmlNode xnfInner in xnlInner)
                {
                    XmlElement xeInner = (XmlElement)xnfInner;
                    templateXmlInner.Add(xeInner.GetAttribute("filed").ToString().Trim(),
                        xeInner.GetAttribute("coordinates").ToString().Trim());
                }
                templateXml.Add(xeOuter.GetAttribute("filed").ToString().Trim(),
                    templateXmlInner);
            }
            else
            {
                templateXml.Add(xeOuter.GetAttribute("filed").ToString().Trim(),
                    xeOuter.GetAttribute("coordinates").ToString().Trim());
            }
            
        }
        return templateXml;
    }

    
}

 

 

对应的xml文件, 这个文件是自己定义的

<?xml version="1.0" encoding="utf-8" ?>
<table name="User">
    <Cell coordinates="A1" filed="name"></Cell>
    <Cell coordinates="A2" filed="sex"></Cell>
    <Cell coordinates="B1" filed="age"></Cell>
    <Cell coordinates="B2" filed="id"></Cell>
    <Cells filed="car">
        <Cell coordinates="B20" filed="id"></Cell>
        <Cell coordinates="E20" filed="name"></Cell>
    </Cells>
    <Cells filed="address">
        <Cell coordinates="D37" filed="id"></Cell>
        <Cell coordinates="D38" filed="name"></Cell>
    </Cells>
</table>

 

 

然后是写入Excel文件的类

 

using System;
using System.Data;
using System.Configuration;
using System.Linq;
using System.Web;
using System.Web.Security;
using Excel = Microsoft.Office.Interop.Excel;
using System.Collections;
using System.Collections.Generic;
using System.Text.RegularExpressions;
using System.Reflection;


/// <summary>
/// 根据模版文件, 描述信息 和 数据集
/// 写Excel 的 sheet
/// </summary>
public class WookSheetWrite
{
    private object missing = System.Reflection.Missing.Value;
    //工作Sheet
    private Excel._Worksheet xSt;

    public WookSheetWrite(Excel._Worksheet _xSt) 
    {
        if (_xSt == null)
        {
            throw new Exception("目标 Excel 的 sheet对象 为空");
        }
        else
        {
            this.xSt = _xSt;
        }
    }

    /// <summary>
    /// 根据模版, 模版描述文件的 Hashtable, 以及数据对象来填充Excel
    /// </summary>
    /// <param name="dataObject">数据集对象, 
    ///         这里的数据集对象 为 linq查出来的实体对象,
    ///         该实体对象可能包含另外一个或多个实体对象, 
    ///         或 另外一个或多个实体对象的List。
    /// </param>
    /// <param name="templateXml">装载模版描述文件的信息的 Hashtable
    ///         该Hashtable
    ///     Hashtable: key:字段名 或 类名,
    ///               value:对应模版文件坐标(例如:A1), 或 一个Hashtable
    ///          当key为类名时, value:为一个Hashtable;
    ///     这个关系 最多为二层
    /// </param>
    public void setWorksheet(Object dataObject, Hashtable templateXml)
    {
        if(dataObject == null)
        {
            throw new Exception("数据集对象为空");
        }
        
        
        foreach (string filedName in templateXml.Keys)
        {
            Object value = templateXml[filedName];
            if (value == null)
            {
                throw new Exception("指定的数据集的属性:" + filedName + " 为空");
            }
            if (value is Hashtable)
            {
                //如果sheet对象里包含 循环结构
                //dataObject数据集里 对应的一个List
                Object innerDataObject = getFiled(dataObject, filedName);
                if (innerDataObject is IList)
                {
                    setCells(value, (IList)innerDataObject);  //数据集属性类型 为一个List
                }
                else 
                {
                    setCells(value, innerDataObject);  //数据集属性类型 为一个实体对象
                }

            }
            else
            {
                string coordinates = value.ToString();
                string data = getFiled(dataObject, filedName).ToString();
                xSt.get_Range(coordinates, missing).Value2 = data;
            }
        }
    }

    

    /// <summary>
    /// 填充一组单元格。这组单元格有如下特征:
    /// 1,这些单元个的字段组合起来是一个类的属性
    /// 2,这些单元个顺序排列在一行里
    /// 3, 这些单元个所在行的接下来几行的值,可以通过循环填充
    /// </summary>
    /// <param name="value">
    ///             Hashtable里指定key对应的 值, 这里仍然是一个Hashtable
    ///             存放的是,key:特定对象的属性名, value:对应的坐标</param>
    /// <param name="innerList">
    ///             指定数据集对象里包含的IList对象,
    ///             IList里包含的对象就是 value 里的属性对应的对象
    /// </param>
    private void setCells(Object value, IList innerList)
    {
        Hashtable templateXmlInner = (Hashtable)value;

        //循环IList 填充行
        for (int i = 0; i < innerList.Count; i++)
        {                
            Object innerObject = innerList[i];

            //循环Hashtable填充单元格组
            foreach (string filedNameInner in templateXmlInner.Keys)
            {
                string coordinates = templateXmlInner[filedNameInner].ToString();

                //对应单元个的行坐标
                string innerNum = getRowNo(coordinates);
                //将行坐标+i返回,第一次为第一行, 第二次为第二行,循环填充
                coordinates = coordinates.Replace(innerNum, (int.Parse(innerNum) + i).ToString());
                //这里还没有判断 模版预留行数量小于 数据数量的情况

                //取得对应单元格的数据
                string dataInnert = getFiled(innerObject, filedNameInner).ToString();
                xSt.get_Range(coordinates, missing).Value2 = dataInnert;
            }
        }
    }

    /// <summary>
    /// 填充一组单元格。这组单元格有如下特征:
    /// 1,这些单元个的字段组合起来是一个类的属性
    /// </summary>
    /// <param name="value">
    ///             Hashtable里指定key对应的 值, 这里仍然是一个Hashtable
    ///             存放的是,key:特定对象的属性名, value:对应的坐标</param>
    /// <param name="innerDataObject">
    ///             指定数据集对象里的 一个数据对象
    ///             该对象的属性与Hashtable的key 一一对应
    /// </param>
    private void setCells(Object value, Object innerDataObject) 
    {
        Hashtable templateXmlInner = (Hashtable)value;
        //循环Hashtable填充单元格组
        foreach (string filedNameInner in templateXmlInner.Keys)
        {
            string coordinates = templateXmlInner[filedNameInner].ToString();
            string data = getFiled(innerDataObject, filedNameInner).ToString();
            xSt.get_Range(coordinates, missing).Value2 = data;
        }
    }

    /// <summary>
    /// 通过类 和 属性名 得到该类的该属性的值
    /// </summary>
    /// <param name="dataObject">类对象</param>
    /// <param name="filedName">字符串类型的属性名</param>
    /// <returns></returns>
    private Object getFiled(Object dataObject, string filedName)
    {
        if (string.IsNullOrEmpty(filedName))
        {
            throw new Exception("属性名为空");

        }
        PropertyInfo field = dataObject.GetType().GetProperty(filedName);
        if (field == null)
        {
            throw new Exception("在类: " + dataObject.GetType().Name.ToString()
                               + " 中不存在名为: " + filedName + " 的属性");
        }
        return field.GetValue(dataObject, null);
    }

    /// <summary>
    /// 取出Excel对应单元格坐标的行号
    /// </summary>
    /// <param name="coordinates">坐标(列:A1)</param>
    /// <returns>单元个的行坐标</returns>
    private static string getRowNo(string coordinates)
    {
        //取出坐标中的数字 “A1” 中的 “1”
        if (string.IsNullOrEmpty(coordinates))
        {
            throw new Exception("模版坐标为空");
        }
        Regex rg = new Regex("\\D");
        return rg.Replace(coordinates, "");
    }
}

 

这样只要有 Excel模版 和 模版描述文件 我们就可以  写Excel文件了

 

vs2008下测试通过

 

分享到:
评论

相关推荐

    C#(dataGridView按Excel模板导出)控件

    在这个特定的场景中,我们讨论的是如何利用C#中的dataGridView控件来实现一个功能,这个功能允许用户按照自定义的Excel模板导出数据。这涉及到对dataGridView控件的操作,以及将数据转换为Excel格式的技术。 首先,...

    C# 导出利用模板,映射文件导出复杂excel

    本主题聚焦于如何使用C#来实现一个复杂的Excel导出功能,结合模板和映射文件,以及可能涉及的操作Excel宏。这个过程通常是为了满足业务需求,如自定义报告生成、数据分析和数据可视化。 首先,我们要理解什么是模板...

    C# 将数据导出到excel模板 自定义字段

    本主题聚焦于如何利用C#将数据导出到Excel模板,并自定义字段,这是一个常见的需求,尤其是在数据分析、报告生成和数据共享的场景中。 在C#中,我们可以利用各种库来操作Excel,如EPPlus、NPOI或Microsoft.Office....

    C# 根据模版写Excel

    在C#编程中,生成Excel文件常常用于数据报表或数据分析的导出,模版写Excel是一种常见的方法,它允许开发者预先定义好Excel的格式和布局,然后根据数据填充内容。以下将详细介绍标题和描述中涉及的知识点: 1. **...

    使用aspose导出Excel(根据模板导出excel).zip

    在本示例中,我们将深入探讨如何使用Aspose库在.NET环境中根据模板导出Excel电子表格。这个过程涉及到多个步骤和技术,包括理解Aspose的API、模板设计以及数据注入。 首先,Aspose库提供了强大的Excel操作功能,...

    c# 按模板导出Excel 通用类

    "c# 按模板导出Excel 通用类"就是为了解决这个问题而设计的,它允许开发者按照预先设定的模板快速、高效地生成Excel文件。 这个通用类的核心功能包括: 1. **模板支持**:它可以读取已存在的Excel模板文件,保留...

    c# 填充Excel并打印类

    本文将深入探讨如何使用C#来填充Excel模板数据并进行打印操作。 首先,`PrintStudent.cs`可能包含一个名为`PrintStudent`的类,这个类是用来处理Excel的填充和打印功能的核心代码。在C#中,我们可以利用开源库如...

    C#操作EXCEL EXCEL类库 Excel模板处理 将DataTable数据写入Excel文件 C#数据写入EXCEL

    本主题主要围绕C#如何使用不同的方法来处理Excel,尤其是将DataTable数据写入Excel文件,并涉及Excel模板处理和样式管理。 首先,我们来探讨使用Microsoft Office Interop库的方式。这是微软提供的一个接口,可以...

    C#创建EXCEl模板

    总的来说,C#创建Excel模板是一个灵活且功能强大的过程,它允许开发人员根据需求构建定制化的数据处理和报告工具。结合适当的库,如EPPlus,你可以避免直接依赖Office,使你的应用具有更好的兼容性和可部署性。通过...

    C#向EXCEL模板文件中插入数据行

    本话题聚焦于如何利用C#在已有的Excel模板文件中插入数据行,同时保持模板原有的格式不受破坏。这在数据分析、报表生成或批量处理数据时非常常见。 首先,我们需要了解的是Microsoft Office Interop库,这是.NET ...

    C#版本Itextsharp根据模板导出pdf报表

    在这个场景下,我们将深入探讨如何使用C#和Itextsharp库根据模板导出PDF报表。 首先,我们需要理解模板的概念。模板通常是一个预定义的PDF文件,包含固定的布局和样式,而实际的数据将被插入到这些预定的位置。在...

    C#写入固定模版的EXCEL

    2. 加载模板Excel文件: ```csharp FileInfo templateFileInfo = new FileInfo("模板路径.xlsx"); ExcelPackage.LicenseContext = LicenseContext.NonCommercial; // 如果不用于商业用途,可以不设置此行 Excel...

    C# EXCEL模板操作.rar

    c#源码工具类型,主要用于EXCEL模板编辑,批量导入图片到EXCEL固定单元格,批量导入文字到EXCEL固定单元格,实现拖放图片显示,循环遍历子控件添加事件等资源,程序附加模板。可直接使用。扩展性强,下载后希望给个...

    C#winform,excel打印工具

    在C# WinForm开发中,实现Excel打印工具是一项常见的需求,尤其在企业级应用中,报表和数据分析的呈现经常依赖于Excel格式。本知识点将详细讲解如何利用C#和WinForm来创建一个基于Excel的打印工具,以及相关的关键...

    ASP.NET/C# 使用NPOI 将数据导入到模板Excel[支持xlsx][源代码]

    本文将深入探讨如何使用NPOI将数据导入到模板Excel中,特别关注对.xlsx格式的支持。 首先,NPOI是一个开源的.NET库,它实现了Apache POI API的功能,使得.NET开发者能够与Microsoft Office文档进行交互。NPOI提供了...

    NPOI基于模板导出到excel

    "NPOI基于模板导出到excel"是指利用NPOI库的功能,根据预先设计的模板来生成新的Excel文件,这在数据报表生成、批量数据处理和自动化办公场景中非常实用。 首先,让我们详细了解一下NPOI的主要功能和工作原理。NPOI...

    C#操作Excel,套用模板并对数据进行分页

    本话题聚焦于如何利用C#操作Excel文件,尤其是套用模板并对数据进行分页。这通常涉及到读写Excel文件,使用模板,以及处理大量数据的高效方法。 首先,C#中操作Excel文件主要依赖于第三方库,例如NPOI、EPPlus等。...

    C# DataSet创建Excel文件(多sheet,支持Excel模板)

    公司因业务需求,需要开发一个自动向供应商发送邮件的系统。难点是 邮件需附带一个Excel附件,此...根据供应商的不同而不同,相关部门已提供一个Excel内容模板。 用VS2010写了一个例子,解决了此问题。与大家分享!

    NPOI按模板导出C#环境

    标题 "NPOI按模板导出C#环境" 指的是使用C#编程语言,结合NPOI库,来实现根据预设模板导出Excel文件的功能。NPOI是一个开源项目,它允许开发者在.NET平台上操作Microsoft Office文档,包括Excel。在Windows Forms...

    [二合一]C#读取和导出EXCEL类库(可操作多个SHEET)

    标题中的 "[二合一]C# 读取和导出 EXCEL 类库(可操作多个 SHEET)" 指的是一个 C# 开发的类库,它整合了读取和导出 Excel 文件的功能,并且能够方便地操作 Excel 文件中的多个工作表(Sheet)。这种类库在处理大量...

Global site tag (gtag.js) - Google Analytics