update ooo310-m15
[ooovba.git] / sc / source / filter / excel / excel.cxx
blobd19958df2ede8a639ca0c7e890150b99fc1dc718
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>
46 #include "filter.hxx"
47 #include "document.hxx"
48 #include "xistream.hxx"
50 #include "scerrors.hxx"
51 #include "root.hxx"
52 #include "imp_op.hxx"
53 #include "excimp8.hxx"
54 #include "exp_op.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" );
68 return eERR_FORMAT;
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();
99 // call the filter
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
104 if( !bResult )
105 return ERRCODE_ABORT;
107 // if OOX filter has been used, exit with OK code
108 if( bUseOoxFilter )
109 return eERR_OK;
111 catch( uno::Exception& )
113 if( bUseOoxFilter )
114 return ERRCODE_ABORT;
115 // else ignore exception and import the document with this filter
117 #endif
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() )
129 xRootStrg = 0;
132 // try to open "Book" or "Workbook" stream in OLE storage
133 if( xRootStrg.Is() )
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+)
163 if( !pBookStrm )
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;
172 if( pBookStrm )
174 pBookStrm->SetBufferSize( 0x8000 ); // still needed?
176 XclImpRootData aImpData( eBiff, rMedium, xRootStrg, *pDocument, RTL_TEXTENCODING_MS_1252 );
177 ::std::auto_ptr< ImportExcel > xFilter;
178 switch( eBiff )
180 case EXC_BIFF2:
181 case EXC_BIFF3:
182 case EXC_BIFF4:
183 case EXC_BIFF5:
184 xFilter.reset( new ImportExcel( aImpData, *pBookStrm ) );
185 break;
186 case EXC_BIFF8:
187 xFilter.reset( new ImportExcel8( aImpData, *pBookStrm ) );
188 break;
189 default: DBG_ERROR_BIFF();
192 eRet = xFilter.get() ? xFilter->Read() : eERR_INTERN;
195 return eRet;
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;
208 if( bBiff8 )
210 aStrmName = EXC_STREAM_WORKBOOK;
211 aClipName = CREATE_STRING( "Biff8" );
212 aClassName = CREATE_STRING( "Microsoft Excel 97-Tabelle" );
214 else
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 );
229 if ( bBiff8 )
231 ExportBiff8 aFilter( aExpData, *xStrgStrm );
232 eRet = aFilter.Write();
234 else
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 );
247 xStrgStrm->Commit();
248 xRootStrg->Commit();
250 return eRet;
253 FltError ScFormatFilterPluginImpl::ScExportExcel5( SfxMedium& rMedium, ScDocument *pDocument,
254 ExportFormatExcel eFormat, CharSet eNach )
256 if( eFormat != ExpBiff5 && eFormat != ExpBiff8 )
257 return eERR_NI;
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 );
272 return eRet;