【OpenXml】Pptx的边框虚线转为WPF的边框虚线
2023-04-18 16:50:20 时间
安装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
相关文章
- 微软.NET 5.1迎来RC1版本 开发者已可上线尝鲜
- 速度和性能狂卷,.NET 7有多少人买单
- 风云再续:他抖任他抖,IO诊断在我手
- 在开源社区的强烈抗议下 微软逆转了有争议的.NET变化
- Windows 11 的 Microsoft Store 上架 Visual Studio
- 微软:.NET 平台采用率的提升归功于开源
- 从文件下载视角来理解Web API
- 你以为的ASP.NET文件上传大小限制是你以为的吗
- 在Ubuntu中搭建.NET开发环境
- gRPC入门与实操(.NET篇)
- Rails MVC 和 CRUD(1)
- FANUC机器人PROFINET双通道板卡组态
- 网络IO
- 开源自己编写的半人工标注平台PaddleOCRLabel(.NET Winform版本)
- 还在死磕Ajax,不如看看Fetch ?
- 【ASP.NET Core】动态映射MVC路由
- 【ASP.NET Core】用配置文件来设置授权角色
- 【ASP.NET Core】按用户等级授权
- 【ASP.NET Core】自定义Session的存储方式
- 【ASP.NET Core】选项类的依赖注入