Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/324.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# OpenXML/DocumentFormat.OpenXML将excel设置为word(字母系列)中邮件合并的数据源_C#_Ms Word_Openxml_Newsletter_Mailmerge - Fatal编程技术网

C# OpenXML/DocumentFormat.OpenXML将excel设置为word(字母系列)中邮件合并的数据源

C# OpenXML/DocumentFormat.OpenXML将excel设置为word(字母系列)中邮件合并的数据源,c#,ms-word,openxml,newsletter,mailmerge,C#,Ms Word,Openxml,Newsletter,Mailmerge,我尝试将excel文件设置为word中的地址列表源(作为收件人),以便使用MailMerge创建word信函系列(例如100个地址) 我使用DocumentFormat.OpenXml编写了以下代码,但是当我打开DocX文件时,没有数据源 我使用以下代码: using (WordprocessingDocument wordDocument = WordprocessingDocument.Open("Microsoft Word-Dokument (neu).docx", tr

我尝试将excel文件设置为word中的地址列表源(作为收件人),以便使用MailMerge创建word信函系列(例如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;
        }
select查询将正确嵌入docx中


但是缺少
测试.xlsx的错误仍然存在…

至少存在两个问题:

  • 属性未正确限定。在.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"));
    
    (我想有一种更好的编码方法可以利用开放式XMLSDK中现有的常量定义)

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

    据我所知,您现有的代码只修改了其中一个关系。因为微软的文档表明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

    @bibadia谢谢,我更改了密码,但遇到了一些新问题。你想看看我的变化吗?谢谢大家!@比巴迪亚如果你想发布任何答案,我会将奖金奖励给你!:)
    mailMerge.MainDocumentType.SetAttribute(new DocumentFormat.OpenXml.OpenXmlAttribute("val", xmlnsw, "formatLetters"));