Kaydet (Commit) 446a3a06 authored tarafından Eike Rathke's avatar Eike Rathke Kaydeden (comit) Markus Mohrhard

Resolves: tdf#96072 export Chart format codes in Excel notation

This is a combination of 4 commits.
Omitted are 2246f478 and
7340872a that replace the Calc code with
calling the new SvNumberFormatter functions.

introduce SvNumberFormatter::FillKeywordTableForExcel()

... to conflate the places that do this on their own.

(cherry picked from commit b5554804)

use proper case "General" keyword

... Excel doesn't seem to care though.

(cherry picked from commit ea1db935)

introduce SvNumberFormatter::GetFormatStringForExcel()

Taking implementation from sc/source/filter/excel/xestyle.cxx
GetNumberFormatCode(), slightly modified to ensure valid conversion and
force en-US locale data. Also don't unnecessarily convert if format is
for system locale and system locale is en-US.

(cherry picked from commit 2011b541)

Resolves: tdf#96072 export Chart format codes in Excel notation

As for the change in chart2/qa/extras/chart2export.cxx
Chart2ExportTest::testAxisNumberFormatXLSX() unit test: also Excel
writes string parts of format codes quoted, including minus sign in
negative subformat.

(cherry picked from commit 509cfa40)

3697a808d8fee2417f0b0e03dba2b94ceea133dd
9223eaa655132b4106a35c94cb0005559d7575b1
201bb012df818129cbc65de0eee8eca59e57d829

Change-Id: Idde2173780e0515ad982b4be46fc4df23a7577ad
Reviewed-on: https://gerrit.libreoffice.org/20249Reviewed-by: 's avatarMarkus Mohrhard <markus.mohrhard@googlemail.com>
Tested-by: 's avatarMarkus Mohrhard <markus.mohrhard@googlemail.com>
üst 52fe817a
......@@ -1277,7 +1277,7 @@ void Chart2ExportTest::testAxisNumberFormatXLSX()
assertXPath(pXmlDoc, "/c:chartSpace/c:chart/c:plotArea/c:valAx[1]/c:numFmt", "formatCode", "0.00E+000");
assertXPath(pXmlDoc, "/c:chartSpace/c:chart/c:plotArea/c:valAx[1]/c:numFmt", "sourceLinked", "0");
assertXPath(pXmlDoc, "/c:chartSpace/c:chart/c:plotArea/c:valAx[2]/c:numFmt", "formatCode", "[$$-409]#,##0;-[$$-409]#,##0");
assertXPath(pXmlDoc, "/c:chartSpace/c:chart/c:plotArea/c:valAx[2]/c:numFmt", "formatCode", "[$$-409]#,##0;\\-[$$-409]#,##0");
assertXPath(pXmlDoc, "/c:chartSpace/c:chart/c:plotArea/c:valAx[2]/c:numFmt", "sourceLinked", "1");
}
......
......@@ -766,6 +766,20 @@ public:
/// Fill a NfKeywordIndex table with keywords of a language/country
void FillKeywordTable( NfKeywordTable& rKeywords, LanguageType eLang );
/** Fill a NfKeywordIndex table with keywords usable in Excel export with
GetFormatStringForExcel() or SvNumberformat::GetMappedFormatstring() */
void FillKeywordTableForExcel( NfKeywordTable& rKeywords );
/** Return a format code string suitable for Excel export.
@param rTempFormatter
SvNumberFormatter to use if a non-en-US format code needs to be
converted and put, should not be the same formatter to not
pollute the entries of this one here.
*/
OUString GetFormatStringForExcel( sal_uInt32 nKey, const NfKeywordTable& rKeywords,
SvNumberFormatter& rTempFormatter ) const;
/** Return a keyword for a language/country and NfKeywordIndex
for XML import, to generate number format strings. */
OUString GetKeyword( LanguageType eLnge, sal_uInt16 nIndex );
......
......@@ -89,6 +89,10 @@
#include <comphelper/random.hxx>
#include <xmloff/SchXMLSeriesHelper.hxx>
#include "ColorPropertySet.hxx"
#include <svl/zforlist.hxx>
#include <svl/numuno.hxx>
#include <set>
#include <unordered_set>
......@@ -3747,17 +3751,26 @@ bool ChartExport::isDeep3dChart()
OUString ChartExport::getNumberFormatCode(sal_Int32 nKey) const
{
/* XXX if this was called more than one or two times per export the two
* SvNumberFormatter instances and NfKeywordTable should be member
* variables and initialized only once. */
OUString aCode("General"); // init with fallback
uno::Reference<util::XNumberFormatsSupplier> xNumberFormatsSupplier(mxChartModel, uno::UNO_QUERY_THROW);
uno::Reference<util::XNumberFormats> xNumberFormats = xNumberFormatsSupplier->getNumberFormats();
uno::Reference<beans::XPropertySet> xNumberFormat = xNumberFormats->getByKey(nKey);
SvNumberFormatsSupplierObj* pSupplierObj = SvNumberFormatsSupplierObj::getImplementation( xNumberFormatsSupplier);
if (!pSupplierObj)
return aCode;
SvNumberFormatter* pNumberFormatter = pSupplierObj->GetNumberFormatter();
if (!pNumberFormatter)
return aCode;
if (!xNumberFormat.is())
return OUString();
SvNumberFormatter aTempFormatter( comphelper::getProcessComponentContext(), LANGUAGE_ENGLISH_US);
NfKeywordTable aKeywords;
aTempFormatter.FillKeywordTableForExcel( aKeywords);
aCode = pNumberFormatter->GetFormatStringForExcel( nKey, aKeywords, aTempFormatter);
uno::Any aAny = xNumberFormat->getPropertyValue("FormatString");
OUString aValue;
aAny >>= aValue;
return aValue;
return aCode;
}
}// drawingml
......
......@@ -718,6 +718,78 @@ void SvNumberFormatter::FillKeywordTable( NfKeywordTable& rKeywords,
}
void SvNumberFormatter::FillKeywordTableForExcel( NfKeywordTable& rKeywords )
{
FillKeywordTable( rKeywords, LANGUAGE_ENGLISH_US );
// Replace upper case "GENERAL" with proper case "General".
rKeywords[ NF_KEY_GENERAL ] = GetStandardName( LANGUAGE_ENGLISH_US );
// Remap codes unknown to Excel.
rKeywords[ NF_KEY_NN ] = "DDD";
rKeywords[ NF_KEY_NNN ] = "DDDD";
// NNNN gets a separator appended in SvNumberformat::GetMappedFormatString()
rKeywords[ NF_KEY_NNNN ] = "DDDD";
// Export the Thai T NatNum modifier.
rKeywords[ NF_KEY_THAI_T ] = "T";
}
OUString SvNumberFormatter::GetFormatStringForExcel( sal_uInt32 nKey, const NfKeywordTable& rKeywords,
SvNumberFormatter& rTempFormatter ) const
{
OUString aFormatStr;
if (const SvNumberformat* pEntry = GetEntry( nKey))
{
if (pEntry->GetType() == css::util::NumberFormat::LOGICAL)
{
// Build Boolean number format, which needs non-zero and zero
// subformat codes with TRUE and FALSE strings.
Color* pColor = nullptr;
OUString aTemp;
const_cast< SvNumberformat* >( pEntry )->GetOutputString( 1.0, aTemp, &pColor );
aFormatStr += "\"" + aTemp + "\";\"" + aTemp + "\";\"";
const_cast< SvNumberformat* >( pEntry )->GetOutputString( 0.0, aTemp, &pColor );
aFormatStr += aTemp + "\"";
}
else
{
LanguageType nLang = pEntry->GetLanguage();
if (nLang == LANGUAGE_SYSTEM)
nLang = SvtSysLocale().GetLanguageTag().getLanguageType();
if (nLang != LANGUAGE_ENGLISH_US)
{
sal_Int32 nCheckPos;
short nType = css::util::NumberFormat::DEFINED;
sal_uInt32 nTempKey;
OUString aTemp( pEntry->GetFormatstring());
rTempFormatter.PutandConvertEntry( aTemp, nCheckPos, nType, nTempKey, nLang, LANGUAGE_ENGLISH_US);
SAL_WARN_IF( nCheckPos != 0, "svl.numbers",
"SvNumberFormatter::GetFormatStringForExcel - format code not convertible");
if (nTempKey != NUMBERFORMAT_ENTRY_NOT_FOUND)
pEntry = rTempFormatter.GetEntry( nTempKey);
}
if (pEntry)
{
// GetLocaleData() returns the current locale's data, so switch
// before (which doesn't do anything if it was the same locale
// already).
rTempFormatter.ChangeIntl( LANGUAGE_ENGLISH_US);
aFormatStr = pEntry->GetMappedFormatstring( rKeywords, *rTempFormatter.GetLocaleData());
}
}
}
else
{
SAL_WARN("svl.numbers","SvNumberFormatter::GetFormatStringForExcel - format not found: " << nKey);
}
if (aFormatStr.isEmpty())
aFormatStr = "General";
return aFormatStr;
}
OUString SvNumberFormatter::GetKeyword( LanguageType eLnge, sal_uInt16 nIndex )
{
ChangeIntl(eLnge);
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment