由于Excel中提供了透视表PivotTable,许多项目都使用它来作为数据分析报表。 在有些情况下,我们需要在Excel中设计好模板,包括数据源表,透视表等, 当数据导入到数据源表时,自动更新透视表。本篇主要讲述导出数据到Excel的过程。

假设我们需要从Sql Server 中读取数据到DataTable中,然后把DataTable中的数据写入到Excel.

那这个导入过程大致有如下逻辑步骤:

1. 读取数据到DataTable中。

2. 读取Excel指定Sheet中的数据字段名。 一般情况下,我们使用表格(Sheet)的第一行作为数据字段名,则如下代码读取WorkSheet中的字段定义. 以下示例代码为实际应用中我使用自定义类来匹配相应字段

  public class Mapping
{
public string SourceField { get; set; }
public string DestinationCellHeader { get; set; }
public string DestinationReference { get; set; }
public CellType CellType { get; set; }
} public List<Mapping> GetRawMappings(string fileName,string sheetName)
{
List<Mapping> mappings = new List<Mapping>();
using (SpreadsheetDocument document = SpreadsheetDocument.Open(fileName, true))
{
WorkbookPart workbookPart = document.WorkbookPart;
Sheet dataSheet = workbookPart.Workbook.Descendants<Sheet>().Where(s => string.Compare(s.Name, sheetName, true) == ).FirstOrDefault();//sheetName为你要导入数据的工作表名称
if (dataSheet != null)
{
WorksheetPart worksheetPart = workbookPart.GetPartById(dataSheet.Id.Value) as WorksheetPart;
var headerRow = worksheetPart.Worksheet.GetFirstChild<SheetData>().Elements<Row>().
FirstOrDefault(c => c.RowIndex == );//读取首行
mappings = headerRow.Elements<Cell>().Select(c => new Mapping()
{
DestinationReference = c.CellReference.Value.Replace("", ""),
DestinationCellHeader = ExcelHelper.GetCellValue(workbookPart, c)
}).ToList();
}
}
}

3. 读取DataTable 中的数据字段名及数据类型。

4. 匹配DataTable中的数据字段名到Excel中的数据字段名。

   public enum CellType
{
Text,
Number,
Date,
Boolean
} private static CellType GetCellType(System.Data.DataColumn col)
{
if (col.DataType == typeof(System.Decimal))
{
return CellType.Number;
}
if (col.DataType == typeof(System.Boolean ))
{
return CellType.Boolean ;
}
if (col.DataType == typeof(System.DateTime) )
{
return CellType.Date ;
}
return CellType.Text;
} //data为从sqlserver中读取得相应的数据表
var cols = GetRawMappings("文件名","工作表名");
List<Mapping> allColumnMappings = new List<Mapping>();
var sourceDataColumns = data.Columns.Cast<System.Data.DataColumn>();
//自动匹配的列
var colsMapped = cols.Where(c => sourceDataColumns.
Any(cl => string.Compare(cl.ColumnName,c.DestinationCellHeader,true) == )).ToList();
foreach (Mapping ma in colsMapped)
{
ma.SourceField = ma.DestinationCellHeader;
System.Data.DataColumn col = sourceDataColumns.FirstOrDefault(c => string.Compare(c.ColumnName,ma.SourceField,true)==);
ma.CellType = GetCellType(col);
}

5. 循环读取每个DataRow,并根据DataColumn的字段类型,循环写入Excel中的相应字段,并设置字段类型。

         private static Row CreateContentRow(SpreadsheetDocument document, int index, System.Data.DataRow dr,List<Mapping> mappings,Nullable<uint> dateStyleID)
{
//Create the new row.
Row row = new Row();
row.RowIndex = (UInt32)index;
//First cell is a text cell, so create it and append it.
//Cell firstCell = CreateTextCell(referenceHeaders[0],index);
//r.AppendChild(firstCell);
//Create the cells that contain the data.
foreach(var mapping in mappings)
{
Cell cell = null;
string source = string.Empty; if (!string.IsNullOrEmpty(mapping.SourceField))
source = dr[mapping.SourceField].ToString(); cell = CreateCell(document, mapping.CellType, mapping.DestinationReference, index, source, dateStyleID); row.AppendChild(cell);
} return row;
} public static Cell CreateCell(SpreadsheetDocument document, CellType type, string header, int index, string text, Nullable<uint> dateStyleID)
{
Cell cell = new Cell();
cell.CellReference = header + index; CellValue value = null;
if (type == CellType.Text )
{
//int stringIndex = ExcelHelper.AppendOrGetSharedStringItem(text, document);
//stringIndex.ToString()
value = new CellValue(text);
cell.DataType = new EnumValue<CellValues>(CellValues.String);
}
if (type == CellType.Date)
{
if (!string.IsNullOrEmpty(text))
{
DateTime dt = DateTime.Parse(text);
value = new CellValue(dt.ToOADate().ToString());
}
cell.StyleIndex = dateStyleID;
cell.DataType = new EnumValue<CellValues>(CellValues.Number); //new EnumValue<CellValues>(CellValues.Date);
}
if (type == CellType.Number)
{
cell.DataType = new EnumValue<CellValues>(CellValues.Number);
value = new CellValue(text);
} cell.CellValue = value;
//cell.AppendChild(value);
return cell;
} Stylesheet styleSheet = workbookPart.WorkbookStylesPart.Stylesheet;
var dateStyleId = ExcelHelper.CreateCellFormat(styleSheet, null, null, UInt32Value.FromUInt32());
//var references = headerRow.Elements<Cell>().Select(c => c.CellReference.Value.Replace("1", "")).ToList();
var i = ;
foreach (System.Data.DataRow row in data.Rows)
{
Row contentRow = CreateContentRow(document, ((int)maxRowIndex) + i++, row, cols, dateStyleId);
//Append new row to sheet data.
sheetData.AppendChild(contentRow);
} 下一篇,我将使用Open Xml修改Pivot table 数据源定义

