PowerPointService.cs 21 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433
  1. using DocumentFormat.OpenXml;
  2. using DocumentFormat.OpenXml.Drawing;
  3. using DocumentFormat.OpenXml.Packaging;
  4. using DocumentFormat.OpenXml.Presentation;
  5. using HiTeachCC.Model.PowerPoint;
  6. using HiTeachCC.Service.Core.Implement;
  7. using HiTeachCC.Service.PowerPoint.Interface;
  8. using System;
  9. using System.Collections.Generic;
  10. using System.IO;
  11. using System.Linq;
  12. using System.Xml;
  13. using ColorMap = DocumentFormat.OpenXml.Presentation.ColorMap;
  14. using Theme = DocumentFormat.OpenXml.Drawing.Theme;
  15. namespace HiTeachCC.Service.PowerPoint.Implement
  16. {
  17. public class PowerPointService : BaseService, IPowerPointService
  18. {
  19. const double inchpixel = 96.00, inchpt = 72.00, pxBase = 914400.00, ptBase = 12700;
  20. const double rotBase = 60000.00;
  21. /// <summary>
  22. /// 加载PPTX文件
  23. /// </summary>
  24. /// <param name="presentationFile"></param>
  25. /// <returns></returns>
  26. public Pptx LoadPresentation(Stream presentationStream)
  27. {
  28. using (PresentationDocument presentationDocument = PresentationDocument.Open(presentationStream, false))
  29. {
  30. if (presentationDocument == null)
  31. {
  32. throw new ArgumentNullException("presentationDocument");
  33. }
  34. // Get a PresentationPart object from the PresentationDocument object.
  35. var thumbnailPart = presentationDocument.ThumbnailPart;
  36. var contentType = thumbnailPart.ContentType;
  37. string base64 = "";
  38. using (var stream = thumbnailPart.GetStream())
  39. {
  40. byte[] buffer = new byte[stream.Length];
  41. stream.Read(buffer, 0, buffer.Length);
  42. stream.Close();
  43. base64 = System.Convert.ToBase64String(buffer);
  44. base64 = "data:" + contentType + ";base64," + base64;
  45. }
  46. PresentationPart presentationPart = presentationDocument.PresentationPart;
  47. if (presentationPart != null && presentationPart.Presentation != null)
  48. {
  49. // Get a Presentation object from the PresentationPart object.
  50. Presentation presentation = presentationPart.Presentation;
  51. int pageSize = 0;
  52. var slideMasterParts = presentationPart.SlideMasterParts;
  53. ColorMap colorMap = null;
  54. SlideMaster slideMaster = null;
  55. Theme theme = null;
  56. foreach (var slideMasterPart in slideMasterParts)
  57. {
  58. if (colorMap != null && theme != null)
  59. {
  60. break;
  61. }
  62. slideMaster = slideMasterPart.SlideMaster;
  63. colorMap = slideMasterPart.SlideMaster.ColorMap;
  64. theme = slideMasterPart.ThemePart.Theme;
  65. }
  66. Dictionary<string, string> slideMasterColors = PowerPointHelper.DoColorMap(null, colorMap, theme);
  67. //获取PPT 一页大小
  68. double x = presentation.SlideSize.Cx * inchpixel / pxBase;
  69. double y = presentation.SlideSize.Cy * inchpixel / pxBase;
  70. List<HiTeachCC.Model.PowerPoint.Slide> slides = new List<HiTeachCC.Model.PowerPoint.Slide>();
  71. string slideMasterXml = slideMaster.OuterXml;
  72. Style slideMasterStyle = PowerPointHelper.IndexNodes(slideMasterXml);
  73. if (presentation.SlideIdList != null)
  74. {
  75. // presentation.SlideIdList.OrderBy(x=>x.);
  76. // Get the title of each slide in the slide order.
  77. // 获取的是几页PPT数量
  78. foreach (var slideId in presentation.SlideIdList.Elements<SlideId>())
  79. {
  80. HiTeachCC.Model.PowerPoint.Slide slide = new HiTeachCC.Model.PowerPoint.Slide();
  81. // 获取这一页 PPT 的id
  82. string id = slideId.RelationshipId;
  83. SlidePart slidePart = presentationPart.GetPartById(slideId.RelationshipId) as SlidePart;
  84. //获取当前页 PPT 的所有元素
  85. // slide.Items = GetSlideElement(slidePart, theme, colorMap);
  86. //slide.Xml = slidePart.Slide.OuterXml;
  87. GetSlideElement(slidePart, slideMaster, slideMasterColors, theme, slideMasterStyle);
  88. slides.Add(slide);
  89. pageSize++;
  90. }
  91. }
  92. Pptx info = new Pptx { Slides = slides, Width = x, Height = y, PageSize = pageSize, Thumbnail = base64 };
  93. return info;
  94. }
  95. return null;
  96. }
  97. }
  98. /// <summary>
  99. /// 处理图形非可视化信息
  100. /// </summary>
  101. /// <param name="slidePart"></param>
  102. /// <param name="slideMaster"></param>
  103. /// <param name="slideMasterColors"></param>
  104. /// <param name="theme"></param>
  105. /// <param name="slideMasterStyle"></param>
  106. /// <returns></returns>
  107. public HiTeachCC.Model.PowerPoint.Slide GetSlideElement(SlidePart slidePart, SlideMaster slideMaster, Dictionary<string, string> slideMasterColors, Theme theme, Style slideMasterStyle)
  108. {
  109. //slidePart.SlideLayoutPart;
  110. string bgColor = PowerPointHelper.GetSlideBackgroundFill(slidePart, slideMaster, slideMasterColors, theme);
  111. string slideLayoutXml = slidePart.SlideLayoutPart.SlideLayout.OuterXml;
  112. var slideLayoutStyle = PowerPointHelper.IndexNodes(slideLayoutXml);
  113. var shapeTrees = from shap in slidePart.Slide.Descendants<ShapeTree>() select shap;
  114. if (shapeTrees.Count() > 0 && shapeTrees.First().ChildElements.Count > 0)
  115. {
  116. OpenXmlElementList openXmlElements = shapeTrees.First().ChildElements;
  117. TransformGroup transformGroup = shapeTrees.First().GroupShapeProperties.TransformGroup;
  118. HiTeachCC.Model.PowerPoint.Position position = new
  119. HiTeachCC.Model.PowerPoint.Position();
  120. position.Rot = transformGroup.Rotation == null ? 0 : transformGroup.Rotation.Value;
  121. position.FlipH = transformGroup.HorizontalFlip == null ? false : transformGroup.HorizontalFlip.Value;
  122. position.FlipV = transformGroup.VerticalFlip == null ? false : transformGroup.VerticalFlip.Value;
  123. position.X = transformGroup.Offset.X == null ? 0 : transformGroup.Offset.X.Value;
  124. position.Y = transformGroup.Offset.Y == null ? 0 : transformGroup.Offset.Y.Value;
  125. position.Cx = transformGroup.Extents.Cx == null ? 0 : transformGroup.Extents.Cx.Value;
  126. position.Cy = transformGroup.Extents.Cy == null ? 0 : transformGroup.Extents.Cy.Value;
  127. position.ChX = transformGroup.ChildOffset.X == null ? 0 : transformGroup.ChildOffset.X.Value;
  128. position.ChY = transformGroup.ChildOffset.Y == null ? 0 : transformGroup.ChildOffset.Y.Value;
  129. position.ChCX = transformGroup.ChildExtents.Cx == null ? 0 : transformGroup.ChildExtents.Cx.Value;
  130. position.ChCY = transformGroup.ChildExtents.Cy == null ? 0 : transformGroup.ChildExtents.Cy.Value;
  131. int index = 0;
  132. foreach (OpenXmlElement element in openXmlElements)
  133. {
  134. ProcessNodesInSlide(element, slidePart, slideMaster, slideMasterColors, index, position, slideLayoutStyle, slideMasterStyle);
  135. index++;
  136. }
  137. }
  138. return null;
  139. }
  140. /// <summary>
  141. /// 单个元素分类
  142. /// </summary>
  143. /// <param name="element"></param>
  144. /// <param name="slidePart"></param>
  145. /// <param name="slideMaster"></param>
  146. /// <param name="slideMasterColors"></param>
  147. /// <param name="index"></param>
  148. /// <param name="position"></param>
  149. /// <param name="slideLayoutStyle"></param>
  150. /// <param name="slideMasterStyle"></param>
  151. /// <returns></returns>
  152. public string ProcessNodesInSlide(OpenXmlElement element,
  153. SlidePart slidePart,
  154. SlideMaster slideMaster,
  155. Dictionary<string, string> slideMasterColors,
  156. int index,
  157. HiTeachCC.Model.PowerPoint.Position position,
  158. Style slideLayoutStyle,
  159. Style slideMasterStyle)
  160. {
  161. if (element is DocumentFormat.OpenXml.Presentation.Shape sp)//p:sp
  162. {
  163. // pptElement = ShapeConvert(shape, theme, colorMap, index);
  164. ProcessSpNode(sp, slidePart, slideMaster, slideMasterColors, index, position, slideLayoutStyle, slideMasterStyle);
  165. }
  166. else if (element is DocumentFormat.OpenXml.Presentation.Picture pic)//p:pic
  167. {
  168. ProcessPicNode(pic, slidePart, slideMaster, slideMasterColors, index, position, slideLayoutStyle, slideMasterStyle);
  169. // pptElement = PictureConvert(picture, theme, colorMap, slidePart, index);
  170. }
  171. else if (element is DocumentFormat.OpenXml.AlternateContent mc)//mc:alternatecontent
  172. {
  173. ProcessMcNode(mc, slidePart, slideMaster, slideMasterColors, index, position, slideLayoutStyle, slideMasterStyle);
  174. /// pptElement = AlternateContentConvert(content, theme, colorMap, slidePart, index);
  175. }
  176. else if (element is DocumentFormat.OpenXml.Presentation.GraphicFrame graphicFrame)//p:graphicFrame
  177. {
  178. ProcessGraphicFrameNode(graphicFrame, slidePart, slideMaster, slideMasterColors, index, position, slideLayoutStyle, slideMasterStyle);
  179. /// pptElement = GraphicFrameConvert(graphicFrame, theme, colorMap, index);
  180. }
  181. else if (element is DocumentFormat.OpenXml.Presentation.GroupShape grpSp)//p:grpSp
  182. {
  183. ProcessGrpSpNode(grpSp, slidePart, slideMaster, slideMasterColors, index, position, slideLayoutStyle, slideMasterStyle);
  184. /// pptElement = GroupShapeConvert(groupShape, theme, colorMap, index);
  185. }
  186. else if (element is DocumentFormat.OpenXml.Presentation.ConnectionShape cxnSp) // p:cxnSp
  187. {
  188. ProcessCxnSpNode(cxnSp, slidePart, slideMaster, slideMasterColors, index, position, slideLayoutStyle, slideMasterStyle);
  189. /// pptElement = ConnectionShapeConvert(connectionShape, theme, colorMap, index);
  190. }
  191. return null;
  192. }
  193. /// <summary>
  194. /// 处理Shape的样式 位置信息
  195. /// </summary>
  196. /// <param name="element"></param>
  197. /// <param name="slidePart"></param>
  198. /// <param name="slideMaster"></param>
  199. /// <param name="colors"></param>
  200. /// <param name="index"></param>
  201. /// <param name="position"></param>
  202. /// <param name="slideLayoutStyle"></param>
  203. /// <param name="slideMasterStyle"></param>
  204. /// <returns></returns>
  205. public string ProcessSpNode(DocumentFormat.OpenXml.Presentation.Shape element, SlidePart slidePart, SlideMaster slideMaster,
  206. Dictionary<string, string> colors, int index, HiTeachCC.Model.PowerPoint.Position position,
  207. Style slideLayoutStyle,
  208. Style slideMasterStyle)
  209. {
  210. HiTeachCC.Model.PowerPoint.Shape shape = new HiTeachCC.Model.PowerPoint.Shape();
  211. HiTeachCC.Model.PowerPoint.Position spPosition = null;
  212. if (element.ShapeProperties != null)
  213. {
  214. Transform2D transform2D = element.ShapeProperties.Transform2D;
  215. if (transform2D != null)
  216. {
  217. spPosition = GetPositionByTransform2D(transform2D);
  218. }
  219. }
  220. DocumentFormat.OpenXml.Presentation.NonVisualShapeProperties nonVisualShapeProperties = element.NonVisualShapeProperties;
  221. XmlDocument doc = new XmlDocument();
  222. doc.LoadXml(element.OuterXml);
  223. //获取当前节点的相关样式属性
  224. XmlNode idNode = doc.SelectSingleNode("//p:nvSpPr/p:cNvPr/@id", PowerPointHelper.GetXmlnsManager(doc.NameTable));
  225. XmlNode nameNode = doc.SelectSingleNode("//p:nvSpPr/p:cNvPr/@name", PowerPointHelper.GetXmlnsManager(doc.NameTable));
  226. XmlNode idxNode = doc.SelectSingleNode("//p:nvSpPr/p:nvPr/p:ph/@idx", PowerPointHelper.GetXmlnsManager(doc.NameTable));
  227. XmlNode typeNode = doc.SelectSingleNode("//p:nvSpPr/p:nvPr/p:ph/@type", PowerPointHelper.GetXmlnsManager(doc.NameTable));
  228. XmlDocument slideLayoutSpNode = null;
  229. XmlDocument slideMasterSpNode = null;
  230. if (typeNode != null)
  231. {
  232. slideLayoutSpNode = slideLayoutStyle.TypeTable;
  233. slideMasterSpNode = slideMasterStyle.TypeTable;
  234. }
  235. else
  236. {
  237. if (idxNode != null)
  238. {
  239. slideLayoutSpNode = slideLayoutStyle.IdxTable;
  240. slideMasterSpNode = slideMasterStyle.IdxTable;
  241. }
  242. }
  243. if (typeNode == null)
  244. {
  245. typeNode = slideLayoutSpNode.SelectSingleNode("//p:nvSpPr/p:nvPr/p:ph/@type", PowerPointHelper.GetXmlnsManager(slideLayoutSpNode.NameTable));
  246. //getTextByPathList(slideLayoutSpNode, ["p:nvSpPr", "p:nvPr", "p:ph", "attrs", "type"]);
  247. if (typeNode == null)
  248. {
  249. typeNode = slideLayoutSpNode.SelectSingleNode("//p:nvSpPr/p:nvPr/p:ph/@type", PowerPointHelper.GetXmlnsManager(slideLayoutSpNode.NameTable));
  250. // typeNode = getTextByPathList(slideMasterSpNode, ["p:nvSpPr", "p:nvPr", "p:ph", "attrs", "type"]);
  251. }
  252. }
  253. return null;
  254. }
  255. /// <summary>
  256. /// 处理图形的具体信息
  257. /// </summary>
  258. /// <param name="element"></param>
  259. /// <param name="slidePart"></param>
  260. /// <param name="slideMaster"></param>
  261. /// <param name="colors"></param>
  262. /// <param name="index"></param>
  263. /// <param name="position"></param>
  264. /// <param name="slideLayoutStyle"></param>
  265. /// <param name="slideMasterStyle"></param>
  266. /// <param name="idNode"></param>
  267. /// <param name="nameNode"></param>
  268. /// <param name="idxNode"></param>
  269. /// <param name="typeNode"></param>
  270. /// <param name="slideLayoutSpNode"></param>
  271. /// <param name="slideMasterSpNode"></param>
  272. /// <returns></returns>
  273. public object GenShape(DocumentFormat.OpenXml.Presentation.Shape element, SlidePart slidePart, SlideMaster slideMaster,
  274. Dictionary<string, string> colors, int index, HiTeachCC.Model.PowerPoint.Position position,
  275. Style slideLayoutStyle,
  276. Style slideMasterStyle, XmlNode idNode, XmlNode nameNode, XmlNode idxNode, XmlNode typeNode, XmlDocument slideLayoutSpNode, XmlDocument slideMasterSpNode)
  277. {
  278. XmlDocument doc = new XmlDocument();
  279. doc.LoadXml(element.OuterXml);
  280. XmlNode shapeType = doc.SelectSingleNode("//p:spPr/a:prstGeom/@prst", PowerPointHelper.GetXmlnsManager(doc.NameTable));
  281. if (shapeType != null)
  282. {
  283. //常规图形
  284. }
  285. else
  286. {
  287. shapeType = doc.SelectSingleNode("//p:spPr/a:custGeom", PowerPointHelper.GetXmlnsManager(doc.NameTable));
  288. if (shapeType != null)
  289. {
  290. //自定义图形 画线 轨迹
  291. }
  292. else {
  293. //都不是的图形 如页眉 页脚
  294. }
  295. }
  296. return null;
  297. }
  298. /// <summary>
  299. /// 获取位置信息
  300. /// </summary>
  301. /// <param name="transform2D"></param>
  302. /// <returns></returns>
  303. private static HiTeachCC.Model.PowerPoint.Position GetPositionByTransform2D(Transform2D transform2D)
  304. {
  305. HiTeachCC.Model.PowerPoint.Position spPosition = new HiTeachCC.Model.PowerPoint.Position();
  306. spPosition.Rot = transform2D.Rotation == null ? 0 : transform2D.Rotation.Value;
  307. spPosition.FlipH = transform2D.HorizontalFlip == null ? false : transform2D.HorizontalFlip.Value;
  308. spPosition.FlipV = transform2D.VerticalFlip == null ? false : transform2D.VerticalFlip.Value;
  309. spPosition.X = transform2D.Offset.X == null ? 0 : transform2D.Offset.X.Value;
  310. spPosition.Y = transform2D.Offset.Y == null ? 0 : transform2D.Offset.Y.Value;
  311. spPosition.Cx = transform2D.Extents.Cx == null ? 0 : transform2D.Extents.Cx.Value;
  312. spPosition.Cy = transform2D.Extents.Cy == null ? 0 : transform2D.Extents.Cy.Value;
  313. return spPosition;
  314. }
  315. /// <summary>
  316. /// 处理图片
  317. /// </summary>
  318. /// <param name="element"></param>
  319. /// <param name="slidePart"></param>
  320. /// <param name="slideMaster"></param>
  321. /// <param name="colors"></param>
  322. /// <param name="index"></param>
  323. /// <param name="position"></param>
  324. /// <param name="slideLayoutStyle"></param>
  325. /// <param name="slideMasterStyle"></param>
  326. /// <returns></returns>
  327. public string ProcessPicNode(DocumentFormat.OpenXml.Presentation.Picture element,
  328. SlidePart slidePart, SlideMaster slideMaster, Dictionary<string, string> colors, int index,
  329. HiTeachCC.Model.PowerPoint.Position position,
  330. Style slideLayoutStyle,
  331. Style slideMasterStyle)
  332. {
  333. return null;
  334. }
  335. /// <summary>
  336. /// 处理包含公式等的信息
  337. /// </summary>
  338. /// <param name="element"></param>
  339. /// <param name="slidePart"></param>
  340. /// <param name="slideMaster"></param>
  341. /// <param name="colors"></param>
  342. /// <param name="index"></param>
  343. /// <param name="position"></param>
  344. /// <param name="slideLayoutStyle"></param>
  345. /// <param name="slideMasterStyle"></param>
  346. /// <returns></returns>
  347. public string ProcessMcNode(DocumentFormat.OpenXml.AlternateContent element, SlidePart slidePart,
  348. SlideMaster slideMaster, Dictionary<string, string> colors,
  349. int index, HiTeachCC.Model.PowerPoint.Position position,
  350. Style slideLayoutStyle,
  351. Style slideMasterStyle)
  352. {
  353. return null;
  354. }
  355. /// <summary>
  356. /// 处理复杂图形的
  357. /// </summary>
  358. /// <param name="element"></param>
  359. /// <param name="slidePart"></param>
  360. /// <param name="slideMaster"></param>
  361. /// <param name="colors"></param>
  362. /// <param name="index"></param>
  363. /// <param name="position"></param>
  364. /// <param name="slideLayoutStyle"></param>
  365. /// <param name="slideMasterStyle"></param>
  366. /// <returns></returns>
  367. public string ProcessGraphicFrameNode(DocumentFormat.OpenXml.Presentation.GraphicFrame element,
  368. SlidePart slidePart, SlideMaster slideMaster, Dictionary<string, string> colors,
  369. int index, HiTeachCC.Model.PowerPoint.Position position,
  370. Style slideLayoutStyle,
  371. Style slideMasterStyle)
  372. {
  373. return null;
  374. }
  375. /// <summary>
  376. /// 处理组合图形
  377. /// </summary>
  378. /// <param name="element"></param>
  379. /// <param name="slidePart"></param>
  380. /// <param name="slideMaster"></param>
  381. /// <param name="colors"></param>
  382. /// <param name="index"></param>
  383. /// <param name="position"></param>
  384. /// <param name="slideLayoutStyle"></param>
  385. /// <param name="slideMasterStyle"></param>
  386. /// <returns></returns>
  387. public string ProcessGrpSpNode(DocumentFormat.OpenXml.Presentation.GroupShape element, SlidePart slidePart,
  388. SlideMaster slideMaster, Dictionary<string, string> colors, int index,
  389. HiTeachCC.Model.PowerPoint.Position position,
  390. Style slideLayoutStyle,
  391. Style slideMasterStyle)
  392. {
  393. var shapes = from shap in element.Descendants<DocumentFormat.OpenXml.Presentation.Shape>() select shap;
  394. foreach (var shape in shapes)
  395. {
  396. string s = ProcessNodesInSlide(shape, slidePart, slideMaster, colors, index, position, slideLayoutStyle, slideMasterStyle);
  397. }
  398. return null;
  399. }
  400. /// <summary>
  401. /// 处理连接线的信息
  402. /// </summary>
  403. /// <param name="element"></param>
  404. /// <param name="slidePart"></param>
  405. /// <param name="slideMaster"></param>
  406. /// <param name="colors"></param>
  407. /// <param name="index"></param>
  408. /// <param name="position"></param>
  409. /// <param name="slideLayoutStyle"></param>
  410. /// <param name="slideMasterStyle"></param>
  411. /// <returns></returns>
  412. public string ProcessCxnSpNode(DocumentFormat.OpenXml.Presentation.ConnectionShape element,
  413. SlidePart slidePart, SlideMaster slideMaster, Dictionary<string, string> colors,
  414. int index, HiTeachCC.Model.PowerPoint.Position position,
  415. Style slideLayoutStyle,
  416. Style slideMasterStyle)
  417. {
  418. return null;
  419. }
  420. }
  421. }