2016-04-06 158 views

答えて

0

私は最終的に内部XMLデータを使用して解決策を見つけ、Excelがequal to 1/9525 pixelあるEMUと呼ばれるメジャーの単位を使用しているようです。ソリューションは

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)を取得しましたか?あなたが1つの写真で作ったExcelファイルに対してあなたの機能を実行すると、あなたは実際に少し短くなります。私のテストでは、私の関数は、あなたの131を与える間に140の幅を与える。私は写真をちょうどCol Cを入れて、Excel AのCols AとBの幅を数えれば137になる.3ピクセルの違いは、 Col Cの開始点と画像との間のギャップ。私は自分の投稿を更新して、私の言いたいことを示しました。 2つの列の幅を同じ(たとえば65 px)に設定すると、両方の機能が131になることに注意してください。 – Ernie

+0

私は2つの方法を使いました。第1は画面上の座標ツールを使用しています。xlsxファイル内の図面xmlファイルをチェックして、私の方法は両方の方法に基づいています。このソースhttp://officeopenxml.com/drwSp-size.phpによると、 'xfrm'タグの値は、EMU内の図形の座標とサイズを指定します。 – MusuNaji

0

それはかなり残念です。あなたが本当に必要とする機能は、ファイルExcelDrawingBase.csGetPixelTopGetPixelLeftですが、internalhttp://epplus.codeplex.com/SourceControl/latest#EPPlus/Drawing/ExcelDrawingBase.csとマークされています。ソースコードを変更せずに実際に呼び出すことはできません。

最も単純なのは、自分のバージョンを再作成することです。

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; 
} 

そして、あなたはこのようにそれを使用することができます:ここでは簡単カット/ペースト(生産井に行く前に、必ずQA作る)である

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添付画像用。

enter image description here

+0

TY、私はすでにこのアプローチを試しましたが、残念なことに 'X'の正確な座標を与えていない、私は上記の(1045,451)ピクセルに位置している形状を持っています異なる値x = 1067。 – MusuNaji

+0

x> 1000の場合、ギャップがより明確になり、1895年と1853年の結果を生み出す別のテストが行​​われました。 – MusuNaji

+0

どのようにして「本当の」結果が得られましたか?私は同じ列幅を1200を超えて合計し、両方の関数がGUIの列幅をカウントすることに基づいて同じ(正しい数)を返すようにしました。 – Ernie

関連する問題