使用Open xml 操作Excel系列之二--从data table导出数据到Excel的更多相关文章

  1. python 导出数据到excel 中,一个好用的导出数据到excel模块,XlsxWriter

    最近公司有项目需要导出数据到excel,首先想到了,tablib,xlwt,xlrd,xlwings,win32com[还可以操作word],openpyxl,等模块但是 实际操作中tablib 写入 ...

  2. 【js-xlsx和file-saver插件】前端html的table导出数据到excel的表格合并显示boder

    最近在做项目,需要从页面的表格中导出excel,一般导出excel有两种方法:一.习惯上是建模版从后台服务程序中导出:二.根据页面table中导出:综合考虑其中利弊选择二.根据页面table中导出ex ...

  3. Dynamics CRM导出数据到Excel

    原创地址:http://www.cnblogs.com/jfzhu/p/4276212.html 转载请注明出处 Pivot Table是微软BI的一个重要工具,所以这里讲一下Dynamics CRM ...

  4. 微软BI 之SSIS 系列 - 导出数据到 Excel 2013 的实现

    开篇介绍 碰到有几个朋友问到这个问题,比较共性,就特意写了这篇小文章说明一下如何实现在 SSIS 中导出数据到 Office Excel 2013 中.通常情况下 2013 以前的版本大多没有问题,但 ...

  5. Java操作Jxl实现导出数据生成Excel表格数据文件

    实现:前台用的框架是Easyui+Bootstrap结合使用,需要引入相应的Js.Css文件.页面:Jsp.拦截请求:Servlet.逻辑处理:ClassBean.数据库:SQLserver. 注意: ...

  6. 从数据库导出数据到excel之POI操作

    项目说明: 1:数据库中有两张表,主键关联 2:根据条件查询数据 3:处理为需要的数据封装类型,然后传到导出excel的方法中 <--框架部署就不详谈了,用的spring框架--> 补充: ...

  7. 导出数据到Excel方法总结

    一,问题的提出 近来在网上经常有人问怎样把数据导出到Excel中?针对这个问题网上也有很多资料.大都比较的琐碎.本人当前从事的项目中,刚好涉及到这些内容.就顺便做了一些归纳整理.共享给大家.避免大家再 ...

  8. pl/sql developer导出数据到excel的方法

    http://yedward.net/?id=92 问题说明:使用pl/sql developer导出数据到excel表格中是非常有必要的,一般的可能直接在导出的时候选择csv格式即可,因为该格式可以 ...

  9. 1.ASP.NET MVC使用EPPlus,导出数据到Excel中

    好久没写博客了,今天特地来更新一下,今天我们要学习的是如何导出数据到Excel文件中,这里我使用的是免费开源的Epplus组件. 源代码下载:https://github.com/caofangshe ...

随机推荐

  1. codevs 1285 二叉查找树STL基本用法

    C++STL库的set就是一个二叉查找树,并且支持结构体. 在写结构体式的二叉查找树时,需要在结构体里面定义操作符 < ,因为需要比较. set经常会用到迭代器,这里说明一下迭代器:可以类似的把 ...

  2. 利用sharding-jdbc分库分表

    sharding-jdbc是当当开源的一款分库分表的数据访问层框架,能对mysql很方便的分库.分表,基本不用修改原有代码,只要配置一下即可,完整的配置参考以下内容: <?xml version ...

  3. [LeetCode] Counting Bits 计数位

    Given a non negative integer number num. For every numbers i in the range 0 ≤ i ≤ num calculate the ...

  4. chrome中获取元素的样式

    以获取背景颜色为例 html部分 <div id="test">abcd</div> css部分 #test { background-color: rgb ...

  5. Redis设计与实现读书笔记(二) 链表

    链表作为最基础的数据结构,在许多高级语言上已经有了很好的实现.由于redis采用C语言编写,需要自己实现链表,于是redis在adlist.h定义了链表类型.作者对于这部分没什么好说,源码比较简单,如 ...

  6. maven-过滤不打入包的文件

    在使用maven打包时,有时有些测试文件,或者配置都希望打入到架包中 此时就需要使用将不用的文件过滤,maven有很方便的过滤插件.因工作时间,暂不讨论.本次讨论一个非常简单除暴的方法,通过配置ecl ...

  7. 一个脚本可以一直运行 ignore_user_abort

    php中ignore_user_abort函数的用法 PHP中的ignore_user_abort函数是当用户关掉终端后脚本不停止仍然在执行,可以用它来实现计划任务与持续进程,下面会通过实例讨论ign ...

  8. jquery中ajax用return来返回值无效

    jquery中,ajax返回值,有三种写法,只有其中一种是成功的 /** * async:false,同步调用 * 返回1:2 * 失败 * 分析:ajax内部是一个或多个定义的函数,ajax中ret ...

  9. 【poj3744】 Scout YYF I

    http://poj.org/problem?id=3744 (题目链接) 题意 给出n个雷,分别在 a[1]...a[n] ,走一步概率为 p ,走两步概率为 1-p ,一开始在 1 号位置,问安全 ...

  10. dataTables添加序号和行选中框

    <table id="mytable" class="table table-striped table-bordered" width="10 ...