1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
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>
37 #include "document.hxx"
38 #include "xistream.hxx"
40 #include "scerrors.hxx"
43 #include "excimp8.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" );
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() )
79 // try to open "Book" or "Workbook" stream in OLE storage
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
;
106 pBookStrm
= xStrgStrm
;
109 // no "Book" or "Workbook" stream found, try plain input stream from medium (even for BIFF5+)
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
;
121 pBookStrm
->SetBufferSize( 0x8000 ); // still needed?
123 XclImpRootData
aImpData( eBiff
, rMedium
, xRootStrg
, *pDocument
, RTL_TEXTENCODING_MS_1252
);
124 ::std::auto_ptr
< ImportExcel
> xFilter
;
131 xFilter
.reset( new ImportExcel( aImpData
, *pBookStrm
) );
134 xFilter
.reset( new ImportExcel8( aImpData
, *pBookStrm
) );
136 default: DBG_ERROR_BIFF();
139 eRet
= xFilter
.get() ? xFilter
->Read() : eERR_INTERN
;
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
;
157 aStrmName
= EXC_STREAM_WORKBOOK
;
158 aClipName
= CREATE_STRING( "Biff8" );
159 aClassName
= CREATE_STRING( "Microsoft Excel 97-Tabelle" );
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
);
178 ExportBiff8
aFilter( aExpData
, *xStrgStrm
);
179 eRet
= aFilter
.Write();
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
);
200 FltError
ScFormatFilterPluginImpl::ScExportExcel5( SfxMedium
& rMedium
, ScDocument
*pDocument
,
201 ExportFormatExcel eFormat
, CharSet eNach
)
203 if( eFormat
!= ExpBiff5
&& eFormat
!= ExpBiff8
)
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
);
224 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */