1

有没有人成功地使用 epplus 在 excel 2010 文件中以像素的形状或图片获得 x 和 y 坐标?

4

3 回答 3

1

不幸的是,它并不漂亮。您真正需要的功能GetPixelTopGetPixelLeft文件中,ExcelDrawingBase.cs但它们被标记为internalhttp ://epplus.codeplex.com/SourceControl/latest#EPPlus/Drawing/ExcelDrawingBase.cs 。所以你不能在不修改源代码的情况下真正调用它们。

最简单的方法就是重新创建您自己的版本。这是一个快速剪切/粘贴(确保在生产前做好 QA):

public int DrawingPixelX(ExcelWorksheet worksheet, ExcelDrawing drawing)
{
    const int emuPerPixel = ExcelDrawing.EMU_PER_PIXEL;
    decimal mdw = worksheet.Workbook.MaxFontWidth;

    var pix = 0;
    for (var i = 1; i <= drawing.From.Column; i++)
        pix += (int)decimal.Truncate(((256 * (decimal)worksheet.Column(i).Width + decimal.Truncate(128 / mdw)) / 256) * mdw);

    pix += drawing.From.ColumnOff / emuPerPixel;
    return pix;
}

public int DrawingPixelY(ExcelWorksheet worksheet, ExcelDrawing drawing)
{
    const int emuPerPixel = ExcelDrawing.EMU_PER_PIXEL;

    var piy = 0;
    for (var i = 1; i <= drawing.From.Row; i++)
        piy += (int)(worksheet.Row(i).Height / 0.75);

    piy += drawing.From.RowOff / emuPerPixel;
    return piy;
}

你可以像这样使用它:

var workbook = package.Workbook;
var ws = workbook.Worksheets.First();
var pic = ws.Drawings.First();

Console.WriteLine(DrawingPixelX(ws, pic));
Console.WriteLine(DrawingPixelY(ws, pic));

对于附加的图像,我得到了 141 和 43 的左侧和顶部。

在此处输入图像描述

于 2016-04-07T16:17:55.847 回答
1

我终于找到了一个使用内部 xml 数据的解决方案,似乎 excel 正在使用一个名为EMUwhich is的度量单位equal to 1/9525 pixel。解决方案如下

public static Rectangle GetDimensions(string shapeName, ExcelWorksheet sheet)
{
  const int EMU = 9525;
  var shapeBaseNodexPath = string.Format("//*[@name='{0}']", shapeName);

  //get node that contains name of the shape
  var shapeNameNode = sheet.Drawings.DrawingXml.SelectSingleNode(shapeBaseNode);

  if (shapeNameNode == null)
    throw new ArgumentException("Invalid shape name");
  //go 2 levels up and select shape properties node <a:xfrm> node
  var propertiesNode = shapeNameNode
    .SelectSingleNode("../../*[local-name() = 'spPr']/*[local-name() = 'xfrm']");
  if (propertiesNode == null)
    throw new InvalidOperationException("Could not parse Excel file xml data");

  //get coodinates and size nodes
  var locationNode = propertiesNode.SelectSingleNode("*[local-name() = 'off']");
  var sizeNode = propertiesNode.SelectSingleNode("*[local-name() = 'ext']");

  //create Rectangle
  int x, y, w, h = 0;
  x = int.Parse(locationNode.Attributes["x"].Value) / EMU;
  y = int.Parse(locationNode.Attributes["y"].Value) / EMU;
  w = int.Parse(sizeNode.Attributes["cx"].Value) / EMU;
  h = int.Parse(sizeNode.Attributes["cy"].Value) / EMU;

  return new Rectangle(x, y, w, h);
}
于 2016-04-07T16:21:15.617 回答
0

您可以从内部ExcelDrawing内部字段_widht_height. 感谢@Ernie 指向ExcelDrawingBase.cs.

shape = (ExcelShape) xls.Workbook.Worksheets[1].Drawings["MyShape"];
var width = (int) shape.GetType()
        .GetProperty("_width", BindingFlags.NonPublic | BindingFlags.Instance)
        .GetValue(shape);
var height = (int) shape.GetType()
        .GetProperty("_height", BindingFlags.NonPublic | BindingFlags.Instance)
        .GetValue(shape);   

编辑:此方法仅在 EPP 4 上进行测试,当前版本的 EPP 5 内部实现可能已更改。

于 2019-07-01T07:06:59.553 回答