2016-04-06 7 views

ответ

0

я, наконец, нашли решение с использованием данных внутреннего XML, кажется, что Excel использует устройство для измерения под названием EMU которое 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); 
} 
+0

Откуда у вас это фактическое число (1045 451)? Когда я запускаю вашу функцию против файла excel, который я создал с помощью одного рисунка, на самом деле это немного немного. В моем тесте моя func дает ширину 140, в то время как ваш дает 131. Я помещал картинку как раз в негладкой Col C, и если я подсчитываю ширину Cols A и B в самом Excel, я получаю 137. Разница в 3 пикселя выглядит правильно для разрыв между началом Col C и изображением. Я обновил свой пост, чтобы показать, что я имею в виду. Обратите внимание, что если я установил две ширины столбца одинаковыми (например, 65 пикселей), тогда я получаю 131 для BOTH funcs. – Ernie

+0

Я использовал два метода: 1-й использует экранный инструмент координат 2-го, проверяя xml-файл рисунка внутри файла xlsx, который мой метод основан на обоих методах, дал мне тот же результат. в соответствии с этим источником http://officeopenxml.com/drwSp-size.php значения в теге 'xfrm' обозначают координаты и размер формы в ЭВС. – MusuNaji

0

Его не очень к сожалению. Вам действительно нужны функции GetPixelTop и GetPixelLeft в файле ExcelDrawingBase.cs, но они обозначены как internal: http://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)); 

я получаю левый и Top 141, и 43 для прикрепленного изображения.

enter image description here

+0

TY за помощью, я уже попробовал этот подход, но, к сожалению, не дает точные координаты «X», у меня есть форма, которая находится в (1045,451) пикселей с вышеизложенным я получаю различное значение x = 1067. – MusuNaji

+0

Зазор становится более ясным, когда x> 1000, я сделал еще один тест, который привел к 1895 году против реального 1853. – MusuNaji

+0

Как вы получили «настоящее»? Я пробовал то же самое с разной шириной столбцов на общую сумму более 1200, и обе функции возвращают одинаковые (правильные числа) на основе подсчета ширины столбцов в графическом интерфейсе. – Ernie