PowerPointService.cs 66 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247
  1. using DocumentFormat.OpenXml;
  2. using DocumentFormat.OpenXml.Drawing;
  3. using DocumentFormat.OpenXml.Office2010.Drawing;
  4. using DocumentFormat.OpenXml.Packaging;
  5. using DocumentFormat.OpenXml.Presentation;
  6. using HiTeachCC.Model.PowerPoint;
  7. using HiTeachCC.Service.PowerPoint.Interface;
  8. using Microsoft.AspNetCore.Http;
  9. using System;
  10. using System.Collections.Generic;
  11. using System.IO;
  12. using System.Linq;
  13. using System.Threading.Tasks;
  14. using System.Xml;
  15. using System.Xml.Linq;
  16. using TEAMModelOS.SDK.Context.Constant;
  17. using TEAMModelOS.SDK.Context.Constant.Common;
  18. using TEAMModelOS.SDK.Context.Exception;
  19. using TEAMModelOS.SDK.Helper.Common.CollectionHelper;
  20. using TEAMModelOS.SDK.Helper.Common.JsonHelper;
  21. using TEAMModelOS.SDK.Helper.Common.StringHelper;
  22. using TEAMModelOS.SDK.Helper.Common.XmlHelper;
  23. using TEAMModelOS.SDK.Helper.Security.ShaHash;
  24. using TEAMModelOS.SDK.Module.AzureBlob.Container;
  25. using TEAMModelOS.SDK.Module.AzureBlob.Interfaces;
  26. using TEAMModelOS.SDK.Module.AzureTable.Interfaces;
  27. using BlipFill = DocumentFormat.OpenXml.Presentation.BlipFill;
  28. using ColorMap = DocumentFormat.OpenXml.Presentation.ColorMap;
  29. using Paragraph = HiTeachCC.Model.PowerPoint.Paragraph;
  30. using Picture = HiTeachCC.Model.PowerPoint.Media;
  31. using Point = HiTeachCC.Model.PowerPoint.Point;
  32. using Shape = HiTeachCC.Model.PowerPoint.Shape;
  33. using Text = HiTeachCC.Model.PowerPoint.Text;
  34. using Theme = DocumentFormat.OpenXml.Drawing.Theme;
  35. using Transform2D = DocumentFormat.OpenXml.Drawing.Transform2D;
  36. namespace HiTeachCC.Service.PowerPoint.Implement
  37. {
  38. public class PowerPointService : IPowerPointService
  39. {
  40. private readonly IAzureBlobDBRepository azureBlobDBRepository;
  41. private readonly IAzureTableDBRepository azureTableDBRepository;
  42. public PowerPointService(IAzureBlobDBRepository _azureBlobDBRepository , IAzureTableDBRepository _azureTableDBRepository)
  43. {
  44. azureBlobDBRepository = _azureBlobDBRepository;
  45. azureTableDBRepository = _azureTableDBRepository;
  46. }
  47. const double inchpixel = 96.00, inchpt = 72.00, pxBase = 914400.00, ptBase = 12700;
  48. const double rotBase = 60000.00;
  49. public Dictionary<string, Dictionary<string, string>> styleTable = new Dictionary<string, Dictionary<string, string>>();
  50. public async Task<Dictionary<string, object>> LoadPresentation(IFormFile file)
  51. {
  52. Dictionary<string, object> resdict = new Dictionary<string, object>();
  53. if (FileType.GetExtention(file.FileName).ToLower().Equals("pptx"))
  54. {
  55. await ProcessPPT(file, resdict);
  56. return resdict;
  57. }
  58. else if (FileType.GetExtention(file.FileName).ToLower().Equals("pdf"))
  59. {
  60. await ProcessPDF(file, resdict);
  61. return resdict;
  62. }
  63. else
  64. {
  65. throw new BizException( "file type does not support!", 500);
  66. }
  67. }
  68. /// <summary>
  69. /// 加载PPTX文件
  70. /// </summary>
  71. /// <param name="presentationFile"></param>
  72. /// <returns></returns>
  73. public async Task<Dictionary<string, object>> ProcessPPT(IFormFile file, Dictionary<string, object> resdict)
  74. {
  75. string shaCode = ShaHashHelper.GetSHA1(file.OpenReadStream());
  76. using (PresentationDocument presentationDocument = PresentationDocument.Open(file.OpenReadStream(), false))
  77. {
  78. XDocument document = presentationDocument.ToFlatOpcDocument();
  79. if (presentationDocument == null)
  80. {
  81. throw new ArgumentNullException("presentationDocument");
  82. }
  83. var thumbnailPart = presentationDocument.ThumbnailPart;
  84. string url = "";
  85. if (thumbnailPart != null)
  86. {
  87. var contentType = thumbnailPart.ContentType;
  88. using (var stream = thumbnailPart.GetStream())
  89. {
  90. //byte[] buffer = new byte[stream.Length];
  91. //stream.Read(buffer, 0, buffer.Length);
  92. //stream.Close();
  93. //string base64 = "";
  94. //base64 = System.Convert.ToBase64String(buffer);
  95. //base64 = "data:" + contentType + ";base64," + base64;
  96. string fileExt = contentType;
  97. if (ContentTypeDict.extdict.TryGetValue(fileExt, out string ext))
  98. {
  99. fileExt = ext;
  100. }
  101. else
  102. {
  103. //解决多种扩展名不能获取的
  104. string[] sp = StringHelper.SubMidString(fileExt, "/", ";").Split("-");
  105. fileExt = sp[sp.Length - 1];
  106. sp = fileExt.Split("+");
  107. fileExt = "." + sp[sp.Length - 1];
  108. }
  109. AzureBlobModel model = await azureBlobDBRepository.UploadFileByFolder(stream, shaCode+ "/files", "thumbnail" + fileExt, "pptx", false);
  110. stream.Close();
  111. url = model.BlobUrl;
  112. }
  113. }
  114. PresentationPart presentationPart = presentationDocument.PresentationPart;
  115. if (presentationPart != null && presentationPart.Presentation != null)
  116. {
  117. // Get a Presentation object from the PresentationPart object.
  118. Presentation presentation = presentationPart.Presentation;
  119. int pageSize = 0;
  120. var slideMasterParts = presentationPart.SlideMasterParts;
  121. ColorMap colorMap = null;
  122. SlideMaster slideMaster = null;
  123. Theme theme = null;
  124. foreach (var slideMasterPart in slideMasterParts)
  125. {
  126. if (colorMap != null && theme != null)
  127. {
  128. break;
  129. }
  130. slideMaster = slideMasterPart.SlideMaster;
  131. colorMap = slideMasterPart.SlideMaster.ColorMap;
  132. theme = slideMasterPart.ThemePart.Theme;
  133. var imgpart = slideMasterPart.ImageParts;
  134. if (imgpart != null)
  135. {
  136. imgpart.ToList().ForEach(yy =>
  137. {
  138. var bgct = yy.ContentType;
  139. string bg64 = "";
  140. using (var stream = yy.GetStream())
  141. {
  142. byte[] buffer = new byte[stream.Length];
  143. stream.Read(buffer, 0, buffer.Length);
  144. stream.Close();
  145. bg64 = System.Convert.ToBase64String(buffer);
  146. bg64 = "data:" + bgct + ";base64," + bg64;
  147. }
  148. });
  149. //slideMaster.CommonSlideData.Background.BackgroundProperties;
  150. //blipfill blipfill = element.blipfill;
  151. //var imagerid = blipfill.blip.embed.value;
  152. //idpartpair idparie = slidepart.parts.where(x => x.relationshipid == imagerid).firstordefault();
  153. //imagepart imagepart = (imagepart)idparie.openxmlpart;
  154. //var contenttype = imagepart.contenttype;
  155. //string base64 = "";
  156. //using (var stream = imagepart.getstream())
  157. //{
  158. // byte[] buffer = new byte[stream.length];
  159. // stream.read(buffer, 0, buffer.length);
  160. // stream.close();
  161. // base64 = system.convert.tobase64string(buffer);
  162. // base64 = "data:" + contenttype + ";base64," + base64;
  163. //}
  164. }
  165. }
  166. Dictionary<string, string> slideMasterColors = PowerPointHelper.DoColorMap(null, colorMap, theme);
  167. //获取PPT 一页大小
  168. double x = presentation.SlideSize.Cx * inchpixel / pxBase;
  169. double y = presentation.SlideSize.Cy * inchpixel / pxBase;
  170. List<string> slides = new List<string>();
  171. string slideMasterXml = slideMaster.OuterXml;
  172. Style slideMasterTables = PowerPointHelper.IndexNodes(slideMasterXml);
  173. XmlDocument SlideMasterTextStyles = PowerPointHelper.GetSlideMasterTextStyles(slideMasterXml);
  174. if (presentation.SlideIdList != null)
  175. {
  176. // presentation.SlideIdList.OrderBy(x=>x.);
  177. // Get the title of each slide in the slide order.
  178. // 获取的是几页PPT数量
  179. foreach (var slideId in presentation.SlideIdList.Elements<SlideId>())
  180. {
  181. // HiTeachCC.Model.PowerPoint.Slide slide = new HiTeachCC.Model.PowerPoint.Slide();
  182. // 获取这一页 PPT 的id
  183. string id = slideId.RelationshipId;
  184. SlidePart slidePart = presentationPart.GetPartById(slideId.RelationshipId) as SlidePart;
  185. //获取当前页 PPT 的所有元素
  186. // slide.Items = GetSlideElement(slidePart, theme, colorMap);
  187. //slide.Xml = slidePart.Slide.OuterXml;
  188. var slide10 = slidePart.Slide;
  189. HiTeachCC.Model.PowerPoint.Slide slide = await GetSlideElement(slidePart, slideMaster, slideMasterColors, theme, slideMasterTables, SlideMasterTextStyles, pageSize, shaCode);
  190. slide.Width = x;
  191. slide.Height = y;
  192. string json = slide.ToJson();
  193. XmlDocument xml = Newtonsoft.Json.JsonConvert.DeserializeXmlNode(json, "Slide");
  194. string result = @"<?xml version=""1.0"" encoding=""UTF-8"" standalone=""yes""?>" +
  195. @"<?xml-stylesheet type=""text/xsl"" href=""hixml2html.xsl""?>" +
  196. xml.OuterXml;
  197. AzureBlobModel amodel = await azureBlobDBRepository.UploadTextByFolder(result, shaCode, (pageSize + 1) + ".xml", "pptx", false);
  198. slides.Add(amodel.BlobUrl);
  199. pageSize++;
  200. }
  201. }
  202. Pptx info = new Pptx { HiXmls = slides, Width = x, Height = y, PageSize = pageSize, Thumbnail = url, Sha1Code = shaCode };
  203. AzureBlobModel model = await azureBlobDBRepository.UploadFileByFolder(file.OpenReadStream(), shaCode, shaCode + ".pptx", "pptx", false);
  204. info.PptUrl = model.BlobUrl;
  205. resdict.Add("pptx", info);
  206. resdict.Add("type", "pptx");
  207. return resdict;
  208. }
  209. return null;
  210. }
  211. }
  212. /// <summary>
  213. /// 处理图形非可视化信息
  214. /// </summary>
  215. /// <param name="slidePart"></param>
  216. /// <param name="slideMaster"></param>
  217. /// <param name="slideMasterColors"></param>
  218. /// <param name="theme"></param>
  219. /// <param name="slideMasterTables"></param>
  220. /// <returns></returns>
  221. public async Task<HiTeachCC.Model.PowerPoint.Slide> GetSlideElement(SlidePart slidePart, SlideMaster slideMaster,
  222. Dictionary<string, string> slideMasterColors, Theme theme,
  223. Style slideMasterTables, XmlDocument SlideMasterTextStyles, int pageSize, string FolderName)
  224. {
  225. Model.PowerPoint.Slide slide = new Model.PowerPoint.Slide() { Index = pageSize };
  226. //用Layout colorMap覆盖 master ColorMap
  227. slideMasterColors = PowerPointHelper.GetLayoutOrMasterColors(slidePart, slideMasterColors, theme);
  228. //slidePart.SlideLayoutPart;
  229. HiTeachCC.Model.PowerPoint.Fill bgFill = PowerPointHelper.GetSlideBackgroundFill(slidePart, slideMaster, slideMasterColors, theme);
  230. if (!string.IsNullOrEmpty(bgFill.Image))
  231. {
  232. string[] strs = bgFill.Image.Split(',');
  233. string fileExt = StringHelper.SubMidString(strs[0], ":", ";");
  234. if (ContentTypeDict.extdict.TryGetValue(fileExt, out string ext))
  235. {
  236. fileExt = ext;
  237. }
  238. else
  239. {
  240. //解决多种扩展名不能获取的
  241. string[] sp = StringHelper.SubMidString(strs[0], "/", ";").Split("-");
  242. fileExt = sp[sp.Length - 1];
  243. sp = fileExt.Split("+");
  244. fileExt = "." + sp[sp.Length - 1];
  245. }
  246. Stream stream = new MemoryStream(Convert.FromBase64String(strs[1]));
  247. // long bizno = IdWorker.getInstance().NextId();
  248. string shaCode = ShaHashHelper.GetSHA1(stream);
  249. string filename = shaCode + fileExt;
  250. stream = new MemoryStream(Convert.FromBase64String(strs[1]));
  251. AzureBlobModel model = await azureBlobDBRepository.UploadFileByFolder(stream, FolderName + "/files", filename, "pptx", false);
  252. bgFill.Image = model.BlobUrl;
  253. stream.Close();
  254. }
  255. string slideLayoutXml = slidePart.SlideLayoutPart.SlideLayout.OuterXml;
  256. var slideLayoutTables = PowerPointHelper.IndexNodes(slideLayoutXml);
  257. var shapeTrees = from shap in slidePart.Slide.Descendants<ShapeTree>() select shap;
  258. if (shapeTrees.Count() > 0 && shapeTrees.First().ChildElements.Count > 0)
  259. {
  260. OpenXmlElementList openXmlElements = shapeTrees.First().ChildElements;
  261. //TransformGroup transformGroup = shapeTrees.First().GroupShapeProperties.TransformGroup;
  262. //HiTeachCC.Model.PowerPoint.Position position = new
  263. //HiTeachCC.Model.PowerPoint.Position();
  264. //position.Rot = transformGroup.Rotation == null ? 0 : transformGroup.Rotation.Value;
  265. //position.FlipH = transformGroup.HorizontalFlip == null ? 0 : transformGroup.HorizontalFlip.Value == true ? 1 : 0;
  266. //position.FlipV = transformGroup.VerticalFlip == null ? 0 : transformGroup.VerticalFlip.Value == true ? 1 : 0;
  267. //position.X = transformGroup.Offset.X == null ? 0 : transformGroup.Offset.X.Value;
  268. //position.Y = transformGroup.Offset.Y == null ? 0 : transformGroup.Offset.Y.Value;
  269. //position.Cx = transformGroup.Extents.Cx == null ? 0 : transformGroup.Extents.Cx.Value;
  270. //position.Cy = transformGroup.Extents.Cy == null ? 0 : transformGroup.Extents.Cy.Value;
  271. //position.ChX = transformGroup.ChildOffset.X == null ? 0 : transformGroup.ChildOffset.X.Value;
  272. //position.ChY = transformGroup.ChildOffset.Y == null ? 0 : transformGroup.ChildOffset.Y.Value;
  273. //position.ChCX = transformGroup.ChildExtents.Cx == null ? 0 : transformGroup.ChildExtents.Cx.Value;
  274. //position.ChCY = transformGroup.ChildExtents.Cy == null ? 0 : transformGroup.ChildExtents.Cy.Value;
  275. int index = 0;
  276. foreach (OpenXmlElement element in openXmlElements)
  277. {
  278. if (element is DocumentFormat.OpenXml.Presentation.NonVisualGroupShapeProperties np || element is DocumentFormat.OpenXml.Presentation.GroupShapeProperties gp)
  279. {
  280. continue;
  281. }
  282. List<Item> list = new List<Item>();
  283. await ProcessNodesInSlide(list, element, slidePart.Parts, slideMaster, slideMasterColors, index, slideLayoutTables, slideMasterTables, SlideMasterTextStyles, theme, slidePart, false , FolderName);
  284. slide.Item.AddRange(list);
  285. index++;
  286. }
  287. }
  288. var layOutshapeTrees = from shap in slidePart.SlideLayoutPart.SlideLayout.Descendants<ShapeTree>() select shap;
  289. if (layOutshapeTrees.Count() > 0 && layOutshapeTrees.First().ChildElements.Count > 0)
  290. {
  291. OpenXmlElementList openXmlElements = layOutshapeTrees.First().ChildElements;
  292. //TransformGroup transformGroup = shapeTrees.First().GroupShapeProperties.TransformGroup;
  293. //HiTeachCC.Model.PowerPoint.Position position = new
  294. //HiTeachCC.Model.PowerPoint.Position();
  295. //position.Rot = transformGroup.Rotation == null ? 0 : transformGroup.Rotation.Value;
  296. //position.FlipH = transformGroup.HorizontalFlip == null ? 0 : transformGroup.HorizontalFlip.Value == true ? 1 : 0;
  297. //position.FlipV = transformGroup.VerticalFlip == null ? 0 : transformGroup.VerticalFlip.Value == true ? 1 : 0;
  298. //position.X = transformGroup.Offset.X == null ? 0 : transformGroup.Offset.X.Value;
  299. //position.Y = transformGroup.Offset.Y == null ? 0 : transformGroup.Offset.Y.Value;
  300. //position.Cx = transformGroup.Extents.Cx == null ? 0 : transformGroup.Extents.Cx.Value;
  301. //position.Cy = transformGroup.Extents.Cy == null ? 0 : transformGroup.Extents.Cy.Value;
  302. //position.ChX = transformGroup.ChildOffset.X == null ? 0 : transformGroup.ChildOffset.X.Value;
  303. //position.ChY = transformGroup.ChildOffset.Y == null ? 0 : transformGroup.ChildOffset.Y.Value;
  304. //position.ChCX = transformGroup.ChildExtents.Cx == null ? 0 : transformGroup.ChildExtents.Cx.Value;
  305. //position.ChCY = transformGroup.ChildExtents.Cy == null ? 0 : transformGroup.ChildExtents.Cy.Value;
  306. int index = 0;
  307. foreach (OpenXmlElement element in openXmlElements)
  308. {
  309. if (element is DocumentFormat.OpenXml.Presentation.NonVisualGroupShapeProperties np || element is DocumentFormat.OpenXml.Presentation.GroupShapeProperties gp)
  310. {
  311. continue;
  312. }
  313. List<Item> list = new List<Item>();
  314. await ProcessNodesInSlide(list, element, slidePart.SlideLayoutPart.Parts, slideMaster, slideMasterColors, index, slideLayoutTables, slideMasterTables, SlideMasterTextStyles, theme, slidePart, true , FolderName);
  315. slide.Item.AddRange(list);
  316. index++;
  317. }
  318. }
  319. slide.Fill = bgFill;
  320. return slide;
  321. }
  322. /// <summary>
  323. /// 单个元素分类
  324. /// </summary>
  325. /// <param name="element"></param>
  326. /// <param name="slidePart"></param>
  327. /// <param name="slideMaster"></param>
  328. /// <param name="slideMasterColors"></param>
  329. /// <param name="index"></param>
  330. /// <param name="position"></param>
  331. /// <param name="slideLayoutTables"></param>
  332. /// <param name="slideMasterTables"></param>
  333. /// <returns></returns>
  334. public async Task ProcessNodesInSlide(List<Item> list, OpenXmlElement element,
  335. IEnumerable<IdPartPair> idPartPairs,
  336. SlideMaster slideMaster,
  337. Dictionary<string, string> colorMaps,
  338. int index,
  339. Style slideLayoutTables,
  340. Style slideMasterTables, XmlDocument SlideMasterTextStyles, Theme theme, SlidePart slidePart, bool isLayOut ,string FolderName)
  341. {
  342. if (element is DocumentFormat.OpenXml.Presentation.Picture pic)//p:pic 图片
  343. {
  344. Model.PowerPoint.Media picture = ProcessPicNode(pic, idPartPairs, slideMaster, colorMaps, index, slideLayoutTables, slideMasterTables, SlideMasterTextStyles, theme);
  345. if (!string.IsNullOrEmpty(picture.Image)) {
  346. string[] strs = picture.Image.Split(',');
  347. string fileExt = StringHelper.SubMidString(strs[0], ":", ";");
  348. if (ContentTypeDict.extdict.TryGetValue(fileExt, out string ext))
  349. {
  350. fileExt = ext;
  351. }
  352. else
  353. {
  354. //解决多种扩展名不能获取的
  355. string[] sp = StringHelper.SubMidString(strs[0], "/", ";").Split("-");
  356. fileExt = sp[sp.Length - 1];
  357. sp = fileExt.Split("+");
  358. fileExt = "." + sp[sp.Length - 1];
  359. }
  360. Stream stream = new MemoryStream(Convert.FromBase64String(strs[1]));
  361. string shaCode = ShaHashHelper.GetSHA1(stream);
  362. stream = new MemoryStream(Convert.FromBase64String(strs[1]));
  363. string filename = shaCode + fileExt;
  364. AzureBlobModel model = await azureBlobDBRepository.UploadFileByFolder(stream, FolderName + "/files", filename, "pptx", false);
  365. picture.Image = model.BlobUrl;
  366. stream.Close();
  367. }
  368. list.Add(picture);
  369. }
  370. else if (element is DocumentFormat.OpenXml.AlternateContent mc)//mc:alternatecontent 公式等
  371. {
  372. Model.PowerPoint.Media picture = ProcessMcNode(mc, idPartPairs, slideMaster, colorMaps, index, slideLayoutTables, slideMasterTables, SlideMasterTextStyles, theme);
  373. if (!string.IsNullOrEmpty(picture.Image))
  374. {
  375. string[] strs = picture.Image.Split(',');
  376. string fileExt = StringHelper.SubMidString(strs[0], ":", ";");
  377. if (ContentTypeDict.extdict.TryGetValue(fileExt, out string ext))
  378. {
  379. fileExt = ext;
  380. }
  381. else
  382. {
  383. //解决多种扩展名不能获取的
  384. string[] sp = StringHelper.SubMidString(strs[0], "/", ";").Split("-");
  385. fileExt = sp[sp.Length - 1];
  386. sp = fileExt.Split("+");
  387. fileExt = "." + sp[sp.Length - 1];
  388. }
  389. Stream stream = new MemoryStream(Convert.FromBase64String(strs[1]));
  390. string shaCode = ShaHashHelper.GetSHA1(stream);
  391. string filename = shaCode + fileExt;
  392. stream = new MemoryStream(Convert.FromBase64String(strs[1]));
  393. AzureBlobModel model = await azureBlobDBRepository.UploadFileByFolder(stream, FolderName+"/img", filename, "pptx", false);
  394. picture.Image = model.BlobUrl;
  395. stream.Close();
  396. }
  397. list.Add(picture);
  398. }
  399. else if (element is DocumentFormat.OpenXml.Presentation.GraphicFrame graphicFrame)//p:graphicFrame Chart, Diagram, Table
  400. {
  401. list.Add(ProcessGraphicFrameNode(graphicFrame, idPartPairs, slideMaster, colorMaps, index, slideLayoutTables, slideMasterTables, SlideMasterTextStyles, theme));
  402. }
  403. else if (element is DocumentFormat.OpenXml.Presentation.GroupShape grpSp)//p:grpSp 组合图形
  404. {
  405. await ProcessGrpSpNode(list, grpSp, idPartPairs, slideMaster, colorMaps, index, slideLayoutTables, slideMasterTables, SlideMasterTextStyles, theme, slidePart , FolderName);
  406. }
  407. else if (element is DocumentFormat.OpenXml.Presentation.ConnectionShape cxnSp) // p:cxnSp 连接线
  408. {
  409. list.Add(ProcessCxnSpNode(cxnSp, idPartPairs, slideMaster, colorMaps, index, slideLayoutTables, slideMasterTables, SlideMasterTextStyles, theme));
  410. }
  411. else if (element is DocumentFormat.OpenXml.Presentation.Shape sp)//p:sp 形状
  412. {
  413. if (isLayOut)
  414. {
  415. XmlDocument doc = new XmlDocument();
  416. doc.LoadXml(element.OuterXml);
  417. XmlNode userDrawnNode = doc.SelectSingleNode("//p:nvPr//@userDrawn", PowerPointHelper.xmlnsManager);
  418. //处理模板中有无背编辑过的元素
  419. if (userDrawnNode != null && userDrawnNode.Value.Equals("1"))
  420. {
  421. list.Add(ProcessSpNode(sp, idPartPairs, slideMaster, colorMaps, index, slideLayoutTables, slideMasterTables, SlideMasterTextStyles, theme, slidePart));
  422. }
  423. }
  424. else
  425. {
  426. list.Add(ProcessSpNode(sp, idPartPairs, slideMaster, colorMaps, index, slideLayoutTables, slideMasterTables, SlideMasterTextStyles, theme, slidePart));
  427. }
  428. }
  429. }
  430. /// <summary>
  431. /// 处理Shape的样式 位置信息
  432. /// </summary>
  433. /// <param name="element"></param>
  434. /// <param name="slidePart"></param>
  435. /// <param name="slideMaster"></param>
  436. /// <param name="colors"></param>
  437. /// <param name="index"></param>
  438. /// <param name="position"></param>
  439. /// <param name="slideLayoutTables"></param>
  440. /// <param name="slideMasterTables"></param>
  441. /// <returns></returns>
  442. public HiTeachCC.Model.PowerPoint.Shape ProcessSpNode(DocumentFormat.OpenXml.Presentation.Shape element, IEnumerable<IdPartPair> idPartPairs, SlideMaster slideMaster,
  443. Dictionary<string, string> colors, int index,
  444. //HiTeachCC.Model.PowerPoint.Position position,
  445. Style slideLayoutTables,
  446. Style slideMasterTables, XmlDocument slideMasterTextStyles, Theme theme, SlidePart slidePart)
  447. {
  448. XmlDocument doc = new XmlDocument();
  449. doc.LoadXml(element.OuterXml);
  450. //获取当前节点的相关样式属性
  451. XmlNode idNode = doc.SelectSingleNode("//p:nvSpPr/p:cNvPr/@id", PowerPointHelper.xmlnsManager);
  452. XmlNode nameNode = doc.SelectSingleNode("//p:nvSpPr/p:cNvPr/@name", PowerPointHelper.xmlnsManager);
  453. XmlNode idxNode = doc.SelectSingleNode("//p:nvSpPr/p:nvPr/p:ph/@idx", PowerPointHelper.xmlnsManager);
  454. XmlNode typeNode = doc.SelectSingleNode("//p:nvSpPr/p:nvPr/p:ph/@type", PowerPointHelper.xmlnsManager);
  455. XmlDocument slideLayoutSpNode = null;
  456. XmlDocument slideMasterSpNode = null;
  457. if (typeNode != null)
  458. {
  459. // 检查 slideLayoutSpNode slideMasterSpNode 为空时产生的位置 横竖排版 空指针问题
  460. //slideLayoutSpNode = slideLayoutTables.TypeTable;
  461. //slideMasterSpNode = slideMasterTables.TypeTable;
  462. doc.LoadXml(slideLayoutTables.TypeTable.OuterXml);
  463. XmlNodeList types = doc.SelectNodes("//xmlDatas/xmlData", PowerPointHelper.xmlnsManager);
  464. if (types != null)
  465. {
  466. int size = types.Count;
  467. for (int i = 0; i < size; i++)
  468. {
  469. XmlNode node = types.Item(i);
  470. doc.LoadXml(node.OuterXml);
  471. XmlNode id = doc.SelectSingleNode("./xmlData/@id", PowerPointHelper.xmlnsManager);
  472. if (id.Value.Equals(typeNode.Value))
  473. {
  474. XmlDocument nodeDoc = new XmlDocument();
  475. nodeDoc.LoadXml(types.Item(i).OuterXml);
  476. slideLayoutSpNode = nodeDoc;
  477. break;
  478. }
  479. }
  480. }
  481. doc.LoadXml(slideMasterTables.TypeTable.OuterXml);
  482. types = doc.SelectNodes("//xmlDatas/xmlData", PowerPointHelper.xmlnsManager);
  483. if (types != null)
  484. {
  485. int size = types.Count;
  486. for (int i = 0; i < size; i++)
  487. {
  488. XmlNode node = types.Item(i);
  489. doc.LoadXml(node.OuterXml);
  490. XmlNode id = doc.SelectSingleNode("./xmlData/@id", PowerPointHelper.xmlnsManager);
  491. if (id.Value.Equals(typeNode.Value))
  492. {
  493. XmlDocument nodeDoc = new XmlDocument();
  494. nodeDoc.LoadXml(types.Item(i).OuterXml);
  495. slideMasterSpNode = nodeDoc;
  496. break;
  497. }
  498. }
  499. }
  500. }
  501. else
  502. {
  503. if (idxNode != null)
  504. {
  505. //slideLayoutSpNode = slideLayoutTables.IdxTable;
  506. //slideMasterSpNode = slideMasterTables.IdxTable;
  507. doc.LoadXml(slideLayoutTables.IdxTable.OuterXml);
  508. XmlNodeList types = doc.SelectNodes("//xmlDatas/xmlData", PowerPointHelper.xmlnsManager);
  509. if (types != null)
  510. {
  511. int size = types.Count;
  512. for (int i = 0; i < size; i++)
  513. {
  514. XmlNode node = types.Item(i);
  515. doc.LoadXml(node.OuterXml);
  516. XmlNode id = doc.SelectSingleNode("./xmlData/@id", PowerPointHelper.xmlnsManager);
  517. if (id.Value.Equals(idxNode.Value))
  518. {
  519. XmlDocument nodeDoc = new XmlDocument();
  520. nodeDoc.LoadXml(types.Item(i).OuterXml);
  521. slideLayoutSpNode = nodeDoc;
  522. break;
  523. }
  524. }
  525. }
  526. doc.LoadXml(slideMasterTables.IdxTable.OuterXml);
  527. types = doc.SelectNodes("//xmlDatas/xmlData", PowerPointHelper.xmlnsManager);
  528. if (types != null)
  529. {
  530. int size = types.Count;
  531. for (int i = 0; i < size; i++)
  532. {
  533. XmlNode node = types.Item(i);
  534. doc.LoadXml(node.OuterXml);
  535. XmlNode id = doc.SelectSingleNode("./xmlData/@id", PowerPointHelper.xmlnsManager);
  536. if (id.Value.Equals(idxNode.Value))
  537. {
  538. XmlDocument nodeDoc = new XmlDocument();
  539. nodeDoc.LoadXml(types.Item(i).OuterXml);
  540. slideMasterSpNode = nodeDoc;
  541. break;
  542. }
  543. }
  544. }
  545. }
  546. }
  547. if (typeNode == null)
  548. {
  549. if (slideLayoutSpNode != null)
  550. {
  551. typeNode = slideLayoutSpNode.SelectSingleNode("//p:nvSpPr/p:nvPr/p:ph/@type", PowerPointHelper.xmlnsManager);
  552. }
  553. //getTextByPathList(slideLayoutSpNode, ["p:nvSpPr", "p:nvPr", "p:ph", "attrs", "type"]);
  554. if (typeNode == null)
  555. {
  556. if (slideMasterSpNode != null)
  557. {
  558. typeNode = slideMasterSpNode.SelectSingleNode("//p:nvSpPr/p:nvPr/p:ph/@type", PowerPointHelper.xmlnsManager);
  559. }
  560. // typeNode = getTextByPathList(slideMasterSpNode, ["p:nvSpPr", "p:nvPr", "p:ph", "attrs", "type"]);
  561. }
  562. }
  563. HiTeachCC.Model.PowerPoint.Shape s = GenShape(element, idPartPairs, slideMaster, colors, index, slideLayoutTables,
  564. slideMasterTables, idNode, nameNode, idxNode, typeNode, slideLayoutSpNode, slideMasterSpNode, slideMasterTextStyles, theme, slidePart);
  565. return s;
  566. }
  567. /// <summary>
  568. /// 处理图形的具体信息
  569. /// </summary>
  570. /// <param name="element"></param>
  571. /// <param name="slidePart"></param>
  572. /// <param name="slideMaster"></param>
  573. /// <param name="colors"></param>
  574. /// <param name="index"></param>
  575. /// <param name="position"></param>
  576. /// <param name="slideLayoutTables"></param>
  577. /// <param name="slideMasterTables"></param>
  578. /// <param name="idNode"></param>
  579. /// <param name="nameNode"></param>
  580. /// <param name="idxNode"></param>
  581. /// <param name="typeNode"></param>
  582. /// <param name="slideLayoutSpNode"></param>
  583. /// <param name="slideMasterSpNode"></param>
  584. /// <returns></returns>
  585. public HiTeachCC.Model.PowerPoint.Shape GenShape(DocumentFormat.OpenXml.Presentation.Shape element, IEnumerable<IdPartPair> idPartPairs, SlideMaster slideMaster,
  586. Dictionary<string, string> colors, int index,
  587. //HiTeachCC.Model.PowerPoint.Position position,
  588. Style slideLayoutTables,
  589. Style slideMasterTables, XmlNode idNode, XmlNode nameNode, XmlNode idxNode, XmlNode typeNode,
  590. XmlDocument slideLayoutSpNode, XmlDocument slideMasterSpNode, XmlDocument slideMasterTextStyles, Theme theme, SlidePart slidePart)
  591. {
  592. HiTeachCC.Model.PowerPoint.Shape shape = new HiTeachCC.Model.PowerPoint.Shape();
  593. HiTeachCC.Model.PowerPoint.Position spPosition = null;
  594. if (element.ShapeProperties != null)
  595. {
  596. Transform2D transform2D = element.ShapeProperties.Transform2D;
  597. if (transform2D != null)
  598. {
  599. spPosition = PowerPointHelper.GetPositionByTransform2D(transform2D);
  600. }
  601. }
  602. DocumentFormat.OpenXml.Presentation.NonVisualShapeProperties nonVisualShapeProperties = element.NonVisualShapeProperties;
  603. XmlDocument doc = new XmlDocument();
  604. doc.LoadXml(element.OuterXml);
  605. XmlNode shapeType = doc.SelectSingleNode("//p:spPr/a:prstGeom/@prst", PowerPointHelper.xmlnsManager);
  606. if (shapeType != null)
  607. {
  608. //常规图形
  609. HiTeachCC.Model.PowerPoint.Position shapePosition = PowerPointHelper.GetPosition(element.OuterXml, slideLayoutSpNode, slideMasterSpNode);
  610. Border border = PowerPointHelper.GetBorder(element.OuterXml, false, colors);
  611. HiTeachCC.Model.PowerPoint.Fill fill = PowerPointHelper.GetShapeFill(element.OuterXml, colors);
  612. //var headEndTypeNode = doc.SelectSingleNode("//p:spPr/a:ln/a:headEnd/@type", PowerPointHelper.xmlnsManager);
  613. // var tailEndTypeNode = doc.SelectSingleNode("//p:spPr/a:ln/a:tailEnd/@type", PowerPointHelper.xmlnsManager);
  614. PowerPointHelper.GenPPTXShape(shapeType);
  615. // shapePosition.Index = index;
  616. shape.Position = shapePosition;
  617. shape.Paragraph = GenTextBody(element.OuterXml, slideLayoutSpNode, slideMasterSpNode, typeNode, slideLayoutTables, slideMasterTables, slideMasterTextStyles, theme, idPartPairs, colors, slidePart);
  618. shape.Fill = fill;
  619. shape.Border = border;
  620. shape.Type = "Sp";
  621. shape.ShapeType = shapeType.Value;
  622. shape.Index = index++;
  623. // shape.VertAlign = PowerPointHelper.GetVerticalAlign(element, slideLayoutSpNode, slideMasterSpNode, typeNode, slideMasterTextStyles);
  624. XmlNode avLstNode = doc.SelectSingleNode("//p:spPr/a:prstGeom/a:avLst", PowerPointHelper.xmlnsManager);
  625. shape.ShapeGuides = GenShapeGuide(avLstNode);
  626. return shape;
  627. }
  628. else
  629. {
  630. shapeType = doc.SelectSingleNode("//p:spPr/a:custGeom", PowerPointHelper.xmlnsManager);
  631. if (shapeType != null)
  632. {
  633. //自定义图形 画线 轨迹
  634. //常规图形
  635. HiTeachCC.Model.PowerPoint.Position shapePosition = PowerPointHelper.GetPosition(element.OuterXml, slideLayoutSpNode, slideMasterSpNode);
  636. Border border = PowerPointHelper.GetBorder(element.OuterXml, false, colors);
  637. HiTeachCC.Model.PowerPoint.Fill fill = PowerPointHelper.GetShapeFill(element.OuterXml, colors);
  638. var headEndTypeNode = doc.SelectSingleNode("//p:spPr/a:ln/a:headEnd/@type", PowerPointHelper.xmlnsManager);
  639. var tailEndTypeNode = doc.SelectSingleNode("//p:spPr/a:ln/a:tailEnd/@type", PowerPointHelper.xmlnsManager);
  640. PowerPointHelper.GenPPTXShape(shapeType);
  641. shape.Position = shapePosition;
  642. shape.Paragraph = GenTextBody(element.OuterXml, slideLayoutSpNode, slideMasterSpNode, typeNode,
  643. slideLayoutTables, slideMasterTables, slideMasterTextStyles, theme, idPartPairs, colors, slidePart);
  644. shape.Fill = fill;
  645. shape.Border = border;
  646. shape.Type = "Sp";
  647. shape.ShapeType = "custom";
  648. shape.Index = index++;
  649. //shape.VertAlign = PowerPointHelper.GetVerticalAlign(element, slideLayoutSpNode, slideMasterSpNode, typeNode, slideMasterTextStyles);
  650. var pathNode = doc.SelectSingleNode("//p:spPr/a:custGeom/a:pathLst/a:path", PowerPointHelper.xmlnsManager);
  651. shape.Paths = GenPath(pathNode.OuterXml);
  652. return shape;
  653. }
  654. else
  655. {
  656. // string align = PowerPointHelper.GetVerticalAlign(element, slideLayoutSpNode, slideMasterSpNode, typeNode, slideMasterTextStyles);
  657. HiTeachCC.Model.PowerPoint.Position shapePosition = PowerPointHelper.GetPosition(element.OuterXml, slideLayoutSpNode, slideMasterSpNode);
  658. Border border = PowerPointHelper.GetBorder(element.OuterXml, false, colors);
  659. HiTeachCC.Model.PowerPoint.Fill fill = PowerPointHelper.GetShapeFill(element.OuterXml, colors);
  660. shape.Position = shapePosition;
  661. shape.Paragraph = GenTextBody(element.OuterXml, slideLayoutSpNode, slideMasterSpNode, typeNode,
  662. slideLayoutTables, slideMasterTables, slideMasterTextStyles, theme, idPartPairs, colors, slidePart);
  663. shape.Fill = fill;
  664. shape.Border = border;
  665. shape.Type = "Sp";
  666. shape.ShapeType = "rect";
  667. shape.Index = index++;
  668. // shape.VertAlign = PowerPointHelper.GetVerticalAlign(element, slideLayoutSpNode, slideMasterSpNode, typeNode, slideMasterTextStyles);
  669. return shape;
  670. }
  671. }
  672. //return null;
  673. }
  674. public List<HiTeachCC.Model.PowerPoint.ShapeGuide> GenShapeGuide(XmlNode avLstNode)
  675. {
  676. if (avLstNode != null)
  677. {
  678. AdjustValueList adjustValueList = new AdjustValueList(avLstNode.OuterXml);
  679. List<HiTeachCC.Model.PowerPoint.ShapeGuide> ShapeGuides = new List<Model.PowerPoint.ShapeGuide>();
  680. var elements = adjustValueList.ChildElements;
  681. foreach (var xmlElement in elements)
  682. {
  683. if (xmlElement is DocumentFormat.OpenXml.Drawing.ShapeGuide shapeGuide)
  684. {
  685. HiTeachCC.Model.PowerPoint.ShapeGuide ShapeGuide = new HiTeachCC.Model.PowerPoint.ShapeGuide { Name = shapeGuide.Name, Fmla = shapeGuide.Formula };
  686. ShapeGuides.Add(ShapeGuide);
  687. }
  688. }
  689. return ShapeGuides;
  690. }
  691. return null;
  692. }
  693. public List<HiTeachCC.Model.PowerPoint.Path> GenPath(string nodeXml)
  694. {
  695. DocumentFormat.OpenXml.Drawing.Path path = new DocumentFormat.OpenXml.Drawing.Path(nodeXml);
  696. OpenXmlElementList elements = path.ChildElements;
  697. List<HiTeachCC.Model.PowerPoint.Path> Paths = new List<Model.PowerPoint.Path>();
  698. foreach (OpenXmlElement xmlElement in elements)
  699. {
  700. //起点
  701. if (xmlElement is DocumentFormat.OpenXml.Drawing.MoveTo moveTo)
  702. {
  703. DocumentFormat.OpenXml.Drawing.Point point = moveTo.Point;
  704. MoveToPath moveToPath = new MoveToPath { Type = "MoveTo" };
  705. // moveToPath.Pts.Add(new HiTeachCC.Model.PowerPoint. Point { X = double.Parse(point.X) * inchpixel / pxBase, Y = double.Parse(point.Y) * inchpixel / pxBase });
  706. Paths.Add(moveToPath);
  707. }
  708. //连线
  709. if (xmlElement is DocumentFormat.OpenXml.Drawing.LineTo linTo)
  710. {
  711. DocumentFormat.OpenXml.Drawing.Point point = linTo.Point;
  712. LineToPath lineToPath = new LineToPath { Type = "LineTo" };
  713. //lineToPath.Pts.Add(new HiTeachCC.Model.PowerPoint.Point { X = double.Parse(point.X) * inchpixel / pxBase, Y = double.Parse(point.Y) * inchpixel / pxBase });
  714. Paths.Add(lineToPath);
  715. }
  716. //三次贝塞尔曲线
  717. if (xmlElement is DocumentFormat.OpenXml.Drawing.CubicBezierCurveTo cubicBezierCurveTo)
  718. {
  719. OpenXmlElementList list = cubicBezierCurveTo.ChildElements;
  720. CubicBezPath cubicBezPath = new CubicBezPath { Type = "CubicBez" };
  721. foreach (var ls in list)
  722. {
  723. if (ls is DocumentFormat.OpenXml.Drawing.Point point)
  724. {
  725. // cubicBezPath.Pts.Add(new HiTeachCC.Model.PowerPoint.Point { X = double.Parse(point.X) * inchpixel / pxBase, Y = double.Parse(point.Y) * inchpixel / pxBase });
  726. }
  727. }
  728. Paths.Add(cubicBezPath);
  729. }
  730. //二次贝塞尔曲线
  731. if (xmlElement is DocumentFormat.OpenXml.Drawing.QuadraticBezierCurveTo quadraticBezierCurveTo)
  732. {
  733. OpenXmlElementList list = quadraticBezierCurveTo.ChildElements;
  734. QuadBezPath quadBezPath = new QuadBezPath { Type = "QuadBez" };
  735. foreach (var ls in list)
  736. {
  737. if (ls is DocumentFormat.OpenXml.Drawing.Point point)
  738. {
  739. //quadBezPath.Pts.Add(new HiTeachCC.Model.PowerPoint.Point { X = double.Parse(point.X) * inchpixel / pxBase, Y = double.Parse(point.Y) * inchpixel / pxBase });
  740. }
  741. }
  742. Paths.Add(quadBezPath);
  743. }
  744. //处理曲线
  745. if (xmlElement is DocumentFormat.OpenXml.Drawing.ArcTo arcTO)
  746. {
  747. //ArcToPath arcToPath = new ArcToPath() { WidthRadius = arcTO.WidthRadius, HeightRadius = arcTO.HeightRadius, StartAngle = arcTO.StartAngle, SwingAngle = arcTO.SwingAngle };
  748. // Paths.Add(arcToPath);
  749. }
  750. ///判断路径是否闭合
  751. if (xmlElement is DocumentFormat.OpenXml.Drawing.CloseShapePath close)
  752. {
  753. if (close != null)
  754. {
  755. ClosePath closePath = new ClosePath { Type = "Close" };
  756. closePath.Close = true;
  757. Paths.Add(closePath);
  758. }
  759. }
  760. }
  761. return Paths;
  762. }
  763. public List<Paragraph> GenTextBody(string nodeXml, XmlDocument slideLayoutSpNode, XmlDocument slideMasterSpNode,
  764. XmlNode typeNode, Style slideLayoutTables,
  765. Style slideMasterTables, XmlDocument slideMasterTextStyles, Theme theme, IEnumerable<IdPartPair> idPartPairs, Dictionary<string, string> colors, SlidePart slidePart)
  766. {
  767. List<Paragraph> paragraphs = new List<Paragraph>();
  768. XmlDocument doc = new XmlDocument();
  769. doc.LoadXml(nodeXml);
  770. XmlNodeList pNodes = doc.SelectNodes("//p:txBody/child::* ", PowerPointHelper.xmlnsManager);
  771. XmlNodeList plvlNodes = doc.SelectNodes("//p:txBody/a:p/a:pPr/@lvl", PowerPointHelper.xmlnsManager);
  772. bool hasBuChar = false;
  773. if (plvlNodes != null && plvlNodes.Count > 0)
  774. {
  775. hasBuChar = true;
  776. }
  777. if (pNodes != null)
  778. {
  779. int size = pNodes.Count;
  780. for (int i = 0; i < size; i++)
  781. {
  782. XmlNode pNode = pNodes.Item(i);
  783. if (!pNode.Name.Equals("a:p"))
  784. {
  785. continue;
  786. }
  787. XmlDocument pXmlNode = new XmlDocument();
  788. pXmlNode.LoadXml(pNode.OuterXml);
  789. //XmlDocument docNode = new XmlDocument();
  790. //docNode.LoadXml(pNode.OuterXml);
  791. string HorizontalAlign = PowerPointHelper.GetHorizontalAlign(pXmlNode, slideLayoutSpNode, slideMasterSpNode, typeNode, slideMasterTextStyles);
  792. string VerticalAlign = PowerPointHelper.GetVerticalAlign(nodeXml, slideLayoutSpNode, slideMasterSpNode, typeNode, slideMasterTextStyles);
  793. Paragraph paragraph = new Paragraph();
  794. ParagraphStyle paragraphStyle = new ParagraphStyle { HoriAlign = HorizontalAlign, VertAlign = VerticalAlign };
  795. XmlNodeList pPrNodes = pXmlNode.SelectNodes("//a:pPr", PowerPointHelper.xmlnsManager);
  796. BuChar buChar = PowerPointHelper.GenBuChar(pXmlNode, slideLayoutTables, slideMasterTables, slideMasterTextStyles, typeNode, hasBuChar);
  797. paragraph.BuChar = buChar;
  798. paragraph.ParagraphStyle = paragraphStyle;
  799. XmlNodeList rNodes = pXmlNode.SelectNodes("//a:r", PowerPointHelper.xmlnsManager);
  800. if (null == rNodes)
  801. {
  802. XmlDocument rNode = new XmlDocument();
  803. rNode.LoadXml(pNode.OuterXml);
  804. paragraph.Texts.Add(GenSpanElement(rNode, slideLayoutSpNode, slideMasterSpNode, typeNode, slideMasterTextStyles, theme, idPartPairs, colors, buChar, slidePart));
  805. }
  806. else
  807. {
  808. int rsize = rNodes.Count;
  809. for (int ri = 0; ri < rsize; ri++)
  810. {
  811. XmlDocument rNode = new XmlDocument();
  812. rNode.LoadXml(rNodes.Item(ri).OuterXml);
  813. paragraph.Texts.Add(GenSpanElement(rNode, slideLayoutSpNode, slideMasterSpNode, typeNode, slideMasterTextStyles, theme, idPartPairs, colors, buChar, slidePart));
  814. }
  815. }
  816. paragraphs.Add(paragraph);
  817. }
  818. }
  819. return paragraphs;
  820. }
  821. public Text GenSpanElement(XmlDocument nodeXml, XmlDocument slideLayoutSpNode, XmlDocument slideMasterSpNode, XmlNode typeNode,
  822. XmlDocument slideMasterTextStyles, Theme theme, IEnumerable<IdPartPair> idPartPairs, Dictionary<string, string> colors, BuChar buChar, SlidePart slidePart)
  823. {
  824. XmlNode tNode = nodeXml.SelectSingleNode("//a:t", PowerPointHelper.xmlnsManager);
  825. /*
  826. var text = node["a:t"];
  827. if (typeof text !== 'string') {
  828. text = getTextByPathList(node, ["a:fld", "a:t"]);
  829. if (typeof text !== 'string') {
  830. text = "&nbsp;";
  831. //debug("XXX: " + JSON.stringify(node));
  832. }
  833. }
  834. */
  835. string color = PowerPointHelper.GetFontColor(nodeXml, typeNode, slideMasterTextStyles, colors);
  836. int font_size = PowerPointHelper.GetFontSize(nodeXml, slideLayoutSpNode, slideMasterSpNode, typeNode, slideMasterTextStyles);
  837. if (font_size == 0 && buChar != null)
  838. {
  839. font_size = buChar.FontSize;
  840. }
  841. string font_family = PowerPointHelper.GetFontType(nodeXml, typeNode, slideMasterTextStyles, theme);
  842. string font_weight = PowerPointHelper.GetFontBold(nodeXml, typeNode, slideMasterTextStyles);
  843. string font_style = PowerPointHelper.GetFontItalic(nodeXml, typeNode, slideMasterTextStyles);
  844. string text_decoration = PowerPointHelper.GetFontDecoration(nodeXml, typeNode, slideMasterTextStyles);
  845. string vertical_align = PowerPointHelper.GetTextVerticalAlign(nodeXml, typeNode, slideMasterTextStyles);
  846. FontStyle fontStyle = new FontStyle
  847. {
  848. Color = color,
  849. Size = font_size,
  850. Family = font_family,
  851. Weight = font_weight,
  852. Style = font_style,
  853. Decoration = text_decoration,
  854. VertAlign = vertical_align
  855. };
  856. string styleText = "color:" + color + ";font-size:" + font_size +
  857. ";font-family:" + font_family + ";font-weight:" + font_weight +
  858. ";font-style:" + font_style + ";text-decoration:" + text_decoration +
  859. ";vertical-align:" + vertical_align;
  860. string cssName = "";
  861. if (styleTable.TryGetValue(styleText, out Dictionary<string, string> css))
  862. {
  863. cssName = css["name"];
  864. }
  865. else
  866. {
  867. cssName = "_css_" + (styleTable.Keys.Count + 1);
  868. styleTable.TryAdd(styleText, new Dictionary<string, string> { { "name", cssName }, { "text", styleText } });
  869. }
  870. Text text = new Text { Content = tNode.InnerText, FontStyle = fontStyle };
  871. XmlNode linkID = nodeXml.SelectSingleNode("//a:rPr/a:hlinkClick/@r:id", PowerPointHelper.xmlnsManager);
  872. if (linkID != null)
  873. {
  874. List<DocumentFormat.OpenXml.Packaging.HyperlinkRelationship> hyperlinkRelationships = slidePart.HyperlinkRelationships.ToList();
  875. bool flag = true;
  876. foreach (var HyperlinkRelationship in hyperlinkRelationships)
  877. {
  878. if (HyperlinkRelationship.Id.Equals(linkID.Value))
  879. {
  880. text.Href = HyperlinkRelationship.Uri.ToString();
  881. flag = false;
  882. break;
  883. }
  884. }
  885. if (flag)
  886. {
  887. text.Href = "#";
  888. }
  889. }
  890. else
  891. {
  892. text.Href = null;
  893. }
  894. return text;
  895. }
  896. /// <summary>
  897. /// 处理图片
  898. /// </summary>
  899. /// <param name="element"></param>
  900. /// <param name="slidePart"></param>
  901. /// <param name="slideMaster"></param>
  902. /// <param name="colors"></param>
  903. /// <param name="index"></param>
  904. /// <param name="position"></param>
  905. /// <param name="slideLayoutTables"></param>
  906. /// <param name="slideMasterTables"></param>
  907. /// <returns></returns>
  908. public Model.PowerPoint.Media ProcessPicNode(DocumentFormat.OpenXml.Presentation.Picture element,
  909. IEnumerable<IdPartPair> idPartPairs, SlideMaster slideMaster, Dictionary<string, string> colors, int index,
  910. Style slideLayoutTables,
  911. Style slideMasterTables, XmlDocument slideMasterTextStyles, Theme theme)
  912. {
  913. HiTeachCC.Model.PowerPoint.Position picPosition = PowerPointHelper.GetPosition(element.OuterXml, null, null);
  914. //picPosition.Index = index;
  915. BlipFill blipFill = element.BlipFill;
  916. var imageRid = blipFill.Blip.Embed.Value;
  917. IdPartPair idParie = idPartPairs.Where(x => x.RelationshipId == imageRid).FirstOrDefault();
  918. ImagePart imagePart = (ImagePart)idParie.OpenXmlPart;
  919. var contentType = imagePart.ContentType;
  920. string base64 = "";
  921. using (var stream = imagePart.GetStream())
  922. {
  923. byte[] buffer = new byte[stream.Length];
  924. stream.Read(buffer, 0, buffer.Length);
  925. stream.Close();
  926. base64 = System.Convert.ToBase64String(buffer);
  927. base64 = "data:" + contentType + ";base64," + base64;
  928. }
  929. Border border = PowerPointHelper.GetBorder(element.OuterXml, false, colors);
  930. Model.PowerPoint.Fill fill = PowerPointHelper.GetShapeFill(element.OuterXml, colors);
  931. Model.PowerPoint.Media picture = new Model.PowerPoint.Media
  932. {
  933. Type = "Pic",
  934. Position = picPosition,
  935. Image = base64,
  936. Fill = fill,
  937. Border = border
  938. };
  939. picture.Index = index++;
  940. return picture;
  941. }
  942. /// <summary>
  943. /// 处理包含公式等的信息
  944. /// </summary>
  945. /// <param name="element"></param>
  946. /// <param name="slidePart"></param>
  947. /// <param name="slideMaster"></param>
  948. /// <param name="colors"></param>
  949. /// <param name="index"></param>
  950. /// <param name="position"></param>
  951. /// <param name="slideLayoutTables"></param>
  952. /// <param name="slideMasterTables"></param>
  953. /// <returns></returns>
  954. public Model.PowerPoint.Media ProcessMcNode(DocumentFormat.OpenXml.AlternateContent element, IEnumerable<IdPartPair> slidePart,
  955. SlideMaster slideMaster, Dictionary<string, string> colors,
  956. int index,
  957. Style slideLayoutTables,
  958. Style slideMasterTables, XmlDocument slideMasterTextStyles, Theme theme)
  959. {
  960. var choices = from contentChoice in element.Descendants<AlternateContentChoice>() select contentChoice;
  961. if (choices.Count() > 0)
  962. {
  963. OpenXmlElement celement = choices.First().ChildElements.First();
  964. if (celement != null)
  965. {
  966. if (celement is DocumentFormat.OpenXml.Presentation.Shape shape)
  967. {
  968. var textMaths = from shap in shape.Descendants<TextMath>() select shap;
  969. if (textMaths.Count() > 0)
  970. {
  971. // return MathConvertMathML(shape, theme, colorMap, index);
  972. return MathConvertImage(element, theme, colors, slidePart, index);
  973. }
  974. }
  975. }
  976. }
  977. return null;
  978. }
  979. public Model.PowerPoint.Media MathConvertImage(AlternateContent content, Theme theme, Dictionary<string, string> colors, IEnumerable<IdPartPair> slidePart, int index)
  980. {
  981. var fallbacks = from contentChoice in content.Descendants<AlternateContentFallback>() select contentChoice;
  982. if (fallbacks.Count() > 0)
  983. {
  984. OpenXmlElement xmlElement = fallbacks.First().ChildElements.First();
  985. if (xmlElement != null)
  986. {
  987. if (xmlElement is DocumentFormat.OpenXml.Presentation.Shape shape)
  988. {
  989. var blipFills = from pic in shape.Descendants<DocumentFormat.OpenXml.Drawing.BlipFill>() select pic;
  990. if (blipFills.Count() > 0)
  991. {
  992. var imageRid = blipFills.First().Blip.Embed.Value;
  993. IdPartPair idParie = slidePart.Where(x => x.RelationshipId == imageRid).FirstOrDefault();
  994. ImagePart imagePart = (ImagePart)idParie.OpenXmlPart;
  995. var contentType = imagePart.ContentType;
  996. string base64 = "";
  997. using (var stream = imagePart.GetStream())
  998. {
  999. byte[] buffer = new byte[stream.Length];
  1000. stream.Read(buffer, 0, buffer.Length);
  1001. stream.Close();
  1002. base64 = System.Convert.ToBase64String(buffer);
  1003. base64 = "data:" + contentType + ";base64," + base64;
  1004. }
  1005. Model.PowerPoint.Position picPosition = PowerPointHelper.GetPosition(shape.OuterXml, null, null);
  1006. Border border = PowerPointHelper.GetBorder(shape.OuterXml, false, colors);
  1007. Model.PowerPoint.Fill fill = PowerPointHelper.GetShapeFill(shape.OuterXml, colors);
  1008. // picPosition.Index = index;
  1009. Model.PowerPoint.Media picture = new Model.PowerPoint.Media
  1010. {
  1011. Type = "Math",
  1012. Position = picPosition,
  1013. Image = base64,
  1014. Fill = fill,
  1015. Border = border
  1016. };
  1017. picture.Index = index++;
  1018. return picture;
  1019. }
  1020. }
  1021. }
  1022. }
  1023. return null;
  1024. }
  1025. /// <summary>
  1026. /// 处理复杂图形的
  1027. /// </summary>
  1028. /// <param name="element"></param>
  1029. /// <param name="slidePart"></param>
  1030. /// <param name="slideMaster"></param>
  1031. /// <param name="colors"></param>
  1032. /// <param name="index"></param>
  1033. /// <param name="position"></param>
  1034. /// <param name="slideLayoutTables"></param>
  1035. /// <param name="slideMasterTables"></param>
  1036. /// <returns></returns>
  1037. public Item ProcessGraphicFrameNode(DocumentFormat.OpenXml.Presentation.GraphicFrame graphicFrame,
  1038. IEnumerable<IdPartPair> slidePart, SlideMaster slideMaster, Dictionary<string, string> colors,
  1039. int index,
  1040. Style slideLayoutTables,
  1041. Style slideMasterTables, XmlDocument slideMasterTextStyles, Theme theme)
  1042. {
  1043. DocumentFormat.OpenXml.Drawing.GraphicData graphicData = graphicFrame.ChildElements.First<DocumentFormat.OpenXml.Drawing.GraphicData>();
  1044. if (graphicData != null)
  1045. {
  1046. OpenXmlElement element = graphicData.ChildElements.First();
  1047. if (element != null)
  1048. {
  1049. if (element is DocumentFormat.OpenXml.Drawing.Table table)
  1050. {
  1051. TableConvert(table, theme, colors);
  1052. }
  1053. if (element is DocumentFormat.OpenXml.Drawing.Chart chart)
  1054. {
  1055. //return ChartConvert(graphicFrame, theme, colorMap);
  1056. }
  1057. if (element is DocumentFormat.OpenXml.Drawing.Diagram diagram)
  1058. {
  1059. //return DiagramConvert(graphicFrame, theme, colorMap);
  1060. }
  1061. }
  1062. }
  1063. return null;
  1064. }
  1065. public void TableConvert(DocumentFormat.OpenXml.Drawing.Table table, Theme theme, Dictionary<string, string> colors)
  1066. {
  1067. }
  1068. /// <summary>
  1069. /// 处理组合图形
  1070. /// </summary>
  1071. /// <param name="element"></param>
  1072. /// <param name="slidePart"></param>
  1073. /// <param name="slideMaster"></param>
  1074. /// <param name="colors"></param>
  1075. /// <param name="index"></param>
  1076. /// <param name="position"></param>
  1077. /// <param name="slideLayoutTables"></param>
  1078. /// <param name="slideMasterTables"></param>
  1079. /// <returns></returns>
  1080. public async Task ProcessGrpSpNode(List<Item> list, DocumentFormat.OpenXml.Presentation.GroupShape element, IEnumerable<IdPartPair> idPartPairs,
  1081. SlideMaster slideMaster, Dictionary<string, string> colors, int index,
  1082. //HiTeachCC.Model.PowerPoint.Position position,
  1083. Style slideLayoutTables,
  1084. Style slideMasterTables, XmlDocument slideMasterTextStyles, Theme theme, SlidePart slidePart ,string FolderName)
  1085. {
  1086. var shapes = from shap in element.Descendants<DocumentFormat.OpenXml.Presentation.Shape>() select shap;
  1087. HiTeachCC.Model.PowerPoint.Position position = new HiTeachCC.Model.PowerPoint.Position();
  1088. TransformGroup transformGroup = element.GroupShapeProperties.TransformGroup;
  1089. position.Rot = transformGroup.Rotation == null ? 0 : transformGroup.Rotation.Value;
  1090. position.FlipH = transformGroup.HorizontalFlip == null ? 0 : transformGroup.HorizontalFlip.Value == true ? 1 : 0;
  1091. position.FlipV = transformGroup.VerticalFlip == null ? 0 : transformGroup.VerticalFlip.Value == true ? 1 : 0;
  1092. position.X = transformGroup.Offset.X == null ? 0 : transformGroup.Offset.X.Value;
  1093. position.Y = transformGroup.Offset.Y == null ? 0 : transformGroup.Offset.Y.Value;
  1094. position.Cx = transformGroup.Extents.Cx == null ? 0 : transformGroup.Extents.Cx.Value;
  1095. position.Cy = transformGroup.Extents.Cy == null ? 0 : transformGroup.Extents.Cy.Value;
  1096. long ChX = transformGroup.ChildOffset.X == null ? 0 : transformGroup.ChildOffset.X.Value;
  1097. long ChY = transformGroup.ChildOffset.Y == null ? 0 : transformGroup.ChildOffset.Y.Value;
  1098. long ChCX = transformGroup.ChildExtents.Cx == null ? 0 : transformGroup.ChildExtents.Cx.Value;
  1099. long ChCY = transformGroup.ChildExtents.Cy == null ? 0 : transformGroup.ChildExtents.Cy.Value;
  1100. position.X = position.X - ChX;
  1101. position.Y = position.Y - ChY;
  1102. position.Cx = position.Cx - ChCX;
  1103. position.Cy = position.Cy - ChCY;
  1104. Group group = new Group();
  1105. group.Position = position;
  1106. group.Type = "Group";
  1107. group.Index = index++;
  1108. List<Item> items = new List<Item>();
  1109. foreach (var shape in shapes)
  1110. {
  1111. await ProcessNodesInSlide(items, shape, idPartPairs, slideMaster, colors, index, slideLayoutTables, slideMasterTables, slideMasterTextStyles, theme, slidePart, false , FolderName);
  1112. }
  1113. group.Shapes = items;
  1114. list.Add(group);
  1115. //return list;
  1116. }
  1117. /// <summary>
  1118. /// 处理连接线的信息
  1119. /// </summary>
  1120. /// <param name="element"></param>
  1121. /// <param name="slidePart"></param>
  1122. /// <param name="slideMaster"></param>
  1123. /// <param name="colors"></param>
  1124. /// <param name="index"></param>
  1125. /// <param name="position"></param>
  1126. /// <param name="slideLayoutTables"></param>
  1127. /// <param name="slideMasterTables"></param>
  1128. /// <returns></returns>
  1129. public HiTeachCC.Model.PowerPoint.Connector ProcessCxnSpNode(DocumentFormat.OpenXml.Presentation.ConnectionShape element,
  1130. IEnumerable<IdPartPair> slidePart, SlideMaster slideMaster, Dictionary<string, string> colors,
  1131. int index,
  1132. Style slideLayoutTables,
  1133. Style slideMasterTables, XmlDocument slideMasterTextStyles, Theme theme)
  1134. {
  1135. HiTeachCC.Model.PowerPoint.Connector shape = new HiTeachCC.Model.PowerPoint.Connector();
  1136. HiTeachCC.Model.PowerPoint.Position spPosition = null;
  1137. if (element.ShapeProperties != null)
  1138. {
  1139. Transform2D transform2D = element.ShapeProperties.Transform2D;
  1140. if (transform2D != null)
  1141. {
  1142. spPosition = PowerPointHelper.GetPositionByTransform2D(transform2D);
  1143. }
  1144. }
  1145. XmlDocument doc = new XmlDocument();
  1146. doc.LoadXml(element.OuterXml);
  1147. XmlNode shapeType = doc.SelectSingleNode("//p:spPr/a:prstGeom/@prst", PowerPointHelper.xmlnsManager);
  1148. if (shapeType != null)
  1149. {
  1150. //常规图形
  1151. HiTeachCC.Model.PowerPoint.Position shapePosition = PowerPointHelper.GetPosition(element.OuterXml, null, null);
  1152. Border border = PowerPointHelper.GetBorder(element.OuterXml, true, colors);
  1153. HiTeachCC.Model.PowerPoint.Fill fill = PowerPointHelper.GetShapeFill(element.OuterXml, colors);
  1154. var headEndTypeNode = doc.SelectSingleNode("//p:spPr/a:ln/a:headEnd/@type", PowerPointHelper.xmlnsManager);
  1155. var tailEndTypeNode = doc.SelectSingleNode("//p:spPr/a:ln/a:tailEnd/@type", PowerPointHelper.xmlnsManager);
  1156. PowerPointHelper.GenPPTXShape(shapeType);
  1157. //shapePosition.Index = index;
  1158. shape.Position = shapePosition;
  1159. // shape.Fill = fill;
  1160. shape.Border = border;
  1161. shape.Type = "CxnSp";
  1162. shape.CxnType = shapeType.Value;
  1163. shape.Index = index++;
  1164. if (headEndTypeNode != null)
  1165. {
  1166. shape.HeadEnd = headEndTypeNode.Value;
  1167. }
  1168. if (tailEndTypeNode != null)
  1169. {
  1170. shape.TailEnd = tailEndTypeNode.Value;
  1171. }
  1172. return shape;
  1173. }
  1174. return null;
  1175. }
  1176. private async Task ProcessPDF(IFormFile file, Dictionary<string, object> resdict)
  1177. {
  1178. string shaCode = ShaHashHelper.GetSHA1(file.OpenReadStream());
  1179. Dictionary<string, object> dict = new Dictionary<string, object> { { "Sha1Code", shaCode } };
  1180. List<AzureBlobModel> models = await azureTableDBRepository. FindListByDict<AzureBlobModel>(dict);
  1181. if (models.IsNotEmpty())
  1182. {
  1183. resdict.Add("pdf", models[0]);
  1184. resdict.Add("type", "pdf");
  1185. }
  1186. else
  1187. {
  1188. AzureBlobModel azureBlobModel = await azureBlobDBRepository.UploadFile(file, "pdffiles", true);
  1189. azureBlobModel.Sha1Code = shaCode;
  1190. await azureTableDBRepository. SaveOrUpdate<AzureBlobModel>(azureBlobModel);
  1191. azureBlobModel.Sha1Code = shaCode;
  1192. resdict.Add("pdf", azureBlobModel);
  1193. resdict.Add("type", "pdf");
  1194. }
  1195. }
  1196. }
  1197. }