首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >通过MailMerge编辑OpenXml

通过MailMerge编辑OpenXml
EN

Stack Overflow用户
提问于 2016-03-31 13:13:29
回答 2查看 2.9K关注 0票数 0

我有一个.docx,其中包括一个MailMerge,我需要通过代码(C#)来更改它的源代码。作为库,我正在使用OpenXml。通过将docx作为zip文件打开并查找路径,我发现数据源的链接存储在两个不同的位置:在word/settings.xml中和在word/_rels/settings.xml.rels中。

替换fisrt:

代码语言:javascript
复制
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中定义的。

代码语言:javascript
复制
<?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.xmlword/_rels/settings.xml.rels中。

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2017-11-15 07:21:12

最后,我提出了以下解决方案:

代码语言:javascript
复制
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();
}
票数 0
EN

Stack Overflow用户

发布于 2016-04-07 16:10:45

如果您已经在设置部分的相关部分拥有适当的rID (关系ID),我相信您可以这样做。我给出的方法依赖于Linq。

但是请注意,Word可以在Settings.xml中存储两个数据源文件名,并在settings.xml.rels中存储两个对应的关系。更重要的是,它们都有相同的关系类型字符串。AIUI实际上并不使用MailMerge设置的ODSO (“”)中的数据文件名,但是您应该检查。

实现旧关系的一种方法是如下(这就需要Linq ):

代码语言:javascript
复制
// 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);
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/36334545

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档