2010-10-10 93 views
9

我必须将多个DOCX文件(使用DocX Package创建)合并为一个大文件。我已经设法合并了多个文件,但是我没有合并页眉和页脚(它们在文件,页面之间有所不同)。我试过DocX package和MS Office COM Interop,它根本不想合并页眉/页脚。他们被跳过。将docx文件合并在一起,包括页眉,页脚和图片

有没有人可以提供可行的解决方案?可以是任何东西(包括使用PDFCreator COM转换为PDF,或者Interop或DocX)。

我也试过C#中的PDFCreator示例,它很好地将一个文档转换为PDF,但我不知道如何提供多个文档,因此它会创建一个大的PDF。所以如果任何人都可以提供一个好的(免费)方式,那将是值得赞赏的。

这是我使用:

internal static class DocumentsMerging { 
    private static object missing = Type.Missing; 
    private static ApplicationClass wordApplication { get; set; } 
    private static void addDocument(object path, Document doc, bool firstDocument) { 
     object subDocPath = path; 
     var subDoc = wordApplication.Documents.Open(ref subDocPath, ref missing, ref missing, ref missing, ref missing, ref missing, ref missing, ref missing, ref missing, ref missing, ref missing, ref missing, ref missing, ref missing, ref missing, ref missing); 
     try { 
      if (!firstDocument) { 
       insertPageBreak(doc); 
      } 
      object docStart = doc.Content.End - 1; 
      object docEnd = doc.Content.End; 
      object start = subDoc.Content.Start; 
      object end = subDoc.Content.End; 
      Range rng = doc.Range(ref docStart, ref docEnd); 
      rng.FormattedText = subDoc.Range(ref start, ref end); 
      //if (!lastDocument) { 
      //} 
     } finally { 
      subDoc.Close(ref missing, ref missing, ref missing); 
     } 
    } 
    public static bool deleteFile(string fileName) { 
     if (File.Exists(fileName)) { 
      try { 
       File.Delete(fileName); 
       if (File.Exists(fileName)) { 
        return false; 
       } 
       return true; 
      } catch (IOException) { 
       DialogResult result = MessageBox.Show(new Form {TopMost = true}, "Plik " + fileName + " jest w użyciu lub nie masz uprawnień do zapisania raportu w tym miejscu. Czy chcesz spróbować ponownie?", "Błąd zapisu (000002)", MessageBoxButtons.YesNo, MessageBoxIcon.Stop); 
       if (result == DialogResult.No) { 
        return false; 
       } 
       if (deleteFile(fileName)) { 
        return true; 
       } 
      } catch (Exception e) { 
       MessageBox.Show(new Form {TopMost = true}, "Plik " + fileName + " nie może zostać skasowany. Błąd " + Environment.NewLine + Environment.NewLine + e, "Błąd zapisu (000003)", MessageBoxButtons.YesNo, MessageBoxIcon.Stop); 
       return false; 
      } 
     } else { 
      return true; 
     } 
     return false; 
    } 
    public static void documentsMerge(object fileName, List<string> arrayList) { 
     // object fileName = Path.Combine(Environment.CurrentDirectory, @"NewDocument.doc"); 
     bool varTest = deleteFile(fileName.ToString()); 
     if (varTest) { 
      try { 
       wordApplication = new ApplicationClass(); 
       var doc = wordApplication.Documents.Add(ref missing, ref missing, ref missing, ref missing); 
       try { 
        doc.Activate(); 
        int count = 0; 
        foreach (var alItem in arrayList) { 
         addDocument(alItem, doc, count == 0); 
         count++; 
        } 
        // addDocument(@"D:\Projects\WordTests\ConsoleApplication1\Documents\Doc1.doc", doc) ; //, false); 
        // addDocument(@"D:\Projects\WordTests\ConsoleApplication1\Documents\Doc2.doc", doc) ; //, true); 
        doc.SaveAs(ref fileName, ref missing, ref missing, ref missing, ref missing, ref missing, ref missing, ref missing, ref missing, ref missing, ref missing, ref missing, ref missing, ref missing, ref missing, ref missing); 
       } finally { 
        doc.Close(ref missing, ref missing, ref missing); 
       } 
      } finally { 
       wordApplication.Quit(ref missing, ref missing, ref missing); 
      } 
     } else { 
      return; 
     } 
    } 
    private static void insertPageBreak(Document doc) { 
     object docStart = doc.Content.End - 1; 
     object docEnd = doc.Content.End; 
     Range rng = doc.Range(ref docStart, ref docEnd); 
     // object pageBreak = WdBreakType.wdPageBreak; 
     object pageBreak = WdBreakType.wdSectionBreakNextPage; 

     rng.InsertBreak(ref pageBreak); 
    } 
} 

回答

6

检查了这一点http://devpinoy.org/blogs/keithrull/archive/2007/05/23/how-to-merge-multiple-microsoft-word-documents-in-c.aspx

改变这一行:

object pageBreak = Word.WdBreakType.wdPageBreak; 

这个

object pageBreak = Word.WdBreakType.wdSectionBreakNextPage; 

要获得HEA来自第二份文件的页脚和页脚。

在整个方法中添加以及如何在源更改时调用它。

的类别:

using System; 
using Word = Microsoft.Office.Interop.Word; 
using System.Configuration; 

namespace KeithRull.Utilities.OfficeInterop 
{ 
    public class MsWord 
    { 
    /// <summary> 
    /// This is the default Word Document Template file. I suggest that you point this to the location 
    /// of your Ms Office Normal.dot file which is usually located in your Ms Office Templates folder. 
    /// If it does not exist, what you could do is create an empty word document and save it as Normal.dot. 
    /// </summary> 
    private static string defaultWordDocumentTemplate = @"Normal.dot"; 

