Неужели кому-нибудь удалось получить координату x и y в пикселях формы или изображения на листе в файле excel 2010, используя epplus ?Как получить координаты фигуры/изображения в пикселях в файле excel (xlsx) с помощью EPPlus
ответ
я, наконец, нашли решение с использованием данных внутреннего 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);
}
Его не очень к сожалению. Вам действительно нужны функции 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 для прикрепленного изображения.
TY за помощью, я уже попробовал этот подход, но, к сожалению, не дает точные координаты «X», у меня есть форма, которая находится в (1045,451) пикселей с вышеизложенным я получаю различное значение x = 1067. – MusuNaji
Зазор становится более ясным, когда x> 1000, я сделал еще один тест, который привел к 1895 году против реального 1853. – MusuNaji
Как вы получили «настоящее»? Я пробовал то же самое с разной шириной столбцов на общую сумму более 1200, и обе функции возвращают одинаковые (правильные числа) на основе подсчета ширины столбцов в графическом интерфейсе. – Ernie
Откуда у вас это фактическое число (1045 451)? Когда я запускаю вашу функцию против файла excel, который я создал с помощью одного рисунка, на самом деле это немного немного. В моем тесте моя func дает ширину 140, в то время как ваш дает 131. Я помещал картинку как раз в негладкой Col C, и если я подсчитываю ширину Cols A и B в самом Excel, я получаю 137. Разница в 3 пикселя выглядит правильно для разрыв между началом Col C и изображением. Я обновил свой пост, чтобы показать, что я имею в виду. Обратите внимание, что если я установил две ширины столбца одинаковыми (например, 65 пикселей), тогда я получаю 131 для BOTH funcs. – Ernie
Я использовал два метода: 1-й использует экранный инструмент координат 2-го, проверяя xml-файл рисунка внутри файла xlsx, который мой метод основан на обоих методах, дал мне тот же результат. в соответствии с этим источником http://officeopenxml.com/drwSp-size.php значения в теге 'xfrm' обозначают координаты и размер формы в ЭВС. – MusuNaji