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
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.
*/
::sax_fastparser::FSHelperPtr
openFragmentStreamWithSerializer(
const OUString& rStreamName,
const OUString& rMediaType );
const OUString& rMediaType,
bool bNoHeader = false);
/** Returns new unique ID for exported document.

View File

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

View File

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

View File

@ -162,6 +162,9 @@ public:
explicit ChartexTypeGroupContext( ::oox::core::ContextHandler2Helper& rParent, TypeGroupModel& rModel );
virtual ~ChartexTypeGroupContext() override;
// Explicitly create a new series
void CreateSeries();
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;
}
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 );
}

View File

@ -211,8 +211,34 @@ ContextHandlerRef PlotAreaContext::onCreateContext( sal_Int32 nElement, const At
}
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 ) );
rTGCtx->CreateSeries();
return rTGCtx;
}
break;

View File

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

View File

@ -50,6 +50,7 @@ ContextHandlerRef TextContext::onCreateContext( sal_Int32 nElement, const Attrib
if( isCurrentElement( C_TOKEN( tx ) ) ) switch( nElement )
{
case C_TOKEN( rich ):
case CX_TOKEN( rich ):
return new TextBodyContext( *this, mrModel.mxTextBody.create() );
case C_TOKEN( strRef ):
@ -57,8 +58,14 @@ ContextHandlerRef TextContext::onCreateContext( sal_Int32 nElement, const Attrib
return new StringSequenceContext( *this, mrModel.mxDataSeq.create() );
case C_TOKEN( v ):
case CX_TOKEN( v ):
OSL_ENSURE( !mrModel.mxDataSeq, "TextContext::onCreateContext - multiple data sequences" );
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;
}

View File

@ -405,10 +405,24 @@ ChartexTypeGroupContext::~ChartexTypeGroupContext()
{
}
void ChartexTypeGroupContext::CreateSeries()
{
mrModel.maSeries.create(false);
}
ContextHandlerRef ChartexTypeGroupContext::onCreateContext( [[maybe_unused]] sal_Int32 nElement,
[[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

View File

@ -162,8 +162,78 @@ private:
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 )
{
bHasDateCategories = false;
@ -982,7 +1052,114 @@ void ChartExport::WriteChartObj( const Reference< XShape >& xShape, sal_Int32 nI
SetFS( pChart );
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();
}
@ -1117,6 +1294,8 @@ void ChartExport::exportData( [[maybe_unused]] const Reference< css::chart::XCha
if (bIsChartex) {
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");
// Just hard-coding this for now
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);
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 OUString& sContentType,
const OUString& sRelationshipType,
OUString* pRelationshipId )
OUString* pRelationshipId,
// if bNoHeader is true, don't create a header (<?xml... ) line
bool bNoHeader /* = false */ )
{
OUString sRelationshipId;
if (xParentRelation.is())
@ -5578,7 +5580,8 @@ sax_fastparser::FSHelperPtr DrawingML::CreateOutputStream (
if( pRelationshipId )
*pRelationshipId = sRelationshipId;
sax_fastparser::FSHelperPtr p = GetFB()->openFragmentStreamWithSerializer( sFullStream, sContentType );
sax_fastparser::FSHelperPtr p = GetFB()->openFragmentStreamWithSerializer(
sFullStream, sContentType, bNoHeader );
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
x12ac http://schemas.microsoft.com/office/spreadsheetml/2011/1/ac
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
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
cs http://schemas.microsoft.com/office/drawing/2012/chartStyle
# 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
x12ac http://schemas.microsoft.com/office/spreadsheetml/2011/1/ac
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
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
cs http://schemas.microsoft.com/office/drawing/2012/chartStyle
# MSO 2014 extensions ---------------------------------------------------------

View File

@ -1,6 +1,8 @@
{Relationship::ACTIVEXCONTROLBINARY, u"http://schemas.microsoft.com/office/2006/relationships/activeXControlBinary"},
{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::CHARTSTYLE, u"http://schemas.microsoft.com/office/2011/relationships/chartStyle"},
{Relationship::CHARTUSERSHAPES, u"http://schemas.openxmlformats.org/officeDocument/2006/relationships/chartUserShapes"},
{Relationship::COMMENTS, u"http://schemas.openxmlformats.org/officeDocument/2006/relationships/comments"},
{Relationship::COMMENTAUTHORS, u"http://schemas.openxmlformats.org/officeDocument/2006/relationships/commentAuthors"},

View File

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

View File

@ -844,7 +844,14 @@ void ExcDocument::WriteXml( XclExpXmlStream& rStrm )
sax_fastparser::FSHelperPtr& rWorkbook = rStrm.GetCurrentStream();
rWorkbook->startElement( XML_workbook,
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,
XML_appName, "Calc"
// OOXTODO: XML_codeName

View File

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

View File

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