使用 Open XML sdk 检索内容控件时出现问题

2024-01-06

我正在开发一个可以生成Word文档的解决方案。 Word文档是根据已定义内容控件的模板文档生成的。当我的模板中只有一个内容控件时,一切都很顺利,但在使用更多内容控件扩展模板文档后,我遇到了异常。我似乎没有找到内容控件。

这是我的方法:

private void CreateReport(File file)

    {
        var byteArray = file.OpenBinary();
        using (var mem = new MemoryStream())
        {
            mem.Write(byteArray, 0, byteArray.Length);
            try
            {
                using (var wordDoc = WordprocessingDocument.Open(mem, true))
                {
                    var mainPart = wordDoc.MainDocumentPart;

                    var firstName = mainPart.Document.Body.Descendants<SdtBlock>().Where
                        (r => r.SdtProperties.GetFirstChild<Tag>().Val == "FirstName").Single();
                    var t = firstName.Descendants<Text>().Single();
                    t.Text = _firstName;

                     var lastName = mainPart.Document.Body.Descendants<SdtBlock>().Where
                        (r => r.SdtProperties.GetFirstChild<Tag>().Val == "LastName").Single();
                     var t2= lastName.Descendants<Text>().Single();
                     t2.Text = _lastName;

                    mainPart.Document.Save();
                    SaveFileToSp(mem);
                }

            }
            catch (FileFormatException)
            {
            }
        }
    }

这是我得到的异常:

System.Core.dll 中发生“System.InvalidOperationException”类型的异常,但未在用户代码中进行处理。内部异常:空

关于如何编写更好的方法来查找控件,有什么建议吗?


您的问题是您的一个(或多个)调用Single()正在对具有多个元素的序列进行调用。这文档 https://msdn.microsoft.com/en-us/library/vstudio/bb155325%28v=vs.100%29.aspx for Single()状态(强调我的):

返回序列中唯一的元素,如果不存在则抛出异常恰好有一个元素在序列中。

在您的代码中,这可能会在两种情况之一中发生。第一个是如果您有多个具有相同功能的控件Tag值,例如,文档中可能有两个标记为“LastName”的控件,这意味着该行

var lastName = mainPart.Document.Body.Descendants<SdtBlock>().Where
                    (r => r.SdtProperties.GetFirstChild<Tag>().Val == "LastName")

将返回两个元素。

第二个是如果您的内容控件有多个Text其中的元素在这种情况下这一行

var t = firstName.Descendants<Text>();

将返回多个元素。例如,如果我创建一个内容为“Thisis一个测试”我最终得到了 XML,其中有 4Text要素:

<w:p w:rsidR="00086A5B" w:rsidRDefault="003515CB">
    <w:r>
        <w:rPr>
            <w:rStyle w:val="PlaceholderText" />
        </w:rPr>
        <w:t xml:space="preserve">This </w:t>
    </w:r>
    <w:r>
        <w:rPr>
            <w:rStyle w:val="PlaceholderText" />
            <w:i />
        </w:rPr>
        <w:t>is</w:t>
    </w:r>
    <w:r>
        <w:rPr>
            <w:rStyle w:val="PlaceholderText" />
        </w:rPr>
        <w:t xml:space="preserve"> </w:t>
    </w:r>
    <w:r w:rsidR="00E1178E">
        <w:rPr>
            <w:rStyle w:val="PlaceholderText" />
        </w:rPr>
        <w:t>a test</w:t>
    </w:r>
</w:p>

如何解决第一个问题取决于您是否想要更换all的匹配的Tag元素或只是一个特定的元素(例如第一个或最后一个)。

如果您只想更换一个,您可以更改呼叫来源Single() to First() or Last()例如,但我想你需要将它们全部替换掉​​。在这种情况下,您需要循环您想要替换的每个标签名称的每个匹配元素。

删除呼叫Single()将返回一个IEnumerable<SdtBlock>您可以迭代替换每一个:

IEnumerable<SdtBlock> firstNameFields = mainPart.Document.Body.Descendants<SdtBlock>().Where
    (r => r.SdtProperties.GetFirstChild<Tag>().Val == "FirstName");

foreach (var firstName in firstNameFields)
{
    var t = firstName.Descendants<Text>().Single();
    t.Text = _firstName;
}

解决第二个问题稍微棘手一些。这easiest我认为解决方案是从内容中删除所有现有段落,然后添加一个包含您希望输出的文本的新段落。

将其分解为一个方法可能是有意义的,因为有很多重复的代码 - 按照这些思路应该可以做到这一点:

