using ICSharpCode.SharpZipLib.Zip; using System; using System.Collections.Generic; using System.IO; using System.Security; using System.Text; namespace HiImRay { public class Docxument { protected string Filename { get; set; } public int CompressionLevel { get; set; } = 9; public Dictionary ReplacementWords = new Dictionary(); public Dictionary>> ReplacementParagraphs = new Dictionary>>(); public Docxument() { } public Docxument(string filename) { Load(filename); } public void Load(string filename) { this.Filename = filename; } public void Save(string saveFilename) { int size = 2048; byte[] buffer = new byte[size]; int bufferSize = 0; // read file ZipEntry readEntry = null; ZipInputStream readStream = new ZipInputStream(File.OpenRead(this.Filename)); // write file ZipOutputStream writeStream = new ZipOutputStream(File.Create(saveFilename)); writeStream.SetLevel(this.CompressionLevel); // loop while (true) { readEntry = readStream.GetNextEntry(); if (readEntry == null) { break; } if (string.IsNullOrWhiteSpace(readEntry.Name)) { break; } if (!readEntry.IsFile) { continue; } // change document if (readEntry.Name.Equals("word/document.xml")) { MemoryStream ms = new MemoryStream(); buffer = new byte[size]; bufferSize = 0; do { bufferSize = readStream.Read(buffer, 0, buffer.Length); ms.Write(buffer, 0, bufferSize); } while (bufferSize > 0); ms.Position = 0; StreamReader sr = new StreamReader(ms); StringBuilder sb = new StringBuilder(); sb.Append(sr.ReadToEnd()); // make changes sb = replaceTokens(sb, this.ReplacementWords); sb = replaceParagraphs(sb, this.ReplacementParagraphs); // make readable MemoryStream ms2 = new MemoryStream(System.Text.Encoding.UTF8.GetBytes(sb.ToString())); ms2.Position = 0; // write new document xml writeStream.PutNextEntry(new ZipEntry(readEntry.Name)); buffer = new byte[size]; bufferSize = 0; do { bufferSize = ms2.Read(buffer, 0, buffer.Length); writeStream.Write(buffer, 0, bufferSize); } while (bufferSize > 0); ms2.Close(); ms2.Dispose(); } else { writeStream.PutNextEntry(new ZipEntry(readEntry.Name)); buffer = new byte[size]; bufferSize = 0; do { bufferSize = readStream.Read(buffer, 0, buffer.Length); writeStream.Write(buffer, 0, bufferSize); } while (bufferSize > 0); } } writeStream.Finish(); writeStream.Flush(); writeStream.Close(); writeStream.Dispose(); readStream.Close(); readStream.Dispose(); } protected StringBuilder replaceTokens(StringBuilder sb, Dictionary options) { foreach (KeyValuePair item in options) { sb.Replace("{{" + item.Key + "}}", SecurityElement.Escape(item.Value)); } return sb; } protected StringBuilder replaceParagraphs(StringBuilder sb, Dictionary>> options) { foreach (KeyValuePair>> item in options) { sb = replaceParagraph(sb, item); } return sb; } protected StringBuilder replaceParagraph(StringBuilder sb, KeyValuePair>> options) { string paragraph = sb.ToString(); Tuple outerCoord = getOuterParagraph(paragraph, "{{" + options.Key + "}}"); if (outerCoord != null) { sb.Remove(outerCoord.Item1, outerCoord.Item2); Tuple innerCoord = getInnerParagraph(paragraph.Substring(outerCoord.Item1, outerCoord.Item2), "{{" + options.Key + "}}"); string innerParagraph = paragraph.Substring((innerCoord.Item1 + outerCoord.Item1), innerCoord.Item2); StringBuilder innerText = new StringBuilder(); foreach (Dictionary row in options.Value) { StringBuilder sb2 = new StringBuilder(); sb2.Append(innerParagraph); sb2 = replaceTokens(sb2, row); innerText.Append(sb2.ToString()); } sb.Insert(outerCoord.Item1, innerText.ToString()); } return sb; } protected Tuple getOuterParagraph(string fullText, string findTerm) { string headTerm = "(headIndex, (tailIndex - headIndex)); } protected Tuple getInnerParagraph(string fullText, string findTerm) { string headTerm = "(headIndex, (tailIndex - headIndex)); } } }