Is There An Open Source XSLT To Convert a WPF FlowDocument to WordML?
Asked Answered
B

2

12

I want to use a WPF RichTextBox which allows users to edit and format text. This formatted text will eventually work its way into a Word document along with some of our other custom XML data.

I've found several examples going from WordML to a FlowDocument but nothing that takes the RichTextBox FlowDocument to WordML.

Rather than re-invent the wheel, is there an open source XSLT file I can use to convert a WPF FlowDocument into WordML?

I'm not looking for a 100% solution (e.g. tables, figures, drawings, etc.). At this point, I'm just interested in preserving font formatting, paragraphs, bullet lists, etc.

Edit:

I need to avoid Word Interop or expensive 3rd party tools (e.g. Apose) if possible. I'm looking for an elegant way to translate some basic FlowDocument XML formatted content to OpenXML, preferrably via XSLT. Since I'm not interested in items such as embedded pictures, I believe it's probably doable given the fact that I've found examples going the other direction (i.e. OpenXML/WordML to XAML Flowdocument)

Bicolor answered 22/1, 2013 at 21:51 Comment(1)
A coworker found this, although it's a tad more brute force. I'm hoping for something a little more elegant: openxml.biz/OpenXMLWriter.htmlBicolor
C
2

There are a couple of solutions I found in my searching. The easiest way would probably be to convert to an .rtf format which supports all of the required XSLT stuff. This is explained VERY well here.

Another solution I found online is where someone goes to PDF, but first converts to .DOCX. You can find his solution here. If you just want the part that converts to .DOCX, you would want to edit out his code so that the .DOCX is not replaced with the .PDF.

Depending on the details of how your project works, you may find this interesting.

I hope this helps you. Currently there are not direct ways to do this with a single API. You need to convert to some format like .XPS, .RTF, etc, and then from their use another API to convert to WordMl.

Happy coding!

Conversation answered 27/1, 2013 at 0:59 Comment(1)
The last line in the article you referenced says it well... "Today, as far I know, you cannot extract fragments of XHTML or WPF markup based on Open XML markup without writing your own XSL transformation. To force customers to write their own XSL transformation for an XML format based on a 6000-page spec is cruel and unusual corporate punishment." This is one of the reasons I'm looking for an XSLT that accomplishes at least some minimal capability. Thanks for the links; it was some interesting reading.Bicolor
V
2

JABFreeware has touched on a method that I have used; taking the FlowDocument content and creating an rtf then build a new Word document and save. However, you may not want to touch libraries like Microsoft.Office.Interop.Word.

There are some examples out there of other methods too. For example, you might want to look at the following open source FlowDocument editor here. It is old, but still informative and converts FlowDocuments to docx. This brings up looking into the OpenXml SDK from Microsoft's site (not enough rep for more links, but Google will get you there).

Also, you might find this useful as a reference. It is a Word add-on that you can get the source code to that will allow you to convert Word documents to FlowDocuments. It's backwards from the original request, but reversing the process is a possibility.

Hope some of this helps.

EDIT:

If you really want to cheat and the documents that you will be creating are really basic, you can. However, I know this to work only with docx.

  1. Create a simple word document with some formatting first (as a docx).
  2. Extract the contents and keep everything but the /word/document.xml file.
  3. Open the /word/document.xml file and use that as a template for your XSLT. I made a simple one here:

FlowDocument XML

<?xml version="1.0" encoding="utf-8"?>
<FlowDocument xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation">
  <Paragraph>
    <Run FontWeight="Bold" Foreground="#FF0000">Testing</Run>
  </Paragraph>
  <Paragraph>
    <Run FontWeight="Bold" Foreground="#0000FF">Testing2</Run>
  </Paragraph>
</FlowDocument>

XSLT (only partially done for demo purposes)

<?xml version="1.0" encoding="utf-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml/presentation">
<xsl:template match="/x:FlowDocument">
    <?mso-application progid="Word.Document"?>
    <w:document xmlns:w="http://schemas.openxmlformats.org/wordprocessingml/2006/main">
       <w:body>
          <w:sect>
        <w:p>
                <xsl:for-each select="x:Paragraph">
            <w:pPr>
                <w:jc w:val="center" />
                <w:spacing w:after="0" w:line="240" w:lineRule="auto"/>
            </w:pPr>
            <w:r>
                <w:rPr>
                    <w:rFonts w:ascii="Segoe UI" w:hAnsi="Segoe UI" w:cs="Segoe UI" />
                    <w:sz w:val="18" />
                    <w:b w:val="on" />
                    <w:i w:val="off" />
                    <w:color>
                        <xsl:attribute name="w:val"><xsl:value-of select="x:Run/@Foreground"/></xsl:attribute>
                    </w:color>
                </w:rPr>
                <w:t><xsl:value-of select="x:Run" /></w:t>
            </w:r>
    </xsl:for-each>
        </w:p>
      </w:sect>
    </w:body>
  </w:document>
</xsl:template>
</xsl:stylesheet>
  1. Use and XmlDocument and XamlWriter to create the xml to transform.
  2. Save your transformation result as a new 'document.xml' and put it in the /word directory and package everything as an archive with a .docx extension.

The biggest headache is that FlowDocuments will probably be RGBA but WordML works with RBG in the color attribute.

So, there is a way to get everything with one xslt, but it is also headache. IMHO, the code from the OpenXmlWriter application would be a much cleaner solution. Or possibly a combination of both...

Volsung answered 28/1, 2013 at 15:46 Comment(1)
I didn't state it in the original question explicitly, but I am trying to avoid Word Interop. I referenced the OpenXml.biz link as a comment to the original question. Unfortunately, that approach is a little more brute-force than I was looking for. I've found numerous examples of Word to XAML, but not XAML to Word... hence the question.Bicolor

© 2022 - 2024 — McMap. All rights reserved.