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 {
#define CREATE_MSOFFICE_RELATION_TYPE( ascii ) \
( "http://schemas.microsoft.com/office/2006/relationships/" ascii )
#define CREATE_XL_CONTENT_TYPE( ascii ) \
( "application/vnd.openxmlformats-officedocument.spreadsheetml." ascii "+xml" )
struct Relation
{
......
......@@ -96,6 +96,7 @@ $(eval $(call gb_Library_add_exception_objects,scfilt,\
sc/source/filter/excel/xename \
sc/source/filter/excel/xepage \
sc/source/filter/excel/xepivot \
sc/source/filter/excel/xepivotxml \
sc/source/filter/excel/xerecord \
sc/source/filter/excel/xeroot \
sc/source/filter/excel/xestream \
......
......@@ -156,6 +156,7 @@ public:
long GetDimMemberCount(long nDim) const;
SCROW GetOrder( long nDim, SCROW nIndex ) const;
const IndexArrayType* GetFieldIndexArray( size_t nDim ) const;
const ItemsType& GetDimMemberValues( SCCOL nDim ) const;
bool InitFromDoc(ScDocument* pDoc, const ScRange& rRange);
bool InitFromDataBase(DBConnector& rDB);
......
......@@ -132,6 +132,7 @@ public:
ScRange GetNewOutputRange( bool& rOverflow );
ScRange GetOutputRangeByType( sal_Int32 nType );
ScRange GetOutputRangeByType( sal_Int32 nType ) const;
void SetSaveData(const ScDPSaveData& rData);
ScDPSaveData* GetSaveData() const { return pSaveData; }
......@@ -287,9 +288,12 @@ public:
UpdateRefMode eMode, const ScRange& r, SCsCOL nDx, SCsROW nDy, SCsTAB nDz);
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);
bool remove(const ScDPCache* p);
SC_DLLPUBLIC const std::vector<ScRange>& getAllRanges() const;
};
/**
......
......@@ -112,7 +112,8 @@ public:
void SetPosition( const ScAddress& rPos );
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();
bool HasError(); // range overflow or exception from source
......
......@@ -850,6 +850,14 @@ SCROW ScDPCache::GetDataSize() const
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
{
OSL_ENSURE( nDim>=0 && nDim < mnColumnCount ," nDim < mnColumnCount ");
......
......@@ -936,6 +936,14 @@ ScRange ScDPObject::GetOutputRangeByType( sal_Int32 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 )
{
return ((const ScMergeFlagAttr*)pDoc->GetAttr( nCol, nRow, nTab, ATTR_MERGE_FLAG ))->HasPivotButton();
......@@ -2905,6 +2913,25 @@ ScDPCache* ScDPCollection::SheetCaches::getExistingCache(const ScRange& rRange)
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
{
return maCaches.size();
......@@ -2990,6 +3017,11 @@ bool ScDPCollection::SheetCaches::remove(const ScDPCache* p)
return false;
}
const std::vector<ScRange>& ScDPCollection::SheetCaches::getAllRanges() const
{
return maRanges;
}
ScDPCollection::NameCaches::NameCaches(ScDocument* pDoc) : mpDoc(pDoc) {}
bool ScDPCollection::NameCaches::hasCache(const OUString& rName) const
......
......@@ -1166,6 +1166,27 @@ ScRange ScDPOutput::GetOutputRange( sal_Int32 nRegionType )
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()
{
CalcSizes();
......
......@@ -68,6 +68,7 @@
#include "xeescher.hxx"
#include "xepivot.hxx"
#include "XclExpChangeTrack.hxx"
#include <xepivotxml.hxx>
#include <math.h>
......@@ -405,10 +406,6 @@ void ExcTable::FillAsHeaderXml( ExcBoundsheetList& rBoundsheetList )
// Formatting: FONT, FORMAT, XF, STYLE, PALETTE
aRecList.AppendNewRecord( new XclExpXmlStyleSheet( *this ) );
// Pivot Cache
GetPivotTableManager().CreatePivotTables();
aRecList.AppendRecord( GetPivotTableManager().CreatePivotCachesRecord() );
// Change tracking
if( rDoc.GetChangeTrack() )
{
......@@ -641,10 +638,6 @@ void ExcTable::FillAsTableXml()
// cell table: DEFCOLWIDTH, COLINFO, DIMENSIONS, ROW, cell records
aRecList.AppendRecord( mxCellTable );
// pivot tables
// not in the worksheet file
aRecList.AppendRecord( GetPivotTableManager().CreatePivotTablesRecord( mnScTab ) );
// list of NOTE records, generated by the cell table
// not in the worksheet file
if( mxNoteList != 0 && !mxNoteList->IsEmpty() )
......@@ -742,6 +735,10 @@ void ExcTable::WriteXml( XclExpXmlStream& rStrm )
mxCellTable->Finalize();
aRecList.SaveXml( rStrm );
XclExpXmlPivotTables* pPT = GetXmlPivotTableManager().GetTablesBySheet(mnScTab);
if (pPT)
pPT->SaveXml(rStrm);
rStrm.GetCurrentStream()->endElement( XML_worksheet );
rStrm.PopStream();
}
......@@ -766,7 +763,10 @@ void ExcDocument::ReadDoc( void )
if (GetOutput() == EXC_OUTPUT_BINARY)
aHeader.FillAsHeaderBinary(maBoundsheetList);
else
{
aHeader.FillAsHeaderXml(maBoundsheetList);
GetXmlPivotTableManager().Initialize();
}
SCTAB nScTab = 0, nScTabCount = GetTabInfo().GetScTabCount();
SCTAB nCodeNameIdx = 0, nCodeNameCount = GetExtDocOptions().GetCodeNameCount();
......@@ -873,6 +873,10 @@ void ExcDocument::WriteXml( XclExpXmlStream& rStrm )
if( pExpChangeTrack )
pExpChangeTrack->WriteXml( rStrm );
XclExpXmlPivotCaches& rCaches = GetXmlPivotTableManager().GetCaches();
if (rCaches.HasCaches())
rCaches.SaveXml(rStrm);
rWorkbook->endElement( XML_workbook );
rWorkbook.reset();
......
This diff is collapsed.
......@@ -37,6 +37,7 @@
#include "xepivot.hxx"
#include "xestyle.hxx"
#include "xeroot.hxx"
#include <xepivotxml.hxx>
#include "excrecds.hxx"
#include "tabprotection.hxx"
......@@ -164,6 +165,12 @@ XclExpPivotTableManager& XclExpRoot::GetPivotTableManager() const
return *mrExpData.mxPTableMgr;
}
XclExpXmlPivotTableManager& XclExpRoot::GetXmlPivotTableManager()
{
assert(mrExpData.mxXmlPTableMgr);
return *mrExpData.mxXmlPTableMgr;
}
void XclExpRoot::InitializeConvert()
{
mrExpData.mxTabInfo.reset( new XclExpTabInfo( GetRoot() ) );
......@@ -201,6 +208,8 @@ void XclExpRoot::InitializeGlobals()
if( GetOutput() == EXC_OUTPUT_XML_2007 )
{
mrExpData.mxXmlPTableMgr.reset(new XclExpXmlPivotTableManager(GetRoot()));
do
{
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;
class XclExpFilterManager;
class XclExpPivotTableManager;
class XclExpDxfs;
class XclExpXmlPivotTableManager;
/** Stores global buffers and data needed for Excel export filter. */
struct XclExpRootData : public XclRootData
......@@ -90,6 +91,8 @@ struct XclExpRootData : public XclRootData
XclExpPTableMgrRef mxPTableMgr; /// All pivot tables and pivot caches.
XclExpDxfsRef mxDxfs; /// All delta formatting entries
boost::shared_ptr<XclExpXmlPivotTableManager> mxXmlPTableMgr;
ScCompiler::OpCodeMapPtr mxOpCodeMap; /// mapping between op-codes and names
bool mbRelUrl; /// true = Store URLs relative.
......@@ -144,6 +147,8 @@ public:
/** Returns the differential formatting list */
XclExpDxfs& GetDxfs() const;
XclExpXmlPivotTableManager& GetXmlPivotTableManager();
/** Is called when export filter starts to create the Excel document (all BIFF versions). */
void InitializeConvert();
/** 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