EPPlus:在单元格中定位图像
EPPlus: Position image in a cell
我正在尝试使用 Epplus 在 excel 的单元格中插入图像 "into"。
使用以下代码
private static void SetImage(ExcelWorksheet sheet, ExcelRange cell)
{
using (WebClient client = new WebClient())
using (Stream stream = client.OpenRead("https://..."))
using (Bitmap bitmap = new Bitmap(stream))
{
var picture = sheet.Drawings.AddPicture(Guid.NewGuid().ToString(), bitmap);
picture.From.Column = cell.Start.Column - 1;
picture.From.Row = cell.Start.Row - 1;
picture.To.Column = cell.Start.Column;
picture.To.Row = cell.Start.Row;
}
}
-
var cell = sheet.Cells[2, 2];
SetImage(sheet, cell);
cell = sheet.Cells[3, 2];
SetImage(sheet, cell);
然而它似乎总是向右重叠。
如果我调整单元格的宽度和高度,重叠会发生变化但不会消失
所以我放弃了
picture.To.Column = cell.Start.Column;
picture.To.Row = cell.Start.Row;
因为我无法让它工作并决定使用以下方法计算我自己的尺寸:
picture.SetSize(width, height);
诀窍是了解 Excel 实际计算宽度和高度的方式。
单元格的高度:它以磅为单位测量,但我们需要像素。一英寸有 72 个点。可以使用以下公式点* (1/72.0) * DPI 将点转换为像素。 DPI 是每英寸点数,可以使用以下方法找到:
using (Graphics graphics = Graphics.FromHwnd(IntPtr.Zero))
{
float dpiY = graphics.DpiY;
}
所以为了计算单元格的高度,我使用了
private static int GetHeightInPixels(ExcelRange cell)
{
using (Graphics graphics = Graphics.FromHwnd(IntPtr.Zero))
{
float dpiY = graphics.DpiY;
return (int)(cell.Worksheet.Row(cell.Start.Row).Height * (1 / 72.0) * dpiY);
}
}
单元格的宽度: 这有点棘手。 excel 中单元格的宽度基本上等于单元格可以水平包含的字符数(使用默认字体格式化)。
例如
该列的长度为 12,可以包含 12 个 Calibri(11) 字体的数字。
这也是我的 excel 默认值,因为我的 body 默认值是 calibri(11)
这里有一个 article 更深入的解释。
下一个问题是究竟如何将其转换为像素。
首先我们需要了解默认字体中一个字符的长度。可以在 System.Windows.Forms 命名空间中使用 TextRenderer.MeasureText。但是我正在使用 .Net Core 并且需要另一种方式。另一种方法是使用现在处于预览状态的 System.Drawing.Common 核心库。
public static float MeasureString(string s, Font font)
{
using (var g = Graphics.FromHwnd(IntPtr.Zero))
{
g.TextRenderingHint = System.Drawing.Text.TextRenderingHint.AntiAlias;
return g.MeasureString(s, font, int.MaxValue, StringFormat.GenericTypographic).Width;
}
}
然后我使用该方法计算宽度(以像素为单位)如下
private static int GetWidthInPixels(ExcelRange cell)
{
double columnWidth = cell.Worksheet.Column(cell.Start.Column).Width;
Font font = new Font(cell.Style.Font.Name, cell.Style.Font.Size, FontStyle.Regular);
double pxBaseline = Math.Round(MeasureString("1234567890", font) / 10);
return (int)(columnWidth * pxBaseline);
}
编辑:请注意,在显示设置下将缩放系数设置为大于 100% 时,重叠仍然会发生
我正在尝试使用 Epplus 在 excel 的单元格中插入图像 "into"。
使用以下代码
private static void SetImage(ExcelWorksheet sheet, ExcelRange cell)
{
using (WebClient client = new WebClient())
using (Stream stream = client.OpenRead("https://..."))
using (Bitmap bitmap = new Bitmap(stream))
{
var picture = sheet.Drawings.AddPicture(Guid.NewGuid().ToString(), bitmap);
picture.From.Column = cell.Start.Column - 1;
picture.From.Row = cell.Start.Row - 1;
picture.To.Column = cell.Start.Column;
picture.To.Row = cell.Start.Row;
}
}
-
var cell = sheet.Cells[2, 2];
SetImage(sheet, cell);
cell = sheet.Cells[3, 2];
SetImage(sheet, cell);
然而它似乎总是向右重叠。
如果我调整单元格的宽度和高度,重叠会发生变化但不会消失
所以我放弃了
picture.To.Column = cell.Start.Column;
picture.To.Row = cell.Start.Row;
因为我无法让它工作并决定使用以下方法计算我自己的尺寸:
picture.SetSize(width, height);
诀窍是了解 Excel 实际计算宽度和高度的方式。
单元格的高度:它以磅为单位测量,但我们需要像素。一英寸有 72 个点。可以使用以下公式点* (1/72.0) * DPI 将点转换为像素。 DPI 是每英寸点数,可以使用以下方法找到:
using (Graphics graphics = Graphics.FromHwnd(IntPtr.Zero))
{
float dpiY = graphics.DpiY;
}
所以为了计算单元格的高度,我使用了
private static int GetHeightInPixels(ExcelRange cell)
{
using (Graphics graphics = Graphics.FromHwnd(IntPtr.Zero))
{
float dpiY = graphics.DpiY;
return (int)(cell.Worksheet.Row(cell.Start.Row).Height * (1 / 72.0) * dpiY);
}
}
单元格的宽度: 这有点棘手。 excel 中单元格的宽度基本上等于单元格可以水平包含的字符数(使用默认字体格式化)。
例如
该列的长度为 12,可以包含 12 个 Calibri(11) 字体的数字。
这也是我的 excel 默认值,因为我的 body 默认值是 calibri(11)
这里有一个 article 更深入的解释。
下一个问题是究竟如何将其转换为像素。
首先我们需要了解默认字体中一个字符的长度。可以在 System.Windows.Forms 命名空间中使用 TextRenderer.MeasureText。但是我正在使用 .Net Core 并且需要另一种方式。另一种方法是使用现在处于预览状态的 System.Drawing.Common 核心库。
public static float MeasureString(string s, Font font)
{
using (var g = Graphics.FromHwnd(IntPtr.Zero))
{
g.TextRenderingHint = System.Drawing.Text.TextRenderingHint.AntiAlias;
return g.MeasureString(s, font, int.MaxValue, StringFormat.GenericTypographic).Width;
}
}
然后我使用该方法计算宽度(以像素为单位)如下
private static int GetWidthInPixels(ExcelRange cell)
{
double columnWidth = cell.Worksheet.Column(cell.Start.Column).Width;
Font font = new Font(cell.Style.Font.Name, cell.Style.Font.Size, FontStyle.Regular);
double pxBaseline = Math.Round(MeasureString("1234567890", font) / 10);
return (int)(columnWidth * pxBaseline);
}
编辑:请注意,在显示设置下将缩放系数设置为大于 100% 时,重叠仍然会发生