private static void ReplaceTags(MainDocumentPart mainPart, string tagName, string tagValue)
{
    //grab all the tag fields
    IEnumerable<SdtBlock> tagFields = mainPart.Document.Body.Descendants<SdtBlock>().Where
        (r => r.SdtProperties.GetFirstChild<Tag>().Val == tagName);

    foreach (var field in tagFields)
    {
        //remove all paragraphs from the content block
        field.SdtContentBlock.RemoveAllChildren<Paragraph>();
        //create a new paragraph containing a run and a text element
        Paragraph newParagraph = new Paragraph();
        Run newRun = new Run();
        Text newText = new Text(tagValue);
        newRun.Append(newText);
        newParagraph.Append(newRun);
        //add the new paragraph to the content block
        field.SdtContentBlock.Append(newParagraph);
    }
}

然后可以从您的代码中调用它,如下所示:

using (var wordDoc = WordprocessingDocument.Open(mem, true))
{
    var mainPart = wordDoc.MainDocumentPart;

    ReplaceTags(mainPart, "FirstName", _firstName);
    ReplaceTags(mainPart, "LastName", _lastName);

    mainPart.Document.Save();
    SaveFileToSp(mem);
}
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

使用 Open XML sdk 检索内容控件时出现问题 的相关文章

  • MS Word 的免费库 [关闭]

    就目前情况而言 这个问题不太适合我们的问答形式 我们希望答案得到事实 参考资料或专业知识的支持 但这个问题可能会引发辩论 争论 民意调查或扩展讨论 如果您觉得这个问题可以改进并可能重新开放 访问帮助中心 help reopen questi
  • 开始VSTO开发

    我很困惑有哪些必要的工具VSTO http en wikipedia org wiki http en wikipedia org wiki Visual Studio Tools for Office发展 具体来说 我想以编程方式操作 E
  • 对通过 OpenXML 与 Microsoft Word 通信的应用程序进行单元测试

    我正在修改一个与 Microsoft Word 进行大量 对话 的应用程序 现在 使用 COM 互操作 但我需要将其更改为 Open XML 我想为此引入单元测试 但我不知道如何做到这一点 这是例如操作之一 模板word文档包含一些书签 该
  • 是否可以自动化即点即用应用程序?

    我有一个小型应用程序 可以通过 COM OLE 自动化实现 Microsoft Word 的自动化 不幸的是 这不适用于虚拟化的即点即用版本的 Word 因为它们在注册表中没有所需的密钥 至少不是预期的位置 换句话说 CreateObjec
  • Office 2016 共享按钮 IdMso

    我正在尝试禁用 Office 2016 应用程序右上角的新共享按钮 有谁知道通讯员IdMso吗 我尝试查找 IdMso 表 但只找到 Office 早期版本的表 Microsoft 已在此处发布了 Office 2016 的 ID Offi
  • MS 缺少 VSTO 4.0 运行时下载?

    我们有代码检查 VSTO 4 0 运行时是否存在并下载 如果丢失 直到今天这一切都运作良好 MS 中的 VSTO 运行时文件似乎丢失了 有人对这个有了解吗 我们能否告诉客户这是 MS 问题并且很快就会得到解决 Google 没有找到任何有关
  • 通过 OpenXml SDK 的 XLSX 文件有效和无效

    我有一个程序将 System Data DataTable 导出到 XLSX OpenXml 电子表格 最后让它大部分工作 但是 当在 Excel 中打开电子表格时 Excel 抱怨文件无效 需要修复 并给出此消息 我们发现 中的某些内容存
  • 如何解析 WordOpenXML 输出中的 mathML?

    我只想读取用于生成方程的 xml 这是我通过使用获得的Paragraph Range WordOpenXML 但用于方程的部分并不符合MathML我发现Equation微软的MathML 我是否需要使用一些特殊的转换器来获取所需的 xml
  • Excel.Application.SelectionChange 仅触发一次

    我只收到第一个事件通知 之后什么也没有发生 有任何想法吗 UPD 我发现了一件奇怪的事情 我的事件处理程序代码如下所示 var cell range Cells 1 1 var rangeName cell Address false fa
  • 如何使用开放的XML SDK基于C#中每行的列读取xlsx?

    我正在尝试使用 open xml sdk 读取一些 xlsx 文件 但我真的很难找到任何好的示例 我想要做的是读取整个 XLSX 文件并循环所有行并从我指定的列中提取单元格值 单元格文本 就像下面这样 GetCellText rowId C
  • 在 MS Excel 中为字符分配一个值并执行字符串(具有字符)的数学函数(+、-、*、/)

    我想根据给定字符串 ABCDEF 的预分配值对其进行求和 即首先我想为每个字符分配值 然后计算具有预先分配的字符的字符串的总值 excel中可以实现这个功能吗 例如 在下面 A 2 B 5 C 8 D 1 E 1 F 2 sum of AB
  • Sharepoint 2013 MVC 5 提供商托管的应用程序。无法使用 [SharePointContextFilter] 在 HttpPost 上进行身份验证

    过去一周我一直在绞尽脑汁 无法解决对共享点提供商托管的应用程序进行正确身份验证的一些问题 我目前正在为公司的 Sharepoint 在线开发一个 sharepoint 应用程序 我正在使用 Visual Studio 2013 我将该应用程
  • 将多个图像添加到 Word 文档的特定位置 OpenXML

    我正在使用 Office Open XML 并且必须在特定点添加图像 在文档上我有一个 标签 这样我就可以很好地找到它 但是 当我添加多个图像时 它会损坏文件 这是我的代码 修改自https msdn microsoft com en us
  • 使用 Python 在 OpenOffice/Microsoft Word 中格式化输出

    我正在开发一个需要格式化 可编辑输出的项目 Python 由于最终用户不会精通技术 因此输出需要采用文字处理器可编辑的格式 格式很复杂 要点 段落 粗体等 有没有办法使用Python生成这样的报告 我觉得应该有一种方法可以使用 Micros
  • OSX/Mac 中的插件持久设置

    我无法找到在 Mac 上存储 Office js 加载项的持久设置的方法 在 Windows 上 localStorage 工作得非常完美 因为它可以保存关闭和打开 Word 时仍保留的设置 在 Mac 上 localStorage 不会持
  • 将 OpenXML 文档嵌入到另一个 OpenXml 文档中

    我需要在一个文件夹中收集多个 docx 文件 并将它们 链接 到一个将显示给用户的文档中 现在我已经读过了布莱恩 琼斯的文章 http blogs msdn com brian jones archive 2009 06 30 embedd
  • MS Office PIA“向后兼容性”

    我已经成功完成了与 MS Word 集成的 Windows 窗体应用程序 该应用程序写入 Word 模板中的合并字段 我使用 MS Word 2007 制作了该模板 但以兼容模式将其保存为 97 2003 dot 文件 由于我安装了 Off
  • 将表(行)与 OpenXML SDK 2.5 保持在一起

    我想在 Word 文档中生成多个表 每行 2 行 但我想将这两行保留在一起 如果可能的话 new KeepNext 第一行不起作用 new KeepNext 第一行的最后一段不起作用 new CantSplit 放在桌子上不起作用 在所有情
  • 更新清单 XML 后强制 Excel 刷新命令功能区(对于 Office 加载项)

    我正在使用 office js 和位于共享驱动器上的 XML 清单来侧载 Office 加载项 加载加载项后 这会添加一个新的功能区 其中包含一些自定义命令图标 然而 编辑manifest XML文件后 假设我从功能区注释掉命令图标 我还没
  • 如何使用 OpenXML SDK 2.5 生成目录?

    我已阅读并理解this https stackoverflow com questions 9762684 how to generate table of contents using openxml sdk 2 0 and this h

