views:

367

answers:

1

Hi

I'm creating a C# application that fills the MergeFields defined on a MS Word document with data from an external Data Source.

I'm using the OpenXml SDK and everything works fine when replacing single fields.

What I want to do is, to have a section with several MergeFields defined and being able to copy such section several times according to the input data.

e.g. I can have in the document a paragraph containing a product information with several MergeFields, but in the data I have information for several products, I want to generate as many paragraphs in the output document as products are in the input data.

Product: [[product-name]], amount: [[product-amount]], price: [[product-price]]

Is there something like a "logical section" in a Word document to wrap the paragraph? if not, what would be your advice to do this?

Any help will be very appreciated, thanks!

A: 

You can try to run separately merge on each of your rows and then concatenate the result into one document. Here's the sample method to join many documents. In this example I use Break element to seperate but this isn't a must..

        private MemoryStream JoinDocuments(List<MemoryStream> subDocuments)
    {
            var sumLength = (from MemoryStream ms in subDocuments select ms.Length).Sum();
            MemoryStream mainDocumentStream = new MemoryStream((int)sumLength);

          // Create a Wordprocessing document.
          using (WordprocessingDocument myDoc = WordprocessingDocument.Create(mainDocumentStream, WordprocessingDocumentType.Document))
          {
            // Add a new main document part.
            MainDocumentPart mainPart = myDoc.AddMainDocumentPart();
            //Create Document tree for simple document.
            mainPart.Document = new Document();
            //Create Body (this element contains other elements that we want to include
            Body body = new Body();

            for (int i = 0; i < subDocuments.Count; i++)
            {
                var subDocument = subDocuments[i];
                subDocument.Position = 0;
                string altChunkId = "AltChunkId" + i;
                AlternativeFormatImportPart chunk = mainPart.AddAlternativeFormatImportPart(AlternativeFormatImportPartType.WordprocessingML, altChunkId);
                chunk.FeedData(subDocument);

                AltChunk altChunk = new AltChunk();
                altChunk.Id = altChunkId;
                body.Append(altChunk);
                Break pageBreak = new Break();
                pageBreak.Type = BreakValues.Page;
                body.Append(pageBreak);

            }

            mainPart.Document.Append(body);
            // Save changes to the main document part.
            mainPart.Document.Save();
          }
          return mainDocumentStream;
    }
Marcin Rybacki