【如何使用aspose.note将onenote笔记本批量转换成html】分享给互联网技能从业者学习和参考。
onenote是一款十分好用的笔记本工具,我想将onenote笔记本转换成html并上传到我的云服务器中,这样在别的主机上就可以查看我做过的笔记。onenote本身并不支持笔记保存为html格式,不过无所不能的插件”GemforOnenote”有这个功能,只是一个个转换过于麻烦,于是使用aspose.notefor.Net将onenote笔记本批量转换成html。
aspose系列提供了word,pdf,excel等文件的操作接口,aspose.notefor.Net顾名思义就是用.Net库对onenote文件进行操作。
安装
在官网上下载aspose.notefor.Net,(下载链接戳这里),用visualstudio新建一个工程,在引用里添加下载的dll文件,就可以使用aspose.note了。
简介和demo
按照我的理解,aspose.note是将一个onenote文件划分成很多个层级,用一种类似于DOM的文档结构模型来表述文件。一个页面上的元素称之为节点(Node),节点又分为CompositeNode和Node,区别在于前者可以包含其它Node,后者不能。页面元素大多继承自这两个基类。
举个例子,一个Document节点由很多个Page子节点构成,Page节点又由Title,Image,RichText等节点构成。每种节点都有相应的类,对其实例化后就可以进行具体的页面元素操作。
官网上有很多demo,举一个将onenote笔记本保存为pdf格式的例子:
//Forcompleteexamplesanddatafiles,pleasegotohttps://github.com/kashifiqb/Aspose.Note-for-.NET
//Thepathtothedocumentsdirectory.
stringdataDir=RunExamples.GetDataDir_LoadingAndSaving();
//LoadthedocumentintoAspose.Note.
DocumentoneFile=newDocument(dataDir+"Aspose.one");
dataDir=dataDir+"SaveWithDefaultSettings_out.pdf";
//SavethedocumentasPDF
oneFile.Save(dataDir,SaveFormat.Pdf);
Save()方法有两个参数,第一个参数是路径名称,第二个参数可以是一个枚举类型SaveFormat,指定保存类型,还可以是SaveOptions及其子类的实例化对象,SaveOptions对象可以在保存时进一步设置,例如从第二页开始保存可以这么写:
//Forcompleteexamplesanddatafiles,pleasegotohttps://github.com/kashifiqb/Aspose.Note-for-.NET
//Thepathtothedocumentsdirectory.
stringdataDir=RunExamples.GetDataDir_LoadingAndSaving();
//LoadthedocumentintoAspose.Note.
DocumentoneFile=newDocument(dataDir+"Aspose.one");
//InitializeImageSaveOptionsobject
ImageSaveOptionsopts=newImageSaveOptions(SaveFormat.Png);
//Setpageindex
opts.PageIndex=1;
dataDir=dataDir+"ConvertSpecificPageToImage_out.png";
//SavethedocumentasPNG.
oneFile.Save(dataDir,opts);
看到这里,我们似乎已经能写出代码,无非也就是遍历onenote文件夹,把每个.one文件的路径作为Document对象构造函数的参数,然后Save()方法保存为html格式。整体上的思路确实是这样,不过还是遇到一些问题,下面一一讲述。
以及,更多的使用方法见官网上的开发指南DevelopGuide
多个page遇到问题
在官网上给的例子都是单页的.one文件,但在多页的情况下(即,onenote右边的“添加页”那一栏有多个标签),直接调用Save()方法保存得到的html只有第一个page的内容,而且是错位的。官网上没有说到多页保存时应该怎么处理,但是既然保存时可以设置PageIndex和PageCount,那么应该是支持多页保存的。我想可能是因为我的aspose.note不兼容我的onenote版本。
首先想到,是不是可以对于每一个Page,都创建一个空白的Document对象,然后把每个Page节点AppendChild()到这个Document对象上,再把这个Document保存成html。然而报错thenodebelongstotheothernode。这是因为节点之间有严格的从属关系,不能随便Append,(我们创建对象的时候就可以看到,例如Pagepage=newPage(doc),这个doc就是一个Document对象,创建对象时就确立了从属关系)即便将之前的Document对象调用RemoveChild()删除Page节点仍然不能让这个节点附着到另一个Document对象上。
那么只好另辟蹊径了,可以用GetChildNodes()得到一个Page的列表,遍历这个列表,每次保存一个Page。
IList<Page>pages=doc.GetChildNodes<Page>();
intcount=pages.Count();
for(inti=0;i<count;i++){
Pagepage=pages[i];
HtmlSaveOptionshs=newHtmlSaveOptions();
hs.PageIndex=i;
hs.PageCount=1;
Console.WriteLine("正在创建HTML"+Path.Combine(child_child_dir,page.Title.TitleText.Text+".html..."));
doc.Save(Path.Combine(child_child_dir,page.Title.TitleText.Text+".html"),hs);
Console.WriteLine("完成");
}
对比文件修改时间,只更新修改过的.one文件
可以稍稍改进一下代码。我们不必每次都生成所有html,可以只有更新后,即当page的修改时间比对应的html文件的修改时间还要迟时才生成。改进后的代码如下:
IList<Page>pages=doc.GetChildNodes<Page>();
intcount=pages.Count();
for(inti=0;i<count;i++){
Pagepage=pages[i];
//若无对应的htmnl文件,或有且源文件(page)修改时间大于目标文件(html),则生成html
stringdes_path=Path.Combine(child_child_dir,page.Title.TitleText.Text+".html");
FileInfodes_file=newFileInfo(des_path);
if(File.Exists(des_path)){
DateTimedes_time=des_file.LastWriteTime;
DateTimesrc_time=page.LastModifiedTime;
if(DateTime.Compare(src_time,des_time)<0)
continue;
}
HtmlSaveOptionshs=newHtmlSaveOptions();
hs.PageIndex=i;
hs.PageCount=1;
Console.WriteLine("正在创建HTML"+des_path+"...");
doc.Save(des_path,hs);
Console.WriteLine("完成");
}
完整代码及运行截图
usingSystem;
usingSystem.Collections.Generic;
usingSystem.Linq;
usingSystem.Text;
usingSystem.Threading.Tasks;
usingAspose.Note;
usingAspose.Note.Saving;
usingSystem.IO;
namespaceOnenote_Up
{
classProgram
{
staticvoidMain(string[]args)
{
stringroot_dir=@"C:UsersfiverDesktoponenotemy_onenoteonenote";
stringnew_root_dir=@"C:UsersfiverDesktoponenotemy_onenotehtml";
DirectoryInfoRootDir=newDirectoryInfo(root_dir);
DirectoryInfoNewRootDir=newDirectoryInfo(new_root_dir);
foreach(DirectoryInfopart_dirinRootDir.GetDirectories()){
stringchild_dir=Path.Combine(root_dir,part_dir.Name);
stringnew_child_dir=Path.Combine(new_root_dir,part_dir.Name);
DirectoryInfoChildDir=newDirectoryInfo(child_dir);
//若没有文件夹则创建
if(!Directory.Exists(child_dir))
{
Directory.CreateDirectory(new_child_dir);
}
//遍历每个文件夹的每个one文件,一个one文件生成对应的一个文件夹,每个one文件的多个page生成多个html放在相应的文件夹下面
else
{
foreach(FileInfonoteinChildDir.GetFiles()){
//只有后缀为one的文件才处理
if(note.Name.Substring(note.Name.Length-3,3)=="one")
{
Documentdoc=newDocument(note.FullName);
//创建对应的文件夹
stringchild_child_dir=Path.Combine(new_child_dir,note.Name.Substring(0,note.Name.Length-4));
if(!Directory.Exists(child_child_dir))
{
Console.WriteLine("创建文件夹"+child_child_dir);
Directory.CreateDirectory(child_child_dir);
}
Console.WriteLine("进入文件夹"+child_child_dir);
//获得.one文件的全部page并遍历
//IsComposite:Checkswhetherthenodeiscomposite.Iftruethenthenodecanhavechildnodes.只有一个page也为true?
if(doc.IsComposite){
IList<Page>pages=doc.GetChildNodes<Page>();
intcount=pages.Count();
for(inti=0;i<count;i++){
Pagepage=pages[i];
//若无对应的htmnl文件,或有且源文件(page)修改时间大于目标文件(html),则生成html
stringdes_path=Path.Combine(child_child_dir,page.Title.TitleText.Text+".html");
FileInfodes_file=newFileInfo(des_path);
if(File.Exists(des_path)){
DateTimedes_time=des_file.LastWriteTime;
DateTimesrc_time=page.LastModifiedTime;
Console.WriteLine(des_path);
Console.WriteLine(src_time.ToString());
Console.WriteLine(des_time.ToString());
if(DateTime.Compare(src_time,des_time)<0)
continue;
}
HtmlSaveOptionshs=newHtmlSaveOptions();
hs.PageIndex=i;
hs.PageCount=1;
Console.WriteLine("正在创建HTML"+des_path+"...");
//doc.Save(des_path,hs);
Console.WriteLine("完成");
}
}
}
}
}
}
Console.WriteLine("Finished.Pressanykeytoexit....");
Console.ReadKey();
}
}
}