diff --git a/OfficeIMO.Tests/Documents/ExampleTemplate.dotx b/OfficeIMO.Tests/Documents/ExampleTemplate.dotx
new file mode 100644
index 0000000..87f95e8
Binary files /dev/null and b/OfficeIMO.Tests/Documents/ExampleTemplate.dotx differ
diff --git a/OfficeIMO.Tests/Word.Converter.cs b/OfficeIMO.Tests/Word.Converter.cs
new file mode 100644
index 0000000..e3621ed
--- /dev/null
+++ b/OfficeIMO.Tests/Word.Converter.cs
@@ -0,0 +1,20 @@
+using OfficeIMO.Word;
+using Xunit;
+
+namespace OfficeIMO.Tests;
+
+public partial class Word {
+ [Fact]
+ public void Test_ConvertDotXtoDocX() {
+ string filePath = Path.Combine(_directoryDocuments, "ExampleTemplate.dotx");
+ string outFilePath = Path.Combine(_directoryWithFiles, "ExampleTemplate.docx");
+ WordHelpers.ConvertDotXtoDocX(filePath, outFilePath);
+
+ Assert.True(File.Exists(outFilePath));
+
+ using (WordDocument document = WordDocument.Load(filePath)) {
+ Assert.True(document.Paragraphs.Count == 57);
+ Assert.Contains(document.Paragraphs[56].Text, "Feel free to use and share the file according to the license above.");
+ }
+ }
+}
diff --git a/OfficeIMO.Word/Helpers.Cloners.cs b/OfficeIMO.Word/Helpers.Cloners.cs
index 594051f..c79af01 100644
--- a/OfficeIMO.Word/Helpers.Cloners.cs
+++ b/OfficeIMO.Word/Helpers.Cloners.cs
@@ -1,37 +1,91 @@
-using System;
-using System.Collections.Generic;
-using System.IO;
-using System.Text;
+namespace OfficeIMO.Word;
+///
+/// Provides helper methods for stream and file operations.
+///
+public static partial class Helpers {
+ ///
+ /// Reads all bytes from a file and writes them to a MemoryStream.
+ ///
+ /// The path of the file to read.
+ /// A MemoryStream containing the file's bytes.
+ public static MemoryStream ReadAllBytesToMemoryStream(string path) {
+ byte[] buffer = File.ReadAllBytes(path);
+ var destStream = new MemoryStream(buffer.Length);
+ destStream.Write(buffer, 0, buffer.Length);
+ destStream.Seek(0, SeekOrigin.Begin);
+ return destStream;
+ }
-namespace OfficeIMO.Word {
- public static partial class Helpers {
- public static MemoryStream ReadAllBytesToMemoryStream(string path) {
- byte[] buffer = File.ReadAllBytes(path);
- var destStream = new MemoryStream(buffer.Length);
- destStream.Write(buffer, 0, buffer.Length);
- destStream.Seek(0, SeekOrigin.Begin);
- return destStream;
- }
+ ///
+ /// Copies the contents of a file stream to a MemoryStream.
+ ///
+ /// The path of the file to read.
+ /// A MemoryStream containing the file's contents.
+ public static MemoryStream CopyFileStreamToMemoryStream(string path) {
+ FileStream sourceStream = File.OpenRead(path);
+ var destStream = new MemoryStream((int)sourceStream.Length);
+ sourceStream.CopyTo(destStream);
+ destStream.Seek(0, SeekOrigin.Begin);
+ return destStream;
+ }
+
+ ///
+ /// Copies the contents of one file stream to another file stream.
+ ///
+ /// The path of the source file.
+ /// The path of the destination file.
+ /// A FileStream for the destination file.
+ public static FileStream CopyFileStreamToFileStream(string sourcePath, string destPath) {
+ FileStream sourceStream = File.OpenRead(sourcePath);
+ FileStream destStream = File.Create(destPath);
+ sourceStream.CopyTo(destStream);
+ destStream.Seek(0, SeekOrigin.Begin);
+ return destStream;
+ }
- public static MemoryStream CopyFileStreamToMemoryStream(string path) {
- FileStream sourceStream = File.OpenRead(path);
+ ///
+ /// Copies a file and opens a file stream for the copied file.
+ ///
+ /// The path of the source file.
+ /// The path of the destination file.
+ /// A FileStream for the copied file.
+ public static FileStream CopyFileAndOpenFileStream(string sourcePath, string destPath) {
+ File.Copy(sourcePath, destPath, true);
+ return new FileStream(destPath, FileMode.Open, FileAccess.ReadWrite, FileShare.None);
+ }
+
+ ///
+ /// Reads the contents of a file into a MemoryStream.
+ ///
+ /// The path of the file to read.
+ /// A MemoryStream containing the file's contents.
+ public static MemoryStream ReadFileToMemoryStream(string path) {
+ using (Stream sourceStream = File.OpenRead(path)) {
var destStream = new MemoryStream((int)sourceStream.Length);
- sourceStream.CopyTo(destStream);
+ CopyStream(sourceStream, destStream);
destStream.Seek(0, SeekOrigin.Begin);
return destStream;
}
+ }
- public static FileStream CopyFileStreamToFileStream(string sourcePath, string destPath) {
- FileStream sourceStream = File.OpenRead(sourcePath);
- FileStream destStream = File.Create(destPath);
- sourceStream.CopyTo(destStream);
- destStream.Seek(0, SeekOrigin.Begin);
- return destStream;
- }
+ ///
+ /// Copies the contents of one stream to another stream.
+ ///
+ /// The source stream.
+ /// The target stream.
+ public static void CopyStream(Stream source, Stream target) {
+ if (source != null) {
+ MemoryStream mstream = source as MemoryStream;
+ if (mstream != null) {
+ mstream.WriteTo(target);
+ } else {
+ byte[] buffer = new byte[2048];
+ int length = buffer.Length, size;
- public static FileStream CopyFileAndOpenFileStream(string sourcePath, string destPath) {
- File.Copy(sourcePath, destPath, true);
- return new FileStream(destPath, FileMode.Open, FileAccess.ReadWrite, FileShare.None);
+ while ((size = source.Read(buffer, 0, length)) != 0) {
+ target.Write(buffer, 0, size);
+ }
+ }
}
}
}
diff --git a/OfficeIMO.Word/WordDocument.cs b/OfficeIMO.Word/WordDocument.cs
index 000faf3..9e11975 100644
--- a/OfficeIMO.Word/WordDocument.cs
+++ b/OfficeIMO.Word/WordDocument.cs
@@ -683,15 +683,8 @@ public static WordDocument Load(string filePath, bool readOnly = false, bool aut
word._fileStream.CopyTo(memoryStream);
memoryStream.Seek(0, SeekOrigin.Begin);
- // Save the memoryStream to a file for inspection
- using (var fileStream = new FileStream("debug_output.docx", FileMode.Create, FileAccess.Write)) {
- memoryStream.CopyTo(fileStream);
- memoryStream.Seek(0, SeekOrigin.Begin);
- }
-
var wordDocument = WordprocessingDocument.Open(memoryStream, !readOnly, openSettings);
-
InitialiseStyleDefinitions(wordDocument, readOnly);
word.FilePath = filePath;
diff --git a/OfficeIMO.Word/WordHelpers.Converters.cs b/OfficeIMO.Word/WordHelpers.Converters.cs
new file mode 100644
index 0000000..9a81fdc
--- /dev/null
+++ b/OfficeIMO.Word/WordHelpers.Converters.cs
@@ -0,0 +1,18 @@
+using DocumentFormat.OpenXml.Packaging;
+
+namespace OfficeIMO.Word {
+ public partial class WordHelpers {
+ ///
+ /// Given a document name, remove all of the headers and footers from the document.
+ ///
+ ///
+ public static void RemoveHeadersAndFooters(string filename) {
+ using (WordprocessingDocument doc = WordprocessingDocument.Open(filename, true)) {
+ WordHeader.RemoveHeaders(doc);
+ WordFooter.RemoveFooters(doc);
+ // save document
+ doc.MainDocumentPart.Document.Save();
+ }
+ }
+ }
+}
diff --git a/OfficeIMO.Word/WordHelpers.HeadersAndFooters.cs b/OfficeIMO.Word/WordHelpers.HeadersAndFooters.cs
index 29b95ca..1f30bc4 100644
--- a/OfficeIMO.Word/WordHelpers.HeadersAndFooters.cs
+++ b/OfficeIMO.Word/WordHelpers.HeadersAndFooters.cs
@@ -1,21 +1,42 @@
-using System;
-using System.Collections.Generic;
-using System.Text;
using DocumentFormat.OpenXml.Packaging;
namespace OfficeIMO.Word {
public partial class WordHelpers {
///
- /// Given a document name, remove all of the headers and footers from the document.
+ /// Converts a DOTX template to a DOCX document.
+ ///
+ /// Based on: https://github.com/onizet/html2openxml/wiki/Convert-.dotx-to-.docx
///
- ///
- public static void RemoveHeadersAndFooters(string filename) {
- using (WordprocessingDocument doc = WordprocessingDocument.Open(filename, true)) {
- WordHeader.RemoveHeaders(doc);
- WordFooter.RemoveFooters(doc);
- // save document
- doc.MainDocumentPart.Document.Save();
+ /// The path to the DOTX template file.
+ /// The path where the converted DOCX file will be saved.
+ public static void ConvertDotXtoDocX(string templatePath, string outputPath) {
+ // Read the DOTX template file into a MemoryStream
+ MemoryStream documentStream = Helpers.ReadFileToMemoryStream(templatePath);
+
+ // Open the WordprocessingDocument from the MemoryStream
+ using (WordprocessingDocument template = WordprocessingDocument.Open(documentStream, true)) {
+ // Change the document type from template to document
+ template.ChangeDocumentType(DocumentFormat.OpenXml.WordprocessingDocumentType.Document);
+
+ // Get the main document part
+ MainDocumentPart mainPart = template.MainDocumentPart;
+
+ // Ensure the DocumentSettingsPart exists
+ if (mainPart.DocumentSettingsPart == null) {
+ mainPart.AddNewPart();
+ }
+
+ // Add an external relationship to the template
+ mainPart.DocumentSettingsPart.AddExternalRelationship(
+ "http://schemas.openxmlformats.org/officeDocument/2006/relationships/attachedTemplate",
+ new Uri(templatePath, UriKind.Absolute));
+
+ // Save the changes to the main document part
+ mainPart.Document.Save();
}
+
+ // Write the MemoryStream contents to the output file
+ File.WriteAllBytes(outputPath, documentStream.ToArray());
}
}
}