123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527 |
- using DocumentFormat.OpenXml;
- using DocumentFormat.OpenXml.Packaging;
- using DocumentFormat.OpenXml.Presentation;
- using HTEXLib.Animations;
- using HTEXLib.Builders;
- using HTEXLib.Models.Inner;
- using System;
- using System.Collections.Generic;
- using System.Linq;
- using System.Text;
- using System.Xml.Linq;
- namespace HTEXLib.Models
- {
- public class PPTSlide:PPTShapeBase
- {
- public PPTSlide(SlidePart openXmlPart, int slideIndex, DefaultTextStyle defaultTextStyle,SlideSize SlideSizes, SlideMasterPart slideMasterPart, XElement root,IEnumerable<XElement> media,TableStylesPart tableStylesPart)
- {
-
- base.tableStylesPart = tableStylesPart;
- base.SlidePart = openXmlPart;
- base.slideMasterPart = slideMasterPart;
- base.Root = root;
- base.Media = media;
- this.advanceAfterTime = -1;
- this.slideIndex = slideIndex;
- // this.fileName = fileName;
- this.defaultTextStyle = defaultTextStyle;
- SlideLayoutPart = openXmlPart.SlideLayoutPart;
- SetShapeNonVisualProperties(openXmlPart);
- SetSpecificProperties(openXmlPart);
- SetSpecificProperties(SlideLayoutPart);
- SetBackground(openXmlPart, slideMasterPart);
- Id = "s1s0";
- //页面过渡 切换 https://docs.microsoft.com/zh-cn/dotnet/api/documentformat.openxml.presentation.transition?view=openxml-2.8.1
- Transition transition = openXmlPart.Slide.Transition;
-
- if (transition == null) {
- transition= openXmlPart.Slide.Descendants<DocumentFormat.OpenXml.Presentation.Transition>().FirstOrDefault();
- }
- Transition = JSONGenerator.GenerateTransitionAnimationObject(transition);
- Animations = new List<IAnimation>();
- animtimes = new List<Animtime>();
- // AddAnimations(openXmlPart.Slide.Timing, Animations, SlideSizes);
- // AddAnimations(openXmlPart.SlideLayoutPart.SlideLayout.Timing, Animations, SlideSizes);
- // AddAnimations(slideMasterPart.SlideMaster.Timing, Animations, SlideSizes);
- //播放母版的动画
- AddTimings(slideMasterPart.SlideMaster.Timing, animtimes, SlideSizes);
- //播放样式表的动画
- AddTimings(openXmlPart.SlideLayoutPart.SlideLayout.Timing, animtimes, SlideSizes);
- //播放单页动画
- AddTimings(openXmlPart.Slide.Timing, animtimes, SlideSizes);
- List<NonVisualDrawingProperties> nonVisualDrawingProperties = ((SlidePart)this.SlidePart).Slide.Descendants<NonVisualDrawingProperties>().ToList();
- animtimes.ForEach(x => {
- NonVisualDrawingProperties nonVisualDrawing= nonVisualDrawingProperties.Where(y => y.Id == x.targetId).FirstOrDefault();
- if (nonVisualDrawing != null) {
- x.text = nonVisualDrawing.Parent.Parent.InnerText;
- }
- });
- //TODO 处理layout 及 master 的 Transition Timing。
- //master 和 layout 过渡效果直接覆盖给slide
- IAnimation transition_animation = AddTransition(openXmlPart.Slide.Transition, "slide");
- // IAnimation layout_transition = AddTransition(openXmlPart.SlideLayoutPart.SlideLayout.Transition, "layout");
- // IAnimation master_transition = AddTransition(slideMasterPart.SlideMaster.Transition, "master");
-
- }
- private void SetBackground(SlidePart slidePart, SlideMasterPart slideMasterPart)
- {
- background= slidePart.Slide.CommonSlideData.Background;
- backgroundFrom = "slide";
- if (background == null) {
- backgroundFrom = "layout";
- background = slidePart.SlideLayoutPart.SlideLayout.CommonSlideData.Background;
- }
- if (background == null) {
- backgroundFrom = "master";
- background = slideMasterPart.SlideMaster.CommonSlideData.Background;
- }
- }
- public List<string> lazyFiles { get; set; } = new List<string>();
- public Background background { get; set; }
- public string backgroundFrom { get; set; }
- //Slide specific properties
- public DefaultTextStyle defaultTextStyle { get; set; }
- public PPTContainerShape ContainerShape { get; set; } = new PPTContainerShape();
- public TextStyles textStyles { get; set; }
- public SlideLayoutPart SlideLayoutPart { get; set; }
- public List<Animtime> animtimes { get; set; }
- public List<IAnimation> Animations { get; set; }
- public string Id { get; set; }
- public IAnimation Transition { get; set; }
- public int slideIndex;
- // public string fileName;
- public int advanceAfterTime { get; set; }
- //Petco:Check if there is objects with animation.
- public void CheckAndSetAnimatableProperty(string animObjectId)
- {
- int tryParse = 0;
- if (int.TryParse(animObjectId, out tryParse))
- {
- foreach (PPTShapeBase shape in ContainerShape.Elements)
- SetAnimatable(animObjectId, shape);
- }
- else
- {
- foreach (PPTShapeBase shapeBase in ContainerShape.Elements)
- if (typeof(PPTShape).Equals(shapeBase.GetType()) && ((PPTShape)shapeBase).IsText)
- foreach (PPTParagraph text in ((PPTShape)shapeBase).Texts)
- {
- if ((shapeBase.NonVisualShapeProp.Id + "p" + text.Paragraph).Equals("s1s" + animObjectId))
- {
- text.Animatable = true;
- }
- }
- }
- }
- private static void SetAnimatable(string animObjectId, PPTShapeBase bshape)
- {
- string shapeId = bshape.NonVisualShapeProp.Id;
- string shapeObjectId = "s1s" + animObjectId;
- if (shapeId.Equals(shapeObjectId))
- {
- bshape.Animatable = true;
- }
- }
- private void SetShapeNonVisualProperties(SlidePart slidePart)
- {
- var nonVisualShapeProp = new PPTNonVisualShapeProp
- {
- Id = "s1s1",
- Name = slidePart.Slide.LocalName,
- Type = "PPTSlide"
- };
- base.NonVisualShapeProp = nonVisualShapeProp;
- }
- private void SetSpecificProperties(SlidePart slidePart)
- {
- textStyles = slidePart.SlideLayoutPart.SlideMasterPart.SlideMaster.TextStyles;
- var groupShapeBuilder = new PPTContainerShapeBuilder();
- var elms = groupShapeBuilder.GetPPTContainerShape(slidePart, this).Elements;
- if (elms != null) {
- ContainerShape.Elements.AddRange(elms);
- }
-
- }
- private void SetSpecificProperties(SlideLayoutPart slideLayoutPart)
- {
- textStyles = SlideLayoutPart.SlideMasterPart.SlideMaster.TextStyles;
- var groupShapeBuilder = new PPTContainerShapeBuilder();
- var elms = groupShapeBuilder.GetPPTContainerShape(slideLayoutPart, this).Elements;
- if (elms != null)
- {
- ContainerShape.Elements.AddRange(elms);
- }
- }
- public void MakeShapeInvisible(String shapeId)
- {
- foreach (PPTShapeBase shape in ContainerShape.Elements)
- if (("s1s" + shape.NonVisualShapeProp.TimingId).Equals(shapeId))
- {
- shape.Invisible = true;
- return;
- }
- else if (typeof(PPTShape).Equals(shape.GetType()) && ((PPTShape)shape).IsText)
- {
- foreach (PPTParagraph text in ((PPTShape)shape).Texts)
- if ((shape.NonVisualShapeProp.TimingId + "p" + text.Paragraph).Equals(shapeId))
- {
- text.Invisible = true;
- return;
- }
- }
- }
- private void AddTimings(OpenXmlCompositeElement element, List<Animtime> resultList, SlideSize SlideSizes)
- {
- if (element == null)
- return;
- Animtime animationForThisNode = null;
- if (element.GetType().Equals(typeof(CommonTimeNode)))
- {
-
- CommonTimeNode node = (CommonTimeNode)element;
- animationForThisNode = new AnimtimeGenerator(this).GetAnimtimeByCommonTimeNode(node);
- if (animationForThisNode != null) {
-
- resultList.Add(animationForThisNode);
- }
- }
- foreach (OpenXmlElement obj in element.ChildElements)
- {
- if (obj.GetType().IsSubclassOf(typeof(OpenXmlCompositeElement)))
- {
- if (animationForThisNode == null)
- AddTimings((OpenXmlCompositeElement)obj, resultList, SlideSizes);
- else {
- // AddTimings((OpenXmlCompositeElement)obj, animationForThisNode.InnerAnimations, SlideSizes);
- }
- }
- }
- }
-
- public void AddAnimations(OpenXmlCompositeElement element, List<IAnimation> resultList, SlideSize SlideSizes)
- {
- if (element == null)
- return;
- List<AnimateMotion> motions = new List<AnimateMotion>();
- IAnimation animationForThisNode = null;
- if (element.GetType().Equals(typeof(CommonTimeNode)))
- {
- CommonTimeNode node = (CommonTimeNode)element;
- animationForThisNode = new JSONGenerator(this).getSimpleAnimationFromCommonTimeNodePreset(node, SlideSizes);
- if (animationForThisNode != null)
- {
- resultList.Add(animationForThisNode);
- //Check if object id is presented in animation list.
- CheckAndSetAnimatableProperty(animationForThisNode.ObjectId);
- if ((animationForThisNode.InnerAnimations == null ||
- animationForThisNode.InnerAnimations.Count == 0) &&
- animationForThisNode.IsItEntranceAnimation())
- MakeShapeInvisible("s1s" + animationForThisNode.ObjectId);
- else if (animationForThisNode.InnerAnimations != null)
- foreach (IAnimation anAnimation in animationForThisNode.InnerAnimations)
- if (anAnimation.IsItEntranceAnimation())
- MakeShapeInvisible("s1s" + animationForThisNode.ObjectId);
- return;
- }
- else
- {
- /*
- * Sometimes there are common time nodes without animations in them. They are used for grouping animations.
- * Usually animations are grouped for timing purposes like adding delay to all, or start a group after another.
- * It's a tree structure and here we try to follow it as much as possible. Later we will strip the unnecessary nodes
- */
- animationForThisNode = new SimpleAnimation();
- if (node.NodeType != null)
- ((SimpleAnimation)animationForThisNode).timingType = node.NodeType;
- int delay = 0;
- if (node.StartConditionList != null)
- foreach (Condition cond in node.StartConditionList)
- if (cond.Delay != null && "indefinite" != cond.Delay.Value && cond.Delay.HasValue)
- delay = delay + int.Parse(cond.Delay.Value);
- if (delay > 0)
- {
- animationForThisNode.Start = delay;
- }
- }
- if (animationForThisNode != null)
- {
- animationForThisNode.InnerAnimations = new List<IAnimation>();
- resultList.Add(animationForThisNode);
- }
- }
- //Go recursive in the Open XML tree
- foreach (OpenXmlElement obj in element.ChildElements)
- {
- if (obj.GetType().IsSubclassOf(typeof(OpenXmlCompositeElement)))
- {
- if (animationForThisNode == null)
- AddAnimations((OpenXmlCompositeElement)obj, resultList, SlideSizes);
- else
- AddAnimations((OpenXmlCompositeElement)obj, animationForThisNode.InnerAnimations, SlideSizes);
- }
- }
- }
- private IAnimation AddTransition(Transition trans,string partForm)
- {
- if (trans == null || trans.FirstChild == null)
- return null;
- TransitionAnimation result = new TransitionAnimation();
- if (trans.Speed != null && TransitionSpeedValues.Fast.Equals(trans.Speed.Value))
- result.Length = 500;
- if (trans.Speed != null && TransitionSpeedValues.Medium.Equals(trans.Speed.Value))
- result.Length = 1000;
- else if (trans.Speed != null && TransitionSpeedValues.Slow.Equals(trans.Speed.Value))
- result.Length = 2000;
- //用于播放 设置持续时长
- else if (trans.Duration != null)
- result.Length = int.Parse(trans.Duration.Value);
- else
- result.Length = 1000;
- result.Start = 0;
- result.InitialState = -1;
- result.Repetitions = 1;
- //指定鼠标单击是否推进幻灯片。如果未指定此属性,则假设值为true。
- if (trans.AdvanceOnClick != null)
- result.AdvanceOnClick = trans.AdvanceOnClick.Value;
- else result.AdvanceOnClick = true;
- //advTm小于 动画总时长 以动画总时长为准
- //当前页动画时长 |___ _____ ______ __|
- //当前页advTm时长 |________________|
- //advTm大于 动画总时长,以advTm 时长为准,动画间隔被平均
- //当前页动画时长 |___ _____ ______ __|
- //当前页advTm时长 |_________________________|
- if (trans.AdvanceAfterTime != null) {
- result.advTm = int.Parse(trans.AdvanceAfterTime.Value);
- }
- if (typeof(DocumentFormat.OpenXml.Presentation.BlindsTransition) == trans.FirstChild.GetType()) {
- var child = trans.GetFirstChild<BlindsTransition>();
- result.Type = AnimationTypes.Blinds;
- //§19.5.18
- //Horizontal = 0, horz Vertical = 1 vert
- result.typeExt = new Dictionary<string, object>() { { result.Type, child.Direction } };
- }
- else if (typeof(DocumentFormat.OpenXml.Presentation.CheckerTransition) == trans.FirstChild.GetType()) {
- var child = trans.GetFirstChild<CheckerTransition>();
- result.Type = AnimationTypes.Checker;
- // §19.5.24
- //Horizontal = 0, horz Vertical = 1 vert
- result.typeExt = new Dictionary<string, object>() { { result.Type, child.Direction } };
- }
- else if (typeof(DocumentFormat.OpenXml.Presentation.CircleTransition) == trans.FirstChild.GetType()) {
- var child = trans.GetFirstChild<CircleTransition>();
- result.Type = AnimationTypes.Circle;
- // §19.5.26
- result.typeExt = new Dictionary<string, object>() { { result.Type,""} };
- }
- else if (typeof(DocumentFormat.OpenXml.Presentation.DissolveTransition) == trans.FirstChild.GetType()) {
- var child = trans.GetFirstChild<DissolveTransition>();
- //§19.5.36
- result.Type = AnimationTypes.Dissolve;// AnimationTypes.DissolveIn;
- result.typeExt = new Dictionary<string, object>() { { result.Type,""} };
- }
- else if (typeof(DocumentFormat.OpenXml.Presentation.CombTransition) == trans.FirstChild.GetType()) {
- var child = trans.GetFirstChild<CombTransition>();
- result.Type = AnimationTypes.Comb;
- // §19.5.30
- //Horizontal = 0, horz Vertical = 1 vert
- result.typeExt = new Dictionary<string, object>() { { result.Type, child.Direction } };
- }
- else if (typeof(DocumentFormat.OpenXml.Presentation.CoverTransition) == trans.FirstChild.GetType()) {
- var child = trans.GetFirstChild<CoverTransition>();
- result.Type = AnimationTypes.Cover;
- // §19.5.32
- //u up 默认 , d down , l left ,r right ,ld left down ,lu left up, rd right down ,ru right up
- result.typeExt = new Dictionary<string, object>() { { result.Type, child.Direction } };
- }
- else if (typeof(DocumentFormat.OpenXml.Presentation.CutTransition) == trans.FirstChild.GetType()) {
- var child = trans.GetFirstChild<CutTransition>();
- result.Type = AnimationTypes.Cut;
- bool flag = false;
- if (child.ThroughBlack != null && child.ThroughBlack.Value) {
- result.Type = AnimationTypes.CutThroughBlack;
- flag = true;
- }
- // §19.5.34
- result.typeExt = new Dictionary<string, object>() { { result.Type, flag} };
- }
- else if (typeof(DocumentFormat.OpenXml.Presentation.DiamondTransition) == trans.FirstChild.GetType()) {
- var child = trans.GetFirstChild<DiamondTransition>();
- result.Type = AnimationTypes.Diamond;
- //§19.5.35
- result.typeExt = new Dictionary<string, object>() { { result.Type,"" } };
- }
- else if (typeof(DocumentFormat.OpenXml.Presentation.FadeTransition) == trans.FirstChild.GetType()) {
- var child = trans.GetFirstChild<FadeTransition>();
- result.Type = AnimationTypes.Fade;
- bool flag = false;
- if (child.ThroughBlack != null && child.ThroughBlack.Value)
- {
- result.Type = AnimationTypes.FadeThroughBlack;
- flag = true;
- }
- // §19.5.41
- result.typeExt = new Dictionary<string, object>() { { result.Type, flag } };
- }
- else if (typeof(DocumentFormat.OpenXml.Presentation.NewsflashTransition) == trans.FirstChild.GetType()) {
- var child = trans.GetFirstChild<NewsflashTransition>();
- result.Type = AnimationTypes.Newsflash;
- // §19.5.50
- result.typeExt = new Dictionary<string, object>() { { result.Type,"" } };
- }
- else if (typeof(DocumentFormat.OpenXml.Presentation.PlusTransition) == trans.FirstChild.GetType()) {
- var child = trans.GetFirstChild<PlusTransition>();
- result.Type = AnimationTypes.Plus;
- // §19.5.54
- result.typeExt = new Dictionary<string, object>() { { result.Type, ""} };
- }
- else if (typeof(DocumentFormat.OpenXml.Presentation.PullTransition) == trans.FirstChild.GetType()) {
- var child = trans.GetFirstChild<PullTransition>();
- result.Type = AnimationTypes.Pull;
- // §19.5.58
- //u up 默认 , d down , l left ,r right ,ld left down ,lu left up, rd right down ,ru right up
- result.typeExt = new Dictionary<string, object>() { { result.Type, child.Direction } };
- }
- else if (typeof(DocumentFormat.OpenXml.Presentation.PushTransition) == trans.FirstChild.GetType()) {
- var child = trans.GetFirstChild<PushTransition>();
- result.Type = AnimationTypes.Push;
- // §19.5.59
- //u up 默认 d down l left r right
- result.typeExt =new Dictionary<string, object>() { { result.Type, child.Direction } };
- }
- else if (typeof(DocumentFormat.OpenXml.Presentation.RandomTransition) == trans.FirstChild.GetType()) {
- var child = trans.GetFirstChild<RandomTransition>();
- result.Type = AnimationTypes.Random;
- //§19.5.60
- result.typeExt = new Dictionary<string, object>() { { result.Type,"" } };
- }
- else if (typeof(DocumentFormat.OpenXml.Presentation.RandomBarTransition) == trans.FirstChild.GetType()) {
- var child = trans.GetFirstChild<RandomBarTransition>();
- result.Type = AnimationTypes.RandomBars;
- // Horizontal = 0, horz Vertical = 1 vert
- // §19.5.61
- result.typeExt = new Dictionary<string, object>() { { result.Type, child.Direction } };
- }
- else if (typeof(DocumentFormat.OpenXml.Presentation.SplitTransition) == trans.FirstChild.GetType()) {
- var child = trans.GetFirstChild<SplitTransition>();
- result.Type = AnimationTypes.Split;
- // Out = 0, out In = 1 in
- var dir = child.Direction;
- // Horizontal = 0, horz Vertical = 1 vert
- // §19.5.71
- var orient = child.Orientation;
- result.typeExt = new Dictionary<string, object>() { { result.Type,new { dir , orient } } };
- }
- else if (typeof(DocumentFormat.OpenXml.Presentation.StripsTransition) == trans.FirstChild.GetType()) {
- var child = trans.GetFirstChild<StripsTransition>();
- result.Type = AnimationTypes.Strips;
- // Left-Up lu , Right-Up ru ,Left-Downld , Right-Down rd
- // §19.5.74
- result.typeExt = new Dictionary<string, object>() { { result.Type, child.Direction } };
- }
- else if (typeof(DocumentFormat.OpenXml.Presentation.WedgeTransition) == trans.FirstChild.GetType()) {
- var child = trans.GetFirstChild<WedgeTransition>();
- result.Type = AnimationTypes.Wedge;
- // §19.5.94
- result.typeExt = new Dictionary<string, object>() { { result.Type, "" } };
- }
- else if (typeof(DocumentFormat.OpenXml.Presentation.WheelTransition) == trans.FirstChild.GetType()) {
- var child = trans.GetFirstChild<WheelTransition>();
- result.Type = AnimationTypes.Wheel;
- //19.5.95
- // 1,一个扇形中心旋转一圈,右上角开始, 2 两个扇形旋转, 3三个扇形旋转,4 四个扇形旋转, 8 八个扇形旋转
- result.typeExt = new Dictionary<string, object>() { { result.Type, child.Spokes } };
- }
- else if (typeof(DocumentFormat.OpenXml.Presentation.WipeTransition) == trans.FirstChild.GetType()) {
- var child = trans.GetFirstChild<WipeTransition>();
- result.Type = AnimationTypes.Wipe;
- //u up 默认 , d down , l left ,r right
- // §19.5.96
- result.typeExt = new Dictionary<string, object>() { { result.Type, child.Direction } };
- }
- else if (typeof(DocumentFormat.OpenXml.Presentation.ZoomTransition) == trans.FirstChild.GetType()) {
- var child = trans.GetFirstChild<ZoomTransition>();
- result.Type = AnimationTypes.Zoom;
- // Out = 0, out In = 1 in
- // §19.5.97
- result.typeExt = new Dictionary<string, object>() { { result.Type, child.Direction } };
- }
- var SoundAction = trans.GetFirstChild<SoundAction>();
- if (SoundAction != null) {
- var loop = false;
- if (SoundAction.StartSoundAction.Loop != null) {
- loop = true;
- }
- var url = "";
- var name = "";
- if (SoundAction.StartSoundAction.Sound != null) {
- var Sound = SoundAction.StartSoundAction.Sound;
- var Embed = Sound.Embed;
- DataPartReferenceRelationship part = null;
- if (partForm == "slide")
- {
- part = SlidePart.DataPartReferenceRelationships.Where(x => x.Id == Embed).FirstOrDefault();
- }
- if (partForm == "layout")
- {
- part = SlideLayoutPart.DataPartReferenceRelationships.Where(x => x.Id == Embed).FirstOrDefault();
- }
- if (partForm == "master")
- {
- part = slideMasterPart.DataPartReferenceRelationships.Where(x => x.Id == Embed).FirstOrDefault();
- }
- if (part != null)
- {
- url = part.Uri.ToString().Replace("../", "/ppt/");
- var thumbnail = Media.Where(x => x.Attributes().Select(y => y.Value == url).FirstOrDefault()).FirstOrDefault();
- //if (thumbnail != null)
- //{
- // var contentType = thumbnail.Attribute("{http://schemas.microsoft.com/office/2006/xmlPackage}contentType").Value;
- // //var data = thumbnail.Value;
- // //url = "data:" + contentType + ";base64," + data;
- // //url = url.Replace("\r\n", "");
- // result.url = url;
- // // htexBlipFill.urlType = "base64";
- // // htexBlipFill.contentType = contentType;
- //}
- }
- result.typeExt = new Dictionary<string, object>() { { "sndAc", new { loop, url, name } } };
- }
- }
- ///TODO Office2013|Office2010
- return result;
- }
- }
- }
|