[Libreoffice-commits] core.git: 3 commits - sw/Library_msword.mk sw/qa sw/source writerfilter/source

Miklos Vajna vmiklos at collabora.co.uk
Wed Oct 30 17:50:56 CET 2013


 sw/Library_msword.mk                          |    1 
 sw/qa/extras/ooxmlexport/ooxmlexport.cxx      |    6 
 sw/source/filter/ww8/docxattributeoutput.cxx  |  376 +------------------
 sw/source/filter/ww8/docxattributeoutput.hxx  |    9 
 sw/source/filter/ww8/docxhelper.hxx           |   25 +
 sw/source/filter/ww8/docxtablestyleexport.cxx |  493 ++++++++++++++++++++++++++
 sw/source/filter/ww8/docxtablestyleexport.hxx |   32 +
 writerfilter/source/dmapper/DomainMapper.cxx  |    8 
 8 files changed, 592 insertions(+), 358 deletions(-)

New commits:
commit 9ab844c7fa907e2d1119a316c695198ef888a059
Author: Miklos Vajna <vmiklos at collabora.co.uk>
Date:   Wed Oct 30 15:19:18 2013 +0100

    DOCX filter: roundtrip more table style properties
    
    Handle wordWrap, beforeLines, afterLines, beforeAutospacing,
    afterAutospacing, asciiTheme, hAnsiTheme, b, i, color, sz and vAlign.
    
    With this, the export filter is now in sync with the import one again.
    
    Change-Id: I7184447baf872374eaa69afdfcb149a7e6e45faa

diff --git a/sw/qa/extras/ooxmlexport/ooxmlexport.cxx b/sw/qa/extras/ooxmlexport/ooxmlexport.cxx
index ffe9c62..5028733 100644
--- a/sw/qa/extras/ooxmlexport/ooxmlexport.cxx
+++ b/sw/qa/extras/ooxmlexport/ooxmlexport.cxx
@@ -1470,6 +1470,12 @@ void Test::testCalendar1()
     // Table style lost its paragraph / run properties.
     assertXPath(pXmlStyles, "/w:styles/w:style[@w:styleId='Calendar1']/w:pPr/w:spacing", "lineRule", "auto");
     assertXPath(pXmlStyles, "/w:styles/w:style[@w:styleId='Calendar1']/w:rPr/w:lang", "eastAsia", "ja-JP");
+
+    // Table style lost its conditional table formatting properties.
+    assertXPath(pXmlStyles, "/w:styles/w:style[@w:styleId='Calendar1']/w:tblStylePr[@w:type='firstRow']/w:pPr/w:wordWrap", 1);
+    assertXPath(pXmlStyles, "/w:styles/w:style[@w:styleId='Calendar1']/w:tblStylePr[@w:type='firstRow']/w:rPr/w:rFonts", "hAnsiTheme", "minorHAnsi");
+    assertXPath(pXmlStyles, "/w:styles/w:style[@w:styleId='Calendar1']/w:tblStylePr[@w:type='firstRow']/w:tblPr", 1);
+    assertXPath(pXmlStyles, "/w:styles/w:style[@w:styleId='Calendar1']/w:tblStylePr[@w:type='firstRow']/w:tcPr/w:vAlign", "val", "bottom");
 }
 
 void Test::testSmartart()
diff --git a/sw/source/filter/ww8/docxtablestyleexport.cxx b/sw/source/filter/ww8/docxtablestyleexport.cxx
index db0608d..634368a 100644
--- a/sw/source/filter/ww8/docxtablestyleexport.cxx
+++ b/sw/source/filter/ww8/docxtablestyleexport.cxx
@@ -111,6 +111,22 @@ void lcl_TableStyleShd(sax_fastparser::FSHelperPtr pSerializer, uno::Sequence<be
     pSerializer->singleElementNS(XML_w, XML_shd, xAttributeList);
 }
 
+/// Export of w:color in a table style.
+void lcl_TableStyleRColor(sax_fastparser::FSHelperPtr pSerializer, uno::Sequence<beans::PropertyValue>& rColor)
+{
+    if (!rColor.hasElements())
+        return;
+
+    sax_fastparser::FastAttributeList* pAttributeList = pSerializer->createAttrList();
+    for (sal_Int32 i = 0; i < rColor.getLength(); ++i)
+    {
+        if (rColor[i].Name == "val")
+            pAttributeList->add(FSNS(XML_w, XML_val), OUStringToOString(rColor[i].Value.get<OUString>(), RTL_TEXTENCODING_UTF8).getStr());
+    }
+    sax_fastparser::XFastAttributeListRef xAttributeList(pAttributeList);
+    pSerializer->singleElementNS(XML_w, XML_color, xAttributeList);
+}
+
 /// Export of w:lang in a table style.
 void lcl_TableStyleRLang(sax_fastparser::FSHelperPtr pSerializer, uno::Sequence<beans::PropertyValue>& rLang)
 {
@@ -138,6 +154,10 @@ void lcl_TableStyleRRFonts(sax_fastparser::FSHelperPtr pSerializer, uno::Sequenc
     {
         if (rRFonts[i].Name == "eastAsiaTheme")
             pAttributeList->add(FSNS(XML_w, XML_eastAsiaTheme), OUStringToOString(rRFonts[i].Value.get<OUString>(), RTL_TEXTENCODING_UTF8).getStr());
+        else if (rRFonts[i].Name == "asciiTheme")
+            pAttributeList->add(FSNS(XML_w, XML_asciiTheme), OUStringToOString(rRFonts[i].Value.get<OUString>(), RTL_TEXTENCODING_UTF8).getStr());
+        else if (rRFonts[i].Name == "hAnsiTheme")
+            pAttributeList->add(FSNS(XML_w, XML_hAnsiTheme), OUStringToOString(rRFonts[i].Value.get<OUString>(), RTL_TEXTENCODING_UTF8).getStr());
     }
     sax_fastparser::XFastAttributeListRef xAttributeList(pAttributeList);
     pSerializer->singleElementNS(XML_w, XML_rFonts, xAttributeList);
@@ -158,6 +178,14 @@ void lcl_TableStylePSpacing(sax_fastparser::FSHelperPtr pSerializer, uno::Sequen
             pAttributeList->add(FSNS(XML_w, XML_line), OUStringToOString(rSpacing[i].Value.get<OUString>(), RTL_TEXTENCODING_UTF8).getStr());
         else if (rSpacing[i].Name == "lineRule")
             pAttributeList->add(FSNS(XML_w, XML_lineRule), OUStringToOString(rSpacing[i].Value.get<OUString>(), RTL_TEXTENCODING_UTF8).getStr());
+        else if (rSpacing[i].Name == "beforeLines")
+            pAttributeList->add(FSNS(XML_w, XML_beforeLines), OUStringToOString(rSpacing[i].Value.get<OUString>(), RTL_TEXTENCODING_UTF8).getStr());
+        else if (rSpacing[i].Name == "beforeAutospacing")
+            pAttributeList->add(FSNS(XML_w, XML_beforeAutospacing), OUStringToOString(rSpacing[i].Value.get<OUString>(), RTL_TEXTENCODING_UTF8).getStr());
+        else if (rSpacing[i].Name == "afterLines")
+            pAttributeList->add(FSNS(XML_w, XML_afterLines), OUStringToOString(rSpacing[i].Value.get<OUString>(), RTL_TEXTENCODING_UTF8).getStr());
+        else if (rSpacing[i].Name == "afterAutospacing")
+            pAttributeList->add(FSNS(XML_w, XML_afterAutospacing), OUStringToOString(rSpacing[i].Value.get<OUString>(), RTL_TEXTENCODING_UTF8).getStr());
     }
     sax_fastparser::XFastAttributeListRef xAttributeList(pAttributeList);
     pSerializer->singleElementNS(XML_w, XML_spacing, xAttributeList);
@@ -181,6 +209,17 @@ void lcl_TableStyleTblInd(sax_fastparser::FSHelperPtr pSerializer, uno::Sequence
     pSerializer->singleElementNS(XML_w, XML_tblInd, xAttributeList);
 }
 
+void lcl_handleBoolean(OUString aValue, sal_Int32 nToken, sax_fastparser::FSHelperPtr pSerializer)
+{
+    if (aValue.isEmpty())
+        return;
+    sax_fastparser::FastAttributeList* pAttributeList = pSerializer->createAttrList();
+    if (aValue != "1")
+        pAttributeList->add(FSNS(XML_w, XML_val), OUStringToOString(aValue, RTL_TEXTENCODING_UTF8).getStr());
+    sax_fastparser::XFastAttributeListRef xAttributeList(pAttributeList);
+    pSerializer->singleElementNS(XML_w, nToken, xAttributeList);
+}
+
 /// Export of w:rPr in a table style.
 void lcl_TableStyleRPr(sax_fastparser::FSHelperPtr pSerializer, uno::Sequence<beans::PropertyValue>& rRPr)
 {
@@ -189,16 +228,32 @@ void lcl_TableStyleRPr(sax_fastparser::FSHelperPtr pSerializer, uno::Sequence<be
 
     pSerializer->startElementNS(XML_w, XML_rPr, FSEND);
 
-    uno::Sequence<beans::PropertyValue> aRFonts, aLang;
+    uno::Sequence<beans::PropertyValue> aRFonts, aLang, aColor;
+    OUString aB, aI, aSz;
     for (sal_Int32 i = 0; i < rRPr.getLength(); ++i)
     {
         if (rRPr[i].Name == "rFonts")
             aRFonts = rRPr[i].Value.get< uno::Sequence<beans::PropertyValue> >();
         else if (rRPr[i].Name == "lang")
             aLang = rRPr[i].Value.get< uno::Sequence<beans::PropertyValue> >();
+        else if (rRPr[i].Name == "b")
+            aB = rRPr[i].Value.get<OUString>();
+        else if (rRPr[i].Name == "i")
+            aI = rRPr[i].Value.get<OUString>();
+        else if (rRPr[i].Name == "color")
+            aColor = rRPr[i].Value.get< uno::Sequence<beans::PropertyValue> >();
+        else if (rRPr[i].Name == "sz")
+            aSz = rRPr[i].Value.get<OUString>();
     }
     lcl_TableStyleRRFonts(pSerializer, aRFonts);
     lcl_TableStyleRLang(pSerializer, aLang);
+    lcl_handleBoolean(aB, XML_b, pSerializer);
+    lcl_handleBoolean(aI, XML_i, pSerializer);
+    lcl_TableStyleRColor(pSerializer, aColor);
+    if (!aSz.isEmpty())
+        pSerializer->singleElementNS(XML_w, XML_sz,
+                FSNS(XML_w, XML_val), OUStringToOString(aSz, RTL_TEXTENCODING_UTF8).getStr(),
+                FSEND);
 
     pSerializer->endElementNS(XML_w, XML_rPr);
 }
@@ -212,11 +267,16 @@ void lcl_TableStylePPr(sax_fastparser::FSHelperPtr pSerializer, uno::Sequence<be
     pSerializer->startElementNS(XML_w, XML_pPr, FSEND);
 
     uno::Sequence<beans::PropertyValue> aSpacing;
+    bool bWordWrap = false;
     for (sal_Int32 i = 0; i < rPPr.getLength(); ++i)
     {
         if (rPPr[i].Name == "spacing")
             aSpacing = rPPr[i].Value.get< uno::Sequence<beans::PropertyValue> >();
+        if (rPPr[i].Name == "wordWrap")
+            bWordWrap = true;
     }
+    if (bWordWrap)
+        pSerializer->singleElementNS(XML_w, XML_wordWrap, FSEND);
     lcl_TableStylePSpacing(pSerializer, aSpacing);
 
     pSerializer->endElementNS(XML_w, XML_pPr);
@@ -266,12 +326,19 @@ void lcl_TableStyleTcPr(sax_fastparser::FSHelperPtr pSerializer, uno::Sequence<b
     pSerializer->startElementNS(XML_w, XML_tcPr, FSEND);
 
     uno::Sequence<beans::PropertyValue> aShd;
+    OUString aVAlign;
     for (sal_Int32 i = 0; i < rTcPr.getLength(); ++i)
     {
         if (rTcPr[i].Name == "shd")
             aShd = rTcPr[i].Value.get< uno::Sequence<beans::PropertyValue> >();
+        else if (rTcPr[i].Name == "vAlign")
+            aVAlign = rTcPr[i].Value.get<OUString>();
     }
     lcl_TableStyleShd(pSerializer, aShd);
+    if (!aVAlign.isEmpty())
+        pSerializer->singleElementNS(XML_w, XML_vAlign,
+                FSNS(XML_w, XML_val), OUStringToOString(aVAlign, RTL_TEXTENCODING_UTF8).getStr(),
+                FSEND);
 
     pSerializer->endElementNS(XML_w, XML_tcPr);
 }
diff --git a/writerfilter/source/dmapper/DomainMapper.cxx b/writerfilter/source/dmapper/DomainMapper.cxx
index 1139671..a0c4bef 100644
--- a/writerfilter/source/dmapper/DomainMapper.cxx
+++ b/writerfilter/source/dmapper/DomainMapper.cxx
@@ -948,13 +948,15 @@ void DomainMapper::lcl_attribute(Id nName, Value & val)
                 m_pImpl->GetTopContext()->Insert(PROP_CHAR_FONT_NAME, uno::makeAny( sStringValue ));
             break;
         case NS_ooxml::LN_CT_Fonts_asciiTheme:
+            m_pImpl->appendGrabBag(m_pImpl->m_aSubInteropGrabBag, "asciiTheme", ThemeTable::getStringForTheme(nIntValue));
             if (m_pImpl->GetTopContext())
                 m_pImpl->GetTopContext()->Insert(PROP_CHAR_FONT_NAME, uno::makeAny( m_pImpl->GetThemeTable()->getFontNameForTheme(nIntValue) ));
             break;
         case NS_ooxml::LN_CT_Fonts_hAnsi:
             break;//unsupported
         case NS_ooxml::LN_CT_Fonts_hAnsiTheme:
-            break; //unsupported
+            m_pImpl->appendGrabBag(m_pImpl->m_aSubInteropGrabBag, "hAnsiTheme", ThemeTable::getStringForTheme(nIntValue));
+            break;
         case NS_ooxml::LN_CT_Fonts_eastAsia:
             if (m_pImpl->GetTopContext())
                 m_pImpl->GetTopContext()->Insert(PROP_CHAR_FONT_NAME_ASIAN, uno::makeAny( sStringValue ));
@@ -978,6 +980,7 @@ void DomainMapper::lcl_attribute(Id nName, Value & val)
                 m_pImpl->GetTopContext()->Insert(PROP_PARA_TOP_MARGIN, uno::makeAny( ConversionHelper::convertTwipToMM100( nIntValue ) ), false);
             break;
         case NS_ooxml::LN_CT_Spacing_beforeLines:
+                m_pImpl->appendGrabBag(m_pImpl->m_aSubInteropGrabBag, "beforeLines", OUString::number(nIntValue));
             break;
         case NS_ooxml::LN_CT_Spacing_after:
             m_pImpl->appendGrabBag(m_pImpl->m_aSubInteropGrabBag, "after", OUString::number(nIntValue));
@@ -986,6 +989,7 @@ void DomainMapper::lcl_attribute(Id nName, Value & val)
                 m_pImpl->GetTopContext()->Insert(PROP_PARA_BOTTOM_MARGIN, uno::makeAny( ConversionHelper::convertTwipToMM100( nIntValue ) ), false);
             break;
         case NS_ooxml::LN_CT_Spacing_afterLines:
+            m_pImpl->appendGrabBag(m_pImpl->m_aSubInteropGrabBag, "afterLines", OUString::number(nIntValue));
             break;
         case NS_ooxml::LN_CT_Spacing_line: //91434
         case NS_ooxml::LN_CT_Spacing_lineRule: //91435
@@ -1173,12 +1177,14 @@ void DomainMapper::lcl_attribute(Id nName, Value & val)
         break;
         // See SwWW8ImplReader::GetParagraphAutoSpace() on why these are 100 and 280
         case NS_ooxml::LN_CT_Spacing_beforeAutospacing:
+            m_pImpl->appendGrabBag(m_pImpl->m_aSubInteropGrabBag, "beforeAutospacing", OUString::number(nIntValue));
             if (!m_pImpl->GetSettingsTable()->GetDoNotUseHTMLParagraphAutoSpacing())
                 m_pImpl->GetTopContext()->Insert( PROP_PARA_TOP_MARGIN, uno::makeAny( ConversionHelper::convertTwipToMM100(280) ) );
             else
                 m_pImpl->GetTopContext()->Insert( PROP_PARA_TOP_MARGIN, uno::makeAny( ConversionHelper::convertTwipToMM100(100) ) );
         break;
         case NS_ooxml::LN_CT_Spacing_afterAutospacing:
+            m_pImpl->appendGrabBag(m_pImpl->m_aSubInteropGrabBag, "afterAutospacing", OUString::number(nIntValue));
             if (!m_pImpl->GetSettingsTable()->GetDoNotUseHTMLParagraphAutoSpacing())
                 m_pImpl->GetTopContext()->Insert( PROP_PARA_BOTTOM_MARGIN, uno::makeAny( ConversionHelper::convertTwipToMM100(280) ) );
             else
commit e0f1ddca3f26df3e84d6fbf1cc373ec287396397
Author: Miklos Vajna <vmiklos at collabora.co.uk>
Date:   Wed Oct 30 13:36:46 2013 +0100

    Factor out DocxTableStyleExport from DocxAttributeOutput
    
    Also add a docxhelper, that contains stuff that was local to
    DocxAttributeOutput till now, but required by DocxTableStyleExport.
    
    Change-Id: I24dcc62d11862078202244c214b317e3bc600567

diff --git a/sw/Library_msword.mk b/sw/Library_msword.mk
index 93a43d1..069795b 100644
--- a/sw/Library_msword.mk
+++ b/sw/Library_msword.mk
@@ -78,6 +78,7 @@ $(eval $(call gb_Library_add_exception_objects,msword,\
     sw/source/filter/ww8/docxattributeoutput \
     sw/source/filter/ww8/docxexport \
     sw/source/filter/ww8/docxexportfilter \
+    sw/source/filter/ww8/docxtablestyleexport \
     sw/source/filter/ww8/rtfattributeoutput \
     sw/source/filter/ww8/rtfexport \
     sw/source/filter/ww8/rtfexportfilter \
diff --git a/sw/source/filter/ww8/docxattributeoutput.cxx b/sw/source/filter/ww8/docxattributeoutput.cxx
index 91b95fb..8f1847e 100644
--- a/sw/source/filter/ww8/docxattributeoutput.cxx
+++ b/sw/source/filter/ww8/docxattributeoutput.cxx
@@ -18,6 +18,7 @@
  */
 
 #include "docxattributeoutput.hxx"
+#include "docxhelper.hxx"
 #include "docxexportfilter.hxx"
 #include "docxfootnotes.hxx"
 #include "writerwordglue.hxx"
@@ -2362,14 +2363,19 @@ void DocxAttributeOutput::StartStyles()
     LatentStyles();
 }
 
-namespace {
-struct StringTokenMap
+sal_Int32 DocxStringGetToken(DocxStringTokenMap const * pMap, OUString aName)
 {
-    const char* pToken;
-    sal_Int32 nToken;
-};
+    OString sName = OUStringToOString(aName, RTL_TEXTENCODING_UTF8);
+    while (pMap->pToken)
+    {
+        if (sName == pMap->pToken)
+            return pMap->nToken;
+        ++pMap;
+    }
+    return 0;
+}
 
-StringTokenMap const aDefaultTokens[] = {
+DocxStringTokenMap const aDefaultTokens[] = {
     {"defQFormat", XML_defQFormat},
     {"defUnhideWhenUsed", XML_defUnhideWhenUsed},
     {"defSemiHidden", XML_defSemiHidden},
@@ -2379,7 +2385,7 @@ StringTokenMap const aDefaultTokens[] = {
     {0, 0}
 };
 
-StringTokenMap const aExceptionTokens[] = {
+DocxStringTokenMap const aExceptionTokens[] = {
     {"name", XML_name},
     {"locked", XML_locked},
     {"uiPriority", XML_uiPriority},
@@ -2389,19 +2395,6 @@ StringTokenMap const aExceptionTokens[] = {
     {0, 0}
 };
 
-sal_Int32 lcl_getToken(StringTokenMap const * pMap, OUString aName)
-{
-    OString sName = OUStringToOString(aName, RTL_TEXTENCODING_UTF8);
-    while (pMap->pToken)
-    {
-        if (sName == pMap->pToken)
-            return pMap->nToken;
-        ++pMap;
-    }
-    return 0;
-}
-}
-
 void DocxAttributeOutput::LatentStyles()
 {
     // Do we have latent styles available?
@@ -2425,7 +2418,7 @@ void DocxAttributeOutput::LatentStyles()
     uno::Sequence<beans::PropertyValue> aLsdExceptions;
     for (sal_Int32 i = 0; i < aLatentStyles.getLength(); ++i)
     {
-        if (sal_Int32 nToken = lcl_getToken(aDefaultTokens, aLatentStyles[i].Name))
+        if (sal_Int32 nToken = DocxStringGetToken(aDefaultTokens, aLatentStyles[i].Name))
             pAttributeList->add(FSNS(XML_w, nToken), OUStringToOString(aLatentStyles[i].Value.get<OUString>(), RTL_TEXTENCODING_UTF8));
         else if (aLatentStyles[i].Name == "lsdExceptions")
             aLatentStyles[i].Value >>= aLsdExceptions;
@@ -2443,7 +2436,7 @@ void DocxAttributeOutput::LatentStyles()
         uno::Sequence<beans::PropertyValue> aAttributes;
         aLsdExceptions[i].Value >>= aAttributes;
         for (sal_Int32 j = 0; j < aAttributes.getLength(); ++j)
-            if (sal_Int32 nToken = lcl_getToken(aExceptionTokens, aAttributes[j].Name))
+            if (sal_Int32 nToken = DocxStringGetToken(aExceptionTokens, aAttributes[j].Name))
                 pAttributeList->add(FSNS(XML_w, nToken), OUStringToOString(aAttributes[j].Value.get<OUString>(), RTL_TEXTENCODING_UTF8));
 
         xAttributeList = pAttributeList;
@@ -2660,382 +2653,9 @@ void DocxAttributeOutput::DocDefaults( )
     m_pSerializer->endElementNS(XML_w, XML_docDefaults);
 }
 
-void DocxAttributeOutput::TableStyles()
-{
-    // Do we have table styles from InteropGrabBag available?
-    uno::Reference<beans::XPropertySet> xPropertySet(m_rExport.pDoc->GetDocShell()->GetBaseModel(), uno::UNO_QUERY_THROW);
-    uno::Sequence<beans::PropertyValue> aInteropGrabBag;
-    xPropertySet->getPropertyValue("InteropGrabBag") >>= aInteropGrabBag;
-    uno::Sequence<beans::PropertyValue> aTableStyles;
-    for (sal_Int32 i = 0; i < aInteropGrabBag.getLength(); ++i)
-    {
-        if (aInteropGrabBag[i].Name == "tableStyles")
-        {
-            aInteropGrabBag[i].Value >>= aTableStyles;
-            break;
-        }
-    }
-    if (!aTableStyles.getLength())
-        return;
-
-    for (sal_Int32 i = 0; i < aTableStyles.getLength(); ++i)
-    {
-        uno::Sequence<beans::PropertyValue> aTableStyle;
-        aTableStyles[i].Value >>= aTableStyle;
-        TableStyle(aTableStyle);
-    }
-}
-
-StringTokenMap const aTblCellMarTokens[] = {
-    {"left", XML_left},
-    {"right", XML_right},
-    {"start", XML_start},
-    {"end", XML_end},
-    {"top", XML_top},
-    {"bottom", XML_bottom},
-    {0, 0}
-};
-
-/// Export of w:tblCellMar in a table style.
-void lcl_TableStyleTblCellMar(sax_fastparser::FSHelperPtr pSerializer, uno::Sequence<beans::PropertyValue>& rTblCellMar)
-{
-    if (!rTblCellMar.hasElements())
-        return;
-
-    pSerializer->startElementNS(XML_w, XML_tblCellMar, FSEND);
-    for (sal_Int32 i = 0; i < rTblCellMar.getLength(); ++i)
-    {
-        if (sal_Int32 nToken = lcl_getToken(aTblCellMarTokens, rTblCellMar[i].Name))
-        {
-            comphelper::SequenceAsHashMap aMap(rTblCellMar[i].Value.get< uno::Sequence<beans::PropertyValue> >());
-            pSerializer->singleElementNS(XML_w, nToken,
-                    FSNS(XML_w, XML_w), OString::number(aMap["w"].get<sal_Int32>()),
-                    FSNS(XML_w, XML_type), OUStringToOString(aMap["type"].get<OUString>(), RTL_TEXTENCODING_UTF8).getStr(),
-                    FSEND);
-        }
-    }
-    pSerializer->endElementNS(XML_w, XML_tblCellMar);
-}
-
-/// Export of w:shd in a table style.
-void lcl_TableStyleShd(sax_fastparser::FSHelperPtr pSerializer, uno::Sequence<beans::PropertyValue>& rShd)
-{
-    if (!rShd.hasElements())
-        return;
-
-    sax_fastparser::FastAttributeList* pAttributeList = pSerializer->createAttrList();
-    for (sal_Int32 i = 0; i < rShd.getLength(); ++i)
-    {
-        if (rShd[i].Name == "val")
-            pAttributeList->add(FSNS(XML_w, XML_val), OUStringToOString(rShd[i].Value.get<OUString>(), RTL_TEXTENCODING_UTF8).getStr());
-        else if (rShd[i].Name == "color")
-            pAttributeList->add(FSNS(XML_w, XML_color), msfilter::util::ConvertColor(rShd[i].Value.get<sal_Int32>(), /*bAutoColor =*/ true));
-        else if (rShd[i].Name == "fill")
-            pAttributeList->add(FSNS(XML_w, XML_fill), msfilter::util::ConvertColor(rShd[i].Value.get<sal_Int32>(), /*bAutoColor =*/ true));
-    }
-    XFastAttributeListRef xAttributeList(pAttributeList);
-    pSerializer->singleElementNS(XML_w, XML_shd, xAttributeList);
-}
-
-/// Export of w:lang in a table style.
-void lcl_TableStyleRLang(sax_fastparser::FSHelperPtr pSerializer, uno::Sequence<beans::PropertyValue>& rLang)
-{
-    if (!rLang.hasElements())
-        return;
-
-    sax_fastparser::FastAttributeList* pAttributeList = pSerializer->createAttrList();
-    for (sal_Int32 i = 0; i < rLang.getLength(); ++i)
-    {
-        if (rLang[i].Name == "eastAsia")
-            pAttributeList->add(FSNS(XML_w, XML_eastAsia), OUStringToOString(rLang[i].Value.get<OUString>(), RTL_TEXTENCODING_UTF8).getStr());
-    }
-    XFastAttributeListRef xAttributeList(pAttributeList);
-    pSerializer->singleElementNS(XML_w, XML_lang, xAttributeList);
-}
-
-/// Export of w:rFonts in a table style.
-void lcl_TableStyleRRFonts(sax_fastparser::FSHelperPtr pSerializer, uno::Sequence<beans::PropertyValue>& rRFonts)
-{
-    if (!rRFonts.hasElements())
-        return;
-
-    sax_fastparser::FastAttributeList* pAttributeList = pSerializer->createAttrList();
-    for (sal_Int32 i = 0; i < rRFonts.getLength(); ++i)
-    {
-        if (rRFonts[i].Name == "eastAsiaTheme")
-            pAttributeList->add(FSNS(XML_w, XML_eastAsiaTheme), OUStringToOString(rRFonts[i].Value.get<OUString>(), RTL_TEXTENCODING_UTF8).getStr());
-    }
-    XFastAttributeListRef xAttributeList(pAttributeList);
-    pSerializer->singleElementNS(XML_w, XML_rFonts, xAttributeList);
-}
-
-/// Export of w:spacing in a table style.
-void lcl_TableStylePSpacing(sax_fastparser::FSHelperPtr pSerializer, uno::Sequence<beans::PropertyValue>& rSpacing)
-{
-    if (!rSpacing.hasElements())
-        return;
-
-    sax_fastparser::FastAttributeList* pAttributeList = pSerializer->createAttrList();
-    for (sal_Int32 i = 0; i < rSpacing.getLength(); ++i)
-    {
-        if (rSpacing[i].Name == "after")
-            pAttributeList->add(FSNS(XML_w, XML_after), OUStringToOString(rSpacing[i].Value.get<OUString>(), RTL_TEXTENCODING_UTF8).getStr());
-        else if (rSpacing[i].Name == "line")
-            pAttributeList->add(FSNS(XML_w, XML_line), OUStringToOString(rSpacing[i].Value.get<OUString>(), RTL_TEXTENCODING_UTF8).getStr());
-        else if (rSpacing[i].Name == "lineRule")
-            pAttributeList->add(FSNS(XML_w, XML_lineRule), OUStringToOString(rSpacing[i].Value.get<OUString>(), RTL_TEXTENCODING_UTF8).getStr());
-    }
-    XFastAttributeListRef xAttributeList(pAttributeList);
-    pSerializer->singleElementNS(XML_w, XML_spacing, xAttributeList);
-}
-
-/// Export of w:tblInd in a table style.
-void lcl_TableStyleTblInd(sax_fastparser::FSHelperPtr pSerializer, uno::Sequence<beans::PropertyValue>& rTblInd)
-{
-    if (!rTblInd.hasElements())
-        return;
-
-    sax_fastparser::FastAttributeList* pAttributeList = pSerializer->createAttrList();
-    for (sal_Int32 i = 0; i < rTblInd.getLength(); ++i)
-    {
-        if (rTblInd[i].Name == "w")
-            pAttributeList->add(FSNS(XML_w, XML_w), OString::number(rTblInd[i].Value.get<sal_Int32>()));
-        else if (rTblInd[i].Name == "type")
-            pAttributeList->add(FSNS(XML_w, XML_type), OUStringToOString(rTblInd[i].Value.get<OUString>(), RTL_TEXTENCODING_UTF8).getStr());
-    }
-    XFastAttributeListRef xAttributeList(pAttributeList);
-    pSerializer->singleElementNS(XML_w, XML_tblInd, xAttributeList);
-}
-
-/// Export of w:rPr in a table style.
-void lcl_TableStyleRPr(sax_fastparser::FSHelperPtr pSerializer, uno::Sequence<beans::PropertyValue>& rRPr)
-{
-    if (!rRPr.hasElements())
-        return;
-
-    pSerializer->startElementNS(XML_w, XML_rPr, FSEND);
-
-    uno::Sequence<beans::PropertyValue> aRFonts, aLang;
-    for (sal_Int32 i = 0; i < rRPr.getLength(); ++i)
-    {
-        if (rRPr[i].Name == "rFonts")
-            aRFonts = rRPr[i].Value.get< uno::Sequence<beans::PropertyValue> >();
-        else if (rRPr[i].Name == "lang")
-            aLang = rRPr[i].Value.get< uno::Sequence<beans::PropertyValue> >();
-    }
-    lcl_TableStyleRRFonts(pSerializer, aRFonts);
-    lcl_TableStyleRLang(pSerializer, aLang);
-
-    pSerializer->endElementNS(XML_w, XML_rPr);
-}
-
-/// Export of w:pPr in a table style.
-void lcl_TableStylePPr(sax_fastparser::FSHelperPtr pSerializer, uno::Sequence<beans::PropertyValue>& rPPr)
-{
-    if (!rPPr.hasElements())
-        return;
-
-    pSerializer->startElementNS(XML_w, XML_pPr, FSEND);
-
-    uno::Sequence<beans::PropertyValue> aSpacing;
-    for (sal_Int32 i = 0; i < rPPr.getLength(); ++i)
-    {
-        if (rPPr[i].Name == "spacing")
-            aSpacing = rPPr[i].Value.get< uno::Sequence<beans::PropertyValue> >();
-    }
-    lcl_TableStylePSpacing(pSerializer, aSpacing);
-
-    pSerializer->endElementNS(XML_w, XML_pPr);
-}
-
-/// Export of w:tblPr in a table style.
-void lcl_TableStyleTblPr(sax_fastparser::FSHelperPtr pSerializer, uno::Sequence<beans::PropertyValue>& rTblPr)
-{
-    if (!rTblPr.hasElements())
-        return;
-
-    pSerializer->startElementNS(XML_w, XML_tblPr, FSEND);
-
-    uno::Sequence<beans::PropertyValue> aTblInd, aTblCellMar;
-    boost::optional<sal_Int32> oTblStyleRowBandSize, oTblStyleColBandSize;
-    for (sal_Int32 i = 0; i < rTblPr.getLength(); ++i)
-    {
-        if (rTblPr[i].Name == "tblStyleRowBandSize")
-            oTblStyleRowBandSize = rTblPr[i].Value.get<sal_Int32>();
-        else if (rTblPr[i].Name == "tblStyleColBandSize")
-            oTblStyleColBandSize = rTblPr[i].Value.get<sal_Int32>();
-        else if (rTblPr[i].Name == "tblInd")
-            aTblInd = rTblPr[i].Value.get< uno::Sequence<beans::PropertyValue> >();
-        else if (rTblPr[i].Name == "tblCellMar")
-            aTblCellMar = rTblPr[i].Value.get< uno::Sequence<beans::PropertyValue> >();
-    }
-    if (oTblStyleRowBandSize)
-        pSerializer->singleElementNS(XML_w, XML_tblStyleRowBandSize,
-                FSNS(XML_w, XML_val), OString::number(oTblStyleRowBandSize.get()),
-                FSEND);
-    if (oTblStyleColBandSize)
-        pSerializer->singleElementNS(XML_w, XML_tblStyleColBandSize,
-                FSNS(XML_w, XML_val), OString::number(oTblStyleColBandSize.get()),
-                FSEND);
-    lcl_TableStyleTblInd(pSerializer, aTblInd);
-    lcl_TableStyleTblCellMar(pSerializer, aTblCellMar);
-
-    pSerializer->endElementNS(XML_w, XML_tblPr);
-}
-
-/// Export of w:tcPr in a table style.
-void lcl_TableStyleTcPr(sax_fastparser::FSHelperPtr pSerializer, uno::Sequence<beans::PropertyValue>& rTcPr)
-{
-    if (!rTcPr.hasElements())
-        return;
-
-    pSerializer->startElementNS(XML_w, XML_tcPr, FSEND);
-
-    uno::Sequence<beans::PropertyValue> aShd;
-    for (sal_Int32 i = 0; i < rTcPr.getLength(); ++i)
-    {
-        if (rTcPr[i].Name == "shd")
-            aShd = rTcPr[i].Value.get< uno::Sequence<beans::PropertyValue> >();
-    }
-    lcl_TableStyleShd(pSerializer, aShd);
-
-    pSerializer->endElementNS(XML_w, XML_tcPr);
-}
-
-/// Export of w:tblStylePr in a table style.
-void lcl_TableStyleTblStylePr(sax_fastparser::FSHelperPtr pSerializer, uno::Sequence<beans::PropertyValue>& rTblStylePr)
-{
-    if (!rTblStylePr.hasElements())
-        return;
-
-    OUString aType;
-    uno::Sequence<beans::PropertyValue> aPPr, aRPr, aTblPr, aTcPr;
-    for (sal_Int32 i = 0; i < rTblStylePr.getLength(); ++i)
-    {
-        if (rTblStylePr[i].Name == "type")
-            aType = rTblStylePr[i].Value.get<OUString>();
-        else if (rTblStylePr[i].Name == "pPr")
-            aPPr = rTblStylePr[i].Value.get< uno::Sequence<beans::PropertyValue> >();
-        else if (rTblStylePr[i].Name == "rPr")
-            aRPr = rTblStylePr[i].Value.get< uno::Sequence<beans::PropertyValue> >();
-        else if (rTblStylePr[i].Name == "tblPr")
-            aTblPr = rTblStylePr[i].Value.get< uno::Sequence<beans::PropertyValue> >();
-        else if (rTblStylePr[i].Name == "tcPr")
-            aTcPr = rTblStylePr[i].Value.get< uno::Sequence<beans::PropertyValue> >();
-    }
-
-    pSerializer->startElementNS(XML_w, XML_tblStylePr,
-            FSNS(XML_w, XML_type), OUStringToOString(aType, RTL_TEXTENCODING_UTF8).getStr(),
-            FSEND);
-
-    lcl_TableStylePPr(pSerializer, aPPr);
-    lcl_TableStyleRPr(pSerializer, aRPr);
-    if (aTblPr.hasElements())
-        lcl_TableStyleTblPr(pSerializer, aTblPr);
-    else
-    {
-        // Even if we have an empty container, write it out, as Word does.
-        pSerializer->singleElementNS(XML_w, XML_tblPr, FSEND);
-    }
-    lcl_TableStyleTcPr(pSerializer, aTcPr);
-
-    pSerializer->endElementNS(XML_w, XML_tblStylePr);
-}
-
-void DocxAttributeOutput::TableStyle(uno::Sequence<beans::PropertyValue>& rStyle)
-{
-    bool bDefault = false, bCustomStyle = false, bQFormat = false, bSemiHidden = false, bUnhideWhenUsed = false;
-    OUString aStyleId, aName, aBasedOn;
-    sal_Int32 nUiPriority = 0, nRsid = 0;
-    uno::Sequence<beans::PropertyValue> aPPr, aRPr, aTblPr, aTcPr;
-    std::vector< uno::Sequence<beans::PropertyValue> > aTblStylePrs;
-    for (sal_Int32 i = 0; i < rStyle.getLength(); ++i)
-    {
-        if (rStyle[i].Name == "default")
-            bDefault = rStyle[i].Value.get<sal_Bool>();
-        else if (rStyle[i].Name == "customStyle")
-            bCustomStyle = rStyle[i].Value.get<sal_Bool>();
-        else if (rStyle[i].Name == "styleId")
-            aStyleId = rStyle[i].Value.get<OUString>();
-        else if (rStyle[i].Name == "name")
-            aName = rStyle[i].Value.get<OUString>();
-        else if (rStyle[i].Name == "basedOn")
-            aBasedOn = rStyle[i].Value.get<OUString>();
-        else if (rStyle[i].Name == "uiPriority")
-            nUiPriority = rStyle[i].Value.get<sal_Int32>();
-        else if (rStyle[i].Name == "qFormat")
-            bQFormat = true;
-        else if (rStyle[i].Name == "semiHidden")
-            bSemiHidden = true;
-        else if (rStyle[i].Name == "unhideWhenUsed")
-            bUnhideWhenUsed = true;
-        else if (rStyle[i].Name == "rsid")
-            nRsid = rStyle[i].Value.get<sal_Int32>();
-        else if (rStyle[i].Name == "pPr")
-            aPPr = rStyle[i].Value.get< uno::Sequence<beans::PropertyValue> >();
-        else if (rStyle[i].Name == "rPr")
-            aRPr = rStyle[i].Value.get< uno::Sequence<beans::PropertyValue> >();
-        else if (rStyle[i].Name == "tblPr")
-            aTblPr = rStyle[i].Value.get< uno::Sequence<beans::PropertyValue> >();
-        else if (rStyle[i].Name == "tcPr")
-            aTcPr = rStyle[i].Value.get< uno::Sequence<beans::PropertyValue> >();
-        else if (rStyle[i].Name == "tblStylePr")
-            aTblStylePrs.push_back(rStyle[i].Value.get< uno::Sequence<beans::PropertyValue> >());
-    }
-
-    sax_fastparser::FastAttributeList* pAttributeList = m_pSerializer->createAttrList();
-    pAttributeList->add(FSNS(XML_w, XML_type), "table");
-    if (bDefault)
-        pAttributeList->add(FSNS(XML_w, XML_default), "1");
-    if (bCustomStyle)
-        pAttributeList->add(FSNS(XML_w, XML_customStyle), "1");
-    if (!aStyleId.isEmpty())
-        pAttributeList->add(FSNS(XML_w, XML_styleId), OUStringToOString(aStyleId, RTL_TEXTENCODING_UTF8).getStr());
-    XFastAttributeListRef xAttributeList(pAttributeList);
-    m_pSerializer->startElementNS(XML_w, XML_style, xAttributeList);
-
-    m_pSerializer->singleElementNS(XML_w, XML_name,
-            FSNS(XML_w, XML_val), OUStringToOString(aName, RTL_TEXTENCODING_UTF8).getStr(),
-            FSEND);
-    if (!aBasedOn.isEmpty())
-        m_pSerializer->singleElementNS(XML_w, XML_basedOn,
-                FSNS(XML_w, XML_val), OUStringToOString(aBasedOn, RTL_TEXTENCODING_UTF8).getStr(),
-                FSEND);
-    if (nUiPriority)
-        m_pSerializer->singleElementNS(XML_w, XML_uiPriority,
-                FSNS(XML_w, XML_val), OString::number(nUiPriority),
-                FSEND);
-    if (bQFormat)
-        m_pSerializer->singleElementNS(XML_w, XML_qFormat, FSEND);
-    if (bSemiHidden)
-        m_pSerializer->singleElementNS(XML_w, XML_semiHidden, FSEND);
-    if (bUnhideWhenUsed)
-        m_pSerializer->singleElementNS(XML_w, XML_unhideWhenUsed, FSEND);
-    if (nRsid)
-    {
-        // We want the rsid as a hex string, but always with the length of 8.
-        OStringBuffer aBuf = OString::number(nRsid, 16);
-        OStringBuffer aStr;
-        comphelper::string::padToLength(aStr, 8 - aBuf.getLength(), '0');
-        aStr.append(aBuf.getStr());
-        m_pSerializer->singleElementNS(XML_w, XML_rsid,
-                FSNS(XML_w, XML_val), aStr.getStr(),
-                FSEND);
-    }
-
-    lcl_TableStylePPr(m_pSerializer, aPPr);
-    lcl_TableStyleRPr(m_pSerializer, aRPr);
-    lcl_TableStyleTblPr(m_pSerializer, aTblPr);
-    lcl_TableStyleTcPr(m_pSerializer, aTcPr);
-    for (size_t i = 0; i < aTblStylePrs.size(); ++i)
-        lcl_TableStyleTblStylePr(m_pSerializer, aTblStylePrs[i]);
-
-    m_pSerializer->endElementNS(XML_w, XML_style);
-}
-
 void DocxAttributeOutput::EndStyles( sal_uInt16 /*nNumberOfStyles*/ )
 {
-    TableStyles();
+    m_pTableStyleExport->TableStyles();
     m_pSerializer->endElementNS( XML_w, XML_styles );
 }
 
@@ -6441,7 +6061,8 @@ DocxAttributeOutput::DocxAttributeOutput( DocxExport &rExport, FSHelperPtr pSeri
       m_anchorId( 0 ),
       m_nextFontId( 1 ),
       m_bBtLr(false),
-      m_bFrameBtLr(false)
+      m_bFrameBtLr(false),
+      m_pTableStyleExport(new DocxTableStyleExport(rExport.pDoc, pSerializer))
 {
 }
 
@@ -6467,6 +6088,12 @@ DocxExport& DocxAttributeOutput::GetExport()
     return m_rExport;
 }
 
+void DocxAttributeOutput::SetSerializer( ::sax_fastparser::FSHelperPtr pSerializer )
+{
+    m_pSerializer = pSerializer;
+    m_pTableStyleExport->SetSerializer(pSerializer);
+}
+
 bool DocxAttributeOutput::HasFootnotes() const
 {
     return !m_pFootnotesList->isEmpty();
diff --git a/sw/source/filter/ww8/docxattributeoutput.hxx b/sw/source/filter/ww8/docxattributeoutput.hxx
index 4aa0b10..a2167d9 100644
--- a/sw/source/filter/ww8/docxattributeoutput.hxx
+++ b/sw/source/filter/ww8/docxattributeoutput.hxx
@@ -36,6 +36,7 @@
 #include <boost/scoped_ptr.hpp>
 #include <boost/optional.hpp>
 #include <oox/export/vmlexport.hxx>
+#include <docxtablestyleexport.hxx>
 
 class SwGrfNode;
 class SdrObject;
@@ -217,10 +218,6 @@ public:
     /// Write latent styles.
     void LatentStyles();
 
-    /// Write table styles from InteropGrabBag.
-    void TableStyles();
-    void TableStyle(com::sun::star::uno::Sequence<com::sun::star::beans::PropertyValue>& rStyle);
-
     /** Similar to OutputItem(), but write something only if it is not the default.
 
         This is to output the docDefaults, and we should write something out
@@ -766,6 +763,8 @@ private:
 
     PageMargins m_pageMargins;
 
+    boost::shared_ptr<DocxTableStyleExport> m_pTableStyleExport;
+
 public:
     DocxAttributeOutput( DocxExport &rExport, ::sax_fastparser::FSHelperPtr pSerializer, oox::drawingml::DrawingML* pDrawingML );
 
@@ -776,7 +775,7 @@ public:
     const DocxExport& GetExport() const { return const_cast< DocxAttributeOutput* >( this )->GetExport(); }
 
     /// For eg. the output of the styles, we need to switch the serializer to an other one.
-    void SetSerializer( ::sax_fastparser::FSHelperPtr pSerializer ) { m_pSerializer = pSerializer; }
+    void SetSerializer( ::sax_fastparser::FSHelperPtr pSerializer );
 
     /// Occasionnaly need to use this serializer from the outside
     ::sax_fastparser::FSHelperPtr GetSerializer( ) { return m_pSerializer; }
diff --git a/sw/source/filter/ww8/docxhelper.hxx b/sw/source/filter/ww8/docxhelper.hxx
new file mode 100644
index 0000000..60f7232
--- /dev/null
+++ b/sw/source/filter/ww8/docxhelper.hxx
@@ -0,0 +1,25 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ */
+
+#ifndef _DOCXHELPER_HXX_
+#define _DOCXHELPER_HXX_
+
+#include <rtl/ustring.hxx>
+
+struct DocxStringTokenMap
+{
+    const char* pToken;
+    sal_Int32 nToken;
+};
+
+sal_Int32 DocxStringGetToken(DocxStringTokenMap const * pMap, OUString aName);
+
+#endif // _DOCXHELPER_HXX_
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sw/source/filter/ww8/docxtablestyleexport.cxx b/sw/source/filter/ww8/docxtablestyleexport.cxx
new file mode 100644
index 0000000..db0608d
--- /dev/null
+++ b/sw/source/filter/ww8/docxtablestyleexport.cxx
@@ -0,0 +1,426 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ */
+
+#include "docxtablestyleexport.hxx"
+#include "docxhelper.hxx"
+#include <doc.hxx>
+#include <docsh.hxx>
+
+#include <oox/token/tokens.hxx>
+#include <comphelper/sequenceashashmap.hxx>
+#include <comphelper/string.hxx>
+#include <filter/msfilter/util.hxx>
+#include <rtl/strbuf.hxx>
+
+#include <com/sun/star/beans/PropertyValue.hpp>
+#include <com/sun/star/uno/Sequence.h>
+
+#include <boost/optional.hpp>
+
+using namespace com::sun::star;
+using namespace oox;
+
+struct DocxTableStyleExport::Impl
+{
+    SwDoc* m_pDoc;
+    sax_fastparser::FSHelperPtr m_pSerializer;
+
+    void TableStyle(uno::Sequence<beans::PropertyValue>& rStyle);
+};
+
+void DocxTableStyleExport::TableStyles()
+{
+    // Do we have table styles from InteropGrabBag available?
+    uno::Reference<beans::XPropertySet> xPropertySet(m_pImpl->m_pDoc->GetDocShell()->GetBaseModel(), uno::UNO_QUERY_THROW);
+    uno::Sequence<beans::PropertyValue> aInteropGrabBag;
+    xPropertySet->getPropertyValue("InteropGrabBag") >>= aInteropGrabBag;
+    uno::Sequence<beans::PropertyValue> aTableStyles;
+    for (sal_Int32 i = 0; i < aInteropGrabBag.getLength(); ++i)
+    {
+        if (aInteropGrabBag[i].Name == "tableStyles")
+        {
+            aInteropGrabBag[i].Value >>= aTableStyles;
+            break;
+        }
+    }
+    if (!aTableStyles.getLength())
+        return;
+
+    for (sal_Int32 i = 0; i < aTableStyles.getLength(); ++i)
+    {
+        uno::Sequence<beans::PropertyValue> aTableStyle;
+        aTableStyles[i].Value >>= aTableStyle;
+        m_pImpl->TableStyle(aTableStyle);
+    }
+}
+
+DocxStringTokenMap const aTblCellMarTokens[] = {
+    {"left", XML_left},
+    {"right", XML_right},
+    {"start", XML_start},
+    {"end", XML_end},
+    {"top", XML_top},
+    {"bottom", XML_bottom},
+    {0, 0}
+};
+
+/// Export of w:tblCellMar in a table style.
+void lcl_TableStyleTblCellMar(sax_fastparser::FSHelperPtr pSerializer, uno::Sequence<beans::PropertyValue>& rTblCellMar)
+{
+    if (!rTblCellMar.hasElements())
+        return;
+
+    pSerializer->startElementNS(XML_w, XML_tblCellMar, FSEND);
+    for (sal_Int32 i = 0; i < rTblCellMar.getLength(); ++i)
+    {
+        if (sal_Int32 nToken = DocxStringGetToken(aTblCellMarTokens, rTblCellMar[i].Name))
+        {
+            comphelper::SequenceAsHashMap aMap(rTblCellMar[i].Value.get< uno::Sequence<beans::PropertyValue> >());
+            pSerializer->singleElementNS(XML_w, nToken,
+                    FSNS(XML_w, XML_w), OString::number(aMap["w"].get<sal_Int32>()),
+                    FSNS(XML_w, XML_type), OUStringToOString(aMap["type"].get<OUString>(), RTL_TEXTENCODING_UTF8).getStr(),
+                    FSEND);
+        }
+    }
+    pSerializer->endElementNS(XML_w, XML_tblCellMar);
+}
+
+/// Export of w:shd in a table style.
+void lcl_TableStyleShd(sax_fastparser::FSHelperPtr pSerializer, uno::Sequence<beans::PropertyValue>& rShd)
+{
+    if (!rShd.hasElements())
+        return;
+
+    sax_fastparser::FastAttributeList* pAttributeList = pSerializer->createAttrList();
+    for (sal_Int32 i = 0; i < rShd.getLength(); ++i)
+    {
+        if (rShd[i].Name == "val")
+            pAttributeList->add(FSNS(XML_w, XML_val), OUStringToOString(rShd[i].Value.get<OUString>(), RTL_TEXTENCODING_UTF8).getStr());
+        else if (rShd[i].Name == "color")
+            pAttributeList->add(FSNS(XML_w, XML_color), msfilter::util::ConvertColor(rShd[i].Value.get<sal_Int32>(), /*bAutoColor =*/ true));
+        else if (rShd[i].Name == "fill")
+            pAttributeList->add(FSNS(XML_w, XML_fill), msfilter::util::ConvertColor(rShd[i].Value.get<sal_Int32>(), /*bAutoColor =*/ true));
+    }
+    sax_fastparser::XFastAttributeListRef xAttributeList(pAttributeList);
+    pSerializer->singleElementNS(XML_w, XML_shd, xAttributeList);
+}
+
+/// Export of w:lang in a table style.
+void lcl_TableStyleRLang(sax_fastparser::FSHelperPtr pSerializer, uno::Sequence<beans::PropertyValue>& rLang)
+{
+    if (!rLang.hasElements())
+        return;
+
+    sax_fastparser::FastAttributeList* pAttributeList = pSerializer->createAttrList();
+    for (sal_Int32 i = 0; i < rLang.getLength(); ++i)
+    {
+        if (rLang[i].Name == "eastAsia")
+            pAttributeList->add(FSNS(XML_w, XML_eastAsia), OUStringToOString(rLang[i].Value.get<OUString>(), RTL_TEXTENCODING_UTF8).getStr());
+    }
+    sax_fastparser::XFastAttributeListRef xAttributeList(pAttributeList);
+    pSerializer->singleElementNS(XML_w, XML_lang, xAttributeList);
+}
+
+/// Export of w:rFonts in a table style.
+void lcl_TableStyleRRFonts(sax_fastparser::FSHelperPtr pSerializer, uno::Sequence<beans::PropertyValue>& rRFonts)
+{
+    if (!rRFonts.hasElements())
+        return;
+
+    sax_fastparser::FastAttributeList* pAttributeList = pSerializer->createAttrList();
+    for (sal_Int32 i = 0; i < rRFonts.getLength(); ++i)
+    {
+        if (rRFonts[i].Name == "eastAsiaTheme")
+            pAttributeList->add(FSNS(XML_w, XML_eastAsiaTheme), OUStringToOString(rRFonts[i].Value.get<OUString>(), RTL_TEXTENCODING_UTF8).getStr());
+    }
+    sax_fastparser::XFastAttributeListRef xAttributeList(pAttributeList);
+    pSerializer->singleElementNS(XML_w, XML_rFonts, xAttributeList);
+}
+
+/// Export of w:spacing in a table style.
+void lcl_TableStylePSpacing(sax_fastparser::FSHelperPtr pSerializer, uno::Sequence<beans::PropertyValue>& rSpacing)
+{
+    if (!rSpacing.hasElements())
+        return;
+
+    sax_fastparser::FastAttributeList* pAttributeList = pSerializer->createAttrList();
+    for (sal_Int32 i = 0; i < rSpacing.getLength(); ++i)
+    {
+        if (rSpacing[i].Name == "after")
+            pAttributeList->add(FSNS(XML_w, XML_after), OUStringToOString(rSpacing[i].Value.get<OUString>(), RTL_TEXTENCODING_UTF8).getStr());
+        else if (rSpacing[i].Name == "line")
+            pAttributeList->add(FSNS(XML_w, XML_line), OUStringToOString(rSpacing[i].Value.get<OUString>(), RTL_TEXTENCODING_UTF8).getStr());
+        else if (rSpacing[i].Name == "lineRule")
+            pAttributeList->add(FSNS(XML_w, XML_lineRule), OUStringToOString(rSpacing[i].Value.get<OUString>(), RTL_TEXTENCODING_UTF8).getStr());
+    }
+    sax_fastparser::XFastAttributeListRef xAttributeList(pAttributeList);
+    pSerializer->singleElementNS(XML_w, XML_spacing, xAttributeList);
+}
+
+/// Export of w:tblInd in a table style.
+void lcl_TableStyleTblInd(sax_fastparser::FSHelperPtr pSerializer, uno::Sequence<beans::PropertyValue>& rTblInd)
+{
+    if (!rTblInd.hasElements())
+        return;
+
+    sax_fastparser::FastAttributeList* pAttributeList = pSerializer->createAttrList();
+    for (sal_Int32 i = 0; i < rTblInd.getLength(); ++i)
+    {
+        if (rTblInd[i].Name == "w")
+            pAttributeList->add(FSNS(XML_w, XML_w), OString::number(rTblInd[i].Value.get<sal_Int32>()));
+        else if (rTblInd[i].Name == "type")
+            pAttributeList->add(FSNS(XML_w, XML_type), OUStringToOString(rTblInd[i].Value.get<OUString>(), RTL_TEXTENCODING_UTF8).getStr());
+    }
+    sax_fastparser::XFastAttributeListRef xAttributeList(pAttributeList);
+    pSerializer->singleElementNS(XML_w, XML_tblInd, xAttributeList);
+}
+
+/// Export of w:rPr in a table style.
+void lcl_TableStyleRPr(sax_fastparser::FSHelperPtr pSerializer, uno::Sequence<beans::PropertyValue>& rRPr)
+{
+    if (!rRPr.hasElements())
+        return;
+
+    pSerializer->startElementNS(XML_w, XML_rPr, FSEND);
+
+    uno::Sequence<beans::PropertyValue> aRFonts, aLang;
+    for (sal_Int32 i = 0; i < rRPr.getLength(); ++i)
+    {
+        if (rRPr[i].Name == "rFonts")
+            aRFonts = rRPr[i].Value.get< uno::Sequence<beans::PropertyValue> >();
+        else if (rRPr[i].Name == "lang")
+            aLang = rRPr[i].Value.get< uno::Sequence<beans::PropertyValue> >();
+    }
+    lcl_TableStyleRRFonts(pSerializer, aRFonts);
+    lcl_TableStyleRLang(pSerializer, aLang);
+
+    pSerializer->endElementNS(XML_w, XML_rPr);
+}
+
+/// Export of w:pPr in a table style.
+void lcl_TableStylePPr(sax_fastparser::FSHelperPtr pSerializer, uno::Sequence<beans::PropertyValue>& rPPr)
+{
+    if (!rPPr.hasElements())
+        return;
+
+    pSerializer->startElementNS(XML_w, XML_pPr, FSEND);
+
+    uno::Sequence<beans::PropertyValue> aSpacing;
+    for (sal_Int32 i = 0; i < rPPr.getLength(); ++i)
+    {
+        if (rPPr[i].Name == "spacing")
+            aSpacing = rPPr[i].Value.get< uno::Sequence<beans::PropertyValue> >();
+    }
+    lcl_TableStylePSpacing(pSerializer, aSpacing);
+
+    pSerializer->endElementNS(XML_w, XML_pPr);
+}
+
+/// Export of w:tblPr in a table style.
+void lcl_TableStyleTblPr(sax_fastparser::FSHelperPtr pSerializer, uno::Sequence<beans::PropertyValue>& rTblPr)
+{
+    if (!rTblPr.hasElements())
+        return;
+
+    pSerializer->startElementNS(XML_w, XML_tblPr, FSEND);
+
+    uno::Sequence<beans::PropertyValue> aTblInd, aTblCellMar;
+    boost::optional<sal_Int32> oTblStyleRowBandSize, oTblStyleColBandSize;
+    for (sal_Int32 i = 0; i < rTblPr.getLength(); ++i)
+    {
+        if (rTblPr[i].Name == "tblStyleRowBandSize")
+            oTblStyleRowBandSize = rTblPr[i].Value.get<sal_Int32>();
+        else if (rTblPr[i].Name == "tblStyleColBandSize")
+            oTblStyleColBandSize = rTblPr[i].Value.get<sal_Int32>();
+        else if (rTblPr[i].Name == "tblInd")
+            aTblInd = rTblPr[i].Value.get< uno::Sequence<beans::PropertyValue> >();
+        else if (rTblPr[i].Name == "tblCellMar")
+            aTblCellMar = rTblPr[i].Value.get< uno::Sequence<beans::PropertyValue> >();
+    }
+    if (oTblStyleRowBandSize)
+        pSerializer->singleElementNS(XML_w, XML_tblStyleRowBandSize,
+                FSNS(XML_w, XML_val), OString::number(oTblStyleRowBandSize.get()),
+                FSEND);
+    if (oTblStyleColBandSize)
+        pSerializer->singleElementNS(XML_w, XML_tblStyleColBandSize,
+                FSNS(XML_w, XML_val), OString::number(oTblStyleColBandSize.get()),
+                FSEND);
+    lcl_TableStyleTblInd(pSerializer, aTblInd);
+    lcl_TableStyleTblCellMar(pSerializer, aTblCellMar);
+
+    pSerializer->endElementNS(XML_w, XML_tblPr);
+}
+
+/// Export of w:tcPr in a table style.
+void lcl_TableStyleTcPr(sax_fastparser::FSHelperPtr pSerializer, uno::Sequence<beans::PropertyValue>& rTcPr)
+{
+    if (!rTcPr.hasElements())
+        return;
+
+    pSerializer->startElementNS(XML_w, XML_tcPr, FSEND);
+
+    uno::Sequence<beans::PropertyValue> aShd;
+    for (sal_Int32 i = 0; i < rTcPr.getLength(); ++i)
+    {
+        if (rTcPr[i].Name == "shd")
+            aShd = rTcPr[i].Value.get< uno::Sequence<beans::PropertyValue> >();
+    }
+    lcl_TableStyleShd(pSerializer, aShd);
+
+    pSerializer->endElementNS(XML_w, XML_tcPr);
+}
+
+/// Export of w:tblStylePr in a table style.
+void lcl_TableStyleTblStylePr(sax_fastparser::FSHelperPtr pSerializer, uno::Sequence<beans::PropertyValue>& rTblStylePr)
+{
+    if (!rTblStylePr.hasElements())
+        return;
+
+    OUString aType;
+    uno::Sequence<beans::PropertyValue> aPPr, aRPr, aTblPr, aTcPr;
+    for (sal_Int32 i = 0; i < rTblStylePr.getLength(); ++i)
+    {
+        if (rTblStylePr[i].Name == "type")
+            aType = rTblStylePr[i].Value.get<OUString>();
+        else if (rTblStylePr[i].Name == "pPr")
+            aPPr = rTblStylePr[i].Value.get< uno::Sequence<beans::PropertyValue> >();
+        else if (rTblStylePr[i].Name == "rPr")
+            aRPr = rTblStylePr[i].Value.get< uno::Sequence<beans::PropertyValue> >();
+        else if (rTblStylePr[i].Name == "tblPr")
+            aTblPr = rTblStylePr[i].Value.get< uno::Sequence<beans::PropertyValue> >();
+        else if (rTblStylePr[i].Name == "tcPr")
+            aTcPr = rTblStylePr[i].Value.get< uno::Sequence<beans::PropertyValue> >();
+    }
+
+    pSerializer->startElementNS(XML_w, XML_tblStylePr,
+            FSNS(XML_w, XML_type), OUStringToOString(aType, RTL_TEXTENCODING_UTF8).getStr(),
+            FSEND);
+
+    lcl_TableStylePPr(pSerializer, aPPr);
+    lcl_TableStyleRPr(pSerializer, aRPr);
+    if (aTblPr.hasElements())
+        lcl_TableStyleTblPr(pSerializer, aTblPr);
+    else
+    {
+        // Even if we have an empty container, write it out, as Word does.
+        pSerializer->singleElementNS(XML_w, XML_tblPr, FSEND);
+    }
+    lcl_TableStyleTcPr(pSerializer, aTcPr);
+
+    pSerializer->endElementNS(XML_w, XML_tblStylePr);
+}
+
+void DocxTableStyleExport::Impl::TableStyle(uno::Sequence<beans::PropertyValue>& rStyle)
+{
+    bool bDefault = false, bCustomStyle = false, bQFormat = false, bSemiHidden = false, bUnhideWhenUsed = false;
+    OUString aStyleId, aName, aBasedOn;
+    sal_Int32 nUiPriority = 0, nRsid = 0;
+    uno::Sequence<beans::PropertyValue> aPPr, aRPr, aTblPr, aTcPr;
+    std::vector< uno::Sequence<beans::PropertyValue> > aTblStylePrs;
+    for (sal_Int32 i = 0; i < rStyle.getLength(); ++i)
+    {
+        if (rStyle[i].Name == "default")
+            bDefault = rStyle[i].Value.get<sal_Bool>();
+        else if (rStyle[i].Name == "customStyle")
+            bCustomStyle = rStyle[i].Value.get<sal_Bool>();
+        else if (rStyle[i].Name == "styleId")
+            aStyleId = rStyle[i].Value.get<OUString>();
+        else if (rStyle[i].Name == "name")
+            aName = rStyle[i].Value.get<OUString>();
+        else if (rStyle[i].Name == "basedOn")
+            aBasedOn = rStyle[i].Value.get<OUString>();
+        else if (rStyle[i].Name == "uiPriority")
+            nUiPriority = rStyle[i].Value.get<sal_Int32>();
+        else if (rStyle[i].Name == "qFormat")
+            bQFormat = true;
+        else if (rStyle[i].Name == "semiHidden")
+            bSemiHidden = true;
+        else if (rStyle[i].Name == "unhideWhenUsed")
+            bUnhideWhenUsed = true;
+        else if (rStyle[i].Name == "rsid")
+            nRsid = rStyle[i].Value.get<sal_Int32>();
+        else if (rStyle[i].Name == "pPr")
+            aPPr = rStyle[i].Value.get< uno::Sequence<beans::PropertyValue> >();
+        else if (rStyle[i].Name == "rPr")
+            aRPr = rStyle[i].Value.get< uno::Sequence<beans::PropertyValue> >();
+        else if (rStyle[i].Name == "tblPr")
+            aTblPr = rStyle[i].Value.get< uno::Sequence<beans::PropertyValue> >();
+        else if (rStyle[i].Name == "tcPr")
+            aTcPr = rStyle[i].Value.get< uno::Sequence<beans::PropertyValue> >();
+        else if (rStyle[i].Name == "tblStylePr")
+            aTblStylePrs.push_back(rStyle[i].Value.get< uno::Sequence<beans::PropertyValue> >());
+    }
+
+    sax_fastparser::FastAttributeList* pAttributeList = m_pSerializer->createAttrList();
+    pAttributeList->add(FSNS(XML_w, XML_type), "table");
+    if (bDefault)
+        pAttributeList->add(FSNS(XML_w, XML_default), "1");
+    if (bCustomStyle)
+        pAttributeList->add(FSNS(XML_w, XML_customStyle), "1");
+    if (!aStyleId.isEmpty())
+        pAttributeList->add(FSNS(XML_w, XML_styleId), OUStringToOString(aStyleId, RTL_TEXTENCODING_UTF8).getStr());
+    sax_fastparser::XFastAttributeListRef xAttributeList(pAttributeList);
+    m_pSerializer->startElementNS(XML_w, XML_style, xAttributeList);
+
+    m_pSerializer->singleElementNS(XML_w, XML_name,
+            FSNS(XML_w, XML_val), OUStringToOString(aName, RTL_TEXTENCODING_UTF8).getStr(),
+            FSEND);
+    if (!aBasedOn.isEmpty())
+        m_pSerializer->singleElementNS(XML_w, XML_basedOn,
+                FSNS(XML_w, XML_val), OUStringToOString(aBasedOn, RTL_TEXTENCODING_UTF8).getStr(),
+                FSEND);
+    if (nUiPriority)
+        m_pSerializer->singleElementNS(XML_w, XML_uiPriority,
+                FSNS(XML_w, XML_val), OString::number(nUiPriority),
+                FSEND);
+    if (bQFormat)
+        m_pSerializer->singleElementNS(XML_w, XML_qFormat, FSEND);
+    if (bSemiHidden)
+        m_pSerializer->singleElementNS(XML_w, XML_semiHidden, FSEND);
+    if (bUnhideWhenUsed)
+        m_pSerializer->singleElementNS(XML_w, XML_unhideWhenUsed, FSEND);
+    if (nRsid)
+    {
+        // We want the rsid as a hex string, but always with the length of 8.
+        OStringBuffer aBuf = OString::number(nRsid, 16);
+        OStringBuffer aStr;
+        comphelper::string::padToLength(aStr, 8 - aBuf.getLength(), '0');
+        aStr.append(aBuf.getStr());
+        m_pSerializer->singleElementNS(XML_w, XML_rsid,
+                FSNS(XML_w, XML_val), aStr.getStr(),
+                FSEND);
+    }
+
+    lcl_TableStylePPr(m_pSerializer, aPPr);
+    lcl_TableStyleRPr(m_pSerializer, aRPr);
+    lcl_TableStyleTblPr(m_pSerializer, aTblPr);
+    lcl_TableStyleTcPr(m_pSerializer, aTcPr);
+    for (size_t i = 0; i < aTblStylePrs.size(); ++i)
+        lcl_TableStyleTblStylePr(m_pSerializer, aTblStylePrs[i]);
+
+    m_pSerializer->endElementNS(XML_w, XML_style);
+}
+
+void DocxTableStyleExport::SetSerializer(sax_fastparser::FSHelperPtr pSerializer)
+{
+    m_pImpl->m_pSerializer = pSerializer;
+}
+
+DocxTableStyleExport::DocxTableStyleExport(SwDoc* pDoc, sax_fastparser::FSHelperPtr pSerializer)
+    : m_pImpl(new Impl)
+{
+    m_pImpl->m_pDoc = pDoc;
+    m_pImpl->m_pSerializer = pSerializer;
+}
+
+DocxTableStyleExport::~DocxTableStyleExport()
+{
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sw/source/filter/ww8/docxtablestyleexport.hxx b/sw/source/filter/ww8/docxtablestyleexport.hxx
new file mode 100644
index 0000000..c66372e
--- /dev/null
+++ b/sw/source/filter/ww8/docxtablestyleexport.hxx
@@ -0,0 +1,32 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ */
+
+#ifndef _DOCXTABLESTYLEXPORT_HXX_
+#define _DOCXTABLESTYLEXPORT_HXX_
+
+#include <boost/shared_ptr.hpp>
+#include <sax/fshelper.hxx>
+
+class SwDoc;
+
+/// Handles DOCX export of table styles, based on InteropGrabBag.
+class DocxTableStyleExport
+{
+    class Impl;
+    boost::shared_ptr<Impl> m_pImpl;
+public:
+    void TableStyles();
+    void SetSerializer(sax_fastparser::FSHelperPtr pSerializer);
+    DocxTableStyleExport(SwDoc* pDoc, sax_fastparser::FSHelperPtr pSerializer);
+    ~DocxTableStyleExport();
+};
+
+#endif // _DOCXTABLESTYLEXPORT_HXX_
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
commit 0501d66d7ea4d91a0542b8d16b873461d4e9b13d
Author: Miklos Vajna <vmiklos at collabora.co.uk>
Date:   Wed Oct 30 12:18:29 2013 +0100

    DOCX export: initial w:tblStylePr handling
    
    Change-Id: Ib368d558913149d7489ed320b459b66d3b1279a0

diff --git a/sw/source/filter/ww8/docxattributeoutput.cxx b/sw/source/filter/ww8/docxattributeoutput.cxx
index 9fb6f67..91b95fb 100644
--- a/sw/source/filter/ww8/docxattributeoutput.cxx
+++ b/sw/source/filter/ww8/docxattributeoutput.cxx
@@ -2902,12 +2902,53 @@ void lcl_TableStyleTcPr(sax_fastparser::FSHelperPtr pSerializer, uno::Sequence<b
     pSerializer->endElementNS(XML_w, XML_tcPr);
 }
 
+/// Export of w:tblStylePr in a table style.
+void lcl_TableStyleTblStylePr(sax_fastparser::FSHelperPtr pSerializer, uno::Sequence<beans::PropertyValue>& rTblStylePr)
+{
+    if (!rTblStylePr.hasElements())
+        return;
+
+    OUString aType;
+    uno::Sequence<beans::PropertyValue> aPPr, aRPr, aTblPr, aTcPr;
+    for (sal_Int32 i = 0; i < rTblStylePr.getLength(); ++i)
+    {
+        if (rTblStylePr[i].Name == "type")
+            aType = rTblStylePr[i].Value.get<OUString>();
+        else if (rTblStylePr[i].Name == "pPr")
+            aPPr = rTblStylePr[i].Value.get< uno::Sequence<beans::PropertyValue> >();
+        else if (rTblStylePr[i].Name == "rPr")
+            aRPr = rTblStylePr[i].Value.get< uno::Sequence<beans::PropertyValue> >();
+        else if (rTblStylePr[i].Name == "tblPr")
+            aTblPr = rTblStylePr[i].Value.get< uno::Sequence<beans::PropertyValue> >();
+        else if (rTblStylePr[i].Name == "tcPr")
+            aTcPr = rTblStylePr[i].Value.get< uno::Sequence<beans::PropertyValue> >();
+    }
+
+    pSerializer->startElementNS(XML_w, XML_tblStylePr,
+            FSNS(XML_w, XML_type), OUStringToOString(aType, RTL_TEXTENCODING_UTF8).getStr(),
+            FSEND);
+
+    lcl_TableStylePPr(pSerializer, aPPr);
+    lcl_TableStyleRPr(pSerializer, aRPr);
+    if (aTblPr.hasElements())
+        lcl_TableStyleTblPr(pSerializer, aTblPr);
+    else
+    {
+        // Even if we have an empty container, write it out, as Word does.
+        pSerializer->singleElementNS(XML_w, XML_tblPr, FSEND);
+    }
+    lcl_TableStyleTcPr(pSerializer, aTcPr);
+
+    pSerializer->endElementNS(XML_w, XML_tblStylePr);
+}
+
 void DocxAttributeOutput::TableStyle(uno::Sequence<beans::PropertyValue>& rStyle)
 {
     bool bDefault = false, bCustomStyle = false, bQFormat = false, bSemiHidden = false, bUnhideWhenUsed = false;
     OUString aStyleId, aName, aBasedOn;
     sal_Int32 nUiPriority = 0, nRsid = 0;
     uno::Sequence<beans::PropertyValue> aPPr, aRPr, aTblPr, aTcPr;
+    std::vector< uno::Sequence<beans::PropertyValue> > aTblStylePrs;
     for (sal_Int32 i = 0; i < rStyle.getLength(); ++i)
     {
         if (rStyle[i].Name == "default")
@@ -2938,6 +2979,8 @@ void DocxAttributeOutput::TableStyle(uno::Sequence<beans::PropertyValue>& rStyle
             aTblPr = rStyle[i].Value.get< uno::Sequence<beans::PropertyValue> >();
         else if (rStyle[i].Name == "tcPr")
             aTcPr = rStyle[i].Value.get< uno::Sequence<beans::PropertyValue> >();
+        else if (rStyle[i].Name == "tblStylePr")
+            aTblStylePrs.push_back(rStyle[i].Value.get< uno::Sequence<beans::PropertyValue> >());
     }
 
     sax_fastparser::FastAttributeList* pAttributeList = m_pSerializer->createAttrList();
@@ -2984,6 +3027,8 @@ void DocxAttributeOutput::TableStyle(uno::Sequence<beans::PropertyValue>& rStyle
     lcl_TableStyleRPr(m_pSerializer, aRPr);
     lcl_TableStyleTblPr(m_pSerializer, aTblPr);
     lcl_TableStyleTcPr(m_pSerializer, aTcPr);
+    for (size_t i = 0; i < aTblStylePrs.size(); ++i)
+        lcl_TableStyleTblStylePr(m_pSerializer, aTblStylePrs[i]);
 
     m_pSerializer->endElementNS(XML_w, XML_style);
 }


More information about the Libreoffice-commits mailing list