三、CHM文件转换为Word
接下来,我们来延伸下,利用反编译的文件,将CHM转换成Word文件。思路是这样的:利用反编译,得到hhc文件(hhc文件中包含htm或html文件的文件名)和一大堆web页面(如果一开始编译进去的是一大堆的话,呵呵),创建一个word文件,将html文件插入到word中,下面以实例的方式来实现。
为了方便代码管理,我创建了一个类库项目,命名为CHM2Word,里面主要实现将CHM文件反编译并将反编译的文件整合为Word。在CreateCHM项目中调用代码即可,另需要你的机器安装Office2003(对应,添加引用 ->COM->Microsoft Word 11.0 Object Library)或2007(对应,添加引用->COM->Microsoft Word 12.0 Object Library)。
/// <summary>
/// 添加到word中
/// </summary>
/// <param name="pathFileHHC"></param>
/// <param name="saveAs"></param>
public void AddToWord(string pathFileHHC, string saveAs)
{
if (File.Exists(saveAs))
{
throw new Exception("word文件已经存在!");
}
Object Nothing = System.Reflection.Missing.Value;
Microsoft.Office.Interop.Word.Application wApp = (Microsoft.Office.Interop.Word.Application)this.Word();
Document wDoc = wApp.Documents.Add(ref Nothing, ref Nothing, ref Nothing, ref Nothing);
if (wApp == null)
{
throw new Exception("转换失败");
}
try
{
string dirfile = "";//目录位置
dirfile = Path.GetDirectoryName(pathFileHHC);//目录的绝对路径
string[] lines = File.ReadAllLines(pathFileHHC);//读取hhc所有的行,这是为了找出里面的htm或html文件
string quote = "" + (char)34;
long filenumber = 0;
//遍历每一行
foreach (string TextLine in lines)
{
string htmFile = null;
if (TextLine.IndexOf(".html", 0) > 0 || TextLine.IndexOf(".htm", 0) > 0)//如果这一行里面有.htm或者html.的字符串
{
#region 以下代码是获取htm或者html文件名
int endQuote = 0;
if (TextLine.IndexOf(".html", 0) > 0)
{
endQuote = TextLine.IndexOf(quote, TextLine.IndexOf(".html", 0));
}
else
{
endQuote = TextLine.IndexOf(quote, TextLine.IndexOf(".htm", 0));
}
int quoteLoop = 0;
quoteLoop = endQuote - 1;
while (TextLine.Substring(quoteLoop, 1) != quote)
{
quoteLoop = quoteLoop - 1;
}
htmFile = TextLine.Substring(quoteLoop + 1, endQuote - quoteLoop - 1);//获取html文件的名字
#endregion
htmFile = dirfile + "\\" + htmFile;
bool b = false;//是否存在html文件
try
{
b = File.Exists(htmFile);
}
catch (Exception ex)
{
}
if ((!b))
{
continue;
}
//将文件插入到word中
wApp.Selection.InsertParagraphAfter();
filenumber += 1;
if (ProcessFile != null)
{
ProcessFile(this, new ProcessFileEventArgs(htmFile, filenumber));
}
//InsertFile参数说明
//文件名: 必选的 String. 要被插入的文件名和路径。如果没有指定路径,Word默认为当前文件夹
//Range: 可选的 Object. 如果指定的文件时word, 参数为bookmark(书签). 如果文件为其他类型(如Excel工作表), 参数为指定的一个单元或区域,如 R1C1:R3C4
//确定是否转换 可选 Object.如果值为 True,则 word 应用程序将在插入非“ Word 文档”格式的文档时提示对转换进行确认。.
//链接: 可选 Object. 如果值为 True,则可用 INCLUDETEXT 域插入该文档。
//附件: 可选 Object. 为 True 时将该文件作为附件插入电子邮件消息中。
wApp.Selection.InsertFile(htmFile, ref Nothing, ref Nothing, ref Nothing, ref Nothing);
if ((filenumber % 10 == 0))
wDoc.Save();
}
}
wDoc.Save();//保存word
wDoc.Close(ref Nothing, ref Nothing, ref Nothing);//关闭
wApp.Quit(ref Nothing, ref Nothing, ref Nothing);//释放
}
catch (Exception ex)
{
}
finally//释放对象
{
if ((wDoc != null))
{
Marshal.ReleaseComObject(wDoc);
wDoc = null;
}
Marshal.ReleaseComObject(wApp);
wApp = null;
}
}
/// 添加到word中
/// </summary>
/// <param name="pathFileHHC"></param>
/// <param name="saveAs"></param>
public void AddToWord(string pathFileHHC, string saveAs)
{
if (File.Exists(saveAs))
{
throw new Exception("word文件已经存在!");
}
Object Nothing = System.Reflection.Missing.Value;
Microsoft.Office.Interop.Word.Application wApp = (Microsoft.Office.Interop.Word.Application)this.Word();
Document wDoc = wApp.Documents.Add(ref Nothing, ref Nothing, ref Nothing, ref Nothing);
if (wApp == null)
{
throw new Exception("转换失败");
}
try
{
string dirfile = "";//目录位置
dirfile = Path.GetDirectoryName(pathFileHHC);//目录的绝对路径
string[] lines = File.ReadAllLines(pathFileHHC);//读取hhc所有的行,这是为了找出里面的htm或html文件
string quote = "" + (char)34;
long filenumber = 0;
//遍历每一行
foreach (string TextLine in lines)
{
string htmFile = null;
if (TextLine.IndexOf(".html", 0) > 0 || TextLine.IndexOf(".htm", 0) > 0)//如果这一行里面有.htm或者html.的字符串
{
#region 以下代码是获取htm或者html文件名
int endQuote = 0;
if (TextLine.IndexOf(".html", 0) > 0)
{
endQuote = TextLine.IndexOf(quote, TextLine.IndexOf(".html", 0));
}
else
{
endQuote = TextLine.IndexOf(quote, TextLine.IndexOf(".htm", 0));
}
int quoteLoop = 0;
quoteLoop = endQuote - 1;
while (TextLine.Substring(quoteLoop, 1) != quote)
{
quoteLoop = quoteLoop - 1;
}
htmFile = TextLine.Substring(quoteLoop + 1, endQuote - quoteLoop - 1);//获取html文件的名字
#endregion
htmFile = dirfile + "\\" + htmFile;
bool b = false;//是否存在html文件
try
{
b = File.Exists(htmFile);
}
catch (Exception ex)
{
}
if ((!b))
{
continue;
}
//将文件插入到word中
wApp.Selection.InsertParagraphAfter();
filenumber += 1;
if (ProcessFile != null)
{
ProcessFile(this, new ProcessFileEventArgs(htmFile, filenumber));
}
//InsertFile参数说明
//文件名: 必选的 String. 要被插入的文件名和路径。如果没有指定路径,Word默认为当前文件夹
//Range: 可选的 Object. 如果指定的文件时word, 参数为bookmark(书签). 如果文件为其他类型(如Excel工作表), 参数为指定的一个单元或区域,如 R1C1:R3C4
//确定是否转换 可选 Object.如果值为 True,则 word 应用程序将在插入非“ Word 文档”格式的文档时提示对转换进行确认。.
//链接: 可选 Object. 如果值为 True,则可用 INCLUDETEXT 域插入该文档。
//附件: 可选 Object. 为 True 时将该文件作为附件插入电子邮件消息中。
wApp.Selection.InsertFile(htmFile, ref Nothing, ref Nothing, ref Nothing, ref Nothing);
if ((filenumber % 10 == 0))
wDoc.Save();
}
}
wDoc.Save();//保存word
wDoc.Close(ref Nothing, ref Nothing, ref Nothing);//关闭
wApp.Quit(ref Nothing, ref Nothing, ref Nothing);//释放
}
catch (Exception ex)
{
}
finally//释放对象
{
if ((wDoc != null))
{
Marshal.ReleaseComObject(wDoc);
wDoc = null;
}
Marshal.ReleaseComObject(wApp);
wApp = null;
}
}
创建word对象
/// <summary>
/// 创建word对象
/// </summary>
/// <returns></returns>
public object Word()
{
Microsoft.Office.Interop.Word.Application WordApp;
try
{
//WordApp = new Microsoft.Office.Interop.Word.ApplicationClass();//如果是office2003和office2007用这样方法
WordApp = new Microsoft.Office.Interop.Word.Application();//如果是office2010,使用这个方法
}
catch (Exception e)
{
WordApp = null;
}
return WordApp;
}
/// 创建word对象
/// </summary>
/// <returns></returns>
public object Word()
{
Microsoft.Office.Interop.Word.Application WordApp;
try
{
//WordApp = new Microsoft.Office.Interop.Word.ApplicationClass();//如果是office2003和office2007用这样方法
WordApp = new Microsoft.Office.Interop.Word.Application();//如果是office2010,使用这个方法
}
catch (Exception e)
{
WordApp = null;
}
return WordApp;
}