XLWorkbook wb = new XLWorkbook();
DataTable dt = GetDataTableOrWhatever();
wb.Worksheets.Add(dt,"WorksheetName");
开发人员响应迅速,乐于助人 . 该项目正在积极开发,文档非常精湛 .
0
尝试简单的代码,将DataTable转换为excel文件为csv:
var lines = new List<string>();
string[] columnNames = dataTable.Columns.Cast<DataColumn>().
Select(column => column.ColumnName).
ToArray();
var header = string.Join(",", columnNames);
lines.Add(header);
var valueLines = dataTable.AsEnumerable()
.Select(row => string.Join(",", row.ItemArray));
lines.AddRange(valueLines);
File.WriteAllLines("excel.csv",lines);
这会将一个新文件 excel.csv 写入"current working directory",这通常是.exe所在的位置或启动它的位置 .
请注意,输出会在dataTable中已包含的数据之间放置逗号( "," ) . 因为它不会在数据中转义逗号,所以程序读取文件时会报告 commas in the data will be mis-interpreted .
52
一个优雅的选择是为.net框架的DataTable类编写扩展方法(见下文) .
这种扩展方法可以如下调用:
using System;
using System.Collections.Generic;
using System.Linq;
using Excel = Microsoft.Office.Interop.Excel;
using System.Data;
using System.Data.OleDb;
DataTable dt;
// fill table data in dt here
...
// export DataTable to excel
// save excel file without ever making it visible if filepath is given
// don't save excel file, just make it visible if no filepath is given
dt.ExportToExcel(ExcelFilePath);
DataTable类的扩展方法:
public static class My_DataTable_Extensions
{
// Export DataTable into an excel file with field names in the header line
// - Save excel file without ever making it visible if filepath is given
// - Don't save excel file, just make it visible if no filepath is given
public static void ExportToExcel(this DataTable tbl, string excelFilePath = null) {
try {
if (tbl == null || tbl.Columns.Count == 0)
throw new Exception("ExportToExcel: Null or empty input table!\n");
// load excel, and create a new workbook
var excelApp = new Excel.Application();
excelApp.Workbooks.Add();
// single worksheet
Excel._Worksheet workSheet = excelApp.ActiveSheet;
// column headings
for (var i = 0; i < tbl.Columns.Count; i++) {
workSheet.Cells[1, i + 1] = tbl.Columns[i].ColumnName;
}
// rows
for (var i = 0; i < tbl.Rows.Count; i++) {
// to do: format datetime values before printing
for (var j = 0; j < tbl.Columns.Count; j++) {
workSheet.Cells[i + 2, j + 1] = tbl.Rows[i][j];
}
}
// check file path
if (!string.IsNullOrEmpty(excelFilePath)) {
try {
workSheet.SaveAs(excelFilePath);
excelApp.Quit();
MessageBox.Show("Excel file saved!");
}
catch (Exception ex) {
throw new Exception("ExportToExcel: Excel file could not be saved! Check filepath.\n"
+ ex.Message);
}
} else { // no file path is given
excelApp.Visible = true;
}
}
catch (Exception ex) {
throw new Exception("ExportToExcel: \n" + ex.Message);
}
}
}
13
解决方案基于tuncalik(感谢您的想法)文章,但在大表的情况下工作得更快(并且不太清楚) .
public static class My_DataTable_Extensions
{
/// <summary>
/// Export DataTable to Excel file
/// </summary>
/// <param name="DataTable">Source DataTable</param>
/// <param name="ExcelFilePath">Path to result file name</param>
public static void ExportToExcel(this System.Data.DataTable DataTable, string ExcelFilePath = null)
{
try
{
int ColumnsCount;
if (DataTable == null || (ColumnsCount = DataTable.Columns.Count) == 0)
throw new Exception("ExportToExcel: Null or empty input table!\n");
// load excel, and create a new workbook
Microsoft.Office.Interop.Excel.Application Excel = new Microsoft.Office.Interop.Excel.Application();
Excel.Workbooks.Add();
// single worksheet
Microsoft.Office.Interop.Excel._Worksheet Worksheet = Excel.ActiveSheet;
object[] Header = new object[ColumnsCount];
// column headings
for (int i = 0; i < ColumnsCount; i++)
Header[i] = DataTable.Columns[i].ColumnName;
Microsoft.Office.Interop.Excel.Range HeaderRange = Worksheet.get_Range((Microsoft.Office.Interop.Excel.Range)(Worksheet.Cells[1, 1]), (Microsoft.Office.Interop.Excel.Range)(Worksheet.Cells[1, ColumnsCount]));
HeaderRange.Value = Header;
HeaderRange.Interior.Color = System.Drawing.ColorTranslator.ToOle(System.Drawing.Color.LightGray);
HeaderRange.Font.Bold = true;
// DataCells
int RowsCount = DataTable.Rows.Count;
object[,] Cells = new object[RowsCount, ColumnsCount];
for (int j = 0; j < RowsCount; j++)
for (int i = 0; i < ColumnsCount; i++)
Cells[j, i] = DataTable.Rows[j][i];
Worksheet.get_Range((Microsoft.Office.Interop.Excel.Range)(Worksheet.Cells[2, 1]), (Microsoft.Office.Interop.Excel.Range)(Worksheet.Cells[RowsCount + 1, ColumnsCount])).Value = Cells;
// check fielpath
if (ExcelFilePath != null && ExcelFilePath != "")
{
try
{
Worksheet.SaveAs(ExcelFilePath);
Excel.Quit();
System.Windows.MessageBox.Show("Excel file saved!");
}
catch (Exception ex)
{
throw new Exception("ExportToExcel: Excel file could not be saved! Check filepath.\n"
+ ex.Message);
}
}
else // no filepath is given
{
Excel.Visible = true;
}
}
catch (Exception ex)
{
throw new Exception("ExportToExcel: \n" + ex.Message);
}
}
}
36
尝试此函数传递要导出的数据表和文件路径
public void CreateCSVFile(ref DataTable dt, string strFilePath)
{
try
{
// Create the CSV file to which grid data will be exported.
StreamWriter sw = new StreamWriter(strFilePath, false);
// First we will write the headers.
//DataTable dt = m_dsProducts.Tables[0];
int iColCount = dt.Columns.Count;
for (int i = 0; i < iColCount; i++)
{
sw.Write(dt.Columns[i]);
if (i < iColCount - 1)
{
sw.Write(",");
}
}
sw.Write(sw.NewLine);
// Now write all the rows.
foreach (DataRow dr in dt.Rows)
{
for (int i = 0; i < iColCount; i++)
{
if (!Convert.IsDBNull(dr[i]))
{
sw.Write(dr[i].ToString());
}
if (i < iColCount - 1)
{
sw.Write(",");
}
}
sw.Write(sw.NewLine);
}
sw.Close();
}
catch (Exception ex)
{
throw ex;
}
}
4
最好最简单的方法
private void exportToExcel(DataTable dt)
{
/*Set up work book, work sheets, and excel application*/
Microsoft.Office.Interop.Excel.Application oexcel = new Microsoft.Office.Interop.Excel.Application();
try
{
string path = AppDomain.CurrentDomain.BaseDirectory;
object misValue = System.Reflection.Missing.Value;
Microsoft.Office.Interop.Excel.Workbook obook = oexcel.Workbooks.Add(misValue);
Microsoft.Office.Interop.Excel.Worksheet osheet = new Microsoft.Office.Interop.Excel.Worksheet();
// obook.Worksheets.Add(misValue);
osheet = (Microsoft.Office.Interop.Excel.Worksheet)obook.Sheets["Sheet1"];
int colIndex = 0;
int rowIndex = 1;
foreach (DataColumn dc in dt.Columns)
{
colIndex++;
osheet.Cells[1, colIndex] = dc.ColumnName;
}
foreach (DataRow dr in dt.Rows)
{
rowIndex++;
colIndex = 0;
foreach (DataColumn dc in dt.Columns)
{
colIndex++;
osheet.Cells[rowIndex, colIndex] = dr[dc.ColumnName];
}
}
osheet.Columns.AutoFit();
string filepath = "C:\\Temp\\Book1";
//Release and terminate excel
obook.SaveAs(filepath);
obook.Close();
oexcel.Quit();
releaseObject(osheet);
releaseObject(obook);
releaseObject(oexcel);
GC.Collect();
}
catch (Exception ex)
{
oexcel.Quit();
log.AddToErrorLog(ex, this.Name);
}
}
public bool DataTableToExcelFile(DataTable dt, string targetFile)
{
const bool dontSave = false;
bool success = true;
//Exit if there is no rows to export
if (dt.Rows.Count == 0) return false;
object misValue = System.Reflection.Missing.Value;
List<int> dateColIndex = new List<int>();
Excel.Application excelApp = new Excel.Application();
Excel.Workbook excelWorkBook = excelApp.Workbooks.Add(misValue);
Excel.Worksheet excelWorkSheet = excelWorkBook.Sheets("sheet1");
//Iterate through the DataTable and populate the Excel work sheet
try {
for (int i = -1; i <= dt.Rows.Count - 1; i++) {
for (int j = 0; j <= dt.Columns.Count - 1; j++) {
if (i < 0) {
//Take special care with Date columns
if (dt.Columns(j).DataType is typeof(DateTime)) {
excelWorkSheet.Cells(1, j + 1).EntireColumn.NumberFormat = "d-MMM-yyyy;@";
dateColIndex.Add(j);
}
//else if ... Feel free to add more Formats
else {
//Otherwise Format the column as text
excelWorkSheet.Cells(1, j + 1).EntireColumn.NumberFormat = "@";
}
excelWorkSheet.Cells(1, j + 1) = dt.Columns(j).Caption;
}
else if (dateColIndex.IndexOf(j) > -1) {
excelWorkSheet.Cells(i + 2, j + 1) = Convert.ToDateTime(dt.Rows(i).ItemArray(j)).ToString("d-MMM-yyyy");
}
else {
excelWorkSheet.Cells(i + 2, j + 1) = dt.Rows(i).ItemArray(j).ToString();
}
}
}
//Add Autofilters to the Excel work sheet
excelWorkSheet.Cells.AutoFilter(1, Type.Missing, Excel.XlAutoFilterOperator.xlAnd, Type.Missing, true);
//Autofit columns for neatness
excelWorkSheet.Columns.AutoFit();
if (File.Exists(exportFile)) File.Delete(exportFile);
excelWorkSheet.SaveAs(exportFile);
} catch {
success = false;
} finally {
//Do this irrespective of whether there was an exception or not.
excelWorkBook.Close(dontSave);
excelApp.Quit();
releaseObject(excelWorkSheet);
releaseObject(excelWorkBook);
releaseObject(excelApp);
}
return success;
}
public class UserDTO
{
public int Id { get; set; }
public int SourceId { get; set; }
public string SourceName { get; set; }
[ReportHeaderAttribute("User Type")]
public string UsereType { get; set; }
[ReportHeaderAttribute("Address")]
public string Address{ get; set; }
[ReportHeaderAttribute("Age")]
public int Age{ get; set; }
public bool IsActive { get; set; }
[ReportHeaderAttribute("Active")]
public string IsActiveString
{
get
{
return IsActive ? "Yes" : "No";
}
}}
Var userList = Service.GetUsers() //Returns List of UserDTO;
var excelFilePath = userList.ToExcel();
HttpResponseMessage result = new HttpResponseMessage(HttpStatusCode.OK);
var stream = new FileStream(excelFilePath, FileMode.Open);
result.Content = new StreamContent(stream);
result.Content.Headers.ContentType =
new MediaTypeHeaderValue("application/vnd.ms-excel");
result.Content.Headers.ContentDisposition = new ContentDispositionHeaderValue("attachment") { FileName = "UserList.xls" };
return result;
var template = new XLTemplate(@".\Templates\report.xlsx");
using (var db = new DbDemos())
{
var cust = db.customers.LoadWith(c => c.Orders).First();
template.AddVariable(cust);
template.Generate();
}
template.SaveAs(outputFile);
0
只需使用CloseMXL.Excel库 . 它也很简单快捷 .
Class
private DataTable getAllList()
{
string constr = ConfigurationManager.ConnectionStrings["RConnection"].ConnectionString;
using (SqlConnection con = new SqlConnection(constr))
{
using (SqlCommand cmd = new SqlCommand("SELECT EmpId, gender, EmpName, pOnHold FROM Employee WHERE EmpId= '"+ AnyVariable + "' ORDER BY EmpName"))
{
using (SqlDataAdapter da = new SqlDataAdapter())
{
DataTable dt = new DataTable();
cmd.CommandType = CommandType.Text;
cmd.Connection = con;
da.SelectCommand = cmd;
da.Fill(dt);
dt.Columns[0].ColumnName = "Employee Id";
dt.Columns[1].ColumnName = "Gender";
dt.Columns[2].ColumnName = "Employee Name";
dt.Columns[3].ColumnName = "On Hold";
return dt;
}
}
}
}
Then another method which get the Dataset
public DataSet getDataSetExportToExcel()
{
DataSet ds = new DataSet();
DataTable dtEmp = new DataTable("CLOT List");
dtEmp = getAllList();
ds.Tables.Add(dtEmp);
ds.Tables[0].TableName = "Employee"; //If you which to use Mutliple Tabs
return ds;
}
Private tmr As System.Windows.Forms.Timer
Private Sub TestExcel() Handles Button1.Click
'// Initial data: SQL Server table with 6 columns and 293000 rows.
'// Data table holding all data
Dim dt As New DataTable("F161")
'// Create connection
Dim conn As New SqlConnection("Server=MYSERVER;Database=Test;Trusted_Connection=Yes;")
Dim fAdapter As New SqlDataAdapter With
{
.SelectCommand = New SqlCommand($"SELECT * FROM dbo.MyTable", conn)
}
'// Fill DataTable
fAdapter.Fill(dt)
'// Create Excel application
Dim xlApp As New Excel.Application With {.Visible = True}
'// Temporarily disable screen updating
xlApp.ScreenUpdating = False
'// Create brand new workbook
Dim xlBook As Excel.Workbook = xlApp.Workbooks.Add()
Dim xlSheet As Excel.Worksheet = DirectCast(xlBook.Sheets(1), Excel.Worksheet)
'// Get number of rows
Dim rows_count = dt.Rows.Count
'// Get number of columns
Dim cols_count = dt.Columns.Count
'// Here 's the core idea: after receiving data
'// you need to create an array and transfer it to sheet.
'// Why array?
'// Because it's the fastest way to transfer data to Excel's sheet.
'// So, we have two tasks:
'// 1) Create array
'// 2) Transfer array to sheet
'// =========================================================
'// TASK 1: Create array
'// =========================================================
'// In order to create array, we need to know that
'// Excel's Range object expects 2-D array whose lower bounds
'// of both dimensions start from 1.
'// This means you can't use C# array.
'// You need to manually create such array.
'// Since we already calculated number of rows and columns,
'// we can use these numbers in creating array.
Dim arr = Array.CreateInstance(GetType(Object), {rows_count, cols_count}, {1, 1})
'// Fill array
For r = 0 To rows_count - 1
For c = 0 To cols_count - 1
arr(r + 1, c + 1) = dt.Rows(r)(c)
Next
Next
'// =========================================================
'// TASK 2: Transfer array to sheet
'// =========================================================
'// Now we need to transfer array to sheet.
'// So, how transfer array to sheet fast?
'//
'// THE FASTEST WAY TO TRANSFER DATA TO SHEET IS TO ASSIGN ARRAY TO RANGE.
'// We could, of course, hard-code values, but Resize property
'// makes this work a breeze:
xlSheet.Range("A1").Resize.Resize(rows_count, cols_count).Value = arr
'// If we decide to dump data by iterating over array,
'// it will take LOTS of time.
'// For r = 1 To rows_count
'// For c = 1 To cols_count
'// xlSheet.Cells(r, c) = arr(r, c)
'// Next
'// Next
'// Here are time results:
'// 1) Assigning array to Range: 3 seconds
'// 2) Iterating over array: 45 minutes
'// Turn updating on
xlApp.ScreenUpdating = True
xlApp = Nothing
xlBook = Nothing
xlSheet = Nothing
'// Here we have another problem:
'// creating array took lots of memory (about 150 MB).
'// Using 'GC.Collect()', by unknown reason, doesn't help here.
'// However, if you run GC.Collect() AFTER this procedure is finished
'// (say, by pressing another button and calling another procedure),
'// then the memory is cleaned up.
'// I was wondering how to avoid creating some extra button to just release memory,
'// so I came up with the idea to use timer to call GC.
'// After 2 seconds GC collects all generations.
'// Do not forget to dispose timer since we need it only once.
tmr = New Timer()
AddHandler tmr.Tick,
Sub()
GC.Collect()
GC.WaitForPendingFinalizers()
GC.WaitForFullGCComplete()
tmr.Dispose()
End Sub
tmr.Interval = TimeSpan.FromSeconds(2).TotalMilliseconds()
tmr.Start()
End Sub
17 回答
我会推荐ClosedXML -
您可以使用一些非常易读的代码将DataTable转换为Excel工作表:
开发人员响应迅速,乐于助人 . 该项目正在积极开发,文档非常精湛 .
尝试简单的代码,将DataTable转换为excel文件为csv:
这会将一个新文件
excel.csv
写入"current working directory",这通常是.exe所在的位置或启动它的位置 .请注意,输出会在dataTable中已包含的数据之间放置逗号(
","
) . 因为它不会在数据中转义逗号,所以程序读取文件时会报告 commas in the data will be mis-interpreted .一个优雅的选择是为.net框架的DataTable类编写扩展方法(见下文) .
这种扩展方法可以如下调用:
DataTable类的扩展方法:
解决方案基于tuncalik(感谢您的想法)文章,但在大表的情况下工作得更快(并且不太清楚) .
尝试此函数传递要导出的数据表和文件路径
最好最简单的方法
您可以使用EasyXLS这是一个用于导出Excel文件的库 .
检查此代码:
另请参阅此示例有关如何export datatable to excel in C# .
注意:如果您尝试将值从数据表传递到对象然后传递到Excel,您也应该进行数据类型错误处理 . 例如,Guids将使用HRESULT:0x800A03EC异常终止您的赋值 . 没有测试数据类型的一种解决方法是在填充对象时使用“ToString()” . Excel会自动将数字转换回数字格式 . FlashTrev解决了日期/时间的相关问题 .
关于 tuncalik 的回答,这很好,特别是如果你想对代码进行一些游戏:)但它将我的日期以美国格式投入Excel,即2014年3月2日在英国是02/03/2014但是在美国它的03/02/2014与第1个月,然后是一周后的一天 . 我需要用英国格式,有什么想法吗?
我已经检查过它是以英国格式存储在我的DataTable中,而且我的Excel设置为英国但是出于某种原因,当它生成Excel文档时它认为它是美国(这是因为微软是一家美国公司:)
我会尝试尝试使用文化代码但不知道在哪里放置文化代码 . 试过但这没有效果 .
附:
我确实需要更改一行以通过添加'cast'来使其工作,如下所示
更新:我通过转换为LongDateTime格式实现了英国日期格式,但它只是一个解决方案 .
干杯 .
Excel Interop:
Excel Interop - Efficiency and performance
CSV:
旧线程 - 但我想我会在这里抛出我的代码 . 我写了一个小函数来将数据表写入指定路径(位置)的新Excel工作表 . 此外,您还需要添加对microsoft excel 14.0库的引用 .
我在撰写任何东西时都从这个帖子中脱颖而出 - How to write some data to excel file(.xlsx)
我用它来推断如何编写数据表
*注意在catch语句中我有一个errorhandler静态类引用(你可以忽略那些)
一种方法是使用ACE OLEDB Provider(另见connection strings for Excel) . 当然,您必须安装和注册提供程序 . 如果安装了Excel,则应该拥有它,但在部署应用程序时必须考虑这一点 .
这是从
ExportHelper
调用辅助方法的示例:ExportHelper.CreateXlsFromDataTable(myDataTable, @"C:\tmp\export.xls");
使用ACE OLEDB导出到Excel文件的帮助程序:
使用以下课程
}
Excel中需要成为列的所有内容都必须使用
[ReportHeaderAttribute("Column Name")]
进行修饰然后简单
要将数据导出到Excel,可以使用ClosedXML.Report库(https://github.com/ClosedXML/ClosedXML.Report) . 相信我,这是一个很棒的图书馆,很容易让她使用 . 该库不需要Excel Interop . ClosedXML.Report基于您可以使用任何格式在Excel中创建的模板生成Excel文件 . 例如:
Class
Then another method which get the Dataset
Now you Button Click Event