How To Write To A OneNote 2013 Page Using C# and The OneNote Interop
Asked Answered
D

3

15

I have seen many articles about this but all of them are either incomplete or do not answer my question. Using C# and the OneNote Interop, I would like to simply write text to an existing OneNote 2013 Page. Currently I have a OneNote Notebook, with a Section titled "Sample_Section" and a Page called "MyPage".

I need to be able to use C# code to write text to this Page, but I cannot figure out how or find any resources to do so. I have looked at all of the code examples on the web and none answer this simple question or are able to do this. Also many of the code examples are outdated and break when attempting to run them.

I used the Microsoft code sample that shows how to change the name of a Section but I cannot find any code to write text to a Page. There is no simple way to do this that I can see. I have taken a lot of time to research this and view the different examples online but none are able to help.

I have already viewed the MSDN articles on the OneNote Interop as well. I vaguely understand how the OneNote Interop works through XML but any extra help understanding that would also be appreciated. Most importantly I would really appreciate a code example that demonstrates how to write text to a OneNote 2013 Notebook Page.

I have tried using this Stack Overflow answer: Creating new One Note 2010 page from C#

However, there are 2 things about this solution that do not answer my question:

1) The marked solution shows how to create a new page, not how to write text to it or how to populate the page with any information.

2) When I try to run the code that is marked as the solution, I get an error at the following line:

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

The reason being that the value of "node" is null, any help would be greatly appreciated.

Donata answered 4/12, 2014 at 12:48 Comment(0)
D
19

I asked the same question on MSDN forums and was given this great answer. Below is a nice, clean example of how to write to OneNote using C# and the OneNote interop. I hope that this can help people in the future.

    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;
    }
Donata answered 7/12, 2014 at 2:50 Comment(1)
If you use this code, be aware that the innocently named method GetPageContent() actually updates the content to the word "modified". This may not be what you intended.Aspirin
S
2

This is just what I've gleaned from reading examples on the web (of course, you've already read all of those) and peeking into the way OneNote stores its data in XML using ONOMspy (http://blogs.msdn.com/b/johnguin/archive/2011/07/28/onenote-spy-omspy-for-onenote-2010.aspx).

If you want to work with OneNote content, you'll need a basic understanding of XML. Writing text to a OneNote page involves creating an outline element, whose content will be contained in OEChildren elements. Within an OEChildren element, you can have many other child elements representing outline content. These can be of type OE or HTMLBlock, if I'm reading the schema correctly. Personally, I've only ever used OE, and in this case, you'll have an OE element containing a T (text) element. The following code will create an outline XElement and add text to it:

// 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());

Here's what the actual XML you're sending to OneNote looks like:

<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>

Hope that helps get you started!

Spiritism answered 9/3, 2015 at 19:45 Comment(0)
L
-2

If you're using C#, Check out the newer OneNote REST API at http://dev.onenote.com. It already supports creating a new page and has a beta API to patch and add content to an existing page.

Ligula answered 4/12, 2014 at 21:43 Comment(3)
Thank you, however I have already read the above article before posting and even tried some code examples. And I was still not able to find the code to add text/content to a OneNote document using the Interop. I am not trying to develop an application such as a Windows Store/Windows Phone application that is going to constantly commmunicate with OneNote or the OneNote API. I am ideally just looking to design a console application to create and edit a One Note document. Similar to what can be done using Interop for Word and ExcelDonata
See if #14876260 helps.Ligula
Isn't this solely for online OneNote documents?Hakan

© 2022 - 2024 — McMap. All rights reserved.