    /// <summary> 
    /// A function that merges Microsoft Word Documents that uses the default template 
    /// </summary> 
    /// <param name="filesToMerge">An array of files that we want to merge</param> 
    /// <param name="outputFilename">The filename of the merged document</param> 
    /// <param name="insertPageBreaks">Set to true if you want to have page breaks inserted after each document</param> 
    public static void Merge(string[] filesToMerge, string outputFilename, bool insertPageBreaks) 
    { 
     Merge(filesToMerge, outputFilename, insertPageBreaks, defaultWordDocumentTemplate); 
    } 

    /// <summary> 
    /// A function that merges Microsoft Word Documents that uses a template specified by the user 
    /// </summary> 
    /// <param name="filesToMerge">An array of files that we want to merge</param> 
    /// <param name="outputFilename">The filename of the merged document</param> 
    /// <param name="insertPageBreaks">Set to true if you want to have page breaks inserted after each document</param> 
    /// <param name="documentTemplate">The word document you want to use to serve as the template</param> 
    public static void Merge(string[] filesToMerge, string outputFilename, bool insertPageBreaks, string documentTemplate) 
    { 
     object defaultTemplate = documentTemplate; 
     object missing = System.Type.Missing; 
     object pageBreak = Word.WdBreakType.wdSectionBreakNextPage; 
     object outputFile = outputFilename; 

     // Create a new Word application 
     Word._Application wordApplication = new Word.Application(); 

     try 
     { 
      // Create a new file based on our template 
      Word.Document wordDocument = wordApplication.Documents.Add(
              ref missing 
             , ref missing 
             , ref missing 
             , ref missing); 

      // Make a Word selection object. 
      Word.Selection selection = wordApplication.Selection; 

      //Count the number of documents to insert; 
      int documentCount = filesToMerge.Length; 

      //A counter that signals that we shoudn't insert a page break at the end of document. 
      int breakStop = 0; 

      // Loop thru each of the Word documents 
      foreach (string file in filesToMerge) 
      { 
       breakStop++; 
       // Insert the files to our template 
       selection.InsertFile(
              file 
             , ref missing 
             , ref missing 
             , ref missing 
             , ref missing); 

       //Do we want page breaks added after each documents? 
       if (insertPageBreaks && breakStop != documentCount) 
       { 
        selection.InsertBreak(ref pageBreak); 
       } 
      } 

      // Save the document to it's output file. 
      wordDocument.SaveAs(
          ref outputFile 
         , ref missing 
         , ref missing 
         , ref missing 
         , ref missing 
         , ref missing 
         , ref missing 
         , ref missing 
         , ref missing 
         , ref missing 
         , ref missing 
         , ref missing 
         , ref missing 
         , ref missing 
         , ref missing 
         , ref missing); 

      // Clean up! 
      wordDocument = null; 
     } 
     catch (Exception ex) 
     { 
      //I didn't include a default error handler so i'm just throwing the error 
      throw ex; 
     } 
     finally 
     { 
      // Finally, Close our Word application 
      wordApplication.Quit(ref missing, ref missing, ref missing); 
     } 
    } 
} 
} 

而且,呼叫:

using System; 
using KeithRull.Utilities.OfficeInterop; 

namespace WordDocMerge2 
{ 
    class Program 
    { 
    static void Main(string[] args) 
    { 
     try 
     { 
      string document1 = @"D:\Visual Studio Projects\31.docx"; 
      string document2 = @"D:\Visual Studio Projects\33.docx"; 
      string document3 = @"D:\Visual Studio Projects\32.docx"; 

      string[] documentsToMerge = { document1, document2, document3 }; 

      string outputFileName = String.Format("D:\\Visual Studio Projects\\{0}.docx", Guid.NewGuid()); 

      MsWord.Merge(documentsToMerge, outputFileName, true); 

     } 
     catch (Exception ex) 
     { 
      //messageLabel.Text = ex.Message; 
     } 
    } 
} 
} 
+0

不幸的是,这并没有合并我记得的脚注和标题,因为我记得之前尝试过。 – MadBoy 2010-10-14 07:37:12

+0

好的,我会对这个解决方案进行修改,看看它是否可以修改。 – darkstar3d 2010-10-14 11:50:05

+0

对不起,迟到了,工作赶上了我。如果您更改了我链接的解决方案类中的分页行,它将为您解决。将其更改为以下内容:object pageBreak = Word.WdBreakType.wdSectionBreakNextPage; – darkstar3d 2010-10-14 16:47:13

0

您是否尝试过在XML层次合并? Docx是里面带有Xml文件的zip文件。

您可能可以使用XDocument合并XML。

+0

我没有。我真的不知道如果你能提供这样的方式,情况会如何如此;) – MadBoy 2010-10-19 17:33:29

4

由于newest version of DocX合并工作正常。因此,不用Interop,现在可以直接使用DocX。唯一要知道的headers/footers是从第一个文档(一个模板)中获取的,因为每个文档的页眉/页脚不是按页面设置的。

public static void documentsMerge(object fileName, List<string> arrayList) { 

     bool varTest = deleteFile(fileName.ToString()); 
     if (varTest) 
     { 
      using (DocX documentToCreate = DocX.Load(arrayList[0])) 
      { 


       foreach (var alItem in arrayList.Skip(1)) 
       { 
        documentToCreate.InsertParagraph().InsertPageBreakAfterSelf(); 
        DocX documentToMergeIn = DocX.Load(alItem); 
        documentToCreate.InsertDocument(documentToMergeIn); 
       } 
       documentToCreate.SaveAs(fileName.ToString()); 
      } 
     } 
    } 
+0

你,我的朋友,是一位救星! – Nathan 2017-12-07 13:32:01