【问题标题】:OpenXML/DocumentFormat.OpenXml set excel as DataSource for MailMerge in word (Letter series)OpenXML/DocumentFormat.OpenXml 将 Excel 设置为 Word 中 MailMerge 的 DataSource(字母系列)
【发布时间】:2015-04-06 16:17:47
【问题描述】:

我尝试将 Excel 文件设置为 Word 中的 Address-List-Source(作为收件人),以便我可以使用 MailMerge 创建一个单词字母系列(例如用于 100 个地址)。

我使用DocumentFormat.OpenXml编写了以下代码,但是当我打开我的DocX文件时,没有数据源。

我使用以下代码:

        using (WordprocessingDocument wordDocument = WordprocessingDocument.Open("Microsoft Word-Dokument (neu).docx", true))
        {
            var settingsPart = wordDocument.MainDocumentPart.GetPartsOfType<DocumentSettingsPart>().First();

            var mailMerge = new MailMerge();

            mailMerge.MainDocumentType = new MainDocumentType();
            mailMerge.MainDocumentType.SetAttribute(new DocumentFormat.OpenXml.OpenXmlAttribute("val", null, "formatLetters"));

            string excel = @"C:\test.xlsx";

            mailMerge.LinkToQuery = new LinkToQuery();

            mailMerge.DataType = new DataType();
            mailMerge.DataType.SetAttribute(new DocumentFormat.OpenXml.OpenXmlAttribute("val", null, "native"));

            mailMerge.ConnectString = new ConnectString();
            mailMerge.ConnectString.SetAttribute(new OpenXmlAttribute("val", null, "Provider=Microsoft.ACE.OLEDB.12.0;Data Source=" + excel + ";Extended Properties=\"Excel 12.0 Xml;HDR=YES\";"));

            mailMerge.Query = new Query();
            mailMerge.Query.SetAttribute(new OpenXmlAttribute("val", null, "SELECT * FROM `Tabelle1$`"));



            mailMerge.ViewMergedData = new ViewMergedData();

            mailMerge.DataSourceObject = new DataSourceObject();
            mailMerge.DataSourceObject.UdlConnectionString = new UdlConnectionString();
            mailMerge.DataSourceObject.UdlConnectionString.SetAttribute(new OpenXmlAttribute("val", null, "Provider=Microsoft.ACE.OLEDB.12.0;Data Source=" + excel + ";Extended Properties=\"Excel 12.0 Xml;HDR=YES\";"));

            mailMerge.DataSourceObject.DataSourceTableName = new DataSourceTableName();
            mailMerge.DataSourceObject.DataSourceTableName.SetAttribute(new OpenXmlAttribute("val", null, "Tabelle1$"));

            mailMerge.DataSourceObject.ColumnDelimiter = new ColumnDelimiter();
            mailMerge.DataSourceObject.ColumnDelimiter.SetAttribute(new OpenXmlAttribute("val", null, "9"));

            settingsPart.Settings.RemoveAllChildren<MailMerge>();
            settingsPart.Settings.InsertAt<MailMerge>(mailMerge, 0);

            foreach (var relationship in wordDocument.ExternalRelationships.Where(Rel => Rel.RelationshipType == "http://schemas.openxmlformats.org/officeDocument/2006/relationships/mailMergeSource"))
            {
                wordDocument.DeleteExternalRelationship(relationship);
            }

            string DataPath = excel;
            var dsRelationship = wordDocument.MainDocumentPart.DocumentSettingsPart.AddExternalRelationship("http://schemas.openxmlformats.org/officeDocument/2006/relationships/mailMergeSource", new Uri(string.Format("file:///{0}", DataPath)));

            if (mailMerge.DataSourceReference == null)
            {
                mailMerge.DataSourceReference = new DataSourceReference();
            }

            mailMerge.DataSourceReference.Id = dsRelationship.Id;
            mailMerge.ViewMergedData.Val = true;
        }

以前有人解决过这个问题吗?

编辑

我添加了关系逻辑,但现在说找不到C:\test.xlsx。但它存在于正确的位置和C:\

还缺少 SQL 语句:

编辑 2

如果我这样创建查询:

mailMerge.Query = new Query()
{
    Val = "SELECT * FROM `Tabelle1$`"
};

选择查询将正确嵌入到 docx 中。

但是缺少Test.xlsx 的错误仍然存​​在...

【问题讨论】:

  • @bibadia 谢谢,我更改了代码,但遇到了一些新问题。您想阅读我的更改吗?谢谢!
  • @bibadia 如果您想发布任何答案,我会将赏金奖励给您! :)

标签: c# ms-word openxml newsletter mailmerge


【解决方案1】:

至少有两个问题:

  1. 属性未正确限定。在 .docx 中,它们显示为 val="whatever",但它们必须是 w:val="whatever"。

你应该能够通过使用例如来解决这个问题

string xmlnsw = @"http://schemas.openxmlformats.org/wordprocessingml/2006/main";

然后更改所有 SetAttribute 语句,以便您拥有,例如

mailMerge.MainDocumentType.SetAttribute(new DocumentFormat.OpenXml.OpenXmlAttribute("val", xmlnsw, "formatLetters"));

(我想有一种更好的编码方式,它利用 Open XML SDK 中的现有常量定义)。

  1. 您还需要(重新)创建至少一个在 w:mailMerge XML 中指定的关系。 (但您已经更改了代码以反映这一点)。

一些额外的 cmets...

据我所知,您现有的代码只修改了其中一种关系。由于 Microsoft 的文档表明 Word 从不“使用” odso 元素的“src”属性,这可能是可以的。然而,Word 确实创建并填充了 src 元素,所以我不确定它永远不会“使用”它。

事实上,对于这种类型的数据源,我认为您可能无论如何都可以删除整个 odso 元素和关联关系。对于文本类型数据源,如果仅指定字段分隔符,您可能需要 odso 元素。

您的代码似乎试图删除现有的关系。它在这里没有这样做,但我没有试图找出原因。我认为这不会导致问题,只是每次针对给定文件运行此代码时,未引用关系的数量都会增加。

我的猜测是,您也可以省略 ConnectString 属性或将其留空(这取决于 .docx 架构的要求)。在最新版本的 Word 中,您通常只需要指定文件名和 Word 查询即可成功连接。如果指定 ConnectString 实际上会导致 Word 使用 ConnectString(而不是生成自己的),则可能会出现问题,例如,如果您使用 Word 2003(它使用 Jet 提供程序而不是 ACE 提供程序)打开。有趣的是,Word 本身在扩展属性中创建并存储了一个带有引擎类型编号(在本例中为 37)而不是名称(“Excel 12.0 Xml”)的 CONNectString。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多