我有一个.docx,其中包括一个MailMerge,我需要通过代码(C#)来更改它的源代码。作为库,我正在使用OpenXml。通过将docx作为zip文件打开并查找路径,我发现数据源的链接存储在两个不同的位置:在word/settings.xml中和在word/_rels/settings.xml.rels中。
替换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;
}
}
}但是,当文件打开时,Word要求从新路径加载文件,但也从旧路径加载文件,因为它是在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>如何在Relation中找到这个对象( WordprocessingDocument )?找不到..。或者有其他方法来改变它?
编辑:
我用不同的源代码创建了两个不同的空文件,然后用OpenXml Productivity工具打开,以便比较它们。正如我已经看到的,区别在word/settings.xml和word/_rels/settings.xml.rels中。
发布于 2017-11-15 07:21:12
最后,我提出了以下解决方案:
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();
}发布于 2016-04-07 16:10:45
如果您已经在设置部分的相关部分拥有适当的rID (关系ID),我相信您可以这样做。我给出的方法依赖于Linq。
但是请注意,Word可以在Settings.xml中存储两个数据源文件名,并在settings.xml.rels中存储两个对应的关系。更重要的是,它们都有相同的关系类型字符串。AIUI实际上并不使用MailMerge设置的ODSO (“”)中的数据文件名,但是您应该检查。
实现旧关系的一种方法是如下(这就需要Linq ):
// Get the Settings part
var settingsPart = wordDocument.MainDocumentPart.DocumentSettingsPart;
// Create a MailMerge object and populate it with the existing data
// (You do not have to do this - you could get the individual
// elements/attributes from the part's XML)
var mailMerge =
new MailMerge(settingsPart.Settings.ChildElements.First<MailMerge>().OuterXml);
// Get the relationship
ReferenceRelationship oldRel
= settingsPart.ExternalRelationships.Where(
Rel => Rel.Id == mailMerge.DataSourceReference.Id
).First();
/*
// to get the ODSO relationship, use the following, and to replace it, follow the pattern I give below for oldRel and newRel
ReferenceRelationship oldOdsoRel =
settingsPart.ExternalRelationships.Where(
Rel => Rel.Id == mailMerge.DataSourceObject.SourceReference.Id
).First();
*/
// Delete the old Relationship (but notice that the oldRel object remains)
settingsPart.DeleteExternalRelationship(oldRel.Id);
var newRel =
settingsPart.AddExternalRelationship(
oldRel.RelationshipType,
new Uri("your file path/name",UriKind.RelativeOrAbsolute),
oldRel.Id);https://stackoverflow.com/questions/36334545
复制相似问题