This project has moved. For the latest updates, please go here.

InsertDocument at Index

Feb 27, 2012 at 8:43 AM

Is it possible to insert a document at an index? Any work around for this?

Thanks in advance!

-M

Developer
Feb 27, 2012 at 9:00 AM

You mean if there's workaround to merge multiple documents into one due to bug in current Insert Document? Yes there is. Interop :( If you want I can send you the code I use but basically it's gonna require office installed on your computer.

Feb 27, 2012 at 9:19 AM

I don't have Office installed on the server that the code will be running on, but I do have Office on the client machine. I'm assuming you mean that Office has to be installed on the server and that won't work.

More info about what I'm trying to do:

I have a main template that I'm loading using docX. The main document has pointers to subtemplates that I load using docX.  I'd like to add these subtemplates/documents into the main template at the location of their reference in the main template. Right now, they just get inserted at the end of the document. This works as long as I don't have anything (text, etc) in between the subtemplates, but it is not ideal!

Suggestions (and code) welcome.

Thank you, Megan

Developer
Feb 27, 2012 at 9:22 AM

As long as the code would be executed on the client you can use Interop. If the code is executed on server it can't be really executed there. DocX insert document is broken (if you go thru Discussions you will notice a lot of problems). Cathal said it's very "young" method so he needs to work on it at some point. I have not been able to merge multiple documents since over a year using DocX. All we can do is "push" Cathal to fix it

Feb 27, 2012 at 9:27 AM

Got it. Thanks MadBoy. The code will be run on the server, so no go for us. Thanks anyway. I'd love to see the code though, if you have a chance to send it or point me to where I can get it.

Thx. Megan

Developer
Feb 27, 2012 at 9:35 AM

Sure. Here you go. It's not perfect (the merging doesn't always position itself properly - like adding some line breaks here and there) but it works.


I use it like this:  MsWord.Merge(arrayList, (string) fileName, true);

 

#region
using System;
using System.Collections.Generic;
using Microsoft.Office.Interop.Word;

#endregion

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 = @"C:\Template.dotx";
        /// <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(List<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(List<string> filesToMerge, string outputFilename, bool insertPageBreaks, string documentTemplate) {
            object defaultTemplate = documentTemplate;
            object missing = Type.Missing;
            object pageBreak = WdBreakType.wdSectionBreakNextPage;
            object outputFile = outputFilename;
            // Create  a new Word application
            _Application wordApplication = new Application();
            try {
                // Create a new file based on our template
                Document wordDocument = wordApplication.Documents.Add(ref missing, ref missing, ref missing, ref missing);
                // Make a Word selection object.
                Selection selection = wordApplication.Selection;
                //Count the number of documents to insert;
                int documentCount = filesToMerge.Count;
                //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);
            }
        }
    }
}

Feb 27, 2012 at 9:46 AM

Awesome. Thanks!