Here is a quick tip to convert a template to a document (dotx -> docx). Renaming the extension of the filename is not the solution ;-)
|
using (WordprocessingDocument template = WordprocessingDocument.Open(documentStream, true))
{
template.ChangeDocumentType(DocumentFormat.OpenXml.WordprocessingDocumentType.Document);
MainDocumentPart mainPart = template.MainDocumentPart;
mainPart.DocumentSettingsPart.AddExternalRelationship(
"http://schemas.openxmlformats.org/officeDocument/2006/relationships/attachedTemplate",
new
Uri(@"C:\temp.dotx", UriKind.Absolute));
...
}
|
The short lines of code above do the tricks. I found that the attachedTemplate link should be added, when using a WinMerge to see the difference between a dotx and a docx saved by Word. There is a lot of garbage but only that link is mandatory.
You can put whatever you want in the Uri of the attached template, it's purely informative and may not exists. In theory, it should refer to the location of the template used to build the document.
Note: ChangeDocumentType requires a writable WordProcessingDocument. In the complete source code, I don't want to overwrite my template so I copy the initial template to a writable temporary stream.
|
Complete source code
|
|
using System;
using System.IO;
using DocumentFormat.OpenXml.Packaging;
namespace TemplateConverter
{
class
Program
{
static
void Main(string[] args)
{
MemoryStream documentStream;
String templatePath = Path.Combine(Environment.CurrentDirectory, "template.dotx");
using (Stream tplStream = File.OpenRead(templatePath))
{
documentStream = new
MemoryStream((int)tplStream.Length);
CopyStream(tplStream, documentStream);
documentStream.Position = 0L;
}
using (WordprocessingDocument template = WordprocessingDocument.Open(documentStream, true))
{
template.ChangeDocumentType(DocumentFormat.OpenXml.WordprocessingDocumentType.Document);
MainDocumentPart mainPart = template.MainDocumentPart;
mainPart.DocumentSettingsPart.AddExternalRelationship(
http://schemas.openxmlformats.org/officeDocument/2006/relationships/attachedTemplate",
new
Uri(templatePath, UriKind.Absolute));
mainPart.Document.Save();
}
string path = "test.doc";
File.WriteAllBytes(path, documentStream.ToArray());
// Run Word to open the document:
System.Diagnostics.Process.Start(path);
}
///
<summary>
/// Write the content of a stream into another.
///
</summary>
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;
while ((size = source.Read(buffer, 0, length)) != 0)
target.Write(buffer, 0, size);
}
}
}
}
}
|