|
@@ -0,0 +1,127 @@
|
|
|
+using System;
|
|
|
+using System.Collections.Generic;
|
|
|
+using System.IO;
|
|
|
+using System.IO.Compression;
|
|
|
+using System.Xml;
|
|
|
+
|
|
|
+namespace DOCX
|
|
|
+{
|
|
|
+ public class Docx : IDisposable
|
|
|
+ {
|
|
|
+ private readonly ZipArchive _zip;
|
|
|
+ private readonly XmlNamespaceManager _ns = new XmlNamespaceManager(new NameTable());
|
|
|
+
|
|
|
+ private readonly Dictionary<string, string> _namespaces = new Dictionary<string, string>
|
|
|
+ {
|
|
|
+ {"w", "http://schemas.openxmlformats.org/wordprocessingml/2006/main"}
|
|
|
+ };
|
|
|
+
|
|
|
+ private void LoadNamespaces()
|
|
|
+ {
|
|
|
+ foreach (var item in _namespaces)
|
|
|
+ {
|
|
|
+ _ns.AddNamespace(item.Key, item.Value);
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ public Docx(string path)
|
|
|
+ {
|
|
|
+ _zip = ZipFile.Open(path, ZipArchiveMode.Update);
|
|
|
+ LoadNamespaces();
|
|
|
+ }
|
|
|
+
|
|
|
+ public Docx(ZipArchive zipArchive)
|
|
|
+ {
|
|
|
+ _zip = zipArchive;
|
|
|
+ LoadNamespaces();
|
|
|
+ }
|
|
|
+
|
|
|
+ private (XmlDocument doc, string message) GetXML(ZipArchiveEntry entry)
|
|
|
+ {
|
|
|
+ XmlDocument doc = new XmlDocument()
|
|
|
+ {
|
|
|
+ PreserveWhitespace = true
|
|
|
+ };
|
|
|
+
|
|
|
+ try
|
|
|
+ {
|
|
|
+ using (StreamReader sr = new StreamReader(entry.Open()))
|
|
|
+ {
|
|
|
+ doc.Load(sr);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ catch (Exception e)
|
|
|
+ {
|
|
|
+ return (null, $"Error reading {entry.Name}!\n{e}");
|
|
|
+ }
|
|
|
+
|
|
|
+ return (doc, "OK");
|
|
|
+ }
|
|
|
+
|
|
|
+ private (bool status, string message) SaveXML(XmlDocument doc, ZipArchiveEntry entry)
|
|
|
+ {
|
|
|
+ try
|
|
|
+ {
|
|
|
+ using (StreamWriter sw = new StreamWriter(entry.Open()))
|
|
|
+ {
|
|
|
+ doc.Save(sw);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ catch (Exception e)
|
|
|
+ {
|
|
|
+ return (false, $"Error saving {entry.Name}!\n{e}");
|
|
|
+ }
|
|
|
+
|
|
|
+ return (true, "OK");
|
|
|
+ }
|
|
|
+
|
|
|
+ private (bool status, string message) AddTrackRevisions(ZipArchiveEntry settings)
|
|
|
+ {
|
|
|
+ var loadResult = GetXML(settings);
|
|
|
+ if (loadResult.doc == null)
|
|
|
+ return (false, loadResult.message);
|
|
|
+
|
|
|
+ XmlDocument doc = loadResult.doc;
|
|
|
+
|
|
|
+ if (doc.SelectSingleNode("//w:trackRevisions", _ns) != null) return (true, "No change needed.");
|
|
|
+
|
|
|
+ XmlElement trackRevisions = doc.CreateElement("w", "trackRevisions", _namespaces["w"]);
|
|
|
+ if (doc.DocumentElement == null)
|
|
|
+ return (false, "No root element in settings.xml!");
|
|
|
+
|
|
|
+ doc.DocumentElement.AppendChild(trackRevisions);
|
|
|
+
|
|
|
+ return SaveXML(doc, settings);
|
|
|
+ }
|
|
|
+
|
|
|
+ public (bool status, string message) EnableTrackedChanges()
|
|
|
+ {
|
|
|
+ ZipArchiveEntry settings = _zip.GetEntry(@"word/settings.xml");
|
|
|
+ if (settings == null)
|
|
|
+ return (false,
|
|
|
+ "Can't access settings.xml!");
|
|
|
+
|
|
|
+ var result = AddTrackRevisions(settings);
|
|
|
+ return !result.status ? (false, result.message) : (true, "OK");
|
|
|
+ }
|
|
|
+
|
|
|
+ public void Dispose()
|
|
|
+ {
|
|
|
+ Dispose(true);
|
|
|
+ GC.SuppressFinalize(this);
|
|
|
+ }
|
|
|
+
|
|
|
+ ~Docx()
|
|
|
+ {
|
|
|
+ Dispose(false);
|
|
|
+ }
|
|
|
+
|
|
|
+ protected virtual void Dispose(bool disposing)
|
|
|
+ {
|
|
|
+ if (disposing)
|
|
|
+ {
|
|
|
+ _zip.Dispose();
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+}
|