如何使用C#和OneNote Interop编写到OneNote 2013页面

14

我看到了很多关于这个问题的文章,但要么不完整,要么不能回答我的问题。 我想使用C#和OneNote Interop,简单地向现有的OneNote 2013页面编写文本。 目前,我有一个OneNote笔记本,其中包含一个名为"Sample_Section"的部分和一个名为"MyPage"的页面。

我需要能够使用C#代码将文本写入此页面,但我无法弄清楚如何做或找到任何资源来完成这项工作。 我查看了所有网络上的代码示例,没有一个回答了这个简单的问题或者能够实现这个功能。 此外,许多代码示例已经过时,在尝试运行它们时会出错。

我使用了Microsoft的代码示例来显示如何更改部分的名称,但我找不到任何可用于编写文本到Page的代码。 我目前没有看到任何简单的方法来完成这件事。 我花了很多时间来研究这个问题并查看网络上的不同示例,但是没有一个能够帮助我。

我已经查看了关于OneNote InteropMSDN文章。 我大致了解XML是如何通过OneNote Interop工作的,但我也希望能够获得理解这一点的任何额外帮助。 最重要的是,我真的很希望有一个示例代码,演示如何向OneNote 2013笔记本页面编写文本。

我尝试使用Stack Overflow答案进行操作:Creating new One Note 2010 page from C#

然而,这个解决方案有两个问题无法回答我的问题:

1)标记的解决方案显示如何创建一个新页面,而不是如何将文本写入其中或如何填充页面的任何信息。

2)当我尝试运行标记为解决方案的代码时,我在以下行收到错误提示:

var node = doc.Descendants(ns + nodeName).Where(n => n.Attribute("name").Value == objectName).FirstOrDefault();
return node.Attribute("ID").Value;
由于“node”的值为null,非常感谢任何帮助。
3个回答

18

我在MSDN论坛上问了同样的问题,得到了一个很好的答案。以下是一个漂亮、干净的示例,展示了如何使用C#和OneNote互操作来写入OneNote。希望这可以帮助未来的人们。

    static Application onenoteApp = new Application();
    static XNamespace ns = null;

    static void Main(string[] args)
    {
        GetNamespace();
        string notebookId = GetObjectId(null, OneNote.HierarchyScope.hsNotebooks, "MyNotebook");
        string sectionId = GetObjectId(notebookId, OneNote.HierarchyScope.hsSections, "Sample_Section");
        string firstPageId = GetObjectId(sectionId, OneNote.HierarchyScope.hsPages, "MyPage");
        GetPageContent(firstPageId);
        Console.Read();
    }
    static void GetNamespace()
    {
        string xml;

        onenoteApp.GetHierarchy(null, OneNote.HierarchyScope.hsNotebooks, out xml);
        var doc = XDocument.Parse(xml);
        ns = doc.Root.Name.Namespace;
    }

    static string GetObjectId(string parentId, OneNote.HierarchyScope scope, string objectName)
    {
        string xml;
        onenoteApp.GetHierarchy(parentId, scope, out xml);

        var doc = XDocument.Parse(xml);
        var nodeName = "";

        switch (scope)
        {
            case (OneNote.HierarchyScope.hsNotebooks): nodeName = "Notebook"; break;
            case (OneNote.HierarchyScope.hsPages): nodeName = "Page"; break;
            case (OneNote.HierarchyScope.hsSections): nodeName = "Section"; break;
            default:
                return null;
        }

        var node = doc.Descendants(ns + nodeName).Where(n => n.Attribute("name").Value == objectName).FirstOrDefault();

        return node.Attribute("ID").Value;
    }
    static string GetPageContent(string pageId)
    {
        string xml;
        onenoteApp.GetPageContent(pageId, out xml, OneNote.PageInfo.piAll);
        var doc = XDocument.Parse(xml);
        var outLine = doc.Descendants(ns + "Outline").First();
        var content = outLine.Descendants(ns + "T").First();
        string contentVal = content.Value;
        content.Value = "modified";
        onenoteApp.UpdatePageContent(doc.ToString());
        return null;
    }

