PresentationConvert.cs 44 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981
  1. using DocumentFormat.OpenXml;
  2. using DocumentFormat.OpenXml.Office2010.Drawing;
  3. using DocumentFormat.OpenXml.Packaging;
  4. using DocumentFormat.OpenXml.Presentation;
  5. using System;
  6. using System.Collections.Generic;
  7. using System.Globalization;
  8. using System.IO;
  9. using System.Linq;
  10. using System.Text;
  11. using System.Text.RegularExpressions;
  12. using System.Xml;
  13. using System.Xml.Linq;
  14. using System.Xml.Xsl;
  15. using TEAMModelOS.SDK.Helper.Common.JsonHelper;
  16. using TEAMModelOS.Test.PPTX.PresentationElement;
  17. using ColorMap = DocumentFormat.OpenXml.Presentation.ColorMap;
  18. using Theme = DocumentFormat.OpenXml.Drawing.Theme;
  19. namespace TEAMModelOS.Test.PPTX
  20. {
  21. public class PresentationConvert
  22. {
  23. const int inchpixel = 96, inchpt = 72, pxBase = 914400, ptBase = 12700;
  24. const int rotBase = 60000;
  25. /// <summary>
  26. /// 处理一页PPT的元素
  27. /// </summary>
  28. /// <param name="slidePart"></param>
  29. /// <param name="theme"></param>
  30. /// <param name="colorMap"></param>
  31. /// <returns></returns>
  32. public List<HtexElement> GetSlideElement(SlidePart slidePart, Theme theme, ColorMap colorMap)
  33. {
  34. List<HtexElement> elements = new List<HtexElement>();
  35. var shapeTrees = from shap in slidePart.Slide.Descendants<DocumentFormat.OpenXml.Presentation.ShapeTree>() select shap;
  36. if (shapeTrees.Count() > 0 && shapeTrees.First().ChildElements.Count > 0)
  37. {
  38. OpenXmlElementList openXmlElements = shapeTrees.First().ChildElements;
  39. int index = 0;
  40. foreach (OpenXmlElement element in openXmlElements)
  41. {
  42. HtexElement pptElement = null;
  43. if (element is DocumentFormat.OpenXml.Presentation.Shape shape)
  44. { //p:sp
  45. pptElement = ShapeConvert(shape, theme, colorMap, index);
  46. }
  47. if (element is DocumentFormat.OpenXml.Presentation.Picture picture)//p:pic
  48. {
  49. pptElement = PictureConvert(picture, slidePart, index);
  50. }
  51. if (element is DocumentFormat.OpenXml.AlternateContent content)//mc:alternatecontent
  52. {
  53. pptElement = AlternateContentConvert(content, theme, colorMap, index);
  54. }
  55. if (element is DocumentFormat.OpenXml.Presentation.GraphicFrame graphicFrame)//p:graphicFrame
  56. {
  57. pptElement = GraphicFrameConvert(graphicFrame, theme, colorMap, index);
  58. }
  59. if (element is DocumentFormat.OpenXml.Presentation.GroupShape groupShape)//p:grpSp
  60. {
  61. pptElement = GroupShapeConvert(groupShape, theme, colorMap, index);
  62. }
  63. if (element is DocumentFormat.OpenXml.Presentation.ConnectionShape connectionShape) // p:cxnSp
  64. {
  65. pptElement = ConnectionShapeConvert(connectionShape, theme, colorMap, index);
  66. }
  67. if (pptElement != null) {
  68. index++;
  69. elements.Add(pptElement);
  70. }
  71. }
  72. }
  73. return elements;
  74. }
  75. public HtexElement GroupShapeConvert(GroupShape groupShape, Theme theme, ColorMap colorMap, int index)
  76. {
  77. return null;
  78. }
  79. public HtexElement ConnectionShapeConvert(ConnectionShape connectionShape, Theme theme, ColorMap colorMap, int index)
  80. {
  81. string type = "";
  82. string fillColor = "";
  83. ShapeProperties properties = connectionShape.ShapeProperties;
  84. IEnumerable<DocumentFormat.OpenXml.Drawing.PresetGeometry> presetGeometries = GetPresetGeometry(properties);
  85. if (presetGeometries.Count() > 0)
  86. {
  87. type = presetGeometries.FirstOrDefault().Preset;
  88. }
  89. HtexConnector element = new HtexConnector() { Type = type };
  90. if (properties != null)
  91. {
  92. if (properties.Transform2D != null)
  93. {
  94. element.OffX = properties.Transform2D.Offset.X * inchpixel/pxBase;
  95. element.OffY = properties.Transform2D.Offset.Y * inchpixel / pxBase;
  96. element.ExtX = properties.Transform2D.Extents.Cx * inchpixel / pxBase;
  97. element.ExtY = properties.Transform2D.Extents.Cy * inchpixel / pxBase;
  98. element.FlipH = properties.Transform2D.HorizontalFlip != null ? BooleanValue.ToBoolean(properties.Transform2D.HorizontalFlip) : false;
  99. element.FlipV = properties.Transform2D.VerticalFlip != null ? BooleanValue.ToBoolean(properties.Transform2D.VerticalFlip) : false;
  100. element.Rot = (properties.Transform2D.Rotation != null ? properties.Transform2D.Rotation.Value : 0)/rotBase;
  101. }
  102. var headEnd = from shap in properties.Descendants<DocumentFormat.OpenXml.Drawing.HeadEnd>() select shap;
  103. var tailEnd = from shap in properties.Descendants<DocumentFormat.OpenXml.Drawing.TailEnd>() select shap;
  104. if (headEnd != null && headEnd.Count() > 0)
  105. {
  106. element.HeadEnd = headEnd.First().Type;
  107. }
  108. if (tailEnd != null && tailEnd.Count() > 0)
  109. {
  110. element.TailEnd = tailEnd.First().Type;
  111. }
  112. fillColor = GetPropertieFillColor(properties, theme, colorMap);
  113. }
  114. if (string.IsNullOrEmpty(fillColor))
  115. {
  116. fillColor = GetShapeStyleColor(connectionShape.ShapeStyle, "Fill", theme);
  117. }
  118. element.FillColor = fillColor;
  119. return element;
  120. }
  121. public HtexElement GraphicFrameConvert(GraphicFrame graphicFrame, Theme theme, ColorMap colorMap, int index)
  122. {
  123. DocumentFormat.OpenXml.Drawing.GraphicData graphicData = graphicFrame.ChildElements.First<DocumentFormat.OpenXml.Drawing.GraphicData>();
  124. if (graphicData != null)
  125. {
  126. OpenXmlElement element = graphicData.ChildElements.First();
  127. if (element != null)
  128. {
  129. if (element is DocumentFormat.OpenXml.Drawing.Table table)
  130. {
  131. return TableConvert(graphicFrame, theme, colorMap);
  132. }
  133. if (element is DocumentFormat.OpenXml.Drawing.Chart chart)
  134. {
  135. //return ChartConvert(graphicFrame, theme, colorMap);
  136. }
  137. if (element is DocumentFormat.OpenXml.Drawing.Diagram diagram)
  138. {
  139. //return DiagramConvert(graphicFrame, theme, colorMap);
  140. }
  141. }
  142. }
  143. return null;
  144. }
  145. public HtexElement TableConvert(GraphicFrame graphicFrame, Theme theme, ColorMap colorMap)
  146. {
  147. return null;
  148. }
  149. /// <summary>
  150. /// 处理普通形状的元素
  151. /// </summary>
  152. /// <param name="shape"></param>
  153. /// <returns></returns>
  154. public HtexElement ShapeConvert(Shape shape, Theme theme, ColorMap colorMap, int index)
  155. {
  156. // shape.base
  157. //文字颜色
  158. string textColor = "";
  159. //填充颜色
  160. string fillColor = "";
  161. // 形状类型
  162. string type = "rect";
  163. //字体大小
  164. int fontSize = 1800;
  165. //是否闭合形状
  166. bool complete = false;
  167. ShapeProperties properties = shape.ShapeProperties;
  168. IEnumerable<DocumentFormat.OpenXml.Drawing.PresetGeometry> presetGeometries = GetPresetGeometry(properties);
  169. IEnumerable<DocumentFormat.OpenXml.Drawing.CustomGeometry> customGeometries = GetCustomGeometry(properties);
  170. if (presetGeometries.Count() > 0)
  171. {
  172. type = presetGeometries.FirstOrDefault().Preset;
  173. }
  174. if (customGeometries.Count() > 0)
  175. {
  176. type = "custom";
  177. }
  178. DocumentFormat.OpenXml.Drawing.Transform2D transform2D = GetTransform2D(properties);
  179. HtexContainer element = new HtexContainer() { Type = type };
  180. if (transform2D != null)
  181. {
  182. element.Close = complete;
  183. element.OffX = transform2D.Offset.X * inchpixel / pxBase;
  184. element.OffY = transform2D.Offset.Y * inchpixel / pxBase;
  185. element.ExtX = transform2D.Extents.Cx * inchpixel / pxBase;
  186. element.ExtY = transform2D.Extents.Cy * inchpixel / pxBase;
  187. element.FlipH = transform2D.HorizontalFlip != null ? BooleanValue.ToBoolean(transform2D.HorizontalFlip) : false;
  188. element.FlipV = transform2D.VerticalFlip != null ? BooleanValue.ToBoolean(transform2D.VerticalFlip) : false;
  189. element.Rot = transform2D.Rotation != null ? transform2D.Rotation.Value : 0;
  190. }
  191. element.Index = index;
  192. ///获取runs的文本及颜色信息
  193. var runs = from shap in shape.Descendants<DocumentFormat.OpenXml.Drawing.Run>() select shap;
  194. foreach (var run in runs)
  195. {
  196. HtexText text = new HtexText() ;
  197. var runprps = from shap in run.Descendants<DocumentFormat.OpenXml.Drawing.RunProperties>() select shap;
  198. DocumentFormat.OpenXml.Drawing.RunProperties runProperties = runprps.FirstOrDefault();
  199. if (runProperties != null)
  200. {
  201. if (runProperties.FontSize != null) {
  202. text.FontSize = runProperties.FontSize;
  203. }
  204. if (runProperties.Italic != null)
  205. {
  206. text.FontItalic = runProperties.Italic;
  207. }
  208. if (runProperties.Bold != null)
  209. {
  210. text.FontBold = runProperties.Bold;
  211. }
  212. //if (runProperties.Italic != null)
  213. //{
  214. // text.FontBold = runProperties.Bold;
  215. //}
  216. if (runProperties.Underline != null )
  217. {
  218. text.FontLine =(int)runProperties.Underline.Value;
  219. }
  220. }
  221. var schemeColor = from shap in run.Descendants<DocumentFormat.OpenXml.Drawing.SchemeColor>() select shap;
  222. var rgbColors = from shap in run.Descendants<DocumentFormat.OpenXml.Drawing.RgbColorModelHex>() select shap;
  223. textColor = GetSchemeColor(schemeColor, theme, colorMap);
  224. if (string.IsNullOrEmpty(textColor))
  225. {
  226. text.TextColor=textColor = GetRgbColor(rgbColors);
  227. }
  228. text.Text = run.InnerText;
  229. element.Texts.Add(text);
  230. }
  231. if (string.IsNullOrEmpty(textColor))
  232. {
  233. textColor = GetShapeStyleColor(shape.ShapeStyle, "Font", theme);
  234. }
  235. if (string.IsNullOrEmpty(fillColor))
  236. {
  237. fillColor = GetShapeStyleColor(shape.ShapeStyle, "Fill", theme);
  238. }
  239. if (string.IsNullOrEmpty(fillColor))
  240. {
  241. fillColor = GetPropertieFillColor(properties, theme, colorMap);
  242. }
  243. element.FillColor = fillColor;
  244. var custGeometrys = from shap in properties.Descendants<DocumentFormat.OpenXml.Drawing.CustomGeometry>() select shap;
  245. if (custGeometrys.Count() > 0)
  246. {
  247. var pathLists = from shap in custGeometrys.First().Descendants<DocumentFormat.OpenXml.Drawing.Path>() select shap;
  248. if (pathLists.Count() > 0)
  249. {
  250. element.Close = false;
  251. OpenXmlElementList elements = pathLists.First().ChildElements;
  252. foreach (OpenXmlElement xmlElement in elements)
  253. {
  254. //起点
  255. if (xmlElement is DocumentFormat.OpenXml.Drawing.MoveTo moveTo)
  256. {
  257. DocumentFormat.OpenXml.Drawing.Point point = moveTo.Point;
  258. HtexMoveToPath moveToPath = new HtexMoveToPath { Type = "MoveTo" };
  259. moveToPath.Pts.Add(new Point { X = int.Parse(point.X) * inchpixel / pxBase, Y = int.Parse(point.Y) * inchpixel / pxBase });
  260. element.Paths.Add(moveToPath);
  261. }
  262. //连线
  263. if (xmlElement is DocumentFormat.OpenXml.Drawing.LineTo linTo)
  264. {
  265. DocumentFormat.OpenXml.Drawing.Point point = linTo.Point;
  266. HtexLineToPath lineToPath = new HtexLineToPath { Type = "LineTo" };
  267. lineToPath.Pts.Add(new Point { X = int.Parse(point.X) * inchpixel / pxBase, Y = int.Parse(point.Y) * inchpixel / pxBase });
  268. element.Paths.Add(lineToPath);
  269. }
  270. //三次贝塞尔曲线
  271. if (xmlElement is DocumentFormat.OpenXml.Drawing.CubicBezierCurveTo cubicBezierCurveTo)
  272. {
  273. OpenXmlElementList list = cubicBezierCurveTo.ChildElements;
  274. HtexCubicBezPath cubicBezPath = new HtexCubicBezPath { Type = "CubicBez" };
  275. foreach (var ls in list)
  276. {
  277. if (ls is DocumentFormat.OpenXml.Drawing.Point point)
  278. {
  279. cubicBezPath.Pts.Add(new Point { X = int.Parse(point.X) * inchpixel / pxBase, Y = int.Parse(point.Y) * inchpixel / pxBase });
  280. }
  281. }
  282. element.Paths.Add(cubicBezPath);
  283. }
  284. //二次贝塞尔曲线
  285. if (xmlElement is DocumentFormat.OpenXml.Drawing.QuadraticBezierCurveTo quadraticBezierCurveTo)
  286. {
  287. OpenXmlElementList list = quadraticBezierCurveTo.ChildElements;
  288. HtexQuadBezPath quadBezPath = new HtexQuadBezPath { Type = "QuadBez" };
  289. foreach (var ls in list)
  290. {
  291. if (ls is DocumentFormat.OpenXml.Drawing.Point point)
  292. {
  293. quadBezPath.Pts.Add(new Point { X = int.Parse(point.X) * inchpixel / pxBase, Y =int.Parse(point.Y) * inchpixel / pxBase });
  294. }
  295. }
  296. element.Paths.Add(quadBezPath);
  297. }
  298. //处理曲线
  299. if (xmlElement is DocumentFormat.OpenXml.Drawing.ArcTo arcTO)
  300. {
  301. HtexArcToPath arcToPath = new HtexArcToPath() { WidthRadius = arcTO.WidthRadius, HeightRadius = arcTO.HeightRadius, StartAngle = arcTO.StartAngle, SwingAngle = arcTO.SwingAngle };
  302. element.Paths.Add(arcToPath);
  303. }
  304. ///判断路径是否闭合
  305. if (xmlElement is DocumentFormat.OpenXml.Drawing.CloseShapePath close)
  306. {
  307. if (close != null)
  308. {
  309. element.Close = true;
  310. }
  311. }
  312. }
  313. }
  314. }
  315. return element;
  316. }
  317. /// <summary>
  318. /// 处理图片的元素
  319. /// </summary>
  320. /// <param name="picture"></param>
  321. /// <returns></returns>
  322. public HtexElement PictureConvert(Picture picture, SlidePart slidePart, int index)
  323. {
  324. BlipFill blipFill = picture.BlipFill;
  325. var imageRid = blipFill.Blip.Embed.Value;
  326. IdPartPair idParie = slidePart.Parts.Where(x => x.RelationshipId == imageRid).FirstOrDefault();
  327. ImagePart imagePart = (ImagePart)idParie.OpenXmlPart;
  328. var contentType = imagePart.ContentType;
  329. string base64 = "";
  330. using (var stream = imagePart.GetStream())
  331. {
  332. byte[] buffer = new byte[stream.Length];
  333. stream.Read(buffer, 0, buffer.Length);
  334. stream.Close();
  335. base64 = System.Convert.ToBase64String(buffer);
  336. base64 = "data:" + contentType + ";base64," + base64;
  337. }
  338. ShapeProperties properties = picture.ShapeProperties;
  339. HtexPicture element = new HtexPicture();
  340. if (properties != null && properties.Transform2D != null)
  341. {
  342. element.OffX = properties.Transform2D.Offset.X * inchpixel / pxBase;
  343. element.OffY = properties.Transform2D.Offset.Y * inchpixel / pxBase;
  344. element.ExtX = properties.Transform2D.Extents.Cx * inchpixel / pxBase;
  345. element.ExtY = properties.Transform2D.Extents.Cy * inchpixel / pxBase;
  346. element.FlipH = properties.Transform2D.HorizontalFlip != null ? BooleanValue.ToBoolean(properties.Transform2D.HorizontalFlip) : false;
  347. element.FlipV = properties.Transform2D.VerticalFlip != null ? BooleanValue.ToBoolean(properties.Transform2D.VerticalFlip) : false;
  348. element.Rot = properties.Transform2D.Rotation != null ? properties.Transform2D.Rotation.Value : 0;
  349. }
  350. element.Data = base64;
  351. return element;
  352. }
  353. /// <summary>
  354. /// 处理兼容元素
  355. /// </summary>
  356. /// <param name="picture"></param>
  357. /// <returns></returns>
  358. public HtexElement AlternateContentConvert(AlternateContent content, Theme theme, ColorMap colorMap, int index)
  359. {
  360. AlternateContentChoice choice = content.ChildElements.First<AlternateContentChoice>();
  361. OpenXmlElement element = choice.ChildElements.First();
  362. if (element != null)
  363. {
  364. if (element is DocumentFormat.OpenXml.Presentation.Shape shape)
  365. {
  366. var textMaths = from shap in shape.Descendants<TextMath>() select shap;
  367. if (textMaths.Count() > 0)
  368. {
  369. return MathConvert(shape, theme, colorMap);
  370. }
  371. }
  372. }
  373. return null;
  374. }
  375. /// <summary>
  376. /// 处理公式
  377. /// </summary>
  378. /// <param name="shape"></param>
  379. /// <param name="theme"></param>
  380. /// <param name="colorMap"></param>
  381. /// <returns></returns>
  382. public HtexElement MathConvert(DocumentFormat.OpenXml.Presentation.Shape shape, Theme theme, ColorMap colorMap)
  383. {
  384. //文字颜色
  385. string textColor = "";
  386. //填充颜色
  387. string fillColor = "";
  388. // 形状类型
  389. string type = "math";
  390. //字体大小
  391. int fontSize = 1800;
  392. //是否闭合形状
  393. bool complete = true;
  394. ShapeProperties properties = shape.ShapeProperties;
  395. //IEnumerable<DocumentFormat.OpenXml.Drawing.PresetGeometry> presetGeometries = GetPresetGeometry(properties);
  396. //if (presetGeometries.Count() > 0)
  397. //{
  398. // type = presetGeometries.FirstOrDefault().Preset;
  399. //}
  400. DocumentFormat.OpenXml.Drawing.Transform2D transform2D = GetTransform2D(properties);
  401. HtexContainer element = new HtexContainer() { Type = type };
  402. if (transform2D != null)
  403. {
  404. element.Close = complete;
  405. element.OffX = properties.Transform2D.Offset.X * inchpixel / pxBase;
  406. element.OffY = properties.Transform2D.Offset.Y * inchpixel / pxBase;
  407. element.ExtX = properties.Transform2D.Extents.Cx * inchpixel / pxBase;
  408. element.ExtY = properties.Transform2D.Extents.Cy * inchpixel / pxBase;
  409. element.FlipH = properties.Transform2D.HorizontalFlip != null ? BooleanValue.ToBoolean(properties.Transform2D.HorizontalFlip) : false;
  410. element.FlipV = properties.Transform2D.VerticalFlip != null ? BooleanValue.ToBoolean(properties.Transform2D.VerticalFlip) : false;
  411. element.Rot = properties.Transform2D.Rotation != null ? properties.Transform2D.Rotation.Value : 0;
  412. }
  413. //获取行内样式
  414. if (string.IsNullOrEmpty(textColor))
  415. {
  416. var rgbColor = from shap in shape.TextBody.Descendants<DocumentFormat.OpenXml.Drawing.RgbColorModelHex>() select shap;
  417. textColor = GetRgbColor(rgbColor);
  418. if (string.IsNullOrEmpty(textColor))
  419. {
  420. var schemes = from shap in shape.TextBody.Descendants<DocumentFormat.OpenXml.Drawing.SchemeColor>() select shap;
  421. textColor = GetSchemeColor(schemes, theme, colorMap);
  422. }
  423. }
  424. if (string.IsNullOrEmpty(textColor))
  425. {
  426. textColor = GetShapeStyleColor(shape.ShapeStyle, "Font", theme);
  427. }
  428. if (string.IsNullOrEmpty(fillColor))
  429. {
  430. fillColor = GetShapeStyleColor(shape.ShapeStyle, "Fill", theme);
  431. }
  432. if (string.IsNullOrEmpty(fillColor))
  433. {
  434. fillColor = GetPropertieFillColor(properties, theme, colorMap);
  435. }
  436. element.FillColor = fillColor;
  437. var textMaths = from shap in shape.Descendants<TextMath>() select shap;
  438. var math = textMaths.First<TextMath>();
  439. string elementData = ProcessOMath(math.InnerXml);
  440. element.Texts.Add(new HtexText { TextColor = textColor, Text = elementData, FontSize = fontSize });
  441. return element;
  442. }
  443. /// <summary>
  444. /// 处理元素的Transform2D属性
  445. /// </summary>
  446. /// <param name="properties"></param>
  447. /// <returns></returns>
  448. public DocumentFormat.OpenXml.Drawing.Transform2D GetTransform2D(ShapeProperties properties)
  449. {
  450. if (properties != null)
  451. {
  452. return properties.Transform2D;
  453. }
  454. return null;
  455. }
  456. /// <summary>
  457. /// 处理元素的Transform2D 系统默认的元素
  458. /// </summary>
  459. /// <param name="properties"></param>
  460. /// <returns></returns>
  461. public IEnumerable<DocumentFormat.OpenXml.Drawing.PresetGeometry> GetPresetGeometry(ShapeProperties properties)
  462. {
  463. if (properties != null)
  464. {
  465. var presetGeometrys = from shap in properties.Descendants<DocumentFormat.OpenXml.Drawing.PresetGeometry>() select shap;
  466. return presetGeometrys;
  467. }
  468. return null;
  469. }
  470. public IEnumerable<DocumentFormat.OpenXml.Drawing.CustomGeometry> GetCustomGeometry(ShapeProperties properties)
  471. {
  472. if (properties != null)
  473. {
  474. var customGeometrys = from shap in properties.Descendants<DocumentFormat.OpenXml.Drawing.CustomGeometry>() select shap;
  475. return customGeometrys;
  476. }
  477. return null;
  478. }
  479. /// <summary>
  480. /// 处理元素属性的填充色
  481. /// </summary>
  482. /// <param name="properties"></param>
  483. /// <returns></returns>
  484. public string GetPropertieFillColor(ShapeProperties properties, Theme theme, ColorMap colorMap)
  485. {
  486. string fillColor = "";
  487. if (properties != null)
  488. {
  489. var solidFills = from shape in properties.Descendants<DocumentFormat.OpenXml.Drawing.SolidFill>() select shape;
  490. if (solidFills.Count() > 0)
  491. {
  492. var propRgbColor = from shape in solidFills.First().Descendants<DocumentFormat.OpenXml.Drawing.RgbColorModelHex>() select shape;
  493. fillColor = GetRgbColor(propRgbColor);
  494. if (string.IsNullOrEmpty(fillColor))
  495. {
  496. var colorScheme = from shape in solidFills.First().Descendants<DocumentFormat.OpenXml.Drawing.SchemeColor>() select shape;
  497. fillColor = GetSchemeColor(colorScheme, theme, colorMap);
  498. }
  499. }
  500. }
  501. return fillColor;
  502. }
  503. /// <summary>
  504. /// 获取ShapeStyle样式表 各种属性 的颜色
  505. /// </summary>
  506. /// <param name="shapeStyle"></param>
  507. /// <param name="colorType"></param>
  508. /// <param name="theme"></param>
  509. /// <returns></returns>
  510. public string GetShapeStyleColor(DocumentFormat.OpenXml.Presentation.ShapeStyle shapeStyle, string colorType, Theme theme)
  511. {
  512. if (shapeStyle == null)
  513. {
  514. return "";
  515. }
  516. // 效果颜色
  517. if (colorType.Equals("Effect"))
  518. {
  519. DocumentFormat.OpenXml.Drawing.SchemeColor EffectcolorScheme = shapeStyle.EffectReference.ChildElements.First<DocumentFormat.OpenXml.Drawing.SchemeColor>();
  520. return ColorForThemeClr(EffectcolorScheme.Val, theme);
  521. }
  522. // 线条颜色
  523. if (colorType.Equals("Line"))
  524. {
  525. DocumentFormat.OpenXml.Drawing.SchemeColor LinecolorScheme = shapeStyle.LineReference.ChildElements.First<DocumentFormat.OpenXml.Drawing.SchemeColor>();
  526. return ColorForThemeClr(LinecolorScheme.Val, theme);
  527. }
  528. // 填充色
  529. if (colorType.Equals("Fill"))
  530. {
  531. DocumentFormat.OpenXml.Drawing.SchemeColor FillcolorScheme = shapeStyle.FillReference.ChildElements.First<DocumentFormat.OpenXml.Drawing.SchemeColor>();
  532. return ColorForThemeClr(FillcolorScheme.Val, theme);
  533. }
  534. // 字体颜色
  535. if (colorType.Equals("Font"))
  536. {
  537. DocumentFormat.OpenXml.Drawing.SchemeColor FontcolorScheme = shapeStyle.FontReference.ChildElements.First<DocumentFormat.OpenXml.Drawing.SchemeColor>();
  538. return ColorForThemeClr(FontcolorScheme.Val, theme);
  539. }
  540. return "";
  541. }
  542. /// <summary>
  543. /// 获取声明式颜色
  544. /// </summary>
  545. /// <param name="rgbColors"></param>
  546. /// <returns></returns>
  547. public string GetSchemeColor(IEnumerable<DocumentFormat.OpenXml.Drawing.SchemeColor> colorScheme, Theme theme, ColorMap colorMap)
  548. {
  549. string rgbColor = "";
  550. if (colorScheme.Count() > 0)
  551. {
  552. rgbColor = ColorForThemeClr(SchemeColorForColorMap(colorScheme.FirstOrDefault().Val.Value, colorMap), theme);
  553. }
  554. return rgbColor;
  555. }
  556. /// <summary>
  557. /// 获取RGBColor
  558. /// </summary>
  559. /// <param name="rgbColors"></param>
  560. /// <returns></returns>
  561. public string GetRgbColor(IEnumerable<DocumentFormat.OpenXml.Drawing.RgbColorModelHex> rgbColors)
  562. {
  563. string rgbColor = "";
  564. if (rgbColors.Count() > 0)
  565. {
  566. rgbColor = rgbColors.FirstOrDefault().Val;
  567. }
  568. return rgbColor;
  569. }
  570. /// <summary>
  571. /// 加载PPTX文件
  572. /// </summary>
  573. /// <param name="presentationFile"></param>
  574. /// <returns></returns>
  575. public object LoadPresentation(string presentationFile)
  576. {
  577. using (PresentationDocument presentationDocument = PresentationDocument.Open(presentationFile, false))
  578. {
  579. if (presentationDocument == null)
  580. {
  581. throw new ArgumentNullException("presentationDocument");
  582. }
  583. // Get a PresentationPart object from the PresentationDocument object.
  584. PresentationPart presentationPart = presentationDocument.PresentationPart;
  585. if (presentationPart != null && presentationPart.Presentation != null)
  586. {
  587. var slideMasterParts = presentationPart.SlideMasterParts;
  588. ColorMap colorMap = null;
  589. Theme theme = null;
  590. foreach (var slideMasterPart in slideMasterParts)
  591. {
  592. if (colorMap != null && theme != null)
  593. {
  594. break;
  595. }
  596. colorMap = slideMasterPart.SlideMaster.ColorMap;
  597. theme = slideMasterPart.ThemePart.Theme;
  598. }
  599. // Get a Presentation object from the PresentationPart object.
  600. Presentation presentation = presentationPart.Presentation;
  601. if (presentation.SlideIdList != null)
  602. {
  603. //获取PPT 一页大小
  604. int x = presentation.SlideSize.Cx;
  605. int y = presentation.SlideSize.Cy;
  606. // Get the title of each slide in the slide order.
  607. // 获取的是几页PPT数量
  608. foreach (var slideId in presentation.SlideIdList.Elements<SlideId>())
  609. {
  610. // 获取这一页 PPT 的id
  611. string id = slideId.RelationshipId;
  612. SlidePart slidePart = presentationPart.GetPartById(slideId.RelationshipId) as SlidePart;
  613. //获取当前页 PPT 的所有元素
  614. GetSlideElement(slidePart, theme, colorMap);
  615. }
  616. }
  617. }
  618. return null;
  619. }
  620. }
  621. /// <summary>
  622. /// 在主题Theme中获取颜色
  623. /// </summary>
  624. /// <param name="scv"></param>
  625. /// <param name="theme"></param>
  626. /// <returns></returns>
  627. public static string ColorForThemeClr(string scv, Theme theme)
  628. {
  629. DocumentFormat.OpenXml.Drawing.ColorScheme colorScheme = theme.ThemeElements.ColorScheme;
  630. string colorStr = "";
  631. if (scv.Equals("dk1"))
  632. {
  633. DocumentFormat.OpenXml.Drawing.SystemColor sysColor = colorScheme.Dark1Color.ChildElements.First<DocumentFormat.OpenXml.Drawing.SystemColor>();
  634. if (sysColor != null)
  635. {
  636. return sysColor.LastColor;
  637. }
  638. DocumentFormat.OpenXml.Drawing.RgbColorModelHex rgbColor = colorScheme.Dark1Color.ChildElements.First<DocumentFormat.OpenXml.Drawing.RgbColorModelHex>();
  639. if (rgbColor != null)
  640. {
  641. return rgbColor.Val;
  642. }
  643. return colorStr;
  644. }
  645. if (scv.Equals("dk2"))
  646. {
  647. DocumentFormat.OpenXml.Drawing.SystemColor sysColor = colorScheme.Dark2Color.ChildElements.First<DocumentFormat.OpenXml.Drawing.SystemColor>();
  648. if (sysColor != null)
  649. {
  650. return sysColor.LastColor;
  651. }
  652. DocumentFormat.OpenXml.Drawing.RgbColorModelHex rgbColor = colorScheme.Dark2Color.ChildElements.First<DocumentFormat.OpenXml.Drawing.RgbColorModelHex>();
  653. if (rgbColor != null)
  654. {
  655. return rgbColor.Val;
  656. }
  657. return colorStr;
  658. }
  659. else if (scv.Equals("accent1"))
  660. {
  661. DocumentFormat.OpenXml.Drawing.SystemColor sysColor = colorScheme.Accent1Color.ChildElements.First<DocumentFormat.OpenXml.Drawing.SystemColor>();
  662. if (sysColor != null)
  663. {
  664. return sysColor.LastColor;
  665. }
  666. DocumentFormat.OpenXml.Drawing.RgbColorModelHex rgbColor = colorScheme.Accent1Color.ChildElements.First<DocumentFormat.OpenXml.Drawing.RgbColorModelHex>();
  667. if (rgbColor != null)
  668. {
  669. return rgbColor.Val;
  670. }
  671. return colorStr;
  672. }
  673. else if (scv.Equals("accent2"))
  674. {
  675. DocumentFormat.OpenXml.Drawing.SystemColor sysColor = colorScheme.Accent2Color.ChildElements.First<DocumentFormat.OpenXml.Drawing.SystemColor>();
  676. if (sysColor != null)
  677. {
  678. return sysColor.LastColor;
  679. }
  680. DocumentFormat.OpenXml.Drawing.RgbColorModelHex rgbColor = colorScheme.Accent2Color.ChildElements.First<DocumentFormat.OpenXml.Drawing.RgbColorModelHex>();
  681. if (rgbColor != null)
  682. {
  683. return rgbColor.Val;
  684. }
  685. return colorStr;
  686. }
  687. else if (scv.Equals("accent3"))
  688. {
  689. DocumentFormat.OpenXml.Drawing.SystemColor sysColor = colorScheme.Accent3Color.ChildElements.First<DocumentFormat.OpenXml.Drawing.SystemColor>();
  690. if (sysColor != null)
  691. {
  692. return sysColor.LastColor;
  693. }
  694. DocumentFormat.OpenXml.Drawing.RgbColorModelHex rgbColor = colorScheme.Accent3Color.ChildElements.First<DocumentFormat.OpenXml.Drawing.RgbColorModelHex>();
  695. if (rgbColor != null)
  696. {
  697. return rgbColor.Val;
  698. }
  699. return colorStr;
  700. }
  701. else if (scv.Equals("accent4"))
  702. {
  703. DocumentFormat.OpenXml.Drawing.SystemColor sysColor = colorScheme.Accent4Color.ChildElements.First<DocumentFormat.OpenXml.Drawing.SystemColor>();
  704. if (sysColor != null)
  705. {
  706. return sysColor.LastColor;
  707. }
  708. DocumentFormat.OpenXml.Drawing.RgbColorModelHex rgbColor = colorScheme.Accent4Color.ChildElements.First<DocumentFormat.OpenXml.Drawing.RgbColorModelHex>();
  709. if (rgbColor != null)
  710. {
  711. return rgbColor.Val;
  712. }
  713. return colorStr;
  714. }
  715. else if (scv.Equals("accent5"))
  716. {
  717. DocumentFormat.OpenXml.Drawing.SystemColor sysColor = colorScheme.Accent5Color.ChildElements.First<DocumentFormat.OpenXml.Drawing.SystemColor>();
  718. if (sysColor != null)
  719. {
  720. return sysColor.LastColor;
  721. }
  722. DocumentFormat.OpenXml.Drawing.RgbColorModelHex rgbColor = colorScheme.Accent5Color.ChildElements.First<DocumentFormat.OpenXml.Drawing.RgbColorModelHex>();
  723. if (rgbColor != null)
  724. {
  725. return rgbColor.Val;
  726. }
  727. return colorStr;
  728. }
  729. else if (scv.Equals("accent6"))
  730. {
  731. DocumentFormat.OpenXml.Drawing.SystemColor sysColor = colorScheme.Accent6Color.ChildElements.First<DocumentFormat.OpenXml.Drawing.SystemColor>();
  732. if (sysColor != null)
  733. {
  734. return sysColor.LastColor;
  735. }
  736. DocumentFormat.OpenXml.Drawing.RgbColorModelHex rgbColor = colorScheme.Accent6Color.ChildElements.First<DocumentFormat.OpenXml.Drawing.RgbColorModelHex>();
  737. if (rgbColor != null)
  738. {
  739. return rgbColor.Val;
  740. }
  741. return colorStr;
  742. }
  743. else if (scv.Equals("lt1"))
  744. {
  745. DocumentFormat.OpenXml.Drawing.SystemColor sysColor = colorScheme.Light1Color.ChildElements.First<DocumentFormat.OpenXml.Drawing.SystemColor>();
  746. if (sysColor != null)
  747. {
  748. return sysColor.LastColor;
  749. }
  750. DocumentFormat.OpenXml.Drawing.RgbColorModelHex rgbColor = colorScheme.Light1Color.ChildElements.First<DocumentFormat.OpenXml.Drawing.RgbColorModelHex>();
  751. if (rgbColor != null)
  752. {
  753. return rgbColor.Val;
  754. }
  755. return colorStr;
  756. }
  757. else if (scv.Equals("lt2"))
  758. {
  759. DocumentFormat.OpenXml.Drawing.SystemColor sysColor = colorScheme.Light2Color.ChildElements.First<DocumentFormat.OpenXml.Drawing.SystemColor>();
  760. if (sysColor != null)
  761. {
  762. return sysColor.LastColor;
  763. }
  764. DocumentFormat.OpenXml.Drawing.RgbColorModelHex rgbColor = colorScheme.Light2Color.ChildElements.First<DocumentFormat.OpenXml.Drawing.RgbColorModelHex>();
  765. if (rgbColor != null)
  766. {
  767. return rgbColor.Val;
  768. }
  769. return colorStr;
  770. }
  771. else if (scv.Equals("hlink"))
  772. {
  773. DocumentFormat.OpenXml.Drawing.SystemColor sysColor = colorScheme.Hyperlink.ChildElements.First<DocumentFormat.OpenXml.Drawing.SystemColor>();
  774. if (sysColor != null)
  775. {
  776. return sysColor.LastColor;
  777. }
  778. DocumentFormat.OpenXml.Drawing.RgbColorModelHex rgbColor = colorScheme.Hyperlink.ChildElements.First<DocumentFormat.OpenXml.Drawing.RgbColorModelHex>();
  779. if (rgbColor != null)
  780. {
  781. return rgbColor.Val;
  782. }
  783. return colorStr;
  784. }
  785. else if (scv.Equals("folHlink"))
  786. {
  787. DocumentFormat.OpenXml.Drawing.SystemColor sysColor = colorScheme.FollowedHyperlinkColor.ChildElements.First<DocumentFormat.OpenXml.Drawing.SystemColor>();
  788. if (sysColor != null)
  789. {
  790. return sysColor.LastColor;
  791. }
  792. DocumentFormat.OpenXml.Drawing.RgbColorModelHex rgbColor = colorScheme.FollowedHyperlinkColor.ChildElements.First<DocumentFormat.OpenXml.Drawing.RgbColorModelHex>();
  793. if (rgbColor != null)
  794. {
  795. return rgbColor.Val;
  796. }
  797. return colorStr;
  798. }
  799. return "";
  800. }
  801. /// <summary>
  802. /// 按照ColorMap 去寻找对应的颜色
  803. /// </summary>
  804. /// <param name="schemeColorValues"></param>
  805. /// <param name="colorMap"></param>
  806. /// <returns></returns>
  807. public static string SchemeColorForColorMap(DocumentFormat.OpenXml.Drawing.SchemeColorValues schemeColorValues, ColorMap colorMap)
  808. {
  809. string scv = schemeColorValues.ToString();
  810. if (scv.Equals("Text1"))
  811. {
  812. return colorMap.Text1.ToString();
  813. }
  814. if (scv.Equals("Text2"))
  815. {
  816. return colorMap.Text2.ToString();
  817. }
  818. else if (scv.Equals("Accent1"))
  819. {
  820. return colorMap.Accent1.ToString();
  821. }
  822. else if (scv.Equals("Accent2"))
  823. {
  824. return colorMap.Accent2.ToString();
  825. }
  826. else if (scv.Equals("Accent3"))
  827. {
  828. return colorMap.Accent3.ToString();
  829. }
  830. else if (scv.Equals("Accent4"))
  831. {
  832. return colorMap.Accent4.ToString();
  833. }
  834. else if (scv.Equals("Accent5"))
  835. {
  836. return colorMap.Accent5.ToString();
  837. }
  838. else if (scv.Equals("Accent6"))
  839. {
  840. return colorMap.Accent6.ToString();
  841. }
  842. else if (scv.Equals("Background1"))
  843. {
  844. return colorMap.Background1.ToString();
  845. }
  846. else if (scv.Equals("Background2"))
  847. {
  848. return colorMap.Background2.ToString();
  849. }
  850. else if (scv.Equals("Hyperlink"))
  851. {
  852. return colorMap.Hyperlink.ToString();
  853. }
  854. else if (scv.Equals("FollowedHyperlink"))
  855. {
  856. return colorMap.FollowedHyperlink.ToString();
  857. }
  858. else if (scv.Equals("PhColor"))
  859. {
  860. return "PhColor";
  861. }
  862. else if (scv.Equals("Dark1"))
  863. {
  864. return "dk1";
  865. }
  866. else if (scv.Equals("Dark2"))
  867. {
  868. return "dk2";
  869. }
  870. else if (scv.Equals("Light1"))
  871. {
  872. return "lt1";
  873. }
  874. else if (scv.Equals("Light2"))
  875. {
  876. return "lt2";
  877. }
  878. return null;
  879. }
  880. /// <summary>
  881. /// 转换Surrogate 类型的编码的字符串
  882. /// </summary>
  883. /// <param name="xml"></param>
  884. /// <returns></returns>
  885. public static Dictionary<string, string> StringEncode(string xml)
  886. {
  887. Dictionary<string, string> codeValues = new Dictionary<string, string>();
  888. Char[] charstr = xml.ToCharArray();
  889. int len = charstr.Length;
  890. for (int i = 0; i < len; i++)
  891. {
  892. var stringBuilder = "";
  893. string str = Char.ToString(charstr[i]);
  894. if (Char.GetUnicodeCategory(charstr[i]) == UnicodeCategory.Surrogate)
  895. {
  896. string str1 = Char.ToString(charstr[i + 1]);
  897. str += str1;
  898. var bytes = Encoding.UTF32.GetBytes(str);
  899. for (var j = 0; j < bytes.Length; j += 2)
  900. {
  901. stringBuilder = bytes[j + 1].ToString("x").PadLeft(2, '0') + bytes[j].ToString("x").PadLeft(2, '0') + stringBuilder;
  902. }
  903. var id = Convert.ToInt64(stringBuilder, 16);
  904. i += 1;
  905. string code = id + "";
  906. codeValues.TryAdd(str, code);
  907. }
  908. }
  909. return codeValues;
  910. }
  911. /// <summary>
  912. /// 根据OfficeML转换为MathML
  913. /// </summary>
  914. /// <param name="innerXml"></param>
  915. /// <returns></returns>
  916. public static string ProcessOMath(string innerXml)
  917. {
  918. Dictionary<string, string> codeValues = StringEncode(innerXml);
  919. if (codeValues != null)
  920. {
  921. foreach (string codeValue in codeValues.Keys)
  922. {
  923. innerXml = Regex.Replace(innerXml, codeValue, codeValues[codeValue]);
  924. }
  925. }
  926. XElement element = XElement.Load(new StringReader(innerXml));
  927. List<XElement> elements = element.Elements().ToList();
  928. element = elements.Where(x => x.Name.LocalName.Equals("oMath")).FirstOrDefault();
  929. XslCompiledTransform xslTransform = new XslCompiledTransform();
  930. xslTransform.Load("E:/document/OMML2MML.XSL");
  931. string mathXml = element.ToString();
  932. string officeML = string.Empty;
  933. using (TextReader tr = new StringReader(mathXml))
  934. {
  935. using (XmlReader reader = XmlReader.Create(tr))
  936. {
  937. using (MemoryStream ms = new MemoryStream())
  938. {
  939. XmlWriterSettings settings = xslTransform.OutputSettings.Clone();
  940. settings.ConformanceLevel = ConformanceLevel.Fragment;
  941. settings.OmitXmlDeclaration = true;
  942. settings.Encoding = Encoding.Unicode;
  943. XmlWriter xw = XmlWriter.Create(ms, settings);
  944. xslTransform.Transform(reader, xw);
  945. ms.Seek(0, SeekOrigin.Begin);
  946. using (StreamReader sr = new StreamReader(ms, Encoding.UTF8))
  947. {
  948. officeML = sr.ReadToEnd();
  949. }
  950. }
  951. }
  952. }
  953. officeML = officeML.Replace("mml:", "");
  954. if (codeValues != null)
  955. {
  956. foreach (string codeValue in codeValues.Keys)
  957. {
  958. officeML = Regex.Replace(officeML, codeValues[codeValue], codeValue);
  959. }
  960. }
  961. return officeML;
  962. }
  963. }
  964. }