1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5 * Copyright 2008 by Sun Microsystems, Inc.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * $RCSfile: excel.cxx,v $
10 * $Revision: 1.26.32.2 $
12 * This file is part of OpenOffice.org.
14 * OpenOffice.org is free software: you can redistribute it and/or modify
15 * it under the terms of the GNU Lesser General Public License version 3
16 * only, as published by the Free Software Foundation.
18 * OpenOffice.org is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU Lesser General Public License version 3 for more details
22 * (a copy is included in the LICENSE file that accompanied this code).
24 * You should have received a copy of the GNU Lesser General Public License
25 * version 3 along with OpenOffice.org. If not, see
26 * <http://www.openoffice.org/license.html>
27 * for a copy of the LGPLv3 License.
29 ************************************************************************/
31 // MARKER(update_precomp.py): autogen include statement, do not remove
32 #include "precompiled_sc.hxx"
34 #include <sfx2/docfile.hxx>
35 #include <sfx2/objsh.hxx>
36 #include <sfx2/app.hxx>
37 #include <sot/storage.hxx>
38 #include <sot/exchange.hxx>
39 #include <tools/globname.hxx>
40 #include <comphelper/mediadescriptor.hxx>
41 #include <comphelper/processfactory.hxx>
42 #include <com/sun/star/document/XFilter.hpp>
43 #include <com/sun/star/document/XImporter.hpp>
44 #include "scitems.hxx"
45 #include <svtools/stritem.hxx>
47 #include "document.hxx"
48 #include "xistream.hxx"
50 #include "scerrors.hxx"
53 #include "excimp8.hxx"
57 FltError
ScFormatFilterPluginImpl::ScImportExcel( SfxMedium
& rMedium
, ScDocument
* pDocument
, const EXCIMPFORMAT eFormat
)
59 // check the passed Calc document
60 DBG_ASSERT( pDocument
, "::ScImportExcel - no document" );
61 if( !pDocument
) return eERR_INTERN
; // should not happen
63 /* Import all BIFF versions regardless on eFormat, needed for import of
64 external cells (file type detection returns Excel4.0). */
65 if( (eFormat
!= EIF_AUTO
) && (eFormat
!= EIF_BIFF_LE4
) && (eFormat
!= EIF_BIFF5
) && (eFormat
!= EIF_BIFF8
) )
67 DBG_ERRORFILE( "::ScImportExcel - wrong file format specification" );
71 // check the input stream from medium
72 SvStream
* pMedStrm
= rMedium
.GetInStream();
73 DBG_ASSERT( pMedStrm
, "::ScImportExcel - medium without input stream" );
74 if( !pMedStrm
) return eERR_OPEN
; // should not happen
76 #if OSL_DEBUG_LEVEL > 0
77 using namespace ::com::sun::star
;
78 using namespace ::comphelper
;
80 // false = use old sc filter for import (OOX only as file dumper), true = use new OOX filter for import
81 bool bUseOoxFilter
= false;
82 if( SfxObjectShell
* pDocShell
= pDocument
->GetDocumentShell() ) try
84 uno::Reference
< lang::XComponent
> xComponent( pDocShell
->GetModel(), uno::UNO_QUERY_THROW
);
86 uno::Sequence
< uno::Any
> aArgs( 2 );
87 aArgs
[ 0 ] <<= getProcessServiceFactory();
88 aArgs
[ 1 ] <<= !bUseOoxFilter
;
89 uno::Reference
< document::XImporter
> xImporter( ScfApiHelper::CreateInstanceWithArgs(
90 CREATE_STRING( "com.sun.star.comp.oox.ExcelBiffFilter" ), aArgs
), uno::UNO_QUERY_THROW
);
91 xImporter
->setTargetDocument( xComponent
);
93 MediaDescriptor aDescriptor
;
94 if( const SfxItemSet
* pItemSet
= rMedium
.GetItemSet() )
95 if( const SfxStringItem
* pItem
= static_cast< const SfxStringItem
* >( pItemSet
->GetItem( SID_FILE_NAME
) ) )
96 aDescriptor
[ MediaDescriptor::PROP_URL() ] <<= ::rtl::OUString( pItem
->GetValue() );
97 aDescriptor
[ MediaDescriptor::PROP_INPUTSTREAM() ] <<= rMedium
.GetInputStream();
100 uno::Reference
< document::XFilter
> xFilter( xImporter
, uno::UNO_QUERY_THROW
);
101 bool bResult
= xFilter
->filter( aDescriptor
.getAsConstPropertyValueList() );
103 // if filter returns false, document is invalid, or dumper has disabled import -> exit here
105 return ERRCODE_ABORT
;
107 // if OOX filter has been used, exit with OK code
111 catch( uno::Exception
& )
114 return ERRCODE_ABORT
;
115 // else ignore exception and import the document with this filter
119 SvStream
* pBookStrm
= 0; // The "Book"/"Workbook" stream containing main data.
120 XclBiff eBiff
= EXC_BIFF_UNKNOWN
; // The BIFF version of the main stream.
122 // try to open an OLE storage
123 SotStorageRef xRootStrg
;
124 SotStorageStreamRef xStrgStrm
;
125 if( SotStorage::IsStorageFile( pMedStrm
) )
127 xRootStrg
= new SotStorage( pMedStrm
, FALSE
);
128 if( xRootStrg
->GetError() )
132 // try to open "Book" or "Workbook" stream in OLE storage
135 // try to open the "Book" stream
136 SotStorageStreamRef xBookStrm5
= ScfTools::OpenStorageStreamRead( xRootStrg
, EXC_STREAM_BOOK
);
137 XclBiff eBookStrm5Biff
= xBookStrm5
.Is() ? XclImpStream::DetectBiffVersion( *xBookStrm5
) : EXC_BIFF_UNKNOWN
;
139 // try to open the "Workbook" stream
140 SotStorageStreamRef xBookStrm8
= ScfTools::OpenStorageStreamRead( xRootStrg
, EXC_STREAM_WORKBOOK
);
141 XclBiff eBookStrm8Biff
= xBookStrm8
.Is() ? XclImpStream::DetectBiffVersion( *xBookStrm8
) : EXC_BIFF_UNKNOWN
;
143 // decide which stream to use
144 if( (eBookStrm8Biff
!= EXC_BIFF_UNKNOWN
) && ((eBookStrm5Biff
== EXC_BIFF_UNKNOWN
) || (eBookStrm8Biff
> eBookStrm5Biff
)) )
146 /* Only "Workbook" stream exists; or both streams exist,
147 and "Workbook" has higher BIFF version than "Book" stream. */
148 xStrgStrm
= xBookStrm8
;
149 eBiff
= eBookStrm8Biff
;
151 else if( eBookStrm5Biff
!= EXC_BIFF_UNKNOWN
)
153 /* Only "Book" stream exists; or both streams exist,
154 and "Book" has higher BIFF version than "Workbook" stream. */
155 xStrgStrm
= xBookStrm5
;
156 eBiff
= eBookStrm5Biff
;
159 pBookStrm
= xStrgStrm
;
162 // no "Book" or "Workbook" stream found, try plain input stream from medium (even for BIFF5+)
165 eBiff
= XclImpStream::DetectBiffVersion( *pMedStrm
);
166 if( eBiff
!= EXC_BIFF_UNKNOWN
)
167 pBookStrm
= pMedStrm
;
170 // try to import the file
171 FltError eRet
= eERR_UNKN_BIFF
;
174 pBookStrm
->SetBufferSize( 0x8000 ); // still needed?
176 XclImpRootData
aImpData( eBiff
, rMedium
, xRootStrg
, *pDocument
, RTL_TEXTENCODING_MS_1252
);
177 ::std::auto_ptr
< ImportExcel
> xFilter
;
184 xFilter
.reset( new ImportExcel( aImpData
, *pBookStrm
) );
187 xFilter
.reset( new ImportExcel8( aImpData
, *pBookStrm
) );
189 default: DBG_ERROR_BIFF();
192 eRet
= xFilter
.get() ? xFilter
->Read() : eERR_INTERN
;
199 static FltError
lcl_ExportExcelBiff( SfxMedium
& rMedium
, ScDocument
*pDocument
,
200 SvStream
* pMedStrm
, BOOL bBiff8
, CharSet eNach
)
202 // try to open an OLE storage
203 SotStorageRef xRootStrg
= new SotStorage( pMedStrm
, FALSE
);
204 if( xRootStrg
->GetError() ) return eERR_OPEN
;
206 // create BIFF dependent strings
207 String aStrmName
, aClipName
, aClassName
;
210 aStrmName
= EXC_STREAM_WORKBOOK
;
211 aClipName
= CREATE_STRING( "Biff8" );
212 aClassName
= CREATE_STRING( "Microsoft Excel 97-Tabelle" );
216 aStrmName
= EXC_STREAM_BOOK
;
217 aClipName
= CREATE_STRING( "Biff5" );
218 aClassName
= CREATE_STRING( "Microsoft Excel 5.0-Tabelle" );
221 // open the "Book"/"Workbook" stream
222 SotStorageStreamRef xStrgStrm
= ScfTools::OpenStorageStreamWrite( xRootStrg
, aStrmName
);
223 if( !xStrgStrm
.Is() || xStrgStrm
->GetError() ) return eERR_OPEN
;
225 xStrgStrm
->SetBufferSize( 0x8000 ); // still needed?
227 FltError eRet
= eERR_UNKN_BIFF
;
228 XclExpRootData
aExpData( bBiff8
? EXC_BIFF8
: EXC_BIFF5
, rMedium
, xRootStrg
, *pDocument
, eNach
);
231 ExportBiff8
aFilter( aExpData
, *xStrgStrm
);
232 eRet
= aFilter
.Write();
236 ExportBiff5
aFilter( aExpData
, *xStrgStrm
);
237 eRet
= aFilter
.Write();
240 if( eRet
== eERR_RNGOVRFLW
)
241 eRet
= SCWARN_EXPORT_MAXROW
;
243 SvGlobalName
aGlobName( 0x00020810, 0x0000, 0x0000, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x46 );
244 sal_uInt32 nClip
= SotExchange::RegisterFormatName( aClipName
);
245 xRootStrg
->SetClass( aGlobName
, nClip
, aClassName
);
253 FltError
ScFormatFilterPluginImpl::ScExportExcel5( SfxMedium
& rMedium
, ScDocument
*pDocument
,
254 ExportFormatExcel eFormat
, CharSet eNach
)
256 if( eFormat
!= ExpBiff5
&& eFormat
!= ExpBiff8
)
259 // check the passed Calc document
260 DBG_ASSERT( pDocument
, "::ScImportExcel - no document" );
261 if( !pDocument
) return eERR_INTERN
; // should not happen
263 // check the output stream from medium
264 SvStream
* pMedStrm
= rMedium
.GetOutStream();
265 DBG_ASSERT( pMedStrm
, "::ScExportExcel5 - medium without output stream" );
266 if( !pMedStrm
) return eERR_OPEN
; // should not happen
268 FltError eRet
= eERR_UNKN_BIFF
;
269 if( eFormat
== ExpBiff5
|| eFormat
== ExpBiff8
)
270 eRet
= lcl_ExportExcelBiff( rMedium
, pDocument
, pMedStrm
, eFormat
== ExpBiff8
, eNach
);