您的位置:首页 > 其它

获取Word目录结构、合并Word文档

2013-03-18 16:07 232 查看
using System;
using System.Collections.Generic;
using System.Text;
using Microsoft.Office.Interop.Word;
using System.Reflection;
using System.IO;
using System.Windows.Forms;

namespace Sysware.Library.WordLib
{
    /// <summary>
    /// Word操作(Word文档合并)
    /// </summary>
    public class WordHelper
    {
        private static ApplicationClass objApp = null;
        private static Document objDocLast = null;
        private static Document objDocBeforeLast = null;

        #region 打开文件

        private static void Open(string tempDoc)
        {
            object objTempDoc = tempDoc;
            object objMissing = System.Reflection.Missing.Value;
            objDocLast = objApp.Documents.Open(
            ref objTempDoc,    //FileName
            ref objMissing,   //ConfirmVersions
            ref objMissing,   //ReadOnly
            ref objMissing,   //AddToRecentFiles
            ref objMissing,   //PasswordDocument
            ref objMissing,   //PasswordTemplate
            ref objMissing,   //Revert
            ref objMissing,   //WritePasswordDocument
            ref objMissing,   //WritePasswordTemplate
            ref objMissing,   //Format
            ref objMissing,   //Enconding
            ref objMissing,   //Visible
            ref objMissing,   //OpenAndRepair
            ref objMissing,  //DocumentDirection
            ref objMissing,  //NoEncodingDialog
            ref objMissing   //XMLTransform
            );
            objDocLast.Activate();

        }

        #endregion

        #region 保存文件到输出模板

        private static void SaveAs(string outDoc)
        {
            object objMissing = System.Reflection.Missing.Value;
            object objOutDoc = outDoc;
            objDocLast.SaveAs(
            ref objOutDoc,    //FileName
            ref objMissing,   //FileFormat
            ref objMissing,   //LockComments
            ref objMissing,    //PassWord
            ref objMissing,    //AddToRecentFiles
            ref objMissing,    //WritePassword
            ref objMissing,    //ReadOnlyRecommended
            ref objMissing,    //EmbedTrueTypeFonts
            ref objMissing,    //SaveNativePictureFormat
            ref objMissing,    //SaveFormsData
            ref objMissing,    //SaveAsAOCELetter,
            ref objMissing,    //Encoding
            ref objMissing,    //InsertLineBreaks
            ref objMissing,    //AllowSubstitutions
            ref objMissing,    //LineEnding
            ref objMissing     //AddBiDiMarks
            );
        }

        #endregion

        #region 循环合并多个文件(复制合并重复的文件)
        /// <summary>   
        /// 循环合并多个文件(复制合并重复的文件)   
        /// </summary>
        /// <param name="tempDoc">模板文件</param>
        /// <param name="arrCopies">需要合并的文件</param>
        /// <param name="outDoc">合并后的输出文件</param>
        public static void CopyMerge(string tempDoc, string[] arrCopies, string outDoc)
        {
            objApp = new ApplicationClass();
            object objMissing = Missing.Value;
            object objFalse = false;
            object objTarget = WdMergeTarget.wdMergeTargetSelected;
            object objUseFormatFrom = WdUseFormattingFrom.wdFormattingFromSelected;
            try
            {
                //打开模板文件
                Open(tempDoc);
                foreach (string strCopy in arrCopies)
                {
                    objDocLast.Merge(strCopy,
                        //FileName
                        ref objTarget,     //MergeTarget
                        ref objMissing,         //DetectFormatChanges
                        ref objUseFormatFrom,   //UseFormattingFrom
                        ref objMissing          //AddToRecentFiles
                        );
                    objDocBeforeLast = objDocLast;
                    objDocLast = objApp.ActiveDocument;
                    if (objDocBeforeLast != null)
                    {
                        objDocBeforeLast.Close(
                        ref objFalse,     //SaveChanges
                        ref objMissing,   //OriginalFormat
                        ref objMissing    //RouteDocument
                        );
                    }
                }
                //保存到输出文件
                SaveAs(outDoc);
                foreach (Document objDocument in objApp.Documents)
                {
                    objDocument.Close(
                    ref objFalse,     //SaveChanges
                    ref objMissing,   //OriginalFormat
                    ref objMissing    //RouteDocument
                    );
                }
            }
            finally
            {
                objApp.Quit(
                ref objMissing,     //SaveChanges
                ref objMissing,     //OriginalFormat
                ref objMissing      //RoutDocument
                );
                objApp = null;
            }
        }

