I am a little new to c# and Visual Studio and I am trying to plot a graph based on the values of a csv file located somewhere else. I have used the ChartObjects and ChartWizard property in c# to create the graph. The graph plotted should be the column range I am providing, in the Y-axis and X-axis should have the current row number(1,2,3,4 etc). However my graph by default takes the X-axis to be the first column in my csv file. It plots properly if I specify a range for X-axis too but how can I get the current row number there?
I went through a lot of articles and questions even on Stack Overflow but none seemed to help.
Here's a snippet of my code:
Microsoft.Office.Interop.Excel.Application xlexcel;
Microsoft.Office.Interop.Excel.Worksheet xlWorkSheet;
object misValue = System.Reflection.Missing.Value;
xlexcel = new Microsoft.Office.Interop.Excel.Application();
var xlWorkBooks = xlexcel.Workbooks;
xlexcel.Visible = false;
xlWorkBooks.OpenText(#"C:\" + processName + ".csv", misValue, misValue, Microsoft.Office.Interop.Excel.XlTextParsingType.xlDelimited, Microsoft.Office.Interop.Excel.XlTextQualifier.xlTextQualifierNone, misValue, misValue, misValue, misValue, misValue, misValue, misValue, misValue, misValue, misValue, misValue, misValue, misValue);
// Set Sheet 1 as the sheet you want to work with
xlWorkSheet = (Microsoft.Office.Interop.Excel.Worksheet)xlWorkBooks[1].Worksheets.get_Item(1);
xlWorkSheet.Shapes.AddChart(misValue, misValue, misValue, misValue, misValue).Select();
//~~> Make it a Line Chart
xlexcel.ActiveChart.ApplyCustomType(Microsoft.Office.Interop.Excel.XlChartType.xlLine);
//~~> Set the data range
xlexcel.ActiveChart.SetSourceData(xlWorkSheet.Range["E2:E200"]);
xlexcel.ActiveChart.ChartWizard(misValue, Title: chartName + " (" + processName + ")", CategoryTitle: "Iterations", ValueTitle: processType);
Microsoft.Office.Interop.Excel.ChartObjects chartObjects =(Microsoft.Office.Interop.Excel.ChartObjects)(xlWorkSheet.ChartObjects(Type.Missing));
foreach (Microsoft.Office.Interop.Excel.ChartObject co in chartObjects)
{
co.Select();
Microsoft.Office.Interop.Excel.Chart chart = (Microsoft.Office.Interop.Excel.Chart)co.Chart;
chart.Export(ConfigurationManager.AppSettings.Get("Charts") + "\\ProcessFiles" + #"\" + chartName + " (" + processName + "of" + processType + ")" + ".png", "PNG", false);
co.Delete();
}
xlWorkBooks[1].Close(true, misValue, misValue);
xlexcel.Quit();
Any guidance would be greatly appreciated.
Thanks!
I tried your code and made some modifications, I hope this will work
using Excel = Microsoft.Office.Interop.Excel;
Excel.Application xlApp;
Excel.Workbook xlWorkBook;
Excel.Worksheet xlWorkSheet;
object misValue = System.Reflection.Missing.Value;
//string appPath = Path.GetDirectoryName(Application.ExecutablePath);
string fileName = "" + "YOUR_PATH" + "\\Templates\\myCSV.csv";
string processName = "test";
xlApp = new Excel.Application();
xlWorkBook = xlApp.Workbooks.Open(fileName);
xlWorkSheet = (Excel.Worksheet)xlWorkBook.Worksheets.get_Item(1);
xlWorkSheet.Shapes.AddChart(misValue, misValue, misValue, misValue, misValue).Select();
//~~> Make it a Line Chart
xlApp.ActiveChart.ApplyCustomType(Microsoft.Office.Interop.Excel.XlChartType.xlLine);
//~~> Set the data range
xlApp.ActiveChart.SetSourceData(xlWorkSheet.Range["B1:B30"]);
string chartName = "TEST CHART", processType="TEST TYPE";
xlApp.ActiveChart.ChartWizard(misValue, Title: chartName + " (" + processName + ")", CategoryTitle: "Iterations", ValueTitle: processType);
Excel.ChartObjects chartObjects = (Excel.ChartObjects)(xlWorkSheet.ChartObjects(Type.Missing));
foreach (Excel.ChartObject co in chartObjects)
{
co.Select();
Excel.Chart chart = (Excel.Chart)co.Chart;
chart.Export("C:\\YOUR_PATH" + #"\" + chart.Name + ".png", "PNG", false);
}
xlWorkBook.Close(true, misValue, misValue);
xlApp.Quit();
xlWorkSheet = null;
xlWorkBook = null;
xlApp = null;
releaseObject(xlWorkBook);
releaseObject(xlWorkSheet);
releaseObject(xlApp);
private void releaseObject(object obj)
{
try
{
System.Runtime.InteropServices.Marshal.ReleaseComObject(obj);
obj = null;
}
catch (Exception ex)
{
obj = null;
MessageBox.Show(ex.Message);
}
finally
{
GC.Collect();
}
}
Related
I am new in C# Programming. I am creating a winform application in which I am using System.Windows.Forms.DataVisualization Chart. This chart contains multiple series. I want to export that chart data to Excel file.
To Add Data to chart I am using
chart.Series[mSeries].Points.AddXY(dt, avgData);
dt is current DateTime and the data.
So my Excel file look like
First Column is Series Name, second is DateTime and third column contain data.
So, can anyone please tell me how I can do this.
Thanks in Advance
You can refer to the following solution. First you will need to add reference to Microsoft Excel Object Library of COM. See this link on how to add. Then next step is pretty simple. You will need to add the code from the above link and replace the data which you fed in Excel with your custom data.
Here is the code shown in the link.
private void button1_Click(object sender, EventArgs e)
{
Excel.Application xlApp;
Excel.Workbook xlWorkBook;
Excel.Worksheet xlWorkSheet;
object misValue = System.Reflection.Missing.Value;
xlApp = new Excel.Application();
xlWorkBook = xlApp.Workbooks.Add(misValue);
xlWorkSheet = (Excel.Worksheet)xlWorkBook.Worksheets.get_Item(1);
for (int i = 0; i < chart1.Series.Count; i++)
{
xlWorkSheet.Cells[1, 1] = "";
xlWorkSheet.Cells[1, 2] = "DateTime";//put your column heading here
xlWorkSheet.Cells[1, 3] = "Data";// put your column heading here
for (int j = 0; j < chart1.Series[i].Points.Count; j++)
{
xlWorkSheet.Cells[j + 2 , 2] = chart1.Series[i].Points[j].XValue;
xlWorkSheet.Cells[j + 2 , 3] = chart1.Series[i].Points[j].YValues[0];
}
}
Excel.Range chartRange;
Excel.ChartObjects xlCharts = (Excel.ChartObjects)xlWorkSheet.ChartObjects(Type.Missing);
Excel.ChartObject myChart = (Excel.ChartObject)xlCharts.Add(10, 80, 300, 250);
Excel.Chart chartPage = myChart.Chart;
chartRange = xlWorkSheet.get_Range("B2", "c5");//update the range here
chartPage.SetSourceData(chartRange, misValue);
chartPage.ChartType = Excel.XlChartType.xlColumnClustered;
xlWorkBook.SaveAs("csharp.net-informations.xls", Excel.XlFileFormat.xlWorkbookNormal, misValue, misValue, misValue, misValue, Excel.XlSaveAsAccessMode.xlExclusive, misValue, misValue, misValue, misValue, misValue);
xlWorkBook.Close(true, misValue, misValue);
xlApp.Quit();
releaseObject(xlWorkSheet);
releaseObject(xlWorkBook);
releaseObject(xlApp);
MessageBox.Show("Excel file created , you can find the file c:\\csharp.net-informations.xls");
}
private void releaseObject(object obj)
{
try
{
System.Runtime.InteropServices.Marshal.ReleaseComObject(obj);
obj = null;
}
catch (Exception ex)
{
obj = null;
MessageBox.Show("Exception Occured while releasing object " + ex.ToString());
}
finally
{
GC.Collect();
}
}
Simply replace the cells and data from the code with your custom data and viola when you click on export button it will export it for you.
I have a datagrid on my visual studio with 40 items. On button click I want the first 30 items to display on my excel template and the balance to go to page two of template.
private void button1_Click_1(object sender, EventArgs e)
{
Excel.Application xlApp ;
Excel.Workbook xlWorkBook ;
Excel.Worksheet xlWorkSheet ;
object misValue = System.Reflection.Missing.Value;
xlApp = new Excel.Application();
xlWorkBook = xlApp.Workbooks.Open(#"C:\CedarData\masterquote.xlsx", misValue, false, misValue, misValue, misValue, misValue, misValue, misValue, misValue, misValue, misValue, misValue, misValue, misValue);
xlWorkSheet = (Excel.Worksheet)xlWorkBook.Worksheets.get_Item(1);
//int i = 1;
//int j = 1;
string datestr = DateTime.Now.ToShortDateString();
//string colName = dataGridView1.Columns[j].HeaderText;
string filename = #"C:\CedarData\CedarQuotes\Quote_" + txtName.Text.Replace(" ", "") + "_" + datestr + ".xls";
string quote = txtName.Text.Replace(" ", "") + "_" + datestr;
string salesman = txtEmail.Text.ToUpper();
string customer = txtName.Text.ToUpper();
// 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++)
{
//string value3 = dataGridView1.Rows[i].Cells[j].Value.ToString();
if (j == 2 || j == 5)
{
xlWorkSheet.Cells[i + 19, j + 1] = "'" + dataGridView1.Rows[i].Cells[j].Value.ToString();
}
else
{
xlWorkSheet.Cells[i + 19, j + 1] = dataGridView1.Rows[i].Cells[j].Value.ToString();
}
xlWorkSheet.get_Range("C10", "E10").Value2 = salesman;
xlWorkSheet.get_Range("C12", "E12").Value2 = customer;
xlWorkSheet.get_Range("C12", "E12").Font.Bold = true;
xlWorkSheet.get_Range("C12", "E12").Font.Bold = true;
xlWorkSheet.get_Range("H12", "I12").Value2 = DateTime.Now;
xlWorkSheet.get_Range("H10", "I10").Value2 = quote;
}
}
xlWorkBook.SaveAs(filename, Excel.XlFileFormat.xlWorkbookNormal, misValue, misValue, misValue, misValue, Excel.XlSaveAsAccessMode.xlExclusive, misValue, misValue, misValue, misValue, misValue);
xlWorkBook.Close(true, misValue, misValue);
xlApp.Quit();
releaseObject(xlWorkSheet);
releaseObject(xlWorkBook);
releaseObject(xlApp);
MessageBox.Show("Excel file created , you can find the file c:\\quote.xls");
}
Please help as this works but on line 31 it ovewrites the clauses on template. I want it must continue to page two.
My code works fine with generating an excel file, thanks to this community here.
But I still have a problem:
I have a ListBox from which I export a data to an excel file.
When I run it and the file will be created, I open it and in the rows I see
"SheduleMenager.Employees"
Employees is the class in my project in which i have two properties:
string Name and bool Experience
Here is a button to create and fill up the excel file :
private void Generateexcelfile_Click(object sender, RoutedEventArgs e)
{
Excel.Application xlApp = new Microsoft.Office.Interop.Excel.Application();
Excel.Workbook xlWorkBook;
Excel.Worksheet xlWorkSheet;
object misValue = System.Reflection.Missing.Value;
xlWorkBook = xlApp.Workbooks.Add(misValue);
xlWorkSheet = (Excel.Worksheet)xlWorkBook.Worksheets.get_Item(1);
for (int i = 0; i < MonBox.Items.Count; i++)
{
xlWorkSheet.Cells[i + 1, 1] = MonBox.Items[i].ToString();
}
xlWorkBook.SaveAs("FILEPATH", Excel.XlFileFormat.xlWorkbookNormal, misValue, misValue, misValue, misValue, Excel.XlSaveAsAccessMode.xlExclusive, misValue, misValue, misValue, misValue, misValue);
xlWorkBook.Close(true, misValue, misValue);
xlApp.Quit();
}
I would be really happy if you can help me to represent a VALUE of Employees.Name
I'm guessing that MonBox contains list of employees, in Items collection.
If that is so, change your line
xlWorkSheet.Cells[i + 1, 1] = MonBox.Items[i].ToString();
into
xlWorkSheet.Cells[i + 1, 1] = (MonBox.Items[i] as SheduleMenager.Employees).Name;
I am creating a dynamic Excel sheet using ExcelWorksheet. I need to create a non-editable excel. ws.Cells["A1:Q12"].Style.Locked = true is not working.
Here is my code :
Default.aspx.cs
protected void Page_Load(object sender, EventArgs e)
{
string filePath = Server.MapPath("~/Download/Sample.xlsx");
using (ExcelPackage pck = new ExcelPackage())
{
FileInfo summaryFilePath = new FileInfo(filePath);
ExcelWorksheet ws= pck.Workbook.Worksheets.Add("Sample Page");
CreateForamters(ws);
}
}
private void CreateForamters(ExcelWorksheet ws)
{
ws.Cells["B8:L8"].Value = "SamplePage";
ws.Cells["B10:L10"].Value = DateTime.Now.ToString("MMM-yy");
ws.Cells["B11:L11"].Value = "test data........-";
ws.Cells["B8:L11"].Style.Fill.PatternType = ExcelFillStyle.Solid;
ws.Cells["B8:L11"].Style.Font.Bold = true;
ws.Cells["B8:L11"].Style.Font.Name = "Arial";
ws.Cells["B8:L11"].Style.Font.Size = 16;
ws.Cells["B8:L11"].Style.Font.Color.SetColor(Color.Blue);
ws.Cells["B8:L11"].Style.Fill.BackgroundColor.SetColor(Color.White);
ws.Cells["B8:L11"].Style.HorizontalAlignment = OfficeOpenXml.Style.ExcelHorizontalAlignment.Center;
ws.Cells["B8:L8"].Merge = true;
ws.Cells["B9:L9"].Merge = true;
ws.Cells["B10:L10"].Merge = true;
ws.Cells["B11:L11"].Merge = true;
ws.Cells["A1:Q12"].Style.Locked = true;
}
Thank you all in advance for your response.
I am creating a dynamic Excel sheet using ExcelWorksheet. I need to create a non-editable excel. ws.Cells["A1:Q12"].Style.Locked = true is not working.
To create NON-Editable Cells, you have to use
ws.get_Range("A1", "Q12").Locked = true;
And then you need to protect the worksheet. Without protecting the worksheet, the .Locked command doesn't have any significance.
Here is a basic example (TRIED AND TESTED IN VS2010 + OFFICE 2010)
object misValue = System.Reflection.Missing.Value;
ws.get_Range("A1", "Q12").Locked = true;
string Password = "Sid";
ws.Protect(Password, misValue, misValue, misValue, misValue, misValue,
misValue, misValue, misValue, misValue, misValue, misValue, misValue,
misValue, misValue, misValue);
NOTE: By default all cells in Excel are locked. If you don't want to protect the rest of the cells in the sheet then remember to set their .Locked property to False.
ws.Cells.Locked = false;
and then use the above code.
if you want to save Excel WorkBook as ReadOnly Save as Below:
object misValue = System.Reflection.Missing.Value;
ExcelWorkBook.ActiveWorkbook.SaveAs(save_path, Excel.XlFileFormat.xlWorkbookNormal, misValue , misValue , True, True,XlSaveAsAccessMode.xlShared, false, false, misValue, misValue , misValue );
I'm working with xls file. How can I save it (if exist) with the same file name + "(copy 1)" like Windows desktop.
method saveCommande(...)
if(!Directory.Exists(System.Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments) + "EE_Commande_Fournisseur"))
{
Directory.CreateDirectory(System.Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments) + "\\EE_Commande_Fournisseur");
}
xlWorkBook.SaveAs("EE_Commande_Fournisseur\\" + path, Excel.XlFileFormat.xlWorkbookNormal, misValue, misValue, true, misValue, Excel.XlSaveAsAccessMode.xlExclusive, misValue, misValue, misValue, misValue, misValue);
path = System.Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments) + "\\EE_Commande_Fournisseur\\" + path;
xlWorkBook.Close(true, misValue, misValue);
xlApp.Quit();
this.ReleaseComObject(xlApp,xlWorkBook);
//sauvergarde dans la base de données
_newAchatCommande.path = path;
this._fileName = path;
contexte.AddToAchatCommande(_newAchatCommande);
contexte.SaveChanges();
thanks
try using File object's Exists method:
if (!System.IO.File.Exists(#"C:\test2.xls"))
{
xlWorkBook.SaveAs(#"c:\test2.xls");
}
else
{
xlWorkBook.SaveAs(#"c:\test2(Copy).xls");
}
Or Alternatively you can overwrite your excel file by
Microsoft.Office.Interop.Excel.Application excel = new Microsoft.Office.Interop.Excel.Application();
excel.DisplayAlerts = false;
excelSheePrint.SaveAs(filename, Microsoft.Office.Interop.Excel.XlFileFormat.xlWorkbookDefault, Type.Missing, Type.Missing, true, false, XlSaveAsAccessMode.xlNoChange, XlSaveConflictResolution.xlLocalSessionChanges, Type.Missing, Type.Missing);
Note: It will overwrite the existing excel (if exist) without asking the user.
DataTable dt= dtData;
using (XLWorkbook wb = new XLWorkbook())
{
//Range(int firstCellRow,int firstCellColumn,int lastCellRow,int lastCellColumn)
int CCount = dt.Columns.Count;
int RCount = dt.Rows.Count;
var ws = wb.Worksheets.Add("Report"); //add worksheet to workbook
ws.Row(1).Cell(1).RichText.AddText(ReportName);
ws.Range(1, 1, 1, CCount).Merge();
ws.Range(1, 1, 1, CCount).Style.Font.Bold = true;//Range(int firstCellRow,int firstCellColumn,int lastCellRow,int lastCellColumn)
ws.Range(1, 1, 1, CCount).Style.Font.FontSize = 16;
ws.Range(1, 1, 1, CCount).Style.Alignment.Horizontal = XLAlignmentHorizontalValues.Center;
ws.Range(1, 1, 1, CCount).Style.Alignment.Vertical = XLAlignmentVerticalValues.Center;
//ws.Range("A1:Z1").Style.Font.Bold = true;
ws.Row(2).Cell(1).InsertTable(dt);
ws.Range("A2:Z2").Style.Font.Bold = true;
ws.Range(2, 1, RCount + 2, CCount).Style.Border.OutsideBorder = XLBorderStyleValues.Medium;
wb.SaveAs(FolderPath + filename + ".xlsx");
ws.Dispose();
}
it works!
thanks
private void SaveNewCommande(YetiBddEntities contexte, Excel.Application xlApp, Excel.Workbook xlWorkBook, string path, object misValue)
{
string tmpPath = System.Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments) + "\\EET_Commande_Fournisseur";
if (!Directory.Exists(tmpPath))
{
Directory.CreateDirectory(tmpPath);
}
foreach (string file in Directory.GetFiles(tmpPath))
{
if ((path+".xls").Equals(file.Substring(tmpPath.Length+1)))
count++;
}
if (count>0)
xlWorkBook.SaveAs(string.Format("EET_Commande_Fournisseur\\{0}_({1}).xls", path, count), Excel.XlFileFormat.xlWorkbookNormal, misValue, misValue, misValue, misValue, Excel.XlSaveAsAccessMode.xlExclusive, misValue, misValue, misValue, misValue, misValue);
else
xlWorkBook.SaveAs(string.Format("EET_Commande_Fournisseur\\{0}.xls", path) + path, Excel.XlFileFormat.xlWorkbookNormal, misValue, misValue, misValue, misValue, Excel.XlSaveAsAccessMode.xlExclusive, misValue, misValue, misValue, misValue, misValue);
path = System.Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments) + "\\EET_Commande_Fournisseur\\" + path+".xls";
xlWorkBook.Close(true, misValue, misValue);
xlApp.Quit();
this.ReleaseComObject(xlApp,xlWorkBook);
//sauvergarde dans la base de données
_newAchatCommande.path = path;
this._fileName = path;
contexte.AddToAchatCommande(_newAchatCommande);
contexte.SaveChanges();
}