Bagaimana cara mengekspor DataTableke Excel di C #? Saya menggunakan Formulir Windows. ItuDataTable terkait dengan DataGridViewkontrol. Saya harus mengekspor catatan DataTableke Excel.
Cara termudah adalah dengan melakukan perulangan foreach bersarang pada item dan subitem.
Saeid Yazdani
CATATAN: Jika Anda mencoba untuk mengirimkan nilai dari tabel data ke objek kemudian ke Excel, Anda harus melakukan penanganan kesalahan tipe data juga. Misalnya, Pemandu akan menghentikan tugas Anda dengan pengecualian HRESULT: 0x800A03EC. Satu solusi tanpa menguji tipe data adalah dengan menggunakan "ToString ()" saat mengisi objek Anda. Excel akan mengonversi angka kembali ke format angka dengan sendirinya. FlashTrev sebagai membahas masalah terkait tanggal / waktu.
Menambahkan ~ 6 MB pustaka yang direferensikan tidak akan membuat aplikasi sedikit berat?
ʞᴉɯ
4
Pertanyaan bagus @MicheleVirgilio. Saya belum melakukan pengujian apa pun untuk mengukur dampak. Tapi untuk apa nilainya, itu tidak mengganggu saya dalam proyek apa pun yang saya gunakan, bahkan saya tidak bisa mengatakan bahwa saya pernah menyadarinya.
hmqcnoesy
Kode ini mengembalikan saya sebuah excel dengan satu kolom dengan nilaiClosedXML.Excel.XLWorkbook
Ini adalah jebakan
78
Coba kode sederhana, untuk mengonversi DataTable ke file excel sebagai csv:
Jawaban yang sangat bagus, bung. Saya tidak memiliki ruang untuk memberikan lebih dari satu suara positif untuk jawaban Anda, jika tidak, saya dapat memberikan lebih dari 100 suara positif.
Ashok kumar
2
@Cuong Le - Jika sel memiliki dua koma, maka itu akan menjadi masalah di "string.Join (", ")"
suneel ranga
@Cuong Le dimana "excel.csv"lokasinya?
Jogi
2
@suneelranga - Jika sebuah sel (yaitu di row.ItemArray) berisi ,(koma), maka menurut standar CSV sel itu harus ditutup dengan tanda kutip ","dan kemudian muncul di file seperti biasa. Jadi, ya - itu akan menimbulkan masalah karena kode ini tidak mendeteksi ,dan menerapkan tanda kutip.
Tom Leys
1
@ Si8 setelah disimpan Anda dapat melakukan Proses. Mulai (File Anda) dan itu akan membukanya untuk mereka. Itu sedekat yang bisa Anda dapatkan, saya percaya ..
TimmRH
40
Opsi elegan menulis metode ekstensi (lihat di bawah) untuk kelas DataTable dari kerangka kerja .net.
Metode perpanjangan ini bisa disebut sebagai berikut:
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);
Metode ekstensi untuk kelas DataTable:
publicstaticclassMy_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 givenpublicstaticvoidExportToExcel(thisDataTable tbl,string excelFilePath =null){try{if(tbl ==null|| tbl.Columns.Count==0)thrownewException("ExportToExcel: Null or empty input table!\n");// load excel, and create a new workbookvar excelApp =newExcel.Application();
excelApp.Workbooks.Add();// single worksheetExcel._Worksheet workSheet = excelApp.ActiveSheet;// column headingsfor(var i =0; i < tbl.Columns.Count; i++){
workSheet.Cells[1, i +1]= tbl.Columns[i].ColumnName;}// rowsfor(var i =0; i < tbl.Rows.Count; i++){// to do: format datetime values before printingfor(var j =0; j < tbl.Columns.Count; j++){
workSheet.Cells[i +2, j +1]= tbl.Rows[i][j];}}// check file pathif(!string.IsNullOrEmpty(excelFilePath)){try{
workSheet.SaveAs(excelFilePath);
excelApp.Quit();MessageBox.Show("Excel file saved!");}catch(Exception ex){thrownewException("ExportToExcel: Excel file could not be saved! Check filepath.\n"+ ex.Message);}}else{// no file path is given
excelApp.Visible=true;}}catch(Exception ex){thrownewException("ExportToExcel: \n"+ ex.Message);}}}
@ alex.pulver juga tidak berfungsi ketika saya mencoba menggunakannya di server. Poin bagus untuk disebutkan.
Si8
Ini akan berhasil tetapi lambat. Yang terbaik adalah menyalin ke clipboard dan menempelkannya ke excel. Jika Anda mengerjakan lebih dari 1000 rekaman, ini akan memakan waktu cukup lama.
Alex M
25
Solusi berdasarkan artikel tuncalik (terima kasih atas ide), tetapi dalam kasus tabel besar bekerja lebih cepat (dan sedikit kurang jelas).
publicstaticclassMy_DataTable_Extensions{/// <summary>/// Export DataTable to Excel file/// </summary>/// <param name="DataTable">Source DataTable</param>/// <param name="ExcelFilePath">Path to result file name</param>publicstaticvoidExportToExcel(thisSystem.Data.DataTableDataTable,stringExcelFilePath=null){try{intColumnsCount;if(DataTable==null||(ColumnsCount=DataTable.Columns.Count)==0)thrownewException("ExportToExcel: Null or empty input table!\n");// load excel, and create a new workbookMicrosoft.Office.Interop.Excel.ApplicationExcel=newMicrosoft.Office.Interop.Excel.Application();Excel.Workbooks.Add();// single worksheetMicrosoft.Office.Interop.Excel._WorksheetWorksheet=Excel.ActiveSheet;object[]Header=newobject[ColumnsCount];// column headings for(int i =0; i <ColumnsCount; i++)Header[i]=DataTable.Columns[i].ColumnName;Microsoft.Office.Interop.Excel.RangeHeaderRange=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;// DataCellsintRowsCount=DataTable.Rows.Count;object[,]Cells=newobject[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 fielpathif(ExcelFilePath!=null&&ExcelFilePath!=""){try{Worksheet.SaveAs(ExcelFilePath);Excel.Quit();System.Windows.MessageBox.Show("Excel file saved!");}catch(Exception ex){thrownewException("ExportToExcel: Excel file could not be saved! Check filepath.\n"+ ex.Message);}}else// no filepath is given{Excel.Visible=true;}}catch(Exception ex){thrownewException("ExportToExcel: \n"+ ex.Message);}}}
Jawaban tuncalik memakan waktu hampir satu menit bagi saya, ini adalah 1 detik jika butuh waktu lama ... Saya benar-benar terkejut.
Wilsu
2
Ini adalah sampel tercepat yang pernah saya coba, kerja bagus. Saya harus menggunakan Marshal untuk merilis file setelahnya. Excel.Quit(); Marshal.FinalReleaseComObject(Worksheet); Marshal.FinalReleaseComObject(HeaderRange); Marshal.FinalReleaseComObject(Excel);
Dave Kelly
Apakah itu memerlukan Office untuk diinstal?
Parshuram Kalvikatte
Bekerja dengan sempurna jika tidak, tetapi warna dasar Header Back saya diatur ke Hitam selalu saat menggunakan solusi ini dalam aplikasi konsol. Apa alasannya ??
Zaveed Abbasi
15
Coba fungsi ini meneruskan jalur data dan file tempat Anda ingin mengekspor
publicvoidCreateCSVFile(refDataTable dt,string strFilePath){try{// Create the CSV file to which grid data will be exported.StreamWriter sw =newStreamWriter(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;}}
Perhatikan bahwa ini tidak akan benar-benar menggunakan sel tabel di dokumen Excel, melainkan semua untuk setiap baris akan dicetak pada sel pertama dari setiap baris.
(harap berada di sini) jika ada lebih dari satu file excel yang terbuka, apakah fungsi rilis ini merusak semuanya atau hanya yang diteruskan sebagai parameter?
Elliott Addi
1
Interop Excel:
Metode ini mencegah Tanggal dibalik dari hh-bb-tttt ke bb-hh-tttt
publicboolDataTableToExcelFile(DataTable dt,string targetFile){constbool dontSave =false;bool success =true;//Exit if there is no rows to exportif(dt.Rows.Count==0)returnfalse;object misValue =System.Reflection.Missing.Value;List<int> dateColIndex =newList<int>();Excel.Application excelApp =newExcel.Application();Excel.Workbook excelWorkBook = excelApp.Workbooks.Add(misValue);Excel.Worksheet excelWorkSheet = excelWorkBook.Sheets("sheet1");//Iterate through the DataTable and populate the Excel work sheettry{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 columnsif(dt.Columns(j).DataTypeistypeof(DateTime)){
excelWorkSheet.Cells(1, j +1).EntireColumn.NumberFormat="d-MMM-yyyy;@";
dateColIndex.Add(j);}//else if ... Feel free to add more Formatselse{//Otherwise Format the column as text
excelWorkSheet.Cells(1, j +1).EntireColumn.NumberFormat="@";}
excelWorkSheet.Cells(1, j +1)= dt.Columns(j).Caption;}elseif(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;}
Jika Anda tidak peduli tentang Tanggal dibalik, gunakan tautan lihat yang menunjukkan cara mengisi semua sel di lembar bentang Excel dalam satu baris kode:
Manfaatkan saja Perpustakaan CloseMXL.Excel . Ini juga mudah dan cukup cepat.
Kelas
privateDataTable getAllList(){string constr =ConfigurationManager.ConnectionStrings["RConnection"].ConnectionString;
using (SqlConnection con =newSqlConnection(constr)){
using (SqlCommand cmd =newSqlCommand("SELECT EmpId, gender, EmpName, pOnHold FROM Employee WHERE EmpId= '"+AnyVariable+"' ORDER BY EmpName")){
using (SqlDataAdapter da =newSqlDataAdapter()){DataTable dt =newDataTable();
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;}}}}
Kemudian metode lain yang mendapatkan Dataset
publicDataSet getDataSetExportToExcel(){DataSet ds =newDataSet();DataTable dtEmp =newDataTable("CLOT List");
dtEmp = getAllList();
ds.Tables.Add(dtEmp);
ds.Tables[0].TableName="Employee";//If you which to use Mutliple Tabsreturn ds;}
Sekarang Anda Acara Klik Tombol
protectedvoid btn_Export_Click(object sender,EventArgs e){DataSet ds = getDataSetExportToExcel();
using (XLWorkbook wb =newXLWorkbook()){
wb.Worksheets.Add(ds);
wb.Style.Alignment.Horizontal=XLAlignmentHorizontalValues.Center;
wb.Style.Font.Bold=true;Response.Clear();Response.Buffer=true;Response.Charset="";Response.ContentType="application/vnd.openxmlformats-officedocument.spreadsheetml.sheet";Response.AddHeader("content-disposition","attachment;filename=EmployeeonHoldList.xlsx");
using (MemoryStreamMyMemoryStream=newMemoryStream()){
wb.SaveAs(MyMemoryStream);MyMemoryStream.WriteTo(Response.OutputStream);Response.Flush();Response.End();}}}
Anda dapat menggunakan perpustakaan SwiftExcel saya . Ini sangat baik ketika kinerja dan penggunaan memori yang rendah diterapkan karena menulis data langsung ke file:
using (var ew =newExcelWriter("C:\\temp\\test.xlsx")){for(var row =1; row <=100; row++){for(var col =1; col <=10; col++){
ew.Write($"row:{row}-col:{col}", col, row);}}}
Saya ingin menambahkan jawaban ini karena saya menghabiskan banyak waktu mencari metode yang cepat dan andal untuk melakukan ini dan tidak ada contoh lengkap penggunaan OpenXMLWriter untuk tujuan ini yang ada di mana pun yang dapat saya temukan.
Pertama, COM / Interop (yang digunakan oleh banyak jawaban lain) tidak masalah untuk tujuan ini, tetapi memiliki beberapa sensitivitas. Saya telah menggunakannya selama beberapa dekade dan sebagian besar stabil, tetapi ketika menerapkan front-end gudang data untuk ratusan pengguna, saya merasa itu menjadi subjek terlalu banyak masalah tergantung pada mesin dan apa yang dilakukan pengguna, jadi saya beralih ke OpenXML. OpenXML DOM cukup baik untuk tujuan ini, tetapi lebih lambat daripada menggunakan OpenXMLWriter. Saat Anda masuk ke kumpulan data besar (100K +) dengan banyak kolom, DOM jauh lebih lambat daripada OpenXMLWriter, jadi saya menggunakan yang terakhir. Metode di bawah ini menulis 420K + baris dengan 30+ kolom dalam waktu kurang dari 30 detik.
Saya harap komentarnya cukup untuk memandu siapa pun melalui apa yang dilakukannya. Ini disederhanakan, karena menulis semua nilai ke file sebagai string, tetapi Anda dapat mengimplementasikan logika untuk menulis berbagai tipe data (dan menggunakan berbagai format sel) berdasarkan konten data Anda. Anda juga dapat menyesuaikan ini untuk digunakan pada DataGridView (bukan DataTable) dengan hanya mengubah beberapa hal (yaitu loop melalui kolom / baris).
Referensi ke DocumentFormat.OpenXML (d / l dengan OpenXML SDK) dan WindowsBase diperlukan.
ImportsDocumentFormat.OpenXmlImportsDocumentFormat.OpenXml.SpreadsheetImportsDocumentFormat.OpenXml.PackagingPublicSubExportToExcelXML(ByRef dt AsDataTable, filename AsString)Dim wbp AsWorkbookPart, wsp AsWorksheetPart'IfthisDataTable has more rows in it than can fit inExcel,throw an exception
If dt.Rows.Count>1048575ThenThrowNewException("The DataTable is too large to export to Excel.")'Delete any previous file of the same name that may exist.File.Delete(filename)'Create an OpenXMLSpreadsheetDocument...Using xls =SpreadsheetDocument.Create(filename,SpreadsheetDocumentType.Workbook)'Add a WorkbookPart to the SpreadsheetDoc, then add a WorksheetPart to the WorkbookPart.
wbp = xls.AddWorkbookPart()
wsp = wbp.AddNewPart(OfWorksheetPart)'Now we need to add the "StyleSheet" to the WorkbookPart(that we just added above).This will allow us to apply formatting to our Cells.'Add the WbStylesPart and the StyleSheet.Dim stp AsWorkbookStylesPart= wbp.AddNewPart(OfWorkbookStylesPart)Dim ss AsNewStylesheet'Create the only two Fonts we're going to use (Regular and Bold).Dim fBold AsNewFont
fBold.Append(NewBold)Dim fnts AsNewFonts
fnts.Append(NewFont)'This creates the default (unmodified, regular) Font. It's added first, so its index is0.
fnts.Append(fBold)'This creates the Bold font. It's added second, so its index is1.'Create the default Fill/Border settings (these have to be here, even though I don't set any custom fills/borders).Dim flls AsNewFillsDim brdrs AsNewBorders
flls.Append(NewFill)
brdrs.Append(NewBorder)'Now I have to add formats (NumberFormat and CellFormat).First, you create a NumberFormat.Thisis basically the pattern of
' the format (i.e."@"forText).For now, I only need a Text format, but I can add more patterns if needed.' I give the format an ID of 164, since 163iswhere the built-inExcel formats end.Dim nbrfmts AsNewNumberingFormats
nbrfmts.Append(NewNumberingFormatWith{.NumberFormatId=164,.FormatCode="@"})'Create the first two CellFormats:Default, which will have an index of 0 and "Header"(Bold/Centered) with an index of 1.Dim cellfmts AsNewCellFormats()
cellfmts.Append(NewCellFormat()With{.FontId=0,.NumberFormatId=164,.FillId=0,.BorderId=0})
cellfmts.Append(NewCellFormat()With{.FontId=1,.NumberFormatId=164,.Alignment=NewAlignment()With{.WrapText=True,.Horizontal=HorizontalAlignmentValues.Center}})'Add all of the Fonts/Fills/Borders/etc to the StyleSheet and add it all to the WorkbookStylesPart.
ss.Append(fnts)
ss.Append(flls)
ss.Append(brdrs)
ss.Append(cellfmts)
ss.NumberingFormats= nbrfmts
stp.Stylesheet= ss
stp.Stylesheet.Save()'Now create an OpenXMLWriter using the WorksheetPart to write the cells to the worksheet.Using oxw AsOpenXmlWriter=OpenXmlWriter.Create(wsp)'Write the start element for the Worksheet and the Columns...
oxw.WriteStartElement(NewWorksheet)
oxw.WriteStartElement(NewColumns())'Now I'm going to loop through the columns in the DataTable...For c AsInteger=0To dt.Columns.Count-1'Now we'll get the width for the column.Todothis, we loop through all of the rows and measure the width of the text
' using the defaultExcelFont(currently Font:CalibriSize:11) and return the largest width (in pixels) to use below.' Why not do this loop below (when I loop through the rows to write the Cells)? Because you can't.You have to
' write the Column XML first before writing the SheetData/Row/Cell XML (I confirmed this by trying it), so there's
' no way (that I'm aware of) to avoid looping through all of the rows twice if you want to AutoFit.'Setup vars we'll use for getting the column widths (below).Dim g =System.Drawing.Graphics.FromHwnd(IntPtr.Zero)Dim fnt =NewSystem.Drawing.Font("Calibri",11)Dim wid AsDouble=0'Get the width of the header (because if this is wider than the widest value, we'll use the header text's width).' I found that adding 2 pixels to the width was necessary to get the column as wide asExcel would make it.Dim tmp AsDouble= g.MeasureString(dt.Columns(c).ColumnName,NewSystem.Drawing.Font(fnt,System.Drawing.FontStyle.Bold)).Width+2'Loop through the rows in the dt and get the width of the value in that row/col. If it's wider than the widest
' width we've encountered thus far, use the new wider width as our basis.ForEach row AsDataRowIn dt.RowsIf tmp > wid Then wid = tmp
tmp = g.MeasureString(row(c).ToString, fnt).WidthNext'Set the column attributes and write it to the file. The Width is set using a formula that converts from pixels to Excel's column width values.Dim oxa AsNewList(OfOpenXmlAttribute)From{NewOpenXmlAttribute("min",Nothing, c +1),NewOpenXmlAttribute("max",Nothing, c +1),NewOpenXmlAttribute("width",Nothing,System.Math.Round((wid -12+5)/7D+1,2))}
oxw.WriteStartElement(NewColumn(), oxa)
oxw.WriteEndElement()Next'CLoseout the Columns collection.
oxw.WriteEndElement()'Write the start element for the SheetData...
oxw.WriteStartElement(NewSheetData)'Write the start element for the Header row.
oxw.WriteStartElement(NewRow)'Loop through the Columnsin the dt.ForEach col AsDataColumnIn dt.Columns'Write a cell for this column's Header.AllHeader cells are written with a DataType of String("str").' I ALSO apply the "Header"CellFormat(StyleIndex1) to all of the HeaderCells.This makes them Bold and Centered.WriteCell(oxw, col.ColumnName,"str",1)Next'Closeout the Header row.
oxw.WriteEndElement()'Loop through all of the rows in the dt...ForEach row AsDataRowIn dt.Rows'Write a StartElementforthis row...
oxw.WriteStartElement(NewRow)'Loop through all of the columns in the dt...For c AsInteger=0To dt.Columns.Count-1'Write a valueinthis row/column to the Excel file. I use the datatype of "String" and the defaultCellFormat/StyleIndex.WriteCell(oxw, row(c).ToString,"str",0)Next'Closeoutthis row.
oxw.WriteEndElement()Next'Closeout the Worksheet and SheetData elements...
oxw.WriteEndElement()
oxw.WriteEndElement()EndUsing'Now we're going to create an OpenXMLWriter using the WorkbookPart(that we created above)...Using oxw AsOpenXmlWriter=OpenXmlWriter.Create(wbp)'Add starting elements for the Workbook and Sheets collection.
oxw.WriteStartElement(NewWorkbook())
oxw.WriteStartElement(NewSheets())'Add the Sheet(name the Sheet after the file name minus the extension).
oxw.WriteElement(NewSheet()With{.Name=Path.GetFileNameWithoutExtension(filename),.SheetId=1,.Id= xls.WorkbookPart.GetIdOfPart(wsp)})'WriteEnd elements for the Workbook/Sheets
oxw.WriteEndElement()
oxw.WriteEndElement()EndUsingEndUsingEndSub'ThisSubis used to write a value to a Cell using OpenXMLWriter.PrivateSubWriteCell(ByRef oxw AsOpenXmlWriter,valueAsString, datatype AsString, style AsUInt32Value)Dim oxa AsNewList(OfOpenXmlAttribute)From{NewOpenXmlAttribute("t",Nothing, datatype),NewOpenXmlAttribute("s",Nothing, style)}
oxw.WriteStartElement(NewCell(), oxa)Ifvalue<>NothingThen oxw.WriteElement(NewCellValue(value))
oxw.WriteEndElement()EndSub
Terima kasih banyak telah meluangkan waktu untuk menjawab ini. Saya memiliki klien yang memiliki solusi yang berfungsi di Excel Interop, tetapi mengeluh tentang betapa lambatnya solusi tersebut. Saya melihat beberapa jawaban lain pada pertanyaan yang memandu saya menuju OpenXML, tetapi saya senang memiliki jalan pintas untuk memulai.
Brandon Barkley
1
Tidak masalah. Saya masih menggunakan COM, tetapi hanya di lingkungan di mana saya memiliki kendali penuh. Saya telah menggunakan pendekatan OpenXML ini di aplikasi dengan beberapa ratus pengguna selama beberapa bulan dan tidak mengalami masalah apa pun dibandingkan dengan kesalahan mingguan dengan COM. Saya juga memeriksa solusi pihak ketiga, seperti yang disebutkan di sini, tetapi saya lebih suka menulisnya sendiri sehingga saya dapat membuatnya seefisien mungkin.
WATYF
0
Tentang tuncalik dengan jawaban , yang bagus, terutama jika Anda ingin sedikit bermain dengan kode :) tetapi memasukkan tanggal saya ke Excel dalam format Amerika yaitu 2 Maret 2014 di Inggris adalah 02/03/2014 tetapi di AS tanggal 03/02/2014 dengan bulan ke-1, kemudian hari dalam seminggu setelahnya. Saya perlu memilikinya dalam format UK, ada ide?
Saya telah memeriksa itu disimpan dalam format Inggris di DataTable saya dan juga Excel saya disetel ke Inggris tetapi untuk beberapa alasan ketika itu membuat dokumen Excel dianggapnya AS (apakah ini karena Microsoft adalah perusahaan AS :)
Saya akan mencoba bereksperimen dengan kode budaya tetapi belum yakin harus meletakkannya di mana. Sudah mencoba tapi ini tidak berpengaruh.
ps
Saya memang harus mengubah satu baris agar berfungsi dengan menambahkan 'pemeran' seperti di bawah ini
// single worksheetExcel._Worksheet workSheet =(Excel._Worksheet)excelApp.ActiveSheet;
Pembaruan: Saya telah mencapai pemformatan Inggris dari tanggal dengan mengonversi ke format LongDateTime, itu hanya solusi sekalipun.
Utas lama - tetapi saya pikir saya akan membuang kode saya di sini. Saya menulis sedikit fungsi untuk menulis tabel data ke lembar excel baru di jalur (lokasi) yang ditentukan. Anda juga perlu menambahkan referensi ke pustaka microsoft excel 14.0.
saya menggunakannya untuk memperkirakan cara menulis dataTable
* Catatan dalam pernyataan tangkap saya memiliki referensi kelas statis errorhandler (Anda dapat mengabaikannya)
using excel =Microsoft.Office.Interop.Excel;
using System.IO;
using System.Data;
using System.Runtime.InteropServices;//class and namespace wrapper is not shown in this example privatevoidWriteToExcel(System.Data.DataTable dt,string location){//instantiate excel objects (application, workbook, worksheets)
excel.ApplicationXlObj=new excel.Application();XlObj.Visible=false;
excel._WorkbookWbObj=(excel.Workbook)(XlObj.Workbooks.Add(""));
excel._WorksheetWsObj=(excel.Worksheet)WbObj.ActiveSheet;//run through datatable and assign cells to values of datatabletry{int row =1;int col =1;foreach(DataColumn column in dt.Columns){//adding columnsWsObj.Cells[row, col]= column.ColumnName;
col++;}//reset column and row variables
col =1;
row++;for(int i =0; i < dt.Rows.Count; i++){//adding dataforeach(var cell in dt.Rows[i].ItemArray){WsObj.Cells[row, col]= cell;
col++;}
col =1;
row++;}WbObj.SaveAs(location);}catch(COMException x){ErrorHandler.Handle(x);}catch(Exception ex){ErrorHandler.Handle(ex);}finally{WbObj.Close();}}
Ini bekerja dengan baik, namun, Anda tidak pernah mematikan proses Excel Anda setelahnya jadi saya sarankan untuk menambahkan ini, mengganti SaveAsbaris Anda seperti yang disertakan di sini: 'XlObj.DisplayAlerts = false; WbObj.SaveAs (lokasi); WbObj.Close (); XlObj.Quit (); Marshal.ReleaseComObject (WsObj); Marshal.ReleaseComObject (WbObj); Marshal.ReleaseComObject (XlObj); ' Untuk menggunakan Marshal.ReleaseComObjectmetode ini, tambahkan using System.Runtime.InteropServicesrakitan ke proyek Anda.
GrammatonCleric
0
Salah satu cara untuk melakukannya juga dengan Penyedia OLEDB ACE (lihat juga string koneksi untuk Excel ). Tentu saja Anda harus menginstal dan mendaftarkan penyedia. Anda harus memilikinya, jika Anda telah menginstal Excel, tetapi ini adalah sesuatu yang harus Anda pertimbangkan saat menerapkan aplikasi.
Ini adalah contoh pemanggilan metode helper dari ExportHelper:ExportHelper.CreateXlsFromDataTable(myDataTable, @"C:\tmp\export.xls");
Pembantu untuk mengekspor ke file Excel menggunakan ACE OLEDB:
publicclassExportHelper{privateconststringExcelOleDbConnectionStringTemplate="Provider=Microsoft.ACE.OLEDB.12.0;Data Source={0};Extended Properties=\"Excel 8.0;HDR=YES\";";/// <summary>/// Creates the Excel file from items in DataTable and writes them to specified output file./// </summary>publicstaticvoidCreateXlsFromDataTable(DataTable dataTable,string fullFilePath){string createTableWithHeaderScript =GenerateCreateTableCommand(dataTable);
using (var conn =newOleDbConnection(String.Format(ExcelOleDbConnectionStringTemplate, fullFilePath))){if(conn.State!=ConnectionState.Open){
conn.Open();}OleDbCommand cmd =newOleDbCommand(createTableWithHeaderScript, conn);
cmd.ExecuteNonQuery();foreach(DataRow dataExportRow in dataTable.Rows){AddNewRow(conn, dataExportRow);}}}privatestaticvoidAddNewRow(OleDbConnection conn,DataRow dataRow){string insertCmd =GenerateInsertRowCommand(dataRow);
using (OleDbCommand cmd =newOleDbCommand(insertCmd, conn)){AddParametersWithValue(cmd, dataRow);
cmd.ExecuteNonQuery();}}/// <summary>/// Generates the insert row command./// </summary>privatestaticstringGenerateInsertRowCommand(DataRow dataRow){var stringBuilder =newStringBuilder();var columns = dataRow.Table.Columns.Cast<DataColumn>().ToList();var columnNamesCommaSeparated =string.Join(",", columns.Select(x => x.Caption));var questionmarkCommaSeparated =string.Join(",", columns.Select(x =>"?"));
stringBuilder.AppendFormat("INSERT INTO [{0}] (", dataRow.Table.TableName);
stringBuilder.Append(columnNamesCommaSeparated);
stringBuilder.Append(") VALUES(");
stringBuilder.Append(questionmarkCommaSeparated);
stringBuilder.Append(")");return stringBuilder.ToString();}/// <summary>/// Adds the parameters with value./// </summary>privatestaticvoidAddParametersWithValue(OleDbCommand cmd,DataRow dataRow){var paramNumber =1;for(int i =0; i <= dataRow.Table.Columns.Count-1; i++){if(!ReferenceEquals(dataRow.Table.Columns[i].DataType,typeof(int))&&!ReferenceEquals(dataRow.Table.Columns[i].DataType,typeof(decimal))){
cmd.Parameters.AddWithValue("@p"+ paramNumber, dataRow[i].ToString().Replace("'","''"));}else{objectvalue=GetParameterValue(dataRow[i]);OleDbParameter parameter = cmd.Parameters.AddWithValue("@p"+ paramNumber,value);if(valueisdecimal){
parameter.OleDbType=OleDbType.Currency;}}
paramNumber = paramNumber +1;}}/// <summary>/// Gets the formatted value for the OleDbParameter./// </summary>privatestaticobjectGetParameterValue(objectvalue){if(valueisstring){returnvalue.ToString().Replace("'","''");}returnvalue;}privatestaticstringGenerateCreateTableCommand(DataTable tableDefination){StringBuilder stringBuilder =newStringBuilder();bool firstcol =true;
stringBuilder.AppendFormat("CREATE TABLE [{0}] (", tableDefination.TableName);foreach(DataColumn tableColumn in tableDefination.Columns){if(!firstcol){
stringBuilder.Append(", ");}
firstcol =false;string columnDataType ="CHAR(255)";switch(tableColumn.DataType.Name){case"String":
columnDataType ="CHAR(255)";break;case"Int32":
columnDataType ="INTEGER";break;case"Decimal":// Use currency instead of decimal because of bug described at // http://social.msdn.microsoft.com/Forums/vstudio/en-US/5d6248a5-ef00-4f46-be9d-853207656bcc/localization-trouble-with-oledbparameter-and-decimal?forum=csharpgeneral
columnDataType ="CURRENCY";break;}
stringBuilder.AppendFormat("{0} {1}", tableColumn.ColumnName, columnDataType);}
stringBuilder.Append(")");return stringBuilder.ToString();}}
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Data;
using excel =Microsoft.Office.Interop.Excel;
using EL =ExcelLibrary.SpreadSheet;
using System.Drawing;
using System.Collections;
using System.Runtime.InteropServices;
using System.Windows.Forms;
namespace _basic
{publicclassExcelProcesser{publicvoidWriteToExcel(System.Data.DataTable dt){
excel.ApplicationXlObj=new excel.Application();XlObj.Visible=false;
excel._WorkbookWbObj=(excel.Workbook)(XlObj.Workbooks.Add(""));
excel._WorksheetWsObj=(excel.Worksheet)WbObj.ActiveSheet;object misValue =System.Reflection.Missing.Value;try{int row =1;int col =1;foreach(DataColumn column in dt.Columns){//adding columnsWsObj.Cells[row, col]= column.ColumnName;
col++;}//reset column and row variables
col =1;
row++;for(int i =0; i < dt.Rows.Count; i++){//adding dataforeach(var cell in dt.Rows[i].ItemArray){WsObj.Cells[row, col]= cell;
col++;}
col =1;
row++;}WbObj.SaveAs(fileFullName, excel.XlFileFormat.xlWorkbookNormal, misValue, misValue, misValue, misValue, excel.XlSaveAsAccessMode.xlExclusive, misValue, misValue, misValue, misValue, misValue);}catch(Exception ex){MessageBox.Show(ex.Message);}finally{WbObj.Close(true, misValue, misValue);}}}
Solusi ini pada dasarnya mendorong List<Object>data ke Excel, Ini menggunakan DataTable untuk mencapai ini, saya menerapkan metode ekstensi, jadi pada dasarnya ada dua hal yang diperlukan. 1. Metode Penyuluhan.
publicstaticclassReportHelper{publicstaticstringToExcel<T>(thisIList<T> data){PropertyDescriptorCollection properties =TypeDescriptor.GetProperties(typeof(T));DataTable table =newDataTable();foreach(PropertyDescriptor prop in properties){//table.Columns.Add(prop.Name, Nullable.GetUnderlyingType(prop.PropertyType) ?? prop.PropertyType);if(prop.Attributes[typeof(FGMS.Entity.Extensions.ReportHeaderAttribute)]!=null){
table.Columns.Add(GetColumnHeader(prop),Nullable.GetUnderlyingType(prop.PropertyType)?? prop.PropertyType);}}//So it seems like when there is only one row of data the headers do not appear//so adding a dummy blank row which fixed the issues//Add a blank Row - Issue # 1471DataRow blankRow = table.NewRow();
table.Rows.Add(blankRow);foreach(T item in data){DataRow row = table.NewRow();foreach(PropertyDescriptor prop in properties)//row[prop.Name] = prop.GetValue(item) ?? DBNull.Value;if(prop.Attributes[typeof(FGMS.Entity.Extensions.ReportHeaderAttribute)]!=null){
row[GetColumnHeader(prop)]= prop.GetValue(item)??DBNull.Value;}
table.Rows.Add(row);}
table.TableName="Results";var filePath =System.IO.Path.GetTempPath()+"\\"+System.Guid.NewGuid().ToString()+".xls";
table.WriteXml(filePath);return filePath;}privatestaticstringGetColumnHeader(PropertyDescriptor prop){return((FGMS.Entity.Extensions.ReportHeaderAttribute)(prop.Attributes[typeof(FGMS.Entity.Extensions.ReportHeaderAttribute)])).ReportHeaderText;}}
Hiasi kelas DTO Anda dengan Atribut [ReportHeaderAttribute("Column Name")]
Segala sesuatu yang perlu menjadi kolom di Excel harus dihias [ReportHeaderAttribute("Column Name")]
Kemudian Cukup
Var userList =Service.GetUsers()//Returns List of UserDTO;var excelFilePath = userList.ToExcel();HttpResponseMessage result =newHttpResponseMessage(HttpStatusCode.OK);var stream =newFileStream(excelFilePath,FileMode.Open);
result.Content=newStreamContent(stream);
result.Content.Headers.ContentType=newMediaTypeHeaderValue("application/vnd.ms-excel");
result.Content.Headers.ContentDisposition=newContentDispositionHeaderValue("attachment"){FileName="UserList.xls"};return result;
dan jika op tidak ingin membuat DTO untuk setiap tabel, mereka akan menjalankannya? Seperti misalnya untuk setiap seribu tabel saya melakukan ini. Menambahkan atribut tajuk laporan tidak dengan cepat - banyak pengkodean di sana dan bahkan sebelum mengerjakan pekerjaan yang sebenarnya. Tidak mengetuk solusi Anda - hanya menunjukkan bahwa prinsip sloth tidak digunakan di sini karena solusi ini menambahkan langkah pembuatan dto dan kemudian mengompilasi .. Saya harus menyatakan - Saya suka Anda menggunakan obat generik.
Ken
0
Untuk mengekspor data ke Excel, Anda dapat menggunakan pustaka ClosedXML.Report ( https://github.com/ClosedXML/ClosedXML.Report ). Percayalah, ini adalah perpustakaan yang luar biasa dan mudah digunakannya. Pustaka tidak membutuhkan Interop Excel. ClosedXML.Report menghasilkan file Excel berdasarkan templat yang dapat Anda buat di Excel menggunakan pemformatan apa pun. Sebagai contoh:
var template =newXLTemplate(@".\Templates\report.xlsx");
using (var db =newDbDemos()){var cust = db.customers.LoadWith(c => c.Orders).First();
template.AddVariable(cust);
template.Generate();}
template.SaveAs(outputFile);
Private tmr AsSystem.Windows.Forms.TimerPrivateSubTestExcel()HandlesButton1.Click'// Initial data: SQL Server table with 6 columns and 293000 rows.'// Data table holding all dataDim dt AsNewDataTable("F161")'// Create connectionDim conn AsNewSqlConnection("Server=MYSERVER;Database=Test;Trusted_Connection=Yes;")Dim fAdapter AsNewSqlDataAdapterWith{.SelectCommand=NewSqlCommand($"SELECT * FROM dbo.MyTable", conn)}'// Fill DataTable
fAdapter.Fill(dt)'// Create Excel applicationDim xlApp AsNewExcel.ApplicationWith{.Visible=True}'// Temporarily disable screen updating
xlApp.ScreenUpdating=False'// Create brand new workbookDim xlBook AsExcel.Workbook= xlApp.Workbooks.Add()Dim xlSheet AsExcel.Worksheet=DirectCast(xlBook.Sheets(1),Excel.Worksheet)'// Get number of rowsDim rows_count = dt.Rows.Count'// Get number of columnsDim 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 Rangeobject 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 arrayFor r =0To rows_count -1For c =0To cols_count -1
arr(r +1, c +1)= dt.Rows(r)(c)NextNext'// ========================================================='// 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 =NewTimer()AddHandler tmr.Tick,Sub()
GC.Collect()
GC.WaitForPendingFinalizers()
GC.WaitForFullGCComplete()
tmr.Dispose()EndSub
tmr.Interval=TimeSpan.FromSeconds(2).TotalMilliseconds()
tmr.Start()EndSub
publicclassTestObject{publicintCol1{get;set;}publicintCol2{get;set;}publicstringCol3{get;set;}publicDateTimeCol4{get;set;}}[TestMethod]publicvoidLoadFromCollection_MemberList_Test(){///programming/32587834/epplus-loadfromcollection-text-converted-to-number/32590626#32590626varTestObjectList=newList<TestObject>();for(var i =0; i <10; i++)TestObjectList.Add(newTestObject{Col1= i,Col2= i*10,Col3=(i*10)+"E4"});//Create a test filevar fi =newFileInfo(@"c:\temp\LoadFromCollection_MemberList_Test.xlsx");if(fi.Exists)
fi.Delete();
using (var pck =newExcelPackage(fi)){//Do NOT include Col1var mi =typeof(TestObject).GetProperties().Where(pi => pi.Name!="Col1").Select(pi =>(MemberInfo)pi).ToArray();var worksheet = pck.Workbook.Worksheets.Add("Sheet1");
worksheet.Cells.LoadFromCollection(TestObjectList,true,TableStyles.Dark1,BindingFlags.Public|BindingFlags.Instance, mi);
pck.Save();}}
Jawaban:
Saya akan merekomendasikan ClosedXML -
Anda dapat mengubah DataTable menjadi lembar kerja Excel dengan beberapa kode yang sangat mudah dibaca:
Pengembang responsif dan membantu. Proyek ini dikembangkan secara aktif, dan dokumentasinya luar biasa.
sumber
ClosedXML.Excel.XLWorkbook
Coba kode sederhana, untuk mengonversi DataTable ke file excel sebagai csv:
Ini akan menulis file baru
excel.csv
ke direktori kerja saat ini yang biasanya di mana exe berada atau di mana Anda meluncurkannya.sumber
"excel.csv"
lokasinya?,
(koma), maka menurut standar CSV sel itu harus ditutup dengan tanda kutip","
dan kemudian muncul di file seperti biasa. Jadi, ya - itu akan menimbulkan masalah karena kode ini tidak mendeteksi,
dan menerapkan tanda kutip.Opsi elegan menulis metode ekstensi (lihat di bawah) untuk kelas DataTable dari kerangka kerja .net.
Metode perpanjangan ini bisa disebut sebagai berikut:
Metode ekstensi untuk kelas DataTable:
sumber
ExcelFilePath != null && ExcelFilePath != ""
bisa jadi!String.IsNullOrEmpty(ExcelFilePath)
Solusi berdasarkan artikel tuncalik (terima kasih atas ide), tetapi dalam kasus tabel besar bekerja lebih cepat (dan sedikit kurang jelas).
sumber
Excel.Quit(); Marshal.FinalReleaseComObject(Worksheet); Marshal.FinalReleaseComObject(HeaderRange); Marshal.FinalReleaseComObject(Excel);
Coba fungsi ini meneruskan jalur data dan file tempat Anda ingin mengekspor
sumber
Cara terbaik dan termudah
sumber
private void releaseObject(object o) { try { while (System.Runtime.InteropServices.Marshal.ReleaseComObject(o) > 0) { } } catch { } finally { o = null; } }
Interop Excel:
Excel Interop - Efisiensi dan kinerja
CSV:
sumber
Kelas
Kemudian metode lain yang mendapatkan Dataset
Sekarang Anda Acara Klik Tombol
sumber
Anda dapat menggunakan perpustakaan SwiftExcel saya . Ini sangat baik ketika kinerja dan penggunaan memori yang rendah diterapkan karena menulis data langsung ke file:
Perintah Nuget untuk menginstal:
sumber
Saya ingin menambahkan jawaban ini karena saya menghabiskan banyak waktu mencari metode yang cepat dan andal untuk melakukan ini dan tidak ada contoh lengkap penggunaan OpenXMLWriter untuk tujuan ini yang ada di mana pun yang dapat saya temukan.
Pertama, COM / Interop (yang digunakan oleh banyak jawaban lain) tidak masalah untuk tujuan ini, tetapi memiliki beberapa sensitivitas. Saya telah menggunakannya selama beberapa dekade dan sebagian besar stabil, tetapi ketika menerapkan front-end gudang data untuk ratusan pengguna, saya merasa itu menjadi subjek terlalu banyak masalah tergantung pada mesin dan apa yang dilakukan pengguna, jadi saya beralih ke OpenXML. OpenXML DOM cukup baik untuk tujuan ini, tetapi lebih lambat daripada menggunakan OpenXMLWriter. Saat Anda masuk ke kumpulan data besar (100K +) dengan banyak kolom, DOM jauh lebih lambat daripada OpenXMLWriter, jadi saya menggunakan yang terakhir. Metode di bawah ini menulis 420K + baris dengan 30+ kolom dalam waktu kurang dari 30 detik.
Saya harap komentarnya cukup untuk memandu siapa pun melalui apa yang dilakukannya. Ini disederhanakan, karena menulis semua nilai ke file sebagai string, tetapi Anda dapat mengimplementasikan logika untuk menulis berbagai tipe data (dan menggunakan berbagai format sel) berdasarkan konten data Anda. Anda juga dapat menyesuaikan ini untuk digunakan pada DataGridView (bukan DataTable) dengan hanya mengubah beberapa hal (yaitu loop melalui kolom / baris).
Referensi ke DocumentFormat.OpenXML (d / l dengan OpenXML SDK) dan WindowsBase diperlukan.
sumber
Tentang tuncalik dengan jawaban , yang bagus, terutama jika Anda ingin sedikit bermain dengan kode :) tetapi memasukkan tanggal saya ke Excel dalam format Amerika yaitu 2 Maret 2014 di Inggris adalah 02/03/2014 tetapi di AS tanggal 03/02/2014 dengan bulan ke-1, kemudian hari dalam seminggu setelahnya. Saya perlu memilikinya dalam format UK, ada ide?
Saya telah memeriksa itu disimpan dalam format Inggris di DataTable saya dan juga Excel saya disetel ke Inggris tetapi untuk beberapa alasan ketika itu membuat dokumen Excel dianggapnya AS (apakah ini karena Microsoft adalah perusahaan AS :)
Saya akan mencoba bereksperimen dengan kode budaya tetapi belum yakin harus meletakkannya di mana. Sudah mencoba tapi ini tidak berpengaruh.
ps
Saya memang harus mengubah satu baris agar berfungsi dengan menambahkan 'pemeran' seperti di bawah ini
Pembaruan: Saya telah mencapai pemformatan Inggris dari tanggal dengan mengonversi ke format LongDateTime, itu hanya solusi sekalipun.
Bersulang.
sumber
Anda dapat menggunakan EasyXLS yang merupakan pustaka untuk mengekspor file Excel.
Periksa kode ini:
Lihat juga contoh ini tentang cara mengekspor datatable ke excel di C # .
sumber
Utas lama - tetapi saya pikir saya akan membuang kode saya di sini. Saya menulis sedikit fungsi untuk menulis tabel data ke lembar excel baru di jalur (lokasi) yang ditentukan. Anda juga perlu menambahkan referensi ke pustaka microsoft excel 14.0.
Saya menarik dari utas ini tentang menulis apa pun untuk unggul - Cara menulis beberapa data ke file excel (.xlsx)
saya menggunakannya untuk memperkirakan cara menulis dataTable
* Catatan dalam pernyataan tangkap saya memiliki referensi kelas statis errorhandler (Anda dapat mengabaikannya)
sumber
SaveAs
baris Anda seperti yang disertakan di sini: 'XlObj.DisplayAlerts = false; WbObj.SaveAs (lokasi); WbObj.Close (); XlObj.Quit (); Marshal.ReleaseComObject (WsObj); Marshal.ReleaseComObject (WbObj); Marshal.ReleaseComObject (XlObj); ' Untuk menggunakanMarshal.ReleaseComObject
metode ini, tambahkanusing System.Runtime.InteropServices
rakitan ke proyek Anda.Salah satu cara untuk melakukannya juga dengan Penyedia OLEDB ACE (lihat juga string koneksi untuk Excel ). Tentu saja Anda harus menginstal dan mendaftarkan penyedia. Anda harus memilikinya, jika Anda telah menginstal Excel, tetapi ini adalah sesuatu yang harus Anda pertimbangkan saat menerapkan aplikasi.
Ini adalah contoh pemanggilan metode helper dari
ExportHelper
:ExportHelper.CreateXlsFromDataTable(myDataTable, @"C:\tmp\export.xls");
Pembantu untuk mengekspor ke file Excel menggunakan ACE OLEDB:
sumber
gunakan kelas berikut
}
sumber
Segala sesuatu yang perlu menjadi kolom di Excel harus dihias
[ReportHeaderAttribute("Column Name")]
Kemudian Cukup
sumber
Untuk mengekspor data ke Excel, Anda dapat menggunakan pustaka ClosedXML.Report ( https://github.com/ClosedXML/ClosedXML.Report ). Percayalah, ini adalah perpustakaan yang luar biasa dan mudah digunakannya. Pustaka tidak membutuhkan Interop Excel. ClosedXML.Report menghasilkan file Excel berdasarkan templat yang dapat Anda buat di Excel menggunakan pemformatan apa pun. Sebagai contoh:
sumber
sumber
Kode sampel murni (jika mungkin membantu seseorang dengan beberapa ide), berdasarkan jawaban Tomasz Wiśniewski dari sini: https://stackoverflow.com/a/21079709/2717521
MainWindow ExportButton:
Kelas ExportToExcel:
sumber
Dengan paket EPPlus NuGet, itu sangat mudah .
Perhatikan bahwa
Col1
TIDAK ada dalam output:sumber