I am drawing a pie chart with some data:
private void DrawFractionChart(Excel.Worksheet activeSheet, Excel.ChartObjects xlCharts, Excel.Range xRange, Excel.Range yRange)
{
Excel.ChartObject myChart = (Excel.ChartObject)xlCharts.Add(200, 500, 200, 100);
Excel.Chart chartPage = myChart.Chart;
Excel.SeriesCollection seriesCollection = chartPage.SeriesCollection();
Excel.Series series1 = seriesCollection.NewSeries();
series1.XValues = activeSheet.Range["E1","E3"];
series1.Values = activeSheet.Range["F1","F3"];
chartPage.ApplyDataLabels(Excel.XlDataLabelsType.xlDataLabelsShowPercent, true,true,false,true,true,true,true);
chartPage.ChartType = Excel.XlChartType.xlDoughnut;
Excel.Axis axis = chartPage.Axes(Excel.XlAxisType.xlValue, Microsoft.Office.Interop.Excel.XlAxisGroup.xlPrimary) as Excel.Axis;
}
I just can't figure out how to turn on data labels. I googled everywhere for it but nothing's been helpful so far sadly.
Try this (TRIED AND TESTED)
private void DrawFractionChart(Excel.Worksheet activeSheet, Excel.ChartObjects xlCharts, Excel.Range xRange, Excel.Range yRange)
{
Excel.ChartObject myChart = (Excel.ChartObject)xlCharts.Add(200, 500, 200, 100);
Excel.Chart chartPage = myChart.Chart;
Excel.SeriesCollection seriesCollection = chartPage.SeriesCollection();
Excel.Series series1 = seriesCollection.NewSeries();
series1.XValues = activeSheet.Range["E1", "E3"];
series1.Values = activeSheet.Range["F1", "F3"];
chartPage.ChartType = Excel.XlChartType.xlDoughnut;
Excel.Axis axis = chartPage.Axes(Excel.XlAxisType.xlValue, Microsoft.Office.Interop.Excel.XlAxisGroup.xlPrimary) as Excel.Axis;
series1.ApplyDataLabels(Excel.XlDataLabelsType.xlDataLabelsShowPercent, true, true, false, true, true, true, true);
}
One quick question though. If you are not using xRange and yRange then why declare it?
This is the completed code that is tried and tested.
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using Excel = Microsoft.Office.Interop.Excel;
namespace WindowsFormsApplication1
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
private void button1_Click(object sender, EventArgs e)
{
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;
// Add a Workbook
xlWorkBook = xlexcel.Workbooks.Add();
// Set Sheet 1 as the sheet you want to work with
xlWorkSheet = (Excel.Worksheet)xlWorkBook.Worksheets.get_Item(1);
xlWorkSheet.Cells[1, 5] = "Apples";
xlWorkSheet.Cells[2, 5] = "Oranges";
xlWorkSheet.Cells[3, 5] = "Pears";
xlWorkSheet.Cells[1, 6] = "80";
xlWorkSheet.Cells[2, 6] = "65";
xlWorkSheet.Cells[3, 6] = "45";
Excel.ChartObjects myCharts = (Excel.ChartObjects)xlWorkSheet.ChartObjects(Type.Missing);
// Specified xlWorkSheet.Cells[3, 6], xlWorkSheet.Cells[3, 6] just for the heck of it.
DrawFractionChart(xlWorkSheet, myCharts, xlWorkSheet.Cells[3, 6], xlWorkSheet.Cells[3, 6]);
//Once done close and quit Excel
//xlWorkBook.Close(true, misValue, misValue);
//xlexcel.Quit();
//releaseObject(xlWorkSheet);
//releaseObject(xlWorkBook);
//releaseObject(xlexcel);
}
private void DrawFractionChart(Excel.Worksheet activeSheet, Excel.ChartObjects xlCharts, Excel.Range xRange, Excel.Range yRange)
{
Excel.ChartObject myChart = (Excel.ChartObject)xlCharts.Add(200, 500, 200, 100);
Excel.Chart chartPage = myChart.Chart;
Excel.SeriesCollection seriesCollection = chartPage.SeriesCollection();
Excel.Series series1 = seriesCollection.NewSeries();
series1.XValues = activeSheet.Range["E1", "E3"];
series1.Values = activeSheet.Range["F1", "F3"];
chartPage.ChartType = Excel.XlChartType.xlDoughnut;
Excel.Axis axis = chartPage.Axes(Excel.XlAxisType.xlValue, Microsoft.Office.Interop.Excel.XlAxisGroup.xlPrimary) as Excel.Axis;
series1.ApplyDataLabels(Excel.XlDataLabelsType.xlDataLabelsShowPercent, true, true, false, true, true, true, true);
}
//private void releaseObject(object obj)
//{
// try
// {
// System.Runtime.InteropServices.Marshal.ReleaseComObject(obj);
// obj = null;
// }
// catch (Exception ex)
// {
// obj = null;
// MessageBox.Show("Unable to release the Object " + ex.ToString());
// }
// finally
// {
// GC.Collect();
// }
//}
}
}
SNAPSHOT
#region Export Excel To Chart
Excel.Range chartRange;
Excel.ChartObjects xlCharts = (Excel.ChartObjects)xlWorkSheet.ChartObjects(Type.Missing);
Excel.ChartObject myChart = (Excel.ChartObject)xlCharts.Add(300, 50, 500, 500);
Excel.Chart chartPage = myChart.Chart;
chartRange = xlWorkSheet.get_Range("A6", "B" + (counter-1));
chartPage.SetSourceData(chartRange, misValue);
chartPage.ChartType = Excel.XlChartType.xlPie;// type of chart
chartPage.ApplyDataLabels(Excel.XlDataLabelsType.xlDataLabelsShowPercent, Excel.XlDataLabelsType.xlDataLabelsShowLabel, true, false, false, true, false, true);// set label
chartPage.Export(#"C:\excel_chart_export.bmp","BMP",misValue );
#endregion
The solution above didn't work for me in VS 2013 and Excel 2013.
Add the following references:
Microsoft.Office.Core
Microsoft.Office.Interop.Excel
and use the following method:
Chart oChart = ...
oChart.SetElement(Microsoft.Office.Core.MsoChartElementType.msoElementDataLabelOutSideEnd);
Source (MSDN):
https://msdn.microsoft.com/en-us/library/microsoft.office.tools.excel.chart.setelement.aspx
https://msdn.microsoft.com/en-us/library/microsoft.office.core.msochartelementtype.aspx
Related
I've looked at all the possible answers on stackoverflow and still cant figure out how to solve my problem.
My program creates an excel file, exports data into the file and then should close it. It doesn't close it completely however and the excel process is still running in the background which makes using my code more than once impossible as it always throws up an error.
I start of by creating my excel object
Excel.Application xlApp = new Microsoft.Office.Interop.Excel.Application();
I then assign variables to everything I need to use:
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);
then do all my manipulation.
To close the excel process I use:
xlWorkBook.SaveAs(#"C:\Users\dphillips\Desktop\Projects\C#\Exported Excel File", Excel.XlFileFormat.xlWorkbookNormal,
misValue, misValue, misValue, misValue, Excel.XlSaveAsAccessMode.xlExclusive, misValue, misValue, misValue, misValue, misValue);
xlWorkBook.Close(true, "Exported Excel File", misValue);
xlApp.Quit();
Marshal.FinalReleaseComObject(xlWorkSheet);
Marshal.FinalReleaseComObject(xlWorkBook);
Marshal.FinalReleaseComObject(xlApp);
xlWorkSheet = null;
xlApp = null;
xlWorkBook = null;
The process doesn't close though. I used http://csharp.net-informations.com/excel/csharp-create-excel.htm as my template to do this as I'm new to C# and don't have enough experience to do it on my own.
Any advice on how to correctly close the program would be greatly appreciated
EDIT:
Since I can't seem to get any luck with it I will just post my whole program. Maybe then you could tell me exactly where I'm going wrong
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using System.IO;
using System.Text.RegularExpressions;
using System.Runtime.InteropServices;
using Excel = Microsoft.Office.Interop.Excel;
namespace FormPractice
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
private void Form1_Load(object sender, EventArgs e)
{
}
private void button1_Click(object sender, EventArgs e)
{
FolderBrowserDialog FBD = new FolderBrowserDialog();
if (FBD.ShowDialog() == DialogResult.OK)
{
textBox1.Text = FBD.SelectedPath;
//Creating excel object
Excel.Application xlApp = new Excel.Application();
xlApp.Visible = true;
//Check to see that excel is installed.
if (xlApp == null)
{
MessageBox.Show("Excel is not properly installed!!");
return;
}
// regular expressions to check for the ID number in the file and the issue number of the document
Regex regularExpressionDocID = new Regex(#"\d{3}[A-Z]\W\d{4}\W\d{6}\W\d{3}\W[A-Z]\d{2}");
Regex regularExpressionIssueNumber = new Regex(#"[i,I]s+(ue)*.?\d{1,2}$");
var filesToBeRead = Directory.GetFiles(FBD.SelectedPath, "*.*", SearchOption.AllDirectories)
.Where(fileNameBeingProcessed =>
(fileNameBeingProcessed.EndsWith(".txt")
|| fileNameBeingProcessed.EndsWith(".docx")
|| fileNameBeingProcessed.EndsWith(".doc")
|| fileNameBeingProcessed.EndsWith(".xls")
|| fileNameBeingProcessed.EndsWith(".pdf")
|| fileNameBeingProcessed.EndsWith(".docm")
|| fileNameBeingProcessed.EndsWith(".xlsm")
|| fileNameBeingProcessed.EndsWith(".xlsx")))
.ToList();
var xlWorkBooks = xlApp.Workbooks;
object misValue = System.Reflection.Missing.Value;
var xlWorkBook = xlWorkBooks.Add(misValue);
var xlWorkSheets = xlWorkBook.Worksheets;
var xlWorkSheet = (Excel.Worksheet)xlWorkSheets.get_Item(1);
string comparingString;
int counter = 2;
// setting all headers
xlWorkSheet.Cells[1, 1] = "Document Number";
xlWorkSheet.Cells[1, 2] = "Name";
xlWorkSheet.Cells[1, 3] = "System Revision";
xlWorkSheet.Cells[1, 4] = "Revision";
xlWorkSheet.Cells[1, 5] = "Type";
xlWorkSheet.Cells[1, 6] = "Old Name";
xlWorkSheet.Cells[1, 7] = "File Name";
xlWorkSheet.Cells[1, 8] = "Directory";
xlWorkSheet.Cells[1, 9] = "Owner";
foreach (string file in filesToBeRead)
{
string documentID, documentName, revision, oldName, directoryOfFile, stringToBeManipulated;
comparingString = Path.GetFileNameWithoutExtension(file);
Match matchesFormat = regularExpressionDocID.Match(comparingString);
Match matchesIssue = regularExpressionIssueNumber.Match(comparingString);
// All manipulations to get each of the required fields for the ARAS upload xlsx
if (matchesFormat.Success)
{
stringToBeManipulated = (Path.GetFileNameWithoutExtension(file)); // document ID sectiom
documentID = stringToBeManipulated.Substring(0, 24);
xlWorkSheet.Cells[counter, 1] = documentID;
if (matchesIssue.Success)
{
//If "issue" is found then gives name(from char [25] and inserts issue into the correct cells
revision = matchesIssue.Value;
documentName = stringToBeManipulated[25..matchesIssue.Index];
}
else
{
//If "issue" is not found fills the issue column with a "-" and makes the entire string the name.
revision = "-";
documentName = stringToBeManipulated[25..stringToBeManipulated.Length];
}
xlWorkSheet.Cells[counter, 2] = documentName;
xlWorkSheet.Cells[counter, 3] = revision;
xlWorkSheet.Cells[counter, 4] = revision;
oldName = (Path.GetFileName(file));
xlWorkSheet.Cells[counter, 6] = oldName;
xlWorkSheet.Cells[counter, 7] = oldName;
directoryOfFile = Path.GetDirectoryName(file);
xlWorkSheet.Cells[counter, 8] = directoryOfFile;
counter++;
}
}
xlWorkBook.SaveAs(#"C:\Users\dphillips\Desktop\Projects\C#\Exported_Old_Doc_ID", Excel.XlFileFormat.xlWorkbookNormal,
misValue, misValue, misValue, misValue, Excel.XlSaveAsAccessMode.xlExclusive, misValue, misValue, misValue, misValue, misValue);
xlWorkBook.Close(true, "Exported Excel File", misValue);
xlApp.DisplayAlerts = false;
xlApp.Quit();
//Releasing all objects to stop memory leaks
GC.WaitForPendingFinalizers();
GC.Collect();
GC.WaitForPendingFinalizers();
GC.Collect();
GC.WaitForPendingFinalizers();
GC.Collect();
GC.WaitForPendingFinalizers();
GC.Collect();
GC.WaitForPendingFinalizers();
GC.Collect();
Marshal.FinalReleaseComObject(xlWorkSheet);
Marshal.FinalReleaseComObject(xlWorkBook);
Marshal.FinalReleaseComObject(xlWorkSheets);
Marshal.FinalReleaseComObject(xlWorkBooks);
Marshal.FinalReleaseComObject(xlApp);
xlWorkSheet = null;
xlApp = null;
xlWorkBook = null;
xlWorkBooks = null;
xlWorkSheets = null;
MessageBox.Show(#"Excel file created , you can find the file C:\Users\dphillips\Desktop\Projects\C#\Directory to pull");
}
GC.Collect();
Close();
I have a Excel chart. How do I add a legend value?
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("B12", "B15");
chartPage.SetSourceData(chartRange, misValue);
chartPage.ChartType = Excel.XlChartType.xl3DPieExploded;
foreach (Series series in chartPage.SeriesCollection())
{
series.Name = "Diagram Name";
}
chartPage.HasLegend = true;
chartPage.Is
//export chart as picture file
String destPath = Directory.GetCurrentDirectory();
chartPage.Export(Directory.GetCurrentDirectory() + "\\dig2.bmp", "BMP", misValue);
Method "Series" not available.
This worked for me. I added in some data so the example would work stand alone.
Application xlApp = new Microsoft.Office.Interop.Excel.Application();
Workbook xlWorkBook;
Worksheet xlWorkSheet;
object misValue = System.Reflection.Missing.Value;
xlWorkBook = xlApp.Workbooks.Add(misValue);
xlWorkSheet = (Worksheet)xlWorkBook.Worksheets.get_Item(1);
xlWorkSheet.Name = "Sheet";
ChartObjects xlCharts = (ChartObjects)xlWorkSheet.ChartObjects(Type.Missing);
ChartObject myChart = (ChartObject)xlCharts.Add(10, 80, 300, 250);
Chart chartPage = myChart.Chart;
chartPage.Legend.Position = XlLegendPosition.xlLegendPositionBottom;
chartPage.HasTitle = true;
chartPage.ChartTitle.Text = "Title";
xlWorkSheet.Cells[12, 1] = "Test";
xlWorkSheet.Cells[13, 1] = "Test2";
xlWorkSheet.Cells[14, 1] = "Test3";
xlWorkSheet.Cells[15, 1] = "Test4";
xlWorkSheet.Cells[12, 2] = 12;
xlWorkSheet.Cells[13, 2] = 13;
xlWorkSheet.Cells[14, 2] = 14;
xlWorkSheet.Cells[15, 2] = 15;
var sc = chartPage.SeriesCollection();
var series1 = sc.NewSeries();
series1.Name = "Title";
series1.XValues = $"'{xlWorkSheet.Name}'!A12:A15";
series1.Values = $"'{xlWorkSheet.Name}'!B12:B15";
series1.ChartType = XlChartType.xl3DPieExploded;
chartPage.ApplyDataLabels();
//export chart as picture file
String destPath = Directory.GetCurrentDirectory();
chartPage.Export(Directory.GetCurrentDirectory() + "\\dig2.bmp", "BMP", misValue);
[![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;
//диаграмма 2
chartRange = xlWorkSheet.get_Range("D12", "E16");
chartPage.SetSourceData(chartRange, misValue);
chartPage.ChartType = Excel.XlChartType.xl3DPieExploded;
foreach (Series series in chartPage.SeriesCollection())
{
series.Name = "Уровень удовлетворенности респондентов длительностью ожидания";
}
chartPage.HasLegend = true;
//export chart as picture file
String destPath = Directory.GetCurrentDirectory();
chartPage.ApplyDataLabels(XlDataLabelsType.xlDataLabelsShowValue, false, true, false, false, false, false, true, false, false);
chartPage.Export(Directory.GetCurrentDirectory() + "\\dig2.bmp", "BMP", misValue);
//конец диаграмы 2][1]][1]
I want to generate two charts in excel. this is my code for generating the first one, then i want to generate one more in the same document using another range.
Range chartRange;
ChartObjects xlCharts = (ChartObjects)ws.ChartObjects(Type.Missing);
ChartObject myChart = (ChartObject)xlCharts.Add(10, 80, 300, 250);
Chart chartPage = myChart.Chart;
chartRange = ws.get_Range("A4", "AZ4");
chartPage.ChartType = XlChartType.xlLineMarkers;
chartPage.HasTitle = true;
chartPage.ChartTitle.Text = "Lägenhetstyp 1";
chartPage.HasLegend = false;
chartPage.SetSourceData(chartRange, misValue);
chartPage.ChartType = XlChartType.xlColumnClustered;
Something like this.
Range chartRange;
//First Chart
ChartObjects xlCharts = (ChartObjects)ws.ChartObjects(Type.Missing);
ChartObject myChart = (ChartObject)xlCharts.Add(10, 80, 300, 250);
Chart chartPage = myChart.Chart;
chartRange = ws.get_Range("A4", "AZ4");
chartPage.ChartType = XlChartType.xlLineMarkers;
chartPage.HasTitle = true;
chartPage.ChartTitle.Text = "Chart 1";
chartPage.HasLegend = false;
chartPage.SetSourceData(chartRange, misValue);
chartPage.ChartType = XlChartType.xlColumnClustered;
//Second chart
ChartObjects xlCharts = (ChartObjects)ws.ChartObjects(Type.Missing);
ChartObject myChart = (ChartObject)xlCharts.Add(10, 80, 300, 250);
Chart chartPage = myChart.Chart;
chartRange = ws.get_Range("A8", "AZ8");
chartPage.ChartType = XlChartType.xlLineMarkers;
chartPage.HasTitle = true;
chartPage.ChartTitle.Text = "Chart 2";
chartPage.HasLegend = false;
chartPage.SetSourceData(chartRange, misValue);
chartPage.ChartType = XlChartType.xlColumnClustered;
This is how i solved it.
for (int i = 1; i <= 2; i++)
{
Range chartRange;
ChartObjects xlCharts = (ChartObjects)ws.ChartObjects(Type.Missing);
ChartObject myChart = (ChartObject)xlCharts.Add(10, 80, 300, 250);
Chart chartPage = myChart.Chart;
if (i == 1)
{
chartRange = ws.get_Range("A4", "AZ4");
}
else
{
chartRange = ws.get_Range("A8", "AZ8");
}
chartPage.ChartType = XlChartType.xlLineMarkers;
chartPage.HasTitle = true;
chartPage.ChartTitle.Text = "Chart " + i;
chartPage.HasLegend = false;
chartPage.SetSourceData(chartRange, misValue);
chartPage.ChartType = XlChartType.xlColumnClustered;
}
I am trying to add two series to an Excel chart. I am able to add one series to the chart with this code. How can i add one more series to my chart?
worksheet.Select(Type.Missing);
Excel.Range chartRange;
object misValue = System.Reflection.Missing.Value;
Excel.ChartObjects xlCharts = (Excel.ChartObjects)worksheet.ChartObjects(Type.Missing);
Excel.ChartObject myChart = (Excel.ChartObject)xlCharts.Add(10, 80, 300, 250);
Excel.Chart chartPage = myChart.Chart;
chartRange = worksheet.get_Range("B2", "B10");
chartPage.SetSourceData(chartRange, Excel.XlRowCol.xlColumns);
chartPage.ChartType = Excel.XlChartType.xlLine;
var series = (Excel.Series)chartPage.SeriesCollection(1);
series.Values = chartRange;
chartRange = worksheet.get_Range("A2", "A10");
series.XValues = chartRange;
Don't know the C# for it, but in VBA I would use something like:
With ChartPage.SeriesCollection.NewSeries
.Values = ActiveSheet.Range("C2:C10")
End With
I have created the sheet1 and populated some data in the sheet, using the data from sheet1 i want to create a chart sheet with ploting the data
try
{
app = new Excel.Application();
app.Visible = true;
workbook = app.Workbooks.Add(1);
worksheet = (Excel.Worksheet)workbook.Sheets[1];
PopulateDateInExcel(pathtologsfolder, startdate, enddate);
// create a chart
Excel.Range chartRange;
object misValue = System.Reflection.Missing.Value;
Excel.ChartObjects xlCharts = (Excel.ChartObjects)worksheet.ChartObjects(Type.Missing);
Excel.ChartObject myChart = (Excel.ChartObject)workbook.Charts[2];
Excel.Chart chartPage = myChart.Chart;
chartRange = worksheet.get_Range("AN1", "AP6");
chartPage.SetSourceData(chartRange, misValue);
chartPage.ChartType = Excel.XlChartType.xl3DLine;
}
catch (Exception e)
{
//Console.Write("Error");
}
finally
{
}
Thanks in advance,
Excel Automation
Try this (UNTESTED)
Excel.ChartObject myChart = (Excel.ChartObject)charts.Add(10, 70, 250, 250);
instead of
Excel.ChartObject myChart = (Excel.ChartObject)workbook.Charts[2];
and then once your chart is created, move it to a chart sheet using this code
chart.Location(XlChartLocation.xlLocationAsNewSheet, Type.Missing);
The way to do this would be to use the Add method:
Excel.Workbook xlWorkbook;
Excel.Chart chartName = (Excel.Chart)xlWorkbook.Charts.Add();
Admittedly, at least in my experiments this causes trouble as the dataset it is using by default is fairly random (Excel magic...) so you might be needing to reformat it afterwards (delete and add datasets, etc), but that's the method to do it.
EDIT:
I should note that Excel support documentation seems to recommend the Add2 method method, but I haven't managed to use it successfully:
Excel.Workbook xlWorkbook;
Excel.Chart chartName = (Excel.Chart)xlWorkbook.Charts.Add2();
Excel.Application oXL = new Excel.Application();
and after then
oXL.Run() and see attached: