Welcome to MSDN Blogs Sign in | Join | Help
How to Use altChunk for Document Assembly

[Blog Map] 

Merging multiple word processing documents into a single document is something that many people want to do.  An application built for attorneys might assemble selected standard clauses into a contract.  An application built for book publishers can assemble chapters of a book into a single document.  This post explains the semantics of the altChunk element, and provides some code using the Open XML SDK that shows how to use altChunk.

Instead of using altChunk, you could write a program to merge the Open XML markup for documents.  You would need to deal with a number of issues, including merging style sheets and resolving conflicting styles, merging the comments from all of the documents, merging bookmarks, and more.  This is doable, but it’s a lot of work.  You can use altChunk to let Word 2007 do the heavy lifting for you.

altChunk is a powerful technique.  It’s a tool that should be in every Open XML developer’s toolbox.  In an upcoming post, I’ll show an example of the use of altChunk in a SharePoint application.  You can create compelling document assembly solutions in SharePoint using altChunk.

Overview of the altChunk Markup

The altChunk markup tells the consuming application to import content into the document.  This behavior is not required for a conforming application – a conforming application is free to ignore the altChunk markup.  However, the standard recommends that if the application ignores the altChunk markup, it should notify the user.  Word 2007 supports altChunk.

To use altChunk, you do the following:

  • You create a new part in the package.  The part can have a number of content types, listed below.  When you create the part, you assign a unique ID to the part.
  • You store the content that you want to import into the part.  You can import a variety of types of content, including another Open XML word processing document, HTML, or text.
  • The main document part has a relationship to the alternative format part.
  • You add a w:altChunk element at the location where you want to import the alternative format content.  The r:id attribute of the w:altChunk element identifies the chunk to import.  The w:altChunk element is a sibling to paragraph elements (w:p).  You can add an altChunk element at any point in the markup that can contain a paragraph element.

A few options for content types that can be imported into a document are:

  • application/vnd.openxmlformats-officedocument.wordprocessingml.document.main+xml

The alternative format content part contains an Open XML document in binary form.

  • application/xhtml+xml

The alternative format content part contains an XHTML document.

  • text/plain

The alternative format content part contains text.

There are more than these three options; the code presented in this post shows how to implement altChunk for these three types of content.

The altChunk markup in the document looks like this:

<w:p>

  <w:r>

    <w:t>Paragraph before.</w:t>

  </w:r>

</w:p>

<w:altChunk r:id="AltChunkId1" />

<w:p>

  <w:r>

    <w:t>Paragraph after.</w:t>

  </w:r>

</w:p>

 

altChunk: Import Only

One important note about altChunk – it is used only for importing content.  If you open the document using Word 2007 and save it, the newly saved document will not contain the alternative format content part, nor the altChunk markup that references it.  Word saves all imported content as paragraph (w:p) elements.  The standard requires this behavior from a conforming application.

Using altChunk

The following screen-clipping shows a simple word processing document.  It has a heading, a paragraph styled as Normal, and a comment:

The following screen-clipping shows another word processing document, with content that we want to insert into the first document.

After running the example program included with this post, the resulting document looks like the following.  Notice that the resulting document has comments from both of the source documents:

The following example shows how to merge two Open XML documents using altChunk.  It uses V1 of the Open XML SDK, and LINQ to XML:

using System;

using System.Collections.Generic;

using System.Linq;

using System.Text;

using System.IO;

using DocumentFormat.OpenXml.Packaging;

using System.Xml;

using System.Xml.Linq;

 

class Program

{

    static void Main(string[] args)

    {

        XNamespace w =

            "http://schemas.openxmlformats.org/wordprocessingml/2006/main";

        XNamespace r =

            "http://schemas.openxmlformats.org/officeDocument/2006/relationships";

 

        using (WordprocessingDocument myDoc =

            WordprocessingDocument.Open("Test.docx", true))

        {

            string altChunkId = "AltChunkId1";

            MainDocumentPart mainPart = myDoc.MainDocumentPart;

            AlternativeFormatImportPart chunk = mainPart.AddAlternativeFormatImportPart(

              "application/vnd.openxmlformats-officedocument.wordprocessingml.document.main+xml",

              altChunkId);

            using (FileStream fileStream =

                File.Open("TestInsertedContent.docx", FileMode.Open))

                chunk.FeedData(fileStream);

            XElement altChunk = new XElement(w + "altChunk",

                new XAttribute(r + "id", altChunkId)

            );

            XDocument mainDocumentXDoc = GetXDocument(myDoc);

            // Add the altChunk element after the last paragraph.

            mainDocumentXDoc.Root

                .Element(w + "body")

                .Elements(w + "p")

                .Last()

                .AddAfterSelf(altChunk);

            SaveXDocument(myDoc, mainDocumentXDoc);

        }

    }

 

    private static void SaveXDocument(WordprocessingDocument myDoc,

        XDocument mainDocumentXDoc)

    {

        // Serialize the XDocument back into the part

        using (Stream str = myDoc.MainDocumentPart.GetStream(

            FileMode.Create, FileAccess.Write))

        using (XmlWriter xw = XmlWriter.Create(str))

            mainDocumentXDoc.Save(xw);

    }

 

    private static XDocument GetXDocument(WordprocessingDocument myDoc)

    {

        // Load the main document part into an XDocument

        XDocument mainDocumentXDoc;

        using (Stream str = myDoc.MainDocumentPart.GetStream())

        using (XmlReader xr = XmlReader.Create(str))

            mainDocumentXDoc = XDocument.Load(xr);

        return mainDocumentXDoc;

    }

}

 

To use altChunk with HTML, the code looks like this:

using (WordprocessingDocument myDoc =

    WordprocessingDocument.Open("Test3.docx", true))

{

    string html =

      @"<html>

            <head/>

            <body>

                <h1>Html Heading</h1>

                <p>This is an html document in a string literal.</p>

            </body>

        </html>";

    string altChunkId = "AltChunkId1";

    MainDocumentPart mainPart = myDoc.MainDocumentPart;

    AlternativeFormatImportPart chunk = mainPart.AddAlternativeFormatImportPart(

        "application/xhtml+xml", altChunkId);

    using (Stream chunkStream = chunk.GetStream(FileMode.Create, FileAccess.Write))

    using (StreamWriter stringStream = new StreamWriter(chunkStream))

        stringStream.Write(html);

    XElement altChunk = new XElement(w + "altChunk",

        new XAttribute(r + "id", altChunkId)

    );

    XDocument mainDocumentXDoc = GetXDocument(myDoc);

    mainDocumentXDoc.Root

        .Element(w + "body")

        .Elements(w + "p")

        .Last()

        .AddAfterSelf(altChunk);

    SaveXDocument(myDoc, mainDocumentXDoc);

}

 

Using V2 of the Open XML SDK:

using (WordprocessingDocument myDoc =

    WordprocessingDocument.Open("Test1.docx", true))

{

    string altChunkId = "AltChunkId1";

    MainDocumentPart mainPart = myDoc.MainDocumentPart;

    AlternativeFormatImportPart chunk = mainPart.AddAlternativeFormatImportPart(

        AlternativeFormatImportPartType.WordprocessingML, altChunkId);

    using (FileStream fileStream = File.Open("TestInsertedContent.docx", FileMode.Open))

        chunk.FeedData(fileStream);

    AltChunk altChunk = new AltChunk();

    altChunk.Id = altChunkId;

    mainPart.Document

        .Body

        .InsertAfter(altChunk, mainPart.Document.Body.Elements<Paragraph>().Last());

    mainPart.Document.Save();

}

 

The attached code shows examples of placing an Open XML document, html, and text into an alternative content part.  I’ve provided two versions of the example – one using V1 of the Open XML SDK (and LINQ to XML), and another using V2 of the Open XML SDK.

Posted: Monday, October 27, 2008 6:45 AM by EricWhite
Attachment(s): altChunk.zip

Comments

Ed Cawthorne said:

Hi Eric,

Interesting post.

I have just been reading up on OpenXML and it looks like a great solution to my document assembly problem.

Is it possible to combine excel tables/charts and powerpoint slides into a word document using OpenXML.

