EPPlus:在单元格中放置图像

Mur*_*ock 3 c# excel openxml epplus .net-core

我正在尝试使用Epplus将图像“插入” excel中的单元格。

使用以下代码

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;
    }
}
Run Code Online (Sandbox Code Playgroud)

--

var cell = sheet.Cells[2, 2];
SetImage(sheet, cell);

cell = sheet.Cells[3, 2];
SetImage(sheet, cell);
Run Code Online (Sandbox Code Playgroud)

但是,它似乎总是与右侧重叠。

在此处输入图片说明

如果我调整单元格的宽度和高度,重叠部分会发生变化,但不会消失

在此处输入图片说明

Mur*_*ock 5

所以我放弃了

picture.To.Column = cell.Start.Column;
picture.To.Row = cell.Start.Row;
Run Code Online (Sandbox Code Playgroud)

由于我无法正常工作,因此决定使用以下方法计算自己的尺寸:

picture.SetSize(width, height);
Run Code Online (Sandbox Code Playgroud)

诀窍是了解Excel如何实际计算宽度和高度。

像元的高度:以点为单位,但是我们需要像素。一英寸有72点。可以使用以下公式点*(1 / 72.0)* DPI将点转换为像素。DPI是每英寸点数,可以使用以下方法找到:

using (Graphics graphics = Graphics.FromHwnd(IntPtr.Zero))
{
    float dpiY = graphics.DpiY;
}
Run Code Online (Sandbox Code Playgroud)

所以要计算我使用的像素的像元高度

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);
    }
}
Run Code Online (Sandbox Code Playgroud)

单元格的宽度:这有点棘手。基本上,excel中单元格的宽度等于单元格可水平包含的字符数(使用默认字体设置)。

例如

在此处输入图片说明

该列的长度为12,可以包含Calibri(11)字体的12个数字。

这也是我的excel默认值,因为我的身体默认值是calibri(11) 在此处输入图片说明

这是一篇更深入地解释它的文章

下一个问题是地球上如何将其转换为像素。

首先,我们需要发现默认字体中字符的长度。可以在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;
    }
}
Run Code Online (Sandbox Code Playgroud)

然后,我使用该方法计算像素的宽度,如下所示

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);
}
Run Code Online (Sandbox Code Playgroud)

编辑:请注意,在显示设置下将缩放系数设置为100%以上时,仍然会发生重叠