c#怎么将datatable数据保存到excel中
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了c#怎么将datatable数据保存到excel中相关的知识,希望对你有一定的参考价值。
参考技术A采用第三方类库工具是一种可快速导出数据的方法,如下spire.xla for .net的导出方法:
//创建一个workbook对象,默认创建03版的Excel
Workbook workbook = new Workbook();
//指定版本信息,07及以上版本最多可以插入1048576行数据
workbook.Version = ExcelVersion.Version2013;
//获取第一张sheet
Worksheet sheet = workbook.Worksheets[0];
//得到在datatable里的数据
DataTable dt = GetDataTable();
//从第一行第一列开始插入数据,true代表数据包含列名
sheet.InsertDataTable(dt, true, 1, 1);
//保存文件
workbook.SaveToFile("ExportDataToExcel.xlsx",ExcelVersion.Version2013);
代码整理参考自原文。
在 c# 中使用 Open Xml SDK 将 DataTable 导出到 Excel
【中文标题】在 c# 中使用 Open Xml SDK 将 DataTable 导出到 Excel【英文标题】:Export DataTable to Excel with Open Xml SDK in c# 【发布时间】:2012-08-04 18:42:59 【问题描述】:我的程序能够将一些数据和 DataTable 导出到 Excel 文件(模板) 在模板中,我将数据插入到一些占位符中。它工作得很好,但我也需要插入一个 DataTable ...... 我的示例代码:
using (Stream OutStream = new MemoryStream())
// read teamplate
using (var fileStream = File.OpenRead(templatePath))
fileStream.CopyTo(OutStream);
// exporting
Exporting(OutStream);
// to start
OutStream.Seek(0L, SeekOrigin.Begin);
// out
using (var resultFile = File.Create(resultPath))
OutStream.CopyTo(resultFile);
下一个导出方法
private void Exporting(Stream template)
using (var workbook = SpreadsheetDocument.Open(template, true, new OpenSettings AutoSave = true ))
// Replace shared strings
SharedStringTablePart sharedStringsPart = workbook.WorkbookPart.SharedStringTablePart;
IEnumerable<Text> sharedStringTextElements = sharedStringsPart.SharedStringTable.Descendants<Text>();
DoReplace(sharedStringTextElements);
// Replace inline strings
IEnumerable<WorksheetPart> worksheetParts = workbook.GetPartsOfType<WorksheetPart>();
foreach (var worksheet in worksheetParts)
DoReplace(worksheet.Worksheet.Descendants<Text>());
int z = 40;
foreach (System.Data.DataRow row in ExcelWorkXLSX.ToOut.Rows)
for (int i = 0; i < row.ItemArray.Count(); i++)
ExcelWorkXLSX.InsertText(workbook, row.ItemArray.ElementAt(i).ToString(), getColumnName(i), Convert.ToUInt32(z));
z++;
但是这个片段输出DataTable slooooooooooooooooooooowwwwwww...
如何快速、真实地将 DataTable 导出到 Excel?
【问题讨论】:
需要使用open xml sdk吗? 嗯...不,但打开 xml sdk 快速读/写 excel 文件。在我的程序中,我读取 xlsx 文件,将数据抓取到 datagridview(使用 DataTable),重新检查数据。首先我使用互操作,但它需要excel并且非常慢。我的问题只是出口。但是,我现在不想重写很多代码:) 【参考方案1】:我写了这个简单的例子。这个对我有用。我只用一个数据集测试了它,里面有一张表,但我想这对你来说可能就足够了。
考虑到我将所有单元格视为字符串(甚至不是 SharedStrings)。如果您想使用 SharedStrings,您可能需要稍微调整一下我的示例。
编辑:要完成这项工作,需要将 WindowsBase 和 DocumentFormat.OpenXml 引用添加到项目中。
享受,
private void ExportDataSet(DataSet ds, string destination)
using (var workbook = SpreadsheetDocument.Create(destination, DocumentFormat.OpenXml.SpreadsheetDocumentType.Workbook))
var workbookPart = workbook.AddWorkbookPart();
workbook.WorkbookPart.Workbook = new DocumentFormat.OpenXml.Spreadsheet.Workbook();
workbook.WorkbookPart.Workbook.Sheets = new DocumentFormat.OpenXml.Spreadsheet.Sheets();
foreach (System.Data.DataTable table in ds.Tables)
var sheetPart = workbook.WorkbookPart.AddNewPart<WorksheetPart>();
var sheetData = new DocumentFormat.OpenXml.Spreadsheet.SheetData();
sheetPart.Worksheet = new DocumentFormat.OpenXml.Spreadsheet.Worksheet(sheetData);
DocumentFormat.OpenXml.Spreadsheet.Sheets sheets = workbook.WorkbookPart.Workbook.GetFirstChild<DocumentFormat.OpenXml.Spreadsheet.Sheets>();
string relationshipId = workbook.WorkbookPart.GetIdOfPart(sheetPart);
uint sheetId = 1;
if (sheets.Elements<DocumentFormat.OpenXml.Spreadsheet.Sheet>().Count() > 0)
sheetId =
sheets.Elements<DocumentFormat.OpenXml.Spreadsheet.Sheet>().Select(s => s.SheetId.Value).Max() + 1;
DocumentFormat.OpenXml.Spreadsheet.Sheet sheet = new DocumentFormat.OpenXml.Spreadsheet.Sheet() Id = relationshipId, SheetId = sheetId, Name = table.TableName ;
sheets.Append(sheet);
DocumentFormat.OpenXml.Spreadsheet.Row headerRow = new DocumentFormat.OpenXml.Spreadsheet.Row();
List<String> columns = new List<string>();
foreach (System.Data.DataColumn column in table.Columns)
columns.Add(column.ColumnName);
DocumentFormat.OpenXml.Spreadsheet.Cell cell = new DocumentFormat.OpenXml.Spreadsheet.Cell();
cell.DataType = DocumentFormat.OpenXml.Spreadsheet.CellValues.String;
cell.CellValue = new DocumentFormat.OpenXml.Spreadsheet.CellValue(column.ColumnName);
headerRow.AppendChild(cell);
sheetData.AppendChild(headerRow);
foreach (System.Data.DataRow dsrow in table.Rows)
DocumentFormat.OpenXml.Spreadsheet.Row newRow = new DocumentFormat.OpenXml.Spreadsheet.Row();
foreach (String col in columns)
DocumentFormat.OpenXml.Spreadsheet.Cell cell = new DocumentFormat.OpenXml.Spreadsheet.Cell();
cell.DataType = DocumentFormat.OpenXml.Spreadsheet.CellValues.String;
cell.CellValue = new DocumentFormat.OpenXml.Spreadsheet.CellValue(dsrow[col].ToString()); //
newRow.AppendChild(cell);
sheetData.AppendChild(newRow);
【讨论】:
我认为workbook.WorkbookPart.Workbook = new...
和 workbook.WorkbookPart.Workbook.Sheets = new
应该移到 foreach 循环之外。否则,循环的每次迭代都会替换工作表,导致 excel 文件仅包含最终的 DataTable
。
@Brian ,感谢您指出这一点。它最初是有效的,因为我只用一张桌子进行了测试。我刚刚修好了,现在还好吗?
是的,看起来不错。顺便说一句,调用 .Max(s=>s.SheetId.Value)
比调用 .Select(s=>s.SheetId.Value).Max()
更干净。同样,您不需要List<String> columns
,因为DataRow
有一个DataColumn
索引器;第二个foreach
也可以迭代table.Columns
。
哦,好吧,我猜这只是为了教育目的:) 谢谢
我自己想通了。要完成这项工作,有必要向项目添加WindowsBase
和DocumentFormat.OpenXml
引用。 SpreadsheetDocument
和 WorksheetPart
也在 DocumentFormat.OpenXml.Packaging
命名空间中【参考方案2】:
eburgos,我稍微修改了您的代码,因为当您的数据集中有多个数据表时,它只是在电子表格中覆盖它们,因此您在工作簿中只剩下一张工作表。我基本上只是将创建工作簿的部分移出循环。这是更新后的代码。
private void ExportDSToExcel(DataSet ds, string destination)
using (var workbook = SpreadsheetDocument.Create(destination, DocumentFormat.OpenXml.SpreadsheetDocumentType.Workbook))
var workbookPart = workbook.AddWorkbookPart();
workbook.WorkbookPart.Workbook = new DocumentFormat.OpenXml.Spreadsheet.Workbook();
workbook.WorkbookPart.Workbook.Sheets = new DocumentFormat.OpenXml.Spreadsheet.Sheets();
uint sheetId = 1;
foreach (DataTable table in ds.Tables)
var sheetPart = workbook.WorkbookPart.AddNewPart<WorksheetPart>();
var sheetData = new DocumentFormat.OpenXml.Spreadsheet.SheetData();
sheetPart.Worksheet = new DocumentFormat.OpenXml.Spreadsheet.Worksheet(sheetData);
DocumentFormat.OpenXml.Spreadsheet.Sheets sheets = workbook.WorkbookPart.Workbook.GetFirstChild<DocumentFormat.OpenXml.Spreadsheet.Sheets>();
string relationshipId = workbook.WorkbookPart.GetIdOfPart(sheetPart);
if (sheets.Elements<DocumentFormat.OpenXml.Spreadsheet.Sheet>().Count() > 0)
sheetId =
sheets.Elements<DocumentFormat.OpenXml.Spreadsheet.Sheet>().Select(s => s.SheetId.Value).Max() + 1;
DocumentFormat.OpenXml.Spreadsheet.Sheet sheet = new DocumentFormat.OpenXml.Spreadsheet.Sheet() Id = relationshipId, SheetId = sheetId, Name = table.TableName ;
sheets.Append(sheet);
DocumentFormat.OpenXml.Spreadsheet.Row headerRow = new DocumentFormat.OpenXml.Spreadsheet.Row();
List<String> columns = new List<string>();
foreach (DataColumn column in table.Columns)
columns.Add(column.ColumnName);
DocumentFormat.OpenXml.Spreadsheet.Cell cell = new DocumentFormat.OpenXml.Spreadsheet.Cell();
cell.DataType = DocumentFormat.OpenXml.Spreadsheet.CellValues.String;
cell.CellValue = new DocumentFormat.OpenXml.Spreadsheet.CellValue(column.ColumnName);
headerRow.AppendChild(cell);
sheetData.AppendChild(headerRow);
foreach (DataRow dsrow in table.Rows)
DocumentFormat.OpenXml.Spreadsheet.Row newRow = new DocumentFormat.OpenXml.Spreadsheet.Row();
foreach (String col in columns)
DocumentFormat.OpenXml.Spreadsheet.Cell cell = new DocumentFormat.OpenXml.Spreadsheet.Cell();
cell.DataType = DocumentFormat.OpenXml.Spreadsheet.CellValues.String;
cell.CellValue = new DocumentFormat.OpenXml.Spreadsheet.CellValue(dsrow[col].ToString()); //
newRow.AppendChild(cell);
sheetData.AppendChild(newRow);
【讨论】:
谢谢,刚刚看到布赖恩的评论,我也做了同样的事情。【参考方案3】:我还写了一个 C#/VB.Net “导出到 Excel” 库,它使用 OpenXML 并且(更重要的是)也使用 OpenXmlWriter,因此在编写大文件时不会耗尽内存。
完整的源代码和演示可以在这里下载:
Export to Excel
它非常容易使用。
只需将您要写入的文件名和DataTable
、DataSet
或List<>
传递给它。
CreateExcelFile.CreateExcelDocument(myDataSet, "MyFilename.xlsx");
如果您从 ASP.Net 应用程序调用它,请将 HttpResponse
传递给它以将文件写入。
CreateExcelFile.CreateExcelDocument(myDataSet, "MyFilename.xlsx", Response);
【讨论】:
对不起...!它现在又活过来了。 @MikeGledhill 是否有任何异步解决方法?尝试写入大文件时出现内存不足异常,我已经阅读了所有相关帖子,似乎它仅限于可用内存? @Afr0:不应该这样。我的库使用 OpenXmlWriter 来写出数据,而不是先尝试在内存中构建整个 Excel 文件。如果可能,请通过我的网站给我发电子邮件,我会看看是否可以提供帮助。 可能我得到的代码库的编写方式不太清楚。【参考方案4】:我编写了自己的导出到 Excel 编写器,因为没有其他东西完全满足我的需求。它速度很快,并允许对单元格进行大量格式化。您可以在
查看它https://openxmlexporttoexcel.codeplex.com/
希望对你有帮助。
【讨论】:
【参考方案5】:您可以尝试看看这个库。我已将它用于我的一个项目,发现它非常易于使用、可靠且快速(我仅将其用于导出数据)。
http://epplus.codeplex.com/
【讨论】:
谢谢!这是一个想法!我会尝试仅用于出口。【参考方案6】:你可以看看我的图书馆here。在文档部分下,您将找到如何导入数据表。
你只需要写
using (var doc = new SpreadsheetDocument(@"C:\OpenXmlPackaging.xlsx"))
Worksheet sheet1 = doc.Worksheets.Add("My Sheet");
sheet1.ImportDataTable(ds.Tables[0], "A1", true);
希望对你有帮助!
【讨论】:
【参考方案7】:我尝试了接受的答案,但在尝试打开时收到消息说生成的 excel 文件已损坏。我可以通过一些修改来修复它,比如在代码的行尾添加。
workbookPart.Workbook.Save();
我已经发布了完整代码@Export DataTable to Excel with Open XML in c#
【讨论】:
【参考方案8】:我想添加这个答案,因为我使用了这个问题的主要答案作为我使用 OpenXML 从数据表导出到 Excel 的基础,但是当我发现它比上述方法快得多时转换到 OpenXMLWriter。
您可以在下面链接中的我的回答中找到完整的详细信息。不过我的代码是在 VB.NET 中的,所以你必须转换它。
How to export DataTable to Excel
【讨论】:
以上是关于c#怎么将datatable数据保存到excel中的主要内容,如果未能解决你的问题,请参考以下文章
C#写ASP.NET,怎么导出一个DataTable到Excel
如何在.net 2.0中将数据从数据库或DataTable保存到Excel文件而没有响应