随机推荐

  • 将文件从应用程序拖动到资源管理器。我的应用程序可以进行复制吗?

    在 Qml 中 我可以使用以下命令开始拖动text uri listmime 类型 以便启动从我的应用程序到文件资源管理器的复制操作 例如 Item id draggable anchors fill parent Drag active
  • 从元素中删除 :active 伪类

    我希望能够告诉一个元素它不再是 active这样 CSS 规则就不再适用 有没有办法在 JavaScript 中做到这一点 可能的解决方案 1 使用类 JS document getElementById element classList
  • ARM 周期精确模拟器

    是否有免费且周期精确的 ARM Cortex A9 模拟器 我认为 ARM IDE 提供了某种分析器 但首先我不确定它是否提供命令行界面 其次它不是免费的 我希望能从 GNU 找到一些东西 但我找不到 没有可用于最新 ARM 内核的免费周期
  • 以编程方式获取 12 Hive 的目录路径

    有没有办法以编程方式获取12 Hive的目录路径 我正在创建一个功能 将文件传递到 12 配置单元中的 XML 目录 并且我不想在代码中硬编码目录路径 是否有任何对象模型属性将 12 Hive 目录路径字符串公开为属性 您可以使用 Micr
  • SQL DataReader 网络使用限制

    我有这样的想法 不知道好坏 我有实用程序 它通过 reglament 连接到 SQL Server 并将一些数据获取到应用程序 数据很简单 2 个 varchar 文本属性 但数据数量约为 300 万行 因此 我的应用程序非常频繁地使用网络
  • 使用 PHP Simple HTML DOM Parser 之前登录 ASP 网站

    我正在使用 PHP Simple HTML DOM Parser 来解析来自游戏 ASP 网站的数据 我需要获取的数据仅对注册用户可见 因此在开始使用之前我需要一些东西来登录网站 有人可以建议我一个脚本或可以做到这一点的东西吗 预先非常感谢
  • 如何在 guile-2.0.11 的 macOS Sierra 版本上修复 libguile/stime.c?

    在此输入链接描述 http lists gnu org archive html bug guile 2016 06 msg00252 htmlguile 2 0 11 的构建因以下错误而停止 Undefined symbols for a
  • 如果命名空间也定义为默认值,则强制 XDocument 不使用命名空间前缀

    我有一个 xml 文件 其中指定了带或不带名称空间前缀的默认名称空间 当我生成 xml 输出时 我会为所有 xml 元素添加前缀 由于我使用的是默认命名空间 有没有办法摆脱前缀 class Program static void Main
  • 物理内存的对齐是如何保证的?

    malloc 返回适合任何内置类型的内存 如果需要更具体的对齐 例如 16 或 32 字节 可以在应用程序级别完成 但这种对齐是在虚拟内存级别 如何保证底层物理内存也处于相同的对齐方式 虚拟内存是在页面级别实现的 因此每个虚拟机页面在加载到
  • 从 F# 中的序列中删除单个非唯一值

    我有一个代表 F 中骰子的整数序列 在所讨论的游戏中 玩家有一池骰子 可以选择玩一个 受某些规则约束 并保留其余的 例如 如果玩家掷出 6 6 和 4 并决定玩一个 6 是否有一种简单的方法可以返回仅删除一个 6 的序列 Seq filte
  • Python - 快速批量修改PNG

    我编写了一个 python 脚本 以独特的方式为 OpenGL 着色器组合图像 问题是我有大量非常大的地图 需要很长时间来处理 有没有办法以更快的方式写这个 import numpy as np map data image data fo
  • 反应本机构建错误:包 android.support.annotation 不存在

    我必须完全重写这个问题 我有一个反应本机 Android 应用程序 当我建造apk文件与 gradlew assembleRelease x bundleReleaseJsAndAssets 一切顺利 但之后就完全停止编译了 甚至react
  • 无限斐波那契数列

    我正在尝试使用序列在 F 中模仿 Haskell 著名的无限斐波那契列表 为什么以下序列的计算结果不符合预期 它是如何被评估的 let rec fibs lazy Seq append Seq ofList 0 1 Seq map2 fib
  • Wicket 是适合单页应用程序的 Web java 框架吗? [关闭]

    就目前情况而言 这个问题不太适合我们的问答形式 我们希望答案得到事实 参考资料或专业知识的支持 但这个问题可能会引发辩论 争论 民意调查或扩展讨论 如果您觉得这个问题可以改进并可能重新开放 访问帮助中心 help reopen questi
  • linq toEntity vs Fluent nhibernate vs linq to sql(帮助)

    我必须为新闻频道建立一个网站 请帮我决定使用哪种技术进行数据操作 1 实体连接 2 Linq 到 SQL 3 流畅的NHibernate 4 ADO Net 网站将基于 ASP Net MVC 和 C 主要问题 1 应该易于维护和扩展 2
  • Visual Studio Code Intellisense 不适用于 Javascript

    我在 Windows 和 Mac 上使用 Visual Studio Code VSC 0 10 11 为了解决这个问题 我有这个小 JavaScript 片段 use strict const os require os console
  • 每天在 8:00、12:30、17:00 运行 Gmail Google Apps 脚本

    我需要每天运行 Google Apps 脚本 3 次 8 00 12 30 17 00 这个怎么做 我已经看过了Triggers 更具体地说Time driven 小时计时器 但是Every hour Every 2 hours Every
  • 如何获取扩展列表视图项中复选框的ID?

    我有一个扩展列表视图 其中父节点和子项目中都有复选框 所有数据均来自网络服务 因此是动态的 附图 现在在菜单项上单击 我想获取所有复选框状态 请指导我如何获取其中使用的复选框的 ID 附代码 public class Object Secu
  • 获取当前页面的url

    在使用 GAS HtmlService 的 Web 应用程序上 我需要获取当前页面的 url 以在模板中构建新链接 该网络应用程序将在 Google 站点页面 GAS 作为小工具 中运行 但也可以独立运行 我正在尝试 var pageUrl
  • 使用 Open XML sdk 检索内容控件时出现问题

    我正在开发一个可以生成Word文档的解决方案 Word文档是根据已定义内容控件的模板文档生成的 当我的模板中只有一个内容控件时 一切都很顺利 但在使用更多内容控件扩展模板文档后 我遇到了异常 我似乎没有找到内容控件 这是我的方法 priva