I have a .docx
which includes a MailMerge, I need to change its source via code (C#). As library I'm using OpenXml
. By Opening the docx as a zip file and looking for the paths, I have found that the link of the datasource is stored in two different places: in the word/settings.xml
and in the word/_rels/settings.xml.rels
.
To replace the fisrt:
var template = new MemoryStream(myDocxInByteArray);
using (var doc = DocumentFormat.OpenXml.Packaging.WordprocessingDocument.Open(template, true))
{
var s = doc.MainDocumentPart.DocumentSettingsPart.Settings;
foreach (var els in s.ChildElements)
{
if (els is DocumentFormat.OpenXml.Wordprocessing.MailMerge)
{
var mm = (DocumentFormat.OpenXml.Wordprocessing.MailMerge)els;
mm.Query.Val = "SELECT * FROM " + myNewPath;
break;
}
}
}
This works fine, however when the file is opened Word asks to load the file from the new path but also from the old one, since it is defined in the word/_rels/settings.xml.rels
.
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<Relationships xmlns="http://schemas.openxmlformats.org/package/2006/relationships">
<Relationship Id="rId1" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/mailMergeSource" Target="oldPath" TargetMode="External"/>
</Relationships>
How can I find this object(Relation
) in the WordprocessingDocument
? Cannot find it...
Or is there another way to change it?
EDIT:
I created two different empty files with a different source and then opened with the OpenXml Productivity Tool in order to compare them. As I already have seen the differences are in the word/settings.xml
and in the word/_rels/settings.xml.rels
.
At the end I came up with the following solution:
using (WordprocessingDocument doc = WordprocessingDocument.Open(docInByteArray, isEditable: true))
{
Settings settings = doc.MainDocumentPart.DocumentSettingsPart.Settings;
OpenXmlElement openXmlElement = null;
foreach (OpenXmlElement element in settings.ChildElements)
{
if (element is MailMerge mailMerge)
{
mailMerge.Query.Val = "SELECT * FROM " + csvPath;
mailMerge.DataSourceObject.Remove();
}
else if (element is AttachedTemplate)
{
openXmlElement = element;
}
}
if (openXmlElement != null)
{
openXmlElement.Remove();
}
doc.Save();
}