繁体   English   中英

PowerPoint幻灯片上的OpenXML自动刷新连接器

[英]OpenXML refresh connectors on a PowerPoint Slide automatically

我有一个简单的场景,其中我使用OpenXML SDK 2.5和c#以编程方式创建一个带有幻灯片的演示文稿。 幻灯片上有2种形状,还有一个连接这2种形状的连接器。

当我在PowerPoint中打开演示文稿时,会同时显示两个形状和连接器,但是连接器在两个形状之间的位置不正确。 当我在幻灯片上拖动一个形状时,PowerPoint立即刷新连接器并将其放置在正确的位置。

我的问题:是否可以创建一个openxml PowerPoint幻灯片,该幻灯片在打开文件时自动刷新连接器位置?

谢谢

我针对此问题想出的解决方案似乎有些破绽,但据我所知,没有更好的方法。 问题是PowerPoint内部控制了连接器的放置,并且没有公开任何刷新它们的方法。 在测试中,我惊讶地发现PowerPoint会在刷新期间根据需要动态更改连接器类型。

为了使刷新发生,我不得不在.pptm文件中编写一个VBA宏,然后从我的C#代码中调用它。 我添加了一个模块,并将函数放在那里,这样它就不会与特定的幻灯片相关联。

该代码在幻灯片上移动每种形状,以触发连接器刷新。 它也在组内寻找形状。 它正在过滤三角形和菱形形状。

我避免在代码中使用ActivePresentation,因为我想在宏运行时隐藏PowerPoint。

Public Sub FixConnectors()
    Dim mySlide As Slide
    Dim shps As Shapes
    Dim shp As Shape
    Dim subshp As Shape

    Set mySlide = Application.Presentations(1).Slides(1)
    Set shps = mySlide.Shapes

    For Each shp In shps
        If shp.AutoShapeType = msoShapeIsoscelesTriangle Or shp.AutoshapeType = msoShapeDiamond Then
            shp.Left = shp.Left + 0.01 - 0.01
        End If
        If shp.Type = mso.Group Then
            For Each subshp In shp.GroupItems
                If subshp.AutoShapeType = msoShapeIsoscelesTriangle Or subshp.AutoshapeType = msoShapeDiamond Then
                    subshp.Left = subshp.Left + 0.01 - 0.01
                End If
             Next subshp
        End If
    Next shp

    Application.Presentations(1).Save
End Sub

接下来是C#代码,以使用PowerPoint Interop运行宏。 作为Windows进程关闭并重新打开文件,垃圾回收器可以清理Interop拥有的所有句柄。 在测试中,终结器可能需要花费几秒钟来运行,因此GC调用在重新打开文件后发生,因此应用程序似乎没有挂起。

using System;
using System.Diagnostics;
using OC = Microsoft.Office.Core;
using PP = Microsoft.Office.Interop.PowerPoint;

string filePath = "C:/Temp/";
string fileName = "Template.pptm";

// Open PowerPoint in hidden mode, run the macro, and shut PowerPoint down
var pptApp = new PP.Application();
PP.Presentation presentation = pptApp.Presentations.Open(filePath + fileName, OC.MsoTriState.msoFalse, OC.MsoTriState.msoFalse, OC.MsoTriState.msoFalse);
pptApp.Run(filename + "!.FixConnectors");
presentation.Close();
presentation = null;
pptApp.Quit();
pptApp = null;

// Reopen the file through Windows
Process.Start(filePath + fileName);

// Clear all references to PowerPoint
GC.Collect();
GC.WaitForPendingFinalizers();
GC.Collect();
GC.WaitForPendingFinalizers();

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM