I am not sure about what is going on here. I use this button event to export data from datagridview to excel and the data get exported, file saved, etc.., so it looks like is working fine to me.
private void button2_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;
try
{
worksheet = (Microsoft.Office.Interop.Excel.Worksheet)workbook.Sheets["Sheet1"];
worksheet = (Microsoft.Office.Interop.Excel.Worksheet)workbook.ActiveSheet;
worksheet.Name = "Gioietta Environment Data";
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();
}
}
string fileName = String.Empty;
SaveFileDialog saveFileDialog1 = new SaveFileDialog();
saveFileDialog1.Filter = "Excel files |*.xls|All files (*.*)|*.*";
saveFileDialog1.FilterIndex = 2;
saveFileDialog1.RestoreDirectory = true;
if (saveFileDialog1.ShowDialog() == DialogResult.OK)
{
fileName = saveFileDialog1.FileName;
workbook.SaveAs(fileName, Type.Missing, Type.Missing, Type.Missing, Type.Missing, Type.Missing, Microsoft.Office.Interop.Excel.XlSaveAsAccessMode.xlExclusive, Type.Missing, Type.Missing, Type.Missing, Type.Missing, Type.Missing);
}
else
return;
}
catch (System.Exception ex)
{
}
finally
{
app.Quit();
workbook = null;
app = null;
}
}
The problem I am experiencing is on that the excel side. Basically even formatting the exported values as numbers, I cannot use them. I cannot even sum them up! If I re-type the value in the same cell manually than it become usable. Has this something to to with the exporting process?
This is how I load the data to the datagridview:
var time = DateTime.Now.ToString("HH:mm:ss");
dataGridView1.Rows.Add(new string[] { time, textBox1.Text, textBox2.Text });
The problem comes from this line and how DataGridView is populated:
worksheet.Cells[i 2, j 1] = dataGridView1.Rows[i].Cells[j].Value.ToString();
Data are exported as string whatever the type due to .ToString() and they are string anyway.
As DataGridViewCell.Value contains a string, so you have to cast the dgvCell.Value to a numeric value before exporting. For example:
if (j == 1 || j == 2)
{
worksheet.Cells(i 2, j 1) = Convert.ToDecimal(dataGridView1.Rows(i).Cells(j).Value)
}
else
{
worksheet.Cells[i 2, j 1] = dataGridView1.Rows[i].Cells[j].Value.ToString();
}
If DataGridViewCell.Value contains a numeric value (Decimal, Double, Integer, ...), Just remove .toString() and it should work as expected (Excel will set the appropriate type).
In both cases, if you want to apply a custom format for displaying in Excel, you will loose it during export, and you will have to explictly set it in Excel, using Range.NumberFormat Property. These Q/A can help to achieve this:
microsoft.interop.excel Formatting cells
excel interop : NumberFormat #,##0.000 doesn't display the expected result
Related
if i export the time is null in the datagridview then when i export it the time null is become 12:00 i dont know how to condition it in exporting excel file.
this is my code:
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;
worksheet = workbook.Sheets["Sheet1"];
worksheet = workbook.ActiveSheet;
worksheet.Name = "Exported from gridview";
for (int i = 1; i < dataGridViewIn.Columns.Count + 1; i++)
{
worksheet.Cells[1, i] = dataGridViewIn.Columns[i - 1].HeaderText;
}
for (int i = 0; i < dataGridViewIn.Rows.Count - 1; i++)
{
(worksheet.Rows[i + 2 + ":" + i + 2, System.Reflection.Missing.Value] as Microsoft.Office.Interop.Excel.Range).NumberFormat = "#";
for (int j = 0; j < dataGridViewIn.Columns.Count; j++)
{
worksheet.Cells[i + 2, j + 1] = dataGridViewIn.Rows[i].Cells[j].Value.ToString();
worksheet.Cells[i + 2, 3].NumberFormat = "m/d/yy h:mm AM/PM";
}
}
var saveFileDialoge = new SaveFileDialog();
saveFileDialoge.FileName = "TimeIn";
saveFileDialoge.DefaultExt = ".xlsx";
if (saveFileDialoge.ShowDialog() == DialogResult.OK)
{
workbook.SaveAs(saveFileDialoge.FileName, Type.Missing, Type.Missing, Type.Missing, Type.Missing, Type.Missing, Microsoft.Office.Interop.Excel.XlSaveAsAccessMode.xlExclusive, Type.Missing, Type.Missing, Type.Missing, Type.Missing, Type.Missing);
app.Visible = true;
}
Just add a check and write into the excel cell only if there is data to write.
for (int j = 0; j < dataGridViewIn.Columns.Count; j++)
{
if (dataGridViewIn.Rows[i].Cells[j].Value != null)
{
worksheet.Cells[i + 2, j + 1] = dataGridViewIn.Rows[i].Cells[j].Value.ToString();
worksheet.Cells[i + 2, 3].NumberFormat = "m/d/yy h:mm AM/PM";
}
}
While exporting the datagridview to Excel in C#.net ,leading zeros are missing.
For example : Data in the cell is "001693"
After exporting to excel it is displaying me like this "1693".
Please help me out of this.
this is my code;
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;
worksheet = workbook.Sheets["Sheet1"];
worksheet = workbook.ActiveSheet;
worksheet.Name = "Exported from gridview";
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();
}
}
var saveFileDialoge = new SaveFileDialog();
saveFileDialoge.FileName = "output";
saveFileDialoge.DefaultExt = ".xlsx";
if (saveFileDialoge.ShowDialog() == DialogResult.OK)
{
workbook.SaveAs(saveFileDialoge.FileName, Type.Missing, Type.Missing, Type.Missing, Type.Missing, Type.Missing, Microsoft.Office.Interop.Excel.XlSaveAsAccessMode.xlExclusive, Type.Missing, Type.Missing, Type.Missing, Type.Missing, Type.Missing);
app.Visible = true;
You need to set text format to cell where you want to save number with leading zeroes.
In this sample I add code which set text format for entire row to speed up processing.
for (int i = 0; i < dataGridView1.Rows.Count - 1; i++)
{
(worksheet.Rows[i+2 + ":" + i+2, System.Reflection.Missing.Value] as Excel.Range).NumberFormat = "#";
for (int j = 0; j < dataGridView1.Columns.Count; j++)
{
worksheet.Cells[i + 2, j + 1] = dataGridView1.Rows[i].Cells[j].Value.ToString();
}
}
I know this topic has been discussed but I think it has some differences. I have dates stored in my database. So when I export data table into EXCEL, it shows like the image.
Here is the image of the EXCEL file:
I need to add only date. Not HH:MM:SS included. my code is pasted below:
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;
worksheet = workbook.Sheets["Sheet1"];
worksheet = workbook.ActiveSheet;
worksheet.Name = "InternDetails";
for (int i = 1; i < dataGridView3.Columns.Count + 1; i++){
worksheet.Cells[1, i] = dataGridView3.Columns[i - 1].HeaderText;
}
for (int i = 0; i < dataGridView3.Rows.Count; i++){
for (int j = 0; j < dataGridView3.Columns.Count; j++){
worksheet.Cells[i + 2, j + 1] = dataGridView3.Rows[i].Cells[j].Value.ToString();
}
}
var saveFileDialog = new SaveFileDialog();
saveFileDialog.FileName = "Interns";
saveFileDialog.DefaultExt = ".xlsx";
if (saveFileDialog.ShowDialog() == DialogResult.OK){
workbook.SaveAs(saveFileDialog.FileName, Type.Missing, Type.Missing, Type.Missing, Type.Missing, Type.Missing, Microsoft.Office.Interop.Excel.XlSaveAsAccessMode.xlExclusive, Type.Missing, Type.Missing, Type.Missing, Type.Missing, Type.Missing);
}
Thanks for the help.
Ok,if you want to show date only.and no time,you should set the number format.
just look at the code like this:
SomeCell.NumberFormat="yyyy-mm-dd"
it will show for example:"2018-05-20"
Correct me if I'm wrong, for what I saw in the provided screenshot, it consist of 3 date column which is statusdate, fplacementdate and periodcomplertion.
Have you tried it this way?
First create a conversion function for you date.
public static string convertDateFormat(this string date)
{
DateTime dateFormat = Convert.ToDateTime(date);
if (dateFormat != DateTime.MinValue)
{
return String.Format("{0:MM/dd/yyyy}", dateFormat);
}
else
{
return "";
}
}
Then use it this way
for (int i = 0; i < dataGridView3.Rows.Count; i++){
for (int j = 0; j < dataGridView3.Columns.Count; j++){
string formatValue = dataGridView3.Rows[i].Cells[j].Value.ToString();
if( dataGridView3.Columns[j].HeaderText == "statusdate" || dataGridView3.Columns[j].HeaderText == "fplacementdate" || dataGridView3.Columns[j].HeaderText == "periodcomplertion"){
formatValue.convertDateFormat();
}
worksheet.Cells[i + 2, j + 1] = formatValue;
}
}
I am creating an excel work book of my daily report. I want the header part to coloured to yellow. All links that are posted either requires a link of the workbook to be opened or are not specific to probelm. I am posting my code here, please suggest how to make Row 6 in yellow color.
string workBookName;
// creating Excel Application
Microsoft.Office.Interop.Excel._Application app = new Microsoft.Office.Interop.Excel.Application();
// creating new WorkBook within Excel application
Microsoft.Office.Interop.Excel._Workbook workbook = app.Workbooks.Add(Type.Missing);
// creating new Excelsheet in workbook
Microsoft.Office.Interop.Excel._Worksheet worksheet = null;
// see the excel sheet behind the program
app.Visible = true;
// get the reference of first sheet. By default its name is Sheet1.
// store its reference to worksheet
worksheet = workbook.Sheets["Sheet1"];
worksheet = workbook.ActiveSheet;
// changing the name of active sheet
workBookName = DateTime.Now.ToString("ddMMMyyyy-HHmmss");
worksheet.Name = workBookName;
worksheet.Cells[1, 1] = "Logistics";
worksheet.Cells[2, 1] = "Tracking Number";
worksheet.Cells[4, 2] = "Date - ";
worksheet.Cells[4, 3] = dateTimePicker1.Value.ToString("dd/MMM/yyyy");
// storing header part in Excel
for (int i = 1; i < dataGridView1.Columns.Count + 1; i++)
{
worksheet.Cells[6, i] = dataGridView1.Columns[i - 1].HeaderText;
// worksheet.get_Range(worksheet.Cells[6, i]).Interior.Color = System.Drawing.ColorTranslator.ToOle(System.Drawing.Color.Green);
}
// storing Each row and column value to excel sheet
for (int i = 0; i < dataGridView1.Rows.Count - 1; i++)
{
for (int j = 0; j < dataGridView1.Columns.Count; j++)
{
//if (!string.IsNullOrWhiteSpace(dataGridView1.Rows[i].Cells[j].Value))
{
worksheet.Cells[i + 8, j + 1] = dataGridView1.Rows[i].Cells[j].Value;
}
}
}
// save the application
workbook.SaveAs("Tracking Number Report " + workBookName + ".xls", Type.Missing, Type.Missing, Type.Missing, Type.Missing, Type.Missing, Microsoft.Office.Interop.Excel.XlSaveAsAccessMode.xlExclusive, Type.Missing, Type.Missing, Type.Missing, Type.Missing);
// Exit from the application
app.Quit();
I want row 6, which is the header part in my case to be colored.
if you run this code you will end up with an Excel instance still running because you have not released resources in interop using the .ReleaseComObject call - much more info on this here
I MUCH prefer to use one of the Open XML libraries such as EPPlus for this type of thing. It makes things a lot simpler and makes it easy to color a row.
Try something like this:
using (var excel = new ExcelPackage())
{
var workBookName = DateTime.Now.ToString("ddMMMyyyy-HHmmss");
var worksheet = excel.Workbook.Worksheets.Add(workBookName);
worksheet.Cells[1, 1].Value = "Logistics";
worksheet.Cells[2, 1].Value = "Tracking Number";
worksheet.Cells[4, 2].Value = "Date - ";
worksheet.Cells[4, 3].Value = dateTimePicker1.Value.ToString("dd/MMM/yyyy");
for (int i = 1; i < dataGridView1.Columns.Count + 1; i++)
{
worksheet.Cells[6, i].Value = dataGridView1.Columns[i - 1].HeaderText;
}
worksheet.Cells["6:6"].Style.Fill.PatternType = OfficeOpenXml.Style.ExcelFillStyle.Solid;
worksheet.Cells["6:6"].Style.Fill.BackgroundColor.SetColor(Color.Yellow);
//
//..etc
//
excel.SaveAs(new FileInfo("Tracking Number Report " + workBookName + ".xlsx"));
}
I am getting data in datagridview with a SQL query. Then I'm exporting the data to excel.
When I click the button I get the data to datagridview perfectly and I can export and save the first data to excel.
When I want to export to new data to excel I cannot do that
on the data I have saved
For example;
I saved 10 rows of data and then when I want to save 20 rows of data it should be 30 rows data on excel but I have 20 rows of data
How can I fix it?
Here is my code to export to excel:
private void bttn_Excel_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["Sayfa1"];
worksheet = workbook.ActiveSheet;
worksheet.Name = "Anlık Değerleri";
// storing header part in Excel
for (int i = 1; i < dataGridView1.Columns.Count + 1; i++)
{
worksheet.Cells[1, i] = dataGridView1.Columns[i - 1].HeaderText;
}
// storing Each row and column value to excel sheet
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();
}
}
// save the application
workbook.SaveAs("C:\\Users\\senerk\\Desktop\\Kitap1.xlsx", Type.Missing, Type.Missing, Type.Missing, Type.Missing, Type.Missing, Microsoft.Office.Interop.Excel.XlSaveAsAccessMode.xlExclusive, Type.Missing, Type.Missing, Type.Missing, Type.Missing);
// Exit from the application
app.Quit();
}
As Azar Shaikh mentioned you should use worksheet.UsedRange.Rows.Count.
Change your second loop to this, and it should work:
for (int i = 0; i < dataGridView1.Rows.Count - 1; i++)
{
for (int j = 0; j < dataGridView1.Columns.Count; j++)
{
worksheet.Cells[worksheet.UsedRange.Rows.Count + 2, j + 1] = dataGridView1.Rows[i].Cells[j].Value.ToString();
}
}
I didn't test it in working environment, but you got the idea!
More info here.