Reputation: 1503
I have a template document that has a few paragraphs and tables with some styles associated with them.
I need to select the elements from template document based on a sequence, and then append them to the body of my new document. Below is my code that does the copying. I somehow need to copy the styles associated with the elements as well. Although some styles get applied, things like font size and table borders are not getting copied onto the new document. Any help would be much appreciated. Thanks
Dictionary<string, string> sequence = GetSequence();
using (WordprocessingDocument templateDocument = WordprocessingDocument.Open(sourceFileLocation, false))
{
Body templateBody = templateDocument.MainDocumentPart.Document.Body;
using (
WordprocessingDocument wordDoc = WordprocessingDocument.Create(destinationFileLocation,
WordprocessingDocumentType.Document))
{
MainDocumentPart mainPart = wordDoc.AddMainDocumentPart();
mainPart.Document = new Document();
Body wordDocDocBody = mainPart.Document.AppendChild(new Body());
//don't think the below two lines work as I intended.
ThemePart themePart1 = templateDocument.MainDocumentPart.ThemePart;
mainPart.AddPart(themePart1);
foreach (var item in sequence)
{
var block = templateBody.Elements().TakeWhile(x => x.InnerText == item.Key);
foreach (var blockItem in block)
{
wordDocBody.Append(blockItem.CloneNode(true));
}
}
}
}
Upvotes: 1
Views: 5209
Reputation: 11
The following code copies a style with a fixed name (in this case, a 'canned' table style) from one Word document to another.
void CopyTableStyles( WordprocessingDocument source, WordprocessingDocument destination )
{
var sourceStyles = source.MainDocumentPart.StyleDefinitionsPart.RootElement;
var tableStyle = sourceStyles.Descendants<Style>()
.Where<Style>( s => s.StyleName.Val == "Light List - Accent 11")
.First<Style>();
if ( tableStyle != null )
{
var destinationStyles = destination.MainDocumentPart.StyleDefinitionsPart.RootElement;
destinationStyles.AppendChild( tableStyle.CloneNode( true ) );
destination.MainDocumentPart.StyleDefinitionsPart.PutXDocument();
}
return;
}
You should be able to work from here to make this more robust and fit you need.
Edit: Sorry, PutXDocument is an extension method that was originally taken from one of Eric White's examples on the Open XML Developer site.
public static void PutXDocument(this OpenXmlPart part)
{
XDocument xdoc = part.GetXDocument();
if (xdoc != null)
{
// Serialize the XDocument object back to the Package.
using (XmlWriter xw = XmlWriter.Create( part.GetStream( FileMode.Create, FileAccess.Write )))
{
xdoc.Save( xw );
}
}
}
The above code is in an OpenXmlPart static extension class in my current "bag of tricks" -- I suspect I haven't changed it since reading the blog post/examples provided by Mr. White.
Upvotes: 1
Reputation: 7898
The solution for your question is going to be rather large, So I', only going to spell out what needs to be done, you can write code for that and get back if you're stuck.
As @tr4nc3 has mentioned, consider copying the parents to the Text
, if you're copying an entire paragraph, copy the Paragraph
object from source to destination else the Run
object should suffice.
If there is a scenario where a Style has been applied to a paragraph then you'll have to get the ParagraphStyle.Val
for that paragraph and use that reference to copy the Style
object from StylePart
to the Destination Object.
I know this a quite a handful of stuff that needs to be done but, if you use the Open XML Productivity Tool it will make your life a lot easier.
Upvotes: 0
Reputation: 641
In this line: var block = templateBody.Elements().TakeWhile(x => x.InnerText == item.Key);
you're selecting only the Text
objects. Therefore, the formatting is getting left out. You will need to also copy the parents of this Text object to the new document. You may need to copy Paragraph
children to Run
to Text
for the formatting to copy over.
Upvotes: 0