使用互操作制作组织结构图 excel

Make Org Chart with interop excel

我想创建一个 excel 工作表,其中包含组织结构图和来自数据库的数据。

我已经在 C# 控制台应用程序中使用互操作 excel 库,但我被卡住了。

我可以制作一个包含带有层次结构图布局(组织结构图)的 smartart 对象的工作表,但我不知道如何向其中添加我自己的数据。当您创建图表时,它带有下图所示的节点。

甚至可以通过互操作 excel 库将您自己的数据添加到图表中吗?

到目前为止,这是我的代码:

    private static Excel.Workbook Wb = null;
    private static Excel.Application Xl = null;
    private static Excel.Worksheet Sheet = null;

    static void Main(string[] args)
    {
        Xl = new Excel.Application();
        Xl.Visible = true;
        Wb = Xl.Workbooks.Add();
        Sheet = Wb.Worksheets[1];

        var myLayout = Xl.SmartArtLayouts[88];

        var smartArtShape = Sheet.Shapes.AddSmartArt(myLayout, 50, 50, 200, 200);

        smartArtShape.AlternativeText = "Test";

    }

这是结果:

是的,可以通过 "interop" 访问该功能 :-) 只是有点...神秘,尤其是对于那些不是来自 PowerPoint 的人。

由于 SmartArt 在 Shape 对象中 "wrapped",因此首先需要获取 Shape,然后通过它获取 SmartArt - Shape 对象具有 HasSmartArt(测试)和 SmartArt(使用)属性。

(注意,我发现显式声明对象type非常有用,而不是依赖var到"guess"。这对排除故障有很大帮助。)

实际内容("boxes")为Nodes。出于某种原因,PIA 不提供 Node 对象(但它们存在于 COM 对象模型中),因此在 C# 中访问它们有点迂回。要获取所有节点,请使用AllNodes 属性 到return 集合。

然后可以对 Node 对象进行寻址集合索引 nds[i]。可以将单个节点分配给 SmartArtNode 或 Office Shape 对象。为了本题的目的-添加文本-下一步是一样的...

"boxes" 本身就是办公绘图文本框 (Shapes),并且具有 TextFrame2.TextRange.Text 属性 来访问其内容。 (请注意,默认内容实际上是一个占位符,因此对于新创建的 SmartArt,此 属性 不会 return 任何内容。)

注意:问题中的代码尝试使用 AlternativeText - 这类似于 HTML 对象中的 "AltText",它提供可访问性信息并且与您的内容无关正在努力。

static void Main(string[] args)
{
    excelApp = new Excel.Application();
    excelApp.Visible = true;
    Excel.Workbook wb = excelApp.Workbooks.Add();
    Excel.Worksheet ws = (Excel.Worksheet) wb.Worksheets[1];

    var myLayout = excelApp.SmartArtLayouts[88];

    var smartArtShape = ws.Shapes.AddSmartArt(myLayout, 50, 50, 200, 200);

    if (smartArtShape.HasSmartArt == Office.MsoTriState.msoTrue)
    {
      Office.SmartArt smartArt = smartArtShape.SmartArt;
      Office.SmartArtNodes nds = smartArt.AllNodes;

      for (int i = 1; i <= nds.Count; i++)
      {
          Office.SmartArtNode nd = nds[i]; //both work
          var shpNode = nd.Shapes.Item(1);
          nd.TextFrame2.TextRange.Text = "Testing Node " + i;
          shpNode.TextFrame2.TextRange.Text = "Testing Shape " + i;
      }
    }
}