tdf#165742 Step 4.3: Establish a narrow export path for chartex

This is a subtask of tdf#165742: Chartex charts are lost on input from OOXML
and re-export.

Fix various aspects of input and output for chartex (and specifically
for funnel charts). This now allows for loading and re-exporting a
very basic funnel chart, with the result that MS Office successfully
loads the exported chart, and it looks similar (though not quite
identical) to the original.

Change-Id: I6eeb277e31250031604f7cdd21b80848a9c642ca
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/184758
Reviewed-by: Tomaž Vajngerl <quikee@gmail.com>
Tested-by: Jenkins
This commit is contained in:
knordback 2025-04-22 11:09:50 -06:00 committed by Tomaž Vajngerl
parent fda2cfeb8e
commit 95b2c8b82e
18 changed files with 330 additions and 24 deletions

View File

@ -201,12 +201,17 @@ public:
The media type string, used in [Content_Types].xml stream in base The media type string, used in [Content_Types].xml stream in base
storage. storage.
@param bNoHeader
If true, do not include a header line in the output. If false,
potentially include a header line based on the media type string.
@return newly created serializer helper. @return newly created serializer helper.
*/ */
::sax_fastparser::FSHelperPtr ::sax_fastparser::FSHelperPtr
openFragmentStreamWithSerializer( openFragmentStreamWithSerializer(
const OUString& rStreamName, const OUString& rStreamName,
const OUString& rMediaType ); const OUString& rMediaType,
bool bNoHeader = false);
/** Returns new unique ID for exported document. /** Returns new unique ID for exported document.

View File

@ -525,7 +525,8 @@ public:
const css::uno::Reference< css::io::XOutputStream >& xParentRelation, const css::uno::Reference< css::io::XOutputStream >& xParentRelation,
const OUString& sContentType, const OUString& sContentType,
const OUString& sRelationshipType, const OUString& sRelationshipType,
OUString* pRelationshipId ); OUString* pRelationshipId,
bool bNoHeader = false); // Don't write a <?xml... header line
OOX_DLLPUBLIC std::shared_ptr<GraphicExport> createGraphicExport(); OOX_DLLPUBLIC std::shared_ptr<GraphicExport> createGraphicExport();
}; };

View File

@ -20,7 +20,9 @@ enum class Relationship
{ {
ACTIVEXCONTROLBINARY, ACTIVEXCONTROLBINARY,
CHART, CHART,
CHARTCOLORSTYLE, // for chartex
CHARTEX, CHARTEX,
CHARTSTYLE, // for chartex
CHARTUSERSHAPES, CHARTUSERSHAPES,
COMMENTS, COMMENTS,
COMMENTAUTHORS, COMMENTAUTHORS,

View File

@ -162,6 +162,9 @@ public:
explicit ChartexTypeGroupContext( ::oox::core::ContextHandler2Helper& rParent, TypeGroupModel& rModel ); explicit ChartexTypeGroupContext( ::oox::core::ContextHandler2Helper& rParent, TypeGroupModel& rModel );
virtual ~ChartexTypeGroupContext() override; virtual ~ChartexTypeGroupContext() override;
// Explicitly create a new series
void CreateSeries();
virtual ::oox::core::ContextHandlerRef onCreateContext( sal_Int32 nElement, const AttributeList& rAttribs ) override; virtual ::oox::core::ContextHandlerRef onCreateContext( sal_Int32 nElement, const AttributeList& rAttribs ) override;
}; };

View File

@ -508,9 +508,10 @@ Reference< XOutputStream > XmlFilterBase::openFragmentStream( const OUString& rS
return xOutputStream; return xOutputStream;
} }
FSHelperPtr XmlFilterBase::openFragmentStreamWithSerializer( const OUString& rStreamName, const OUString& rMediaType ) FSHelperPtr XmlFilterBase::openFragmentStreamWithSerializer(
const OUString& rStreamName, const OUString& rMediaType, bool bNoHeader /* = false */)
{ {
const bool bWriteHeader = rMediaType.indexOf( "vml" ) < 0 || rMediaType.indexOf( "+xml" ) >= 0; const bool bWriteHeader = !bNoHeader && (rMediaType.indexOf( "vml" ) < 0 || rMediaType.indexOf( "+xml" ) >= 0);
return std::make_shared<FastSerializerHelper>( openFragmentStream( rStreamName, rMediaType ), bWriteHeader ); return std::make_shared<FastSerializerHelper>( openFragmentStream( rStreamName, rMediaType ), bWriteHeader );
} }

View File

