c#(WinForms-App)将DataSet导出到Excel

我需要一个解决scheme将数据集导出到没有任何asp代码(HttpResonpsne …)的Excel文件,但我没有find一个很好的例子来做到这一点…

最好提前致谢

我创build了一个将DataGridViewDataTable导出到Excel文件的类。 您可以稍微改变一下,使其使用DataSet (迭代其中的DataTables )。 它也做一些基本的格式,你也可以扩展。

要使用它,只需调用ExcelExport,并指定文件名以及是否在导出后自动打开文件。 我也可以让他们扩展的方法,但我没有。 随意地。

请注意,Excel文件可以保存为一个荣耀的XML文档,并利用它。

编辑:这用来使用香草StreamWriter ,但正如指出的,事情不会在许多情况下正确逃脱。 现在它使用一个XmlWriter ,它会为你逃跑。

ExcelWriter类包装一个XmlWriter 。 我没有打扰,但是你可能想要做更多的错误检查,以确保你不能在开始一行之前写入单元格数据,等等。 代码如下。

 public class ExcelWriter : IDisposable { private XmlWriter _writer; public enum CellStyle { General, Number, Currency, DateTime, ShortDate }; public void WriteStartDocument() { if (_writer == null) throw new InvalidOperationException("Cannot write after closing."); _writer.WriteProcessingInstruction("mso-application", "progid=\"Excel.Sheet\""); _writer.WriteStartElement("ss", "Workbook", "urn:schemas-microsoft-com:office:spreadsheet"); WriteExcelStyles(); } public void WriteEndDocument() { if (_writer == null) throw new InvalidOperationException("Cannot write after closing."); _writer.WriteEndElement(); } private void WriteExcelStyleElement(CellStyle style) { _writer.WriteStartElement("Style", "urn:schemas-microsoft-com:office:spreadsheet"); _writer.WriteAttributeString("ID", "urn:schemas-microsoft-com:office:spreadsheet", style.ToString()); _writer.WriteEndElement(); } private void WriteExcelStyleElement(CellStyle style, string NumberFormat) { _writer.WriteStartElement("Style", "urn:schemas-microsoft-com:office:spreadsheet"); _writer.WriteAttributeString("ID", "urn:schemas-microsoft-com:office:spreadsheet", style.ToString()); _writer.WriteStartElement("NumberFormat", "urn:schemas-microsoft-com:office:spreadsheet"); _writer.WriteAttributeString("Format", "urn:schemas-microsoft-com:office:spreadsheet", NumberFormat); _writer.WriteEndElement(); _writer.WriteEndElement(); } private void WriteExcelStyles() { _writer.WriteStartElement("Styles", "urn:schemas-microsoft-com:office:spreadsheet"); WriteExcelStyleElement(CellStyle.General); WriteExcelStyleElement(CellStyle.Number, "General Number"); WriteExcelStyleElement(CellStyle.DateTime, "General Date"); WriteExcelStyleElement(CellStyle.Currency, "Currency"); WriteExcelStyleElement(CellStyle.ShortDate, "Short Date"); _writer.WriteEndElement(); } public void WriteStartWorksheet(string name) { if (_writer == null) throw new InvalidOperationException("Cannot write after closing."); _writer.WriteStartElement("Worksheet", "urn:schemas-microsoft-com:office:spreadsheet"); _writer.WriteAttributeString("Name", "urn:schemas-microsoft-com:office:spreadsheet", name); _writer.WriteStartElement("Table", "urn:schemas-microsoft-com:office:spreadsheet"); } public void WriteEndWorksheet() { if (_writer == null) throw new InvalidOperationException("Cannot write after closing."); _writer.WriteEndElement(); _writer.WriteEndElement(); } public ExcelWriter(string outputFileName) { XmlWriterSettings settings = new XmlWriterSettings(); settings.Indent = true; _writer = XmlWriter.Create(outputFileName, settings); } public void Close() { if (_writer == null) throw new InvalidOperationException("Already closed."); _writer.Close(); _writer = null; } public void WriteExcelColumnDefinition(int columnWidth) { if (_writer == null) throw new InvalidOperationException("Cannot write after closing."); _writer.WriteStartElement("Column", "urn:schemas-microsoft-com:office:spreadsheet"); _writer.WriteStartAttribute("Width", "urn:schemas-microsoft-com:office:spreadsheet"); _writer.WriteValue(columnWidth); _writer.WriteEndAttribute(); _writer.WriteEndElement(); } public void WriteExcelUnstyledCell(string value) { if (_writer == null) throw new InvalidOperationException("Cannot write after closing."); _writer.WriteStartElement("Cell", "urn:schemas-microsoft-com:office:spreadsheet"); _writer.WriteStartElement("Data", "urn:schemas-microsoft-com:office:spreadsheet"); _writer.WriteAttributeString("Type", "urn:schemas-microsoft-com:office:spreadsheet", "String"); _writer.WriteValue(value); _writer.WriteEndElement(); _writer.WriteEndElement(); } public void WriteStartRow() { if (_writer == null) throw new InvalidOperationException("Cannot write after closing."); _writer.WriteStartElement("Row", "urn:schemas-microsoft-com:office:spreadsheet"); } public void WriteEndRow() { if (_writer == null) throw new InvalidOperationException("Cannot write after closing."); _writer.WriteEndElement(); } public void WriteExcelStyledCell(object value, CellStyle style) { if (_writer == null) throw new InvalidOperationException("Cannot write after closing."); _writer.WriteStartElement("Cell", "urn:schemas-microsoft-com:office:spreadsheet"); _writer.WriteAttributeString("StyleID", "urn:schemas-microsoft-com:office:spreadsheet", style.ToString()); _writer.WriteStartElement("Data", "urn:schemas-microsoft-com:office:spreadsheet"); switch (style) { case CellStyle.General: _writer.WriteAttributeString("Type", "urn:schemas-microsoft-com:office:spreadsheet", "String"); break; case CellStyle.Number: case CellStyle.Currency: _writer.WriteAttributeString("Type", "urn:schemas-microsoft-com:office:spreadsheet", "Number"); break; case CellStyle.ShortDate: case CellStyle.DateTime: _writer.WriteAttributeString("Type", "urn:schemas-microsoft-com:office:spreadsheet", "DateTime"); break; } _writer.WriteValue(value); // tag += String.Format("{1}\"><ss:Data ss:Type=\"DateTime\">{0:yyyy\\-MM\\-dd\\THH\\:mm\\:ss\\.fff}</ss:Data>", value, _writer.WriteEndElement(); _writer.WriteEndElement(); } public void WriteExcelAutoStyledCell(object value) { if (_writer == null) throw new InvalidOperationException("Cannot write after closing."); //write the <ss:Cell> and <ss:Data> tags for something if (value is Int16 || value is Int32 || value is Int64 || value is SByte || value is UInt16 || value is UInt32 || value is UInt64 || value is Byte) { WriteExcelStyledCell(value, CellStyle.Number); } else if (value is Single || value is Double || value is Decimal) //we'll assume it's a currency { WriteExcelStyledCell(value, CellStyle.Currency); } else if (value is DateTime) { //check if there's no time information and use the appropriate style WriteExcelStyledCell(value, ((DateTime)value).TimeOfDay.CompareTo(new TimeSpan(0, 0, 0, 0, 0)) == 0 ? CellStyle.ShortDate : CellStyle.DateTime); } else { WriteExcelStyledCell(value, CellStyle.General); } } #region IDisposable Members public void Dispose() { if (_writer == null) return; _writer.Close(); _writer = null; } #endregion } 

然后您可以使用以下方式导出您的DataTable

 public static void ExcelExport(DataTable data, String fileName, bool openAfter) { //export a DataTable to Excel DialogResult retry = DialogResult.Retry; while (retry == DialogResult.Retry) { try { using (ExcelWriter writer = new ExcelWriter(fileName)) { writer.WriteStartDocument(); // Write the worksheet contents writer.WriteStartWorksheet("Sheet1"); //Write header row writer.WriteStartRow(); foreach (DataColumn col in data.Columns) writer.WriteExcelUnstyledCell(col.Caption); writer.WriteEndRow(); //write data foreach (DataRow row in data.Rows) { writer.WriteStartRow(); foreach (object o in row.ItemArray) { writer.WriteExcelAutoStyledCell(o); } writer.WriteEndRow(); } // Close up the document writer.WriteEndWorksheet(); writer.WriteEndDocument(); writer.Close(); if (openAfter) OpenFile(fileName); retry = DialogResult.Cancel; } } catch (Exception myException) { retry = MessageBox.Show(myException.Message, "Excel Export", MessageBoxButtons.RetryCancel, MessageBoxIcon.Asterisk); } } } 

以下站点演示如何将DataSet(或DataTable或List <>)导出到“ 正版 ”Excel 2007 .xlsx文件中。

它使用OpenXML库,所以你不需要在你的服务器上安装Excel。

MikesKnowledgeBase – ExportToExcel

所有的源代码是免费提供 ,以及演示应用程序。

添加到自己的应用程序非常简单,只需调用一个函数,传入Excel文件名和数据源即可:

 DataSet ds = CreateSampleData(); string excelFilename = "C:\\Sample.xlsx"; CreateExcelFile.CreateExcelDocument(ds, excelFilename); 

希望这可以帮助。

在.NET应用程序中创buildexcel文件是相当普遍的,以前也曾经有过类似的问题。 例如在这里和这里 。 最后一个问题是关于读取excel文件的问题,但是大多数build议的解决scheme应该是双向的。

 using XL = Microsoft.Office.Interop.Excel; using System.Reflection; public static void Datasource(DataTable dt) { XL.Application oXL; XL._Workbook oWB; XL._Worksheet oSheet; XL.Range oRng; try { oXL = new XL.Application(); Application.DoEvents(); oXL.Visible = false; //Get a new workbook. oWB = (XL._Workbook)(oXL.Workbooks.Add(Missing.Value)); oSheet = (XL._Worksheet)oWB.ActiveSheet; //System.Data.DataTable dtGridData=ds.Tables[0]; int iRow = 2; if (dt.Rows.Count > 0) { for (int j = 0; j < dt.Columns.Count; j++) { oSheet.Cells[1, j + 1] = dt.Columns[j].ColumnName; } // For each row, print the values of each column. for (int rowNo = 0; rowNo < dt.Rows.Count; rowNo++) { for (int colNo = 0; colNo < dt.Columns.Count; colNo++) { oSheet.Cells[iRow, colNo + 1] = dt.Rows[rowNo][colNo].ToString(); } iRow++; } iRow++; } oRng = oSheet.get_Range("A1", "IV1"); oRng.EntireColumn.AutoFit(); oXL.Visible = true; } catch (Exception theException) { throw theException; } finally { oXL = null; oWB = null; oSheet = null; oRng = null; } } Import from Excel to datatable DataTable dtTable = new DataTable(); DataColumn col = new DataColumn("Rfid"); dtTable.Columns.Add(col); DataRow drRow; Microsoft.Office.Interop.Excel.Application ExcelObj = new Microsoft.Office.Interop.Excel.Application(); Microsoft.Office.Interop.Excel.Workbook theWorkbook = ExcelObj.Workbooks.Open(txt_FilePath.Text, Type.Missing, Type.Missing, Type.Missing, Type.Missing, Type.Missing, Type.Missing, Type.Missing, Type.Missing, Type.Missing, Type.Missing, Type.Missing, Type.Missing, Type.Missing, Type.Missing); Microsoft.Office.Interop.Excel.Sheets sheets = theWorkbook.Worksheets; try { for (int sht = 1; sht <= sheets.Count; sht++) { Microsoft.Office.Interop.Excel.Worksheet worksheet = (Microsoft.Office.Interop.Excel.Worksheet)sheets.get_Item(sht); for (int i = 2; i <= worksheet.UsedRange.Rows.Count; i++) { Microsoft.Office.Interop.Excel.Range range = worksheet.get_Range("A" + i.ToString(), "B" + i.ToString()); System.Array myvalues = (System.Array)range.Cells.Value2; String name = Convert.ToString(myvalues.GetValue(1, 1)); if (string.IsNullOrEmpty(name) == false) { drRow = dtTable.NewRow(); drRow["Rfid"] = name; dtTable.Rows.Add(drRow); } } Marshal.ReleaseComObject(worksheet); worksheet = null; } return dtTable; } catch { throw; } finally { // Marshal.ReleaseComObject(worksheet); Marshal.ReleaseComObject(sheets); Marshal.ReleaseComObject(theWorkbook); Marshal.ReleaseComObject(ExcelObj); //worksheet = null; sheets = null; theWorkbook = null; ExcelObj = null; } 

这是一个非常有用的顶级答案,但是我发现它缺乏,因为没有简单的方法将XML文件导入到数据表中。 我最终不得不写下自己的想法,并认为我会在这里分享,以防其他人在同一条船上(谷歌在这方面特别没有帮助):

 public static DataTable ImportExcelXML(string Filename) { //create a new dataset to load in the XML file DataSet DS = new DataSet(); //Read the XML file into the dataset DS.ReadXml(Filename); //Create a new datatable to store the raw Data DataTable Raw = new DataTable(); //assign the raw data from the file to the datatable Raw = DS.Tables["Data"]; //count the number of columns in the XML file int ColumnNumber = Raw.Columns.Count; //create a datatable to store formatted Import Data DataTable ImportData = new DataTable(); //create a string list to store the cell data of each row List<string> RowData = new List<string>(); //loop through each row in the raw data table for (int Counter = 0; Counter < Raw.Rows.Count; Counter++) { //if the data in the row is a colum header if (Counter < ColumnNumber) { //add the column name to our formatted datatable ImportData.Columns.Add(Raw.Rows[Counter].ItemArray.GetValue(1).ToString()); } else { //if the row # (1 row = 1 cell from the excel file) from the raw datatable is divisable evenly by the number of columns in the formated import datatable AND this is not the 1st row of the raw table data after the headers if ((Counter % ColumnNumber == 0) && (Counter != ColumnNumber)) { //add the row we just built to the formatted import datatable ImportData.Rows.Add(GenerateRow(ImportData, RowData)); //clear rowdata list in preperation for the next row RowData.Clear(); } //add the current cell data value from the raw datatable to the string list of cell values for the next row to be added to the formatted input datatable RowData.Add(Raw.Rows[Counter].ItemArray.GetValue(1).ToString()); } } //add the final row ImportData.Rows.Add(GenerateRow(ImportData, RowData)); return ImportData; } public static DataRow GenerateRow(DataTable ImportData, List<string> RowData) { //create a counter to keep track of the column position during row composition int ColumnPosition = 0; //make a new datarow based on the schema of the formated import datatable DataRow NewRow = ImportData.NewRow(); //for each string cell value collected for the RowData list for this row foreach (string CellData in RowData) { //add the cell value to the new datarow NewRow[ImportData.Columns[ColumnPosition].ColumnName] = CellData; //incriment column position in the new row ColumnPosition++; } //return the generated row return NewRow; } 

代码有空值的问题。

  public void WriteExcelAutoStyledCell(object value) { //solve null values if (value is DBNull) return; 

我会添加到评论,但我是新的堆栈,所以我无法发表评论。 使用LC的解决scheme,我添加了另一个function,testing无效的XML字符的string字符。 当我出口到擅长的时候,有人发现导致出口失败的字符。

您将需要修改lc代码中的某个函数。

 public void WriteExcelAutoStyledCell(object value) { if (_writer == null) throw new InvalidOperationException("Cannot write after closing."); string newValue = string.Empty; try { //write the <ss:Cell> and <ss:Data> tags for something if (value is Int16 || value is Int32 || value is Int64 || value is SByte || value is UInt16 || value is UInt32 || value is UInt64 || value is Byte) { WriteExcelStyledCell(value, CellStyle.Number); } else if (value is Single || value is Double || value is Decimal) //we'll assume it's a currency { WriteExcelStyledCell(value, CellStyle.Currency); } else if (value is DateTime) { //check if there's no time information and use the appropriate style WriteExcelStyledCell(value, ((DateTime)value).TimeOfDay.CompareTo(new TimeSpan(0, 0, 0, 0, 0)) == 0 ? CellStyle.ShortDate : CellStyle.DateTime); } else { newValue = CheckXmlCompatibleValues(value.ToString()).ToString(); WriteExcelStyledCell(newValue, CellStyle.General); } } catch (Exception thisException) { throw new InvalidOperationException(thisException.Message.ToString()); } } 

并将此函数添加到“ExcelWriter”类

 public string CheckXmlCompatibleValues(string value) { string newValue = string.Empty; bool found = false; foreach (char c in value) { if (XmlConvert.IsXmlChar(c)) newValue += c.ToString(); else found = true; } return newValue.ToString(); } 

LC。 感谢代码!

Microsoft有一个内置的导入/导出Excel文件的解决scheme。 这不是最直接的库,但通常比上面列出的其他库更好。

需要这样做的库包含在Office中,可以在Microsoft.Office.Interop.Excel的框架程序集列表中find。

以下是一些示例代码:

 using Excel = Microsoft.Office.Interop.Excel; Excel.Application app = new Excel.Application(); //Open existing workbook //Excel.Workbook workbook = xlApp.Workbooks.Open(fileName); //Create new workbook Excel.Workbook workbook = app.Workbooks.Add(); Excel.Worksheet worksheet = workbook.ActiveSheet; worksheet.Cells[1,1] = "Hello world!"; // Indexes start at 1, because Excel workbook.SaveAs("C:\\MyWorkbook.xlsx"); workbook.Close(); app.Quit();