Recovered missing file
This commit is contained in:
parent
9996d65969
commit
c1079d056e
248
2019/02/Docxument.cs
Normal file
248
2019/02/Docxument.cs
Normal file
@ -0,0 +1,248 @@
|
||||
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<string, string> ReplacementWords = new Dictionary<string, string>();
|
||||
public Dictionary<string, List<Dictionary<string, string>>> ReplacementParagraphs = new Dictionary<string, List<Dictionary<string, string>>>();
|
||||
|
||||
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<string, string> options)
|
||||
{
|
||||
foreach (KeyValuePair<string, string> item in options)
|
||||
{
|
||||
sb.Replace("{{" + item.Key + "}}", SecurityElement.Escape(item.Value));
|
||||
}
|
||||
|
||||
return sb;
|
||||
}
|
||||
|
||||
protected StringBuilder replaceParagraphs(StringBuilder sb, Dictionary<string, List<Dictionary<string, string>>> options)
|
||||
{
|
||||
foreach (KeyValuePair<string, List<Dictionary<string, string>>> item in options)
|
||||
{
|
||||
sb = replaceParagraph(sb, item);
|
||||
}
|
||||
|
||||
return sb;
|
||||
}
|
||||
|
||||
protected StringBuilder replaceParagraph(StringBuilder sb, KeyValuePair<string, List<Dictionary<string, string>>> options)
|
||||
{
|
||||
string paragraph = sb.ToString();
|
||||
|
||||
Tuple<int, int> outerCoord = getOuterParagraph(paragraph, "{{" + options.Key + "}}");
|
||||
if (outerCoord != null)
|
||||
{
|
||||
sb.Remove(outerCoord.Item1, outerCoord.Item2);
|
||||
|
||||
Tuple<int, int> 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<string, string> 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<int, int> getOuterParagraph(string fullText, string findTerm)
|
||||
{
|
||||
string headTerm = "<w:p ";
|
||||
string tailTerm = "</w:p>";
|
||||
|
||||
int headIndex = fullText.IndexOf(findTerm);
|
||||
if (headIndex < 0)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
int tailIndex = fullText.IndexOf(findTerm, (headIndex + findTerm.Length));
|
||||
if (tailIndex < 0)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
headIndex = fullText.LastIndexOf(headTerm, headIndex);
|
||||
if (headIndex < 0)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
tailIndex = fullText.IndexOf(tailTerm, (tailIndex + tailTerm.Length));
|
||||
if (tailIndex < 0)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
tailIndex += tailTerm.Length;
|
||||
|
||||
return new Tuple<int, int>(headIndex, (tailIndex - headIndex));
|
||||
}
|
||||
|
||||
protected Tuple<int, int> getInnerParagraph(string fullText, string findTerm)
|
||||
{
|
||||
string headTerm = "<w:p ";
|
||||
string tailTerm = "</w:p>";
|
||||
|
||||
int headIndex = fullText.IndexOf(findTerm);
|
||||
if (headIndex < 0)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
int tailIndex = fullText.IndexOf(findTerm, (headIndex + findTerm.Length));
|
||||
if (tailIndex < 0)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
headIndex = fullText.IndexOf(tailTerm, headIndex);
|
||||
if (headIndex < 0)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
headIndex += tailTerm.Length;
|
||||
|
||||
tailIndex = fullText.LastIndexOf(headTerm, tailIndex);
|
||||
if (tailIndex < 0)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
return new Tuple<int, int>(headIndex, (tailIndex - headIndex));
|
||||
}
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue
Block a user