Line data Source code
1 : /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 : /*
3 : * This file is part of the LibreOffice project.
4 : *
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/.
8 : *
9 : * This file incorporates work covered by the following license notice:
10 : *
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 .
18 : */
19 :
20 :
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"
39 :
40 : #include "scerrors.hxx"
41 : #include "root.hxx"
42 : #include "imp_op.hxx"
43 : #include "excimp8.hxx"
44 : #include "exp_op.hxx"
45 :
46 :
47 21 : FltError ScFormatFilterPluginImpl::ScImportExcel( SfxMedium& rMedium, ScDocument* pDocument, const EXCIMPFORMAT eFormat )
48 : {
49 : // check the passed Calc document
50 : OSL_ENSURE( pDocument, "::ScImportExcel - no document" );
51 21 : if( !pDocument ) return eERR_INTERN; // should not happen
52 :
53 : /* Import all BIFF versions regardless on eFormat, needed for import of
54 : external cells (file type detection returns Excel4.0). */
55 21 : if( (eFormat != EIF_AUTO) && (eFormat != EIF_BIFF_LE4) && (eFormat != EIF_BIFF5) && (eFormat != EIF_BIFF8) )
56 : {
57 : OSL_FAIL( "::ScImportExcel - wrong file format specification" );
58 0 : return eERR_FORMAT;
59 : }
60 :
61 : // check the input stream from medium
62 21 : SvStream* pMedStrm = rMedium.GetInStream();
63 : OSL_ENSURE( pMedStrm, "::ScImportExcel - medium without input stream" );
64 21 : if( !pMedStrm ) return eERR_OPEN; // should not happen
65 :
66 21 : SvStream* pBookStrm = 0; // The "Book"/"Workbook" stream containing main data.
67 21 : XclBiff eBiff = EXC_BIFF_UNKNOWN; // The BIFF version of the main stream.
68 :
69 : // try to open an OLE storage
70 21 : SotStorageRef xRootStrg;
71 21 : SotStorageStreamRef xStrgStrm;
72 21 : if( SotStorage::IsStorageFile( pMedStrm ) )
73 : {
74 21 : xRootStrg = new SotStorage( pMedStrm, false );
75 21 : if( xRootStrg->GetError() )
76 1 : xRootStrg = 0;
77 : }
78 :
79 : // try to open "Book" or "Workbook" stream in OLE storage
80 21 : if( xRootStrg.Is() )
81 : {
82 : // try to open the "Book" stream
83 20 : SotStorageStreamRef xBookStrm = ScfTools::OpenStorageStreamRead( xRootStrg, EXC_STREAM_BOOK );
84 20 : XclBiff eBookBiff = xBookStrm.Is() ? XclImpStream::DetectBiffVersion( *xBookStrm ) : EXC_BIFF_UNKNOWN;
85 :
86 : // try to open the "Workbook" stream
87 20 : SotStorageStreamRef xWorkbookStrm = ScfTools::OpenStorageStreamRead( xRootStrg, EXC_STREAM_WORKBOOK );
88 20 : XclBiff eWorkbookBiff = xWorkbookStrm.Is() ? XclImpStream::DetectBiffVersion( *xWorkbookStrm ) : EXC_BIFF_UNKNOWN;
89 :
90 : // decide which stream to use
91 20 : if( (eWorkbookBiff != EXC_BIFF_UNKNOWN) && ((eBookBiff == EXC_BIFF_UNKNOWN) || (eWorkbookBiff > eBookBiff)) )
92 : {
93 : /* Only "Workbook" stream exists; or both streams exist,
94 : and "Workbook" has higher BIFF version than "Book" stream. */
95 20 : xStrgStrm = xWorkbookStrm;
96 20 : eBiff = eWorkbookBiff;
97 : }
98 0 : else if( eBookBiff != EXC_BIFF_UNKNOWN )
99 : {
100 : /* Only "Book" stream exists; or both streams exist,
101 : and "Book" has higher BIFF version than "Workbook" stream. */
102 0 : xStrgStrm = xBookStrm;
103 0 : eBiff = eBookBiff;
104 : }
105 :
106 20 : pBookStrm = xStrgStrm;
107 : }
108 :
109 : // no "Book" or "Workbook" stream found, try plain input stream from medium (even for BIFF5+)
110 21 : if( !pBookStrm )
111 : {
112 1 : eBiff = XclImpStream::DetectBiffVersion( *pMedStrm );
113 1 : if( eBiff != EXC_BIFF_UNKNOWN )
114 0 : pBookStrm = pMedStrm;
115 : }
116 :
117 : // try to import the file
118 21 : FltError eRet = eERR_UNKN_BIFF;
119 21 : if( pBookStrm )
120 : {
121 20 : pBookStrm->SetBufferSize( 0x8000 ); // still needed?
122 :
123 20 : XclImpRootData aImpData( eBiff, rMedium, xRootStrg, *pDocument, RTL_TEXTENCODING_MS_1252 );
124 20 : ::std::auto_ptr< ImportExcel > xFilter;
125 20 : switch( eBiff )
126 : {
127 : case EXC_BIFF2:
128 : case EXC_BIFF3:
129 : case EXC_BIFF4:
130 : case EXC_BIFF5:
131 0 : xFilter.reset( new ImportExcel( aImpData, *pBookStrm ) );
132 0 : break;
133 : case EXC_BIFF8:
134 20 : xFilter.reset( new ImportExcel8( aImpData, *pBookStrm ) );
135 20 : break;
136 : default: DBG_ERROR_BIFF();
137 : }
138 :
139 20 : eRet = xFilter.get() ? xFilter->Read() : eERR_INTERN;
140 : }
141 :
142 21 : return eRet;
143 : }
144 :
145 :
146 0 : static FltError lcl_ExportExcelBiff( SfxMedium& rMedium, ScDocument *pDocument,
147 : SvStream* pMedStrm, sal_Bool bBiff8, CharSet eNach )
148 : {
149 : // try to open an OLE storage
150 0 : SotStorageRef xRootStrg = new SotStorage( pMedStrm, false );
151 0 : if( xRootStrg->GetError() ) return eERR_OPEN;
152 :
153 : // create BIFF dependent strings
154 0 : String aStrmName, aClipName, aClassName;
155 0 : if( bBiff8 )
156 : {
157 0 : aStrmName = EXC_STREAM_WORKBOOK;
158 0 : aClipName = CREATE_STRING( "Biff8" );
159 0 : aClassName = CREATE_STRING( "Microsoft Excel 97-Tabelle" );
160 : }
161 : else
162 : {
163 0 : aStrmName = EXC_STREAM_BOOK;
164 0 : aClipName = CREATE_STRING( "Biff5" );
165 0 : aClassName = CREATE_STRING( "Microsoft Excel 5.0-Tabelle" );
166 : }
167 :
168 : // open the "Book"/"Workbook" stream
169 0 : SotStorageStreamRef xStrgStrm = ScfTools::OpenStorageStreamWrite( xRootStrg, aStrmName );
170 0 : if( !xStrgStrm.Is() || xStrgStrm->GetError() ) return eERR_OPEN;
171 :
172 0 : xStrgStrm->SetBufferSize( 0x8000 ); // still needed?
173 :
174 0 : FltError eRet = eERR_UNKN_BIFF;
175 0 : XclExpRootData aExpData( bBiff8 ? EXC_BIFF8 : EXC_BIFF5, rMedium, xRootStrg, *pDocument, eNach );
176 0 : if ( bBiff8 )
177 : {
178 0 : ExportBiff8 aFilter( aExpData, *xStrgStrm );
179 0 : eRet = aFilter.Write();
180 : }
181 : else
182 : {
183 0 : ExportBiff5 aFilter( aExpData, *xStrgStrm );
184 0 : eRet = aFilter.Write();
185 : }
186 :
187 0 : if( eRet == eERR_RNGOVRFLW )
188 0 : eRet = SCWARN_EXPORT_MAXROW;
189 :
190 0 : SvGlobalName aGlobName( 0x00020810, 0x0000, 0x0000, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x46 );
191 0 : sal_uInt32 nClip = SotExchange::RegisterFormatName( aClipName );
192 0 : xRootStrg->SetClass( aGlobName, nClip, aClassName );
193 :
194 0 : xStrgStrm->Commit();
195 0 : xRootStrg->Commit();
196 :
197 0 : return eRet;
198 : }
199 :
200 0 : FltError ScFormatFilterPluginImpl::ScExportExcel5( SfxMedium& rMedium, ScDocument *pDocument,
201 : ExportFormatExcel eFormat, CharSet eNach )
202 : {
203 0 : if( eFormat != ExpBiff5 && eFormat != ExpBiff8 )
204 0 : return eERR_NI;
205 :
206 : // check the passed Calc document
207 : OSL_ENSURE( pDocument, "::ScImportExcel - no document" );
208 0 : if( !pDocument ) return eERR_INTERN; // should not happen
209 :
210 : // check the output stream from medium
211 0 : SvStream* pMedStrm = rMedium.GetOutStream();
212 : OSL_ENSURE( pMedStrm, "::ScExportExcel5 - medium without output stream" );
213 0 : if( !pMedStrm ) return eERR_OPEN; // should not happen
214 :
215 0 : FltError eRet = eERR_UNKN_BIFF;
216 0 : if( eFormat == ExpBiff5 || eFormat == ExpBiff8 )
217 0 : eRet = lcl_ExportExcelBiff( rMedium, pDocument, pMedStrm, eFormat == ExpBiff8, eNach );
218 :
219 0 : return eRet;
220 9 : }
221 :
222 :
223 :
224 : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|