diff options
author | Eike Rathke <erack@redhat.com> | 2015-09-15 16:41:07 +0200 |
---|---|---|
committer | Andras Timar <andras.timar@collabora.com> | 2015-09-17 21:45:31 +0200 |
commit | 6e959437aef14621b74181e50a5fa1422688b176 (patch) | |
tree | dbcf2552f0193b8c61266b9dcef994205c19455f /sc | |
parent | d48ccabe922fcdb28dbbeec17a4ecc2ee9de2404 (diff) |
tdf#61908 OOXML export cell range for matrix/array formula
Problem Description:
- Matrix multiplication cell formula range is not exported after roundtrip.
XML Difference:
Original : <f t="array" ref="G5:G6">MMULT(A1:C2,E1:E3)</f>
Roundtrip : <f aca="false">MMULT(A1:C2,E1:E3)</f>
Solution : Added formula cell range support for matrix multiplication.
Reviewed-on: https://gerrit.libreoffice.org/16033
Reviewed-by: David Tardon <dtardon@redhat.com>
Tested-by: David Tardon <dtardon@redhat.com>
(cherry picked from commit beb8e2830dc9e1c771e196fcaf08cdfd6bf3dde3)
Conflicts:
sc/qa/unit/subsequent_export-test.cxx
Omitted test case and document from commit.
fix 176 unbalanced XML_f xlsx export failuires
regression from
commit beb8e2830dc9e1c771e196fcaf08cdfd6bf3dde3
Author: yogesh.bharate001 <yogesh.bharate@synerzip.com>
Date: Tue Jun 2 16:39:09 2015 +0530
tdf#61908:XLSX formula cell range is not exported for MMULT.
(cherry picked from commit 103b619401f06697255167c788192601e87758b9)
array formulas do not consist only of multiple rows, tdf#61908 follow-up
For example, {={1,2}*3} is a two columns one row vector, or even a
single cell could hold an array formula.
(cherry picked from commit 92df7db85a3da10f18a5a06fb53a9cb69910e835)
a54ce5ce437e592378fe930b779c518de9670995
14a44ac8356fdffc98b7097f48319755f5f2f317
do not write MM_REFERENCE formulas to OOXML, tdf#61908 follow-up
The array range is covered by MM_FORMULA.
Excel even complained when loading such a document.
(cherry picked from commit f501fe4da88e1d64fcc88a492a52911113d28f6a)
Change-Id: Ic871f064a98a324bc16a4253b633c97417c3f900
10e1b19fbfb8ea849ffe3d46504fdf3389633c5f
Reviewed-on: https://gerrit.libreoffice.org/18593
Reviewed-by: Caolán McNamara <caolanm@redhat.com>
Tested-by: Caolán McNamara <caolanm@redhat.com>
Diffstat (limited to 'sc')
-rw-r--r-- | sc/source/filter/excel/xetable.cxx | 93 |
1 files changed, 76 insertions, 17 deletions
diff --git a/sc/source/filter/excel/xetable.cxx b/sc/source/filter/excel/xetable.cxx index 53a3c860dc5a..ce561589ba34 100644 --- a/sc/source/filter/excel/xetable.cxx +++ b/sc/source/filter/excel/xetable.cxx @@ -932,23 +932,82 @@ void XclExpFormulaCell::SaveXml( XclExpXmlStream& rStrm ) // OOXTODO: XML_cm, XML_vm, XML_ph FSEND ); - rWorksheet->startElement( XML_f, - // OOXTODO: XML_t, ST_CellFormulaType - XML_aca, XclXmlUtils::ToPsz( (mxTokArr && mxTokArr->IsVolatile()) || (mxAddRec && mxAddRec->IsVolatile()) ), - // OOXTODO: XML_ref, ST_Ref - // OOXTODO: XML_dt2D, bool - // OOXTODO: XML_dtr, bool - // OOXTODO: XML_del1, bool - // OOXTODO: XML_del2, bool - // OOXTODO: XML_r1, ST_CellRef - // OOXTODO: XML_r2, ST_CellRef - // OOXTODO: XML_ca, bool - // OOXTODO: XML_si, uint - // OOXTODO: XML_bx bool - FSEND ); - rWorksheet->writeEscaped( XclXmlUtils::ToOUString( - rStrm.GetRoot().GetCompileFormulaContext(), mrScFmlaCell.aPos, mrScFmlaCell.GetCode())); - rWorksheet->endElement( XML_f ); + bool bWriteFormula = true; + bool bTagStarted = false; + ScAddress aScPos( static_cast< SCCOL >( GetXclPos().mnCol ), + static_cast< SCROW >( GetXclPos().mnRow ), rStrm.GetRoot().GetCurrScTab() ); + + switch (mrScFmlaCell.GetMatrixFlag()) + { + case MM_NONE: + break; + case MM_REFERENCE: + bWriteFormula = false; + break; + case MM_FORMULA: + case MM_FAKE: + { + // origin of the matrix - find the used matrix range + SCCOL nMatWidth; + SCROW nMatHeight; + mrScFmlaCell.GetMatColsRows( nMatWidth, nMatHeight ); + OSL_ENSURE( nMatWidth && nMatHeight, "XclExpFormulaCell::XclExpFormulaCell - empty matrix" ); + ScRange aMatScRange( aScPos ); + ScAddress& rMatEnd = aMatScRange.aEnd; + rMatEnd.IncCol( static_cast< SCsCOL >( nMatWidth - 1 ) ); + rMatEnd.IncRow( static_cast< SCsROW >( nMatHeight - 1 ) ); + // reduce to valid range (range keeps valid, because start position IS valid + rStrm.GetRoot().GetAddressConverter().ValidateRange( aMatScRange, true ); + + OStringBuffer sFmlaCellRange; + if (ValidRange(aMatScRange)) + { + // calculate the cell range. + sFmlaCellRange.append( XclXmlUtils::ToOString( + rStrm.GetRoot().GetStringBuf(), aMatScRange.aStart ).getStr()); + sFmlaCellRange.append(":"); + sFmlaCellRange.append( XclXmlUtils::ToOString( + rStrm.GetRoot().GetStringBuf(), aMatScRange.aEnd ).getStr()); + } + + if ( aMatScRange.aStart.Col() == GetXclPos().mnCol && + aMatScRange.aStart.Row() == static_cast<SCROW>(GetXclPos().mnRow)) + { + rWorksheet->startElement( XML_f, + XML_aca, XclXmlUtils::ToPsz( (mxTokArr && mxTokArr->IsVolatile()) || + (mxAddRec && mxAddRec->IsVolatile())), + XML_t, mxAddRec ? "array" : NULL, + XML_ref, !sFmlaCellRange.isEmpty()? sFmlaCellRange.getStr() : NULL, + // OOXTODO: XML_dt2D, bool + // OOXTODO: XML_dtr, bool + // OOXTODO: XML_del1, bool + // OOXTODO: XML_del2, bool + // OOXTODO: XML_r1, ST_CellRef + // OOXTODO: XML_r2, ST_CellRef + // OOXTODO: XML_ca, bool + // OOXTODO: XML_si, uint + // OOXTODO: XML_bx bool + FSEND ); + bTagStarted = true; + } + } + break; + } + + if (bWriteFormula) + { + if (!bTagStarted) + { + rWorksheet->startElement( XML_f, + XML_aca, XclXmlUtils::ToPsz( (mxTokArr && mxTokArr->IsVolatile()) || + (mxAddRec && mxAddRec->IsVolatile()) ), + FSEND ); + } + rWorksheet->writeEscaped( XclXmlUtils::ToOUString( + rStrm.GetRoot().GetCompileFormulaContext(), mrScFmlaCell.aPos, mrScFmlaCell.GetCode())); + rWorksheet->endElement( XML_f ); + } + if( strcmp( sType, "inlineStr" ) == 0 ) { rWorksheet->startElement( XML_is, FSEND ); |