        /// <summary>          
        /// 循环合并多个文件(复制合并重复的文件)          
        /// </summary>
        /// <param name="tempDoc">模板文件</param>
        /// <param name="arrCopies">需要合并的文件</param>
        /// <param name="outDoc">合并后的输出文件</param>
        public static void CopyMerge(string tempDoc, string strCopyFolder, string outDoc)
        {
            string[] arrFiles = Directory.GetFiles(strCopyFolder);
            CopyMerge(tempDoc, arrFiles, outDoc);
        }
        #endregion

        #region 循环合并多个文件(插入合并文件)
        /// <summary>          
        /// 循环合并多个文件(插入合并文件)  
        /// </summary>
        /// <param name="tempDoc">模板文件</param>
        /// <param name="arrCopies">需要合并的文件</param>
        /// <param name="outDoc">合并后的输出文件</param>
        public static void InsertMerge(string tempDoc, string[] arrCopies, string outDoc)
        {
            objApp = new ApplicationClass();
            object objMissing = Missing.Value;
            object objFalse = false;
            object confirmConversion = false;
            object link = false;
            object attachment = false;
            try
            {
                //打开模板文件
                Open(tempDoc);
                foreach (string strCopy in arrCopies)
                {
                    objApp.Selection.InsertFile(
                    strCopy,
                    ref objMissing,
                    ref confirmConversion,
                    ref link,
                    ref attachment
                    );
                }
                //保存到输出文件   
                SaveAs(outDoc);
                foreach (Document objDocument in objApp.Documents)
                {
                    objDocument.Close(
                    ref objFalse,     //SaveChanges
                    ref objMissing,   //OriginalFormat
                    ref objMissing    //RouteDocument
                    );
                }
            }
            catch (Exception ex)
            {
                Console.WriteLine(ex.Message);
            }
            finally
            {
                objApp.Quit(
                ref objMissing,     //SaveChanges
                ref objMissing,     //OriginalFormat
                ref objMissing      //RoutDocument
                );
                objApp = null;
            }
        }

        /// <summary>
        /// 循环合并多个文件(插入合并文件)
        /// </summary>
        /// <param name="tempDoc">模板文件</param>
        /// <param name="arrCopies">需要合并的文件</param>
        /// <param name="outDoc">合并后的输出文件</param>
        public static void InsertMerge(string tempDoc, string strCopyFolder, string outDoc)
        {
            string[] arrFiles = Directory.GetFiles(strCopyFolder);
            InsertMerge(tempDoc, arrFiles, outDoc);
        }

        /// <summary>
        /// 循环合并多个文件(插入合并文件)
        /// </summary>
        /// <param name="arrCopies">需要合并的文件</param>
        /// <param name="outDoc">合并后的输出文件</param>
        public static void InsertMerge(string[] arrCopies, string outDoc)
        {
            try
            {
                string templateDoc = GetDefaultTemplateDoc(outDoc);
                InsertMerge(templateDoc, arrCopies, outDoc);

                File.Delete(templateDoc);
            }
            catch (Exception ex)
            {
                Console.WriteLine(ex.Message);
            }
        }
        #endregion

        #region 创建临时模板文件
        /// <summary>
        /// 创建临时模板文件
        /// </summary>
        /// <param name="path"></param>
        /// <returns></returns>
        private static string GetDefaultTemplateDoc(string path)
        {
            string dir = Path.GetDirectoryName(path);
            string tempFile = (Guid.NewGuid().ToString()) + ".doc";
            tempFile = Path.Combine(dir, tempFile);

            using (FileStream fs = File.Create(tempFile))
            {
                FileInfo fi = new FileInfo(tempFile);
                fi.Attributes = FileAttributes.Hidden;
            }
            return tempFile;
        }
        #endregion

        #region 另存为HTML
        /// <summary>
        /// 将Word文件另存为HTML
        /// </summary>
        /// <param name="baseWordFile"></param>
        /// <param name="destHtmlFile"></param>
        public static bool SaveAsHTML(String baseWordFile, String destHtmlFile)
        {
            Word.ApplicationClass word = new Word.ApplicationClass();
            Type wordType = word.GetType();
            try
            {
                //另存为文件格式
                object FileFormat = Word.WdSaveFormat.wdFormatHTML;
                Word.Documents docs = word.Documents;

                // 打开文件 
                Type docsType = docs.GetType();

                Word.Document doc = (Word.Document)docsType.InvokeMember("Open", System.Reflection.BindingFlags.InvokeMethod
                    , null, docs, new Object[] { baseWordFile, true, true });

                docsType.InvokeMember("SaveAs", System.Reflection.BindingFlags.InvokeMethod, null, doc
                    , new object[] { destHtmlFile, FileFormat });
                //关闭文档
                docsType.InvokeMember("Close", System.Reflection.BindingFlags.InvokeMethod,
                    null, doc, new object[] { null, null, null });
                return true;
            }
            catch (Exception ex)
            {
                Console.WriteLine(ex.InnerException == null ? ex.Message : ex.InnerException.Message);
                return false;
            }
            finally
            {
                try
                {
                    // 退出 Word
                    wordType.InvokeMember("Quit", System.Reflection.BindingFlags.InvokeMethod, null, word, null);
                    System.Runtime.InteropServices.Marshal.ReleaseComObject(word);
                }
                catch (Exception ex)
                {
                    Console.WriteLine(ex.Message);
                }
            }
        }
        #endregion