Clearly altChunk wouldn't be the method as it only works with Word/XML/XTML files but would it work for Excel/Powerpoint elements embedded into Word?

Ed

# October 28, 2008 10:22 AM

teltest said:

Hi Eric,  Great bit of code - nearly exactly what I was looking for.  I seem to have a problem though if each sub-document has a different header - the headers seem to get lost.  Any ideas?

Terry

# October 28, 2008 4:27 PM

Anand said:

Hi Eric,

Thanks for the code sample.

I am facing a problem with the bullets & numbering when using altChunk to merge two word documents (office 2003 .doc documents converted to .docx using OFC.exe). The code I am using is given below.

           string oriDoc = @"C:\Final.docx";

           string mergedDocPath= @"C:\A.docx";

           using (WordprocessingDocument doc = WordprocessingDocument.Open(oriDoc, true))

           {

               IEnumerator<Locked> enumerator = doc.MainDocumentPart.StyleDefinitionsPart.Styles.Descendants<Locked>().GetEnumerator();

               while (enumerator.MoveNext() == true)

                   enumerator.Current.Val = BooleanValues.True; //Tried using False as well, but it doesnt make sense here.

               doc.MainDocumentPart.Document.Save();

               Paragraph paragraph = doc.MainDocumentPart.Document.Descendants<Paragraph>().Last();

               AlternativeFormatImportPart importPart = doc.MainDocumentPart.AddAlternativeFormatImportPart(AlternativeFormatImportPartType.WordprocessingML);

               using (StreamReader reader = new StreamReader(mergedDocPath, true))

                   importPart.FeedData(reader.BaseStream);

               AltChunk altChunk = new AltChunk();

               altChunk.AltChunkProperties = new AltChunkProperties();

               altChunk.AltChunkProperties.MatchSource = new MatchSource();

               altChunk.AltChunkProperties.MatchSource.Val = BooleanValues.True;//Tried using False as well

               altChunk.Id = doc.MainDocumentPart.GetIdOfPart(importPart);

               paragraph.InsertAfterSelf(altChunk);

               doc.MainDocumentPart.Document.Save();

           }

A.docx originally looks like this,

----------------------------------------------------------------------------------------------------

Diggity dog

ffdgfgfdg

first time dfvidjgldgdgm

dfsfsdfgdgdfgghfgghfh:

1.       Zoom vroom

2.       doom boom

3.       dhgfhfghgfhfghgfhgfhgfh dsfsfsddfsfdsfgdsfdgffg fgffdgdghfdh fsfgf fdsfsfsdfdsf:

4.       Sweeetdfvggdggf

a.       dfsfvcff

                                                              i.      why Go

                                                            ii.      jeremy

                                                           iii.      black

----------------------------------------------------------------------------------------------------

After merging the formatting becomes like this,

----------------------------------------------------------------------------------------------------

Diggity dog

ffdgfgfdg

first time dfvidjgldgdgm

dfsfsdfgdgdfgghfgghfh:

• Zoom vroom

• doom boom

• dhgfhfghgfhfghgfhgfhgfh dsfsfsddfsfdsfgdsfdgffg fgffdgdghfdh fsfgf fdsfsfsdfdsf:

• Sweeetdfvggdggf

• dfsfvcff

• why Go

• jeremy

• black

----------------------------------------------------------------------------------------------------

Something similar happens to bullets too. The bullets style changes to the bullets styling of "Final.Docx".

On checking the afchunk the bullet & numbering were correct, which indicates that the parent document superimposes its bulleting & numbering on the chunk.

I thought about setting DocumentProtection.Enforcement and DocumentProtection.Formatting to false. Also I tried setting AutoFormatOverride.Val to false. But I couldn't find a way to do that. Also will setting these help?

Also does setting AltChunk.Id manually rather than by using MainDocumentPart.GetIdOfPart cause a difference?

If the above method does not work, should I instead take all the Styles from the second document and merge them into the first document? Although this does not look like the right way to go about doing things.

Thanks,

Anand.

# October 29, 2008 12:30 PM

Doug Mahugh said:

Stephen McGibbon has screenshots of the Open XML and ODF support coming in Windows 7 Wordpad , as announced

# October 31, 2008 5:00 PM

EricWhite said:

Hi, Ed, Terry, and Anand,

Thanks for the great questions.  I'll be responding to these, but it may be as late as the end of next week, due to schedule constraints.  Thanks for your patience.

-Eric

# November 3, 2008 6:07 AM

Julien Chable said:

Suite à la PDC 2008 et au workshop Open XML donné par Microsoft à Redmond ( Doug , encore mille excuses

# November 3, 2008 9:10 AM

EricWhite said:

I received this message privately, but the question and the response are relevant to many, so including it here.

Question:

I'm attempting to merge multiple documents (which contain rows of a table) into a single document.  When the merge process happens, I get what looks to be a paragraph marker between my table rows (so there's visual seperation between the rows of the table, wich isn't what I want).

Any thoughts on how to modify altChunk's behavior to not include the document delimeter between the documents that it merges?

My response:

I've seen this same behavior, and as far as I know, this is behavior that is not configurable in Word.  I'll check, but would guess that this can't be changed.

The solution to this is to write some utility that can move content between docs (not using altChunk).  I'm starting on the prep work for this.  See this post:

http://blogs.msdn.com/ericwhite/archive/2008/11/03/inserting-deleting-moving-paragraphs-in-open-xml-wordprocessing-documents.aspx

-Eric

# November 5, 2008 3:00 PM

Knut Hamang said:

Eric, I am having the excact problem as Anand. Maybe you have a good solution for this.

Rather strange that it is not possible to do inline numbering type in the document.xml itself.

# November 14, 2008 9:14 AM

KumaAnith said:

Hi,

i have few doubts

1. is it possible to view a altchunk from word 2007 or it can be view only in xml format

2. can we insert the contents in between the documents?

# November 18, 2008 1:35 AM

Brian Jones: Office Extensibility said:

One of the most common requests we hear related to word processing documents is the ability to merge

# December 8, 2008 3:16 PM

Ernest said:

Hi,

I try to mergedonc and then making some string replace using this code : http://www.codeproject.com/KB/office/OfficeTokenReplacement.aspx

It'sdoing some regex on thewhole xml

but when I use chunk, the unziped embeded content is under AltChunk1.docx and I have to uzip after.

I first tried with the PDC source code

//Find all content controls in document

               List<SdtBlock> sdtList = mainPart.Document

                   .Descendants<SdtBlock>().Where(s => sourceFile

                       .Contains(s.SdtProperties

                           .GetFirstChild<Alias>().Val.Value)).ToList();

               //Go through all the content controls

               if (sdtList.Count != 0)

               {

                   string altChunkId = "AltChunkId" + id;

                   id++;

                   //Add altchunk into document

                   AlternativeFormatImportPart chunk =

                       mainPart.AddAlternativeFormatImportPart(

                       "application/vnd.openxmlformats-officedocument.wordprocessingml.document.main+xml",

                       altChunkId);

                   //stream data from source file into altchunk

                   chunk.FeedData(File.Open(sourceFile, FileMode.Open));

                   //Create new altchunk element

                   AltChunk altChunk = new AltChunk();

                   altChunk.Id = altChunkId;

                   //Swap out content control for altchunk

                   foreach (SdtBlock sdt in sdtList)

                   {

                       OpenXmlElement parent = sdt.Parent;

                       parent.InsertAfter(altChunk, sdt);

                       sdt.Remove();

                   }

                   //Save

                   mainPart.Document.Save();

               }

but I only have paragraph and no SdtBlock ?

Could you please help me !!

# January 5, 2009 8:31 PM

siri said:

Hi Eric ...Can this be used with word 2003?

# January 6, 2009 3:07 PM

Ernest Bariq said:

How can I insert an AltChunk at a special place ?

# January 11, 2009 5:04 PM

S K Tripathi said:

Hi Eric, Nice sample of code. I am using some html as altChunk. Its working for plain html but, if the html contains some images, the images are not coming. I understand the problem as images are not in the scope of the document. As you have mentioned that whwn the document with alt chunk is saved by MS Word2007, it converts all the altChunk to WordML. My question is whether can we do the same(converting HTML to WordML).

It wil be a great help for my project.

# February 11, 2009 4:41 AM

Visual Studio Office Developer (VSOD) Support Team said:

Resolution ================ Step 1: Open a new Microsoft Word 2007 document and type A B C Save the document

# April 13, 2009 8:33 PM

rama said:

Hi Eric, I'm getting following error when trying to execute the above code in an aspx page. may I know what is causing this issue.

Thanks,

Rama

Server Error in '/TMS' Application.

'AltChunkId14' ID conflicts with the ID of an existing relationship for the specified source.

Description: An unhandled exception occurred during the execution of the current web request. Please review the stack trace for more information about the error and where it originated in the code.

Exception Details: System.Xml.XmlException: 'AltChunkId14' ID conflicts with the ID of an existing relationship for the specified source.

Source Error:

Line 78:                             string altChunkId = "AltChunkId" + loop;

Line 79:                             MainDocumentPart mainPart = myDoc.MainDocumentPart;

Line 80:                             AlternativeFormatImportPart chunk = mainPart.AddAlternativeFormatImportPart(

Line 81:                               "application/vnd.openxmlformats-officedocument.wordprocessingml.document.main+xml",

Line 82:                               altChunkId);

Source File: c:\Inetpub\wwwroot\tms\trunk\web\Tariff\Tariff.aspx.cs    Line: 80

Stack Trace:

[XmlException: 'AltChunkId14' ID conflicts with the ID of an existing relationship for the specified source.]

  MS.Internal.IO.Packaging.InternalRelationshipCollection.ValidateUniqueRelationshipId(String id) +634905

  MS.Internal.IO.Packaging.InternalRelationshipCollection.Add(Uri targetUri, TargetMode targetMode, String relationshipType, String id, Boolean parsing) +210

  System.IO.Packaging.PackagePart.CreateRelationship(Uri targetUri, TargetMode targetMode, String relationshipType, String id) +62

  DocumentFormat.OpenXml.Packaging.OpenXmlPart.CreateRelationship(Uri targetUri, TargetMode targetMode, String relationshipType, String id) +36

  DocumentFormat.OpenXml.Packaging.OpenXmlPartContainer.AttachChild(OpenXmlPart part, String rId) +88

  DocumentFormat.OpenXml.Packaging.OpenXmlPartContainer.InitPart(T newPart, String contentType, String id) +246

  DocumentFormat.OpenXml.Packaging.MainDocumentPart.AddAlternativeFormatImportPart(String contentType, String id) +47

  Systrends.TMS.Web.Tariff.Tariff.<Page_Load>b__1(<>f__AnonymousType1`3 mergingdocuments) in c:\Inetpub\wwwroot\tms\trunk\web\Tariff\Tariff.aspx.cs:80

  System.Array.ForEach(T[] array, Action`1 action) +47

  Systrends.TMS.Web.Tariff.Tariff.Page_Load(Object sender, EventArgs e) in c:\Inetpub\wwwroot\tms\trunk\web\Tariff\Tariff.aspx.cs:66

  System.Web.Util.CalliHelper.EventArgFunctionCaller(IntPtr fp, Object o, Object t, EventArgs e) +14

  System.Web.Util.CalliEventHandlerDelegateProxy.Callback(Object sender, EventArgs e) +35

  System.Web.UI.Control.OnLoad(EventArgs e) +99

  System.Web.UI.Control.LoadRecursive() +50

  System.Web.UI.Page.ProcessRequestMain(Boolean includeStagesBeforeAsyncPoint, Boolean includeStagesAfterAsyncPoint) +627

Version Information: Microsoft .NET Framework Version:2.0.50727.3053; ASP.NET Version:2.0.50727.3053

# April 16, 2009 11:42 AM

EricWhite said:

Hi Rama,

Somehow you are getting duplicate rIDs for the altChunk that you are adding.  rIDs need to be unique - there are a variety of ways to enforce this.  It isn't a problem when creating a document from scratch, but when modifying an existing document, you need to take care that you only add new parts with uniuqe rIDs.  Does this help you with your issue?

-Eric

# April 17, 2009 3:37 PM

Kulio said:

Hi Eric,

I've really appreciated your article and I have one question: regarding the "altChunk: Import Only" section, is there any way to avoid this peculiar behaviour?

In other words, is there an altChunk property or another markup that can be used to embed external sources (i.e. html files) avoiding them to be totally erased from the archive after the first saving?

Many thanks,

Kulio.

# April 19, 2009 5:24 AM

EricWhite said:

Hi Kulio,

Unfortunately, the behavior can't be changed.  When you open the document in Word, the embedded external source is removed from the package.

-Eric

# April 19, 2009 5:46 PM

Eric White's Blog said:

There are two ways to assemble multiple Open XML word processing documents into a single document: altChunk,

# April 20, 2009 12:28 AM

Eric White's Blog said:

DocumentBuilder is an example class that’s part of the PowerTools for Open XML project that enables you

# April 21, 2009 8:48 AM

Ramesh said:

i have used your v2 code to merge the documents, and i add my page to sharepoint site, but sharepoint not recongnzing Last() method in the following line:

InsertAfter(altChunk, mainPart.Document.Body.Elements<Paragraph>().Last());

Iam getting following exception.

'System.Collections.Generic.IEnumerable<DocumentFormat.OpenXml.Wordprocessing.Paragraph>' does not contain a definition for 'Last'   at System.Web.Compilation.AssemblyBuilder.Compile()

# April 29, 2009 9:08 AM

EricWhite said:

Hi Ramesh, you need to include a "using System.Linq;" using statement.

-Eric

# April 29, 2009 12:44 PM

rpallothu said:

hi Eric,

Thanks for your response.

but i used System.Xml.Linq namespace.

I used System.Xml.Linq  and DocumentFormat.OpenXml dll to merge the office documents, which is working fine in 3.5 framework. When i bind my page with sharepoint site iam getting an exception saying

'System.Collections.Generic.IEnumerable<DocumentFormat.OpenXml.Wordprocessing.Paragraph>' does not contain a definition for 'Last'   at System.Web.Compilation.AssemblyBuilder.Compile()

Code snippet:

using (WordprocessingDocument myDoc =

                   WordprocessingDocument.Open("Desc.docx", true))

               {

                   string altChunkId = "AltChunkId" + i;

                   MainDocumentPart mainPart = myDoc.MainDocumentPart;

                   AlternativeFormatImportPart chunk = mainPart.AddAlternativeFormatImportPart(

                       AlternativeFormatImportPartType.WordprocessingML, altChunkId);

                   using (FileStream fileStream = File.Open("Temp.docx", FileMode.Open))

                       chunk.FeedData(fileStream);

                   AltChunk altChunk = new AltChunk();

                   altChunk.Id = altChunkId;

                   mainPart.Document

                       .Body.InsertAfter(altChunk, mainPart.Document.Body.Elements<Paragraph>().Last());

                   mainPart.Document.Save();

               }

Note: when i change my applicaiton framework version to 3.0 also i am getting the same exception in my local, which i got in sharepoint.

Is it mean that sharepoint doens't support 3.5 framework DLL..

Please advise.

# April 30, 2009 12:47 AM

EricWhite said:

Hi Ramesh, the Enumerable.Last extension method is in the System.Linq namespace, not System.Xml.Linq.  By default, the SharePoint project doesn't include a using for System.Linq.  So to use the Last extension method, you need to add that using statement.

In general, when you get build errors like this, take a look at the MSDN docs on the class/method/type.  The docs always tell you which assembly the class is in, and what namespace the class is in.  Then, you can add appropriate references and using statements.  Make sense?

-Eric

# April 30, 2009 11:25 AM

rmagill said:

Good stuff, very helpful.   I have a slight twist to this I am working on, maybe someone can help.  

Instead of opening existing files and merging them, I am programmatically creating WordProcessingDocuments using C# in .NET.  Then based on various conditions I may or may not want to combine them and then stream them out as a single document.    

So instead of adding data to the stream in the form of:

Stream fileStream = System.IO.File.Open(fileName, FileMode.Open);

chunk.FeedData(fileStream);

I tried to do this:

Stream stream = wordDoc.MainDocumentPart.GetStream();

chunk.FeedData(stream);

Which compiles but then when you try to open the final document it give me a message that the docx can't be opened because of problems with the contents.    Any ideas?

# May 6, 2009 9:18 AM

EricWhite said:

Hi rmagill,  quick question - are you properly disposing of all of your streams?  That could very well cause this problem.  Another debugging technique for a situation like this - read streams to byte arrays - as necessary, you can create a non-resizable memory stream from a byte array using one of the MemoryStream constructors (I believe that the memory stream uses the passed in byte array as its backing store).  You can then examine this byte array to see what's different.

It's best to always use a 'using' block for every object that implements IDisposable:

private static void SaveXDocument(WordprocessingDocument myDoc,

    XDocument mainDocumentXDoc)

{

    // Serialize the XDocument back into the part

    using (Stream str = myDoc.MainDocumentPart.GetStream(FileMode.Create, FileAccess.Write))

    using (XmlWriter xw = XmlWriter.Create(str))

        mainDocumentXDoc.Save(xw);

}

-Eric

# May 7, 2009 3:18 PM

Kulio said:

Hi Eric,

I thank you for your last answer.

I've solved the problem creating the html files 'on the fly' and using a kind of 'custom marker' in the document that is replaced at runtime with the proper altchunk reference tag.

Now I am wondering if there is a way to embed also a css stylesheet for the html files.

The stylesheet file is placed in a directory "word/html".

I've found out that if I insert "<Default Extension="css" ContentType="text/css" />"

into [Content_Types].xml I get no error message when opening the docx.

However the CSS is ignored in the docx file.

On the contrary, ff I integrate the styles in a <style> tag inside the html file, the proper style is displayed correctly inside the docx file.

Many thanks,

Kulio.

# May 12, 2009 8:07 AM

EricWhite said:

Hi Kulio,

From the dev team:

Word only supports a few content types for altChunks. Word does support HTML and MHT, which is why putting them in a <style> tag worked. For HTML, Word only reads the HTML file itself and not any supporting files in the package. So if you have any external stylesheets, images, etc. MHT might be the best route.

-Eric

# May 12, 2009 1:08 PM

Balazs said:

I've had no trouble getting this working.  However, the one difficult I'm having is this:

If I have a hyperlink in my source HTML that looks like this: <a href="myimage.jpeg">, and I have added myimage.jpeg, is there any way that I can get my hyperlink to refer to that image?  Currently the URL is resolved to "directoryTheDocumentIsIn/myimage.jpeg". I'm not sure whether the HyperlinkBase extended property could be used for this...I can't figure out a way.

Also, I'm a little confused. I was under the impression that with altchunk, Word does a one-time conversion of the content and does away with the source altchunk file.  However, I find that even after opening the docx file several times, the altchunk file remains, and document.xml still contains the <altchunk> tag, rather than any imported html.

# May 21, 2009 4:05 PM

Robert te Kaat said:

AltChunk rocks! However, I can't get it to work inside a headerpart. Inside the maindocumentpart it works perfect. Is this supported at all?

You can check the broken document here: http://blogs.infosupport.com/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/porint/order.docx

# May 26, 2009 8:33 AM

Sanjay said:

Beautiful work Eric.  Worked like a charm.

I have captured content using InfoPath forms in Moss and wished to export the content to a word document.  the content control do not allow you to map the content directly by including the customxml parts.  This option sure worked.

Cheers

# June 12, 2009 1:26 AM

Maria Hsiung said:

Thanks for the awesome post!

I'm also trying to assemble different types of office documents (excel, word, powerpoint) into a single document.  Your post really helped me with combining word documents, but I'm not sure how to proceed with the other types (excel, powerpoint).  Any suggestions?

# June 16, 2009 9:01 PM
Leave a Comment

(required) 

(required) 

(optional)

(required) 

Comment Notification

If you would like to receive an email when updates are made to this post, please register here

Subscribe to this post's comments using RSS

Page view tracker