Version 4.0.2.1, tag libreoffice-4.0.2.1
[LibreOffice.git] / sc / source / filter / excel / excel.cxx
blob95ce2e3b2db6fd2a17d35d6c3e810deef1f68404
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
3 * This file is part of the LibreOffice project.
5 * This Source Code Form is subject to the terms of the Mozilla Public
6 * License, v. 2.0. If a copy of the MPL was not distributed with this
7 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
9 * This file incorporates work covered by the following license notice:
11 * Licensed to the Apache Software Foundation (ASF) under one or more
12 * contributor license agreements. See the NOTICE file distributed
13 * with this work for additional information regarding copyright
14 * ownership. The ASF licenses this file to you under the Apache
15 * License, Version 2.0 (the "License"); you may not use this file
16 * except in compliance with the License. You may obtain a copy of
17 * the License at http://www.apache.org/licenses/LICENSE-2.0 .
21 #include <sfx2/docfile.hxx>
22 #include <sfx2/objsh.hxx>
23 #include <sfx2/app.hxx>
24 #include <sfx2/frame.hxx>
25 #include <sfx2/request.hxx>
26 #include <sot/storage.hxx>
27 #include <sot/exchange.hxx>
28 #include <tools/globname.hxx>
29 #include <comphelper/mediadescriptor.hxx>
30 #include <comphelper/processfactory.hxx>
31 #include <com/sun/star/beans/NamedValue.hpp>
32 #include <com/sun/star/document/XFilter.hpp>
33 #include <com/sun/star/document/XImporter.hpp>
34 #include "scitems.hxx"
35 #include <svl/stritem.hxx>
36 #include "filter.hxx"
37 #include "document.hxx"
38 #include "xistream.hxx"
40 #include "scerrors.hxx"
41 #include "root.hxx"
42 #include "imp_op.hxx"
43 #include "excimp8.hxx"
44 #include "exp_op.hxx"
47 FltError ScFormatFilterPluginImpl::ScImportExcel( SfxMedium& rMedium, ScDocument* pDocument, const EXCIMPFORMAT eFormat )
49 // check the passed Calc document
50 OSL_ENSURE( pDocument, "::ScImportExcel - no document" );
51 if( !pDocument ) return eERR_INTERN; // should not happen
53 /* Import all BIFF versions regardless on eFormat, needed for import of
54 external cells (file type detection returns Excel4.0). */
55 if( (eFormat != EIF_AUTO) && (eFormat != EIF_BIFF_LE4) && (eFormat != EIF_BIFF5) && (eFormat != EIF_BIFF8) )
57 OSL_FAIL( "::ScImportExcel - wrong file format specification" );
58 return eERR_FORMAT;
61 // check the input stream from medium
62 SvStream* pMedStrm = rMedium.GetInStream();
63 OSL_ENSURE( pMedStrm, "::ScImportExcel - medium without input stream" );
64 if( !pMedStrm ) return eERR_OPEN; // should not happen
66 SvStream* pBookStrm = 0; // The "Book"/"Workbook" stream containing main data.
67 XclBiff eBiff = EXC_BIFF_UNKNOWN; // The BIFF version of the main stream.
69 // try to open an OLE storage
70 SotStorageRef xRootStrg;
71 SotStorageStreamRef xStrgStrm;
72 if( SotStorage::IsStorageFile( pMedStrm ) )
74 xRootStrg = new SotStorage( pMedStrm, false );
75 if( xRootStrg->GetError() )
76 xRootStrg = 0;
79 // try to open "Book" or "Workbook" stream in OLE storage
80 if( xRootStrg.Is() )
82 // try to open the "Book" stream
83 SotStorageStreamRef xBookStrm = ScfTools::OpenStorageStreamRead( xRootStrg, EXC_STREAM_BOOK );
84 XclBiff eBookBiff = xBookStrm.Is() ? XclImpStream::DetectBiffVersion( *xBookStrm ) : EXC_BIFF_UNKNOWN;
86 // try to open the "Workbook" stream
87 SotStorageStreamRef xWorkbookStrm = ScfTools::OpenStorageStreamRead( xRootStrg, EXC_STREAM_WORKBOOK );
88 XclBiff eWorkbookBiff = xWorkbookStrm.Is() ? XclImpStream::DetectBiffVersion( *xWorkbookStrm ) : EXC_BIFF_UNKNOWN;
90 // decide which stream to use
91 if( (eWorkbookBiff != EXC_BIFF_UNKNOWN) && ((eBookBiff == EXC_BIFF_UNKNOWN) || (eWorkbookBiff > eBookBiff)) )
93 /* Only "Workbook" stream exists; or both streams exist,
94 and "Workbook" has higher BIFF version than "Book" stream. */
95 xStrgStrm = xWorkbookStrm;
96 eBiff = eWorkbookBiff;
98 else if( eBookBiff != EXC_BIFF_UNKNOWN )
100 /* Only "Book" stream exists; or both streams exist,
101 and "Book" has higher BIFF version than "Workbook" stream. */
102 xStrgStrm = xBookStrm;
103 eBiff = eBookBiff;
106 pBookStrm = xStrgStrm;
109 // no "Book" or "Workbook" stream found, try plain input stream from medium (even for BIFF5+)
110 if( !pBookStrm )
112 eBiff = XclImpStream::DetectBiffVersion( *pMedStrm );
113 if( eBiff != EXC_BIFF_UNKNOWN )
114 pBookStrm = pMedStrm;
117 // try to import the file
118 FltError eRet = eERR_UNKN_BIFF;
119 if( pBookStrm )
121 pBookStrm->SetBufferSize( 0x8000 ); // still needed?
123 XclImpRootData aImpData( eBiff, rMedium, xRootStrg, *pDocument, RTL_TEXTENCODING_MS_1252 );
124 ::std::auto_ptr< ImportExcel > xFilter;
125 switch( eBiff )
127 case EXC_BIFF2:
128 case EXC_BIFF3:
129 case EXC_BIFF4:
130 case EXC_BIFF5:
131 xFilter.reset( new ImportExcel( aImpData, *pBookStrm ) );
132 break;
133 case EXC_BIFF8:
134 xFilter.reset( new ImportExcel8( aImpData, *pBookStrm ) );
135 break;
136 default: DBG_ERROR_BIFF();
139 eRet = xFilter.get() ? xFilter->Read() : eERR_INTERN;
142 return eRet;
146 static FltError lcl_ExportExcelBiff( SfxMedium& rMedium, ScDocument *pDocument,
147 SvStream* pMedStrm, sal_Bool bBiff8, CharSet eNach )
149 // try to open an OLE storage
150 SotStorageRef xRootStrg = new SotStorage( pMedStrm, false );
151 if( xRootStrg->GetError() ) return eERR_OPEN;
153 // create BIFF dependent strings
154 String aStrmName, aClipName, aClassName;
155 if( bBiff8 )
157 aStrmName = EXC_STREAM_WORKBOOK;
158 aClipName = CREATE_STRING( "Biff8" );
159 aClassName = CREATE_STRING( "Microsoft Excel 97-Tabelle" );
161 else
163 aStrmName = EXC_STREAM_BOOK;
164 aClipName = CREATE_STRING( "Biff5" );
165 aClassName = CREATE_STRING( "Microsoft Excel 5.0-Tabelle" );
168 // open the "Book"/"Workbook" stream
169 SotStorageStreamRef xStrgStrm = ScfTools::OpenStorageStreamWrite( xRootStrg, aStrmName );
170 if( !xStrgStrm.Is() || xStrgStrm->GetError() ) return eERR_OPEN;
172 xStrgStrm->SetBufferSize( 0x8000 ); // still needed?
174 FltError eRet = eERR_UNKN_BIFF;
175 XclExpRootData aExpData( bBiff8 ? EXC_BIFF8 : EXC_BIFF5, rMedium, xRootStrg, *pDocument, eNach );
176 if ( bBiff8 )
178 ExportBiff8 aFilter( aExpData, *xStrgStrm );
179 eRet = aFilter.Write();
181 else
183 ExportBiff5 aFilter( aExpData, *xStrgStrm );
184 eRet = aFilter.Write();
187 if( eRet == eERR_RNGOVRFLW )
188 eRet = SCWARN_EXPORT_MAXROW;
190 SvGlobalName aGlobName( 0x00020810, 0x0000, 0x0000, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x46 );
191 sal_uInt32 nClip = SotExchange::RegisterFormatName( aClipName );
192 xRootStrg->SetClass( aGlobName, nClip, aClassName );
194 xStrgStrm->Commit();
195 xRootStrg->Commit();
197 return eRet;
200 FltError ScFormatFilterPluginImpl::ScExportExcel5( SfxMedium& rMedium, ScDocument *pDocument,
201 ExportFormatExcel eFormat, CharSet eNach )
203 if( eFormat != ExpBiff5 && eFormat != ExpBiff8 )
204 return eERR_NI;
206 // check the passed Calc document
207 OSL_ENSURE( pDocument, "::ScImportExcel - no document" );
208 if( !pDocument ) return eERR_INTERN; // should not happen
210 // check the output stream from medium
211 SvStream* pMedStrm = rMedium.GetOutStream();
212 OSL_ENSURE( pMedStrm, "::ScExportExcel5 - medium without output stream" );
213 if( !pMedStrm ) return eERR_OPEN; // should not happen
215 FltError eRet = eERR_UNKN_BIFF;
216 if( eFormat == ExpBiff5 || eFormat == ExpBiff8 )
217 eRet = lcl_ExportExcelBiff( rMedium, pDocument, pMedStrm, eFormat == ExpBiff8, eNach );
219 return eRet;
224 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */