使用Open xml 操作Excel系列之二--从data table导出数据到Excel
由于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的更多相关文章
- python 导出数据到excel 中,一个好用的导出数据到excel模块,XlsxWriter
最近公司有项目需要导出数据到excel,首先想到了,tablib,xlwt,xlrd,xlwings,win32com[还可以操作word],openpyxl,等模块但是 实际操作中tablib 写入 ...
- 【js-xlsx和file-saver插件】前端html的table导出数据到excel的表格合并显示boder
最近在做项目,需要从页面的表格中导出excel,一般导出excel有两种方法:一.习惯上是建模版从后台服务程序中导出:二.根据页面table中导出:综合考虑其中利弊选择二.根据页面table中导出ex ...
- Dynamics CRM导出数据到Excel
原创地址:http://www.cnblogs.com/jfzhu/p/4276212.html 转载请注明出处 Pivot Table是微软BI的一个重要工具,所以这里讲一下Dynamics CRM ...
- 微软BI 之SSIS 系列 - 导出数据到 Excel 2013 的实现
开篇介绍 碰到有几个朋友问到这个问题,比较共性,就特意写了这篇小文章说明一下如何实现在 SSIS 中导出数据到 Office Excel 2013 中.通常情况下 2013 以前的版本大多没有问题,但 ...
- Java操作Jxl实现导出数据生成Excel表格数据文件
实现:前台用的框架是Easyui+Bootstrap结合使用,需要引入相应的Js.Css文件.页面:Jsp.拦截请求:Servlet.逻辑处理:ClassBean.数据库:SQLserver. 注意: ...
- 从数据库导出数据到excel之POI操作
项目说明: 1:数据库中有两张表,主键关联 2:根据条件查询数据 3:处理为需要的数据封装类型,然后传到导出excel的方法中 <--框架部署就不详谈了,用的spring框架--> 补充: ...
- 导出数据到Excel方法总结
一,问题的提出 近来在网上经常有人问怎样把数据导出到Excel中?针对这个问题网上也有很多资料.大都比较的琐碎.本人当前从事的项目中,刚好涉及到这些内容.就顺便做了一些归纳整理.共享给大家.避免大家再 ...
- pl/sql developer导出数据到excel的方法
http://yedward.net/?id=92 问题说明:使用pl/sql developer导出数据到excel表格中是非常有必要的,一般的可能直接在导出的时候选择csv格式即可,因为该格式可以 ...
- 1.ASP.NET MVC使用EPPlus,导出数据到Excel中
好久没写博客了,今天特地来更新一下,今天我们要学习的是如何导出数据到Excel文件中,这里我使用的是免费开源的Epplus组件. 源代码下载:https://github.com/caofangshe ...
随机推荐
- Winform进程、线程
进程: 一般来说,一个程序就是一个进程,不过也有一个程序需要多个进程支持的情况. 进程要使用的类是:Process它在命名空间:System.Diagnostics; 1.静态方法Start(); 2 ...
- flex自适应高度内容高度超出容器高度自动出现滚动条的问题
在容器中设置 flex-grow:2; overflow-y:auto;overflow-x:hidden;容器高度自适应. 内容高度不固定,无法出现滚动条,然后在容器中添加height:0,出现滚动 ...
- [LeetCode] Matchsticks to Square 火柴棍组成正方形
Remember the story of Little Match Girl? By now, you know exactly what matchsticks the little match ...
- [LeetCode] Majority Element II 求众数之二
Given an integer array of size n, find all elements that appear more than ⌊ n/3 ⌋ times. The algorit ...
- ACM模板(持续补完)
1.KMP #include<cstring> #include<algorithm> #include<cstdio> using namespace std; ...
- 1229【MySQL】性能优化之 Index Condition Pushdown
转自http://blog.itpub.net/22664653/viewspace-1210844/ [MySQL]性能优化之 Index Condition Pushdown2014-07-06 ...
- 庆祝下,提交了第一个ceph pull request。实现了从0到1的突破
庆祝一下!经过社区老司机的带路,昨天提交了第一个ceph pull request.实现了从0到1的突破,希望再接再厉提交更多代码到社区,为社区发展贡献一点自己力量. 提交的第一个被社区fix的bug ...
- iOS dealloc 不被调用的问题
最近项目中老是无缘无故的出现一下奔溃.查看一下堆栈信息,指针的指向都有,但还是奔溃.所以第一个怀疑出现野指针引起的问题.然后调试代码中的一下dealloc函数.好多对象在释放之后都没掉用.顿时吓出一身 ...
- div自适应高度
div自适应高度 Div即父容器不根据内容自适应高度,我们看下面的代码: <div id="main"> <div id="content"& ...
- iis6 服务器做301跳转返回状态码200解决方法。
倘若你的配置和上图一样的话,在查询返回值是200的情况,你试着把你服务器上的安全狗或者防火墙,还有360网站卫士之类的安全软件停止试试,看是否能正常.