Как экспортировать данные dataGridView мгновенно в Excel при нажатии кнопки?
у меня есть 10k строк и 15 столбцов в моем представлении сетки данных. Я хочу экспортировать эти данные в лист excel o нажмите кнопку. Я уже пробовал С ниже код.
private void btExport_Click(object sender, EventArgs e)
{
Microsoft.Office.Interop.Excel._Application app = new Microsoft.Office.Interop.Excel.Application();
Microsoft.Office.Interop.Excel._Workbook workbook = app.Workbooks.Add(Type.Missing);
Microsoft.Office.Interop.Excel._Worksheet worksheet = null;
app.Visible = true;
worksheet = workbook.Sheets["Sheet1"];
worksheet = workbook.ActiveSheet;
for(int i=1;i<dataGridView1.Columns.Count+1;i++)
{
worksheet.Cells[1, i] = dataGridView1.Columns[i-1].HeaderText;
}
for (int i=0; i < dataGridView1.Rows.Count-1 ; i++)
{
for(int j=0;j<dataGridView1.Columns.Count;j++)
{
if (dataGridView1.Rows[i].Cells[j].Value != null)
{
worksheet.Cells[i + 2, j + 1] = dataGridView1.Rows[i].Cells[j].Value.ToString();
}
else
{
worksheet.Cells[i + 2, j + 1] = "";
}
}
}
}
это работает для меня, но это занимает много времени завершить процесс экспорта.
можно ли экспортировать из dataGridView (с 10k строками)в excel мгновенно одним нажатием кнопки?
кроме этого, когда я попытался скопировать все dataGridview содержание для того чтобы закрепить доску и после этого вставить ее к листу excel вручную, оно случается почти немедленно.
Итак, есть ли способ скопировать все ячейки dataGridView в клип и вставить его в лист excel (с форматированием ячеек) одним нажатием кнопки?
у меня есть код для копирования в буфер обмена, как показано ниже, но я не знаю, как вставить его в новый лист Excel, открыв его.
private void copyAllToolStripMenuItem_Click(object sender, EventArgs e)
{
dataGridView1.SelectAll();
DataObject dataObj = dataGridView1.GetClipboardContent();
if (dataObj != null)
Clipboard.SetDataObject(dataObj);
}
пожалуйста, помогите с примером. Я новичок в C#.
9 ответов
Я решил это простым методом копирования и вставки. Я не знаю, что это лучший способ сделать это, но для меня это работает хорошо и почти мгновенно. Вот мой код.
private void copyAlltoClipboard()
{
dataGridView1.SelectAll();
DataObject dataObj = dataGridView1.GetClipboardContent();
if (dataObj != null)
Clipboard.SetDataObject(dataObj);
}
private void button3_Click_1(object sender, EventArgs e)
{
copyAlltoClipboard();
Microsoft.Office.Interop.Excel.Application xlexcel;
Microsoft.Office.Interop.Excel.Workbook xlWorkBook;
Microsoft.Office.Interop.Excel.Worksheet xlWorkSheet;
object misValue = System.Reflection.Missing.Value;
xlexcel = new Excel.Application();
xlexcel.Visible = true;
xlWorkBook = xlexcel.Workbooks.Add(misValue);
xlWorkSheet = (Excel.Worksheet)xlWorkBook.Worksheets.get_Item(1);
Excel.Range CR = (Excel.Range)xlWorkSheet.Cells[1, 1];
CR.Select();
xlWorkSheet.PasteSpecial(CR, Type.Missing, Type.Missing, Type.Missing, Type.Missing, Type.Missing, true);
}
спасибо.
это отличный вопрос, и я был удивлен тем, как трудно было найти четкий и полный ответ, большинство ответов, которые я нашел, были либо sudo-кодом, либо не 100% полными.
я смог создать полное решение для копирования и сохранения данных из моего DataGridView в файл excel на основе ответа Джейка, поэтому я публикую свое полное решение в надежде, что оно может помочь другим новым пользователям c#, таким как я :)
во-первых, вам понадобится Microsoft.Office.Interop.Excel
ссылка в вашем проекте. См.MSDN о том, как добавить его.
Мой Код:
using Excel = Microsoft.Office.Interop.Excel;
private void btnExportToExcel_Click(object sender, EventArgs e)
{
SaveFileDialog sfd = new SaveFileDialog();
sfd.Filter = "Excel Documents (*.xls)|*.xls";
sfd.FileName = "Inventory_Adjustment_Export.xls";
if (sfd.ShowDialog() == DialogResult.OK)
{
// Copy DataGridView results to clipboard
copyAlltoClipboard();
object misValue = System.Reflection.Missing.Value;
Excel.Application xlexcel = new Excel.Application();
xlexcel.DisplayAlerts = false; // Without this you will get two confirm overwrite prompts
Excel.Workbook xlWorkBook = xlexcel.Workbooks.Add(misValue);
Excel.Worksheet xlWorkSheet = (Excel.Worksheet)xlWorkBook.Worksheets.get_Item(1);
// Format column D as text before pasting results, this was required for my data
Excel.Range rng = xlWorkSheet.get_Range("D:D").Cells;
rng.NumberFormat = "@";
// Paste clipboard results to worksheet range
Excel.Range CR = (Excel.Range)xlWorkSheet.Cells[1, 1];
CR.Select();
xlWorkSheet.PasteSpecial(CR, Type.Missing, Type.Missing, Type.Missing, Type.Missing, Type.Missing, true);
// For some reason column A is always blank in the worksheet. ¯\_(ツ)_/¯
// Delete blank column A and select cell A1
Excel.Range delRng = xlWorkSheet.get_Range("A:A").Cells;
delRng.Delete(Type.Missing);
xlWorkSheet.get_Range("A1").Select();
// Save the excel file under the captured location from the SaveFileDialog
xlWorkBook.SaveAs(sfd.FileName, Excel.XlFileFormat.xlWorkbookNormal, misValue, misValue, misValue, misValue, Excel.XlSaveAsAccessMode.xlExclusive, misValue, misValue, misValue, misValue, misValue);
xlexcel.DisplayAlerts = true;
xlWorkBook.Close(true, misValue, misValue);
xlexcel.Quit();
releaseObject(xlWorkSheet);
releaseObject(xlWorkBook);
releaseObject(xlexcel);
// Clear Clipboard and DataGridView selection
Clipboard.Clear();
dgvItems.ClearSelection();
// Open the newly saved excel file
if (File.Exists(sfd.FileName))
System.Diagnostics.Process.Start(sfd.FileName);
}
}
private void copyAlltoClipboard()
{
dgvItems.SelectAll();
DataObject dataObj = dgvItems.GetClipboardContent();
if (dataObj != null)
Clipboard.SetDataObject(dataObj);
}
private void releaseObject(object obj)
{
try
{
System.Runtime.InteropServices.Marshal.ReleaseComObject(obj);
obj = null;
}
catch (Exception ex)
{
obj = null;
MessageBox.Show("Exception Occurred while releasing object " + ex.ToString());
}
finally
{
GC.Collect();
}
}
Я не собирался красть ответ @Jake и @Cornelius, поэтому я попытался его отредактировать. но его отвергли.
В любом случае, единственное улучшение, на которое я должен указать, - это избежать дополнительного пустого столбца в excel после вставки. Добавление одной строки dataGridView1.RowHeadersVisible = false;
скрывает так называемый "заголовок строки", который появляется в левой части DataGridView, и поэтому он не выбран и не скопирован в буфер обмена, когда вы делаете dataGridView1.SelectAll();
private void copyAlltoClipboard()
{
//to remove the first blank column from datagridview
dataGridView1.RowHeadersVisible = false;
dataGridView1.SelectAll();
DataObject dataObj = dataGridView1.GetClipboardContent();
if (dataObj != null)
Clipboard.SetDataObject(dataObj);
}
private void button3_Click_1(object sender, EventArgs e)
{
copyAlltoClipboard();
Microsoft.Office.Interop.Excel.Application xlexcel;
Microsoft.Office.Interop.Excel.Workbook xlWorkBook;
Microsoft.Office.Interop.Excel.Worksheet xlWorkSheet;
object misValue = System.Reflection.Missing.Value;
xlexcel = new Excel.Application();
xlexcel.Visible = true;
xlWorkBook = xlexcel.Workbooks.Add(misValue);
xlWorkSheet = (Excel.Worksheet)xlWorkBook.Worksheets.get_Item(1);
Excel.Range CR = (Excel.Range)xlWorkSheet.Cells[1, 1];
CR.Select();
xlWorkSheet.PasteSpecial(CR, Type.Missing, Type.Missing, Type.Missing, Type.Missing, Type.Missing, true);
}
using Excel = Microsoft.Office.Interop.Excel;
private void btnExportExcel_Click(object sender, EventArgs e)
{
try
{
Microsoft.Office.Interop.Excel.Application excel = new Microsoft.Office.Interop.Excel.Application();
excel.Visible = true;
Microsoft.Office.Interop.Excel.Workbook workbook = excel.Workbooks.Add(System.Reflection.Missing.Value);
Microsoft.Office.Interop.Excel.Worksheet sheet1 = (Microsoft.Office.Interop.Excel.Worksheet)workbook.Sheets[1];
int StartCol = 1;
int StartRow = 1;
int j = 0, i = 0;
//Write Headers
for (j = 0; j < dgvSource.Columns.Count; j++)
{
Microsoft.Office.Interop.Excel.Range myRange = (Microsoft.Office.Interop.Excel.Range)sheet1.Cells[StartRow, StartCol + j];
myRange.Value2 = dgvSource.Columns[j].HeaderText;
}
StartRow++;
//Write datagridview content
for (i = 0; i < dgvSource.Rows.Count; i++)
{
for (j = 0; j < dgvSource.Columns.Count; j++)
{
try
{
Microsoft.Office.Interop.Excel.Range myRange = (Microsoft.Office.Interop.Excel.Range)sheet1.Cells[StartRow + i, StartCol + j];
myRange.Value2 = dgvSource[j, i].Value == null ? "" : dgvSource[j, i].Value;
}
catch
{
;
}
}
}
}
catch (Exception ex)
{
MessageBox.Show(ex.ToString());
}
}
взаимодействие происходит медленно и имеет другие проблемы, использование буфера обмена кажется не расширяемым. Вот два других способа сделать это
работа с файлами Excel 2007 + непосредственно вместо работы с Excel, это будет намного (намного) быстрее. Вы можете использовать OpenXML (http://openxmldeveloper.org/), который является SDK Microsoft. Лучший способ узнать OpenXML-загрузить инструмент производительности (http://www.microsoft.com/en-us/download/details.aspx?id=5124), он уходит существующий файл и генерирует код, необходимый для создания. Другой, возможно, более простой вариант-использовать ClosedXML (http://closedxml.codeplex.com/). Это кажется намного проще в использовании (посмотрите на пример http://closedxml.codeplex.com/wikipage?title=Showcase&referringTitle=Home), но у меня нет опыта в этом. Я уверен, что есть другие библиотеки, которые обертывают работу с Превосходить.
работа с excel через OLEDB. Это позволяет работать с Excel, как если бы это dababase. См.http://www.codeproject.com/Articles/8500/Reading-and-Writing-Excel-using-OLEDB или производительность OLEDB для чтения Excel для примеров и более подробной информации.
Я бы начал с ClosedXML.
лучше использовать библиотеки closedxml.codeplex.com .Обратитесь к нему @https://closedxml.codeplex.com/wikipage?title=Adding%20DataTable%20as%20Worksheet&referringTitle=Documentation
var wb = new ClosedXML.Excel.XLWorkbook();
DataTable dt = GetTheDataTable();//Refer documentation
wb.Worksheets.Add(dt);
Response.Clear();
Response.ContentType = "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet";
Response.AddHeader("content-disposition", "attachment;filename=\"FileName.xlsx\"");
using (var ms = new System.IO.MemoryStream()) {
wb.SaveAs(ms);
ms.WriteTo(Response.OutputStream);
ms.Close();
}
Response.End();
Мне нравится решение Джейка. Проблема без заголовка решается следующим образом
xlWorkSheet.Cells[1, 1] = "Header 1";
xlWorkSheet.Cells[1, 2] = "Header 2";
xlWorkSheet.Cells[1, 3] = "Header 3";
конечно, это работает только, вы знаете, что заголовки должны быть впереди времени.
это то, что я использую для своего gridview, попробуйте использовать его для данных yr , он отлично работает:
GridView1.AllowPaging = false;
GridView1.DataBind();
StringBuilder sb = new StringBuilder();
for (int k = 0; k < GridView1.Columns.Count; k++)
{
//add separator
sb.Append(GridView1.Columns[k].HeaderText+";");
}
//append new line
sb.Append("\r\n");
for (int i = 0; i < GridView1.Rows.Count; i++)
{
for (int k = 0; k < GridView1.Columns.Count; k++)
{
sb.Append(GridView1.Rows[i].Cells[k].Text+";");
}
sb.AppendLine();
}
этот ответ для первого вопроса, почему это занимает так много времени, и он предлагает альтернативное решение для экспорта DataGridView в Excel.
MS Office Interop работает медленно, и даже Microsoft не рекомендует использовать взаимодействие на стороне сервера и не может использоваться для экспорта больших файлов Excel. Более подробную информацию см. Почему бы не использовать Ole Automation С точки зрения Microsoft.
Interop сохраняет файлы Excel в формате XLS (старый файл Excel 97-2003 формат) и поддержка Office 2003 завершилась. Microsoft Excel выпустила XLSX формат файла с Office 2007 и рекомендует использовать OpenXML SDK вместо взаимодействия. Но XLSX файлы на самом деле не так быстро и не очень хорошо обрабатывать большие файлы Excel, потому что они основаны на формате XML-файла. Вот почему Microsoft также выпустила XLSB формат файла с Office 2007, формат файла, который рекомендуется для больших файлов Excel. Это двоичный формат. Поэтому лучшее и быстрое решение-сохранить XLSB файлы.
вы можете использовать этот библиотека Excel C# для сохранения файлов XLSB, но он также поддерживает форматы файлов XLS и XLSX.
см. следующий пример кода в качестве альтернативы экспорту DataGridView в Excel:
// Create a DataSet and add the DataTable of DataGridView
DataSet dataSet = new DataSet();
dataSet.Tables.Add((DataTable)dataGridView);
//or ((DataTable)dataGridView.DataSource).Copy() to create a copy
// Export Excel file
ExcelDocument workbook = new ExcelDocument();
workbook.easy_WriteXLSBFile_FromDataSet(filePath, dataSet,
new EasyXLS.ExcelAutoFormat(EasyXLS.Constants.Styles.AUTOFORMAT_EASYXLS1),
"Sheet1");
Если Вам также нужно экспортировать форматирование DataGridView, проверьте этот пример кода о том, как экспорт datagridview в Excel в C#.