I'm new to c# and WPF and trying to import a large .xlsx file into a datagrid, i can have around 200+ columns & 100,000+ rows. With my current method it is taking over an hour (i didn't let it finish). An example of my format in csv terms would be;
"Time","Dist","V_Front","V_Rear","RPM"
"s","m","km/h","km/h","rpm"
"0.000","0","30.3","30.0","11995"
"0.005","0","30.3","30.0","11965"
"0.010","0","30.3","31.0","11962"
I'm using Interop at the moment but i'm wondering whether there is another approach which would drastically cut down load time. I hope to plot this data using SciCharts (they have a student licence), with check boxes for channel selection but that's another matter.
.CS
private void Button_Click(object sender, RoutedEventArgs e)
{
OpenFileDialog openfile = new OpenFileDialog();
openfile.DefaultExt = ".xlsx";
openfile.Filter = "(.xlsx)|*.xlsx";
var browsefile = openfile.ShowDialog();
if (browsefile == true)
{
txtFilePath.Text = openfile.FileName;
Microsoft.Office.Interop.Excel.Application excelApp = new Microsoft.Office.Interop.Excel.Application();
Microsoft.Office.Interop.Excel.Workbook excelBook = excelApp.Workbooks.Open(txtFilePath.Text.ToString(), 0, true, 5, "", "", true, Microsoft.Office.Interop.Excel.XlPlatform.xlWindows, "\t", false, false, 0, true, 1, 0);
Microsoft.Office.Interop.Excel.Worksheet excelSheet = (Microsoft.Office.Interop.Excel.Worksheet)excelBook.Worksheets.get_Item(1); ;
Microsoft.Office.Interop.Excel.Range excelRange = excelSheet.UsedRange;
string strCellData = "";
double douCellData;
int rowCnt = 0;
int colCnt = 0;
DataTable dt = new DataTable();
for (colCnt = 1; colCnt <= excelRange.Columns.Count; colCnt++)
{
string strColumn = "";
strColumn = (string)(excelRange.Cells[1, colCnt] as Microsoft.Office.Interop.Excel.Range).Value2;
dt.Columns.Add(strColumn, typeof(string));
}
for (rowCnt = 2; rowCnt <= excelRange.Rows.Count; rowCnt++)
{
string strData = "";
for (colCnt = 1; colCnt <= excelRange.Columns.Count; colCnt++)
{
try
{
strCellData = (string)(excelRange.Cells[rowCnt, colCnt] as Microsoft.Office.Interop.Excel.Range).Value2;
strData += strCellData + "|";
}
catch (Exception ex)
{
douCellData = (excelRange.Cells[rowCnt, colCnt] as Microsoft.Office.Interop.Excel.Range).Value2;
strData += douCellData.ToString() + "|";
}
}
strData = strData.Remove(strData.Length - 1, 1);
dt.Rows.Add(strData.Split('|'));
}
dtGrid.ItemsSource = dt.DefaultView;
excelBook.Close(true, null, null);
excelApp.Quit();
}
}
Any help i really appreciated.
The problem is that there is too many individual reads which causes a lot of reflection usage and marshalling between Excel and your application. If you're not concerned about memory usage, you can just read the whole Range into memory and work from memory instead of individually reading cells. The below code runs in 3880 ms on a test file with 5 columns and 103938 rows:
OpenFileDialog openfile = new OpenFileDialog();
openfile.DefaultExt = ".xlsx";
openfile.Filter = "(.xlsx)|*.xlsx";
var browsefile = openfile.ShowDialog();
if (browsefile == true)
{
txtFilePath.Text = openfile.FileName;
var excelApp = new Microsoft.Office.Interop.Excel.Application();
var excelBook = excelApp.Workbooks.Open(txtFilePath.Text, 0, true, 5, "", "", true,
Microsoft.Office.Interop.Excel.XlPlatform.xlWindows, "\t", false, false, 0, true, 1, 0);
var excelSheet = (Microsoft.Office.Interop.Excel.Worksheet) excelBook.Worksheets.Item[1];
Microsoft.Office.Interop.Excel.Range excelRange = excelSheet.UsedRange;
DataTable dt = new DataTable();
object[,] value = excelRange.Value;
int columnsCount = value.GetLength(1);
for (var colCnt = 1; colCnt <= columnsCount; colCnt++)
{
dt.Columns.Add((string)value[1, colCnt], typeof(string));
}
int rowsCount = value.GetLength(0);
for (var rowCnt = 2; rowCnt <= rowsCount; rowCnt++)
{
var dataRow = dt.NewRow();
for (var colCnt = 1; colCnt <= columnsCount; colCnt++)
{
dataRow[colCnt - 1] = value[rowCnt, colCnt];
}
dt.Rows.Add(dataRow);
}
dtGrid.ItemsSource = dt.DefaultView;
excelBook.Close(true);
excelApp.Quit();
}
If you don't want to read the whole Range in, then you should do that in sensible batches.
Another optimization is to run this on a background thread, so it won't block the UI while it's loading.
Edit
For running this on a background thread you could modify the button click handler to be an async method and put the parsing logic into another method which runs the actual parsing on a threadpool thread with Task.Run:
private async void Button_Click(object sender, RoutedEventArgs e)
{
OpenFileDialog openfile = new OpenFileDialog();
openfile.DefaultExt = ".xlsx";
openfile.Filter = "(.xlsx)|*.xlsx";
var browsefile = openfile.ShowDialog();
if (browsefile == true)
{
txtFilePath.Text = openfile.FileName;
DataTable dataTable = await ParseExcel(txtFilePath.Text).ConfigureAwait(true);
dtGrid.ItemsSource = dataTable.DefaultView;
}
}
private Task<DataTable> ParseExcel(string filePath)
{
return Task.Run(() =>
{
var excelApp = new Microsoft.Office.Interop.Excel.Application();
var excelBook = excelApp.Workbooks.Open(filePath, 0, true, 5, "", "", true,
Microsoft.Office.Interop.Excel.XlPlatform.xlWindows, "\t", false, false, 0, true, 1, 0);
var excelSheet = (Microsoft.Office.Interop.Excel.Worksheet) excelBook.Worksheets.Item[1];
Microsoft.Office.Interop.Excel.Range excelRange = excelSheet.UsedRange;
DataTable dt = new DataTable();
object[,] value = excelRange.Value;
int columnsCount = value.GetLength(1);
for (var colCnt = 1; colCnt <= columnsCount; colCnt++)
{
dt.Columns.Add((string) value[1, colCnt], typeof(string));
}
int rowsCount = value.GetLength(0);
for (var rowCnt = 2; rowCnt <= rowsCount; rowCnt++)
{
var dataRow = dt.NewRow();
for (var colCnt = 1; colCnt <= columnsCount; colCnt++)
{
dataRow[colCnt - 1] = value[rowCnt, colCnt];
}
dt.Rows.Add(dataRow);
}
excelBook.Close(true);
excelApp.Quit();
return dt;
});
}
The handler just invokes the parsing function, the parsing function runs on a background thread and when it finishes the handler can continue by assigning the resulting DataTable to the ItemsSource.
Related
This is a simple way to export to an excel file
i tried with Microsoft.Office.Interop.Excel but failed with it.Finally i found the simpler solution
Could not load file or assembly 'office, Version=15.0.0.0, Culture=neutral, PublicKeyToken=71e9bc111e9429c' or one of its dependencies. The system cannot find the file specified
private void btnExport_Click(object sender, EventArgs e)
{
DataTable dataTable= new Database().SelectData("SelectAllSinhVien",lstPara);//return (DataTable) from database
string filePath = "";
SaveFileDialog dialog = new SaveFileDialog();
dialog.Filter = "Excel | *.xlsx";
if (dialog.ShowDialog() == DialogResult.OK)
{
filePath = dialog.FileName;
}
if (string.IsNullOrEmpty(filePath))
{
MessageBox.Show("Invalid!!!");
return;
}
ExcelPackage.LicenseContext= OfficeOpenXml.LicenseContext.NonCommercial;
try
{
using (ExcelPackage p = new ExcelPackage())
{
p.Workbook.Properties.Author = "Hà Văn Ri";
p.Workbook.Properties.Title = "Report File";
p.Workbook.Worksheets.Add("Sheet 1");
ExcelWorksheet ws = p.Workbook.Worksheets[0];
ws.Name = "Sheet 1";
ws.Cells.Style.Font.Size = 12;
ws.Cells.Style.Font.Bold = true;
ws.Cells.Style.Font.Name = "Times New Roman";
string[] arrColumnHeader =
{
"Mã sinh viên","Họ tên","Ngày sinh","Giới tính","Địa chỉ","Điện thoại","Email"//headerText list
};
var countColHeader = arrColumnHeader.Count();
ws.Cells[1, 1].Value = "Danh sách sinh viên";
ws.Cells[1, 1, 1, countColHeader].Merge = true;
ws.Cells[1, 1, 1, countColHeader].Style.HorizontalAlignment=OfficeOpenXml.Style.ExcelHorizontalAlignment.Center;
int colHeader = 1;
int rowHeader = 2;
foreach(var header in arrColumnHeader)
{
var cell = ws.Cells[rowHeader, colHeader];
var fill = cell.Style.Fill;
fill.PatternType = OfficeOpenXml.Style.ExcelFillStyle.Solid;
fill.BackgroundColor.SetColor(System.Drawing.Color.LightBlue);
cell.Value = header;
colHeader++;
}
int colIndex = 1;
int rowIndex = 2;
foreach (DataRow dr in dataTable.Rows)//fields in obj
{
colIndex = 1;
rowIndex++;
ws.Cells[rowIndex, colIndex++].Value = dr["masinhvien"].ToString();
ws.Cells[rowIndex, colIndex++].Value = dr["hoten"].ToString();
ws.Cells[rowIndex, colIndex++].Value = dr["ngaysinh"].ToString();
ws.Cells[rowIndex, colIndex++].Value = dr["gioitinh"].ToString();
ws.Cells[rowIndex, colIndex++].Value = dr["diachi"].ToString();
ws.Cells[rowIndex, colIndex++].Value = dr["dienthoai"].ToString();
ws.Cells[rowIndex, colIndex++].Value = dr["email"].ToString();
}
Byte[] bin =p.GetAsByteArray();
File.WriteAllBytes(filePath, bin);
}
MessageBox.Show("Thành công");
}
catch (Exception ex )
{
MessageBox.Show("thất bại: "+ex);
}
}
I have a datagridview and already have a export function using Microsoft interop however i am struggling to find a solution to the loading the data.
My code to export to Excel:
private void iSave()
{
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["Journal"];
worksheet = workbook.ActiveSheet;
worksheet.Name = "Exported from Journal Pro";
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++)
{
worksheet.Cells[i + 2, j + 1] = dataGridView1.Rows[i].Cells[j].Value.ToString();
}
}
}
I also want it to add data from the second row as the first row is the title of the columns.
If theres a solution to use excel to load data in using the same format which is exported in i would be grateful :)
I am also open to other methods of saving, it doesn't have to be to an excel file.
I have used some other codes found online such as
`
using (OpenFileDialog ofd = new OpenFileDialog())
{
ofd.Filter = "Excel Files Only | *.xlsx; *.xls";
ofd.Title = "Choose the File";
if (ofd.ShowDialog() == DialogResult.OK)
FileName_LBL.Text = ofd.FileName;
}
Microsoft.Office.Interop.Excel._Application xlapp;
Microsoft.Office.Interop.Excel._Workbook xlworkbook;
Microsoft.Office.Interop.Excel._Worksheet xlworksheet;
Microsoft.Office.Interop.Excel._Worksheet xlrange;
try
{
xlapp = new Microsoft.Office.Interop.Excel.Application();
xlworkbook = xlapp.Workbooks.Open(FileName_LBL.Text);
xlworksheet = xlworkbook.Worksheets["Exported from Journal Pro"];
xlrange = (Microsoft.Office.Interop.Excel._Worksheet)xlworksheet.UsedRange;
dataGridView1.ColumnCount = xlrange.Columns.Count;
for (int xlrow = 2; xlrow <= xlrange.Rows.Count; xlrow++)
{
dataGridView1.Rows.Add(xlrange.Cells[xlrow, 2].Text, xlrange.Cells[xlrow, 3].Text, xlrange.Cells[xlrow, 4].Text, xlrange.Cells[xlrow, 5].Text, xlrange.Cells[xlrow, 6].Text, xlrange.Cells[xlrow, 7].Text);
}
xlworkbook.Close();
xlapp.Quit();
}
catch (Exception ex)
{
MessageBox.Show(ex.Message);
}
`
but i get errors such as DISP_E_BADINDEX and E_NOINTERFACE
You can use this method to finish loading the data.
Step 1: Convert dataGridView to dataTable.
Step 2: Export dataTable to Excel .
Step 3: button calls the OutputExcel method.
Full Code
private void button1_Click(object sender, EventArgs e)
{
OutputExcel(dataGridView1);
}
public void OutputExcel(DataGridView dataGridView)
{
string filePath = "";
SaveFileDialog s = new SaveFileDialog();
s.Title = "Excel";
s.Filter = "Excel(*.xlsx)|*.xlsx";
s.FilterIndex = 1;
if (s.ShowDialog() == DialogResult.OK)
filePath = s.FileName;
else
return;
//Step 1: Convert dataGridView to dataTable
DataTable tmpDataTable = new DataTable("tmpDataTable");
DataTable modelTable = new DataTable("ModelTable");
for (int column = 0; column < dataGridView.Columns.Count; column++)
{
if (dataGridView.Columns[column].Visible == true)
{
DataColumn tempColumn = new DataColumn(dataGridView.Columns[column].HeaderText, typeof(string));
tmpDataTable.Columns.Add(tempColumn);
DataColumn modelColumn = new DataColumn(dataGridView.Columns[column].Name, typeof(string));
modelTable.Columns.Add(modelColumn);
}
}
for (int row = 0; row < dataGridView.Rows.Count; row++)
{
if (dataGridView.Rows[row].Visible == false)
continue;
DataRow tempRow = tmpDataTable.NewRow();
for (int i = 0; i < tmpDataTable.Columns.Count; i++)
tempRow[i] = dataGridView.Rows[row].Cells[modelTable.Columns[i].ColumnName].Value;
tmpDataTable.Rows.Add(tempRow);
}
if (tmpDataTable == null)
{
return;
}
//Step 2: Export dataTable to Excel
long rowNum = tmpDataTable.Rows.Count;//line
int columnNum = tmpDataTable.Columns.Count;//column
Excel.Application m_xlApp = new Excel.Application();
m_xlApp.DisplayAlerts = false;
m_xlApp.Visible = false;
Excel.Workbooks workbooks = m_xlApp.Workbooks;
Excel.Workbook workbook = workbooks.Add(Excel.XlWBATemplate.xlWBATWorksheet);
Excel.Worksheet worksheet = (Excel.Worksheet)workbook.Worksheets[1];//Get sheet1
try
{
string[,] datas = new string[rowNum + 1, columnNum];
for (int i = 0; i < columnNum; i++) //Write field
datas[0, i] = tmpDataTable.Columns[i].Caption;
Excel.Range range = m_xlApp.Range[worksheet.Cells[1, 1], worksheet.Cells[1, columnNum]];
range.Interior.ColorIndex = 15;
range.Font.Bold = true;
range.Font.Size = 10;
int r = 0;
for (r = 0; r < rowNum; r++)
{
for (int i = 0; i < columnNum; i++)
{
object obj = tmpDataTable.Rows[r][tmpDataTable.Columns[i].ToString()];
datas[r + 1, i] = obj == null ? "" : "'" + obj.ToString().Trim();
}
Application.DoEvents();
}
Excel.Range fchR = m_xlApp.Range[worksheet.Cells[1, 1], worksheet.Cells[rowNum + 1, columnNum]];
fchR.Value2 = datas;
worksheet.Columns.EntireColumn.AutoFit();
m_xlApp.Visible = false;
range = m_xlApp.Range[worksheet.Cells[1, 1], worksheet.Cells[rowNum + 1, columnNum]];
range.Font.Size = 9;
range.RowHeight = 14.25;
range.Borders.LineStyle = 1;
range.HorizontalAlignment = 1;
workbook.Saved = true;
workbook.SaveCopyAs(filePath);
}
catch (Exception ex)
{
MessageBox.Show("Export Exception:" + ex.Message, "Export Exception", MessageBoxButtons.OK, MessageBoxIcon.Warning);
}
m_xlApp.Workbooks.Close();
m_xlApp.Workbooks.Application.Quit();
m_xlApp.Application.Quit();
m_xlApp.Quit();
MessageBox.Show("Export successful!", "Tips", MessageBoxButtons.OK, MessageBoxIcon.Information);
}
Effect:
Hope it can help you.
I have a DataGridView in WinForms 2.0 C# that is populated from a DataTable (from SQL) and with already created column headers in DataGridView:
OleDbDataAdapter dAdapter = new OleDbDataAdapter(query, conn.ConnectionString);
OleDbCommandBuilder cBuilder = new OleDbCommandBuilder(dAdapter);
tableMainGrid = new DataTable();
dAdapter.Fill(tableMainGrid);
...
dataGridView1.DataSource = tableMainGrid;
dataGridView1.AutoGenerateColumns = false;
The problem is, when I use the following command:
worksheet.ImportDataGridView(dgv, 1, 1,true,false);
I get the header from the SQL command / DataTable and not from the Grid.
I use this code to export:
public static void ExportToExcel(DataGridView dgv, string lang, string tablename)
{
using (ExcelEngine excelEngine = new ExcelEngine())
{
IApplication application = excelEngine.Excel;
application.DefaultVersion = ExcelVersion.Excel2013;
IWorkbook workbook = application.Workbooks.Create(1);
IWorksheet worksheet = workbook.Worksheets[0];
worksheet.ImportDataGridView(dgv, 1, 1,true,false);
worksheet.AutoFilters.FilterRange = worksheet.Range;
worksheet.Range.AutofitColumns();
worksheet.Range.AutofitRows();
//...more code - styling header and cells
SaveFileDialog saveFileDialog1 = new SaveFileDialog();
saveFileDialog1.Filter = "Excel XLS|*.xls";
saveFileDialog1.ShowDialog();
if (saveFileDialog1.FileName != "")
{
workbook.SaveAs(saveFileDialog1.FileName, ExcelSaveType.SaveAsXLS);
System.Diagnostics.Process.Start(saveFileDialog1.FileName);
}
}
}
Syncfusion Version : 16.3.0.21
Visual Studio: 2005
Instead of using:
worksheet.ImportDataGridView(dgv, 1, 1,true,false);
OR
worksheet.ImportDataTable(table, true, 1, 1);
I'm using for loops:
using (ExcelEngine excelEngine = new ExcelEngine())
{
IApplication application = excelEngine.Excel;
application.DefaultVersion = ExcelVersion.Excel2013;
IWorkbook workbook = application.Workbooks.Create(1);
IWorksheet worksheet = workbook.Worksheets[0];
for (int i = 1; i < dgv.Columns.Count + 1; i++)
{
worksheet.Range[1, i].Text = dgv.Columns[i - 1].HeaderText;
}
for (int i = 0; i < dgv.Rows.Count; i++)
{
for (int j = 0; j < dgv.Columns.Count; j++)
{
worksheet.Range[i + 2, j + 1].Text = dgv.Rows[i].Cells[j].Value.ToString();
}
}
worksheet.AutoFilters.FilterRange = worksheet.Range;
worksheet.Range.AutofitColumns();
worksheet.Range.AutofitRows();
worksheet.Range.IgnoreErrorOptions = ExcelIgnoreError.All;
SaveFileDialog saveFileDialog1 = new SaveFileDialog();
saveFileDialog1.Filter = "Excel XLS|*.xls";
saveFileDialog1.ShowDialog();
if (saveFileDialog1.FileName != "")
{
workbook.SaveAs(saveFileDialog1.FileName, ExcelSaveType.SaveAsXLS);
System.Diagnostics.Process.Start(saveFileDialog1.FileName);
}
}
this way I get the header and also all the rows
#jdweng and #housheng: thanks for the help
i am using Interop.Excel to export data from datatable and generate line chart too. i have got a code which export data to excel from data table and also create chart there but the code is giving error at this line
Excel.Axis yAxis = (Excel.Axis)xlChart.Axes(Excel.XlAxisType.xlSeriesAxis,
Excel.XlAxisGroup.xlPrimary);
and the error message i am getting Value does not fall within the expected range
my full code for line chart generation.
private void button1_Click(object sender, EventArgs e)
{
System.Data.DataTable dt = GetGraphData();
Excel.Application xla = new Excel.Application();
xla.Visible = true;
Excel.Workbook wb = xla.Workbooks.Add(Excel.XlSheetType.xlWorksheet);
Excel.Worksheet ws = (Excel.Worksheet)wb.ActiveSheet;
//********************** Now create the chart. *****************************
Excel.ChartObjects chartObjs = (Excel.ChartObjects)ws.ChartObjects(Type.Missing);
Excel.ChartObject chartObj = chartObjs.Add(250, 60, 300, 300);
Excel.Chart xlChart = chartObj.Chart;
int nRows = 2;
int nColumns = dt.Rows.Count;
string upperLeftCell = "B2";
int endRowNumber = System.Int32.Parse(upperLeftCell.Substring(1))
+ nRows - 1;
char endColumnLetter = System.Convert.ToChar(
Convert.ToInt32(upperLeftCell[0]) + nColumns - 1);
string upperRightCell = System.String.Format("{0}{1}",
endColumnLetter, System.Int32.Parse(upperLeftCell.Substring(1)));
string lowerRightCell = System.String.Format("{0}{1}",
endColumnLetter, endRowNumber);
Excel.Range rg = ws.get_Range(upperLeftCell, lowerRightCell);
for (int i = 1; i <= dt.Rows.Count; i++)
{
rg[1, i] = dt.Rows[i - 1][0].ToString(); //For Adding Header Text
rg[2, i] = int.Parse(dt.Rows[i - 1][1].ToString()); //For Adding Datarow Value
}
Excel.Range chartRange = ws.get_Range(upperLeftCell, lowerRightCell);
xlChart.SetSourceData(chartRange, Type.Missing);
xlChart.ChartType = Excel.XlChartType.xlLine;
// *******************Customize axes: ***********************
Excel.Axis xAxis = (Excel.Axis)xlChart.Axes(Excel.XlAxisType.xlCategory,
Excel.XlAxisGroup.xlPrimary);
//xAxis.HasTitle = true;
// xAxis.AxisTitle.Text = "X Axis";
Excel.Axis yAxis = (Excel.Axis)xlChart.Axes(Excel.XlAxisType.xlSeriesAxis,
Excel.XlAxisGroup.xlPrimary);
//yAxis.HasTitle = true;
//yAxis.AxisTitle.Text = "Y Axis";
Excel.Axis zAxis = (Excel.Axis)xlChart.Axes(Excel.XlAxisType.xlValue,
Excel.XlAxisGroup.xlPrimary);
//zAxis.HasTitle = true;
//zAxis.AxisTitle.Text = "Z Axis";
// *********************Add title: *******************************
xlChart.HasTitle = true;
xlChart.ChartTitle.Text = "Project Status Graph";
// *****************Set legend:***************************
xlChart.HasLegend = true;
FileStream file = new FileStream(#"c:\pop.xls", FileMode.Create);
file.Close();
wb.SaveCopyAs(#"c:\pop.xls");
// ****************For Quiting The Excel Aplication ***********************
if (xla != null)
{
xla.DisplayAlerts = false;
wb.Close();
wb = null;
xla.Quit();
xla = null;
}
}
private System.Data.DataTable GetGraphData()
{
System.Data.DataTable dt = new System.Data.DataTable();
dt.Columns.AddRange(new DataColumn[2] { new DataColumn("ProjectStatus"), new DataColumn("per") });
DataRow dr1 = dt.NewRow();
dr1[0] = "Compleet";
dr1[1] = 20;
dt.Rows.Add(dr1);
DataRow dr2 = dt.NewRow();
dr2[0] = "Pending";
dr2[1] = 20;
dt.Rows.Add(dr2);
DataRow dr3 = dt.NewRow();
dr3[0] = "UnCompleet";
dr3[1] = 20;
dt.Rows.Add(dr3);
return dt;
}
looking for help. thanks
My coworker tells me that according to intellisense, the value of the first argument (Excel.XlAxisType.xlSeriesAxis) is valid only for 3D charts.
What kind of chart are you creating?
I am trying to copy DataGridView data to Excel and I am using this code:
public static void ExportToExcel(DataGridView dgView)
{
Microsoft.Office.Interop.Excel.Application excelApp = null;
try
{
// instantiating the excel application class
object misValue = System.Reflection.Missing.Value;
excelApp = new Microsoft.Office.Interop.Excel.Application();
Microsoft.Office.Interop.Excel.Workbook currentWorkbook = excelApp.Workbooks.Add(Type.Missing);
Microsoft.Office.Interop.Excel.Worksheet currentWorksheet = (Microsoft.Office.Interop.Excel.Worksheet)currentWorkbook.ActiveSheet;
currentWorksheet.Columns.ColumnWidth = 18;
if (dgView.Rows.Count > 0)
{
currentWorksheet.Cells[1, 1] = DateTime.Now.ToString("s");
int i = 1;
foreach (DataGridViewColumn dgviewColumn in dgView.Columns)
{
// Excel work sheet indexing starts with 1
currentWorksheet.Cells[2, i] = dgviewColumn.Name;
++i;
}
Microsoft.Office.Interop.Excel.Range headerColumnRange = currentWorksheet.get_Range("A2", "G2");
headerColumnRange.Font.Bold = true;
headerColumnRange.Font.Color = 0xFF0000;
//headerColumnRange.EntireColumn.AutoFit();
int rowIndex = 0;
for (rowIndex = 0; rowIndex < dgView.Rows.Count; rowIndex++)
{
DataGridViewRow dgRow = dgView.Rows[rowIndex];
for (int cellIndex = 0; cellIndex < dgRow.Cells.Count; cellIndex++)
{
currentWorksheet.Cells[rowIndex + 3, cellIndex + 1] = dgRow.Cells[cellIndex].Value;
}
}
Microsoft.Office.Interop.Excel.Range fullTextRange = currentWorksheet.get_Range("A1", "G" + (rowIndex + 1).ToString());
fullTextRange.WrapText = true;
fullTextRange.HorizontalAlignment = Microsoft.Office.Interop.Excel.XlHAlign.xlHAlignLeft;
}
else
{
string timeStamp = DateTime.Now.ToString("s");
timeStamp = timeStamp.Replace(':', '-');
timeStamp = timeStamp.Replace("T", "__");
currentWorksheet.Cells[1, 1] = timeStamp;
currentWorksheet.Cells[1, 2] = "No error occured";
}
using (SaveFileDialog exportSaveFileDialog = new SaveFileDialog())
{
exportSaveFileDialog.Title = "Select Excel File";
exportSaveFileDialog.Filter = "Microsoft Office Excel Workbook(*.xlsx)|*.xlsx";
if (DialogResult.OK == exportSaveFileDialog.ShowDialog())
{
string fullFileName = exportSaveFileDialog.FileName;
// currentWorkbook.SaveCopyAs(fullFileName);
// indicating that we already saved the workbook, otherwise call to Quit() will pop up
// the save file dialogue box
currentWorkbook.SaveAs(fullFileName, Microsoft.Office.Interop.Excel.XlFileFormat.xlOpenXMLWorkbook, System.Reflection.Missing.Value, misValue, false, false, Microsoft.Office.Interop.Excel.XlSaveAsAccessMode.xlNoChange, Microsoft.Office.Interop.Excel.XlSaveConflictResolution.xlUserResolution, true, misValue, misValue, misValue);
currentWorkbook.Saved = true;
MessageBox.Show("Exported successfully", "Exported to Excel", MessageBoxButtons.OK, MessageBoxIcon.Information);
}
}
}
catch (Exception ex)
{
MessageBox.Show(ex.Message, "Exception", MessageBoxButtons.OK, MessageBoxIcon.Error);
}
finally
{
if (excelApp != null)
{
excelApp.Quit();
}
}
}
But as there is over 200 000 records, its taking a long time to export. Is there a faster way to do this?
Try this code. It's faster than the normal interop methods, also it converts into CSV which can be read easily by excel.
int cols;
//open file
StreamWriter wr = new StreamWriter("GB STOCK.csv");
//determine the number of columns and write columns to file
cols = dgvStock.Columns.Count;
for (int i = 0; i < cols - 1; i++)
{
wr.Write(dgvStock.Columns[i].Name.ToString().ToUpper() + ",");
}
wr.WriteLine();
//write rows to excel file
for (int i = 0; i < (dgvStock.Rows.Count - 1); i++)
{
for (int j = 0; j < cols; j++)
{
if (dgvStock.Rows[i].Cells[j].Value != null)
{
wr.Write(dgvStock.Rows[i].Cells[j].Value + ",");
}
else
{
wr.Write(",");
}
}
wr.WriteLine();
}
//close file
wr.Close();
How to export GridView data to excel in asp.net in C#.
more details click here