using DocumentFormat.OpenXml; using DocumentFormat.OpenXml.Office2010.Drawing; using DocumentFormat.OpenXml.Packaging; using DocumentFormat.OpenXml.Presentation; using System; using System.Collections.Generic; using System.Drawing; using System.Globalization; using System.IO; using System.Linq; using System.Text; using System.Text.RegularExpressions; using System.Xml; using System.Xml.Linq; using System.Xml.Xsl; using TEAMModelOS.SDK.Context.Configuration; using TEAMModelOS.SDK.Helper.Common.ColorHelper; using TEAMModelOS.SDK.Module.PowerPointX.Model; using ColorMap = DocumentFormat.OpenXml.Presentation.ColorMap; using Point = TEAMModelOS.SDK.Module.PowerPointX.Model.Point; using Theme = DocumentFormat.OpenXml.Drawing.Theme; namespace TEAMModelOS.SDK.Module.PowerPointX { public class PresentationConvert { const double inchpixel = 96.00, inchpt = 72.00, pxBase = 914400.00, ptBase = 12700; const double rotBase = 60000.00; /// /// 加载PPTX文件 /// /// /// public PPTXInfo LoadPresentation(Stream presentationStream) { using (PresentationDocument presentationDocument = PresentationDocument.Open(presentationStream, false)) { if (presentationDocument == null) { throw new ArgumentNullException("presentationDocument"); } // Get a PresentationPart object from the PresentationDocument object. var thumbnailPart = presentationDocument.ThumbnailPart; var contentType = thumbnailPart.ContentType; string base64 = ""; using (var stream = thumbnailPart.GetStream()) { byte[] buffer = new byte[stream.Length]; stream.Read(buffer, 0, buffer.Length); stream.Close(); base64 = System.Convert.ToBase64String(buffer); base64 = "data:" + contentType + ";base64," + base64; } PresentationPart presentationPart = presentationDocument.PresentationPart; if (presentationPart != null && presentationPart.Presentation != null) { // Get a Presentation object from the PresentationPart object. Presentation presentation = presentationPart.Presentation; int pageSize = 0; var slideMasterParts = presentationPart.SlideMasterParts; ColorMap colorMap = null; Theme theme = null; foreach (var slideMasterPart in slideMasterParts) { if (colorMap != null && theme != null) { break; } colorMap = slideMasterPart.SlideMaster.ColorMap; theme = slideMasterPart.ThemePart.Theme; } //获取PPT 一页大小 double x = presentation.SlideSize.Cx* inchpixel/ pxBase; double y = presentation.SlideSize.Cy * inchpixel / pxBase; List slides = new List(); if (presentation.SlideIdList != null) { // Get the title of each slide in the slide order. // 获取的是几页PPT数量 foreach (var slideId in presentation.SlideIdList.Elements()) { PPTXSlide slide = new PPTXSlide(); // 获取这一页 PPT 的id string id = slideId.RelationshipId; SlidePart slidePart = presentationPart.GetPartById(slideId.RelationshipId) as SlidePart; //获取当前页 PPT 的所有元素 slide.Elements=GetSlideElement(slidePart, theme, colorMap); slides.Add(slide); pageSize++; } } PPTXInfo info = new PPTXInfo {Slides=slides,Width=x,Height=y ,PageSize= pageSize ,Thumbnail=base64 }; return info; } return null; } } /// /// 处理一页PPT的元素 /// /// /// /// /// public List GetSlideElement(SlidePart slidePart, Theme theme, ColorMap colorMap) { List elements = new List(); var shapeTrees = from shap in slidePart.Slide.Descendants() select shap; if (shapeTrees.Count() > 0 && shapeTrees.First().ChildElements.Count > 0) { OpenXmlElementList openXmlElements = shapeTrees.First().ChildElements; int index = 0; foreach (OpenXmlElement element in openXmlElements) { PPTXElement pptElement = null; if (element is DocumentFormat.OpenXml.Presentation.Shape shape) { //p:sp pptElement = ShapeConvert(shape, theme, colorMap, index); } if (element is DocumentFormat.OpenXml.Presentation.Picture picture)//p:pic { pptElement = PictureConvert(picture, theme, colorMap, slidePart, index); } if (element is DocumentFormat.OpenXml.AlternateContent content)//mc:alternatecontent { pptElement = AlternateContentConvert(content, theme, colorMap,slidePart, index); } if (element is DocumentFormat.OpenXml.Presentation.GraphicFrame graphicFrame)//p:graphicFrame { pptElement = GraphicFrameConvert(graphicFrame, theme, colorMap, index); } if (element is DocumentFormat.OpenXml.Presentation.GroupShape groupShape)//p:grpSp { pptElement = GroupShapeConvert(groupShape, theme, colorMap, index); } if (element is DocumentFormat.OpenXml.Presentation.ConnectionShape connectionShape) // p:cxnSp { pptElement = ConnectionShapeConvert(connectionShape, theme, colorMap, index); } if (pptElement != null) { index++; elements.Add(pptElement); } } } return elements; } public PPTXElement GroupShapeConvert(GroupShape groupShape, Theme theme, ColorMap colorMap, int index) { return null; } public PPTXElement ConnectionShapeConvert(ConnectionShape connectionShape, Theme theme, ColorMap colorMap, int index) { string type = ""; string fillColor = ""; ShapeProperties properties = connectionShape.ShapeProperties; IEnumerable presetGeometries = GetPresetGeometry(properties); if (presetGeometries.Count() > 0) { type = presetGeometries.FirstOrDefault().Preset; } PPTXConnector element = new PPTXConnector() { Type = type }; if (properties != null) { if (properties.Transform2D != null) { element.OffX = properties.Transform2D.Offset.X * inchpixel / pxBase; element.OffY = properties.Transform2D.Offset.Y * inchpixel / pxBase; element.ExtX = properties.Transform2D.Extents.Cx * inchpixel / pxBase; element.ExtY = properties.Transform2D.Extents.Cy * inchpixel / pxBase; element.FlipH = properties.Transform2D.HorizontalFlip != null ? BooleanValue.ToBoolean(properties.Transform2D.HorizontalFlip) : false; element.FlipV = properties.Transform2D.VerticalFlip != null ? BooleanValue.ToBoolean(properties.Transform2D.VerticalFlip) : false; element.Rot = (properties.Transform2D.Rotation != null ? properties.Transform2D.Rotation.Value : 0) / rotBase; } var headEnd = from shap in properties.Descendants() select shap; var tailEnd = from shap in properties.Descendants() select shap; if (headEnd != null && headEnd.Count() > 0) { element.HeadEnd = headEnd.First().Type; } if (tailEnd != null && tailEnd.Count() > 0) { element.TailEnd = tailEnd.First().Type; } fillColor = GetPropertieColor(properties, theme, colorMap, "Line"); } if (string.IsNullOrEmpty(fillColor)) { fillColor = GetShapeStyleColor(connectionShape.ShapeStyle, "Line", theme); } element.FillColor = fillColor; return element; } public PPTXElement GraphicFrameConvert(GraphicFrame graphicFrame, Theme theme, ColorMap colorMap, int index) { DocumentFormat.OpenXml.Drawing.GraphicData graphicData = graphicFrame.ChildElements.First(); if (graphicData != null) { OpenXmlElement element = graphicData.ChildElements.First(); if (element != null) { if (element is DocumentFormat.OpenXml.Drawing.Table table) { return TableConvert(graphicFrame, theme, colorMap); } if (element is DocumentFormat.OpenXml.Drawing.Chart chart) { //return ChartConvert(graphicFrame, theme, colorMap); } if (element is DocumentFormat.OpenXml.Drawing.Diagram diagram) { //return DiagramConvert(graphicFrame, theme, colorMap); } } } return null; } public PPTXElement TableConvert(GraphicFrame graphicFrame, Theme theme, ColorMap colorMap) { return null; } /// /// 处理普通形状的元素 /// /// /// public PPTXElement ShapeConvert(Shape shape, Theme theme, ColorMap colorMap, int index) { // shape.base //文字颜色 string textColor = ""; //填充颜色 string fillColor = ""; //填充颜色 string lineColor = ""; // 形状类型 string type = "rect"; //字体大小 int fontSize = 1800; //是否闭合形状 bool complete = true; PPTXContainer element = new PPTXContainer() ; ShapeProperties properties = shape.ShapeProperties; IEnumerable presetGeometries = GetPresetGeometry(properties); IEnumerable customGeometries = GetCustomGeometry(properties); if (presetGeometries.Count() > 0) { type = presetGeometries.FirstOrDefault().Preset; var adjusts = from shap in presetGeometries.First().Descendants() select shap; if (adjusts.Count() > 0) { var elements = adjusts.First().ChildElements; foreach (var xmlElement in elements) { if (xmlElement is DocumentFormat.OpenXml.Drawing.ShapeGuide shapeGuide) { PPTXShapeGuide PPTXShapeGuide = new PPTXShapeGuide { Name = shapeGuide.Name, Fmla = shapeGuide.Formula }; element.ShapeGuides.Add(PPTXShapeGuide); } } } } if (customGeometries.Count() > 0) { type = "custom"; } element.Type = type; DocumentFormat.OpenXml.Drawing.Transform2D transform2D = GetTransform2D(properties); if (transform2D != null) { element.Close = complete; element.OffX = transform2D.Offset.X * inchpixel / pxBase; element.OffY = transform2D.Offset.Y * inchpixel / pxBase; element.ExtX = transform2D.Extents.Cx * inchpixel / pxBase; element.ExtY = transform2D.Extents.Cy * inchpixel / pxBase; element.FlipH = transform2D.HorizontalFlip != null ? BooleanValue.ToBoolean(transform2D.HorizontalFlip) : false; element.FlipV = transform2D.VerticalFlip != null ? BooleanValue.ToBoolean(transform2D.VerticalFlip) : false; element.Rot = transform2D.Rotation != null ? transform2D.Rotation.Value : 0; } var nofill = GetNoFill(properties); if (nofill.Count() > 0) { element.Fill = false; } element.Index = index; ///获取runs的文本及颜色信息 var bodyProp = from shap in shape.Descendants() select shap; if (bodyProp.Count() > 0) { DocumentFormat.OpenXml.Drawing.BodyProperties bdpros = bodyProp.First(); if (bdpros.Vertical != null && !bdpros.Vertical.Value.Equals("horz")) { element.TextLayout = "vert"; } //0顶 1中 2底 if (bdpros.Anchor != null) { element.Align = bdpros.Anchor.Value.ToString(); } //bodyAlign = element.Align == null || string.IsNullOrEmpty(bdpros.Ancestors) ? "" : element.Align; //element.Wrap == null || string.IsNullOrEmpty(element.Wrap) ? "none" : element.Wrap; } var paragraphs = from shap in shape.Descendants() select shap; foreach (var paragrap in paragraphs) { string textAling = "l"; if (paragrap.ParagraphProperties != null) { textAling = paragrap.ParagraphProperties.Alignment; } //if (string.IsNullOrEmpty(textAling)) //{ //if (string.IsNullOrEmpty(bodyAlign)) //{ // textAling = "l"; //} //else //{ // textAling = bodyAlign; //} //} List texts = new List(); var runs = from shap in paragrap.Descendants() select shap; foreach (var run in runs) { PPTXText text = new PPTXText(); var runprps = from shap in run.Descendants() select shap; DocumentFormat.OpenXml.Drawing.RunProperties runProperties = runprps.FirstOrDefault(); if (runProperties != null) { if (runProperties.FontSize != null) { text.FontSize = runProperties.FontSize; } if (runProperties.Italic != null) { text.FontItalic = runProperties.Italic; } if (runProperties.Bold != null) { text.FontBold = runProperties.Bold; } //if (runProperties.Italic != null) //{ // text.FontBold = runProperties.Bold; //} if (runProperties.Underline != null) { text.FontLine = (int)runProperties.Underline.Value; } } var schemeColor = from shap in run.Descendants() select shap; var rgbColors = from shap in run.Descendants() select shap; textColor = GetSchemeColor(schemeColor, theme, colorMap); if (string.IsNullOrEmpty(textColor)) { text.TextColor = textColor = GetRgbColor(rgbColors); } if (string.IsNullOrEmpty(textColor)) { textColor = GetShapeStyleColor(shape.ShapeStyle, "Font", theme); } if (string.IsNullOrEmpty(textColor)) { textColor = "FFFFFF"; } text.FontSize = fontSize; text.Text = run.InnerText; text.TextAlign = textAling; texts.Add(text); } if (texts.Count() > 0) { PPTXParagraph paragraph = new PPTXParagraph(); paragraph.Texts = texts; element.Paragraphs.Add(paragraph); } } if (string.IsNullOrEmpty(textColor)) { textColor = GetShapeStyleColor(shape.ShapeStyle, "Font", theme); } if (string.IsNullOrEmpty(fillColor)) { fillColor = GetPropertieColor(properties, theme, colorMap, "Fill"); } if (string.IsNullOrEmpty(lineColor)) { lineColor = GetPropertieColor(properties, theme, colorMap, "Line"); } if (string.IsNullOrEmpty(lineColor)) { lineColor = GetShapeStyleColor(shape.ShapeStyle, "Line", theme); } if (string.IsNullOrEmpty(fillColor)) { fillColor = GetShapeStyleColor(shape.ShapeStyle, "Fill", theme); } element.LineColor = lineColor; element.FillColor = fillColor; var custGeometrys = from shap in properties.Descendants() select shap; if (custGeometrys.Count() > 0) { var pathLists = from shap in custGeometrys.First().Descendants() select shap; if (pathLists.Count() > 0) { element.Close = false; OpenXmlElementList elements = pathLists.First().ChildElements; foreach (OpenXmlElement xmlElement in elements) { //起点 if (xmlElement is DocumentFormat.OpenXml.Drawing.MoveTo moveTo) { DocumentFormat.OpenXml.Drawing.Point point = moveTo.Point; PPTXMoveToPath moveToPath = new PPTXMoveToPath { Type = "MoveTo" }; moveToPath.Pts.Add(new Point { X = double.Parse(point.X) * inchpixel / pxBase, Y = double.Parse(point.Y) * inchpixel / pxBase }); element.Paths.Add(moveToPath); } //连线 if (xmlElement is DocumentFormat.OpenXml.Drawing.LineTo linTo) { DocumentFormat.OpenXml.Drawing.Point point = linTo.Point; PPTXLineToPath lineToPath = new PPTXLineToPath { Type = "LineTo" }; lineToPath.Pts.Add(new Point { X = double.Parse(point.X) * inchpixel / pxBase, Y = double.Parse(point.Y) * inchpixel / pxBase }); element.Paths.Add(lineToPath); } //三次贝塞尔曲线 if (xmlElement is DocumentFormat.OpenXml.Drawing.CubicBezierCurveTo cubicBezierCurveTo) { OpenXmlElementList list = cubicBezierCurveTo.ChildElements; PPTXCubicBezPath cubicBezPath = new PPTXCubicBezPath { Type = "CubicBez" }; foreach (var ls in list) { if (ls is DocumentFormat.OpenXml.Drawing.Point point) { cubicBezPath.Pts.Add(new Point { X = double.Parse(point.X) * inchpixel / pxBase, Y = double.Parse(point.Y) * inchpixel / pxBase }); } } element.Paths.Add(cubicBezPath); } //二次贝塞尔曲线 if (xmlElement is DocumentFormat.OpenXml.Drawing.QuadraticBezierCurveTo quadraticBezierCurveTo) { OpenXmlElementList list = quadraticBezierCurveTo.ChildElements; PPTXQuadBezPath quadBezPath = new PPTXQuadBezPath { Type = "QuadBez" }; foreach (var ls in list) { if (ls is DocumentFormat.OpenXml.Drawing.Point point) { quadBezPath.Pts.Add(new Point { X = double.Parse(point.X) * inchpixel / pxBase, Y = double.Parse(point.Y) * inchpixel / pxBase }); } } element.Paths.Add(quadBezPath); } //处理曲线 if (xmlElement is DocumentFormat.OpenXml.Drawing.ArcTo arcTO) { PPTXArcToPath arcToPath = new PPTXArcToPath() { WidthRadius = arcTO.WidthRadius, HeightRadius = arcTO.HeightRadius, StartAngle = arcTO.StartAngle, SwingAngle = arcTO.SwingAngle }; element.Paths.Add(arcToPath); } ///判断路径是否闭合 if (xmlElement is DocumentFormat.OpenXml.Drawing.CloseShapePath close) { if (close != null) { element.Close = true; } } } } } return element; } /// /// 处理图片的元素 /// /// /// public PPTXElement PictureConvert(Picture picture, Theme theme, ColorMap colorMap, SlidePart slidePart, int index) { BlipFill blipFill = picture.BlipFill; var imageRid = blipFill.Blip.Embed.Value; IdPartPair idParie = slidePart.Parts.Where(x => x.RelationshipId == imageRid).FirstOrDefault(); ImagePart imagePart = (ImagePart)idParie.OpenXmlPart; var contentType = imagePart.ContentType; string base64 = ""; using (var stream = imagePart.GetStream()) { byte[] buffer = new byte[stream.Length]; stream.Read(buffer, 0, buffer.Length); stream.Close(); base64 = System.Convert.ToBase64String(buffer); base64 = "data:" + contentType + ";base64," + base64; } ShapeProperties properties = picture.ShapeProperties; PPTXPicture element = new PPTXPicture(); if (properties != null && properties.Transform2D != null) { element.OffX = properties.Transform2D.Offset.X * inchpixel / pxBase; element.OffY = properties.Transform2D.Offset.Y * inchpixel / pxBase; element.ExtX = properties.Transform2D.Extents.Cx * inchpixel / pxBase; element.ExtY = properties.Transform2D.Extents.Cy * inchpixel / pxBase; element.FlipH = properties.Transform2D.HorizontalFlip != null ? BooleanValue.ToBoolean(properties.Transform2D.HorizontalFlip) : false; element.FlipV = properties.Transform2D.VerticalFlip != null ? BooleanValue.ToBoolean(properties.Transform2D.VerticalFlip) : false; element.Rot = properties.Transform2D.Rotation != null ? properties.Transform2D.Rotation.Value : 0; } element.FillColor = GetPropertieColor(properties, theme, colorMap, "Fill"); element.LineColor = GetPropertieColor(properties, theme, colorMap, "Line"); element.Data = base64; element.Index = index; return element; } /// /// 处理兼容元素 /// /// /// public PPTXElement AlternateContentConvert(AlternateContent content, Theme theme, ColorMap colorMap, SlidePart slidePart, int index) { var choices = from contentChoice in content.Descendants() select contentChoice; if (choices.Count() > 0) { OpenXmlElement element = choices.First().ChildElements.First(); if (element != null) { if (element is DocumentFormat.OpenXml.Presentation.Shape shape) { var textMaths = from shap in shape.Descendants() select shap; if (textMaths.Count() > 0) { // return MathConvertMathML(shape, theme, colorMap, index); return MathConvertImage(content, theme, colorMap,slidePart, index); } } } } //AlternateContentChoice choice = content.ChildElements.First(); return null; } public PPTXElement MathConvertImage(AlternateContent content, Theme theme, ColorMap colorMap, SlidePart slidePart, int index) { var fallbacks = from contentChoice in content.Descendants() select contentChoice; if (fallbacks.Count() > 0) { OpenXmlElement xmlElement = fallbacks.First().ChildElements.First(); if (xmlElement != null) { if (xmlElement is DocumentFormat.OpenXml.Presentation.Shape shape) { var blipFills = from pic in shape.Descendants() select pic; if (blipFills.Count() > 0) { var imageRid= blipFills.First().Blip.Embed.Value; IdPartPair idParie = slidePart.Parts.Where(x => x.RelationshipId == imageRid).FirstOrDefault(); ImagePart imagePart = (ImagePart)idParie.OpenXmlPart; var contentType = imagePart.ContentType; string base64 = ""; using (var stream = imagePart.GetStream()) { byte[] buffer = new byte[stream.Length]; stream.Read(buffer, 0, buffer.Length); stream.Close(); base64 = System.Convert.ToBase64String(buffer); base64 = "data:" + contentType + ";base64," + base64; } ShapeProperties properties = shape.ShapeProperties; PPTXPicture element = new PPTXPicture(); if (properties != null && properties.Transform2D != null) { element.OffX = properties.Transform2D.Offset.X * inchpixel / pxBase; element.OffY = properties.Transform2D.Offset.Y * inchpixel / pxBase; element.ExtX = properties.Transform2D.Extents.Cx * inchpixel / pxBase; element.ExtY = properties.Transform2D.Extents.Cy * inchpixel / pxBase; element.FlipH = properties.Transform2D.HorizontalFlip != null ? BooleanValue.ToBoolean(properties.Transform2D.HorizontalFlip) : false; element.FlipV = properties.Transform2D.VerticalFlip != null ? BooleanValue.ToBoolean(properties.Transform2D.VerticalFlip) : false; element.Rot = properties.Transform2D.Rotation != null ? properties.Transform2D.Rotation.Value : 0; } element.FillColor = GetPropertieColor(properties, theme, colorMap, "Fill"); element.LineColor = GetPropertieColor(properties, theme, colorMap, "Line"); element.Data = base64; element.Index = index; return element; } } } } return null; } /// /// 处理公式 /// /// /// /// /// public PPTXElement MathConvertMathML(DocumentFormat.OpenXml.Presentation.Shape shape, Theme theme, ColorMap colorMap, int index) { //文字颜色 string textColor = ""; //填充颜色 string fillColor = ""; // 形状类型 string type = "math"; //字体大小 int fontSize = 1800; //是否闭合形状 bool complete = true; ShapeProperties properties = shape.ShapeProperties; //IEnumerable presetGeometries = GetPresetGeometry(properties); //if (presetGeometries.Count() > 0) //{ // type = presetGeometries.FirstOrDefault().Preset; //} DocumentFormat.OpenXml.Drawing.Transform2D transform2D = GetTransform2D(properties); PPTXContainer element = new PPTXContainer() { Type = type }; if (transform2D != null) { element.Close = complete; element.OffX = properties.Transform2D.Offset.X * inchpixel / pxBase; element.OffY = properties.Transform2D.Offset.Y * inchpixel / pxBase; element.ExtX = properties.Transform2D.Extents.Cx * inchpixel / pxBase; element.ExtY = properties.Transform2D.Extents.Cy * inchpixel / pxBase; element.FlipH = properties.Transform2D.HorizontalFlip != null ? BooleanValue.ToBoolean(properties.Transform2D.HorizontalFlip) : false; element.FlipV = properties.Transform2D.VerticalFlip != null ? BooleanValue.ToBoolean(properties.Transform2D.VerticalFlip) : false; element.Rot = properties.Transform2D.Rotation != null ? properties.Transform2D.Rotation.Value : 0; } textColor = GetPropertieColor(properties, theme, colorMap, "Font"); var nofill = GetNoFill(properties); if (nofill.Count() > 0) { element.Fill = false; } //获取行内样式 if (string.IsNullOrEmpty(textColor)) { var rgbColor = from shap in shape.TextBody.Descendants() select shap; textColor = GetRgbColor(rgbColor); if (string.IsNullOrEmpty(textColor)) { var schemes = from shap in shape.TextBody.Descendants() select shap; textColor = GetSchemeColor(schemes, theme, colorMap); } } if (string.IsNullOrEmpty(textColor)) { textColor = GetShapeStyleColor(shape.ShapeStyle, "Font", theme); } { textColor = "FFFFFF"; } if (string.IsNullOrEmpty(fillColor)) { fillColor = GetPropertieColor(properties, theme, colorMap, "Fill"); } if (string.IsNullOrEmpty(fillColor)) { fillColor = GetShapeStyleColor(shape.ShapeStyle, "Fill", theme); } string lineColor = GetPropertieColor(properties, theme, colorMap, "Line"); if (string.IsNullOrEmpty(lineColor)) { lineColor = GetShapeStyleColor(shape.ShapeStyle, "Line", theme); } element.LineColor = lineColor; element.FillColor = fillColor; var textMaths = from shap in shape.Descendants() select shap; var math = textMaths.First(); /// TODO 文字大小 //XElement xElement= XElement.Load(math.InnerXml); // var aa = xElement.Element("a:rPr"); //var runProperties = from shap in shape.Descendants() select shap; //if (runProperties.Count() > 0) { // DocumentFormat.OpenXml.Drawing.RunProperties propert= runProperties.First(); // fontSize = propert.FontSize!=null&& propert.FontSize.Value > 0 ? propert.FontSize.Value : fontSize; //} string elementData = ProcessOMath(math.InnerXml); PPTXParagraph paragraph = new PPTXParagraph(); paragraph.Texts.Add(new PPTXText { TextColor = textColor, Text = elementData, FontSize = fontSize }); element.Paragraphs.Add(paragraph); element.Index = index; return element; } /// /// 处理元素的Transform2D属性 /// /// /// public DocumentFormat.OpenXml.Drawing.Transform2D GetTransform2D(ShapeProperties properties) { if (properties != null) { return properties.Transform2D; } return null; } /// /// 处理元素的Transform2D 系统默认的元素 /// /// /// public IEnumerable GetPresetGeometry(ShapeProperties properties) { if (properties != null) { var presetGeometrys = from shap in properties.Descendants() select shap; return presetGeometrys; } return null; } public IEnumerable GetCustomGeometry(ShapeProperties properties) { if (properties != null) { var customGeometrys = from shap in properties.Descendants() select shap; return customGeometrys; } return null; } /// /// 处理是否填充 /// /// /// public IEnumerable GetNoFill(ShapeProperties properties) { if (properties != null) { var customGeometrys = from shap in properties.Descendants() select shap; return customGeometrys; } return null; } ///// ///// 获取属性填充色 ///// ///// ///// //public IEnumerable GetPropFill(ShapeProperties properties) //{ // if (properties != null) // { // var solidFills = properties.ChildElements // .Where(x => x is DocumentFormat.OpenXml.Drawing.SolidFill); // if (solidFills.Count() > 0) { // DocumentFormat.OpenXml.Drawing.SolidFill solidFills.ToList().First(); // } // } // return null; //} /// /// 获取轮廓颜色填充 /// /// /// public IEnumerable GetPropLineFill(ShapeProperties properties) { if (properties != null) { var customGeometrys = from shap in properties.Descendants() select shap; return customGeometrys; } return null; } /// /// 处理元素属性的填充色 /// /// /// public string GetPropertieColor(ShapeProperties properties, Theme theme, ColorMap colorMap, string type) { if (properties != null) { var cidElement = properties.ChildElements; foreach (var element in cidElement) { if (type.Equals("Fill") && element is DocumentFormat.OpenXml.Drawing.SolidFill solidFill) { string fillColor = ""; var propRgbColor = from shape in solidFill.Descendants() select shape; fillColor = GetRgbColor(propRgbColor); if (string.IsNullOrEmpty(fillColor)) { var colorScheme = from shape in solidFill.Descendants() select shape; fillColor = GetSchemeColor(colorScheme, theme, colorMap); } return fillColor; } if (type.Equals("Line") && element is DocumentFormat.OpenXml.Drawing.Outline outline) { string lineColor = ""; var propRgbColor = from shape in outline.Descendants() select shape; lineColor = GetRgbColor(propRgbColor); if (string.IsNullOrEmpty(lineColor)) { var colorScheme = from shape in outline.Descendants() select shape; lineColor = GetSchemeColor(colorScheme, theme, colorMap); } return lineColor; } } } return ""; } /// /// 获取ShapeStyle样式表 各种属性 的颜色 /// /// /// /// /// public string GetShapeStyleColor(DocumentFormat.OpenXml.Presentation.ShapeStyle shapeStyle, string colorType, Theme theme) { if (shapeStyle == null) { return ""; } // 效果颜色 if (colorType.Equals("Effect")) { DocumentFormat.OpenXml.Drawing.SchemeColor EffectcolorScheme = shapeStyle.EffectReference.ChildElements.First(); //return ColorForThemeClr(EffectcolorScheme.Val, theme); return GetColorSchemeExtInfo(EffectcolorScheme, ColorForThemeClr(EffectcolorScheme.Val, theme)); } // 轮廓颜色 if (colorType.Equals("Line")) { DocumentFormat.OpenXml.Drawing.SchemeColor LinecolorScheme = shapeStyle.LineReference.ChildElements.First(); //return ColorForThemeClr(LinecolorScheme.Val, theme); return GetColorSchemeExtInfo(LinecolorScheme, ColorForThemeClr(LinecolorScheme.Val, theme)); } // 填充色 if (colorType.Equals("Fill")) { DocumentFormat.OpenXml.Drawing.SchemeColor FillcolorScheme = shapeStyle.FillReference.ChildElements.First(); // return ColorForThemeClr(FillcolorScheme.Val, theme); return GetColorSchemeExtInfo(FillcolorScheme, ColorForThemeClr(FillcolorScheme.Val, theme)); } // 字体颜色 if (colorType.Equals("Font")) { DocumentFormat.OpenXml.Drawing.SchemeColor FontcolorScheme = shapeStyle.FontReference.ChildElements.First(); //return ColorForThemeClr(FontcolorScheme.Val, theme); return GetColorSchemeExtInfo(FontcolorScheme, ColorForThemeClr(FontcolorScheme.Val, theme)); } return ""; } /// /// 获取 声明颜色的色调扩展 /// /// /// /// public string GetColorSchemeExtInfo(DocumentFormat.OpenXml.Drawing.SchemeColor scheme, string schemeColor) { var childeElemet = scheme.ChildElements; int lumModVal = 0; int lumOffVal = 0; int tintVal = 0; int shadeVal = 0; if (childeElemet.Count() > 0) { foreach (var element in childeElemet) { if (element is DocumentFormat.OpenXml.Drawing.LuminanceModulation lumMod) { lumModVal = lumMod.Val; } if (element is DocumentFormat.OpenXml.Drawing.LuminanceOffset lumOff) { lumOffVal = lumOff.Val; } if (element is DocumentFormat.OpenXml.Drawing.Luminance lum) { } //与白色中和 if (element is DocumentFormat.OpenXml.Drawing.Tint tint) { tintVal = tint.Val; } //与黑色中和 if (element is DocumentFormat.OpenXml.Drawing.Shade shade) { shadeVal = shade.Val; } } } if (lumModVal > 0 || lumOffVal > 0) { Color color = ColorTranslator.FromHtml("#" + schemeColor); schemeColor = ColorHelper.GetColorLumModAndLumOff(color, lumModVal, lumOffVal); } if (tintVal > 0) { schemeColor = ColorHelper.GetShadeOrTintColor(ColorTranslator.FromHtml("#" + schemeColor), tintVal, "Tint"); } if (shadeVal > 0) { schemeColor = ColorHelper.GetShadeOrTintColor(ColorTranslator.FromHtml("#" + schemeColor), shadeVal, "Shade"); } return schemeColor; } /// /// 获取声明式颜色 /// /// /// public string GetSchemeColor(IEnumerable colorScheme, Theme theme, ColorMap colorMap) { string schemeColor = ""; if (colorScheme.Count() > 0) { schemeColor = ColorForThemeClr(SchemeColorForColorMap(colorScheme.FirstOrDefault().Val.Value, colorMap), theme); var scheme = colorScheme.First(); schemeColor = GetColorSchemeExtInfo(scheme, schemeColor); } return schemeColor; } /// /// 获取RGBColor /// /// /// public string GetRgbColor(IEnumerable rgbColors) { string rgbColor = ""; if (rgbColors.Count() > 0) { rgbColor = rgbColors.FirstOrDefault().Val; } return rgbColor; } /// /// 在主题Theme中获取颜色 /// /// /// /// public static string ColorForThemeClr(string scv, Theme theme) { DocumentFormat.OpenXml.Drawing.ColorScheme colorScheme = theme.ThemeElements.ColorScheme; string colorStr = ""; if (scv.Equals("dk1")) { DocumentFormat.OpenXml.Drawing.SystemColor sysColor = colorScheme.Dark1Color.ChildElements.First(); if (sysColor != null) { return sysColor.LastColor; } DocumentFormat.OpenXml.Drawing.RgbColorModelHex rgbColor = colorScheme.Dark1Color.ChildElements.First(); if (rgbColor != null) { return rgbColor.Val; } return colorStr; } if (scv.Equals("dk2")) { DocumentFormat.OpenXml.Drawing.SystemColor sysColor = colorScheme.Dark2Color.ChildElements.First(); if (sysColor != null) { return sysColor.LastColor; } DocumentFormat.OpenXml.Drawing.RgbColorModelHex rgbColor = colorScheme.Dark2Color.ChildElements.First(); if (rgbColor != null) { return rgbColor.Val; } return colorStr; } else if (scv.Equals("accent1")) { DocumentFormat.OpenXml.Drawing.SystemColor sysColor = colorScheme.Accent1Color.ChildElements.First(); if (sysColor != null) { return sysColor.LastColor; } DocumentFormat.OpenXml.Drawing.RgbColorModelHex rgbColor = colorScheme.Accent1Color.ChildElements.First(); if (rgbColor != null) { return rgbColor.Val; } return colorStr; } else if (scv.Equals("accent2")) { DocumentFormat.OpenXml.Drawing.SystemColor sysColor = colorScheme.Accent2Color.ChildElements.First(); if (sysColor != null) { return sysColor.LastColor; } DocumentFormat.OpenXml.Drawing.RgbColorModelHex rgbColor = colorScheme.Accent2Color.ChildElements.First(); if (rgbColor != null) { return rgbColor.Val; } return colorStr; } else if (scv.Equals("accent3")) { DocumentFormat.OpenXml.Drawing.SystemColor sysColor = colorScheme.Accent3Color.ChildElements.First(); if (sysColor != null) { return sysColor.LastColor; } DocumentFormat.OpenXml.Drawing.RgbColorModelHex rgbColor = colorScheme.Accent3Color.ChildElements.First(); if (rgbColor != null) { return rgbColor.Val; } return colorStr; } else if (scv.Equals("accent4")) { DocumentFormat.OpenXml.Drawing.SystemColor sysColor = colorScheme.Accent4Color.ChildElements.First(); if (sysColor != null) { return sysColor.LastColor; } DocumentFormat.OpenXml.Drawing.RgbColorModelHex rgbColor = colorScheme.Accent4Color.ChildElements.First(); if (rgbColor != null) { return rgbColor.Val; } return colorStr; } else if (scv.Equals("accent5")) { DocumentFormat.OpenXml.Drawing.SystemColor sysColor = colorScheme.Accent5Color.ChildElements.First(); if (sysColor != null) { return sysColor.LastColor; } DocumentFormat.OpenXml.Drawing.RgbColorModelHex rgbColor = colorScheme.Accent5Color.ChildElements.First(); if (rgbColor != null) { return rgbColor.Val; } return colorStr; } else if (scv.Equals("accent6")) { DocumentFormat.OpenXml.Drawing.SystemColor sysColor = colorScheme.Accent6Color.ChildElements.First(); if (sysColor != null) { return sysColor.LastColor; } DocumentFormat.OpenXml.Drawing.RgbColorModelHex rgbColor = colorScheme.Accent6Color.ChildElements.First(); if (rgbColor != null) { return rgbColor.Val; } return colorStr; } else if (scv.Equals("lt1")) { DocumentFormat.OpenXml.Drawing.SystemColor sysColor = colorScheme.Light1Color.ChildElements.First(); if (sysColor != null) { return sysColor.LastColor; } DocumentFormat.OpenXml.Drawing.RgbColorModelHex rgbColor = colorScheme.Light1Color.ChildElements.First(); if (rgbColor != null) { return rgbColor.Val; } return colorStr; } else if (scv.Equals("lt2")) { DocumentFormat.OpenXml.Drawing.SystemColor sysColor = colorScheme.Light2Color.ChildElements.First(); if (sysColor != null) { return sysColor.LastColor; } DocumentFormat.OpenXml.Drawing.RgbColorModelHex rgbColor = colorScheme.Light2Color.ChildElements.First(); if (rgbColor != null) { return rgbColor.Val; } return colorStr; } else if (scv.Equals("hlink")) { DocumentFormat.OpenXml.Drawing.SystemColor sysColor = colorScheme.Hyperlink.ChildElements.First(); if (sysColor != null) { return sysColor.LastColor; } DocumentFormat.OpenXml.Drawing.RgbColorModelHex rgbColor = colorScheme.Hyperlink.ChildElements.First(); if (rgbColor != null) { return rgbColor.Val; } return colorStr; } else if (scv.Equals("folHlink")) { DocumentFormat.OpenXml.Drawing.SystemColor sysColor = colorScheme.FollowedHyperlinkColor.ChildElements.First(); if (sysColor != null) { return sysColor.LastColor; } DocumentFormat.OpenXml.Drawing.RgbColorModelHex rgbColor = colorScheme.FollowedHyperlinkColor.ChildElements.First(); if (rgbColor != null) { return rgbColor.Val; } return colorStr; } return ""; } /// /// 按照ColorMap 去寻找对应的颜色 /// /// /// /// public static string SchemeColorForColorMap(DocumentFormat.OpenXml.Drawing.SchemeColorValues schemeColorValues, ColorMap colorMap) { string scv = schemeColorValues.ToString(); if (scv.Equals("Text1")) { return colorMap.Text1.ToString(); } if (scv.Equals("Text2")) { return colorMap.Text2.ToString(); } else if (scv.Equals("Accent1")) { return colorMap.Accent1.ToString(); } else if (scv.Equals("Accent2")) { return colorMap.Accent2.ToString(); } else if (scv.Equals("Accent3")) { return colorMap.Accent3.ToString(); } else if (scv.Equals("Accent4")) { return colorMap.Accent4.ToString(); } else if (scv.Equals("Accent5")) { return colorMap.Accent5.ToString(); } else if (scv.Equals("Accent6")) { return colorMap.Accent6.ToString(); } else if (scv.Equals("Background1")) { return colorMap.Background1.ToString(); } else if (scv.Equals("Background2")) { return colorMap.Background2.ToString(); } else if (scv.Equals("Hyperlink")) { return colorMap.Hyperlink.ToString(); } else if (scv.Equals("FollowedHyperlink")) { return colorMap.FollowedHyperlink.ToString(); } else if (scv.Equals("PhColor")) { return "PhColor"; } else if (scv.Equals("Dark1")) { return "dk1"; } else if (scv.Equals("Dark2")) { return "dk2"; } else if (scv.Equals("Light1")) { return "lt1"; } else if (scv.Equals("Light2")) { return "lt2"; } return null; } /// /// 转换Surrogate 类型的编码的字符串 /// /// /// public static Dictionary StringEncode(string xml) { Dictionary codeValues = new Dictionary(); Char[] charstr = xml.ToCharArray(); int len = charstr.Length; for (int i = 0; i < len; i++) { var stringBuilder = ""; string str = Char.ToString(charstr[i]); if (Char.GetUnicodeCategory(charstr[i]) == UnicodeCategory.Surrogate) { string str1 = Char.ToString(charstr[i + 1]); str += str1; var bytes = Encoding.UTF32.GetBytes(str); for (var j = 0; j < bytes.Length; j += 2) { stringBuilder = bytes[j + 1].ToString("x").PadLeft(2, '0') + bytes[j].ToString("x").PadLeft(2, '0') + stringBuilder; } var id = Convert.ToInt64(stringBuilder, 16); i += 1; string code = id + ""; codeValues.TryAdd(str, code); } } return codeValues; } /// /// 根据OfficeML转换为MathML /// /// /// public static string ProcessOMath(string innerXml) { Dictionary codeValues = StringEncode(innerXml); if (codeValues != null) { foreach (string codeValue in codeValues.Keys) { innerXml = Regex.Replace(innerXml, codeValue, codeValues[codeValue]); } } XElement element = XElement.Load(new StringReader(innerXml)); List elements = element.Elements().ToList(); element = elements.Where(x => x.Name.LocalName.Equals("oMath")).FirstOrDefault(); XslCompiledTransform xslTransform = new XslCompiledTransform(); xslTransform.Load(BaseConfigModel.ContentRootPath + "/XslFiles/OMML2MML.XSL"); string mathXml = element.ToString(); string officeML = string.Empty; using (TextReader tr = new StringReader(mathXml)) { using (XmlReader reader = XmlReader.Create(tr)) { using (MemoryStream ms = new MemoryStream()) { XmlWriterSettings settings = xslTransform.OutputSettings.Clone(); settings.ConformanceLevel = ConformanceLevel.Fragment; settings.OmitXmlDeclaration = true; settings.Encoding = Encoding.Unicode; XmlWriter xw = XmlWriter.Create(ms, settings); xslTransform.Transform(reader, xw); ms.Seek(0, SeekOrigin.Begin); using (StreamReader sr = new StreamReader(ms, Encoding.UTF8)) { officeML = sr.ReadToEnd(); } } } } officeML = officeML.Replace("mml:", ""); if (codeValues != null) { foreach (string codeValue in codeValues.Keys) { officeML = Regex.Replace(officeML, codeValues[codeValue], codeValue); } } return officeML; } } }