Kaydet (Commit) f5aeaa38 authored tarafından Kohei Yoshida's avatar Kohei Yoshida

bnc#822173: Initial work on exporting pivot cache and pivot table to xlsx.

Still not perfect, but it somewhat does work.

Change-Id: Ic248e20f7ab18a37f56b2034f57551dded956bab
üst 902e3898
...@@ -50,7 +50,8 @@ namespace core { ...@@ -50,7 +50,8 @@ namespace core {
#define CREATE_MSOFFICE_RELATION_TYPE( ascii ) \ #define CREATE_MSOFFICE_RELATION_TYPE( ascii ) \
( "http://schemas.microsoft.com/office/2006/relationships/" ascii ) ( "http://schemas.microsoft.com/office/2006/relationships/" ascii )
#define CREATE_XL_CONTENT_TYPE( ascii ) \
( "application/vnd.openxmlformats-officedocument.spreadsheetml." ascii "+xml" )
struct Relation struct Relation
{ {
......
...@@ -96,6 +96,7 @@ $(eval $(call gb_Library_add_exception_objects,scfilt,\ ...@@ -96,6 +96,7 @@ $(eval $(call gb_Library_add_exception_objects,scfilt,\
sc/source/filter/excel/xename \ sc/source/filter/excel/xename \
sc/source/filter/excel/xepage \ sc/source/filter/excel/xepage \
sc/source/filter/excel/xepivot \ sc/source/filter/excel/xepivot \
sc/source/filter/excel/xepivotxml \
sc/source/filter/excel/xerecord \ sc/source/filter/excel/xerecord \
sc/source/filter/excel/xeroot \ sc/source/filter/excel/xeroot \
sc/source/filter/excel/xestream \ sc/source/filter/excel/xestream \
......
...@@ -156,6 +156,7 @@ public: ...@@ -156,6 +156,7 @@ public:
long GetDimMemberCount(long nDim) const; long GetDimMemberCount(long nDim) const;
SCROW GetOrder( long nDim, SCROW nIndex ) const; SCROW GetOrder( long nDim, SCROW nIndex ) const;
const IndexArrayType* GetFieldIndexArray( size_t nDim ) const;
const ItemsType& GetDimMemberValues( SCCOL nDim ) const; const ItemsType& GetDimMemberValues( SCCOL nDim ) const;
bool InitFromDoc(ScDocument* pDoc, const ScRange& rRange); bool InitFromDoc(ScDocument* pDoc, const ScRange& rRange);
bool InitFromDataBase(DBConnector& rDB); bool InitFromDataBase(DBConnector& rDB);
......
...@@ -132,6 +132,7 @@ public: ...@@ -132,6 +132,7 @@ public:
ScRange GetNewOutputRange( bool& rOverflow ); ScRange GetNewOutputRange( bool& rOverflow );
ScRange GetOutputRangeByType( sal_Int32 nType ); ScRange GetOutputRangeByType( sal_Int32 nType );
ScRange GetOutputRangeByType( sal_Int32 nType ) const;
void SetSaveData(const ScDPSaveData& rData); void SetSaveData(const ScDPSaveData& rData);
ScDPSaveData* GetSaveData() const { return pSaveData; } ScDPSaveData* GetSaveData() const { return pSaveData; }
...@@ -287,9 +288,12 @@ public: ...@@ -287,9 +288,12 @@ public:
UpdateRefMode eMode, const ScRange& r, SCsCOL nDx, SCsROW nDy, SCsTAB nDz); UpdateRefMode eMode, const ScRange& r, SCsCOL nDx, SCsROW nDy, SCsTAB nDz);
SC_DLLPUBLIC ScDPCache* getExistingCache(const ScRange& rRange); SC_DLLPUBLIC ScDPCache* getExistingCache(const ScRange& rRange);
SC_DLLPUBLIC const ScDPCache* getExistingCache(const ScRange& rRange) const;
void updateCache(const ScRange& rRange, std::set<ScDPObject*>& rRefs); void updateCache(const ScRange& rRange, std::set<ScDPObject*>& rRefs);
bool remove(const ScDPCache* p); bool remove(const ScDPCache* p);
SC_DLLPUBLIC const std::vector<ScRange>& getAllRanges() const;
}; };
/** /**
......
...@@ -112,7 +112,8 @@ public: ...@@ -112,7 +112,8 @@ public:
void SetPosition( const ScAddress& rPos ); void SetPosition( const ScAddress& rPos );
void Output(); //! Refresh? void Output(); //! Refresh?
ScRange GetOutputRange( sal_Int32 nRegionType = ::com::sun::star::sheet::DataPilotOutputRangeType::WHOLE ); ScRange GetOutputRange( sal_Int32 nRegionType = ::com::sun::star::sheet::DataPilotOutputRangeType::WHOLE );
ScRange GetOutputRange( sal_Int32 nRegionType = ::com::sun::star::sheet::DataPilotOutputRangeType::WHOLE ) const;
long GetHeaderRows(); long GetHeaderRows();
bool HasError(); // range overflow or exception from source bool HasError(); // range overflow or exception from source
......
...@@ -850,6 +850,14 @@ SCROW ScDPCache::GetDataSize() const ...@@ -850,6 +850,14 @@ SCROW ScDPCache::GetDataSize() const
return mnDataSize >= 0 ? mnDataSize : 0; return mnDataSize >= 0 ? mnDataSize : 0;
} }
const ScDPCache::IndexArrayType* ScDPCache::GetFieldIndexArray( size_t nDim ) const
{
if (nDim >= maFields.size())
return NULL;
return &maFields[nDim].maData;
}
const ScDPCache::ItemsType& ScDPCache::GetDimMemberValues(SCCOL nDim) const const ScDPCache::ItemsType& ScDPCache::GetDimMemberValues(SCCOL nDim) const
{ {
OSL_ENSURE( nDim>=0 && nDim < mnColumnCount ," nDim < mnColumnCount "); OSL_ENSURE( nDim>=0 && nDim < mnColumnCount ," nDim < mnColumnCount ");
......
...@@ -936,6 +936,14 @@ ScRange ScDPObject::GetOutputRangeByType( sal_Int32 nType ) ...@@ -936,6 +936,14 @@ ScRange ScDPObject::GetOutputRangeByType( sal_Int32 nType )
return pOutput->GetOutputRange(nType); return pOutput->GetOutputRange(nType);
} }
ScRange ScDPObject::GetOutputRangeByType( sal_Int32 nType ) const
{
if (!pOutput || pOutput->HasError())
return ScRange(ScAddress::INITIALIZE_INVALID);
return pOutput->GetOutputRange(nType);
}
static bool lcl_HasButton( ScDocument* pDoc, SCCOL nCol, SCROW nRow, SCTAB nTab ) static bool lcl_HasButton( ScDocument* pDoc, SCCOL nCol, SCROW nRow, SCTAB nTab )
{ {
return ((const ScMergeFlagAttr*)pDoc->GetAttr( nCol, nRow, nTab, ATTR_MERGE_FLAG ))->HasPivotButton(); return ((const ScMergeFlagAttr*)pDoc->GetAttr( nCol, nRow, nTab, ATTR_MERGE_FLAG ))->HasPivotButton();
...@@ -2905,6 +2913,25 @@ ScDPCache* ScDPCollection::SheetCaches::getExistingCache(const ScRange& rRange) ...@@ -2905,6 +2913,25 @@ ScDPCache* ScDPCollection::SheetCaches::getExistingCache(const ScRange& rRange)
return itCache->second; return itCache->second;
} }
const ScDPCache* ScDPCollection::SheetCaches::getExistingCache(const ScRange& rRange) const
{
RangeIndexType::const_iterator it = std::find(maRanges.begin(), maRanges.end(), rRange);
if (it == maRanges.end())
// Not cached.
return NULL;
// Already cached.
size_t nIndex = std::distance(maRanges.begin(), it);
CachesType::const_iterator itCache = maCaches.find(nIndex);
if (itCache == maCaches.end())
{
OSL_FAIL("Cache pool and index pool out-of-sync !!!");
return NULL;
}
return itCache->second;
}
size_t ScDPCollection::SheetCaches::size() const size_t ScDPCollection::SheetCaches::size() const
{ {
return maCaches.size(); return maCaches.size();
...@@ -2990,6 +3017,11 @@ bool ScDPCollection::SheetCaches::remove(const ScDPCache* p) ...@@ -2990,6 +3017,11 @@ bool ScDPCollection::SheetCaches::remove(const ScDPCache* p)
return false; return false;
} }
const std::vector<ScRange>& ScDPCollection::SheetCaches::getAllRanges() const
{
return maRanges;
}
ScDPCollection::NameCaches::NameCaches(ScDocument* pDoc) : mpDoc(pDoc) {} ScDPCollection::NameCaches::NameCaches(ScDocument* pDoc) : mpDoc(pDoc) {}
bool ScDPCollection::NameCaches::hasCache(const OUString& rName) const bool ScDPCollection::NameCaches::hasCache(const OUString& rName) const
......
...@@ -1166,6 +1166,27 @@ ScRange ScDPOutput::GetOutputRange( sal_Int32 nRegionType ) ...@@ -1166,6 +1166,27 @@ ScRange ScDPOutput::GetOutputRange( sal_Int32 nRegionType )
return ScRange(aStartPos.Col(), aStartPos.Row(), nTab, nTabEndCol, nTabEndRow, nTab); return ScRange(aStartPos.Col(), aStartPos.Row(), nTab, nTabEndCol, nTabEndRow, nTab);
} }
ScRange ScDPOutput::GetOutputRange( sal_Int32 nRegionType ) const
{
using namespace ::com::sun::star::sheet;
if (!bSizesValid)
return ScRange(ScAddress::INITIALIZE_INVALID);
SCTAB nTab = aStartPos.Tab();
switch (nRegionType)
{
case DataPilotOutputRangeType::RESULT:
return ScRange(nDataStartCol, nDataStartRow, nTab, nTabEndCol, nTabEndRow, nTab);
case DataPilotOutputRangeType::TABLE:
return ScRange(aStartPos.Col(), nTabStartRow, nTab, nTabEndCol, nTabEndRow, nTab);
default:
OSL_ENSURE(nRegionType == DataPilotOutputRangeType::WHOLE, "ScDPOutput::GetOutputRange: unknown region type");
break;
}
return ScRange(aStartPos.Col(), aStartPos.Row(), nTab, nTabEndCol, nTabEndRow, nTab);
}
bool ScDPOutput::HasError() bool ScDPOutput::HasError()
{ {
CalcSizes(); CalcSizes();
......
...@@ -68,6 +68,7 @@ ...@@ -68,6 +68,7 @@
#include "xeescher.hxx" #include "xeescher.hxx"
#include "xepivot.hxx" #include "xepivot.hxx"
#include "XclExpChangeTrack.hxx" #include "XclExpChangeTrack.hxx"
#include <xepivotxml.hxx>
#include <math.h> #include <math.h>
...@@ -405,10 +406,6 @@ void ExcTable::FillAsHeaderXml( ExcBoundsheetList& rBoundsheetList ) ...@@ -405,10 +406,6 @@ void ExcTable::FillAsHeaderXml( ExcBoundsheetList& rBoundsheetList )
// Formatting: FONT, FORMAT, XF, STYLE, PALETTE // Formatting: FONT, FORMAT, XF, STYLE, PALETTE
aRecList.AppendNewRecord( new XclExpXmlStyleSheet( *this ) ); aRecList.AppendNewRecord( new XclExpXmlStyleSheet( *this ) );
// Pivot Cache
GetPivotTableManager().CreatePivotTables();
aRecList.AppendRecord( GetPivotTableManager().CreatePivotCachesRecord() );
// Change tracking // Change tracking
if( rDoc.GetChangeTrack() ) if( rDoc.GetChangeTrack() )
{ {
...@@ -641,10 +638,6 @@ void ExcTable::FillAsTableXml() ...@@ -641,10 +638,6 @@ void ExcTable::FillAsTableXml()
// cell table: DEFCOLWIDTH, COLINFO, DIMENSIONS, ROW, cell records // cell table: DEFCOLWIDTH, COLINFO, DIMENSIONS, ROW, cell records
aRecList.AppendRecord( mxCellTable ); aRecList.AppendRecord( mxCellTable );
// pivot tables
// not in the worksheet file
aRecList.AppendRecord( GetPivotTableManager().CreatePivotTablesRecord( mnScTab ) );
// list of NOTE records, generated by the cell table // list of NOTE records, generated by the cell table
// not in the worksheet file // not in the worksheet file
if( mxNoteList != 0 && !mxNoteList->IsEmpty() ) if( mxNoteList != 0 && !mxNoteList->IsEmpty() )
...@@ -742,6 +735,10 @@ void ExcTable::WriteXml( XclExpXmlStream& rStrm ) ...@@ -742,6 +735,10 @@ void ExcTable::WriteXml( XclExpXmlStream& rStrm )
mxCellTable->Finalize(); mxCellTable->Finalize();
aRecList.SaveXml( rStrm ); aRecList.SaveXml( rStrm );
XclExpXmlPivotTables* pPT = GetXmlPivotTableManager().GetTablesBySheet(mnScTab);
if (pPT)
pPT->SaveXml(rStrm);
rStrm.GetCurrentStream()->endElement( XML_worksheet ); rStrm.GetCurrentStream()->endElement( XML_worksheet );
rStrm.PopStream(); rStrm.PopStream();
} }
...@@ -766,7 +763,10 @@ void ExcDocument::ReadDoc( void ) ...@@ -766,7 +763,10 @@ void ExcDocument::ReadDoc( void )
if (GetOutput() == EXC_OUTPUT_BINARY) if (GetOutput() == EXC_OUTPUT_BINARY)
aHeader.FillAsHeaderBinary(maBoundsheetList); aHeader.FillAsHeaderBinary(maBoundsheetList);
else else
{
aHeader.FillAsHeaderXml(maBoundsheetList); aHeader.FillAsHeaderXml(maBoundsheetList);
GetXmlPivotTableManager().Initialize();
}
SCTAB nScTab = 0, nScTabCount = GetTabInfo().GetScTabCount(); SCTAB nScTab = 0, nScTabCount = GetTabInfo().GetScTabCount();
SCTAB nCodeNameIdx = 0, nCodeNameCount = GetExtDocOptions().GetCodeNameCount(); SCTAB nCodeNameIdx = 0, nCodeNameCount = GetExtDocOptions().GetCodeNameCount();
...@@ -873,6 +873,10 @@ void ExcDocument::WriteXml( XclExpXmlStream& rStrm ) ...@@ -873,6 +873,10 @@ void ExcDocument::WriteXml( XclExpXmlStream& rStrm )
if( pExpChangeTrack ) if( pExpChangeTrack )
pExpChangeTrack->WriteXml( rStrm ); pExpChangeTrack->WriteXml( rStrm );
XclExpXmlPivotCaches& rCaches = GetXmlPivotTableManager().GetCaches();
if (rCaches.HasCaches())
rCaches.SaveXml(rStrm);
rWorkbook->endElement( XML_workbook ); rWorkbook->endElement( XML_workbook );
rWorkbook.reset(); rWorkbook.reset();
......
This diff is collapsed.
...@@ -37,6 +37,7 @@ ...@@ -37,6 +37,7 @@
#include "xepivot.hxx" #include "xepivot.hxx"
#include "xestyle.hxx" #include "xestyle.hxx"
#include "xeroot.hxx" #include "xeroot.hxx"
#include <xepivotxml.hxx>
#include "excrecds.hxx" #include "excrecds.hxx"
#include "tabprotection.hxx" #include "tabprotection.hxx"
...@@ -164,6 +165,12 @@ XclExpPivotTableManager& XclExpRoot::GetPivotTableManager() const ...@@ -164,6 +165,12 @@ XclExpPivotTableManager& XclExpRoot::GetPivotTableManager() const
return *mrExpData.mxPTableMgr; return *mrExpData.mxPTableMgr;
} }
XclExpXmlPivotTableManager& XclExpRoot::GetXmlPivotTableManager()
{
assert(mrExpData.mxXmlPTableMgr);
return *mrExpData.mxXmlPTableMgr;
}
void XclExpRoot::InitializeConvert() void XclExpRoot::InitializeConvert()
{ {
mrExpData.mxTabInfo.reset( new XclExpTabInfo( GetRoot() ) ); mrExpData.mxTabInfo.reset( new XclExpTabInfo( GetRoot() ) );
...@@ -201,6 +208,8 @@ void XclExpRoot::InitializeGlobals() ...@@ -201,6 +208,8 @@ void XclExpRoot::InitializeGlobals()
if( GetOutput() == EXC_OUTPUT_XML_2007 ) if( GetOutput() == EXC_OUTPUT_XML_2007 )
{ {
mrExpData.mxXmlPTableMgr.reset(new XclExpXmlPivotTableManager(GetRoot()));
do do
{ {
ScDocument& rDoc = GetDoc(); ScDocument& rDoc = GetDoc();
......
/* -*- 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 INCLUDED_SC_FILTER_XEPIVOTXML_HXX
#define INCLUDED_SC_FILTER_XEPIVOTXML_HXX
#include <xerecord.hxx>
#include <xeroot.hxx>
#include <boost/ptr_container/ptr_map.hpp>
#include <boost/unordered_map.hpp>
class ScDPCache;
class ScDPCollection;
class ScDPObject;
class XclExpXmlPivotCaches : public XclExpRecordBase, protected XclExpRoot
{
public:
enum EntryType { Worksheet, Name, Database };
struct Entry
{
const ScDPCache* mpCache;
EntryType meType;
ScRange maSrcRange;
};
XclExpXmlPivotCaches( const XclExpRoot& rRoot );
virtual void SaveXml( XclExpXmlStream& rStrm ) SAL_OVERRIDE;
void SetCaches( const std::vector<Entry>& rCaches );
bool HasCaches() const;
const Entry* GetCache( sal_Int32 nCacheId ) const;
private:
void SavePivotCacheXml( XclExpXmlStream& rStrm, const Entry& rEntry, sal_Int32 nCacheId );
private:
std::vector<Entry> maCaches;
};
class XclExpXmlPivotTables : public XclExpRecordBase, protected XclExpRoot
{
struct Entry
{
const ScDPObject* mpTable;
sal_Int32 mnCacheId;
sal_Int32 mnPivotId; /// used as [n] in pivotTable[n].xml part name.
Entry( const ScDPObject* pTable, sal_Int32 nCacheId, sal_Int32 nPivotId );
};
const XclExpXmlPivotCaches& mrCaches;
typedef std::vector<Entry> TablesType;
TablesType maTables;
public:
XclExpXmlPivotTables( const XclExpRoot& rRoot, const XclExpXmlPivotCaches& rCaches );
virtual void SaveXml( XclExpXmlStream& rStrm ) SAL_OVERRIDE;
void AppendTable( const ScDPObject* pTable, sal_Int32 nCacheId, sal_Int32 nPivotId );
private:
void SavePivotTableXml( XclExpXmlStream& rStrm, const ScDPObject& rObj, sal_Int32 nCacheId );
};
class XclExpXmlPivotTableManager : protected XclExpRoot
{
typedef boost::ptr_map<SCTAB, XclExpXmlPivotTables> TablesType;
typedef boost::unordered_map<const ScDPObject*, sal_Int32> CacheIdMapType;
public:
XclExpXmlPivotTableManager( const XclExpRoot& rRoot );
void Initialize();
XclExpXmlPivotCaches& GetCaches();
XclExpXmlPivotTables* GetTablesBySheet( SCTAB nTab );
private:
XclExpXmlPivotCaches maCaches;
TablesType maTables;
CacheIdMapType maCacheIdMap;
};
#endif
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
...@@ -51,6 +51,7 @@ class XclExpObjectManager; ...@@ -51,6 +51,7 @@ class XclExpObjectManager;
class XclExpFilterManager; class XclExpFilterManager;
class XclExpPivotTableManager; class XclExpPivotTableManager;
class XclExpDxfs; class XclExpDxfs;
class XclExpXmlPivotTableManager;
/** Stores global buffers and data needed for Excel export filter. */ /** Stores global buffers and data needed for Excel export filter. */
struct XclExpRootData : public XclRootData struct XclExpRootData : public XclRootData
...@@ -90,6 +91,8 @@ struct XclExpRootData : public XclRootData ...@@ -90,6 +91,8 @@ struct XclExpRootData : public XclRootData
XclExpPTableMgrRef mxPTableMgr; /// All pivot tables and pivot caches. XclExpPTableMgrRef mxPTableMgr; /// All pivot tables and pivot caches.
XclExpDxfsRef mxDxfs; /// All delta formatting entries XclExpDxfsRef mxDxfs; /// All delta formatting entries
boost::shared_ptr<XclExpXmlPivotTableManager> mxXmlPTableMgr;
ScCompiler::OpCodeMapPtr mxOpCodeMap; /// mapping between op-codes and names ScCompiler::OpCodeMapPtr mxOpCodeMap; /// mapping between op-codes and names
bool mbRelUrl; /// true = Store URLs relative. bool mbRelUrl; /// true = Store URLs relative.
...@@ -144,6 +147,8 @@ public: ...@@ -144,6 +147,8 @@ public:
/** Returns the differential formatting list */ /** Returns the differential formatting list */
XclExpDxfs& GetDxfs() const; XclExpDxfs& GetDxfs() const;
XclExpXmlPivotTableManager& GetXmlPivotTableManager();
/** Is called when export filter starts to create the Excel document (all BIFF versions). */ /** Is called when export filter starts to create the Excel document (all BIFF versions). */
void InitializeConvert(); void InitializeConvert();
/** Is called when export filter starts to create the workbook global data (>=BIFF5). */ /** Is called when export filter starts to create the workbook global data (>=BIFF5). */
......
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