本文记录,用 VBA 读取 OneNote 的方法!小白贡献,语失莫怪!
问题背景:
我在 OneNote 里有上百篇笔记,可 OneNote 自己,却无法导出全部的标题。于是我费尽心机,想要读取 OneNote 的文件,来获取标题和日志信息。尝试了各种方案,都没能读出 OneNote 的数据。最后过了好久好久,才找到了这种,基于 Excel VBA 的解决方式!那么接下来,我们就来看下它的代码!在片尾我也会讲下,尝试过的其他方式,大概哪位路过的大神,能解决掉其中的问题!
代码如下:
- 首先要留意,这个代码是要添加到 Excel VBA 编辑器里的!因为 OneNote 里根本就没有 vba 编辑器,以是只能通过 Excel 里的 VBA 编辑器,来实现 OneNote 的操控和读取!
- 然后要留意,在运行代码前,需先添加几个 Reference (引用库)!
- Microsoft OneNote 12.0 Object Library
- Microsoft OneNote 15.0 Object Library
- Microsoft XML, V3.0
- 不同的 Office 可能会出现,这几个库的版本不一样,那么就必要根据你的库的版本,去微调下这个代码!否者会报错!
- 'Add the following references (adjust to your office version):
- '- Microsoft OneNote 12.0 Object Library
- '- Microsoft OneNote 15.0 Object Library
- '- Microsoft XML, v3.0
- Sub ListOneNotePages()
- 'OneNote will be started, if it's not running.
- Dim OneNote As OneNote.Application
- Set OneNote = New OneNote.Application
- 'Get the XML that represents the OneNote pages
- Dim oneNotePagesXml As String
- 'Use note hierarchy, to get all page id.
- OneNote.GetHierarchy "", OneNote12.HierarchyScope.hsPages, oneNotePagesXml
- 'Use the MSXML Library to parse the XML.
- Dim doc As MSXML2.DOMDocument
- Set doc = New MSXML2.DOMDocument
- If doc.LoadXML(oneNotePagesXml) Then
- 'Find all the Page nodes in the one namespace.
- Dim nodes As MSXML2.IXMLDOMNodeList
- Set nodes = doc.DocumentElement.SelectNodes("//one:Page")
- Dim node As MSXML2.IXMLDOMNode
- Dim pageName As String
- Dim sectionName As String
- Dim pageContent As String
- Dim temp As String
- 'Go through each page, and print out page content
- For Each node In nodes
- pageName = node.Attributes.getNamedItem("name").Text
- Debug.Print "Page name: "; vbCrLf & " " & pageName
- Call OneNote.GetPageContent(GetAttributeValueFromNode(node, "ID"), pageContent, piBasic)
- Debug.Print " content: " & pageContent
- Next
- Else
- MsgBox "OneNote 2010 XML Data failed to load."
- End If
- End Sub
- Private Function GetAttributeValueFromNode(node As MSXML2.IXMLDOMNode, attributeName As String) As String
- If node.Attributes.getNamedItem(attributeName) Is Nothing Then
- GetAttributeValueFromNode = "Not found."
- Else
- GetAttributeValueFromNode = node.Attributes.getNamedItem(attributeName).Text
- End If
- End Function
复制代码 Remote Procedure Call Failed 报错:
- 这个报错,我的理解是,它是在说,无法访问你要用的那个程序!具体为什么无法访问,和什么原因,我到现在也还是不知道!
- 在上面 VBA 的解决方案里,我只是把代码里的 OneNote12.Application,改成了 OneNote.Application 就解决了!具体为什么,不知道!但这个报错,确实就没了!我猜测是因为 OneNote 的版本的问题,之前报错,是因为它一直找不到 OneNote14.Application 这个本版本,但细节的问题就不讨论了!
- 但在 Python 的 win32com 方案里,则是一直都卡在,这个报错这里,一直没能过去!也因此在 Python 的解决方案里,到了最后也无法读取任何的 OneNote Page!
OneNote 无法启动问题:
- 如果发现,运行了 Python 的代码后,自己的 OneNote 显示正在恢复,无法打开!不用担心,只需去资源管理器里,把 OneNote.exe 这个任务关掉即可。然后 OneNote 就可以正常打开了!
其他解决方案:
其实在 Excel VBA 的解决方案之前,还尝试了很多很多其他的方案,那也大抵的说一下吧。
- 在 OneNote 中添加 COM 插件,使其能运行宏,雷同于 VBA!这个插件叫做Onetastic!据说这个插件的作者,正是来自原 OneNote 的开辟团队的成员,以是其实这个插件的质量很高,但就是要费钱买,以是最后也没采用这个方案!还有一个插件也很强悍,叫Gem for OneNote,但不符合我的需求!OneNote 的插件还有很多,感兴趣的同学,可以去看下面的链接!
- 就是自己开辟插件,让其能在 OneNote 中运行。这个要求有点高,这种大神应该就不用,看我这篇文章了。以是如果有能力,这也确实是个选项!
- 就是使用 Python 的 win32com,其实 win32com 也是使用的 windows 自己的 com 接口,但 Python 毕竟是通过一个第三库,在做这件事情,以是这个库,要是运行不畅,或者出什么问题,作为小白,就真是很难明决了!就例如一直困扰我的,Remote Procedure Call Failed 的报错问题,就到现在也没能解决!这个报错很可能是,更深层的 COM 服务的问题,很可能是 onenote.dll 没了什么的,但这已经超出小白的范畴了。
- 就是还有各种 Python 的第三方库,例如:pyOneNote,onepy 什么的!我自己几乎都试一遍了,根本没一个好使了,都是很久之前的库了!我以为这可能是,很少有人会去操控 OneNote,以是在这上面花心思的人就很少,这也是为什么,我找了很久,都找不到答案!以是才决定写这篇文章,盼望能给必要的人,一点方便!
一些可用的 Python 代码:
至于下列代码里,为什么都是 OneNote.Application.12 我也不知道!但如果你的欠好使,也可以改成 OneNote.Application.14 试试!但在我的电脑里,只有 OneNote.Application.12 好使!- # 输出页面结构信息
- import win32com.client
- oneapp = win32com.client.Dispatch('OneNote.Application.12')
- result = oneapp.GetHierarchy("",4)
- print(result)
- ## 输出所有页面的标题
- import win32com.client
- oneapp = win32com.client.Dispatch('OneNote.Application.12')
- result = oneapp.GetHierarchy("",4)
- from bs4 import BeautifulSoup
- soup = BeautifulSoup(result, 'xml')
- for tag in soup.find_all('one:Page'):
- print(tag.attrs['name'])
- # 试图输出任何一个页面的内容 (报错暂时无解)
- # >>> Error occurred: (-2147023170, 'The remote procedure call failed)
- import win32com.client
- onapp = win32com.client.Dispatch('OneNote.Application.12')
- result = onapp.GetHierarchy("",4)
- print(result)
- pageID = "任何上面输出过的PageID"
- content = onapp.GetPageContent(pageID)
- print(content)
复制代码 后期的应用
被 VBA 读取出来了,是 OneNote 每个页面的全部内容!信息量很大,都是 XML 形式的!之后的处置惩罚就不再赘述了,怎么处置惩罚就取决于各自的需求了!好的就写到这里了,盼望能有资助,(^_^)b
Reference:
免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。 |