Set Column Width in C# (Interop.Excel) could be too larger - c#

I counldn't set the width with Interop.
My code is :
double kA = ((Excel.Range)st.Columns[1]).EntireColumn.Width;
double kB = ((Excel.Range)st.Columns[2]).EntireColumn.Width;
int KNA = Convert.ToInt32(kA + kB);
//((Excel.Range)st.Columns[1]).EntireColumn.ColumnWidth = kA + kB;
Console.WriteLine(KNA);
((Excel.Range)st.Columns[1]).ColumnWidth = KNA;
Console.WriteLine(((Excel.Range)st.Columns[1]).EntireColumn.Width);
((Excel.Range)st.Columns[2]).EntireColumn.Delete();
Both kA and kB is 59.25,and KNA is 118.But the actual width of Column A is 801.75,and it couldn't be modified any way.
I use ((Excel.Range)st.Columns1).ColumnWidth = KNA;
But the columnA width couldn't be change.
What's wrong?
I tried to change the initial columnWidth of column A&B,and I got the different value of new column width but is still more larger than KNA,about 6.8 times each time.
Before run code:
After run code:

I use columnWith to get and set columnwidth,and It's OK.

Related

Getting the height of excel row after auto-fitting and then increase it Epplus

I'm trying to increase the height of rows after auto fitting them.
For example: first row height is 15
I autofit them by:
//The first row
var start = sheet.Dimension.Start;
//The last row
var end = sheet.Dimension.End;
for (int row = start.Row; row <= end.Row; row++)
{
//This makes Excel auto fit the row but content
sheet.Row(row).CustomHeight = true;
}
So the first row height is now :30
Then, I want to increase each row size by adding this code in the loop
double x = sheet.Row(row).Height;
sheet.Row(row).Height = 1.25 * x;
The Problem is Excel doing the auto fitting when opening the Excel file so EPPlus doesn't get the updated row height information but the old infomation.
So the row height is now 18.75 (15 * 1.25) instead of 37.5 (30 * 1.25)
You cannot. As you say "Excel doing the auto fitting when opening the Excel file" - so that is long after EPPlus has been working on that file. All you do (and can do) is to tell Excel to adjust the height accordingly.
(That is different with columns: EPPlus can perform sheet.Column(column).AutoFit(); and set the width to an appropriate value - but not for row heights, unfortunately. Mayby this is added in the new, commercial version of EPPlus?)
I think your option is do some experimenting and try to calculate and set the height yourself in EPPlus.
Or you run a VBA Script in your Excel File to do the job - this is no problem, it goes like this:
With Sheets("Formular").Range(Cells(14, 1), Cells(14 + i - 1, 4))
.EntireRow.AutoFit
.VerticalAlignment = xlTop
For Each r In .Rows
r.RowHeight = r.Height + 5
Next r
End With
This might not be an option for you, of course, when you are not allowed to run Macros in your environment.

How to set height of element using variable in C#?

I'm trying to set the height of a WPF element using C# to a programatically calculated value.
I've already tried the obvious of setting the height to a variable, a constant variable and just straight-up writing the calculation during the assignment.
Image image1 = new Image()
{
Stretch = Stretch.UniformToFill,
Height = (450 / 650) * 260
};
I'm expecting that the image appears with the size 260x180, but the image doesn't appear at all. Setting the Height to be 180 (the outcome of the calculation) makes it look as expected, though.
How do I fix it and why does it happen?
You need to convert your calculations not to use integers
Image image1 = new Image()
{
Stretch = Stretch.UniformToFill,
Height = ((double)450 / (double)650) * (double)260
};
Didn't test it, but something like this should do the trick.
The problem is that 450 / 650 is 0 when using int.
Maybe 260 * 450 / 650 works too.

C# EPPLUS Chart SetPosition Method Row Offset does not work

I am creating a chart to export to excel. I need to create several, so I would offset them using the SetPosition() method with the 4 parameters:
SetPosition(int row, int rowoffset in pixel, int col, int coloffset in pixel)
thus
chart.SetPosition(startRow, 350*i, 0, 50);
The problem is that the second row offset parameter stretches the chart by 350*i pixels higher. This must be a bug since the col offset 4th parameter works fine and as expected.
I need to use startRow to start at a specific row cell in the sheet, so I need to get the row offset to work somehow.
Any ideas?
The RowOffset and ColumnOffset have given me trouble as well and I avoid using them in that function. If you look at the source could you can see it doing alot of match with the chart height/width so it seems to do more then just set and top/left position. I have not gone through the effort to fully reverse engineer it.
I just do the math myself. Knowing the default row height in pixels is the only thing that you have to watch out for since this can be customized by the user which you cannot know at design time Here is what I do:
using (var pck = new ExcelPackage(fi))
{
var workbook = pck.Workbook;
var worksheet = workbook.Worksheets.Add("Sheet1");
worksheet.Cells.LoadFromDataTable(datatable, true);
//Set specific values to make predictable
const int EXCELCHARTWIDTH = 375;
const int EXCELCHARTHEIGHT = 350;
//Have to assume a standard screen dpi but can be customized by the user
const double EXCELDEFAULTROWHEIGHT = 20.0;
var startCell = (ExcelRangeBase)worksheet.Cells["A1"];
for (var i = 0; i < 10; i++)
{
var chart = worksheet.Drawings.AddChart("chart " + i, eChartType.Pie);
chart.SetSize(EXCELCHARTWIDTH, EXCELCHARTHEIGHT);
chart.SetPosition(startCell.Start.Row, 0, startCell.Start.Column, 0);
var chartcellheight = (int)Math.Ceiling(EXCELCHARTHEIGHT / EXCELDEFAULTROWHEIGHT);
startCell = startCell.Offset(chartcellheight, 0);
}
pck.Save();
}
The offset is an offset within one cell.
So if you have a cell 64 x 20 pixels (default) it should not usually exceed 64 or 20 resp. To set the top left corner of a chart just in the middle of a cell, call:
chart.SetPosition(row , 10, col, 32);
also note that if you read the position from From.RowOff, you need to divide it by 9525

