Skip to content

Commit

Permalink
Merge pull request #257 from EvotecIT/ConvertDotXtoDocX
Browse files Browse the repository at this point in the history
Add converter from DOTX to DOCX
  • Loading branch information
PrzemyslawKlys authored Sep 27, 2024
2 parents 4d9b643 + 17db8c2 commit 80bd156
Show file tree
Hide file tree
Showing 6 changed files with 150 additions and 44 deletions.
Binary file added OfficeIMO.Tests/Documents/ExampleTemplate.dotx
Binary file not shown.
20 changes: 20 additions & 0 deletions OfficeIMO.Tests/Word.Converter.cs
Original file line number Diff line number Diff line change
@@ -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.");
}
}
}
106 changes: 80 additions & 26 deletions OfficeIMO.Word/Helpers.Cloners.cs
Original file line number Diff line number Diff line change
@@ -1,37 +1,91 @@
using System;
using System.Collections.Generic;
using System.IO;
using System.Text;
namespace OfficeIMO.Word;
/// <summary>
/// Provides helper methods for stream and file operations.
/// </summary>
public static partial class Helpers {
/// <summary>
/// Reads all bytes from a file and writes them to a MemoryStream.
/// </summary>
/// <param name="path">The path of the file to read.</param>
/// <returns>A MemoryStream containing the file's bytes.</returns>
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;
}
/// <summary>
/// Copies the contents of a file stream to a MemoryStream.
/// </summary>
/// <param name="path">The path of the file to read.</param>
/// <returns>A MemoryStream containing the file's contents.</returns>
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;
}

/// <summary>
/// Copies the contents of one file stream to another file stream.
/// </summary>
/// <param name="sourcePath">The path of the source file.</param>
/// <param name="destPath">The path of the destination file.</param>
/// <returns>A FileStream for the destination file.</returns>
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);
/// <summary>
/// Copies a file and opens a file stream for the copied file.
/// </summary>
/// <param name="sourcePath">The path of the source file.</param>
/// <param name="destPath">The path of the destination file.</param>
/// <returns>A FileStream for the copied file.</returns>
public static FileStream CopyFileAndOpenFileStream(string sourcePath, string destPath) {
File.Copy(sourcePath, destPath, true);
return new FileStream(destPath, FileMode.Open, FileAccess.ReadWrite, FileShare.None);
}

/// <summary>
/// Reads the contents of a file into a MemoryStream.
/// </summary>
/// <param name="path">The path of the file to read.</param>
/// <returns>A MemoryStream containing the file's contents.</returns>
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;
}
/// <summary>
/// Copies the contents of one stream to another stream.
/// </summary>
/// <param name="source">The source stream.</param>
/// <param name="target">The target stream.</param>
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);
}
}
}
}
}
7 changes: 0 additions & 7 deletions OfficeIMO.Word/WordDocument.cs
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down
18 changes: 18 additions & 0 deletions OfficeIMO.Word/WordHelpers.Converters.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
using DocumentFormat.OpenXml.Packaging;

namespace OfficeIMO.Word {
public partial class WordHelpers {
/// <summary>
/// Given a document name, remove all of the headers and footers from the document.
/// </summary>
/// <param name="filename"></param>
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();
}
}
}
}
43 changes: 32 additions & 11 deletions OfficeIMO.Word/WordHelpers.HeadersAndFooters.cs
Original file line number Diff line number Diff line change
@@ -1,21 +1,42 @@
using System;
using System.Collections.Generic;
using System.Text;
using DocumentFormat.OpenXml.Packaging;

namespace OfficeIMO.Word {
public partial class WordHelpers {
/// <summary>
/// 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
/// </summary>
/// <param name="filename"></param>
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();
/// <param name="templatePath">The path to the DOTX template file.</param>
/// <param name="outputPath">The path where the converted DOCX file will be saved.</param>
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<DocumentSettingsPart>();
}

// 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());
}
}
}

0 comments on commit 80bd156

Please sign in to comment.