@ -211,8 +211,34 @@ ContextHandlerRef PlotAreaContext::onCreateContext( sal_Int32 nElement, const At
} }
assert(nChartType != 0); assert(nChartType != 0);
return new ChartexTypeGroupContext( *this, // This is a little awkward. The existing parsing
// structures are set up for the ECMA-376 charts, which
// are structured in the XML as
// ...
// <c:plotArea>
// <c:barChart> (or whatever)
// <c:series ... />
// <c:barChart/>
// <c:plotArea/>
//
// By contrast, chartex is like this:
// ...
// <cx:plotArea>
// <cx:plotAreaRegion>
// <cx:series layoutId="funnel" ... /> (or other chart type)
// <cx:plotAreaRegion/>
// <cx:plotArea/>
//
// The best way I've figured out to bridge this
// difference is via the explicit CreateSeries() call
// below, since the structure wants a TypeGroup but
// we're already in the series handling. There may well
// be a better solution.
rtl::Reference<ChartexTypeGroupContext> rTGCtx = new ChartexTypeGroupContext( *this,
mrModel.maTypeGroups.create( nChartType, false ) ); mrModel.maTypeGroups.create( nChartType, false ) );
rTGCtx->CreateSeries();
return rTGCtx;
} }
break; break;

View File

@ -49,6 +49,7 @@ ContextHandlerRef lclDataLabelSharedCreateContext( ContextHandler2& rContext,
orModel.monLabelPos = rAttribs.getToken( XML_val, XML_TOKEN_INVALID ); orModel.monLabelPos = rAttribs.getToken( XML_val, XML_TOKEN_INVALID );
return nullptr; return nullptr;
case C_TOKEN( numFmt ): case C_TOKEN( numFmt ):
case CX_TOKEN( numFmt ):
orModel.maNumberFormat.setAttributes( rAttribs ); orModel.maNumberFormat.setAttributes( rAttribs );
return nullptr; return nullptr;
case C_TOKEN( showBubbleSize ): case C_TOKEN( showBubbleSize ):
@ -70,19 +71,25 @@ ContextHandlerRef lclDataLabelSharedCreateContext( ContextHandler2& rContext,
orModel.mobShowVal = rAttribs.getBool( XML_val ); orModel.mobShowVal = rAttribs.getBool( XML_val );
return nullptr; return nullptr;
case C_TOKEN( separator ): case C_TOKEN( separator ):
case CX_TOKEN( separator ):
// collect separator text in onCharacters() // collect separator text in onCharacters()
return &rContext; return &rContext;
case C_TOKEN( spPr ): case C_TOKEN( spPr ):
case CX_TOKEN( spPr ):
return new ShapePropertiesContext( rContext, orModel.mxShapeProp.create() ); return new ShapePropertiesContext( rContext, orModel.mxShapeProp.create() );
case C_TOKEN( txPr ): case C_TOKEN( txPr ):
case CX_TOKEN( txPr ):
return new TextBodyContext( rContext, orModel.mxTextProp.create() ); return new TextBodyContext( rContext, orModel.mxTextProp.create() );
case CX_TOKEN( visibility ):
return nullptr; // TODO
} }
return nullptr; return nullptr;
} }
void lclDataLabelSharedCharacters( ContextHandler2 const & rContext, const OUString& rChars, DataLabelModelBase& orModel ) void lclDataLabelSharedCharacters( ContextHandler2 const & rContext, const OUString& rChars, DataLabelModelBase& orModel )
{ {
if( rContext.isCurrentElement( C_TOKEN( separator ) ) ) if( rContext.isCurrentElement( C_TOKEN( separator ) ) ||
rContext.isCurrentElement( CX_TOKEN( separator ) ) )
orModel.moaSeparator = rChars; orModel.moaSeparator = rChars;
} }
@ -132,6 +139,7 @@ ContextHandlerRef DataLabelContext::onCreateContext( sal_Int32 nElement, const A
else if (nElement == C15_TOKEN(layout)) else if (nElement == C15_TOKEN(layout))
return new LayoutContext(*this, mrModel.mxLayout.getOrCreate()); return new LayoutContext(*this, mrModel.mxLayout.getOrCreate());
break; break;
// Not sure how to handle <cx:extLst> and <cx:ext>. TODO
} }
} }
bool bMSO2007 = getFilter().isMSO2007Document(); bool bMSO2007 = getFilter().isMSO2007Document();
@ -761,11 +769,9 @@ ContextHandlerRef ChartexSeriesContext::onCreateContext( sal_Int32 nElement, con
switch( getCurrentElement() ) switch( getCurrentElement() )
{ {
case CX_TOKEN( tx ): case CX_TOKEN( tx ):
// TODO return new TextContext( *this, mrModel.mxText.create() );
return nullptr;
case CX_TOKEN( spPr ): case CX_TOKEN( spPr ):
// TODO return new ShapePropertiesContext( *this, mrModel.mxShapeProp.create() );
return nullptr;
case CX_TOKEN( valueColors ): case CX_TOKEN( valueColors ):
// TODO // TODO
return nullptr; return nullptr;
@ -773,16 +779,14 @@ ContextHandlerRef ChartexSeriesContext::onCreateContext( sal_Int32 nElement, con
// TODO // TODO
return nullptr; return nullptr;
case CX_TOKEN( dataPt ): case CX_TOKEN( dataPt ):
// TODO return new DataPointContext( *this, mrModel.maPoints.create(false) );
return nullptr;
case CX_TOKEN( dataLabels ): case CX_TOKEN( dataLabels ):
// TODO return new DataLabelsContext( *this, mrModel.mxLabels.create(false) );
return nullptr;
case CX_TOKEN( dataId ): case CX_TOKEN( dataId ):
// TODO // TODO
return nullptr; return nullptr;
case CX_TOKEN( layoutPr ): case CX_TOKEN( layoutPr ):
// TODO // This looks complicated. TODO
return nullptr; return nullptr;
case CX_TOKEN( axisId ): case CX_TOKEN( axisId ):
// TODO // TODO

View File

@ -50,6 +50,7 @@ ContextHandlerRef TextContext::onCreateContext( sal_Int32 nElement, const Attrib
if( isCurrentElement( C_TOKEN( tx ) ) ) switch( nElement ) if( isCurrentElement( C_TOKEN( tx ) ) ) switch( nElement )
{ {
case C_TOKEN( rich ): case C_TOKEN( rich ):
case CX_TOKEN( rich ):
return new TextBodyContext( *this, mrModel.mxTextBody.create() ); return new TextBodyContext( *this, mrModel.mxTextBody.create() );
case C_TOKEN( strRef ): case C_TOKEN( strRef ):
@ -57,8 +58,14 @@ ContextHandlerRef TextContext::onCreateContext( sal_Int32 nElement, const Attrib
return new StringSequenceContext( *this, mrModel.mxDataSeq.create() ); return new StringSequenceContext( *this, mrModel.mxDataSeq.create() );
case C_TOKEN( v ): case C_TOKEN( v ):
case CX_TOKEN( v ):
OSL_ENSURE( !mrModel.mxDataSeq, "TextContext::onCreateContext - multiple data sequences" ); OSL_ENSURE( !mrModel.mxDataSeq, "TextContext::onCreateContext - multiple data sequences" );
return this; // collect value in onCharacters() return this; // collect value in onCharacters()
case CX_TOKEN( txData ):
// CT_TextData can have a <cx:v> element or a sequence
// <cx:f> <cx:v>. The former case will be handled through the
// CX_TOKEN(v) above, but the latter is not handled. TODO
return this;
} }
return nullptr; return nullptr;
} }

View File

@ -405,10 +405,24 @@ ChartexTypeGroupContext::~ChartexTypeGroupContext()
{ {
} }
void ChartexTypeGroupContext::CreateSeries()
{
mrModel.maSeries.create(false);
}
ContextHandlerRef ChartexTypeGroupContext::onCreateContext( [[maybe_unused]] sal_Int32 nElement, ContextHandlerRef ChartexTypeGroupContext::onCreateContext( [[maybe_unused]] sal_Int32 nElement,
[[maybe_unused]] const AttributeList& rAttribs ) [[maybe_unused]] const AttributeList& rAttribs )
{ {
return new ChartexSeriesContext( *this, mrModel.maSeries.create(false) ); if (isRootElement()) switch (nElement) {
case CX_TOKEN(dataLabels):
// TODO
return nullptr;
case CX_TOKEN(dataId):
// TODO
return nullptr;
}
return nullptr;
} }
} // namespace oox::drawingml::chart } // namespace oox::drawingml::chart

View File

@ -162,8 +162,78 @@ private:
OUString m_aRole; OUString m_aRole;
}; };
void outputStyleEntry(FSHelperPtr pFS, sal_Int32 nElTokenId)
{
// Just default values for now
pFS->startElement(FSNS(XML_cs, nElTokenId));
pFS->singleElement(FSNS(XML_cs, XML_lnRef), XML_idx, "0");
pFS->singleElement(FSNS(XML_cs, XML_fillRef), XML_idx, "0");
pFS->singleElement(FSNS(XML_cs, XML_effectRef), XML_idx, "0");
pFS->singleElement(FSNS(XML_cs, XML_fontRef), XML_idx, "minor");
pFS->endElement(FSNS(XML_cs, nElTokenId));
} }
void outputChartAreaStyleEntry(FSHelperPtr pFS)
{
// Just default values for now
pFS->startElement(FSNS(XML_cs, XML_chartArea), XML_mods, "allowNoFillOverride allowNoLineOverride");
pFS->singleElement(FSNS(XML_cs, XML_lnRef), XML_idx, "0");
pFS->singleElement(FSNS(XML_cs, XML_fillRef), XML_idx, "0");
pFS->singleElement(FSNS(XML_cs, XML_effectRef), XML_idx, "0");
pFS->startElement(FSNS(XML_cs, XML_fontRef), XML_idx, "minor");
pFS->singleElement(FSNS(XML_a, XML_schemeClr), XML_val, "tx1");
pFS->endElement(FSNS(XML_cs, XML_fontRef));
pFS->startElement(FSNS(XML_cs, XML_spPr));
pFS->startElement(FSNS(XML_a, XML_solidFill));
pFS->singleElement(FSNS(XML_a, XML_schemeClr), XML_val, "bg1");
pFS->endElement(FSNS(XML_a, XML_solidFill));
pFS->startElement(FSNS(XML_a, XML_ln), XML_w, "9525", XML_cap, "flat",
XML_cmpd, "sng", XML_algn, "ctr");
pFS->startElement(FSNS(XML_a, XML_solidFill));
pFS->startElement(FSNS(XML_a, XML_schemeClr), XML_val, "tx1");
pFS->singleElement(FSNS(XML_a, XML_lumMod), XML_val, "15000");
pFS->singleElement(FSNS(XML_a, XML_lumOff), XML_val, "85000");
pFS->endElement(FSNS(XML_a, XML_schemeClr));
pFS->endElement(FSNS(XML_a, XML_solidFill));
pFS->singleElement(FSNS(XML_a, XML_round));
pFS->endElement(FSNS(XML_a, XML_ln));
pFS->endElement(FSNS(XML_cs, XML_spPr));
pFS->endElement(FSNS(XML_cs, XML_chartArea));
}
void outputDataPointStyleEntry(FSHelperPtr pFS)
{
pFS->startElement(FSNS(XML_cs, XML_dataPoint));
pFS->singleElement(FSNS(XML_cs, XML_lnRef), XML_idx, "0");
pFS->startElement(FSNS(XML_cs, XML_fillRef), XML_idx, "0");
pFS->singleElement(FSNS(XML_cs, XML_styleClr), XML_val, "auto");
pFS->endElement(FSNS(XML_cs, XML_fillRef));
pFS->singleElement(FSNS(XML_cs, XML_effectRef), XML_idx, "0");
pFS->startElement(FSNS(XML_cs, XML_fontRef), XML_idx, "minor");
pFS->singleElement(FSNS(XML_cs, XML_schemeClr), XML_val, "tx1");
pFS->endElement(FSNS(XML_cs, XML_fontRef));
pFS->startElement(FSNS(XML_cs, XML_spPr));
pFS->startElement(FSNS(XML_a, XML_solidFill));
pFS->singleElement(FSNS(XML_a, XML_schemeClr), XML_val, "phClr");
pFS->endElement(FSNS(XML_a, XML_solidFill));
pFS->endElement(FSNS(XML_cs, XML_spPr));
pFS->endElement(FSNS(XML_cs, XML_dataPoint));
}
} // unnamed namespace
static Reference< chart2::data::XLabeledDataSequence > lcl_getCategories( const Reference< chart2::XDiagram > & xDiagram, bool& bHasDateCategories ) static Reference< chart2::data::XLabeledDataSequence > lcl_getCategories( const Reference< chart2::XDiagram > & xDiagram, bool& bHasDateCategories )
{ {
bHasDateCategories = false; bHasDateCategories = false;
@ -982,7 +1052,114 @@ void ChartExport::WriteChartObj( const Reference< XShape >& xShape, sal_Int32 nI
SetFS( pChart ); SetFS( pChart );
ExportContent(); ExportContent();
SetFS( pFS );
if (bIsChartex) {
SetFS( pChart );
sRelativePath ="";
FSHelperPtr pChartFS = GetFS();
// output style and colorstyle files
// first style
static constexpr char sStyleFnamePrefix[] = "style";
OUStringBuffer sFullStreamBuf;
sFullStreamBuf.appendAscii(sFullPath);
sFullStreamBuf = sFullStreamBuf + sStyleFnamePrefix + OUString::number(nChartCount) + ".xml";
sFullStream = sFullStreamBuf.makeStringAndClear();
OUStringBuffer sRelativeStreamBuf;
sRelativeStreamBuf.appendAscii(sRelativePath);
sRelativeStreamBuf = sRelativeStreamBuf + sStyleFnamePrefix + OUString::number(nChartCount) + ".xml";
sRelativeStream = sRelativeStreamBuf.makeStringAndClear();
FSHelperPtr pStyle = CreateOutputStream(
sFullStream,
sRelativeStream,
pChartFS->getOutputStream(),
u"application/vnd.ms-office.chartstyle+xml"_ustr,
oox::getRelationship(Relationship::CHARTSTYLE),
&sId,
true /* for some reason this doesn't have a header line */);
SetFS( pStyle );
pFS = GetFS();
pFS->startElement(FSNS(XML_cs, XML_chartStyle),
FSNS( XML_xmlns, XML_cs ), pFB->getNamespaceURL(OOX_NS(cs)),
FSNS( XML_xmlns, XML_a ), pFB->getNamespaceURL(OOX_NS(dml)),
XML_id, "419" /* no idea what this number is supposed to be */);
outputStyleEntry(pFS, XML_axisTitle);;
outputStyleEntry(pFS, XML_categoryAxis);
outputChartAreaStyleEntry(pFS);
outputStyleEntry(pFS, XML_dataLabel);
outputDataPointStyleEntry(pFS);
outputStyleEntry(pFS, XML_dataPoint3D);
outputStyleEntry(pFS, XML_dataPointLine);
outputStyleEntry(pFS, XML_dataPointMarker);
outputStyleEntry(pFS, XML_dataPointWireframe);
outputStyleEntry(pFS, XML_dataTable);
outputStyleEntry(pFS, XML_downBar);
outputStyleEntry(pFS, XML_dropLine);
outputStyleEntry(pFS, XML_errorBar);
outputStyleEntry(pFS, XML_floor);
outputStyleEntry(pFS, XML_gridlineMajor);
outputStyleEntry(pFS, XML_gridlineMinor);
outputStyleEntry(pFS, XML_hiLoLine);
outputStyleEntry(pFS, XML_leaderLine);
outputStyleEntry(pFS, XML_legend);
outputStyleEntry(pFS, XML_plotArea);
outputStyleEntry(pFS, XML_plotArea3D);
outputStyleEntry(pFS, XML_seriesAxis);
outputStyleEntry(pFS, XML_seriesLine);
outputStyleEntry(pFS, XML_title);
outputStyleEntry(pFS, XML_trendline);
outputStyleEntry(pFS, XML_trendlineLabel);
outputStyleEntry(pFS, XML_upBar);
outputStyleEntry(pFS, XML_valueAxis);
outputStyleEntry(pFS, XML_wall);
pFS->endElement(FSNS(XML_cs, XML_chartStyle));
pStyle->endDocument();
// now colorstyle
static constexpr char sColorFnamePrefix[] = "colors";
sFullStreamBuf = OUStringBuffer();
sFullStreamBuf.appendAscii(sFullPath);
sFullStreamBuf = sFullStreamBuf + sColorFnamePrefix + OUString::number(nChartCount) + ".xml";
sFullStream = sFullStreamBuf.makeStringAndClear();
sRelativeStreamBuf = OUStringBuffer();
sRelativeStreamBuf.appendAscii(sRelativePath);
sRelativeStreamBuf = sRelativeStreamBuf + sColorFnamePrefix + OUString::number(nChartCount) + ".xml";
sRelativeStream = sRelativeStreamBuf.makeStringAndClear();
FSHelperPtr pColorStyle = CreateOutputStream(
sFullStream,
sRelativeStream,
pChartFS->getOutputStream(),
u"application/vnd.ms-office.chartcolorstyle+xml"_ustr,
oox::getRelationship(Relationship::CHARTCOLORSTYLE),
&sId,
true /* also no header line */);
SetFS( pColorStyle );
pFS = GetFS();
pFS->startElement(FSNS(XML_cs, XML_colorStyle),
FSNS( XML_xmlns, XML_cs ), pFB->getNamespaceURL(OOX_NS(cs)),
FSNS( XML_xmlns, XML_a ), pFB->getNamespaceURL(OOX_NS(dml)),
XML_meth, "cycle",
XML_id, "10" /* no idea what this number is supposed to be */);
pFS->singleElement(FSNS(XML_a, XML_schemeClr),
XML_val, "accent1");
pFS->endElement(FSNS(XML_cs, XML_colorStyle));
pColorStyle->endDocument();
}
pChart->endDocument(); pChart->endDocument();
} }
@ -1117,6 +1294,8 @@ void ChartExport::exportData( [[maybe_unused]] const Reference< css::chart::XCha
if (bIsChartex) { if (bIsChartex) {
FSHelperPtr pFS = GetFS(); FSHelperPtr pFS = GetFS();
// Not sure if the data id is always 0. However, it seems it may need to
// agree with the id in exportSeries(). See DATA_ID_COMMENT
pFS->startElement(FSNS(XML_cx, XML_data), XML_id, "0"); pFS->startElement(FSNS(XML_cx, XML_data), XML_id, "0");
// Just hard-coding this for now // Just hard-coding this for now
pFS->startElement(FSNS(XML_cx, XML_numDim), XML_type, "val"); pFS->startElement(FSNS(XML_cx, XML_numDim), XML_type, "val");
@ -3127,6 +3306,12 @@ void ChartExport::exportSeries( const Reference<chart2::XChartType>& xChartType,
writeDataLabelsRange(pFS, GetFB(), aDLblsRange); writeDataLabelsRange(pFS, GetFB(), aDLblsRange);
pFS->endElement( FSNS( XML_c, XML_ser ) ); pFS->endElement( FSNS( XML_c, XML_ser ) );
} else {
// chartex
// Align the data id here with that in exportData().
// See DATA_ID_COMMENT
pFS->singleElement(FSNS(XML_cx, XML_dataId), XML_val, "0");
} }
} }
} }

View File

@ -5567,7 +5567,9 @@ sax_fastparser::FSHelperPtr DrawingML::CreateOutputStream (
const Reference< XOutputStream >& xParentRelation, const Reference< XOutputStream >& xParentRelation,
const OUString& sContentType, const OUString& sContentType,
const OUString& sRelationshipType, const OUString& sRelationshipType,
OUString* pRelationshipId ) OUString* pRelationshipId,
// if bNoHeader is true, don't create a header (<?xml... ) line
bool bNoHeader /* = false */ )
{ {
OUString sRelationshipId; OUString sRelationshipId;
if (xParentRelation.is()) if (xParentRelation.is())
@ -5578,7 +5580,8 @@ sax_fastparser::FSHelperPtr DrawingML::CreateOutputStream (
if( pRelationshipId ) if( pRelationshipId )
*pRelationshipId = sRelationshipId; *pRelationshipId = sRelationshipId;
sax_fastparser::FSHelperPtr p = GetFB()->openFragmentStreamWithSerializer( sFullStream, sContentType ); sax_fastparser::FSHelperPtr p = GetFB()->openFragmentStreamWithSerializer(
sFullStream, sContentType, bNoHeader );
return p; return p;
} }

View File

@ -91,8 +91,13 @@ w15 http://schemas.microsoft.com/office/word/2012/wordml
p15 http://schemas.microsoft.com/office/powerpoint/2012/main p15 http://schemas.microsoft.com/office/powerpoint/2012/main
x12ac http://schemas.microsoft.com/office/spreadsheetml/2011/1/ac x12ac http://schemas.microsoft.com/office/spreadsheetml/2011/1/ac
c15 http://schemas.microsoft.com/office/drawing/2012/chart c15 http://schemas.microsoft.com/office/drawing/2012/chart
x15 http://schemas.microsoft.com/office/spreadsheetml/2010/11/main
xr http://schemas.microsoft.com/office/spreadsheetml/2014/revision
xr2 http://schemas.microsoft.com/office/spreadsheetml/2015/revision2 xr2 http://schemas.microsoft.com/office/spreadsheetml/2015/revision2
xr6 http://schemas.microsoft.com/office/spreadsheetml/2016/revision6
xr10 http://schemas.microsoft.com/office/spreadsheetml/2016/revision10
xr16 http://schemas.microsoft.com/office/spreadsheetml/2017/revision16 xr16 http://schemas.microsoft.com/office/spreadsheetml/2017/revision16
cs http://schemas.microsoft.com/office/drawing/2012/chartStyle
# MSO 2014 extensions --------------------------------------------------------- # MSO 2014 extensions ---------------------------------------------------------

View File

@ -89,8 +89,13 @@ w15 http://schemas.microsoft.com/office/word/2012/wordml
p15 http://schemas.microsoft.com/office/powerpoint/2012/main p15 http://schemas.microsoft.com/office/powerpoint/2012/main
x12ac http://schemas.microsoft.com/office/spreadsheetml/2011/1/ac x12ac http://schemas.microsoft.com/office/spreadsheetml/2011/1/ac
c15 http://schemas.microsoft.com/office/drawing/2012/chart c15 http://schemas.microsoft.com/office/drawing/2012/chart
x15 http://schemas.microsoft.com/office/spreadsheetml/2010/11/main
xr http://schemas.microsoft.com/office/spreadsheetml/2014/revision
xr2 http://schemas.microsoft.com/office/spreadsheetml/2015/revision2 xr2 http://schemas.microsoft.com/office/spreadsheetml/2015/revision2
xr6 http://schemas.microsoft.com/office/spreadsheetml/2016/revision6
xr10 http://schemas.microsoft.com/office/spreadsheetml/2016/revision10
xr16 http://schemas.microsoft.com/office/spreadsheetml/2017/revision16 xr16 http://schemas.microsoft.com/office/spreadsheetml/2017/revision16
cs http://schemas.microsoft.com/office/drawing/2012/chartStyle
# MSO 2014 extensions --------------------------------------------------------- # MSO 2014 extensions ---------------------------------------------------------

View File

@ -1,6 +1,8 @@
{Relationship::ACTIVEXCONTROLBINARY, u"http://schemas.microsoft.com/office/2006/relationships/activeXControlBinary"}, {Relationship::ACTIVEXCONTROLBINARY, u"http://schemas.microsoft.com/office/2006/relationships/activeXControlBinary"},
{Relationship::CHART, u"http://schemas.openxmlformats.org/officeDocument/2006/relationships/chart"}, {Relationship::CHART, u"http://schemas.openxmlformats.org/officeDocument/2006/relationships/chart"},
{Relationship::CHARTCOLORSTYLE, u"http://schemas.microsoft.com/office/2011/relationships/chartColorStyle"},
{Relationship::CHARTEX, u"http://schemas.microsoft.com/office/2014/relationships/chartEx"}, {Relationship::CHARTEX, u"http://schemas.microsoft.com/office/2014/relationships/chartEx"},
{Relationship::CHARTSTYLE, u"http://schemas.microsoft.com/office/2011/relationships/chartStyle"},
{Relationship::CHARTUSERSHAPES, u"http://schemas.openxmlformats.org/officeDocument/2006/relationships/chartUserShapes"}, {Relationship::CHARTUSERSHAPES, u"http://schemas.openxmlformats.org/officeDocument/2006/relationships/chartUserShapes"},
{Relationship::COMMENTS, u"http://schemas.openxmlformats.org/officeDocument/2006/relationships/comments"}, {Relationship::COMMENTS, u"http://schemas.openxmlformats.org/officeDocument/2006/relationships/comments"},
{Relationship::COMMENTAUTHORS, u"http://schemas.openxmlformats.org/officeDocument/2006/relationships/commentAuthors"}, {Relationship::COMMENTAUTHORS, u"http://schemas.openxmlformats.org/officeDocument/2006/relationships/commentAuthors"},

View File

@ -755,6 +755,7 @@ axisId
axisPage axisPage
axisPosition axisPosition
axisRow axisRow
axisTitle
axisValues axisValues
azure azure
b b
@ -1113,6 +1114,7 @@ catAx
catLst catLst
catalog catalog
category category
categoryAxis
categoryEl categoryEl
categoryIdx categoryIdx
ccw ccw
@ -1175,6 +1177,7 @@ characteristic
charset charset
chart chart
chartAndTx chartAndTx
chartArea
chartData chartData
chartFormat chartFormat
chartFormats chartFormats
@ -1182,6 +1185,7 @@ chartObject
chartPlus chartPlus
chartSpace chartSpace
chartStar chartStar
chartStyle
chartX chartX
chartex chartex
chartreuse chartreuse
@ -1311,6 +1315,7 @@ colorMarkers
colorNegative colorNegative
colorScale colorScale
colorSeries colorSeries
colorStyle
colorTemp colorTemp
colorTemperature colorTemperature
colormenu colormenu
@ -1668,6 +1673,11 @@ dataModel
dataModelExt dataModelExt
dataOnRows dataOnRows
dataOnly dataOnly
dataPoint
dataPoint3D
dataPointLine
dataPointMarker
dataPointWireframe
dataPosition dataPosition
dataPt dataPt
dataRef dataRef
@ -1985,6 +1995,7 @@ doughnutChart
down down
downArrow downArrow
downArrowCallout downArrowCallout
downBar
downBars downBars
downThenOver downThenOver
dpi dpi
@ -2004,6 +2015,7 @@ drill
drop drop
dropCap dropCap
dropDownList dropDownList
dropLine
dropLines dropLines
dropauto dropauto
ds ds
@ -2154,6 +2166,7 @@ errBars
errDir errDir
errValType errValType
error error
errorBar
errorCaption errorCaption
errorStyle errorStyle
errorTitle errorTitle
@ -2563,6 +2576,8 @@ gridLinesSet
gridSize gridSize
gridSpacing gridSpacing
gridSpan gridSpan
gridlineMajor
gridlineMinor
group group
groupBy groupBy
groupChr groupChr
@ -2678,6 +2693,7 @@ hex
hexBinary hexBinary
hexagon hexagon
hf hf
hiLoLine
hiLowLines hiLowLines
hidden hidden
hiddenButton hiddenButton
@ -3044,6 +3060,7 @@ lc
ld ld
le le
leader leader
leaderLine
leaderLines leaderLines
ledger ledger
left left
@ -3484,6 +3501,7 @@ modelId
modern modern
modified modified
modifyVerifier modifyVerifier
mods
mongolianVert mongolianVert
monospace monospace
month month
@ -4072,6 +4090,7 @@ plaqueTabs
plastic plastic
plcHide plcHide
plotArea plotArea
plotArea3D
plotAreaRegion plotAreaRegion
plotSurface plotSurface
plotVisOnly plotVisOnly
@ -4590,8 +4609,10 @@ ser
serAx serAx
serLines serLines
series series
seriesAxis
seriesEl seriesEl
seriesIdx seriesIdx
seriesLine
serverCommand serverCommand
serverField serverField
serverFill serverFill
@ -5054,6 +5075,7 @@ strokeok
strokeweight strokeweight
sty sty
style style
styleClr
styleData styleData
styleDef styleDef
styleDefHdr styleDefHdr
@ -5460,6 +5482,7 @@ trees
trellis trellis
trend trend
trendline trendline
trendlineLabel
trendlineLbl trendlineLbl
trendlineType trendlineType
tri tri
@ -5578,6 +5601,7 @@ unsignedShort
up up
upArrow upArrow
upArrowCallout upArrowCallout
upBar
upBars upBars
upDiag upDiag
upDownArrow upDownArrow
@ -5667,6 +5691,7 @@ vacatedStyle
val val
valAx valAx
value value
valueAxis
valueBetween valueBetween
valueColors valueColors
valueColorPositions valueColorPositions
@ -5749,6 +5774,7 @@ wBefore
wMode wMode
wOff wOff
wR wR
wall
warmMatte warmMatte
warning warning
warp warp
@ -5858,6 +5884,8 @@ wsp
x x
x12ac x12ac
x14 x14
x15
x2
xAlign xAlign
xIllusions xIllusions
xMode xMode
@ -5882,8 +5910,11 @@ xmlDataType
xmlPr xmlPr
xmlns xmlns
xpath xpath
xr2 xr
xr10
xr16 xr16
xr2
xr6
xrange xrange
xsc xsc
xscale xscale

View File

@ -844,7 +844,14 @@ void ExcDocument::WriteXml( XclExpXmlStream& rStrm )
sax_fastparser::FSHelperPtr& rWorkbook = rStrm.GetCurrentStream(); sax_fastparser::FSHelperPtr& rWorkbook = rStrm.GetCurrentStream();
rWorkbook->startElement( XML_workbook, rWorkbook->startElement( XML_workbook,
XML_xmlns, rStrm.getNamespaceURL(OOX_NS(xls)), XML_xmlns, rStrm.getNamespaceURL(OOX_NS(xls)),
FSNS(XML_xmlns, XML_r), rStrm.getNamespaceURL(OOX_NS(officeRel)) ); FSNS(XML_xmlns, XML_r), rStrm.getNamespaceURL(OOX_NS(officeRel)),
// the following are for chartex
FSNS(XML_xmlns, XML_mc), rStrm.getNamespaceURL(OOX_NS(mce)),
FSNS(XML_xmlns, XML_x15), rStrm.getNamespaceURL(OOX_NS(x15)),
FSNS(XML_xmlns, XML_xr), rStrm.getNamespaceURL(OOX_NS(xr)),
FSNS(XML_xmlns, XML_xr6), rStrm.getNamespaceURL(OOX_NS(xr6)),
FSNS(XML_xmlns, XML_xr10), rStrm.getNamespaceURL(OOX_NS(xr10)),
FSNS(XML_xmlns, XML_xr2), rStrm.getNamespaceURL(OOX_NS(xr2)) );
rWorkbook->singleElement( XML_fileVersion, rWorkbook->singleElement( XML_fileVersion,
XML_appName, "Calc" XML_appName, "Calc"
// OOXTODO: XML_codeName // OOXTODO: XML_codeName

View File

@ -956,7 +956,9 @@ sax_fastparser::FSHelperPtr XclExpXmlStream::CreateOutputStream (
const uno::Reference< XOutputStream >& xParentRelation, const uno::Reference< XOutputStream >& xParentRelation,
const char* sContentType, const char* sContentType,
const OUString& sRelationshipType, const OUString& sRelationshipType,
OUString* pRelationshipId ) OUString* pRelationshipId,
// if bNoHeader is true, don't create a header (<?xml... ) line
bool bNoHeader /* = false */ )
{ {
OUString sRelationshipId; OUString sRelationshipId;
if (xParentRelation.is()) if (xParentRelation.is())
@ -967,7 +969,8 @@ sax_fastparser::FSHelperPtr XclExpXmlStream::CreateOutputStream (
if( pRelationshipId ) if( pRelationshipId )
*pRelationshipId = sRelationshipId; *pRelationshipId = sRelationshipId;
sax_fastparser::FSHelperPtr p = openFragmentStreamWithSerializer( sFullStream, OUString::createFromAscii( sContentType ) ); sax_fastparser::FSHelperPtr p = openFragmentStreamWithSerializer(
sFullStream, OUString::createFromAscii( sContentType ), bNoHeader );
maOpenedStreamMap[ sFullStream ] = std::make_pair( sRelationshipId, p ); maOpenedStreamMap[ sFullStream ] = std::make_pair( sRelationshipId, p );

View File

@ -313,7 +313,9 @@ public:
const css::uno::Reference< css::io::XOutputStream >& xParentRelation, const css::uno::Reference< css::io::XOutputStream >& xParentRelation,
const char* sContentType, const char* sContentType,
const OUString& sRelationshipType, const OUString& sRelationshipType,
OUString* pRelationshipId = nullptr ); OUString* pRelationshipId = nullptr,
// if bNoHeader is true, don't create a header (<?xml... ) line
bool bNoHeader = false);
// ignore // ignore
virtual bool exportDocument() override; virtual bool exportDocument() override;