        #region 获取Word文档目录结构
        /// <summary>
        /// 获取Word文档目录结构,并将目录对应的正文保存到树节点的Tag中
        /// (适用于小文档,效率低)
        /// </summary>
        /// <param name="rootNode">树节点</param>
        /// <param name="docFile">Word文件</param>
        public static void GetDocStructure(TreeNode rootNode, String docFile)
        {
            //文档总段落数
            int paragCount = 0;

            //当前段落级别(1~10 其中10为正文)
            int currentoutlineLevel = -1;

            //段落内容
            string paragraphText = string.Empty;

            //临时树节点
            TreeNode tempNode = null;

            //临时目录实体
            Catalogue tempCatalogue = null;

            //新目录节点的父节点
            TreeNode parentNode = null;

            //最后一个节点(最后添加的节点)
            TreeNode lastNode = rootNode;

            Word.ApplicationClass word = new Word.ApplicationClass();
            Type wordType = word.GetType();
            try
            {
                Word.Documents docs = word.Documents;

                // 打开文件 
                Type docsType = docs.GetType();
                Word.Document doc = (Word.Document)docsType.InvokeMember("Open", System.Reflection.BindingFlags.InvokeMethod
                        , null, docs, new Object[] { docFile, true, true });

                paragCount = doc.Paragraphs.Count;
                for (int i = 1; i <= paragCount; i++)
                {
                    currentoutlineLevel = (int)doc.Paragraphs.Item(i).OutlineLevel;
                    paragraphText = doc.Paragraphs.Item(i).Range.Text;
                    if (currentoutlineLevel < 10)//目录
                    {
                        tempNode = new TreeNode(paragraphText);
                        tempCatalogue = new Catalogue();
                        tempCatalogue.OutlineLevel = currentoutlineLevel;
                        tempNode.Tag = tempCatalogue;
                    }
                    else if (tempNode != null) //正文
                    {
                        tempCatalogue.Contents = tempCatalogue.Contents + "\n" + paragraphText;
                        tempNode.Tag = tempCatalogue;
                    }
                    if (currentoutlineLevel > 9)
                        continue;

                    //将当前目录节点添加到父节点
                    parentNode = GetParentCatalogue(lastNode, currentoutlineLevel);
                    parentNode.Nodes.Add(tempNode);
                    lastNode = tempNode;
                }
            }
            finally
            {
                // 退出 Word
                wordType.InvokeMember("Quit", System.Reflection.BindingFlags.InvokeMethod, null, word, null);
                System.Runtime.InteropServices.Marshal.ReleaseComObject(word);
            }
        }

        /// <summary>
        /// 获取父目录节点
        /// 传入树的最后一个节点,递归获取当前目录级别的父节点
        /// </summary>
        /// <param name="lastNode">树的最后一个节点</param>
        /// <param name="currentOutlineLevel">当前目录级别</param>
        /// <returns>当前目录级别的父目录节点</returns>
        private static TreeNode GetParentCatalogue(TreeNode lastNode, int currentOutlineLevel)
        {
            Catalogue lastCatalogue = lastNode.Tag as Catalogue;
            if (lastCatalogue == null)
                return lastNode;
            if (lastCatalogue.OutlineLevel == currentOutlineLevel) //平级,返回父
                return lastNode.Parent;
            else if (lastCatalogue.OutlineLevel < currentOutlineLevel) //下级,返回当前
                return lastNode;
            else
                return GetParentCatalogue(lastNode.Parent, currentOutlineLevel);//上级,递归找
        }
        #endregion
    }

    /// <summary>
    /// 目录标题实体
    /// </summary>
    public class Catalogue
    {
        int _outlineLevel = 0;
        /// <summary>
        /// 目录级别
        /// </summary>
        public int OutlineLevel
        {
            get { return _outlineLevel; }
            set { _outlineLevel = value; }
        }
        string _contents = string.Empty;
        /// <summary>
        /// 目录正文
        /// </summary>
        public string Contents
        {
            get { return _contents; }
            set { _contents = value; }
        }
    }
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: