I am trying to get a xlWorkSheet range and format it to "MMM/YYYY" in the xAxis of a chart. But I dont want to change the date format in that WorkSheet cells where I am taking the info and where I want to keep having a "MM/YYYY" format.
I've already formatted the row to "MM/YYYY" and "MMM/YYYY", but not to use one in the excel table and the other one in just the chart.
My code is:
ChartObject myChart
Chart chartPage = myChart.Chart;
chartPage.ChartType = XlChartType.xlArea;
var yAxis = (Axis)chartPage.Axes(XlAxisType.xlValue, XlAxisGroup.xlPrimary);
Axis.HasTitle = false;
Range chartRange = xlWorkSheet.Range[xlWorkSheet.Cells[4, 1],
xlWorkSheet.Cells[rows, columns]];
Range x_Range = xlWorkSheet.Range[xlWorkSheet.Cells[1, 2], xlWorkSheet.Cells[1, columnsCount]];
Range x_Range2 = x_Range.EntireRow.NumberFormat("MMM/YYYY");
Axis xAxis = (Axis)chartPage.Axes(XlAxisType.xlValue, XlAxisGroup.xlPrimary);
xAxis.CategoryNames = x_Range2;
(...series definition... and rest of code)
Related
I'm creating a chart (of ComboChart type) in the PPTX file using GemBox.Presentation (together with GemBox.Spreadsheet). I'm using the code from the PowerPoint Chart example and added parts of the Excel Combo Chart example.
This is what I have so far:
var presentation = new PresentationDocument();
var slide = presentation.Slides.AddNew(SlideLayoutType.Custom);
var chart = slide.Content.AddChart(GemBox.Presentation.ChartType.Combo, 25, 25, 300, 500);
var comboChart = (ComboChart)chart.ExcelChart;
var worksheet = comboChart.Worksheet;
worksheet.Cells["A1"].Value = "Name";
worksheet.Cells["A2"].Value = "John Doe";
worksheet.Cells["A3"].Value = "Fred Nurk";
worksheet.Cells["B1"].Value = "Salary";
worksheet.Cells["B2"].Value = 4023;
worksheet.Cells["B3"].Value = 3263;
worksheet.Cells["C1"].Value = "Max";
worksheet.Cells["C2"].Value = 4500;
worksheet.Cells["C3"].Value = 4300;
worksheet.Cells["D1"].Value = "Min";
worksheet.Cells["D2"].Value = 3000;
worksheet.Cells["D3"].Value = 2800;
comboChart.CategoryLabelsReference = "A2:A3";
var salaryChart = comboChart.Add(GemBox.Spreadsheet.Charts.ChartType.Column);
salaryChart.Series.Add("=B1", "B2:B3");
var minMaxChart = comboChart.Add(GemBox.Spreadsheet.Charts.ChartType.Line);
minMaxChart.Series.Add("=C1", "C2:C3");
minMaxChart.Series.Add("=D1", "D2:D3");
presentation.Save("output.pptx");
And this is what I get:
Now my problem is that I cannot find any way to access and format the Category axis and Vertical axis.
I tried to use chart, comboChart, salaryChart, and minMaxChart objects, but none of them have any axes properties!?
How can I, let's say, set the axes titles?
To set the axes of the Combo chart, you'll need to use the axes of one of its containing charts, so either salaryChart or minMaxChart.
Now the reason why you don't see any axes properties on them is that they are of a base type (ExcelChart). You need to cast them to a derived type, like this:
var salaryChart = (ColumnChart)comboChart.Add(GemBox.Spreadsheet.Charts.ChartType.Column);
salaryChart.Series.Add("=B1", "B2:B3");
salaryChart.Axes.Horizontal.Title.Text = "My Categories";
salaryChart.Axes.Vertical.Title.Text = "My Values";
I am using ClosedXML (https://github.com/ClosedXML/ClosedXML) for creating an excel file in my C# MVC Controller. As per the documentation in https://github.com/closedxml/closedxml/wiki/How-can-I-insert-an-image, I have inserted an image in a cell and merged that cell with to cells on the right side.My code is as follows:
For adding image
var imagePath = #"c:\myFolder\image.jpg";
var image = MyWorkSheet.AddPicture(imagePath ) .MoveTo((MyWorkSheet.Cell(3,1).Address)) .Scale(0.2);
image.Width = 50;
image.Height = 50;
For merging cell
MyWorkSheet.Range(MyWorkSheet.Cell(3,1).Address, MyWorkSheet.Cell(3, 3).Address).Merge();
But the image lies on the upper left corner of the cell. I cant find any web source explaining how to center the image in the cell range. Anyone please help me.
You have to move your image with an offset from the cell. To do that, you have to calculate that offset.
Column width is returned in point (not in pixel). You have to convert it to pixel to compare with image pixel width.
So you can do :
int iColumnWidth = (MyWorkSheet.Column(1).Width - 1) * 7 + 12; // To convert column width in pixel unit.
int xOffset = (iColumnWidth - image.Width) / 2;
int yOffset = 0;
image.MoveTo(MyWorkSheet.Cell(3,1), New Point(xOffset, yOffset));
You need to do some manual calculation based on the with respect to image and cell size.
Workbook wb = new Workbook();
Worksheet sheet = wb.Worksheets[0];
sheet.Range["A1"].Text = "Align Picture Within A Cell:";
sheet.Range["A1"].Style.VerticalAlignment = VerticalAlignType.Top;
string picPath = #"C:\Users\Administrator\Desktop\scenery.jpg";
ExcelPicture picture = sheet.Pictures.Add(1, 1, picPath);
sheet.Columns[0].ColumnWidth = 50;
sheet.Rows[0].RowHeight = 150;
picture.LeftColumnOffset =100;
picture.TopRowOffset = 25;
wb.SaveToFile("AlignPicture.xlsx", ExcelVersion.Version2013);
I am inserting an image in an excel cell, but usually that image will be larger, both in height and in width than the original cell. So after I have inserted my image I would like to: resize the specific excel row and column according to the image's size. This is what I have:
Microsoft.Office.Interop.Excel.Application xlApp;
Microsoft.Office.Interop.Excel.Worksheet ws;
object misValue = System.Reflection.Missing.Value;
xlApp = new Microsoft.Office.Interop.Excel.Application();
Workbook wb = xlApp.Workbooks.Open(#".../MyExcelFile.xlsx");
ws = wb.Sheets[1];
string picPath = #"..../MyPic.png";
System.Drawing.Image img = System.Drawing.Image.FromFile(picPath);
var size = img.Size;
Microsoft.Office.Interop.Excel.Range oRange = (Microsoft.Office.Interop.Excel.Range)ws.Cells[1, 5];
float Left = (float)((double)oRange.Left);
float Top = (float)((double)oRange.Top);
const float ImageSize = 32;
ws.Shapes.AddPicture(picPath, Microsoft.Office.Core.MsoTriState.msoFalse, Microsoft.Office.Core.MsoTriState.msoCTrue, Left, Top, ImageSize, ImageSize);
So here I am inserting my image in the 5th cell of the 1st row, but setting its size to 32.However, I have access to this image's height and width. How can I set row 1 to that height and column 5 to that width?
EDIT: With the current code from Richard Mneyan, it looks like this, so the image doesn't fit in the cell:
The below would set height and width of your cell to respective picture height and width if you apply ratio of Column widths to Row Heights:
var sh = ws.Shapes.AddPicture(picPath, Microsoft.Office.Core.MsoTriState.msoFalse, Microsoft.Office.Core.MsoTriState.msoCTrue, Left, Top, ImageSize, ImageSize);
oRange.Rows[1].RowHeight = sh.Height;
oRange.Columns[1].ColumnWidth = sh.Width;
This is not perfect answer because it is really hard to set Excel Column Widths to exact number. For instance the default Excel Column width is 8.43, the next increment would be 8.57. Why?; because it is based on number of the Normal font
characters that can fit in a cell: https://support.microsoft.com/en-us/help/214123/description-of-how-column-widths-are-determined-in-excel
Here applying approximate ratios (which is not perfect):
double rColRow = 6; // Ratio of units of measure: columns widths to row heights
double rImgColWidth = 5.9; // Ratio of units of measure: image size and column widths
oRange.Rows[1].RowHeight = (sh.Width * rColRow / rImgColWidth);
oRange.Columns[1].ColumnWidth = (sh.Height / rImgColWidth);
I'm using Interop excel 12.0 to create a chart.
My assigned datarange to yaxis starts from 7/5/2010 till 8/29/2011. but Y axis on chart starts from 7/12/2010 and ends at 8/22/2011 however the chart line growth shows the datas from start to end
myChart.Chart.ChartWizard(xlWorkSheet.get_Range("A1", "B62"),misValue, misValue, misValue,misValue, Excel.XlRowCol.xlColumns, false,
"Space Used Trend Report for databases DLP01P, DLP07P, DPN01P and DUV01P", "Date", "GB", misValue);
Font f = new System.Drawing.Font(FontFamily.GenericSansSerif, 10.0f);
myChart.Chart.ChartTitle.Characters.Font.Size = f.Size;
chartPage.HasTitle = true;
//Trend Line setting
//Creating a series
Excel.Series series = (Excel.Series)chartPage.SeriesCollection(1);
//Setting the series to Secondary (y) axis so as to format the same
series.AxisGroup = Excel.XlAxisGroup.xlSecondary;
//Setting the trendline type
Excel.Trendlines trendlines = (Excel.Trendlines)series.Trendlines(System.Type.Missing);
Excel.Trendline trendline = trendlines.Add(Microsoft.Office.Interop.Excel.XlTrendlineType.xlLinear, 2,
0, misValue, misValue, misValue, false, false, misValue);
//Creating a variable for yaxis and assigning the chart's y axis to the same
Excel.Axis yaxis = (Excel.Axis)chartPage.Axes(Excel.XlAxisType.xlCategory, series.AxisGroup);
yaxis.MajorUnit = 14;
yaxis.MinorUnit = 7;
yaxis.Format.Line.BackColor.RGB = Color.Red.ToArgb();
yaxis.Format.Line.ForeColor.RGB = Color.Red.ToArgb();
yaxis.MajorUnitScale = Excel.XlTimeUnit.xlDays;
yaxis.MinorUnitScale = Excel.XlTimeUnit.xlDays;
yaxis.MinimumScaleIsAuto = false;
yaxis.MinimumScale = ?????
the minimum scale is taking only double values.
If I understand you well, this is what you're looking for: in Excel a date is the day number since 1-1-1900. If you want to calculate that in C# code, keep in mind that in Excel 1900 is a leap year (which it is not, of course, but this originates from compatibility with Lotus 123!), so 7/12/2010 would be 40519.00.
Try something like this, just change the values
{
chartPrincipal.YAxis.ScaleRange.ValueHigh = 100;
chartPrincipal.YAxis.ScaleRange.ValueLow = 0;
}
I am using excel to draw charts from c#, but i need the chart to be one series related to each other not two series (when i select a range that has two columns of data)
can any one help:
xla.Visible = true;
Workbook wb = xla.Workbooks.Add(XlSheetType.xlWorksheet);
Worksheet ws = (Worksheet)xla.ActiveSheet;
// Now create the chart.
ChartObjects chartObjs = (ChartObjects)ws.ChartObjects(Type.Missing);
ChartObject chartObj = chartObjs.Add(100, 20, 300, 300);
Chart xlChart = chartObj.Chart;
Range rg = ws.get_Range("B2", "C17");
xlChart.SetSourceData(chartRange, XlRowCol.xlColumns);
thanks
I cleaned the code up a bit and added the generation of random data so this should run on its own.
Random random = new Random();
Microsoft.Office.Interop.Excel.Application xla = new Microsoft.Office.Interop.Excel.Application();
xla.Visible = true;
Workbook wb = xla.Workbooks.Add(XlSheetType.xlWorksheet);
Worksheet ws = (Worksheet)xla.ActiveSheet;
// Now create the chart.
ChartObjects chartObjs = (ChartObjects)ws.ChartObjects();
ChartObject chartObj = chartObjs.Add(150, 20, 300, 300);
Chart xlChart = chartObj.Chart;
// generate some random data
for (int row = 0; row < 16; row++)
{
ws.Cells[row + 2, 2] = row + 1;
ws.Cells[row + 2, 3] = random.Next(100);
}
Range xValues = ws.Range["B2", "B17"];
Range values = ws.Range["C2", "C17"];
SeriesCollection seriesCollection = xlChart.SeriesCollection();
Series series1 = seriesCollection.NewSeries();
series1.XValues = xValues;
series1.Values = values;