C# EPPlus AddPicture 100%大小

C# EPPlus AddPicture 100%大小,c#,epplus,C#,Epplus,更新:部分问题是Excels故障。它可以在不同的视图设置(普通布局与页面布局)之间更改图像大小。我可能需要重新评估,剩下的差异是否重要 如何通过EPPlus将图像添加到excel工作表而不进行任何大小调整(随后在excel中打开,并在图像属性中设置100%缩放) 我的测试用例中的图像(Testfile.jpg)是一个宽度为508px、高度为177px、分辨率为300dpi的jpg 我的测试代码: class Program { static void Main(string[] arg

更新:部分问题是Excels故障。它可以在不同的视图设置(普通布局与页面布局)之间更改图像大小。我可能需要重新评估,剩下的差异是否重要


如何通过EPPlus将图像添加到excel工作表而不进行任何大小调整(随后在excel中打开,并在图像属性中设置100%缩放)

我的测试用例中的图像(
Testfile.jpg
)是一个宽度为508px、高度为177px、分辨率为300dpi的jpg

我的测试代码:

class Program
{
    static void Main(string[] args)
    {
        using (var package = new OfficeOpenXml.ExcelPackage(new FileInfo(@"C:\UserTemp\Test\TestFormat.xlsx")))
        {
            OfficeOpenXml.ExcelWorksheet worksheet = package.Workbook.Worksheets[1];

            var img = worksheet.Drawings.AddPicture("Test", new FileInfo(@"C:\UserTemp\Test\Testfile.jpg"));
            img.SetPosition(4, 0, 5, 0);
            img.SetSize(100);

            package.SaveAs(new FileInfo(@"C:\UserTemp\Test\TestFormat2.xlsx"));
        }
    }
}
对于EPPlus 4.0.5,当查看生成的xlsx文件中的图像大小时,我得到以下结果:

  • 使用未格式化的空输入xlsx文件,我得到的是
    4.31cm
    ,而不是
    4.30cm
    图像宽度
  • 不同的输入xlsx文件具有更复杂的格式(不同的行大小、不同的列大小、连接的单元格),给了我更糟糕的结果:
    4.47cm
    而不是
    4.30cm
    图像宽度
对于EPPlus 4.1.0,我得到了完全不同的结果:

  • 使用未格式化的空输入xlsx文件,我得到的是
    13,44cm
    ,而不是
    4.30cm
    图像宽度
  • 使用预格式化的xlsx文件,我得到的是
    13,81cm
    ,而不是
    4.30cm
    图像宽度
“高度”属性的行为类似,但不幸的是,“宽度:高度”比率不一致

我已经尝试过一些东西,比如
img.SetSize(widthPx,heighthpx)
和不同的图像格式,但没有成功

所以现在我对不一致的结果感到迷茫

  • 在ePlus版本之间
  • 在不同的excel输入文件之间
我需要至少保证宽度:高度比例,最好是保证图像大小

注意:我不能在这里创建和使用96 DPI的图像,因为这会导致非常像素化的打印

编辑:

下图显示了我刚刚创建为showcase的一个布局有点不规则的文件的结果。绿色框是插入的图像,混乱的比例在对话框窗口中高亮显示(德语,但相关内容是数字)


如果有人遇到类似问题,下面是我如何解决我的具体问题

与正常视图相比,Excel正在页面视图中拉伸图像。因为我不关心正常视图中的图像比例,所以我可以调整图像大小。我分析了我的案例的拉伸,发现96 DPI调整图像宽度的以下范围(在我的案例中高度没有改变):

请注意,校正值并非100%准确,因为在不同DPI的图像大小变换中也存在一些舍入误差

0px - 54px: 0px to much width
55px - 109px: 4px to much width
110px - 165px: 8px to much width
166px - 317px: 12px to much width
318px - 442px: 23px to much width
443px - ???: 32px to much width // I didn't bother to investigate larger values
这意味着可以通过减去所述偏移来调整大多数宽度。对于不同偏移之间的边界情况,将保留一个小错误。以下宽度转换功能(
AdjustExcelPageViewImageWidth
)用于纠正所述错误

/// <summary>
/// Excel is changing the image size in page view, this is an attempt to correct the change for a range of widths.
/// Input width is required as pixel equivalent of the desired width for 96 DPI.
/// </summary>
int AdjustExcelPageViewImageWidth(int desiredWidth96DPI)
{
    return
        LimitedRangeTransform(desiredWidth96DPI, 0, 54, 0, 4) ??
        LimitedRangeTransform(desiredWidth96DPI, 55, 109, 4, 8) ??
        LimitedRangeTransform(desiredWidth96DPI, 110, 165, 8, 12) ??
        LimitedRangeTransform(desiredWidth96DPI, 166, 317, 12, 23) ??
        LimitedRangeTransform(desiredWidth96DPI, 318, 442, 23, 32) ??
        // no data gathered for larger images
        desiredWidth96DPI - 32;
}
/// <summary>
/// Interpolation function between ranges with different limit and offset. Returns the transformed width or null.
/// </summary>
/// <param name="width">the desired width</param>
/// <param name="lower">the lower bound of the range, where the offset applies</param>
/// <param name="upper">the upper bound of the range, where the offset applies</param>
/// <param name="offset">the offset value will be subtracted for width within the range</param>
/// <param name="nextOffset">the offset value for the next range following the upper bound</param>
/// <returns></returns>
int? LimitedRangeTransform(int width, int lower, int upper, int offset, int nextOffset)
{
    // not handling those cases
    if (upper < lower || width < lower + offset)
    {
        return null;
    }
    if (width <= upper + offset)
    {
        return width - offset;
    }
    if (width <= upper + offset + (nextOffset - offset) / 2)
    {
        // border cases, can't be accurate
        return upper;
    }
    if (width <= upper + nextOffset)
    {
        // border cases, can't be accurate
        return upper + 1;
    }
    return null;
}

结果自然会有一些较小的舍入误差,因为EPPlus将大小作为整数,但图像比例不再明显失真。

好的,实际上还有更多的情况发生。。。Excel普通视图->页面视图扩展宽度,不更改高度。“打印预览”或“实际打印”会扩展宽度并收缩高度。注意:打印宽度甚至相对于页面视图也被扩展了,所以我猜它的微软正处于最佳状态。
static void Main(string[] args)
{
    using (var package = new OfficeOpenXml.ExcelPackage(new FileInfo(@"C:\UserTemp\Test\TestFormat.xlsx")))
    {
        OfficeOpenXml.ExcelWorksheet worksheet = package.Workbook.Worksheets[1];

        var img = worksheet.Drawings.AddPicture("Test", new FileInfo(@"C:\UserTemp\Test\Testfile.jpg"));
        img.SetPosition(4, 0, 5, 0);

        var width = (int)Math.Round(img.Image.Width * 96.0 / img.Image.HorizontalResolution);
        var height = (int)Math.Round(img.Image.Height * 96.0 / img.Image.VerticalResolution);
        var adjustedWidth = AdjustExcelPageViewImageWidth(width);
        img.SetSize(adjustedWidth, height);

        package.SaveAs(new FileInfo(@"C:\UserTemp\Test\TestFormat2.xlsx"));
    }
}