如果你使用这段代码,请注意,看似无害的方法GetPageContent()实际上会将内容更新为单词"modified"。这可能不是你想要的结果。 - Erica Ackerman

2

我只是通过阅读网络上的例子(当然,你已经阅读了所有这些例子)和使用ONOMspy查看OneNote在XML中存储其数据的方式(http://blogs.msdn.com/b/johnguin/archive/2011/07/28/onenote-spy-omspy-for-onenote-2010.aspx)来获得这些信息。

如果您想使用OneNote内容,您需要基本了解XML。将文本写入OneNote页面涉及创建大纲元素,其内容将包含在OEChildren元素中。在OEChildren元素中,您可以有许多其他表示大纲内容的子元素。如果我正确地阅读模式,则可以是OEHTMLBlock类型。就个人而言,我只使用过OE,在这种情况下,您将拥有一个包含T(文本)元素的OE元素。以下代码将创建一个大纲XElement并向其中添加文本:

// Get info from OneNote
string xml;
onApp.GetHierarchy(null, OneNote.HierarchyScope.hsSections, out xml);
XDocument doc = XDocument.Parse(xml);
XNamespace ns = doc.Root.Name.Namespace;

// Assuming you have a notebook called "Test"
XElement notebook = doc.Root.Elements(ns + "Notebook").Where(x => x.Attribute("name").Value == "Test").FirstOrDefault();
if (notebook == null)
{
    Console.WriteLine("Did not find notebook titled 'Test'.  Aborting.");
    return;
}

// If there is a section, just use the first one we encounter
XElement section;
if (notebook.Elements(ns + "Section").Any())
{
    section = notebook.Elements(ns + "Section").FirstOrDefault();
}
else
{
    Console.WriteLine("No sections found.  Aborting");
    return;
}

// Create a page
string newPageID;
onApp.CreateNewPage(section.Attribute("ID").Value, out newPageID);

// Create the page element using the ID of the new page OneNote just created
XElement newPage = new XElement(ns + "Page");
newPage.SetAttributeValue("ID", newPageID);

// Add a title just for grins
newPage.Add(new XElement(ns + "Title",
    new XElement(ns + "OE",
        new XElement(ns + "T",
            new XCData("Test Page")))));

// Add an outline and text content
newPage.Add(new XElement(ns + "Outline",
    new XElement(ns + "OEChildren",
        new XElement(ns + "OE",
            new XElement(ns + "T",
                new XCData("Here is some new sample text."))))));

// Now update the page content
onApp.UpdatePageContent(newPage.ToString());

以下是您发送到OneNote的实际XML:

<Page ID="{20A13151-AD1C-4944-A3D3-772025BB8084}{1}{A1954187212743991351891701718491104445838501}" xmlns="http://schemas.microsoft.com/office/onenote/2013/onenote">
  <Title>
    <OE>
      <T><![CDATA[Test Page]]></T>
    </OE>
  </Title>
  <Outline>
    <OEChildren>
      <OE>
        <T><![CDATA[Here is some new sample text.]]></T>
      </OE>
    </OEChildren>
  </Outline>
</Page>

希望这能帮助你开始!(注:已保留HTML标签,无其他修改)

-1
如果您正在使用C#,请查看http://dev.onenote.com上的较新的OneNote REST API。它已经支持创建一个新页面,并且具有用于修补和添加内容到现有页面的beta API。

2
谢谢,不过在发布之前我已经阅读了上面的文章,甚至尝试了一些代码示例。但是我仍然无法找到使用Interop添加文本/内容到OneNote文档的代码。我并不想开发像Windows Store / Windows Phone应用程序这样会不断与OneNote或OneNote API通信的应用程序。我理想情况下只是想设计一个控制台应用程序来创建和编辑OneNote文档。类似于使用Interop为Word和Excel所做的操作。 - B17
看看这个链接是否有帮助:http://stackoverflow.com/questions/14875760/onenote-inserting-elements-with-updatepagecontent - DipakBoyed
1
这难道不仅适用于在线OneNote文档吗? - johnny

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接