PtOpenXmlDocument.cs 30 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821
  1. // Copyright (c) Microsoft. All rights reserved.
  2. // Licensed under the MIT license. See LICENSE file in the project root for full license information.
  3. /*
  4. Here is modification of a WmlDocument:
  5. public static WmlDocument SimplifyMarkup(WmlDocument doc, SimplifyMarkupSettings settings)
  6. {
  7. using (OpenXmlMemoryStreamDocument streamDoc = new OpenXmlMemoryStreamDocument(doc))
  8. {
  9. using (WordprocessingDocument document = streamDoc.GetWordprocessingDocument())
  10. {
  11. SimplifyMarkup(document, settings);
  12. }
  13. return streamDoc.GetModifiedWmlDocument();
  14. }
  15. }
  16. Here is read-only of a WmlDocument:
  17. public static string GetBackgroundColor(WmlDocument doc)
  18. {
  19. using (OpenXmlMemoryStreamDocument streamDoc = new OpenXmlMemoryStreamDocument(doc))
  20. using (WordprocessingDocument document = streamDoc.GetWordprocessingDocument())
  21. {
  22. XDocument mainDocument = document.MainDocumentPart.GetXDocument();
  23. XElement backgroundElement = mainDocument.Descendants(W.background).FirstOrDefault();
  24. return (backgroundElement == null) ? string.Empty : backgroundElement.Attribute(W.color).Value;
  25. }
  26. }
  27. Here is creating a new WmlDocument:
  28. private OpenXmlPowerToolsDocument CreateSplitDocument(WordprocessingDocument source, List<XElement> contents, string newFileName)
  29. {
  30. using (OpenXmlMemoryStreamDocument streamDoc = OpenXmlMemoryStreamDocument.CreateWordprocessingDocument())
  31. {
  32. using (WordprocessingDocument document = streamDoc.GetWordprocessingDocument())
  33. {
  34. DocumentBuilder.FixRanges(source.MainDocumentPart.GetXDocument(), contents);
  35. PowerToolsExtensions.SetContent(document, contents);
  36. }
  37. OpenXmlPowerToolsDocument newDoc = streamDoc.GetModifiedDocument();
  38. newDoc.FileName = newFileName;
  39. return newDoc;
  40. }
  41. }
  42. */
  43. using System;
  44. using System.Diagnostics.CodeAnalysis;
  45. using System.IO;
  46. using System.IO.Packaging;
  47. using System.Linq;
  48. using System.Xml.Linq;
  49. using DocumentFormat.OpenXml;
  50. using DocumentFormat.OpenXml.Packaging;
  51. namespace OpenXmlPowerTools
  52. {
  53. public class PowerToolsDocumentException : Exception
  54. {
  55. public PowerToolsDocumentException(string message) : base(message)
  56. {
  57. }
  58. }
  59. public class PowerToolsInvalidDataException : Exception
  60. {
  61. public PowerToolsInvalidDataException(string message) : base(message)
  62. {
  63. }
  64. }
  65. [SuppressMessage("ReSharper", "MemberCanBeProtected.Global")]
  66. public class OpenXmlPowerToolsDocument
  67. {
  68. public OpenXmlPowerToolsDocument(OpenXmlPowerToolsDocument original)
  69. {
  70. DocumentByteArray = new byte[original.DocumentByteArray.Length];
  71. Array.Copy(original.DocumentByteArray, DocumentByteArray, original.DocumentByteArray.Length);
  72. FileName = original.FileName;
  73. }
  74. public OpenXmlPowerToolsDocument(OpenXmlPowerToolsDocument original, bool convertToTransitional)
  75. {
  76. if (convertToTransitional)
  77. {
  78. ConvertToTransitional(original.FileName, original.DocumentByteArray);
  79. }
  80. else
  81. {
  82. DocumentByteArray = new byte[original.DocumentByteArray.Length];
  83. Array.Copy(original.DocumentByteArray, DocumentByteArray, original.DocumentByteArray.Length);
  84. FileName = original.FileName;
  85. }
  86. }
  87. public OpenXmlPowerToolsDocument(string fileName)
  88. {
  89. FileName = fileName;
  90. DocumentByteArray = File.ReadAllBytes(fileName);
  91. }
  92. public OpenXmlPowerToolsDocument(string fileName, bool convertToTransitional)
  93. {
  94. FileName = fileName;
  95. if (convertToTransitional)
  96. {
  97. byte[] tempByteArray = File.ReadAllBytes(fileName);
  98. ConvertToTransitional(fileName, tempByteArray);
  99. }
  100. else
  101. {
  102. FileName = fileName;
  103. DocumentByteArray = File.ReadAllBytes(fileName);
  104. }
  105. }
  106. public OpenXmlPowerToolsDocument(byte[] byteArray)
  107. {
  108. DocumentByteArray = new byte[byteArray.Length];
  109. Array.Copy(byteArray, DocumentByteArray, byteArray.Length);
  110. FileName = null;
  111. }
  112. public OpenXmlPowerToolsDocument(byte[] byteArray, bool convertToTransitional)
  113. {
  114. if (convertToTransitional)
  115. {
  116. ConvertToTransitional(null, byteArray);
  117. }
  118. else
  119. {
  120. DocumentByteArray = new byte[byteArray.Length];
  121. Array.Copy(byteArray, DocumentByteArray, byteArray.Length);
  122. FileName = null;
  123. }
  124. }
  125. public OpenXmlPowerToolsDocument(string fileName, MemoryStream memStream)
  126. {
  127. FileName = fileName;
  128. DocumentByteArray = new byte[memStream.Length];
  129. Array.Copy(memStream.GetBuffer(), DocumentByteArray, memStream.Length);
  130. }
  131. public OpenXmlPowerToolsDocument(string fileName, MemoryStream memStream, bool convertToTransitional)
  132. {
  133. if (convertToTransitional)
  134. {
  135. ConvertToTransitional(fileName, memStream.ToArray());
  136. }
  137. else
  138. {
  139. FileName = fileName;
  140. DocumentByteArray = new byte[memStream.Length];
  141. Array.Copy(memStream.GetBuffer(), DocumentByteArray, memStream.Length);
  142. }
  143. }
  144. public string FileName { get; set; }
  145. public byte[] DocumentByteArray { get; set; }
  146. public static OpenXmlPowerToolsDocument FromFileName(string fileName)
  147. {
  148. byte[] bytes = File.ReadAllBytes(fileName);
  149. Type type;
  150. try
  151. {
  152. type = GetDocumentType(bytes);
  153. }
  154. catch (FileFormatException)
  155. {
  156. throw new PowerToolsDocumentException("Not an Open XML document.");
  157. }
  158. if (type == typeof(WordprocessingDocument))
  159. {
  160. return new WmlDocument(fileName, bytes);
  161. }
  162. if (type == typeof(SpreadsheetDocument))
  163. {
  164. return new SmlDocument(fileName, bytes);
  165. }
  166. if (type == typeof(PresentationDocument))
  167. {
  168. return new PmlDocument(fileName, bytes);
  169. }
  170. if (type == typeof(Package))
  171. {
  172. return new OpenXmlPowerToolsDocument(bytes) { FileName = fileName };
  173. }
  174. throw new PowerToolsDocumentException("Not an Open XML document.");
  175. }
  176. public static OpenXmlPowerToolsDocument FromDocument(OpenXmlPowerToolsDocument doc)
  177. {
  178. Type type = doc.GetDocumentType();
  179. if (type == typeof(WordprocessingDocument))
  180. {
  181. return new WmlDocument(doc);
  182. }
  183. if (type == typeof(SpreadsheetDocument))
  184. {
  185. return new SmlDocument(doc);
  186. }
  187. if (type == typeof(PresentationDocument))
  188. {
  189. return new PmlDocument(doc);
  190. }
  191. return null; // This should not be possible from a valid OpenXmlPowerToolsDocument object
  192. }
  193. private void ConvertToTransitional(string fileName, byte[] tempByteArray)
  194. {
  195. Type type;
  196. try
  197. {
  198. type = GetDocumentType(tempByteArray);
  199. }
  200. catch (FileFormatException)
  201. {
  202. throw new PowerToolsDocumentException("Not an Open XML document.");
  203. }
  204. using (var ms = new MemoryStream())
  205. {
  206. ms.Write(tempByteArray, 0, tempByteArray.Length);
  207. if (type == typeof(WordprocessingDocument))
  208. {
  209. using (WordprocessingDocument sDoc = WordprocessingDocument.Open(ms, true))
  210. {
  211. // following code forces the SDK to serialize
  212. foreach (IdPartPair part in sDoc.Parts)
  213. {
  214. try
  215. {
  216. OpenXmlPartRootElement unused = part.OpenXmlPart.RootElement;
  217. }
  218. catch (Exception)
  219. {
  220. // Ignore
  221. }
  222. }
  223. }
  224. }
  225. else if (type == typeof(SpreadsheetDocument))
  226. {
  227. using (SpreadsheetDocument sDoc = SpreadsheetDocument.Open(ms, true))
  228. {
  229. // following code forces the SDK to serialize
  230. foreach (IdPartPair part in sDoc.Parts)
  231. {
  232. try
  233. {
  234. OpenXmlPartRootElement unused = part.OpenXmlPart.RootElement;
  235. }
  236. catch (Exception)
  237. {
  238. // Ignore
  239. }
  240. }
  241. }
  242. }
  243. else if (type == typeof(PresentationDocument))
  244. {
  245. using (PresentationDocument sDoc = PresentationDocument.Open(ms, true))
  246. {
  247. // following code forces the SDK to serialize
  248. foreach (IdPartPair part in sDoc.Parts)
  249. {
  250. try
  251. {
  252. OpenXmlPartRootElement unused = part.OpenXmlPart.RootElement;
  253. }
  254. catch (Exception)
  255. {
  256. // Ignore
  257. }
  258. }
  259. }
  260. }
  261. FileName = fileName;
  262. DocumentByteArray = ms.ToArray();
  263. }
  264. }
  265. public string GetName()
  266. {
  267. if (FileName == null)
  268. return "Unnamed Document";
  269. var file = new FileInfo(FileName);
  270. return file.Name;
  271. }
  272. public void SaveAs(string fileName)
  273. {
  274. File.WriteAllBytes(fileName, DocumentByteArray);
  275. }
  276. public void Save()
  277. {
  278. if (FileName == null)
  279. throw new InvalidOperationException("Attempting to Save a document that has no file name. Use SaveAs instead.");
  280. File.WriteAllBytes(FileName, DocumentByteArray);
  281. }
  282. public void WriteByteArray(Stream stream)
  283. {
  284. stream.Write(DocumentByteArray, 0, DocumentByteArray.Length);
  285. }
  286. public Type GetDocumentType()
  287. {
  288. return GetDocumentType(DocumentByteArray);
  289. }
  290. private static Type GetDocumentType(byte[] bytes)
  291. {
  292. // Relationship types:
  293. const string coreDocument = "http://schemas.openxmlformats.org/officeDocument/2006/relationships/officeDocument";
  294. const string strictCoreDocument = "http://purl.oclc.org/ooxml/officeDocument/relationships/officeDocument";
  295. using (var stream = new MemoryStream())
  296. {
  297. stream.Write(bytes, 0, bytes.Length);
  298. using (Package package = Package.Open(stream, FileMode.Open))
  299. {
  300. PackageRelationship relationship =
  301. package.GetRelationshipsByType(coreDocument).FirstOrDefault() ??
  302. package.GetRelationshipsByType(strictCoreDocument).FirstOrDefault();
  303. if (relationship != null)
  304. {
  305. Uri partUri = PackUriHelper.ResolvePartUri(relationship.SourceUri, relationship.TargetUri);
  306. PackagePart part = package.GetPart(partUri);
  307. switch (part.ContentType)
  308. {
  309. case "application/vnd.openxmlformats-officedocument.wordprocessingml.document.main+xml":
  310. case "application/vnd.ms-word.document.macroEnabled.main+xml":
  311. case "application/vnd.ms-word.template.macroEnabledTemplate.main+xml":
  312. case "application/vnd.openxmlformats-officedocument.wordprocessingml.template.main+xml":
  313. return typeof(WordprocessingDocument);
  314. case "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet.main+xml":
  315. case "application/vnd.ms-excel.sheet.macroEnabled.main+xml":
  316. case "application/vnd.ms-excel.template.macroEnabled.main+xml":
  317. case "application/vnd.openxmlformats-officedocument.spreadsheetml.template.main+xml":
  318. return typeof(SpreadsheetDocument);
  319. case "application/vnd.openxmlformats-officedocument.presentationml.template.main+xml":
  320. case "application/vnd.openxmlformats-officedocument.presentationml.presentation.main+xml":
  321. case "application/vnd.ms-powerpoint.template.macroEnabled.main+xml":
  322. case "application/vnd.ms-powerpoint.addin.macroEnabled.main+xml":
  323. case "application/vnd.openxmlformats-officedocument.presentationml.slideshow.main+xml":
  324. case "application/vnd.ms-powerpoint.presentation.macroEnabled.main+xml":
  325. return typeof(PresentationDocument);
  326. default:
  327. return typeof(Package);
  328. }
  329. }
  330. return null;
  331. }
  332. }
  333. }
  334. public static void SavePartAs(OpenXmlPart part, string filePath)
  335. {
  336. Stream partStream = part.GetStream(FileMode.Open, FileAccess.Read);
  337. var partContent = new byte[partStream.Length];
  338. partStream.Read(partContent, 0, (int)partStream.Length);
  339. File.WriteAllBytes(filePath, partContent);
  340. }
  341. }
  342. public partial class WmlDocument : OpenXmlPowerToolsDocument
  343. {
  344. public WmlDocument(OpenXmlPowerToolsDocument original)
  345. : base(original)
  346. {
  347. if (GetDocumentType() != typeof(WordprocessingDocument))
  348. throw new PowerToolsDocumentException("Not a Wordprocessing document.");
  349. }
  350. public WmlDocument(OpenXmlPowerToolsDocument original, bool convertToTransitional)
  351. : base(original, convertToTransitional)
  352. {
  353. if (GetDocumentType() != typeof(WordprocessingDocument))
  354. throw new PowerToolsDocumentException("Not a Wordprocessing document.");
  355. }
  356. public WmlDocument(string fileName)
  357. : base(fileName)
  358. {
  359. if (GetDocumentType() != typeof(WordprocessingDocument))
  360. throw new PowerToolsDocumentException("Not a Wordprocessing document.");
  361. }
  362. public WmlDocument(string fileName, bool convertToTransitional)
  363. : base(fileName, convertToTransitional)
  364. {
  365. if (GetDocumentType() != typeof(WordprocessingDocument))
  366. throw new PowerToolsDocumentException("Not a Wordprocessing document.");
  367. }
  368. public WmlDocument(string fileName, byte[] byteArray)
  369. : base(byteArray)
  370. {
  371. FileName = fileName;
  372. if (GetDocumentType() != typeof(WordprocessingDocument))
  373. throw new PowerToolsDocumentException("Not a Wordprocessing document.");
  374. }
  375. public WmlDocument(string fileName, byte[] byteArray, bool convertToTransitional)
  376. : base(byteArray, convertToTransitional)
  377. {
  378. FileName = fileName;
  379. if (GetDocumentType() != typeof(WordprocessingDocument))
  380. throw new PowerToolsDocumentException("Not a Wordprocessing document.");
  381. }
  382. public WmlDocument(string fileName, MemoryStream memStream)
  383. : base(fileName, memStream)
  384. {
  385. }
  386. public WmlDocument(string fileName, MemoryStream memStream, bool convertToTransitional)
  387. : base(fileName, memStream, convertToTransitional)
  388. {
  389. }
  390. }
  391. public partial class SmlDocument : OpenXmlPowerToolsDocument
  392. {
  393. public SmlDocument(OpenXmlPowerToolsDocument original)
  394. : base(original)
  395. {
  396. if (GetDocumentType() != typeof(SpreadsheetDocument))
  397. throw new PowerToolsDocumentException("Not a Spreadsheet document.");
  398. }
  399. public SmlDocument(OpenXmlPowerToolsDocument original, bool convertToTransitional)
  400. : base(original, convertToTransitional)
  401. {
  402. if (GetDocumentType() != typeof(SpreadsheetDocument))
  403. throw new PowerToolsDocumentException("Not a Spreadsheet document.");
  404. }
  405. public SmlDocument(string fileName)
  406. : base(fileName)
  407. {
  408. if (GetDocumentType() != typeof(SpreadsheetDocument))
  409. throw new PowerToolsDocumentException("Not a Spreadsheet document.");
  410. }
  411. public SmlDocument(string fileName, bool convertToTransitional)
  412. : base(fileName, convertToTransitional)
  413. {
  414. if (GetDocumentType() != typeof(SpreadsheetDocument))
  415. throw new PowerToolsDocumentException("Not a Spreadsheet document.");
  416. }
  417. public SmlDocument(string fileName, byte[] byteArray)
  418. : base(byteArray)
  419. {
  420. FileName = fileName;
  421. if (GetDocumentType() != typeof(SpreadsheetDocument))
  422. throw new PowerToolsDocumentException("Not a Spreadsheet document.");
  423. }
  424. public SmlDocument(string fileName, byte[] byteArray, bool convertToTransitional)
  425. : base(byteArray, convertToTransitional)
  426. {
  427. FileName = fileName;
  428. if (GetDocumentType() != typeof(SpreadsheetDocument))
  429. throw new PowerToolsDocumentException("Not a Spreadsheet document.");
  430. }
  431. public SmlDocument(string fileName, MemoryStream memStream)
  432. : base(fileName, memStream)
  433. {
  434. }
  435. public SmlDocument(string fileName, MemoryStream memStream, bool convertToTransitional)
  436. : base(fileName, memStream, convertToTransitional)
  437. {
  438. }
  439. }
  440. public partial class PmlDocument : OpenXmlPowerToolsDocument
  441. {
  442. public PmlDocument(OpenXmlPowerToolsDocument original)
  443. : base(original)
  444. {
  445. if (GetDocumentType() != typeof(PresentationDocument))
  446. throw new PowerToolsDocumentException("Not a Presentation document.");
  447. }
  448. public PmlDocument(OpenXmlPowerToolsDocument original, bool convertToTransitional)
  449. : base(original, convertToTransitional)
  450. {
  451. if (GetDocumentType() != typeof(PresentationDocument))
  452. throw new PowerToolsDocumentException("Not a Presentation document.");
  453. }
  454. public PmlDocument(string fileName)
  455. : base(fileName)
  456. {
  457. if (GetDocumentType() != typeof(PresentationDocument))
  458. throw new PowerToolsDocumentException("Not a Presentation document.");
  459. }
  460. public PmlDocument(string fileName, bool convertToTransitional)
  461. : base(fileName, convertToTransitional)
  462. {
  463. if (GetDocumentType() != typeof(PresentationDocument))
  464. throw new PowerToolsDocumentException("Not a Presentation document.");
  465. }
  466. public PmlDocument(string fileName, byte[] byteArray)
  467. : base(byteArray)
  468. {
  469. FileName = fileName;
  470. if (GetDocumentType() != typeof(PresentationDocument))
  471. throw new PowerToolsDocumentException("Not a Presentation document.");
  472. }
  473. public PmlDocument(string fileName, byte[] byteArray, bool convertToTransitional)
  474. : base(byteArray, convertToTransitional)
  475. {
  476. FileName = fileName;
  477. if (GetDocumentType() != typeof(PresentationDocument))
  478. throw new PowerToolsDocumentException("Not a Presentation document.");
  479. }
  480. public PmlDocument(string fileName, MemoryStream memStream)
  481. : base(fileName, memStream)
  482. {
  483. }
  484. public PmlDocument(string fileName, MemoryStream memStream, bool convertToTransitional)
  485. : base(fileName, memStream, convertToTransitional)
  486. {
  487. }
  488. }
  489. public class OpenXmlMemoryStreamDocument : IDisposable
  490. {
  491. private readonly OpenXmlPowerToolsDocument _document;
  492. private MemoryStream _docMemoryStream;
  493. private Package _docPackage;
  494. public OpenXmlMemoryStreamDocument(OpenXmlPowerToolsDocument doc)
  495. {
  496. _document = doc;
  497. _docMemoryStream = new MemoryStream();
  498. _docMemoryStream.Write(doc.DocumentByteArray, 0, doc.DocumentByteArray.Length);
  499. try
  500. {
  501. _docPackage = Package.Open(_docMemoryStream, FileMode.Open);
  502. }
  503. catch (Exception e)
  504. {
  505. throw new PowerToolsDocumentException(e.Message);
  506. }
  507. }
  508. internal OpenXmlMemoryStreamDocument(MemoryStream stream)
  509. {
  510. _docMemoryStream = stream;
  511. try
  512. {
  513. _docPackage = Package.Open(_docMemoryStream, FileMode.Open);
  514. }
  515. catch (Exception e)
  516. {
  517. throw new PowerToolsDocumentException(e.Message);
  518. }
  519. }
  520. public void Dispose()
  521. {
  522. Dispose(true);
  523. }
  524. public static OpenXmlMemoryStreamDocument CreateWordprocessingDocument()
  525. {
  526. var stream = new MemoryStream();
  527. using (WordprocessingDocument doc = WordprocessingDocument.Create(stream, WordprocessingDocumentType.Document))
  528. {
  529. doc.AddMainDocumentPart();
  530. doc.MainDocumentPart.PutXDocument(new XDocument(
  531. new XElement(W.document,
  532. new XAttribute(XNamespace.Xmlns + "w", W.w),
  533. new XAttribute(XNamespace.Xmlns + "r", R.r),
  534. new XElement(W.body))));
  535. doc.Close();
  536. return new OpenXmlMemoryStreamDocument(stream);
  537. }
  538. }
  539. public static OpenXmlMemoryStreamDocument CreateSpreadsheetDocument()
  540. {
  541. var stream = new MemoryStream();
  542. using (SpreadsheetDocument doc = SpreadsheetDocument.Create(stream, SpreadsheetDocumentType.Workbook))
  543. {
  544. doc.AddWorkbookPart();
  545. XNamespace ns = "http://schemas.openxmlformats.org/spreadsheetml/2006/main";
  546. XNamespace relationshipsns = "http://schemas.openxmlformats.org/officeDocument/2006/relationships";
  547. doc.WorkbookPart.PutXDocument(new XDocument(
  548. new XElement(ns + "workbook",
  549. new XAttribute("xmlns", ns),
  550. new XAttribute(XNamespace.Xmlns + "r", relationshipsns),
  551. new XElement(ns + "sheets"))));
  552. doc.Close();
  553. return new OpenXmlMemoryStreamDocument(stream);
  554. }
  555. }
  556. public static OpenXmlMemoryStreamDocument CreatePresentationDocument()
  557. {
  558. var stream = new MemoryStream();
  559. using (PresentationDocument doc = PresentationDocument.Create(stream, PresentationDocumentType.Presentation))
  560. {
  561. doc.AddPresentationPart();
  562. XNamespace ns = "http://schemas.openxmlformats.org/presentationml/2006/main";
  563. XNamespace relationshipsns = "http://schemas.openxmlformats.org/officeDocument/2006/relationships";
  564. XNamespace drawingns = "http://schemas.openxmlformats.org/drawingml/2006/main";
  565. doc.PresentationPart.PutXDocument(new XDocument(
  566. new XElement(ns + "presentation",
  567. new XAttribute(XNamespace.Xmlns + "a", drawingns),
  568. new XAttribute(XNamespace.Xmlns + "r", relationshipsns),
  569. new XAttribute(XNamespace.Xmlns + "p", ns),
  570. new XElement(ns + "sldMasterIdLst"),
  571. new XElement(ns + "sldIdLst"),
  572. new XElement(ns + "notesSz", new XAttribute("cx", "6858000"), new XAttribute("cy", "9144000")))));
  573. doc.Close();
  574. return new OpenXmlMemoryStreamDocument(stream);
  575. }
  576. }
  577. public static OpenXmlMemoryStreamDocument CreatePackage()
  578. {
  579. var stream = new MemoryStream();
  580. Package package = Package.Open(stream, FileMode.Create);
  581. package.Close();
  582. return new OpenXmlMemoryStreamDocument(stream);
  583. }
  584. public Package GetPackage()
  585. {
  586. return _docPackage;
  587. }
  588. public WordprocessingDocument GetWordprocessingDocument()
  589. {
  590. try
  591. {
  592. if (GetDocumentType() != typeof(WordprocessingDocument))
  593. throw new PowerToolsDocumentException("Not a Wordprocessing document.");
  594. return WordprocessingDocument.Open(_docPackage);
  595. }
  596. catch (Exception e)
  597. {
  598. throw new PowerToolsDocumentException(e.Message);
  599. }
  600. }
  601. public SpreadsheetDocument GetSpreadsheetDocument()
  602. {
  603. try
  604. {
  605. if (GetDocumentType() != typeof(SpreadsheetDocument))
  606. throw new PowerToolsDocumentException("Not a Spreadsheet document.");
  607. return SpreadsheetDocument.Open(_docPackage);
  608. }
  609. catch (Exception e)
  610. {
  611. throw new PowerToolsDocumentException(e.Message);
  612. }
  613. }
  614. public PresentationDocument GetPresentationDocument()
  615. {
  616. try
  617. {
  618. if (GetDocumentType() != typeof(PresentationDocument))
  619. throw new PowerToolsDocumentException("Not a Presentation document.");
  620. return PresentationDocument.Open(_docPackage);
  621. }
  622. catch (Exception e)
  623. {
  624. throw new PowerToolsDocumentException(e.Message);
  625. }
  626. }
  627. public Type GetDocumentType()
  628. {
  629. PackageRelationship relationship = _docPackage
  630. .GetRelationshipsByType("http://schemas.openxmlformats.org/officeDocument/2006/relationships/officeDocument")
  631. .FirstOrDefault();
  632. if (relationship == null)
  633. {
  634. relationship = _docPackage
  635. .GetRelationshipsByType("http://purl.oclc.org/ooxml/officeDocument/relationships/officeDocument")
  636. .FirstOrDefault();
  637. }
  638. if (relationship == null)
  639. {
  640. throw new PowerToolsDocumentException("Not an Open XML Document.");
  641. }
  642. PackagePart part = _docPackage.GetPart(PackUriHelper.ResolvePartUri(relationship.SourceUri, relationship.TargetUri));
  643. switch (part.ContentType)
  644. {
  645. case "application/vnd.openxmlformats-officedocument.wordprocessingml.document.main+xml":
  646. case "application/vnd.ms-word.document.macroEnabled.main+xml":
  647. case "application/vnd.ms-word.template.macroEnabledTemplate.main+xml":
  648. case "application/vnd.openxmlformats-officedocument.wordprocessingml.template.main+xml":
  649. return typeof(WordprocessingDocument);
  650. case "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet.main+xml":
  651. case "application/vnd.ms-excel.sheet.macroEnabled.main+xml":
  652. case "application/vnd.ms-excel.template.macroEnabled.main+xml":
  653. case "application/vnd.openxmlformats-officedocument.spreadsheetml.template.main+xml":
  654. return typeof(SpreadsheetDocument);
  655. case "application/vnd.openxmlformats-officedocument.presentationml.template.main+xml":
  656. case "application/vnd.openxmlformats-officedocument.presentationml.presentation.main+xml":
  657. case "application/vnd.ms-powerpoint.template.macroEnabled.main+xml":
  658. case "application/vnd.ms-powerpoint.addin.macroEnabled.main+xml":
  659. case "application/vnd.openxmlformats-officedocument.presentationml.slideshow.main+xml":
  660. case "application/vnd.ms-powerpoint.presentation.macroEnabled.main+xml":
  661. return typeof(PresentationDocument);
  662. }
  663. return null;
  664. }
  665. public OpenXmlPowerToolsDocument GetModifiedDocument()
  666. {
  667. _docPackage.Close();
  668. _docPackage = null;
  669. return new OpenXmlPowerToolsDocument(_document?.FileName, _docMemoryStream);
  670. }
  671. public WmlDocument GetModifiedWmlDocument()
  672. {
  673. _docPackage.Close();
  674. _docPackage = null;
  675. return new WmlDocument(_document?.FileName, _docMemoryStream);
  676. }
  677. public SmlDocument GetModifiedSmlDocument()
  678. {
  679. _docPackage.Close();
  680. _docPackage = null;
  681. return new SmlDocument(_document?.FileName, _docMemoryStream);
  682. }
  683. public PmlDocument GetModifiedPmlDocument()
  684. {
  685. _docPackage.Close();
  686. _docPackage = null;
  687. return new PmlDocument(_document?.FileName, _docMemoryStream);
  688. }
  689. public void Close()
  690. {
  691. Dispose(true);
  692. }
  693. ~OpenXmlMemoryStreamDocument()
  694. {
  695. Dispose(false);
  696. }
  697. private void Dispose(bool disposing)
  698. {
  699. if (disposing)
  700. {
  701. _docPackage?.Close();
  702. _docMemoryStream?.Dispose();
  703. }
  704. if (_docPackage == null && _docMemoryStream == null)
  705. {
  706. return;
  707. }
  708. _docPackage = null;
  709. _docMemoryStream = null;
  710. GC.SuppressFinalize(this);
  711. }
  712. }
  713. }