OpenXML将DataTable中数据导出到Excel示例
2011-11-14 23:16 ps_zw 阅读(2329) 评论(4) 编辑 收藏 举报前言:将DataTable中得数据导出到Excel中游很多中实现方式,这里介绍一下使用OpenXML将数据导出到Excel中。本文进给出代码,详细介绍将在后续文章中一一给出。(文中有不当之处还望各位大虾指出)
说明:OpenXML只能操作Office2007以上版本,且需要使用LINQ。
使用OpenXML将数据导出到Excel中大致有以下几步:
一、下载OpenXML的SDK,这个SDK里包含了导出所需的dll,点击这里下载,安装SDK需要.net3.5SP1以上版本。
二、添加对程序集 DocumentFormat.OpenXml.dll 和 WindowBase.dll的引用
三、在指定目录创建Excel文档 参考方法:SpreadsheetDocument CreateParts(string filePath)
四、创建工作簿WorksheetPart,它必须被创建,否则无法存储数据,对象创建后需要调用Save方法
(参见代码中的 newWorksheetPart.Worksheet.Save());
五、将数据插入到Excel中,插入时需要一个单元格一个单元格的插入数据;
六、创建一个SharedStringTablePart(相当于各Sheet共用的存放字符串的容器);
七、如果需要还可以在代码中设置单元格格式,如:合并单元格,设置字体,插入图片等。
具体的代码示例如下:
1.在指定路径创建SpreadsheetDocument文档;
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 ///<summary>
2 /// 在指定路径创建SpreadsheetDocument文档
3 ///</summary>
4 ///<param name="filePath">Excel文档的保存路径</param>
5 ///<returns></returns>
6 private SpreadsheetDocument CreateParts(string filePath)
7 {
8 SpreadsheetDocument document = SpreadsheetDocument.Create(filePath, SpreadsheetDocumentType.Workbook);
9
10 WorkbookPart workbookPart = document.AddWorkbookPart();
11
12 workbookPart.Workbook = new Workbook();
13
14 return document;
15 }
2.创建WorksheetPart
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 ///<summary>
2 /// 创建WorksheetPart
3 ///</summary>
4 ///<param name="workbookPart"></param>
5 ///<param name="sheetName"></param>
6 private WorksheetPart CreateWorksheet(WorkbookPart workbookPart, string sheetName)
7 {
8 WorksheetPart newWorksheetPart = workbookPart.AddNewPart<WorksheetPart>();
9
10 newWorksheetPart.Worksheet = new Worksheet(new SheetData());
11
12 newWorksheetPart.Worksheet.Save();
13
14 Sheets sheets = workbookPart.Workbook.GetFirstChild<Sheets>();
15 if (sheets == null)
16 sheets = workbookPart.Workbook.AppendChild<Sheets>(new Sheets());
17
18 string relationshipId = workbookPart.GetIdOfPart(newWorksheetPart);
19
20 uint sheetId = 1;
21
22 if (sheets.Elements<Sheet>().Count() > 0)
23 {//确定sheet的唯一编号
24 sheetId = sheets.Elements<Sheet>().Select(s => s.SheetId.Value).Max() + 1;
25 }
26 if (string.IsNullOrEmpty(sheetName))
27 {
28 sheetName = "Sheet" + sheetId;
29 }
30
31 Sheet sheet = new Sheet() { Id = relationshipId, SheetId = sheetId, Name = sheetName };
32 sheets.Append(sheet);
33
34 workbookPart.Workbook.Save();
35
36 return newWorksheetPart;
37 }
3. 创建sheet样式
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 ///<summary>
2 /// 创建sheet样式
3 ///</summary>
4 ///<param name="workbookPart"></param>
5 ///<returns></returns>
6 private Stylesheet CreateStylesheet(WorkbookPart workbookPart)
7 {
8 Stylesheet stylesheet = null;
9
10 if (workbookPart.WorkbookStylesPart != null)
11 {
12 stylesheet = workbookPart.WorkbookStylesPart.Stylesheet;
13 if (stylesheet != null)
14 {
15 return stylesheet;
16 }
17 }
18 workbookPart.AddNewPart<WorkbookStylesPart>("Style");
19 workbookPart.WorkbookStylesPart.Stylesheet = new Stylesheet();
20 stylesheet = workbookPart.WorkbookStylesPart.Stylesheet;
21
22 stylesheet.Fonts = new Fonts()
23 {
24 Count = (UInt32Value)3U
25 };
26
27 //fontId =0,默认样式
28 Font fontDefault = new Font(
29 new FontSize() { Val = 11D },
30 new FontName() { Val = "Calibri" },
31 new FontFamily() { Val = 2 },
32 new FontScheme() { Val = FontSchemeValues.Minor });
33
34 stylesheet.Fonts.Append(fontDefault);
35
36 //fontId =1,标题样式
37 Font fontTitle = new Font(new FontSize() { Val = 15D },
38 new Bold() { Val = true },
39 new FontName() { Val = "Calibri" },
40 new FontFamily() { Val = 2 },
41 new FontScheme() { Val = FontSchemeValues.Minor });
42 stylesheet.Fonts.Append(fontTitle);
43
44 //fontId =2,列头样式
45 Font fontHeader = new Font(new FontSize() { Val = 13D },
46 new Bold() { Val = true },
47 new FontName() { Val = "Calibri" },
48 new FontFamily() { Val = 2 },
49 new FontScheme() { Val = FontSchemeValues.Minor });
50 stylesheet.Fonts.Append(fontHeader);
51
52 //fillId,0总是None,1总是gray125,自定义的从fillid =2开始
53 stylesheet.Fills = new Fills()
54 {
55 Count = (UInt32Value)3U
56 };
57
58 //fillid=0
59 Fill fillDefault = new Fill(new PatternFill() { PatternType = PatternValues.None });
60 stylesheet.Fills.Append(fillDefault);
61
62 //fillid=1
63 Fill fillGray = new Fill();
64 PatternFill patternFillGray = new PatternFill()
65 {
66 PatternType = PatternValues.Gray125
67 };
68 fillGray.Append(patternFillGray);
69 stylesheet.Fills.Append(fillGray);
70
71 //fillid=2
72 Fill fillYellow = new Fill();
73 PatternFill patternFillYellow = new PatternFill(new ForegroundColor() { Rgb = new HexBinaryValue() { Value = "FFFFFF00" } })
74 {
75 PatternType = PatternValues.Solid
76 };
77 fillYellow.Append(patternFillYellow);
78 stylesheet.Fills.Append(fillYellow);
79
80 stylesheet.Borders = new Borders()
81 {
82 Count = (UInt32Value)2U
83 };
84
85 //borderID=0
86 Border borderDefault = new Border(new LeftBorder(), new RightBorder(), new TopBorder() { }, new BottomBorder(), new DiagonalBorder());
87 stylesheet.Borders.Append(borderDefault);
88
89 //borderID=1
90 Border borderContent = new Border(
91 new LeftBorder(new Color() { Auto = true }) { Style = BorderStyleValues.Thin },
92 new RightBorder(new Color() { Auto = true }) { Style = BorderStyleValues.Thin },
93 new TopBorder(new Color() { Auto = true }) { Style = BorderStyleValues.Thin },
94 new BottomBorder(new Color() { Auto = true }) { Style = BorderStyleValues.Thin },
95 new DiagonalBorder()
96 );
97 stylesheet.Borders.Append(borderContent);
98
99 stylesheet.CellFormats = new CellFormats();
100 stylesheet.CellFormats.Count = 3;
101
102 //styleIndex =0U
103 CellFormat cfDefault = new CellFormat();
104 cfDefault.Alignment = new Alignment();
105 cfDefault.NumberFormatId = 0;
106 cfDefault.FontId = 0;
107 cfDefault.BorderId = 0;
108 cfDefault.FillId = 0;
109 cfDefault.ApplyAlignment = true;
110 cfDefault.ApplyBorder = true;
111 stylesheet.CellFormats.Append(cfDefault);
112
113 //styleIndex =1U
114 CellFormat cfTitle = new CellFormat();
115 cfTitle.Alignment = new Alignment();
116 cfTitle.NumberFormatId = 0;
117 cfTitle.FontId = 1;
118 cfTitle.BorderId = 1;
119 cfTitle.FillId = 0;
120 cfTitle.ApplyBorder = true;
121 cfTitle.ApplyAlignment = true;
122 cfTitle.Alignment.Horizontal = HorizontalAlignmentValues.Center;
123 stylesheet.CellFormats.Append(cfTitle);
124
125 //styleIndex =2U
126 CellFormat cfHeader = new CellFormat();
127 cfHeader.Alignment = new Alignment();
128 cfHeader.NumberFormatId = 0;
129 cfHeader.FontId = 2;
130 cfHeader.BorderId = 1;
131 cfHeader.FillId = 2;
132 cfHeader.ApplyAlignment = true;
133 cfHeader.ApplyBorder = true;
134 cfHeader.ApplyFill = true;
135 cfHeader.Alignment.Horizontal = HorizontalAlignmentValues.Center;
136 stylesheet.CellFormats.Append(cfHeader);
137
138 //styleIndex =3U
139 CellFormat cfContent = new CellFormat();
140 cfContent.Alignment = new Alignment();
141 cfContent.NumberFormatId = 0;
142 cfContent.FontId = 0;
143 cfContent.BorderId = 1;
144 cfContent.FillId = 0;
145 cfContent.ApplyAlignment = true;
146 cfContent.ApplyBorder = true;
147 stylesheet.CellFormats.Append(cfContent);
148
149 workbookPart.WorkbookStylesPart.Stylesheet.Save();
150 return stylesheet;
151 }
4. 创建文本单元格(没有格式,仅填充数据)
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 ///<summary>
2 /// 创建文本单元格,Cell的内容均视为文本
3 ///</summary>
4 ///<param name="columnIndex"></param>
5 ///<param name="rowIndex"></param>
6 ///<param name="cellValue"></param>
7 ///<returns></returns>
8 private Cell CreateTextCell(int columnIndex, int rowIndex, object cellValue, Nullable<uint> styleIndex)
9 {
10 Cell cell = new Cell();
11
12 cell.DataType = CellValues.InlineString;
13
14 cell.CellReference = GetCellReference(columnIndex) + rowIndex;
15
16 if (styleIndex.HasValue)
17 cell.StyleIndex = styleIndex.Value;
18
19 InlineString inlineString = new InlineString();
20 Text t = new Text();
21
22 t.Text = cellValue.ToString();
23 inlineString.AppendChild(t);
24 cell.AppendChild(inlineString);
25
26 return cell;
27 }
5.按指定的格式创建单元格
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 ///<summary>
2 /// 创建值单元格,Cell会根据单元格值的类型
3 ///</summary>
4 ///<param name="columnIndex"></param>
5 ///<param name="rowIndex"></param>
6 ///<param name="cellValue"></param>
7 ///<param name="styleIndex"></param>
8 ///<returns></returns>
9 private Cell CreateValueCell(int columnIndex, int rowIndex, object cellValue, Nullable<uint> styleIndex)
10 {
11 Cell cell = new Cell();
12 cell.CellReference = GetCellReference(columnIndex) + rowIndex;
13 CellValue value = new CellValue();
14 value.Text = cellValue.ToString();
15
16 //apply the cell style if supplied
17 if (styleIndex.HasValue)
18 cell.StyleIndex = styleIndex.Value;
19
20 cell.AppendChild(value);
21
22 return cell;
23 }
6.获取行引用
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 ///<summary>
2 /// 获取行引用,如A1
3 ///</summary>
4 ///<param name="colIndex"></param>
5 ///<returns></returns>
6 private string GetCellReference(int colIndex)
7 {
8 int dividend = colIndex;
9 string columnName = String.Empty;
10 int modifier;
11
12 while (dividend > 0)
13 {
14 modifier = (dividend - 1) % 26;
15 columnName =
16 Convert.ToChar(65 + modifier).ToString() + columnName;
17 dividend = (int)((dividend - modifier) / 26);
18 }
19 return columnName;
20 }
7. 创建行数据
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 ///<summary>
2 /// 创建行数据,不同类型使用不同的styleIndex
3 ///</summary>
4 ///<param name="dataRow"></param>
5 ///<param name="rowIndex"></param>
6 ///<returns></returns>
7 private Row CreateDataRow(DataRow dataRow, int rowIndex)
8 {
9 Row row = new Row
10 {
11 RowIndex = (UInt32)rowIndex
12 };
13
14 Nullable<uint> styleIndex = null;
15 double doubleValue;
16 int intValue;
17 DateTime dateValue;
18 decimal decValue;
19
20 for (int i = 0; i < dataRow.Table.Columns.Count; i++)
21 {
22 Cell dataCell;
23 if (DateTime.TryParse(dataRow[i].ToString(), out dateValue) && dataRow[i].GetType() == typeof(DateTime))
24 {
25 dataCell = CreateTextCell(i + 1, rowIndex, dataRow[i], 3u);
26 //dataCell.DataType = CellValues.Date;
27 }
28 else if (decimal.TryParse(dataRow[i].ToString(), out decValue) && dataRow[i].GetType() == typeof(decimal))
29 {
30 dataCell = CreateValueCell(i + 1, rowIndex, decValue, 3u);
31 }
32 else if (int.TryParse(dataRow[i].ToString(), out intValue) && dataRow[i].GetType() == typeof(int))
33 {
34 dataCell = CreateValueCell(i + 1, rowIndex, intValue, 3u);
35 }
36 else if (Double.TryParse(dataRow[i].ToString(), out doubleValue) && dataRow[i].GetType() == typeof(double))
37 {
38 dataCell = CreateValueCell(i + 1, rowIndex, doubleValue, 3u);
39 }
40 else
41 {
42 dataCell = CreateTextCell(i + 1, rowIndex, dataRow[i], 3u);
43 }
44
45 row.AppendChild(dataCell);
46 styleIndex = null;
47 }
48 return row;
49 }
7. 将DataTable中得数据插入到Sheet中
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 ///<summary>
2 /// 将数据插入到sheet中
3 ///</summary>
4 ///<param name="dt"></param>
5 ///<param name="newWorksheetPart"></param>
6 ///<returns></returns>
7 private void InsertDataIntoSheet(DataTable dt, SheetData sheetData)
8 {
9 //SheetData sheetData = newWorksheetPart.Worksheet.GetFirstChild<SheetData>();
10
11 // CreateTableHeader(dt, sheetData);
12
13 for (int i = 0; i < dt.Rows.Count; i++)
14 {
15 Row contentRow = CreateContentRow(dt.Rows[i], i + 3);
16 sheetData.AppendChild(contentRow);
17 }
18 return;
19 }
8. 创建一个SharedStringTablePart(相当于各Sheet共用的存放字符串的容器)
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 ///<summary>
2 /// 创建一个SharedStringTablePart(相当于各Sheet共用的存放字符串的容器)
3 ///</summary>
4 ///<param name="workbookPart"></param>
5 ///<returns></returns>
6 private SharedStringTablePart CreateSharedStringTablePart(WorkbookPart workbookPart)
7 {
8 SharedStringTablePart shareStringPart = null;
9 if (workbookPart.GetPartsOfType<SharedStringTablePart>().Count() > 0)
10 {
11 shareStringPart = workbookPart.GetPartsOfType<SharedStringTablePart>().First();
12 }
13 else
14 {
15 shareStringPart = workbookPart.AddNewPart<SharedStringTablePart>();
16 }
17 return shareStringPart;
18 }
9 .执行导出方法
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 ///<summary>
2 /// 执行导出
3 ///</summary>
4 ///<param name="dt"></param>
5 ///<param name="filePath"></param>
6 private void DoExport(DataTable dt, string filePath)
7 {
8 try
9 {
10 using (SpreadsheetDocument document = CreateParts(filePath))
11 {
12 WorksheetPart worksheetPart = CreateWorksheet(document.WorkbookPart, parameter.SheetName);
13
14 SheetData sheetData = worksheetPart.Worksheet.GetFirstChild<SheetData>();
15
16 Stylesheet styleSheet = CreateStylesheet(document.WorkbookPart);
17
18 InsertTableTitle(parameter.SheetName, sheetData, styleSheet);
19
20 // MergeTableTitleCells(dt.Columns.Count, worksheetPart.Worksheet);
21
22 //CreateTableHeader(dt, sheetData);
23
24 InsertDataIntoSheet(dt, sheetData);
25
26 SharedStringTablePart sharestringTablePart = CreateSharedStringTablePart(document.WorkbookPart);
27 sharestringTablePart.SharedStringTable = new SharedStringTable();
28
29 sharestringTablePart.SharedStringTable.AppendChild(new SharedStringItem(new DocumentFormat.OpenXml.Spreadsheet.Text("ExcelReader")));
30 sharestringTablePart.SharedStringTable.Save();
31 }
32 result = 0;
33 }
34 catch (Exception ex)
35 {
36 iSession.AddError(ex);
37 result = error_result_prefix - 99;
38 }
39 return result;
40 }
这里列出了使用OpenXML创建Excel文档的祥光代码,后续我将具体给出分析。