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