summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMuthu Subramanian <sumuthu@novell.com>2011-06-09 19:15:17 +0530
committerMuthu Subramanian <sumuthu@novell.com>2011-06-10 12:39:08 +0530
commit1b66e024f9fe8c01c0f04731d26ce1d94824bbc9 (patch)
tree4c82f8f4634e733b137b670cfec85a44641ec623
parent2cfe404afa3d136d8aefa1cc4d918a98442dcc2c (diff)
n#683578: Performance improvements for xlsx imports.
Specifically reduces the number of UNO calls for importing cell attributes.
-rwxr-xr-xoox/inc/oox/xls/sheetdatabuffer.hxx12
-rwxr-xr-xoox/source/xls/sheetdatabuffer.cxx98
2 files changed, 51 insertions, 59 deletions
diff --git a/oox/inc/oox/xls/sheetdatabuffer.hxx b/oox/inc/oox/xls/sheetdatabuffer.hxx
index 82ee27ff7..b8a939740 100755
--- a/oox/inc/oox/xls/sheetdatabuffer.hxx
+++ b/oox/inc/oox/xls/sheetdatabuffer.hxx
@@ -274,10 +274,9 @@ private:
/** Writes all cell formatting attributes to the passed row range. */
void writeXfIdRowRangeProperties( const XfIdRowRange& rXfIdRowRange ) const;
- /** Writes all cell formatting attributes to the passed cell range. */
- void writeXfIdRangeProperties( const XfIdRange& rXfIdRange ) const;
- /** Tries to merge the ranges last inserted in maXfIdRanges with existing ranges. */
- void mergeXfIdRanges();
+
+ /** Writes all cell formatting attributes to the passed cell range list. (depreciates writeXfIdRangeProperties) */
+ void writeXfIdRangeListProperties( sal_Int32 nXfId, sal_Int32 nNumFmtId, const ApiCellRangeList& rRanges ) const;
/** Merges the passed merged range and updates right/bottom cell borders. */
void finalizeMergedRange( const ::com::sun::star::table::CellRangeAddress& rRange );
@@ -317,7 +316,8 @@ private:
bool tryExpand( const ::com::sun::star::table::CellAddress& rCellAddr, sal_Int32 nXfId, sal_Int32 nNumFmtId );
bool tryMerge( const XfIdRange& rXfIdRange );
};
- typedef ::std::map< BinAddress, XfIdRange > XfIdRangeMap;
+ typedef ::std::pair< sal_Int32, sal_Int32 > XfIdNumFmtKey;
+ typedef ::std::map< XfIdNumFmtKey, ApiCellRangeList > XfIdRangeListMap;
/** Stores information about a merged cell range. */
struct MergedRange
@@ -340,7 +340,7 @@ private:
maSharedFmlaAddr; /// Address of a cell containing a pending shared formula.
BinAddress maSharedBaseAddr; /// Base address of the pending shared formula.
XfIdRowRange maXfIdRowRange; /// Cached XF identifier for a range of rows.
- XfIdRangeMap maXfIdRanges; /// Collected XF identifiers for cell ranges.
+ XfIdRangeListMap maXfIdRangeLists; /// Collected XF identifiers for cell rangelists.
MergedRangeList maMergedRanges; /// Merged cell ranges.
MergedRangeList maCenterFillRanges; /// Merged cell ranges from 'center across' or 'fill' alignment.
bool mbPendingSharedFmla; /// True = maSharedFmlaAddr and maSharedBaseAddr are valid.
diff --git a/oox/source/xls/sheetdatabuffer.cxx b/oox/source/xls/sheetdatabuffer.cxx
index 76790d675..d97b382eb 100755
--- a/oox/source/xls/sheetdatabuffer.cxx
+++ b/oox/source/xls/sheetdatabuffer.cxx
@@ -545,11 +545,8 @@ void SheetDataBuffer::finalizeImport()
// write default formatting of remaining row range
writeXfIdRowRangeProperties( maXfIdRowRange );
- // try to merge remaining inserted ranges
- mergeXfIdRanges();
- // write all formatting
- for( XfIdRangeMap::const_iterator aIt = maXfIdRanges.begin(), aEnd = maXfIdRanges.end(); aIt != aEnd; ++aIt )
- writeXfIdRangeProperties( aIt->second );
+ for( XfIdRangeListMap::const_iterator aIt = maXfIdRangeLists.begin(), aEnd = maXfIdRangeLists.end(); aIt != aEnd; aIt++ )
+ writeXfIdRangeListProperties( aIt->first.first, aIt->first.second, aIt->second );
// merge all cached merged ranges and update right/bottom cell borders
for( MergedRangeList::iterator aIt = maMergedRanges.begin(), aEnd = maMergedRanges.end(); aIt != aEnd; ++aIt )
@@ -786,35 +783,50 @@ void SheetDataBuffer::setCellFormat( const CellModel& rModel, sal_Int32 nNumFmtI
{
if( (rModel.mnXfId >= 0) || (nNumFmtId >= 0) )
{
- // try to merge existing ranges and to write some formatting properties
- if( !maXfIdRanges.empty() )
+ ApiCellRangeList::reverse_iterator aIt = maXfIdRangeLists[ XfIdNumFmtKey( rModel.mnXfId, nNumFmtId ) ].rbegin();
+ ApiCellRangeList::reverse_iterator aItEnd = maXfIdRangeLists[ XfIdNumFmtKey( rModel.mnXfId, nNumFmtId ) ].rend();
+ /* The xlsx sheet data contains row wise information.
+ * It is sufficient to check if the row range size is one
+ */
+ if( aIt != aItEnd &&
+ aIt->Sheet == rModel.maCellAddr.Sheet &&
+ aIt->StartRow == aIt->EndRow &&
+ aIt->StartRow == rModel.maCellAddr.Row &&
+ (aIt->EndColumn+1) == rModel.maCellAddr.Column )
{
- // get row index of last inserted cell
- sal_Int32 nLastRow = maXfIdRanges.rbegin()->second.maRange.StartRow;
- // row changed - try to merge ranges of last row with existing ranges
- if( rModel.maCellAddr.Row != nLastRow )
+ aIt->EndColumn++; // Expand Column
+ }
+ else
+ {
+ maXfIdRangeLists[ XfIdNumFmtKey (rModel.mnXfId, nNumFmtId ) ].push_back(
+ CellRangeAddress( rModel.maCellAddr.Sheet, rModel.maCellAddr.Column, rModel.maCellAddr.Row,
+ rModel.maCellAddr.Column, rModel.maCellAddr.Row ) );
+ }
+
+ aIt = maXfIdRangeLists[ XfIdNumFmtKey( rModel.mnXfId, nNumFmtId ) ].rbegin();
+ aItEnd = maXfIdRangeLists[ XfIdNumFmtKey( rModel.mnXfId, nNumFmtId ) ].rend();
+ ApiCellRangeList::reverse_iterator aItM = aIt+1;
+ while( aItM != aItEnd )
+ {
+ if( aIt->Sheet == aItM->Sheet )
{
- mergeXfIdRanges();
- // write format properties of all ranges above last row and remove them
- XfIdRangeMap::iterator aIt = maXfIdRanges.begin(), aEnd = maXfIdRanges.end();
- while( aIt != aEnd )
+ /* Try to merge this with the previous range */
+ if( aIt->StartRow == (aItM->EndRow + 1) &&
+ aIt->StartColumn == aItM->StartColumn &&
+ aIt->EndColumn == aItM->EndColumn)
{
- // check that range cannot be merged with current row, and that range is not in cached row range
- if( (aIt->second.maRange.EndRow < nLastRow) && !maXfIdRowRange.intersects( aIt->second.maRange ) )
- {
- writeXfIdRangeProperties( aIt->second );
- maXfIdRanges.erase( aIt++ );
- }
- else
- ++aIt;
+ aItM->EndRow = aIt->EndRow;
+ maXfIdRangeLists[ XfIdNumFmtKey( rModel.mnXfId, nNumFmtId ) ].pop_back();
+ break;
}
+ else if( aIt->StartRow > aItM->EndRow + 1 )
+ break; // Un-necessary to check with any other rows
}
+ else
+ break;
+ aItM++;
}
- // try to expand last existing range, or create new range entry
- if( maXfIdRanges.empty() || !maXfIdRanges.rbegin()->second.tryExpand( rModel.maCellAddr, rModel.mnXfId, nNumFmtId ) )
- maXfIdRanges[ BinAddress( rModel.maCellAddr ) ].set( rModel.maCellAddr, rModel.mnXfId, nNumFmtId );
-
// update merged ranges for 'center across selection' and 'fill'
if( const Xf* pXf = getStyles().getCellXf( rModel.mnXfId ).get() )
{
@@ -846,38 +858,18 @@ void SheetDataBuffer::writeXfIdRowRangeProperties( const XfIdRowRange& rXfIdRowR
}
}
-void SheetDataBuffer::writeXfIdRangeProperties( const XfIdRange& rXfIdRange ) const
+void SheetDataBuffer::writeXfIdRangeListProperties( sal_Int32 nXfId, sal_Int32 nNumFmtId, const ApiCellRangeList& rRanges ) const
{
StylesBuffer& rStyles = getStyles();
PropertyMap aPropMap;
- if( rXfIdRange.mnXfId >= 0 )
- rStyles.writeCellXfToPropertyMap( aPropMap, rXfIdRange.mnXfId );
- if( rXfIdRange.mnNumFmtId >= 0 )
- rStyles.writeNumFmtToPropertyMap( aPropMap, rXfIdRange.mnNumFmtId );
- PropertySet aPropSet( getCellRange( rXfIdRange.maRange ) );
+ if( nXfId >= 0 )
+ rStyles.writeCellXfToPropertyMap( aPropMap, nXfId );
+ if( nNumFmtId >= 0 )
+ rStyles.writeNumFmtToPropertyMap( aPropMap, nNumFmtId );
+ PropertySet aPropSet( getCellRangeList( rRanges ) );
aPropSet.setProperties( aPropMap );
}
-void SheetDataBuffer::mergeXfIdRanges()
-{
- if( !maXfIdRanges.empty() )
- {
- // get row index of last range
- sal_Int32 nLastRow = maXfIdRanges.rbegin()->second.maRange.StartRow;
- // process all ranges located in the same row of the last range
- XfIdRangeMap::iterator aMergeIt = maXfIdRanges.end();
- while( (aMergeIt != maXfIdRanges.begin()) && ((--aMergeIt)->second.maRange.StartRow == nLastRow) )
- {
- const XfIdRange& rMergeXfIdRange = aMergeIt->second;
- // try to find a range that can be merged with rMergeRange
- bool bFound = false;
- for( XfIdRangeMap::iterator aIt = maXfIdRanges.begin(); !bFound && (aIt != aMergeIt); ++aIt )
- if( (bFound = aIt->second.tryMerge( rMergeXfIdRange )) == true )
- maXfIdRanges.erase( aMergeIt++ );
- }
- }
-}
-
void SheetDataBuffer::finalizeMergedRange( const CellRangeAddress& rRange )
{
bool bMultiCol = rRange.StartColumn < rRange.EndColumn;