解析OpenXml Pptx的边框虚线转为WPF的边框虚线问题

 更新时间:2021年12月29日 08:33:47   作者:RyzenAdorer  
这篇文章主要介绍了OpenXml Pptx的边框虚线转为WPF的边框虚线,在文中用PPTX的7种直线,分别设置7种能够设置的虚线类型,具体实例代码跟随小编一起看看吧

安装Openxml sdk

首先,我们先安装nuget的需要的有关的Openxml sdk,我们开源了解析pptx的Openxml拍平层,下面两种方式都可以安装:

nuget包管理器控制台:

Install-Package dotnetCampus.DocumentFormat.OpenXml.Flatten -Version 2.0.0

csproj引用:

<PackageReference Include="dotnetCampus.DocumentFormat.OpenXml.Flatten" Version="2.0.0" />

解析Pptx

我这里用PPTX的7种直线,分别设置7种能够设置的虚线类型,PPTX的显示效果是这样的:

然后解析代码如下,解析主要逻辑部分:

        private void PptxToGeometry(string filePath)
        {
            if (!File.Exists(filePath) || !filePath.EndsWith(".pptx", StringComparison.OrdinalIgnoreCase))
            {
                return;
            }

            var lines = new List<Line>();
            using var presentationDocument = PresentationDocument.Open(filePath, false);
            var presentationPart = presentationDocument.PresentationPart;
            var presentation = presentationPart?.Presentation;
            var slideIdList = presentation?.SlideIdList;
            if (slideIdList == null)
            {
                return;
            }
            foreach (var slideId in slideIdList.ChildElements.OfType<SlideId>())
            {
                var slidePart = (SlidePart)presentationPart.GetPartById(slideId.RelationshipId);
                var slide = slidePart.Slide;
                foreach (var shapeProperties in slide.Descendants<ShapeProperties>())
                {
                    var presetGeometry = shapeProperties.GetFirstChild<PresetGeometry>();
                    if (presetGeometry != null && presetGeometry.Preset.HasValue)
                    {
                        if (presetGeometry.Preset == ShapeTypeValues.StraightConnector1)
                        {
                            var transform2D = shapeProperties.GetFirstChild<Transform2D>();
                            var extents = transform2D?.GetFirstChild<Extents>();
                            if (extents != null)
                            {
                                var width = new Emu(extents.Cx!.Value).ToPixel().Value;
                                var height = new Emu(extents.Cy!.Value).ToPixel().Value;


                                var presetDash = shapeProperties.GetFirstChild<Outline>()?.GetFirstChild<PresetDash>()?.Val;
                                var dashArray = GetDashArrayByPresetLineDashValues(presetDash);
                                var line = ConverterToGeometry( width, height, dashArray); 
                                lines.Add(line);
                            }
                        }
                    }
                }
            }

            this.ListBox.ItemsSource = lines;
        }

PPTX映射成WPF虚线的方法:

        private DoubleCollection GetDashArrayByPresetLineDashValues(PresetLineDashValues presetLineDashValues)
        {
            DoubleCollection dashStyle = presetLineDashValues switch
            {
                PresetLineDashValues.Solid => new(),
                PresetLineDashValues.Dot => new() { 0, 2 },
                PresetLineDashValues.Dash => new() { 3, 3 },
                PresetLineDashValues.LargeDash => new() { 8, 3 },
                PresetLineDashValues.DashDot => new() { 3, 3, 1, 3 },
                PresetLineDashValues.LargeDashDot => new() { 7.5, 3.5, 1, 3.5 },
                PresetLineDashValues.LargeDashDotDot => new() { 8, 3, 1, 3, 1, 3 },
                PresetLineDashValues.SystemDash => new() { 3, 1 },
                PresetLineDashValues.SystemDot => new() { 1, 1 },
                PresetLineDashValues.SystemDashDot => new() { 2, 2, 0, 2 },
                PresetLineDashValues.SystemDashDotDot => new() { 2, 2, 0, 2 },
                _ => new DoubleCollection()
            };
            return dashStyle;
        }

最终绘制线条的方法:

        private Line ConverterToGeometry(double width, double height, DoubleCollection dashDoubleCollection)
        {
            var line = new Line
            {
                X1 = 0,
                Y1 = 0,
                X2 = width,
                Y2 = height,
                StrokeDashArray = dashDoubleCollection,
                Stroke = Stroke,
                StrokeThickness = StrokeThickness
            };
            return line;
        }

最终的效果:

我们可以看到几乎是接近的效果了,当然你也可以根据我的代码去微调更精确的值,只需要稍微改下GetDashArrayByPresetLineDashValues方法内相对应的值即可

后话

实际上,openxml文档是给出了PresetDash的值的,大致如下:

但是其值跟WPF的设置Dash的DoubleCollection不对应,因此以上的映射值都是我自己微调的

源码

BlogCodeSample/PptDashConverToWpfSample at main · ZhengDaoWang/BlogCodeSample

到此这篇关于OpenXml Pptx的边框虚线转为WPF的边框虚线的文章就介绍到这了,更多相关Pptx边框虚线转为WPF的边框虚线内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • C#异常处理的最佳实践与内存模型深度剖析

    C#异常处理的最佳实践与内存模型深度剖析

    C#提供了强大的异常处理机制,它帮助开发者捕获并响应运行时的错误,然而,异常的处理不仅仅是捕获错误,它还需要合理的策略来确保代码的性能、可维护性和可靠性,本文将深入探讨C#异常处理的最佳实践,如何有效记录日志,避免性能损失,并对C#的内存模型做详细解析
    2025-01-01
  • C#实现获取磁盘空间大小的方法

    C#实现获取磁盘空间大小的方法

    这篇文章主要介绍了C#实现获取磁盘空间大小的方法,分别基于System.IO.DriveInfo.GetDrives方法与ManagementClass("Win32_LogicalDisk")来实现这一功能,是非常实用的技巧,需要的朋友可以参考下
    2014-12-12
  • C#中限制并发任务数量的高效方法与技巧分享

    C#中限制并发任务数量的高效方法与技巧分享

    在C#中,处理并发操作是一项常见且强大的功能,尤其是在需要执行多个任务但又希望限制同时运行任务数量的场景中,本文将深入探讨几种有效的方法来限制C#中的并发任务数量,并通过具体的应用场景和示例代码展示如何实现这些方法,需要的朋友可以参考下
    2024-12-12
  • C#实现Socket服务器及多客户端连接的方式

    C#实现Socket服务器及多客户端连接的方式

    这篇文章介绍了C#实现Socket服务器及多客户端连接的方式,文中通过示例代码介绍的非常详细。对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下
    2022-01-01
  • C#多线程学习之Thread、ThreadPool、Task、Parallel四者区别

    C#多线程学习之Thread、ThreadPool、Task、Parallel四者区别

    这篇文章主要以一些简单的小例子,简述多线程的发展历程:Thread,ThreadPool,Task,Parallel。文中的示例代码讲解详细,对我们学习C#多线程有一定帮助,需要的朋友可以参考一下
    2021-12-12
  • C# winform实现中英文切换功能的四种方式

    C# winform实现中英文切换功能的四种方式

    这篇文章主要介绍了在C# winform应用程序中实现中英文切换功能的四种方式,资源文件(Resources),本地化(Localization),动态设置控件字体和切换语言环境这四种方式,下面将详细介绍每种方式及其具体实现,并讨论它们的优缺点,需要的朋友可以参考下
    2024-04-04
  • C#如何检测操作系统版本

    C#如何检测操作系统版本

    这篇文章主要为大家详细介绍了C#如何检测操作系统版本的相关资料,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2016-10-10
  • C#中类与结构的区别实例分析

    C#中类与结构的区别实例分析

    这篇文章主要介绍了C#中类与结构的区别,类与结构是C#初学者比较轻易混淆的概念,本文加以实例说明,需要的朋友可以参考下
    2014-08-08
  • C#中Winform窗体Form的关闭按钮变灰色的方法

    C#中Winform窗体Form的关闭按钮变灰色的方法

    这篇文章主要介绍了C#中Winform窗体Form的关闭按钮变灰色的方法,对于C#程序界面的设计有一定的借鉴价值,需要的朋友可以参考下
    2014-08-08
  • C# WinForm调用Shell_NotifyIcon的示例代码

    C# WinForm调用Shell_NotifyIcon的示例代码

    这篇文章主要介绍了C# WinForm调用Shell_NotifyIcon的示例代码,帮助大家更好的理解和使用c#,感兴趣的朋友可以了解下
    2020-11-11

最新评论