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 .
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>
35 #include "document.hxx"
36 #include "xistream.hxx"
38 #include "scerrors.hxx"
41 #include "excimp8.hxx"
44 #include <boost/scoped_ptr.hpp>
46 FltError
ScFormatFilterPluginImpl::ScImportExcel( SfxMedium
& rMedium
, ScDocument
* pDocument
, const EXCIMPFORMAT eFormat
)
48 // check the passed Calc document
49 OSL_ENSURE( pDocument
, "::ScImportExcel - no document" );
50 if( !pDocument
) return eERR_INTERN
; // should not happen
52 /* Import all BIFF versions regardless on eFormat, needed for import of
53 external cells (file type detection returns Excel4.0). */
54 if( (eFormat
!= EIF_AUTO
) && (eFormat
!= EIF_BIFF_LE4
) && (eFormat
!= EIF_BIFF5
) && (eFormat
!= EIF_BIFF8
) )
56 OSL_FAIL( "::ScImportExcel - wrong file format specification" );
60 // check the input stream from medium
61 SvStream
* pMedStrm
= rMedium
.GetInStream();
62 OSL_ENSURE( pMedStrm
, "::ScImportExcel - medium without input stream" );
63 if( !pMedStrm
) return eERR_OPEN
; // should not happen
65 SvStream
* pBookStrm
= 0; // The "Book"/"Workbook" stream containing main data.
66 XclBiff eBiff
= EXC_BIFF_UNKNOWN
; // The BIFF version of the main stream.
68 // try to open an OLE storage
69 tools::SvRef
<SotStorage
> xRootStrg
;
70 tools::SvRef
<SotStorageStream
> xStrgStrm
;
71 if( SotStorage::IsStorageFile( pMedStrm
) )
73 xRootStrg
= new SotStorage( pMedStrm
, false );
74 if( xRootStrg
->GetError() )
78 // try to open "Book" or "Workbook" stream in OLE storage
81 // try to open the "Book" stream
82 tools::SvRef
<SotStorageStream
> xBookStrm
= ScfTools::OpenStorageStreamRead( xRootStrg
, EXC_STREAM_BOOK
);
83 XclBiff eBookBiff
= xBookStrm
.Is() ? XclImpStream::DetectBiffVersion( *xBookStrm
) : EXC_BIFF_UNKNOWN
;
85 // try to open the "Workbook" stream
86 tools::SvRef
<SotStorageStream
> xWorkbookStrm
= ScfTools::OpenStorageStreamRead( xRootStrg
, EXC_STREAM_WORKBOOK
);
87 XclBiff eWorkbookBiff
= xWorkbookStrm
.Is() ? XclImpStream::DetectBiffVersion( *xWorkbookStrm
) : EXC_BIFF_UNKNOWN
;
89 // decide which stream to use
90 if( (eWorkbookBiff
!= EXC_BIFF_UNKNOWN
) && ((eBookBiff
== EXC_BIFF_UNKNOWN
) || (eWorkbookBiff
> eBookBiff
)) )
92 /* Only "Workbook" stream exists; or both streams exist,
93 and "Workbook" has higher BIFF version than "Book" stream. */
94 xStrgStrm
= xWorkbookStrm
;
95 eBiff
= eWorkbookBiff
;
97 else if( eBookBiff
!= EXC_BIFF_UNKNOWN
)
99 /* Only "Book" stream exists; or both streams exist,
100 and "Book" has higher BIFF version than "Workbook" stream. */
101 xStrgStrm
= xBookStrm
;
105 pBookStrm
= xStrgStrm
;
108 // no "Book" or "Workbook" stream found, try plain input stream from medium (even for BIFF5+)
111 eBiff
= XclImpStream::DetectBiffVersion( *pMedStrm
);
112 if( eBiff
!= EXC_BIFF_UNKNOWN
)
113 pBookStrm
= pMedStrm
;
116 // try to import the file
117 FltError eRet
= eERR_UNKN_BIFF
;
120 pBookStrm
->SetBufferSize( 0x8000 ); // still needed?
122 XclImpRootData
aImpData( eBiff
, rMedium
, xRootStrg
, *pDocument
, RTL_TEXTENCODING_MS_1252
);
123 boost::scoped_ptr
< ImportExcel
> xFilter
;
130 xFilter
.reset( new ImportExcel( aImpData
, *pBookStrm
) );
133 xFilter
.reset( new ImportExcel8( aImpData
, *pBookStrm
) );
135 default: DBG_ERROR_BIFF();
138 eRet
= xFilter
.get() ? xFilter
->Read() : eERR_INTERN
;
144 static FltError
lcl_ExportExcelBiff( SfxMedium
& rMedium
, ScDocument
*pDocument
,
145 SvStream
* pMedStrm
, bool bBiff8
, rtl_TextEncoding eNach
)
147 // try to open an OLE storage
148 tools::SvRef
<SotStorage
> xRootStrg
= new SotStorage( pMedStrm
, false );
149 if( xRootStrg
->GetError() ) return eERR_OPEN
;
151 // create BIFF dependent strings
152 OUString aStrmName
, aClipName
, aClassName
;
155 aStrmName
= EXC_STREAM_WORKBOOK
;
157 aClassName
= "Microsoft Excel 97-Tabelle";
161 aStrmName
= EXC_STREAM_BOOK
;
163 aClassName
= "Microsoft Excel 5.0-Tabelle";
166 // open the "Book"/"Workbook" stream
167 tools::SvRef
<SotStorageStream
> xStrgStrm
= ScfTools::OpenStorageStreamWrite( xRootStrg
, aStrmName
);
168 if( !xStrgStrm
.Is() || xStrgStrm
->GetError() ) return eERR_OPEN
;
170 xStrgStrm
->SetBufferSize( 0x8000 ); // still needed?
172 FltError eRet
= eERR_UNKN_BIFF
;
173 XclExpRootData
aExpData( bBiff8
? EXC_BIFF8
: EXC_BIFF5
, rMedium
, xRootStrg
, *pDocument
, eNach
);
176 ExportBiff8
aFilter( aExpData
, *xStrgStrm
);
177 eRet
= aFilter
.Write();
181 ExportBiff5
aFilter( aExpData
, *xStrgStrm
);
182 eRet
= aFilter
.Write();
185 if( eRet
== eERR_RNGOVRFLW
)
186 eRet
= SCWARN_EXPORT_MAXROW
;
188 SvGlobalName
aGlobName( 0x00020810, 0x0000, 0x0000, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x46 );
189 SotClipboardFormatId nClip
= SotExchange::RegisterFormatName( aClipName
);
190 xRootStrg
->SetClass( aGlobName
, nClip
, aClassName
);
198 FltError
ScFormatFilterPluginImpl::ScExportExcel5( SfxMedium
& rMedium
, ScDocument
*pDocument
,
199 ExportFormatExcel eFormat
, rtl_TextEncoding eNach
)
201 if( eFormat
!= ExpBiff5
&& eFormat
!= ExpBiff8
)
204 // check the passed Calc document
205 OSL_ENSURE( pDocument
, "::ScImportExcel - no document" );
206 if( !pDocument
) return eERR_INTERN
; // should not happen
208 // check the output stream from medium
209 SvStream
* pMedStrm
= rMedium
.GetOutStream();
210 OSL_ENSURE( pMedStrm
, "::ScExportExcel5 - medium without output stream" );
211 if( !pMedStrm
) return eERR_OPEN
; // should not happen
213 FltError eRet
= eERR_UNKN_BIFF
;
214 if( eFormat
== ExpBiff5
|| eFormat
== ExpBiff8
)
215 eRet
= lcl_ExportExcelBiff( rMedium
, pDocument
, pMedStrm
, eFormat
== ExpBiff8
, eNach
);
220 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */