(C#) Can I programmatically set an XLSX cell to a picture/image? - c#

I am hoping to make spreadsheets that contain some pictures (embed pictures from files) and I started looking at EPPlus (looks like a great library)
However it seems that the images are not tied to a cell - rather to an x,y, coordinate.
Is there a way with EPPlus or other way to set a cell to a picture (and then manipulate the size of the cell?)
SetPosition

My misunderstanding...
Here is a comment I found when looking around:
No version of Excel allows you to insert a picture into a cell. Pictures are inserted into the worksheet and will always float.
One of the properties of a picture can be set to "move and size with cells" but that only moves or stretches the picture when the underlying rows and columns are inserted, deleted or sized. It does not confine a picture to a cell.
So perhaps I just need to set the properties appropriately.
If I can do this programmatically I will be all set
EDIT
The following code does pretty much what I want/need.
Note that before inserting the pics I set the width and height of the cell I was overlaying to appropriate sizes.
private static void AddImage(ExcelWorksheet ws, int rowIndex, String imageFile)
{
ExcelPicture picture = null;
Bitmap image = new Bitmap(imageFile);
if (image != null)
{
picture = ws.Drawings.AddPicture("pic" + rowIndex.ToString(), image);
picture.From.Column = 0;
picture.From.Row = rowIndex-1;
picture.SetSize(320, 240);
}
}

You can insert the picture, then adjust its .Top and .Left so it aligns with the .Top and .Left of the appropriate cell. You can set the .RowHeight of the cell's row using the same units as the .height of the picture (though there's a maximum height). The .ColumnWidth of the column is in units of text characters wide, so what I do is something like:
myColumn.ColumnWidth = myColumn.ColumnWidth / myColumn.Width * myPicture.Width
and I run it twice because sometimes the first time you set .ColumnWidth, it isn't set precisely.

I don't think you can do that in Excel itself; when you add a picture to an Excel worksheet, it's a floating object, it's not fixed to a specific cell.

Found in the EPPLUS documentation it should be possible with the EditAs setting on value TwoCell.
picture.EditAs = eEditAs.TwoCell;
"Specifies that the current drawing shall move and resize to maintain its row and column anchors (i.e. the object is anchored to the actual from and to row and column). "

Related

NPOI how to get size of text in the cell

I just started to learn NPOI. I think, that I have some idea how to use it, but I just need two more things to know how to do.
The first one is how to get the minimum size (height and width) of the cell with some text and style, so I will be able to set the correct cell size.
I can't use the auto size feature, because I have structured document and I need some different text in the same column to be on multiple lines.
An example:
I need the column "Name" to have size of "Total amount". Is there a way, how to get the width of the"Total amount" text for selected font?
Thank you.

Remove extra padding in DataGridView column label?

I have a DataGridView that I am trying to reduce the width of so it displays how I wish in my form. I am having issues "removing" the extra padding in the column names when reducing the size of the DataGridView.
On the left is the table as I originally had it, I realized that I would like it smaller so I decreased its width. The center image represents the smallest the columns will go before the text wraps to the next line. The right image is the size I would like the table to be, I have shown that the text "(px)" will fit in the space.
I have gone through all of the settings I can find in the designer and have not found anything to help. Does anyone know how to fix this?
Here is my example. Although it might not be the best solution but worked.
I measured the exact width of HeaderCell's content ("Height (px)") and set the column's width with some additional padding (For example, 9).
dataGridView1.AutoSizeColumnsMode = DataGridViewAutoSizeColumnsMode.None;
dataGridView1.ColumnHeadersDefaultCellStyle.WrapMode = DataGridViewTriState.False;
Size textSize = TextRenderer.MeasureText(dataGridView1.Columns[0].HeaderText, dataGridView1.Font);
dataGridView1.Columns[0].Width = textSize.Width + 9; // Adding some padding

Detect Printable Area Width in OpenXml.Wordprocessing

I'm adding an image to a Word document using OpenXml.
I am able to tell the size of the image being added, and I can resize it if I want to. But what I really want is to only resize it if it's wider than the current column. (In my case, there is only one column but perhaps that could change.)
Is there any way to know how wide the current column is and, therefore, be able to ensure that the image fits within the column? As it is, large images are extending off the page.
I've updated my answer, because it was an answer for a case when table columns are involved, but the word column in the question mean a column or text rather than a column in a table.
In the document, You should be able to get the following values:
// ...
var sectionProperties = body.GetFirstChild<SectionProperties>();
// pageSize contains Width and Height properties
var pageSize = sectionProperties.GetFirstChild<PageSize>();
// this contains information about surrounding margins
var pageMargin = sectionProperties.GetFirstChild<PageMargin>();
// this contains information about spacing between neighbouring columns of text
// this can be useful if You use page layout with multiple text columns
var columns = sectionProperties.GetFirstChild<Columns>();
var spaceBetweenColumns = columns.Space.Value;
var columnsCount = columns.ColumnCount.Value;
I haven't tested this, but I suppose You may be able to calculate the actual width of a text column using those values.

Displaying two images in single column on datagridview

how can i create a column that can display 2 images in one column on datagridview?
i tried to create 2 datagridviewimagecolumn (for the different images)
and if it the cell in it contains the same image path.
the image will match depending on the path on the cell.
this must combine in one column (as shown on the figure below)
for example.
here i will create 2 datagridimagecolumn
DataGridViewImageColumn img1 - new DataGridViewImageColumn();
Image Simg1 = Image.FromFile (C:\Desktop\Green.jpg);
img1.Image = Simg1;
dgv.Columns.Add(img1); //it will display on the datagridview
DataGridViewImageColumn img2 - new DataGridViewImageColumn();
Image Simg2 = Image.FromFile (C:\Desktop\Red.jpg);
img2.Image = Simg1;
dgv.Columns.Add(img2);
if the generated column from the sql server looks like this
column1
---------
c:\Desktop\Greeen.jpg
c:\Desktop\Green.jpg
c:\Desktop\Red.jpg
c:\Desktop\Green.jpg
how will i do this one.
the green path will display green image.
and the red path will contain red image.
I don't know if I understand well your question but I think you can work around creating an Image that is the tiling of the 2 images and print it inside your column.
you can see here or here how to do that.
You'll need to write your own merged cell class implementing onpaint event. You can see an example of it's being done here.

Calculate width available for columns in dataGridView

My question is very simple - after data binding I want to set all columns width so that it will not be horizontal scrolling. Something like this:
columnWidth = grid.width/grid.Columns.Count
But this expression does not consider the "left part of gridView" with which I can select row, which displays current row. How can I calculate its width? [(grid.width - X)/grid.Columns.Count]
Very easy to do this. Just set the DataGridView.AutoSizeColumnMode property to Fill.
grid.AutoSizeColumnsMode = DataGridViewAutoSizeColumnsMode.Fill;
And you may need to explicitly ask the grid to resize column spacing. I can't remember for sure. But that is simple to do:
grid.AutoResizeColumns();
According to the documentation, Fill will do the following:
The column widths adjust so that the widths of all columns exactly
fill the display area of the control, requiring horizontal scrolling
only to keep column widths above the DataGridViewColumn.MinimumWidth
property values. Relative column widths are determined by the relative
DataGridViewColumn.FillWeight property values.
So basically, as long as you don't have any columns with a MinimumWidth that will prevent it, this property does exactly what you are looking for.
EDIT: Addressing the comment of the OP:
You can always create a simple property to report that information to you. Something like...
public int DataGridViewDeadSpaceWidth
{
get
{
int x = grid.Width;
foreach (DataGridViewColumn column in grid.Columns)
x -= column.Width;
return x;
}
}
You could also use this to inherit from a DataGridView and add the property yourself to the control. Note that there is probably some other dead space from the borders of the DataGridView that you need to account for.

Categories

Resources