.NET Multiline TextBox - Set number of lines

I want to be able to set the number of lines in a multilined TextBox.
I've tried the following:
int initHeight = textBox1.Height;
textBox1.Height = initHeight * numOfLines;
But this makes it too large when numOfLines gets large. So then I tried this:
float fontHeight = textBox1.CreateGraphics().MeasureString("W", textBox1.Font).Height;
textBox1.Height = fontHeight * numOfLines;
But this was too small when numOfLines was small, and too large when numOfLines was large.
So I'm doing SOMETHING wrong... any ideas?
This would set the exact Width & Height of your multi line Textbox:
Size size = TextRenderer.MeasureText(textBox1.Text, textBox1.Font);
textBox1.Width = size.Width;
textBox1.Height = size.Height + Convert.ToInt32(textBox1.Font.Size);
Something like this should work:
Size size = TextRenderer.MeasureText(textBox1.Text, textBox1.Font);
textBox1.Width = size.Width;
textBox1.Height = size.Height;
This was from C# Resize textbox to fit content
What you are doing should work, but you need to set the MinimumSize and MaximumSize I am not 100% positive, but I think this constraint will still hold if height is set via code
From the documentation of Graphics.MeasureString:
To obtain metrics suitable for adjacent strings in layout (for example, when implementing formatted text), use the MeasureCharacterRanges method or one of the MeasureString methods that takes a StringFormat, and pass GenericTypographic. Also, ensure the TextRenderingHint for the Graphics is AntiAlias.
As such, you should use one of these overloads, such as this one, which allow you to specify StringFormat.GenericTypograpic to get the required size.
Try this:
float fontHeight;
using (var g = textBox1.CreateGraphics())
fontHeight = g.MeasureString("W", textBox1.Font, new PointF(), StringFormat.GenericTypograpic).Height;

set lower and upper bound of axes in excel chart from C# API to min/max values of data set

I am using C# Excel API to generate some reports. However, Excel leaves gaps between the first axis point and minimum value in data set, and between last axis point and maximum value in data set. My data set is sorted by datetime. How do I force excel to set the lower and upper bounds of axes precisely to minimum and maximum values in my data set so that I don't see any gaps? I can do that in excel by manually setting min/max axis points in excel chart.
But is there a way to have excel do this automatically, or otherwise set min/max points from my C# application using the data set?
Example (marked gaps)
Hope it makes sense.
thanks
[Edited] OK, I did some playing, and I've figured out how to set the vertical and horizontal axis range. This is working with Excel 2010.
Here, I clear all charts on the page and create a new one (_resultsSheet is an Excel.Worksheet):
var resultCharts = (ChartObjects)_resultsSheet.ChartObjects();
foreach (ChartObject ch in resultCharts)
{
ch.Delete();
}
ChartObject resultChart = resultCharts.Add(150, 40, 300, 200);
_resultChartPage = resultChart.Chart;
Now set up the source - I've just used a predefined range of fixed values. You could scan your source to find the actual min and max values:
_resultChartRange = _resultsSheet.get_Range("J5", "K15");
_resultChartPage.SetSourceData(_resultChartRange);
_resultChartPage.ChartType = Excel.XlChartType.xlXYScatterLines;
_resultChartPage.HasLegend = false;
Now for the vertical axis setup:
Axis vertAxis = (Axis)resultChart.Chart.Axes(XlAxisType.xlValue, XlAxisGroup.xlPrimary);
vertAxis.HasMajorGridlines = true; // change this to whatever you wish
vertAxis.HasTitle = true;
vertAxis.AxisTitle.Text = "up the side";
vertAxis.MaximumScaleIsAuto = false;
vertAxis.MaximumScale = 500; // you can pick this based on your input
vertAxis.MinimumScaleIsAuto = false;
vertAxis.MinimumScale = 5;
now for the other axis. Note here I've used fixed times. To convert a time to an axis scale, just use the 24 hour time in decimal, divided by 24. Eg. 9:30pm is 21:30 which is 21.5 hours. Don't forget the (double) cast just in case you use to ints.
Axis horizAxis = resultChart.Chart.Axes(XlAxisType.xlCategory, XlAxisGroup.xlPrimary);
horizAxis.MaximumScaleIsAuto = false;
horizAxis.MaximumScale = (double)21.5 / 24; // 9:30 pm
horizAxis.MinimumScaleIsAuto = false;
horizAxis.MinimumScale = (double)13 / 24; // 1:00 pm
horizAxis.HasTitle = true;
horizAxis.AxisTitle.Text = "across the bottom";
and for those who "like to watch":
_resultsSheet.Activate();
_workBook.Application.Visible = true;

Categories