2012-04-19 62 views
2

使用.NET 4.0/VS2010,Office 2007的将多个文档与Word.Application(COM互操作)结合导致格式不正确?

注意,我接受任何其他的方法来完成最后的结果。我没有与Word结婚,但我的确有限制,无法包含任何许可的第三方工具(无Aspose),并且希望尽量减少用户机器上的任何安装。这是一个企业环境,所以我确实有一些控制权。

我需要打印2个或3个字的文件,作为一个单一的文件。我的代码如下,它的作品....除了第二个文档的格式总是有点关闭(段落间距,字体,边距)。奇怪的是,第三个文档(它有不同的页面方向)很好。有时用户需要将文档发送到传真服务器,因此第一页将是传真封面。

我在哪里失败?方法KillCom(object o)调用System.Runtime.InteropServices.Marshal.ReleaseComObject(o);

public void CombineMultipleDocuments(string coverSheetPath, string[] documentPaths, string destinationFile, bool makeVisible) 
     { 
      List<string> docs = new List<string>(); 

      if (string.IsNullOrWhiteSpace(destinationFile)) 
       throw new ArgumentException("The destinationfile is required"); 
      try 
      { 
       //strip invalid paths 
       foreach (string p in documentPaths) 
       { 
        if (!string.IsNullOrWhiteSpace(p) && File.Exists(p)) 
        { 
         docs.Add(p); 
        } 
       } 

       if (docs.Count == 0) 
        throw new ArgumentException("There are no documents to print"); 
       //open the cover sheet 
       wrdApp = new Word.Application(); 
       wrdApp.Visible = makeVisible; 

       //if there is no cover sheet open the first document and append the remaining docs to it 
       if (string.IsNullOrWhiteSpace(coverSheetPath)) 
       { 
        coverSheetPath = docs[0]; 
        docs.RemoveAt(0); 
       } 
       wrdDoc = wrdApp.Documents.Open(coverSheetPath, ref oMissing, ref oMissing, ref oMissing, ref oMissing, ref oMissing 
        , ref oMissing, ref oMissing, ref oMissing, ref oMissing, ref oMissing, ref oMissing, ref oMissing, ref oMissing 
        , ref oMissing, ref oMissing); 
       wrdRange = wrdDoc.Content; 

       //a little space 
       wrdRange.InsertParagraphAfter(); 
       //attach the rest of the documents 
       foreach (string path in docs) 
       { 
        //open the new source document to be inserted 
        Word._Document newDoc = wrdApp.Documents.Open(path, ref oMissing, ref oMissing, ref oMissing, ref oMissing, ref oMissing 
        , ref oMissing, ref oMissing, ref oMissing, ref oMissing, ref oMissing, ref oMissing, ref oMissing, ref oMissing 
        , ref oMissing, ref oMissing); 

        //continues page break 
        wrdRange.Collapse(Word.WdCollapseDirection.wdCollapseEnd); 
        wrdRange.InsertBreak(Microsoft.Office.Interop.Word.WdBreakType.wdSectionBreakNextPage); 

        //create a new section for our new content 
        Word.Section sec = wrdRange.Sections.Add(ref oMissing, ref oMissing); 

        //copy the source document's styles, fonts, etc 
        sec.PageSetup.Orientation = newDoc.PageSetup.Orientation; 

        sec.Range.Font = newDoc.Content.Font; 

        //unlink footer and headers 
        sec.Footers[Word.WdHeaderFooterIndex.wdHeaderFooterPrimary].LinkToPrevious = false; 
        sec.Footers[Word.WdHeaderFooterIndex.wdHeaderFooterPrimary].Range.FormattedText = newDoc.Sections[1].Footers[Word.WdHeaderFooterIndex.wdHeaderFooterPrimary].Range.FormattedText; 

        sec.Headers[Word.WdHeaderFooterIndex.wdHeaderFooterPrimary].LinkToPrevious = false; 
        sec.Headers[Word.WdHeaderFooterIndex.wdHeaderFooterPrimary].Range.FormattedText = newDoc.Sections[1].Headers[Word.WdHeaderFooterIndex.wdHeaderFooterPrimary].Range.FormattedText; 

        wrdRange.FormattedText = newDoc.Content.FormattedText; 


        //close 
        newDoc.Saved = true; 
        newDoc.Close(ref oFalse, ref oMissing, ref oMissing); 
        newDoc = null; 
        KillCOM(newDoc); 

       } 

       //the diary function needs these variables to be set 
       Word.Variables wrdVars = wrdDoc.Variables; 

       wrdVars.Add("Letter", WrdPropLETTER_NAME); 
       wrdVars.Add("FileKey", WrdPropFILE_KEY); 
       wrdVars.Add("LetterTo", WrdPropLETTER_TO); 
       wrdVars.Add("LetterFirstName", WrdPropLETTER_FNAME); 
       wrdVars.Add("LetterLastName", WrdPropLETTER_LNAME); 
       wrdVars.Add("LetterCompany", WrdPropLETTER_COMPANY); 
       wrdVars.Add("LetterCategory", WrdPropLETTER_CATEGORY); 
       wrdVars.Add("CurrentHeaderDoc",WrdPropCUR_HEADERDOC); 
       wrdVars.Add("CurrentDataDoc", WrdPropCUR_DATADOC); 


       wrdDoc.Protect(Word.WdProtectionType.wdAllowOnlyFormFields, ref oMissing, "mojojojo"); 
       wrdDoc.SaveAs(destinationFile, ref oMissing, ref oMissing, ref oMissing, ref oMissing, ref oMissing 
        , ref oMissing, ref oMissing, ref oMissing, ref oMissing, ref oMissing, ref oMissing, ref oMissing, ref oMissing 
        , ref oMissing, ref oMissing); 

       //close if hidden 
       if (!makeVisible) 
       { 
        wrdDoc.Saved = true; 
        wrdDoc.Close(ref oFalse, ref oMissing, ref oMissing); 

        wrdApp.Quit(ref oFalse, ref oMissing, ref oMissing); 
        wrdDoc = null; 
        wrdApp = null; 
       } 

       //clean up 
       if (File.Exists(coverSheetPath)) 
        File.Delete(coverSheetPath); 
       foreach (string path in documentPaths) 
       { 
        if (File.Exists(path)) 
         File.Delete(path); 
       } 
      } 
      catch (Exception e) 
      { 
       string error = e.ToString(); 
      } 
      finally 
      { 
       wrdRange = null; 
       wrdDoc = null; 
       wrdApp = null; 
       KillCOM(wrdRange); 
       KillCOM(wrdDoc); 
       KillCOM(wrdApp); 

      } 

     } 
+0

你可能会合并不同的样式定义。 – SLaks 2012-04-19 21:27:36

回答

0

我用PasteAndFormat功能,以保持原始格式,并且还复制页面属性,以保持利润率和方向为每个文档。

void mergeDocumentsTest(List<string> documentFiles) 
{ 

     _Application oWord = new Microsoft.Office.Interop.Word.Application(); 
     _Document oDoc = oWord.Documents.Add(); 
     Selection oSelection = oWord.Selection; 

     foreach (string documentFile in documentFiles) 
     { 
      _Document oCurrentDocument = oWord.Documents.Add(documentFile); 
      copyPageSetup(oCurrentDocument.PageSetup, oDoc.Sections.Last.PageSetup); 
      oCurrentDocument.Range().Copy(); 
      oSelection.PasteAndFormat(WdRecoveryType.wdFormatOriginalFormatting); 
      if (!Object.ReferenceEquals(documentFile, documentFiles.Last())) 
       oSelection.InsertBreak(WdBreakType.wdSectionBreakNextPage); 
     } 

     oDoc.SaveAs("testdoc.doc"); 
     oDoc.Close(); 

     //TODO: release objects, close word application 

    } 

    void copyPageSetup(PageSetup source, PageSetup target) 
    { 
     target.PaperSize = source.PaperSize; 

     //target.Orientation = source.Orientation; //not working in word 2003, so here is another way 
     if (!source.Orientation.Equals(target.Orientation)) 
      target.TogglePortrait(); 

     target.TopMargin = source.TopMargin; 
     target.BottomMargin = source.BottomMargin; 
     target.RightMargin = source.RightMargin; 
     target.LeftMargin = source.LeftMargin; 
     target.FooterDistance = source.FooterDistance; 
     target.HeaderDistance = source.HeaderDistance; 
     target.LayoutMode = source.LayoutMode; 
    }