开发人员技术 | C#
一种面向对象的类型安全的编程语言,它起源于 C 语言系列,包括对面向组件的编程的支持。
我正在开发一个使用 VSTO 分析 PowerPoint 演示文稿并将其转换为 JSON 格式的 C# 应用程序。大多数元素(文本框、自定义形状等)都能正常工作,但我在检测嵌套组时遇到了问题。
VSTO 无法捕获 PowerPoint 幻灯片中的嵌套组。例如以下结构:
Group1:
├── Group2:
│ ├── Rectangle1
│ ├── Rectangle2
│ └── Line (connecting Rectangle1 and Rectangle2)
└── Group3:
├── Rectangle3
└── Rectangle4
ppt 演示如下:
ppt 对应 slide.xml 如下
<!--
Source - https://stackoverflow.com/questions/79809551/how-to-detect-nested-groups-in-powerpoint-using-vsto-c
Posted by D.Galaxy
Retrieved 2025/11/5, License - CC-BY-SA 4.0
-->
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<p:sld xmlns:a="http://schemas.openxmlformats.org/drawingml/2006/main" xmlns:r="http://schemas.openxmlformats.org/officeDocument/2006/relationships" xmlns:p="http://schemas.openxmlformats.org/presentationml/2006/main">
<p:cSld>
<p:spTree>
<p:nvGrpSpPr>
<p:cNvPr id="1" name="" />
<p:cNvGrpSpPr />
<p:nvPr />
</p:nvGrpSpPr>
<p:grpSpPr>
<a:xfrm>
<a:off x="0" y="0" />
<a:ext cx="0" cy="0" />
<a:chOff x="0" y="0" />
<a:chExt cx="0" cy="0" />
</a:xfrm>
</p:grpSpPr>
<p:grpSp>
<p:nvGrpSpPr>
<p:cNvPr id="14" name="group 13" />
<p:cNvGrpSpPr />
<p:nvPr />
</p:nvGrpSpPr>
<p:grpSpPr>
<a:xfrm>
<a:off x="1515291" y="1828800" />
<a:ext cx="5486400" cy="3422469" />
<a:chOff x="1515291" y="1828800" />
<a:chExt cx="5486400" cy="3422469" />
</a:xfrm>
</p:grpSpPr>
<p:grpSp>
<p:nvGrpSpPr>
<p:cNvPr id="12" name="group 11" />
<p:cNvGrpSpPr />
<p:nvPr />
</p:nvGrpSpPr>
<p:grpSpPr>
<a:xfrm>
<a:off x="1515291" y="1828800" />
<a:ext cx="5486400" cy="1410789" />
<a:chOff x="1515291" y="1828800" />
<a:chExt cx="5486400" cy="1410789" />
</a:xfrm>
</p:grpSpPr>
<p:sp>
<p:nvSpPr>
<p:cNvPr id="4" name="rectangle 3" />
<p:cNvSpPr />
<p:nvPr />
</p:nvSpPr>
<p:spPr>
<a:xfrm>
<a:off x="1515291" y="1828800" />
<a:ext cx="2011680" cy="1410789" />
</a:xfrm>
<a:prstGeom prst="rect">
<a:avLst />
</a:prstGeom>
</p:spPr>
<p:style>
<a:lnRef idx="2">
<a:schemeClr val="accent1">
<a:shade val="50000" />
</a:schemeClr>
</a:lnRef>
<a:fillRef idx="1">
<a:schemeClr val="accent1" />
</a:fillRef>
<a:effectRef idx="0">
<a:schemeClr val="accent1" />
</a:effectRef>
<a:fontRef idx="minor">
<a:schemeClr val="lt1" />
</a:fontRef>
</p:style>
<p:txBody>
<a:bodyPr rtlCol="0" anchor="ctr" />
<a:lstStyle />
<a:p>
<a:pPr algn="ctr" />
<a:endParaRPr lang="zh-CN" altLang="en-US" />
</a:p>
</p:txBody>
</p:sp>
<p:sp>
<p:nvSpPr>
<p:cNvPr id="5" name="rectangle 4" />
<p:cNvSpPr />
<p:nvPr />
</p:nvSpPr>
<p:spPr>
<a:xfrm>
<a:off x="4990011" y="1828800" />
<a:ext cx="2011680" cy="1410789" />
</a:xfrm>
<a:prstGeom prst="rect">
<a:avLst />
</a:prstGeom>
</p:spPr>
<p:style>
<a:lnRef idx="2">
<a:schemeClr val="accent1">
<a:shade val="50000" />
</a:schemeClr>
</a:lnRef>
<a:fillRef idx="1">
<a:schemeClr val="accent1" />
</a:fillRef>
<a:effectRef idx="0">
<a:schemeClr val="accent1" />
</a:effectRef>
<a:fontRef idx="minor">
<a:schemeClr val="lt1" />
</a:fontRef>
</p:style>
<p:txBody>
<a:bodyPr rtlCol="0" anchor="ctr" />
<a:lstStyle />
<a:p>
<a:pPr algn="ctr" />
<a:endParaRPr lang="zh-CN" altLang="en-US" />
</a:p>
</p:txBody>
</p:sp>
<p:cxnSp>
<p:nvCxnSpPr>
<p:cNvPr id="8" name="Direct arrow connector 7" />
<p:cNvCxnSpPr>
<a:stCxn id="4" idx="3" />
<a:endCxn id="5" idx="1" />
</p:cNvCxnSpPr>
<p:nvPr />
</p:nvCxnSpPr>
<p:spPr>
<a:xfrm>
<a:off x="3526971" y="2534195" />
<a:ext cx="1463040" cy="0" />
</a:xfrm>
<a:prstGeom prst="straightConnector1">
<a:avLst />
</a:prstGeom>
<a:ln>
<a:tailEnd type="triangle" />
</a:ln>
</p:spPr>
<p:style>
<a:lnRef idx="1">
<a:schemeClr val="accent1" />
</a:lnRef>
<a:fillRef idx="0">
<a:schemeClr val="accent1" />
</a:fillRef>
<a:effectRef idx="0">
<a:schemeClr val="accent1" />
</a:effectRef>
<a:fontRef idx="minor">
<a:schemeClr val="tx1" />
</a:fontRef>
</p:style>
</p:cxnSp>
</p:grpSp>
<p:grpSp>
<p:nvGrpSpPr>
<p:cNvPr id="13" name="group 12" />
<p:cNvGrpSpPr />
<p:nvPr />
</p:nvGrpSpPr>
<p:grpSpPr>
<a:xfrm>
<a:off x="1515291" y="3840480" />
<a:ext cx="4754880" cy="1410789" />
<a:chOff x="1515291" y="3840480" />
<a:chExt cx="4754880" cy="1410789" />
</a:xfrm>
</p:grpSpPr>
<p:sp>
<p:nvSpPr>
<p:cNvPr id="10" name="rectangle 9" />
<p:cNvSpPr />
<p:nvPr />
</p:nvSpPr>
<p:spPr>
<a:xfrm>
<a:off x="1515291" y="3840480" />
<a:ext cx="2011680" cy="1410789" />
</a:xfrm>
<a:prstGeom prst="rect">
<a:avLst />
</a:prstGeom>
</p:spPr>
<p:style>
<a:lnRef idx="2">
<a:schemeClr val="accent1">
<a:shade val="50000" />
</a:schemeClr>
</a:lnRef>
<a:fillRef idx="1">
<a:schemeClr val="accent1" />
</a:fillRef>
<a:effectRef idx="0">
<a:schemeClr val="accent1" />
</a:effectRef>
<a:fontRef idx="minor">
<a:schemeClr val="lt1" />
</a:fontRef>
</p:style>
<p:txBody>
<a:bodyPr rtlCol="0" anchor="ctr" />
<a:lstStyle />
<a:p>
<a:pPr algn="ctr" />
<a:endParaRPr lang="zh-CN" altLang="en-US" />
</a:p>
</p:txBody>
</p:sp>
<p:sp>
<p:nvSpPr>
<p:cNvPr id="11" name="rectangle 10" />
<p:cNvSpPr />
<p:nvPr />
</p:nvSpPr>
<p:spPr>
<a:xfrm>
<a:off x="4258491" y="3840480" />
<a:ext cx="2011680" cy="1410789" />
</a:xfrm>
<a:prstGeom prst="rect">
<a:avLst />
</a:prstGeom>
</p:spPr>
<p:style>
<a:lnRef idx="2">
<a:schemeClr val="accent1">
<a:shade val="50000" />
</a:schemeClr>
</a:lnRef>
<a:fillRef idx="1">
<a:schemeClr val="accent1" />
</a:fillRef>
<a:effectRef idx="0">
<a:schemeClr val="accent1" />
</a:effectRef>
<a:fontRef idx="minor">
<a:schemeClr val="lt1" />
</a:fontRef>
</p:style>
<p:txBody>
<a:bodyPr rtlCol="0" anchor="ctr" />
<a:lstStyle />
<a:p>
<a:pPr algn="ctr" />
<a:endParaRPr lang="zh-CN" altLang="en-US" />
</a:p>
</p:txBody>
</p:sp>
</p:grpSp>
</p:grpSp>
</p:spTree>
<p:extLst>
<p:ext uri="{BB962C8B-B14F-4D97-AF65-F5344CB8AC3E}">
<p14:creationId xmlns:p14="http://schemas.microsoft.com/office/powerpoint/2010/main" val="1958624764" />
</p:ext>
</p:extLst>
</p:cSld>
<p:clrMapOvr>
<a:masterClrMapping />
</p:clrMapOvr>
</p:sld>
当前结果:
{
"group1": {
"child_elements": [
"rectangle1",
"rectangle2",
"line1",
"rectangle3",
"rectangle4"
]
}
}
预期结果:
注意: 我已验证 python-pptx 可以成功检测并解析这些嵌套的组关系,因此数据存在于文件结构中。
一种潜在的方法是直接解析 PowerPoint XML 文件(类似于 python-pptx 的工作方式)以提取组关系。但是,这需要:
是否存在我遗漏的用于检测 PowerPoint 中嵌套组的 VSTO API 或方法?或者直接解析 XML 是唯一可行的解决方案?
代码示例(如有需要):
一种面向对象的类型安全的编程语言,它起源于 C 语言系列,包括对面向组件的编程的支持。