excelimport.cpp
1/* This file is part of the KDE project
2 Copyright (C) 2003-2006 Ariya Hidayat <ariya@kde.org>
3 Copyright (C) 2006 Marijn Kruisselbrink <m.kruisselbrink@student.tue.nl>
4
5 This library is free software; you can redistribute it and/or
6 modify it under the terms of the GNU Library General Public
7 License as published by the Free Software Foundation; either
8 version 2 of the License, or (at your option) any later version.
9
10 This library is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 Library General Public License for more details.
14
15 You should have received a copy of the GNU Library General Public License
16 along with this library; see the file COPYING.LIB. If not, write to
17 the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
18 * Boston, MA 02110-1301, USA.
19*/
20
21#include <config.h>
22
23#ifdef HAVE_UNISTD_H
24#include <unistd.h>
25#endif
26
27#include <excelimport.h>
28#include <excelimport.moc>
29
30#include <tqbuffer.h>
31#include <tqcstring.h>
32#include <tqdatetime.h>
33#include <tqfile.h>
34#include <tqmap.h>
35#include <tqstring.h>
36#include <tqtextstream.h>
37
38#include <kdebug.h>
39#include <KoFilterChain.h>
40#include <KoGlobal.h>
41#include <KoUnit.h>
42#include <kgenericfactory.h>
43
44#include <KoXmlWriter.h>
45#include <KoOasisStore.h>
46
47#include "swinder.h"
48#include <iostream>
49
50typedef KGenericFactory<ExcelImport, KoFilter> ExcelImportFactory;
51K_EXPORT_COMPONENT_FACTORY( libexcelimport, ExcelImportFactory( "kofficefilters" ) )
52
53
54// UString -> TQConstString conversion. Use .string() to get the TQString.
55// Always store the TQConstString into a variable first, to avoid a deep copy.
56inline TQConstString string( const Swinder::UString& str ) {
57 // Let's hope there's no copying of the TQConstString happening...
58 return TQConstString( reinterpret_cast<const TQChar*>( str.data() ), str.length() );
59}
60
61using namespace Swinder;
62
63class ExcelImport::Private
64{
65public:
66 TQString inputFile;
67 TQString outputFile;
68
69 Workbook *workbook;
70
71 bool createStyles( KoOasisStore* store );
72 bool createContent( KoOasisStore* store );
73 bool createManifest( KoOasisStore* store );
74
75 int sheetFormatIndex;
76 int columnFormatIndex;
77 int rowFormatIndex;
78
79 TQMap<int,bool> styleFormats;
80 TQMap<int,bool> isPercentageStyle;
81 TQMap<int,bool> isDateStyle;
82 TQMap<int,bool> isTimeStyle;
83
84 void processWorkbookForBody( Workbook* workbook, KoXmlWriter* xmlWriter );
85 void processWorkbookForStyle( Workbook* workbook, KoXmlWriter* xmlWriter );
86 void processSheetForBody( Sheet* sheet, KoXmlWriter* xmlWriter );
87 void processSheetForStyle( Sheet* sheet, KoXmlWriter* xmlWriter );
88 void processColumnForBody( Column* column, int repeat, KoXmlWriter* xmlWriter );
89 void processColumnForStyle( Column* column, int repeat, KoXmlWriter* xmlWriter );
90 void processRowForBody( Row* row, int repeat, KoXmlWriter* xmlWriter );
91 void processRowForStyle( Row* row, int repeat, KoXmlWriter* xmlWriter );
92 void processCellForBody( Cell* cell, KoXmlWriter* xmlWriter );
93 void processCellForStyle( Cell* cell, KoXmlWriter* xmlWriter );
94 void processFormat( const Format* format, KoXmlWriter* xmlWriter );
95 void processValueFormat( TQString valueFormat, TQString refName, KoXmlWriter* xmlWriter );
96};
97
98
99ExcelImport::ExcelImport ( TQObject*, const char*, const TQStringList& )
100 : KoFilter()
101{
102 d = new Private;
103}
104
105ExcelImport::~ExcelImport()
106{
107 delete d;
108}
109
110KoFilter::ConversionStatus ExcelImport::convert( const TQCString& from, const TQCString& to )
111{
112 if ( from != "application/msexcel" )
113 return KoFilter::NotImplemented;
114
115 if ( to != "application/vnd.oasis.opendocument.spreadsheet" )
116 return KoFilter::NotImplemented;
117
118 d->inputFile = m_chain->inputFile();
119 d->outputFile = m_chain->outputFile();
120
121 TQTime time;
122 time.start();
123
124 // open inputFile
125 d->workbook = new Swinder::Workbook;
126 if( !d->workbook->load( d->inputFile.local8Bit() ) )
127 {
128 delete d->workbook;
129 d->workbook = 0;
130 return KoFilter::StupidError;
131 }
132
133 if( d->workbook->isPasswordProtected() )
134 {
135 delete d->workbook;
136 d->workbook = 0;
137 return KoFilter::PasswordProtected;
138 }
139
140 kdDebug(30511) << "File " << d->inputFile << " loaded. Time: " << time.elapsed() << " ms " << endl;
141 time.restart();
142
143 // create output store
144 KoStore* storeout;
145 storeout = KoStore::createStore( d->outputFile, KoStore::Write,
146 "application/vnd.oasis.opendocument.spreadsheet", KoStore::Zip );
147
148 if ( !storeout )
149 {
150 kdWarning() << "Couldn't open the requested file." << endl;
151 delete d->workbook;
152 return KoFilter::FileNotFound;
153 }
154
155 // Tell KoStore not to touch the file names
156 storeout->disallowNameExpansion();
157 KoOasisStore oasisStore( storeout );
158
159 // store document styles
160 d->sheetFormatIndex = 1;
161 d->columnFormatIndex = 1;
162 d->rowFormatIndex = 1;
163 if ( !d->createStyles( &oasisStore ) )
164 {
165 kdWarning() << "Couldn't open the file 'styles.xml'." << endl;
166 delete d->workbook;
167 delete storeout;
168 return KoFilter::CreationError;
169 }
170
171 // store document content
172 d->sheetFormatIndex = 1;
173 d->columnFormatIndex = 1;
174 d->rowFormatIndex = 1;
175 if ( !d->createContent( &oasisStore ) )
176 {
177 kdWarning() << "Couldn't open the file 'content.xml'." << endl;
178 delete d->workbook;
179 delete storeout;
180 return KoFilter::CreationError;
181 }
182
183 // store document manifest
184 if ( !d->createManifest( &oasisStore ) )
185 {
186 kdWarning() << "Couldn't open the file 'META-INF/manifest.xml'." << endl;
187 delete d->workbook;
188 delete storeout;
189 return KoFilter::CreationError;
190 }
191
192 kdDebug(30511) << "Converted to " << d->outputFile << ". Time: " << time.elapsed() << " ms " << endl;
193
194 // we are done!
195 delete d->workbook;
196 delete storeout;
197 d->inputFile = TQString();
198 d->outputFile = TQString();
199 d->workbook = 0;
200
201
202 return KoFilter::OK;
203}
204
205bool ExcelImport::Private::createContent( KoOasisStore* store )
206{
207 KoXmlWriter* bodyWriter = store->bodyWriter();
208 KoXmlWriter* contentWriter = store->contentWriter();
209 if ( !bodyWriter || !contentWriter )
210 return false;
211
212 // FIXME this is dummy and hardcoded, replace with real font names
213 contentWriter->startElement( "office:font-face-decls" );
214 contentWriter->startElement( "style:font-face" );
215 contentWriter->addAttribute( "style:name", "Arial" );
216 contentWriter->addAttribute( "svg:font-family", "Arial" );
217 contentWriter->endElement(); // style:font-face
218 contentWriter->startElement( "style:font-face" );
219 contentWriter->addAttribute( "style:name", "Times New Roman" );
220 contentWriter->addAttribute( "svg:font-family", "&apos;Times New Roman&apos;" );
221 contentWriter->endElement(); // style:font-face
222 contentWriter->endElement(); // office:font-face-decls
223
224 // important: reset all indexes
225 sheetFormatIndex = 1;
226 columnFormatIndex = 1;
227 rowFormatIndex = 1;
228
229 // office:automatic-styles
230 contentWriter->startElement( "office:automatic-styles" );
231 processWorkbookForStyle( workbook, contentWriter );
232 contentWriter->endElement(); // office:automatic-style
233
234 // important: reset all indexes
235 sheetFormatIndex = 1;
236 columnFormatIndex = 1;
237 rowFormatIndex = 1;
238
239 // office:body
240 bodyWriter->startElement( "office:body" );
241 processWorkbookForBody( workbook, bodyWriter );
242 bodyWriter->endElement(); // office:body
243
244 return store->closeContentWriter();
245}
246
247bool ExcelImport::Private::createStyles( KoOasisStore* store )
248{
249 if ( !store->store()->open( "styles.xml" ) )
250 return false;
251 KoStoreDevice dev( store->store() );
252 KoXmlWriter* stylesWriter = new KoXmlWriter( &dev );
253
254 // FIXME this is dummy default, replace if necessary
255 stylesWriter->startDocument( "office:document-styles" );
256 stylesWriter->startElement( "office:document-styles" );
257 stylesWriter->addAttribute( "xmlns:office", "urn:oasis:names:tc:opendocument:xmlns:office:1.0" );
258 stylesWriter->addAttribute( "xmlns:style", "urn:oasis:names:tc:opendocument:xmlns:style:1.0" );
259 stylesWriter->addAttribute( "xmlns:text", "urn:oasis:names:tc:opendocument:xmlns:text:1.0" );
260 stylesWriter->addAttribute( "xmlns:table", "urn:oasis:names:tc:opendocument:xmlns:table:1.0" );
261 stylesWriter->addAttribute( "xmlns:draw", "urn:oasis:names:tc:opendocument:xmlns:drawing:1.0" );
262 stylesWriter->addAttribute( "xmlns:fo", "urn:oasis:names:tc:opendocument:xmlns:xsl-fo-compatible:1.0" );
263 stylesWriter->addAttribute( "xmlns:svg","urn:oasis:names:tc:opendocument:xmlns:svg-compatible:1.0" );
264 stylesWriter->addAttribute( "office:version","1.0" );
265 stylesWriter->startElement( "office:styles" );
266 stylesWriter->startElement( "style:default-style" );
267 stylesWriter->addAttribute( "style:family", "table-cell" );
268 stylesWriter->startElement( "style:table-cell-properties" );
269 stylesWriter->addAttribute( "style:decimal-places", "2" );
270 stylesWriter->endElement(); // style:table-cell-properties
271 stylesWriter->startElement( "style:paragraph-properties" );
272 stylesWriter->addAttribute( "style:tab-stop-distance", "0.5in" );
273 stylesWriter->endElement(); // style:paragraph-properties
274 stylesWriter->startElement( "style:text-properties" );
275 stylesWriter->addAttribute( "style:font-name", "Albany AMT" );
276 stylesWriter->addAttribute( "fo:language", "en" );
277 stylesWriter->addAttribute( "fo:country", "US" );
278 stylesWriter->addAttribute( "style:font-name-asian", "Albany AMT1" );
279 stylesWriter->addAttribute( "style:country-asian", "none" );
280 stylesWriter->addAttribute( "style:font-name-complex", "Lucidasans" );
281 stylesWriter->addAttribute( "style:language-complex", "none" );
282 stylesWriter->addAttribute( "style:country-complex", "none" );
283 stylesWriter->endElement(); // style:text-properties
284 stylesWriter->endElement(); // style:default-style
285 stylesWriter->startElement( "style:style" );
286 stylesWriter->addAttribute( "style:name", "Default" );
287 stylesWriter->addAttribute( "style:family", "table-cell" );
288 stylesWriter->endElement(); // style:style
289 stylesWriter->endElement(); // office:styles
290
291 // office:automatic-styles
292 stylesWriter->startElement( "office:automatic-styles" );
293 stylesWriter->endElement(); // office:automatic-styles
294
295 stylesWriter->endElement(); // office:document-styles
296 stylesWriter->endDocument();
297
298 delete stylesWriter;
299
300 return store->store()->close();
301}
302
303bool ExcelImport::Private::createManifest( KoOasisStore* store )
304{
305 KoXmlWriter* manifestWriter = store->manifestWriter( "application/vnd.oasis.opendocument.spreadsheet" );
306
307 manifestWriter->addManifestEntry( "styles.xml", "text/xml" );
308 manifestWriter->addManifestEntry( "content.xml", "text/xml" );
309
310 return store->closeManifestWriter();
311}
312
313void ExcelImport::Private::processWorkbookForBody( Workbook* workbook, KoXmlWriter* xmlWriter )
314{
315 if( !workbook ) return;
316 if( !xmlWriter ) return;
317
318 xmlWriter->startElement( "office:spreadsheet" );
319
320 for( unsigned i=0; i < workbook->sheetCount(); i++ )
321 {
322 Sheet* sheet = workbook->sheet( i );
323 processSheetForBody( sheet, xmlWriter );
324 }
325
326 xmlWriter->endElement(); // office:spreadsheet
327}
328
329void ExcelImport::Private::processWorkbookForStyle( Workbook* workbook, KoXmlWriter* xmlWriter )
330{
331 if( !workbook ) return;
332 if( !xmlWriter ) return;
333
334 for( unsigned i=0; i < workbook->sheetCount(); i++ )
335 {
336 Sheet* sheet = workbook->sheet( i );
337 processSheetForStyle( sheet, xmlWriter );
338 }
339}
340
341void ExcelImport::Private::processSheetForBody( Sheet* sheet, KoXmlWriter* xmlWriter )
342{
343 if( !sheet ) return;
344 if( !xmlWriter ) return;
345
346 xmlWriter->startElement( "table:table" );
347
348 xmlWriter->addAttribute( "table:name", string( sheet->name() ).string() );
349 xmlWriter->addAttribute( "table:print", "false" );
350 xmlWriter->addAttribute( "table:protected", "false" );
351 xmlWriter->addAttribute( "table:style-name", TQString("ta%1").arg(sheetFormatIndex));
352 sheetFormatIndex++;
353
354 unsigned ci = 0;
355 while( ci <= sheet->maxColumn() )
356 {
357 Column* column = sheet->column( ci, false );
358 if( column )
359 {
360 // forward search for columns with same properties
361 unsigned cj = ci + 1;
362 while( cj <= sheet->maxColumn() )
363 {
364 const Column* nextColumn = sheet->column( cj, false );
365 if( !nextColumn ) break;
366 if( column->width() != nextColumn->width() ) break;
367 if( column->visible() != nextColumn->visible() ) break;
368 if( column->formatIndex() != nextColumn->formatIndex() ) break;
369 cj++;
370 }
371
372 int repeated = cj - ci;
373 processColumnForBody( column, repeated, xmlWriter );
374 ci += repeated;
375 }
376 else {
377 ci++;
378 xmlWriter->startElement( "table:table-column" );
379 xmlWriter->endElement();
380 }
381 }
382
383 for( unsigned i = 0; i <= sheet->maxRow(); i++ )
384 {
385 // FIXME optimized this when operator== in Swinder::Format is implemented
386 processRowForBody( sheet->row( i, false ), 1, xmlWriter );
387 }
388
389 xmlWriter->endElement(); // table:table
390}
391
392void ExcelImport::Private::processSheetForStyle( Sheet* sheet, KoXmlWriter* xmlWriter )
393{
394 if( !sheet ) return;
395 if( !xmlWriter ) return;
396
397 xmlWriter->startElement( "style:style" );
398 xmlWriter->addAttribute( "style:family", "table" );
399 xmlWriter->addAttribute( "style:master-page-name", "Default" );
400 xmlWriter->addAttribute( "style:name", TQString("ta%1").arg(sheetFormatIndex) );
401 sheetFormatIndex++;
402
403 xmlWriter->startElement( "style:table-properties" );
404 xmlWriter->addAttribute( "table:display", sheet->visible() ? "true" : "false" );
405 xmlWriter->addAttribute( "table:writing-mode", "lr-tb" );
406 xmlWriter->endElement(); // style:table-properties
407
408 xmlWriter->endElement(); // style:style
409
410 unsigned ci = 0;
411 while( ci <= sheet->maxColumn() )
412 {
413 Column* column = sheet->column( ci, false );
414 if( column )
415 {
416 // forward search for similar column
417 unsigned cj = ci + 1;
418 while( cj <= sheet->maxColumn() )
419 {
420 Column* nextColumn = sheet->column( cj, false );
421 if( !nextColumn ) break;
422 if( column->width() != nextColumn->width() ) break;
423 if( column->visible() != nextColumn->visible() ) break;
424 if( column->formatIndex() != nextColumn->formatIndex() ) break;
425 cj++;
426 }
427
428 int repeated = cj - ci;
429 processColumnForStyle( column, repeated, xmlWriter );
430 ci += repeated;
431 }
432 else
433 ci++;
434 }
435
436 for( unsigned i = 0; i <= sheet->maxRow(); i++ )
437 {
438 Row* row = sheet->row( i, false );
439 // FIXME optimized this when operator== in Swinder::Format is implemented
440 processRowForStyle( row, 1, xmlWriter );
441 }
442}
443
444void ExcelImport::Private::processColumnForBody( Column* column, int repeat, KoXmlWriter* xmlWriter )
445{
446 if( !column ) return;
447 if( !xmlWriter ) return;
448
449 xmlWriter->startElement( "table:table-column" );
450 xmlWriter->addAttribute( "table:default-style-name", "Default" );
451 xmlWriter->addAttribute( "table:visibility", column->visible() ? "visible" : "collapse" );
452 if(repeat > 1) xmlWriter->addAttribute( "table:number-columns-repeated", repeat );
453 xmlWriter->addAttribute( "table:style-name", TQString("co%1").arg(columnFormatIndex) );
454 columnFormatIndex++;
455
456 xmlWriter->endElement(); // table:table-column
457}
458
459void ExcelImport::Private::processColumnForStyle( Column* column, int /*repeat*/, KoXmlWriter* xmlWriter )
460{
461 if( !column ) return;
462 if( !xmlWriter ) return;
463
464 xmlWriter->startElement( "style:style" );
465 xmlWriter->addAttribute( "style:family", "table-column" );
466 xmlWriter->addAttribute( "style:name", TQString("co%1").arg(columnFormatIndex) );
467 columnFormatIndex++;
468
469 xmlWriter->startElement( "style:table-column-properties" );
470 xmlWriter->addAttribute( "fo:break-before", "auto" );
471 xmlWriter->addAttribute( "style:column-width", TQString("%1in").arg(column->width()/27) );
472 xmlWriter->endElement(); // style:table-column-properties
473
474 xmlWriter->endElement(); // style:style
475}
476
477void ExcelImport::Private::processRowForBody( Row* row, int /*repeat*/, KoXmlWriter* xmlWriter )
478{
479 if( !xmlWriter ) return;
480 if( !row ) {
481 xmlWriter->startElement( "table:table-row" );
482 xmlWriter->endElement();
483 return;
484 }
485 if( !row->sheet() ) return;
486
487 // find the column of the rightmost cell (if any)
488 int lastCol = -1;
489 Sheet* sheet= row->sheet();
490 unsigned rowIndex = row->index();
491 for( unsigned i = 0; i <= sheet->maxColumn(); i++ )
492 if( sheet->cell( i, rowIndex, false ) )
493 lastCol = i;
494
495 xmlWriter->startElement( "table:table-row" );
496 xmlWriter->addAttribute( "table:visibility", row->visible() ? "visible" : "collapse" );
497 xmlWriter->addAttribute( "table:style-name", TQString("ro%1").arg(rowFormatIndex) );
498 rowFormatIndex++;
499
500 for( int i = 0; i <= lastCol; i++ )
501 {
502 Cell* cell = sheet->cell( i, rowIndex, false );
503 if( cell )
504 processCellForBody( cell, xmlWriter );
505 else
506 {
507 // empty cell
508 xmlWriter->startElement( "table:table-cell" );
509 xmlWriter->endElement();
510 }
511 }
512
513 xmlWriter->endElement(); // table:table-row
514}
515
516void ExcelImport::Private::processRowForStyle( Row* row, int repeat, KoXmlWriter* xmlWriter )
517{
518 if( !row ) return;
519 if( !row->sheet() ) return;
520 if( !xmlWriter ) return;
521
522 // find the column of the rightmost cell (if any)
523 int lastCol = -1;
524 Sheet* sheet= row->sheet();
525 unsigned rowIndex = row->index();
526 for( unsigned i = 0; i <= sheet->maxColumn(); i++ )
527 if( sheet->cell( i, rowIndex, false ) )
528 lastCol = i;
529
530 xmlWriter->startElement( "style:style" );
531 xmlWriter->addAttribute( "style:family", "table-row" );
532 if(repeat > 1) xmlWriter->addAttribute( "table:number-rows-repeated", repeat );
533 xmlWriter->addAttribute( "style:name", TQString("ro%1").arg(rowFormatIndex) );
534 rowFormatIndex++;
535
536 xmlWriter->startElement( "style:table-row-properties" );
537 xmlWriter->addAttribute( "fo:break-before", "auto" );
538 xmlWriter->addAttribute( "style:row-height", TQString("%1pt").arg(row->height()) );
539 xmlWriter->endElement(); // style:table-row-properties
540
541 xmlWriter->endElement(); // style:style
542
543 for( int i = 0; i <= lastCol; i++ )
544 {
545 Cell* cell = sheet->cell( i, rowIndex, false );
546 if( cell )
547 processCellForStyle( cell, xmlWriter );
548 }
549}
550
551static bool isPercentageFormat( const TQString& valueFormat )
552{
553 if( valueFormat.isEmpty() ) return false;
554 if( valueFormat.length() < 1 ) return false;
555 return valueFormat[valueFormat.length()-1] == TQChar('%');
556}
557
558static bool isDateFormat( const TQString& valueFormat )
559{
560 TQString vfu = valueFormat.upper();
561
562 if( vfu == "M/D/YY" ) return true;
563 if( vfu == "M/D/YYYY" ) return true;
564 if( vfu == "MM/DD/YY" ) return true;
565 if( vfu == "MM/DD/YYYY" ) return true;
566 if( vfu == "D-MMM-YY" ) return true;
567 if( vfu == "D\\-MMM\\-YY" ) return true;
568 if( vfu == "D-MMM-YYYY" ) return true;
569 if( vfu == "D\\-MMM\\-YYYY" ) return true;
570 if( vfu == "D-MMM" ) return true;
571 if( vfu == "D\\-MMM" ) return true;
572 if( vfu == "D-MM" ) return true;
573 if( vfu == "D\\-MM" ) return true;
574 if( vfu == "MMM/DD" ) return true;
575 if( vfu == "MMM/D" ) return true;
576 if( vfu == "MM/DD" ) return true;
577 if( vfu == "MM/D" ) return true;
578 if( vfu == "MM/DD/YY" ) return true;
579 if( vfu == "MM/DD/YYYY" ) return true;
580 if( vfu == "YYYY/MM/D" ) return true;
581 if( vfu == "YYYY/MM/DD" ) return true;
582 if( vfu == "YYYY-MM-D" ) return true;
583 if( vfu == "YYYY\\-MM\\-D" ) return true;
584 if( vfu == "YYYY-MM-DD" ) return true;
585 if( vfu == "YYYY\\-MM\\-DD" ) return true;
586
587 return false;
588}
589
590static bool isTimeFormat( const TQString& valueFormat )
591{
592 TQString vf = valueFormat;
593
594 if( vf == "h:mm AM/PM" ) return true;
595 if( vf == "h:mm:ss AM/PM" ) return true;
596 if( vf == "h:mm" ) return true;
597 if( vf == "h:mm:ss" ) return true;
598 if( vf == "[h]:mm:ss" ) return true;
599 if( vf == "[h]:mm" ) return true;
600 if( vf == "[mm]:ss" ) return true;
601 if( vf == "M/D/YY h:mm" ) return true;
602 if( vf == "[ss]" ) return true;
603 if( vf == "mm:ss" ) return true;
604 if( vf == "mm:ss.0" ) return true;
605 if( vf == "[mm]:ss" ) return true;
606 if( vf == "[ss]" ) return true;
607
608 return false;
609}
610
611static TQString convertDate( double serialNo )
612{
613 // reference is midnight 30 Dec 1899
614 TQDate dd( 1899, 12, 30 );
615 dd = dd.addDays( (int) serialNo );
616 return dd.toString( "yyyy-MM-dd" );
617}
618
619static TQString convertTime( double serialNo )
620{
621 // reference is midnight 30 Dec 1899
622 TQTime tt;
623 tt = tt.addMSecs( tqRound( (serialNo-(int)serialNo) * 86400 * 1000 ) );
624 return tt.toString( "PThhHmmMss,zzz0S" );
625}
626
627void ExcelImport::Private::processCellForBody( Cell* cell, KoXmlWriter* xmlWriter )
628{
629 if( !cell ) return;
630 if( !xmlWriter ) return;
631
632 int formatIndex = cell->formatIndex();
633
634 TQString styleName("ce");
635 styleName.append( TQString::number( formatIndex ) );
636 xmlWriter->startElement( "table:table-cell" );
637 xmlWriter->addAttribute( "table:style-name", styleName );
638
639 if( !cell->formula().isEmpty() )
640 {
641 TQString formula = string( cell->formula() ).string();
642 xmlWriter->addAttribute( "table:formula", formula.prepend("=") );
643 }
644
645 const Value& value = cell->value();
646
647 if( value.isBoolean() )
648 {
649 xmlWriter->addAttribute( "office:value-type", "boolean" );
650 xmlWriter->addAttribute( "office:boolean-value", value.asBoolean() ? "true" : "false" );
651 }
652 else if( value.isFloat() || value.isInteger() )
653 {
654 if( isPercentageStyle[formatIndex] )
655 {
656 xmlWriter->addAttribute( "office:value-type", "percentage" );
657 xmlWriter->addAttribute( "office:value", TQString::number( value.asFloat(), 'g', 15 ) );
658 }
659 else if( isDateStyle[formatIndex] )
660 {
661 xmlWriter->addAttribute( "office:value-type", "date" );
662 xmlWriter->addAttribute( "office:date-value", convertDate( value.asFloat() ) );
663 }
664 else if( isTimeStyle[formatIndex] )
665 {
666 xmlWriter->addAttribute( "office:value-type", "time" );
667 xmlWriter->addAttribute( "office:time-value", convertTime( value.asFloat() ) );
668 }
669 else
670 {
671 // fallback, just write as normal number
672 xmlWriter->addAttribute( "office:value-type", "float" );
673 xmlWriter->addAttribute( "office:value", TQString::number( value.asFloat(), 'g', 15 ) );
674 }
675 }
676 else if( value.isString() )
677 {
678 TQString str = string( value.asString() ).string();
679 xmlWriter->addAttribute( "office:value-type", "string" );
680 xmlWriter->addAttribute( "office:string-value", str );
681 xmlWriter->startElement( "text:p" );
682 xmlWriter->addTextNode( str );
683 xmlWriter->endElement(); // text:p
684 }
685
686 xmlWriter->endElement(); // table:table-cell
687}
688
689void ExcelImport::Private::processCellForStyle( Cell* cell, KoXmlWriter* xmlWriter )
690{
691 if( !cell ) return;
692 if( !xmlWriter ) return;
693
694 // only IF automatic style for this format has not been already created yet
695 if( !styleFormats.contains( cell->formatIndex() ) )
696 {
697 styleFormats[ cell->formatIndex() ] = true;
698
699 const Format& format = cell->sheet()->workbook()->format( cell->formatIndex() );
700
701 // handle data format, e.g. number style
702 TQString refName;
703 const UString& valueFormat = format.valueFormat();
704 if( !valueFormat.isEmpty() )
705 {
706 refName = TQString("N%1").arg(cell->formatIndex());
707 TQString numformat = string( valueFormat ).string();
708 processValueFormat( numformat, refName, xmlWriter );
709 }
710
711 // later for writing the value
712 TQString numformat = string( valueFormat ).string();
713 isPercentageStyle[ cell->formatIndex() ] = isPercentageFormat( numformat );
714 isDateStyle[ cell->formatIndex() ] = isDateFormat( numformat );
715 isTimeStyle[ cell->formatIndex() ] = isTimeFormat( numformat );
716
717 // now the real table-cell
718 xmlWriter->startElement( "style:style" );
719 xmlWriter->addAttribute( "style:family", "table-cell" );
720 xmlWriter->addAttribute( "style:name", TQString("ce%1").arg( cell->formatIndex() ) );
721 if( !refName.isEmpty() )
722 xmlWriter->addAttribute( "style:data-style-name", refName );
723
724 processFormat( &format, xmlWriter );
725
726 xmlWriter->endElement(); // style:style
727 }
728}
729
730TQString convertColor( const Color& color )
731{
732 char buf[8];
733 sprintf( buf, "#%02x%02x%02x", color.red, color.green, color.blue );
734 return TQString( buf );
735}
736
737TQString convertBorder( const Pen& pen )
738{
739 if( pen.style == Pen::NoLine || pen.width == 0 ) return "none";
740
741 TQString result = TQString::number( pen.width );
742 result += "pt ";
743
744 switch( pen.style )
745 {
746 case Pen::SolidLine: result += "solid "; break;
747 case Pen::DashLine: result += "dashed "; break;
748 case Pen::DotLine: result += "dotted "; break;
749 case Pen::DashDotLine: result += "dot-dash "; break;
750 case Pen::DashDotDotLine: result += "dot-dot-dash "; break;
751 }
752
753 return result + convertColor( pen.color );
754}
755
756void ExcelImport::Private::processFormat( const Format* format, KoXmlWriter* xmlWriter )
757{
758 if( !format ) return;
759 if( !xmlWriter ) return;
760
761 const FormatFont& font = format->font();
762 const FormatAlignment& align = format->alignment();
763 const FormatBackground& back = format->background();
764 const FormatBorders& borders = format->borders();
765
766 if( !font.isNull() )
767 {
768 xmlWriter->startElement( "style:text-properties" );
769
770 if( font.bold() )
771 xmlWriter->addAttribute( "fo:font-weight", "bold" );
772
773 if( font.italic() )
774 xmlWriter->addAttribute( "fo:font-style", "italic" );
775
776 if( font.underline() )
777 {
778 xmlWriter->addAttribute( "style:text-underline-style", "solid" );
779 xmlWriter->addAttribute( "style:text-underline-width", "auto" );
780 xmlWriter->addAttribute( "style:text-underline-color", "font-color" );
781 }
782
783 if( font.strikeout() )
784 xmlWriter->addAttribute( "style:text-line-through-style", "solid" );
785
786 if( font.subscript() )
787 xmlWriter->addAttribute( "style:text-position", "sub" );
788
789 if( font.superscript() )
790 xmlWriter->addAttribute( "style:text-position", "super" );
791
792 if( !font.fontFamily().isEmpty() )
793 xmlWriter->addAttribute( "style:font-name", string(font.fontFamily()).string() );
794
795 xmlWriter->addAttribute( "fo:font-size", TQString("%1pt").arg(font.fontSize()) );
796
797 xmlWriter->addAttribute( "fo:color", convertColor( font.color() ) );
798
799 xmlWriter->endElement(); // style:text-properties
800 }
801
802 xmlWriter->startElement( "style:table-cell-properties" );
803 if( !align.isNull() )
804 {
805 switch( align.alignY() ) {
806 case Format::Top: xmlWriter->addAttribute( "style:vertical-align", "top" ); break;
807 case Format::Middle: xmlWriter->addAttribute( "style:vertical-align", "middle" ); break;
808 case Format::Bottom: xmlWriter->addAttribute( "style:vertical-align", "bottom" ); break;
809 }
810
811 xmlWriter->addAttribute( "fo:wrap-option", align.wrap() ? "wrap" : "no-wrap" );
812 //TODO rotation
813 //TODO stacked letters
814 }
815
816 if( !borders.isNull() )
817 {
818 xmlWriter->addAttribute( "fo:border-left", convertBorder( borders.leftBorder() ) );
819 xmlWriter->addAttribute( "fo:border-right", convertBorder( borders.rightBorder() ) );
820 xmlWriter->addAttribute( "fo:border-top", convertBorder( borders.topBorder() ) );
821 xmlWriter->addAttribute( "fo:border-bottom", convertBorder( borders.bottomBorder() ) );
822 //TODO diagonal 'borders'
823 }
824
825 if( !back.isNull() && back.pattern() != FormatBackground::EmptyPattern )
826 {
827 Color backColor = back.backgroundColor();
828 if( back.pattern() == FormatBackground::SolidPattern )
829 backColor = back.foregroundColor();
830
831 xmlWriter->addAttribute( "fo:background-color", convertColor( backColor ) );
832
833 //TODO patterns
834 }
835 xmlWriter->endElement(); // style:table-cell-properties
836
837 xmlWriter->startElement( "style:paragraph-properties" );
838 if( !align.isNull() )
839 {
840 switch( align.alignX() ) {
841 case Format::Left: xmlWriter->addAttribute( "fo:text-align", "start" ); break;
842 case Format::Center: xmlWriter->addAttribute( "fo:text-align", "center" ); break;
843 case Format::Right: xmlWriter->addAttribute( "fo:text-align", "end" ); break;
844 }
845
846 if( align.indentLevel() != 0 )
847 xmlWriter->addAttribute( "fo:margin-left", TQString::number( align.indentLevel() ) + "0pt" );
848 }
849 xmlWriter->endElement(); // style:paragraph-properties
850}
851
852void ExcelImport::Private::processValueFormat( TQString valueFormat, TQString refName,
853KoXmlWriter* xmlWriter )
854{
855 /*int decimalPlaces = 2;
856 int leadingZeroes = 1;
857 int exponentDigits = -1;
858 bool percentage = false;*/
859
860 // TODO: someday we need a real MS Excel to OpenDocument format paraser
861 // this just catches the most common format, not covers all possible cases
862
863 if( valueFormat == "0")
864 {
865 xmlWriter->startElement( "number:number-style" );
866 xmlWriter->addAttribute( "style:name", refName );
867 xmlWriter->addAttribute( "style:family", "data-style" );
868 xmlWriter->startElement( "number:number" );
869 xmlWriter->addAttribute( "number:decimal-places", 0 );
870 xmlWriter->addAttribute( "number:min-integer-digits", 1 );
871 xmlWriter->endElement(); // number:number
872 xmlWriter->endElement(); // number:number-style
873 }
874 else if( valueFormat == "0.0")
875 {
876 xmlWriter->startElement( "number:number-style" );
877 xmlWriter->addAttribute( "style:name", refName );
878 xmlWriter->addAttribute( "style:family", "data-style" );
879 xmlWriter->startElement( "number:number" );
880 xmlWriter->addAttribute( "number:decimal-places", 1 );
881 xmlWriter->addAttribute( "number:min-integer-digits", 1 );
882 xmlWriter->endElement(); // number:number
883 xmlWriter->endElement(); // number:number-style
884 }
885 else if( valueFormat == "0.00")
886 {
887 xmlWriter->startElement( "number:number-style" );
888 xmlWriter->addAttribute( "style:name", refName );
889 xmlWriter->addAttribute( "style:family", "data-style" );
890 xmlWriter->startElement( "number:number" );
891 xmlWriter->addAttribute( "number:decimal-places", 2 );
892 xmlWriter->addAttribute( "number:min-integer-digits", 1 );
893 xmlWriter->endElement(); // number:number
894 xmlWriter->endElement(); // number:number-style
895 }
896 else if( valueFormat == "0.000")
897 {
898 xmlWriter->startElement( "number:number-style" );
899 xmlWriter->addAttribute( "style:name", refName );
900 xmlWriter->addAttribute( "style:family", "data-style" );
901 xmlWriter->startElement( "number:number" );
902 xmlWriter->addAttribute( "number:decimal-places", 3 );
903 xmlWriter->addAttribute( "number:min-integer-digits", 1 );
904 xmlWriter->endElement(); // number:number
905 xmlWriter->endElement(); // number:number-style
906 }
907 else if( valueFormat == "0.0000")
908 {
909 xmlWriter->startElement( "number:number-style" );
910 xmlWriter->addAttribute( "style:name", refName );
911 xmlWriter->addAttribute( "style:family", "data-style" );
912 xmlWriter->startElement( "number:number" );
913 xmlWriter->addAttribute( "number:decimal-places", 4 );
914 xmlWriter->addAttribute( "number:min-integer-digits", 1 );
915 xmlWriter->endElement(); // number:number
916 xmlWriter->endElement(); // number:number-style
917 }
918 else if( valueFormat == "0.00000")
919 {
920 xmlWriter->startElement( "number:number-style" );
921 xmlWriter->addAttribute( "style:name", refName );
922 xmlWriter->addAttribute( "style:family", "data-style" );
923 xmlWriter->startElement( "number:number" );
924 xmlWriter->addAttribute( "number:decimal-places", 5 );
925 xmlWriter->addAttribute( "number:min-integer-digits", 1 );
926 xmlWriter->endElement(); // number:number
927 xmlWriter->endElement(); // number:number-style
928 }
929 else if( valueFormat == "0.000000")
930 {
931 xmlWriter->startElement( "number:number-style" );
932 xmlWriter->addAttribute( "style:name", refName );
933 xmlWriter->addAttribute( "style:family", "data-style" );
934 xmlWriter->startElement( "number:number" );
935 xmlWriter->addAttribute( "number:decimal-places", 6 );
936 xmlWriter->addAttribute( "number:min-integer-digits", 1 );
937 xmlWriter->endElement(); // number:number
938 xmlWriter->endElement(); // number:number-style
939 }
940 else if( valueFormat == "0.0000000")
941 {
942 xmlWriter->startElement( "number:number-style" );
943 xmlWriter->addAttribute( "style:name", refName );
944 xmlWriter->addAttribute( "style:family", "data-style" );
945 xmlWriter->startElement( "number:number" );
946 xmlWriter->addAttribute( "number:decimal-places", 7 );
947 xmlWriter->addAttribute( "number:min-integer-digits", 1 );
948 xmlWriter->endElement(); // number:number
949 xmlWriter->endElement(); // number:number-style
950 }
951 else if( valueFormat == "0.00000000")
952 {
953 xmlWriter->startElement( "number:number-style" );
954 xmlWriter->addAttribute( "style:name", refName );
955 xmlWriter->addAttribute( "style:family", "data-style" );
956 xmlWriter->startElement( "number:number" );
957 xmlWriter->addAttribute( "number:decimal-places", 8 );
958 xmlWriter->addAttribute( "number:min-integer-digits", 1 );
959 xmlWriter->endElement(); // number:number
960 xmlWriter->endElement(); // number:number-style
961 }
962 else if( valueFormat == "0.000000000")
963 {
964 xmlWriter->startElement( "number:number-style" );
965 xmlWriter->addAttribute( "style:name", refName );
966 xmlWriter->addAttribute( "style:family", "data-style" );
967 xmlWriter->startElement( "number:number" );
968 xmlWriter->addAttribute( "number:decimal-places", 9 );
969 xmlWriter->addAttribute( "number:min-integer-digits", 1 );
970 xmlWriter->endElement(); // number:number
971 xmlWriter->endElement(); // number:number-style
972 }
973 else if( valueFormat == "0.0000000000")
974 {
975 xmlWriter->startElement( "number:number-style" );
976 xmlWriter->addAttribute( "style:name", refName );
977 xmlWriter->addAttribute( "style:family", "data-style" );
978 xmlWriter->startElement( "number:number" );
979 xmlWriter->addAttribute( "number:decimal-places", 10 );
980 xmlWriter->addAttribute( "number:min-integer-digits", 1 );
981 xmlWriter->endElement(); // number:number
982 xmlWriter->endElement(); // number:number-style
983 }
984 else if( valueFormat == "0.00000000000")
985 {
986 xmlWriter->startElement( "number:number-style" );
987 xmlWriter->addAttribute( "style:name", refName );
988 xmlWriter->addAttribute( "style:family", "data-style" );
989 xmlWriter->startElement( "number:number" );
990 xmlWriter->addAttribute( "number:decimal-places", 11 );
991 xmlWriter->addAttribute( "number:min-integer-digits", 1 );
992 xmlWriter->endElement(); // number:number
993 xmlWriter->endElement(); // number:number-style
994 }
995 else if( valueFormat == "0.000000000000")
996 {
997 xmlWriter->startElement( "number:number-style" );
998 xmlWriter->addAttribute( "style:name", refName );
999 xmlWriter->addAttribute( "style:family", "data-style" );
1000 xmlWriter->startElement( "number:number" );
1001 xmlWriter->addAttribute( "number:decimal-places", 12 );
1002 xmlWriter->addAttribute( "number:min-integer-digits", 1 );
1003 xmlWriter->endElement(); // number:number
1004 xmlWriter->endElement(); // number:number-style
1005 }
1006 else if( valueFormat == "0.0000000000000")
1007 {
1008 xmlWriter->startElement( "number:number-style" );
1009 xmlWriter->addAttribute( "style:name", refName );
1010 xmlWriter->addAttribute( "style:family", "data-style" );
1011 xmlWriter->startElement( "number:number" );
1012 xmlWriter->addAttribute( "number:decimal-places", 13 );
1013 xmlWriter->addAttribute( "number:min-integer-digits", 1 );
1014 xmlWriter->endElement(); // number:number
1015 xmlWriter->endElement(); // number:number-style
1016 }
1017 else if( valueFormat == "0.00000000000000")
1018 {
1019 xmlWriter->startElement( "number:number-style" );
1020 xmlWriter->addAttribute( "style:name", refName );
1021 xmlWriter->addAttribute( "style:family", "data-style" );
1022 xmlWriter->startElement( "number:number" );
1023 xmlWriter->addAttribute( "number:decimal-places", 14 );
1024 xmlWriter->addAttribute( "number:min-integer-digits", 1 );
1025 xmlWriter->endElement(); // number:number
1026 xmlWriter->endElement(); // number:number-style
1027 }
1028 else if( valueFormat == "0.000000000000000")
1029 {
1030 xmlWriter->startElement( "number:number-style" );
1031 xmlWriter->addAttribute( "style:name", refName );
1032 xmlWriter->addAttribute( "style:family", "data-style" );
1033 xmlWriter->startElement( "number:number" );
1034 xmlWriter->addAttribute( "number:decimal-places", 15 );
1035 xmlWriter->addAttribute( "number:min-integer-digits", 1 );
1036 xmlWriter->endElement(); // number:number
1037 xmlWriter->endElement(); // number:number-style
1038 }
1039 else if( valueFormat == "0.0000000000000000")
1040 {
1041 xmlWriter->startElement( "number:number-style" );
1042 xmlWriter->addAttribute( "style:name", refName );
1043 xmlWriter->addAttribute( "style:family", "data-style" );
1044 xmlWriter->startElement( "number:number" );
1045 xmlWriter->addAttribute( "number:decimal-places", 16 );
1046 xmlWriter->addAttribute( "number:min-integer-digits", 1 );
1047 xmlWriter->endElement(); // number:number
1048 xmlWriter->endElement(); // number:number-style
1049 }
1050 else if( valueFormat == "0E+00")
1051 {
1052 xmlWriter->startElement( "number:number-style" );
1053 xmlWriter->addAttribute( "style:name", refName );
1054 xmlWriter->addAttribute( "style:family", "data-style" );
1055 xmlWriter->startElement( "number:scientific-number" );
1056 xmlWriter->addAttribute( "number:decimal-places", 0 );
1057 xmlWriter->addAttribute( "number:min-integer-digits", 1 );
1058 xmlWriter->addAttribute( "number:min-exponent-digits", 2 );
1059 xmlWriter->endElement(); // number:scientific-number
1060 xmlWriter->endElement(); // number:number-style
1061 }
1062 else if( valueFormat == "0.0E+00")
1063 {
1064 xmlWriter->startElement( "number:number-style" );
1065 xmlWriter->addAttribute( "style:name", refName );
1066 xmlWriter->addAttribute( "style:family", "data-style" );
1067 xmlWriter->startElement( "number:scientific-number" );
1068 xmlWriter->addAttribute( "number:decimal-places", 1 );
1069 xmlWriter->addAttribute( "number:min-integer-digits", 1 );
1070 xmlWriter->addAttribute( "number:min-exponent-digits", 2 );
1071 xmlWriter->endElement(); // number:scientific-number
1072 xmlWriter->endElement(); // number:number-style
1073 }
1074 else if( valueFormat == "0.00E+00")
1075 {
1076 xmlWriter->startElement( "number:number-style" );
1077 xmlWriter->addAttribute( "style:name", refName );
1078 xmlWriter->addAttribute( "style:family", "data-style" );
1079 xmlWriter->startElement( "number:scientific-number" );
1080 xmlWriter->addAttribute( "number:decimal-places", 2 );
1081 xmlWriter->addAttribute( "number:min-integer-digits", 1 );
1082 xmlWriter->addAttribute( "number:min-exponent-digits", 2 );
1083 xmlWriter->endElement(); // number:scientific-number
1084 xmlWriter->endElement(); // number:number-style
1085 }
1086 else if( valueFormat == "0.000E+00")
1087 {
1088 xmlWriter->startElement( "number:number-style" );
1089 xmlWriter->addAttribute( "style:name", refName );
1090 xmlWriter->addAttribute( "style:family", "data-style" );
1091 xmlWriter->startElement( "number:scientific-number" );
1092 xmlWriter->addAttribute( "number:decimal-places", 3 );
1093 xmlWriter->addAttribute( "number:min-integer-digits", 1 );
1094 xmlWriter->addAttribute( "number:min-exponent-digits", 2 );
1095 xmlWriter->endElement(); // number:scientific-number
1096 xmlWriter->endElement(); // number:number-style
1097 }
1098 else if( valueFormat == "0.0000E+00")
1099 {
1100 xmlWriter->startElement( "number:number-style" );
1101 xmlWriter->addAttribute( "style:name", refName );
1102 xmlWriter->addAttribute( "style:family", "data-style" );
1103 xmlWriter->startElement( "number:scientific-number" );
1104 xmlWriter->addAttribute( "number:decimal-places", 4 );
1105 xmlWriter->addAttribute( "number:min-integer-digits", 1 );
1106 xmlWriter->addAttribute( "number:min-exponent-digits", 2 );
1107 xmlWriter->endElement(); // number:scientific-number
1108 xmlWriter->endElement(); // number:number-style
1109 }
1110 else if( valueFormat == "0.00000E+00")
1111 {
1112 xmlWriter->startElement( "number:number-style" );
1113 xmlWriter->addAttribute( "style:name", refName );
1114 xmlWriter->addAttribute( "style:family", "data-style" );
1115 xmlWriter->startElement( "number:scientific-number" );
1116 xmlWriter->addAttribute( "number:decimal-places", 5 );
1117 xmlWriter->addAttribute( "number:min-integer-digits", 1 );
1118 xmlWriter->addAttribute( "number:min-exponent-digits", 2 );
1119 xmlWriter->endElement(); // number:scientific-number
1120 xmlWriter->endElement(); // number:number-style
1121 }
1122 else if( valueFormat == "0.000000E+00")
1123 {
1124 xmlWriter->startElement( "number:number-style" );
1125 xmlWriter->addAttribute( "style:name", refName );
1126 xmlWriter->addAttribute( "style:family", "data-style" );
1127 xmlWriter->startElement( "number:scientific-number" );
1128 xmlWriter->addAttribute( "number:decimal-places", 6 );
1129 xmlWriter->addAttribute( "number:min-integer-digits", 1 );
1130 xmlWriter->addAttribute( "number:min-exponent-digits", 2 );
1131 xmlWriter->endElement(); // number:scientific-number
1132 xmlWriter->endElement(); // number:number-style
1133 }
1134 else if( valueFormat == "0.0000000E+00")
1135 {
1136 xmlWriter->startElement( "number:number-style" );
1137 xmlWriter->addAttribute( "style:name", refName );
1138 xmlWriter->addAttribute( "style:family", "data-style" );
1139 xmlWriter->startElement( "number:scientific-number" );
1140 xmlWriter->addAttribute( "number:decimal-places", 7 );
1141 xmlWriter->addAttribute( "number:min-integer-digits", 1 );
1142 xmlWriter->addAttribute( "number:min-exponent-digits", 2 );
1143 xmlWriter->endElement(); // number:scientific-number
1144 xmlWriter->endElement(); // number:number-style
1145 }
1146 else if( valueFormat == "0.00000000E+00")
1147 {
1148 xmlWriter->startElement( "number:number-style" );
1149 xmlWriter->addAttribute( "style:name", refName );
1150 xmlWriter->addAttribute( "style:family", "data-style" );
1151 xmlWriter->startElement( "number:scientific-number" );
1152 xmlWriter->addAttribute( "number:decimal-places", 8 );
1153 xmlWriter->addAttribute( "number:min-integer-digits", 1 );
1154 xmlWriter->addAttribute( "number:min-exponent-digits", 2 );
1155 xmlWriter->endElement(); // number:scientific-number
1156 xmlWriter->endElement(); // number:number-style
1157 }
1158 else if( valueFormat == "0.000000000E+00")
1159 {
1160 xmlWriter->startElement( "number:number-style" );
1161 xmlWriter->addAttribute( "style:name", refName );
1162 xmlWriter->addAttribute( "style:family", "data-style" );
1163 xmlWriter->startElement( "number:scientific-number" );
1164 xmlWriter->addAttribute( "number:decimal-places", 9 );
1165 xmlWriter->addAttribute( "number:min-integer-digits", 1 );
1166 xmlWriter->addAttribute( "number:min-exponent-digits", 2 );
1167 xmlWriter->endElement(); // number:scientific-number
1168 xmlWriter->endElement(); // number:number-style
1169 }
1170 else if( valueFormat == "0.0000000000E+00")
1171 {
1172 xmlWriter->startElement( "number:number-style" );
1173 xmlWriter->addAttribute( "style:name", refName );
1174 xmlWriter->addAttribute( "style:family", "data-style" );
1175 xmlWriter->startElement( "number:scientific-number" );
1176 xmlWriter->addAttribute( "number:decimal-places", 10 );
1177 xmlWriter->addAttribute( "number:min-integer-digits", 1 );
1178 xmlWriter->addAttribute( "number:min-exponent-digits", 2 );
1179 xmlWriter->endElement(); // number:scientific-number
1180 xmlWriter->endElement(); // number:number-style
1181 }
1182 else if( valueFormat == "0.00000000000E+00")
1183 {
1184 xmlWriter->startElement( "number:number-style" );
1185 xmlWriter->addAttribute( "style:name", refName );
1186 xmlWriter->addAttribute( "style:family", "data-style" );
1187 xmlWriter->startElement( "number:scientific-number" );
1188 xmlWriter->addAttribute( "number:decimal-places", 11 );
1189 xmlWriter->addAttribute( "number:min-integer-digits", 1 );
1190 xmlWriter->addAttribute( "number:min-exponent-digits", 2 );
1191 xmlWriter->endElement(); // number:scientific-number
1192 xmlWriter->endElement(); // number:number-style
1193 }
1194 else if( valueFormat == "0.000000000000E+00")
1195 {
1196 xmlWriter->startElement( "number:number-style" );
1197 xmlWriter->addAttribute( "style:name", refName );
1198 xmlWriter->addAttribute( "style:family", "data-style" );
1199 xmlWriter->startElement( "number:scientific-number" );
1200 xmlWriter->addAttribute( "number:decimal-places", 12 );
1201 xmlWriter->addAttribute( "number:min-integer-digits", 1 );
1202 xmlWriter->addAttribute( "number:min-exponent-digits", 2 );
1203 xmlWriter->endElement(); // number:scientific-number
1204 xmlWriter->endElement(); // number:number-style
1205 }
1206 else if( valueFormat == "0.0000000000000E+00")
1207 {
1208 xmlWriter->startElement( "number:number-style" );
1209 xmlWriter->addAttribute( "style:name", refName );
1210 xmlWriter->addAttribute( "style:family", "data-style" );
1211 xmlWriter->startElement( "number:scientific-number" );
1212 xmlWriter->addAttribute( "number:decimal-places", 13 );
1213 xmlWriter->addAttribute( "number:min-integer-digits", 1 );
1214 xmlWriter->addAttribute( "number:min-exponent-digits", 2 );
1215 xmlWriter->endElement(); // number:scientific-number
1216 xmlWriter->endElement(); // number:number-style
1217 }
1218 else if( valueFormat == "0.00000000000000E+00")
1219 {
1220 xmlWriter->startElement( "number:number-style" );
1221 xmlWriter->addAttribute( "style:name", refName );
1222 xmlWriter->addAttribute( "style:family", "data-style" );
1223 xmlWriter->startElement( "number:scientific-number" );
1224 xmlWriter->addAttribute( "number:decimal-places", 14 );
1225 xmlWriter->addAttribute( "number:min-integer-digits", 1 );
1226 xmlWriter->addAttribute( "number:min-exponent-digits", 2 );
1227 xmlWriter->endElement(); // number:scientific-number
1228 xmlWriter->endElement(); // number:number-style
1229 }
1230 else if( valueFormat == "0.000000000000000E+00")
1231 {
1232 xmlWriter->startElement( "number:number-style" );
1233 xmlWriter->addAttribute( "style:name", refName );
1234 xmlWriter->addAttribute( "style:family", "data-style" );
1235 xmlWriter->startElement( "number:scientific-number" );
1236 xmlWriter->addAttribute( "number:decimal-places", 16 );
1237 xmlWriter->addAttribute( "number:min-integer-digits", 1 );
1238 xmlWriter->addAttribute( "number:min-exponent-digits", 2 );
1239 xmlWriter->endElement(); // number:scientific-number
1240 xmlWriter->endElement(); // number:number-style
1241 }
1242 else if( valueFormat == "0.0000000000000000E+00")
1243 {
1244 xmlWriter->startElement( "number:number-style" );
1245 xmlWriter->addAttribute( "style:name", refName );
1246 xmlWriter->addAttribute( "style:family", "data-style" );
1247 xmlWriter->startElement( "number:scientific-number" );
1248 xmlWriter->addAttribute( "number:decimal-places", 17 );
1249 xmlWriter->addAttribute( "number:min-integer-digits", 1 );
1250 xmlWriter->addAttribute( "number:min-exponent-digits", 2 );
1251 xmlWriter->endElement(); // number:scientific-number
1252 xmlWriter->endElement(); // number:number-style
1253 }
1254 else if( valueFormat == "0%")
1255 {
1256 xmlWriter->startElement( "number:percentage-style" );
1257 xmlWriter->addAttribute( "style:name", refName );
1258 xmlWriter->startElement( "number:number" );
1259 xmlWriter->addAttribute( "number:decimal-places", 0 );
1260 xmlWriter->addAttribute( "number:min-integer-digits", 1 );
1261 xmlWriter->endElement(); // number:number
1262 xmlWriter->startElement( "number:text" );
1263 xmlWriter->addTextNode( "%" );
1264 xmlWriter->endElement(); // number:text
1265 xmlWriter->endElement(); // number:percentage-style
1266 }
1267 else if( valueFormat == "0.0%")
1268 {
1269 xmlWriter->startElement( "number:percentage-style" );
1270 xmlWriter->addAttribute( "style:name", refName );
1271 xmlWriter->startElement( "number:number" );
1272 xmlWriter->addAttribute( "number:decimal-places", 1 );
1273 xmlWriter->addAttribute( "number:min-integer-digits", 1 );
1274 xmlWriter->endElement(); // number:number
1275 xmlWriter->startElement( "number:text" );
1276 xmlWriter->addTextNode( "%" );
1277 xmlWriter->endElement(); // number:text
1278 xmlWriter->endElement(); // number:percentage-style
1279 }
1280 else if( valueFormat == "0.00%")
1281 {
1282 xmlWriter->startElement( "number:percentage-style" );
1283 xmlWriter->addAttribute( "style:name", refName );
1284 xmlWriter->startElement( "number:number" );
1285 xmlWriter->addAttribute( "number:decimal-places", 2 );
1286 xmlWriter->addAttribute( "number:min-integer-digits", 1 );
1287 xmlWriter->endElement(); // number:number
1288 xmlWriter->startElement( "number:text" );
1289 xmlWriter->addTextNode( "%" );
1290 xmlWriter->endElement(); // number:text
1291 xmlWriter->endElement(); // number:percentage-style
1292 }
1293 else if( valueFormat == "0.000%")
1294 {
1295 xmlWriter->startElement( "number:percentage-style" );
1296 xmlWriter->addAttribute( "style:name", refName );
1297 xmlWriter->startElement( "number:number" );
1298 xmlWriter->addAttribute( "number:decimal-places", 3 );
1299 xmlWriter->addAttribute( "number:min-integer-digits", 1 );
1300 xmlWriter->endElement(); // number:number
1301 xmlWriter->startElement( "number:text" );
1302 xmlWriter->addTextNode( "%" );
1303 xmlWriter->endElement(); // number:text
1304 xmlWriter->endElement(); // number:percentage-style
1305 }
1306 else if( valueFormat == "0.0000%")
1307 {
1308 xmlWriter->startElement( "number:percentage-style" );
1309 xmlWriter->addAttribute( "style:name", refName );
1310 xmlWriter->startElement( "number:number" );
1311 xmlWriter->addAttribute( "number:decimal-places", 4 );
1312 xmlWriter->addAttribute( "number:min-integer-digits", 1 );
1313 xmlWriter->endElement(); // number:number
1314 xmlWriter->startElement( "number:text" );
1315 xmlWriter->addTextNode( "%" );
1316 xmlWriter->endElement(); // number:text
1317 xmlWriter->endElement(); // number:percentage-style
1318 }
1319 else if( valueFormat == "0.00000%")
1320 {
1321 xmlWriter->startElement( "number:percentage-style" );
1322 xmlWriter->addAttribute( "style:name", refName );
1323 xmlWriter->startElement( "number:number" );
1324 xmlWriter->addAttribute( "number:decimal-places", 5 );
1325 xmlWriter->addAttribute( "number:min-integer-digits", 1 );
1326 xmlWriter->endElement(); // number:number
1327 xmlWriter->startElement( "number:text" );
1328 xmlWriter->addTextNode( "%" );
1329 xmlWriter->endElement(); // number:text
1330 xmlWriter->endElement(); // number:percentage-style
1331 }
1332 else if( valueFormat == "0.000000%")
1333 {
1334 xmlWriter->startElement( "number:percentage-style" );
1335 xmlWriter->addAttribute( "style:name", refName );
1336 xmlWriter->startElement( "number:number" );
1337 xmlWriter->addAttribute( "number:decimal-places", 6 );
1338 xmlWriter->addAttribute( "number:min-integer-digits", 1 );
1339 xmlWriter->endElement(); // number:number
1340 xmlWriter->startElement( "number:text" );
1341 xmlWriter->addTextNode( "%" );
1342 xmlWriter->endElement(); // number:text
1343 xmlWriter->endElement(); // number:percentage-style
1344 }
1345 else if( valueFormat == "0.0000000%")
1346 {
1347 xmlWriter->startElement( "number:percentage-style" );
1348 xmlWriter->addAttribute( "style:name", refName );
1349 xmlWriter->startElement( "number:number" );
1350 xmlWriter->addAttribute( "number:decimal-places", 7 );
1351 xmlWriter->addAttribute( "number:min-integer-digits", 1 );
1352 xmlWriter->endElement(); // number:number
1353 xmlWriter->startElement( "number:text" );
1354 xmlWriter->addTextNode( "%" );
1355 xmlWriter->endElement(); // number:text
1356 xmlWriter->endElement(); // number:percentage-style
1357 }
1358 else if( valueFormat == "0.00000000%")
1359 {
1360 xmlWriter->startElement( "number:percentage-style" );
1361 xmlWriter->addAttribute( "style:name", refName );
1362 xmlWriter->startElement( "number:number" );
1363 xmlWriter->addAttribute( "number:decimal-places", 8 );
1364 xmlWriter->addAttribute( "number:min-integer-digits", 1 );
1365 xmlWriter->endElement(); // number:number
1366 xmlWriter->startElement( "number:text" );
1367 xmlWriter->addTextNode( "%" );
1368 xmlWriter->endElement(); // number:text
1369 xmlWriter->endElement(); // number:percentage-style
1370 }
1371 else if( valueFormat == "0.000000000%")
1372 {
1373 xmlWriter->startElement( "number:percentage-style" );
1374 xmlWriter->addAttribute( "style:name", refName );
1375 xmlWriter->startElement( "number:number" );
1376 xmlWriter->addAttribute( "number:decimal-places", 9 );
1377 xmlWriter->addAttribute( "number:min-integer-digits", 1 );
1378 xmlWriter->endElement(); // number:number
1379 xmlWriter->startElement( "number:text" );
1380 xmlWriter->addTextNode( "%" );
1381 xmlWriter->endElement(); // number:text
1382 xmlWriter->endElement(); // number:percentage-style
1383 }
1384 else if( valueFormat == "0.0000000000%")
1385 {
1386 xmlWriter->startElement( "number:percentage-style" );
1387 xmlWriter->addAttribute( "style:name", refName );
1388 xmlWriter->startElement( "number:number" );
1389 xmlWriter->addAttribute( "number:decimal-places", 10 );
1390 xmlWriter->addAttribute( "number:min-integer-digits", 1 );
1391 xmlWriter->endElement(); // number:number
1392 xmlWriter->startElement( "number:text" );
1393 xmlWriter->addTextNode( "%" );
1394 xmlWriter->endElement(); // number:text
1395 xmlWriter->endElement(); // number:percentage-style
1396 }
1397 else if( valueFormat == "0.00000000000%")
1398 {
1399 xmlWriter->startElement( "number:percentage-style" );
1400 xmlWriter->addAttribute( "style:name", refName );
1401 xmlWriter->startElement( "number:number" );
1402 xmlWriter->addAttribute( "number:decimal-places", 11 );
1403 xmlWriter->addAttribute( "number:min-integer-digits", 1 );
1404 xmlWriter->endElement(); // number:number
1405 xmlWriter->startElement( "number:text" );
1406 xmlWriter->addTextNode( "%" );
1407 xmlWriter->endElement(); // number:text
1408 xmlWriter->endElement(); // number:percentage-style
1409 }
1410 else if( valueFormat == "0.000000000000%")
1411 {
1412 xmlWriter->startElement( "number:percentage-style" );
1413 xmlWriter->addAttribute( "style:name", refName );
1414 xmlWriter->startElement( "number:number" );
1415 xmlWriter->addAttribute( "number:decimal-places", 12 );
1416 xmlWriter->addAttribute( "number:min-integer-digits", 1 );
1417 xmlWriter->endElement(); // number:number
1418 xmlWriter->startElement( "number:text" );
1419 xmlWriter->addTextNode( "%" );
1420 xmlWriter->endElement(); // number:text
1421 xmlWriter->endElement(); // number:percentage-style
1422 }
1423 else if( valueFormat == "0.0000000000000%")
1424 {
1425 xmlWriter->startElement( "number:percentage-style" );
1426 xmlWriter->addAttribute( "style:name", refName );
1427 xmlWriter->startElement( "number:number" );
1428 xmlWriter->addAttribute( "number:decimal-places", 13 );
1429 xmlWriter->addAttribute( "number:min-integer-digits", 1 );
1430 xmlWriter->endElement(); // number:number
1431 xmlWriter->startElement( "number:text" );
1432 xmlWriter->addTextNode( "%" );
1433 xmlWriter->endElement(); // number:text
1434 xmlWriter->endElement(); // number:percentage-style
1435 }
1436 else if( valueFormat == "0.00000000000000%")
1437 {
1438 xmlWriter->startElement( "number:percentage-style" );
1439 xmlWriter->addAttribute( "style:name", refName );
1440 xmlWriter->startElement( "number:number" );
1441 xmlWriter->addAttribute( "number:decimal-places", 14 );
1442 xmlWriter->addAttribute( "number:min-integer-digits", 1 );
1443 xmlWriter->endElement(); // number:number
1444 xmlWriter->startElement( "number:text" );
1445 xmlWriter->addTextNode( "%" );
1446 xmlWriter->endElement(); // number:text
1447 xmlWriter->endElement(); // number:percentage-style
1448 }
1449 else if( valueFormat == "0.000000000000000%")
1450 {
1451 xmlWriter->startElement( "number:percentage-style" );
1452 xmlWriter->addAttribute( "style:name", refName );
1453 xmlWriter->startElement( "number:number" );
1454 xmlWriter->addAttribute( "number:decimal-places", 15 );
1455 xmlWriter->addAttribute( "number:min-integer-digits", 1 );
1456 xmlWriter->endElement(); // number:number
1457 xmlWriter->startElement( "number:text" );
1458 xmlWriter->addTextNode( "%" );
1459 xmlWriter->endElement(); // number:text
1460 xmlWriter->endElement(); // number:percentage-style
1461 }
1462 else if( valueFormat == "0.0000000000000000%")
1463 {
1464 xmlWriter->startElement( "number:percentage-style" );
1465 xmlWriter->addAttribute( "style:name", refName );
1466 xmlWriter->startElement( "number:number" );
1467 xmlWriter->addAttribute( "number:decimal-places", 16 );
1468 xmlWriter->addAttribute( "number:min-integer-digits", 1 );
1469 xmlWriter->endElement(); // number:number
1470 xmlWriter->startElement( "number:text" );
1471 xmlWriter->addTextNode( "%" );
1472 xmlWriter->endElement(); // number:text
1473 xmlWriter->endElement(); // number:percentage-style
1474 }
1475 else if( valueFormat.lower() == "m/d/yy")
1476 {
1477 xmlWriter->startElement( "number:date-style" );
1478 xmlWriter->addAttribute( "style:name", refName );
1479 xmlWriter->addAttribute( "style:family", "data-style" );
1480
1481 xmlWriter->startElement( "number:month" );
1482 xmlWriter->addAttribute( "number:textual", "false" );
1483 xmlWriter->addAttribute( "number:style", "short" );
1484 xmlWriter->endElement(); // number:month
1485
1486 xmlWriter->startElement( "number:text");
1487 xmlWriter->addTextNode( "/" );
1488 xmlWriter->endElement(); // number:text
1489
1490 xmlWriter->startElement( "number:day" );
1491 xmlWriter->addAttribute( "number:style", "short" );
1492 xmlWriter->endElement(); // number:day
1493
1494 xmlWriter->startElement( "number:text");
1495 xmlWriter->addTextNode( "/" );
1496 xmlWriter->endElement(); // number:text
1497
1498 xmlWriter->startElement( "number:year" );
1499 xmlWriter->addAttribute( "number:style", "short" );
1500 xmlWriter->endElement(); // number:year
1501
1502 xmlWriter->endElement(); // number:date-style
1503 }
1504 else if( valueFormat.lower() == "m/d/yyyy")
1505 {
1506 xmlWriter->startElement( "number:date-style" );
1507 xmlWriter->addAttribute( "style:name", refName );
1508 xmlWriter->addAttribute( "style:family", "data-style" );
1509
1510 xmlWriter->startElement( "number:month" );
1511 xmlWriter->addAttribute( "number:textual", "false" );
1512 xmlWriter->addAttribute( "number:style", "short" );
1513 xmlWriter->endElement(); // number:month
1514
1515 xmlWriter->startElement( "number:text");
1516 xmlWriter->addTextNode( "/" );
1517 xmlWriter->endElement(); // number:text
1518
1519 xmlWriter->startElement( "number:day" );
1520 xmlWriter->addAttribute( "number:style", "short" );
1521 xmlWriter->endElement(); // number:day
1522
1523 xmlWriter->startElement( "number:text");
1524 xmlWriter->addTextNode( "/" );
1525 xmlWriter->endElement(); // number:text
1526
1527 xmlWriter->startElement( "number:year" );
1528 xmlWriter->addAttribute( "number:style", "long" );
1529 xmlWriter->endElement(); // number:year
1530
1531 xmlWriter->endElement(); // number:date-style
1532 }
1533 else if( (valueFormat.lower() == "d-mmm-yy") || (valueFormat.lower() == "d\\-mmm\\-yy") )
1534 {
1535 xmlWriter->startElement( "number:date-style" );
1536 xmlWriter->addAttribute( "style:name", refName );
1537 xmlWriter->addAttribute( "style:family", "data-style" );
1538
1539 xmlWriter->startElement( "number:day" );
1540 xmlWriter->addAttribute( "number:style", "short" );
1541 xmlWriter->endElement(); // number:day
1542
1543 xmlWriter->startElement( "number:text");
1544 xmlWriter->addTextNode( "-" );
1545 xmlWriter->endElement(); // number:text
1546
1547 xmlWriter->startElement( "number:month" );
1548 xmlWriter->addAttribute( "number:textual", "true" );
1549 xmlWriter->addAttribute( "number:style", "short" );
1550 xmlWriter->endElement(); // number:month
1551
1552 xmlWriter->startElement( "number:text");
1553 xmlWriter->addTextNode( "-" );
1554 xmlWriter->endElement(); // number:text
1555
1556 xmlWriter->startElement( "number:year" );
1557 xmlWriter->addAttribute( "number:style", "short" );
1558 xmlWriter->endElement(); // number:year
1559
1560 xmlWriter->endElement(); // number:date-style
1561 }
1562 else if( (valueFormat.lower() == "d-mmm-yyyy") || (valueFormat.lower() == "d\\-mmm\\-yyyy") )
1563 {
1564 xmlWriter->startElement( "number:date-style" );
1565 xmlWriter->addAttribute( "style:name", refName );
1566 xmlWriter->addAttribute( "style:family", "data-style" );
1567
1568 xmlWriter->startElement( "number:day" );
1569 xmlWriter->addAttribute( "number:style", "short" );
1570 xmlWriter->endElement(); // number:day
1571
1572 xmlWriter->startElement( "number:text");
1573 xmlWriter->addTextNode( "-" );
1574 xmlWriter->endElement(); // number:text
1575
1576 xmlWriter->startElement( "number:month" );
1577 xmlWriter->addAttribute( "number:textual", "true" );
1578 xmlWriter->addAttribute( "number:style", "short" );
1579 xmlWriter->endElement(); // number:month
1580
1581 xmlWriter->startElement( "number:text");
1582 xmlWriter->addTextNode( "-" );
1583 xmlWriter->endElement(); // number:text
1584
1585 xmlWriter->startElement( "number:year" );
1586 xmlWriter->addAttribute( "number:style", "long" );
1587 xmlWriter->endElement(); // number:year
1588
1589 xmlWriter->endElement(); // number:date-style
1590 }
1591 else if( (valueFormat.lower() == "d-mmm") || (valueFormat.lower() == "d\\-mmm") )
1592 {
1593 xmlWriter->startElement( "number:date-style" );
1594 xmlWriter->addAttribute( "style:name", refName );
1595 xmlWriter->addAttribute( "style:family", "data-style" );
1596
1597 xmlWriter->startElement( "number:day" );
1598 xmlWriter->addAttribute( "number:style", "short" );
1599 xmlWriter->endElement(); // number:day
1600
1601 xmlWriter->startElement( "number:text");
1602 xmlWriter->addTextNode( "-" );
1603 xmlWriter->endElement(); // number:text
1604
1605 xmlWriter->startElement( "number:month" );
1606 xmlWriter->addAttribute( "number:textual", "true" );
1607 xmlWriter->addAttribute( "number:style", "short" );
1608 xmlWriter->endElement(); // number:month
1609
1610 xmlWriter->endElement(); // number:date-style
1611 }
1612 else if( (valueFormat.lower() == "d-mm") || (valueFormat.lower() == "d\\-mm") )
1613 {
1614 xmlWriter->startElement( "number:date-style" );
1615 xmlWriter->addAttribute( "style:name", refName );
1616 xmlWriter->addAttribute( "style:family", "data-style" );
1617
1618 xmlWriter->startElement( "number:day" );
1619 xmlWriter->addAttribute( "number:style", "short" );
1620 xmlWriter->endElement(); // number:day
1621
1622 xmlWriter->startElement( "number:text");
1623 xmlWriter->addTextNode( "-" );
1624 xmlWriter->endElement(); // number:text
1625
1626 xmlWriter->startElement( "number:month" );
1627 xmlWriter->addAttribute( "number:textual", "false" );
1628 xmlWriter->addAttribute( "number:style", "long" );
1629 xmlWriter->endElement(); // number:month
1630
1631 xmlWriter->endElement(); // number:date-style
1632 }
1633 else if( valueFormat.lower() == "mmm/d" )
1634 {
1635 xmlWriter->startElement( "number:date-style" );
1636 xmlWriter->addAttribute( "style:name", refName );
1637 xmlWriter->addAttribute( "style:family", "data-style" );
1638
1639 xmlWriter->startElement( "number:month" );
1640 xmlWriter->addAttribute( "number:textual", "true" );
1641 xmlWriter->addAttribute( "number:style", "short" );
1642 xmlWriter->endElement(); // number:month
1643
1644 xmlWriter->startElement( "number:text");
1645 xmlWriter->addTextNode( "/" );
1646 xmlWriter->endElement(); // number:text
1647
1648 xmlWriter->startElement( "number:day" );
1649 xmlWriter->addAttribute( "number:style", "short" );
1650 xmlWriter->endElement(); // number:day
1651
1652 xmlWriter->endElement(); // number:date-style
1653 }
1654 else if( valueFormat.lower() == "mmm/dd" )
1655 {
1656 xmlWriter->startElement( "number:date-style" );
1657 xmlWriter->addAttribute( "style:name", refName );
1658 xmlWriter->addAttribute( "style:family", "data-style" );
1659
1660 xmlWriter->startElement( "number:month" );
1661 xmlWriter->addAttribute( "number:textual", "true" );
1662 xmlWriter->addAttribute( "number:style", "short" );
1663 xmlWriter->endElement(); // number:month
1664
1665 xmlWriter->startElement( "number:text");
1666 xmlWriter->addTextNode( "/" );
1667 xmlWriter->endElement(); // number:text
1668
1669 xmlWriter->startElement( "number:day" );
1670 xmlWriter->addAttribute( "number:style", "long" );
1671 xmlWriter->endElement(); // number:day
1672
1673 xmlWriter->endElement(); // number:date-style
1674 }
1675 else if( valueFormat.lower() == "mm/d" )
1676 {
1677 xmlWriter->startElement( "number:date-style" );
1678 xmlWriter->addAttribute( "style:name", refName );
1679 xmlWriter->addAttribute( "style:family", "data-style" );
1680
1681 xmlWriter->startElement( "number:month" );
1682 xmlWriter->addAttribute( "number:textual", "false" );
1683 xmlWriter->addAttribute( "number:style", "long" );
1684 xmlWriter->endElement(); // number:month
1685
1686 xmlWriter->startElement( "number:text");
1687 xmlWriter->addTextNode( "/" );
1688 xmlWriter->endElement(); // number:text
1689
1690 xmlWriter->startElement( "number:day" );
1691 xmlWriter->addAttribute( "number:style", "short" );
1692 xmlWriter->endElement(); // number:day
1693
1694 xmlWriter->endElement(); // number:date-style
1695 }
1696 else if( valueFormat.lower() == "mm/dd" )
1697 {
1698 xmlWriter->startElement( "number:date-style" );
1699 xmlWriter->addAttribute( "style:name", refName );
1700 xmlWriter->addAttribute( "style:family", "data-style" );
1701
1702 xmlWriter->startElement( "number:month" );
1703 xmlWriter->addAttribute( "number:textual", "false" );
1704 xmlWriter->addAttribute( "number:style", "long" );
1705 xmlWriter->endElement(); // number:month
1706
1707 xmlWriter->startElement( "number:text");
1708 xmlWriter->addTextNode( "/" );
1709 xmlWriter->endElement(); // number:text
1710
1711 xmlWriter->startElement( "number:day" );
1712 xmlWriter->addAttribute( "number:style", "long" );
1713 xmlWriter->endElement(); // number:day
1714
1715 xmlWriter->endElement(); // number:date-style
1716 }
1717 else if( valueFormat.lower() == "mm/dd/yy" )
1718 {
1719 xmlWriter->startElement( "number:date-style" );
1720 xmlWriter->addAttribute( "style:name", refName );
1721 xmlWriter->addAttribute( "style:family", "data-style" );
1722
1723 xmlWriter->startElement( "number:month" );
1724 xmlWriter->addAttribute( "number:textual", "false" );
1725 xmlWriter->addAttribute( "number:style", "long" );
1726 xmlWriter->endElement(); // number:month
1727
1728 xmlWriter->startElement( "number:text");
1729 xmlWriter->addTextNode( "/" );
1730 xmlWriter->endElement(); // number:text
1731
1732 xmlWriter->startElement( "number:day" );
1733 xmlWriter->addAttribute( "number:style", "long" );
1734 xmlWriter->endElement(); // number:day
1735
1736 xmlWriter->startElement( "number:text");
1737 xmlWriter->addTextNode( "/" );
1738 xmlWriter->endElement(); // number:text
1739
1740 xmlWriter->startElement( "number:year" );
1741 xmlWriter->addAttribute( "number:style", "short" );
1742 xmlWriter->endElement(); // number:year
1743
1744 xmlWriter->endElement(); // number:date-style
1745 }
1746 else if( valueFormat.lower() == "mm/dd/yyyy" )
1747 {
1748 xmlWriter->startElement( "number:date-style" );
1749 xmlWriter->addAttribute( "style:name", refName );
1750 xmlWriter->addAttribute( "style:family", "data-style" );
1751
1752 xmlWriter->startElement( "number:month" );
1753 xmlWriter->addAttribute( "number:textual", "false" );
1754 xmlWriter->addAttribute( "number:style", "long" );
1755 xmlWriter->endElement(); // number:month
1756
1757 xmlWriter->startElement( "number:text");
1758 xmlWriter->addTextNode( "/" );
1759 xmlWriter->endElement(); // number:text
1760
1761 xmlWriter->startElement( "number:day" );
1762 xmlWriter->addAttribute( "number:style", "long" );
1763 xmlWriter->endElement(); // number:day
1764
1765 xmlWriter->startElement( "number:text");
1766 xmlWriter->addTextNode( "/" );
1767 xmlWriter->endElement(); // number:text
1768
1769 xmlWriter->startElement( "number:year" );
1770 xmlWriter->addAttribute( "number:style", "long" );
1771 xmlWriter->endElement(); // number:year
1772
1773 xmlWriter->endElement(); // number:date-style
1774 }
1775 else if( valueFormat.lower() == "yyyy/mm/dd" )
1776 {
1777 xmlWriter->startElement( "number:date-style" );
1778 xmlWriter->addAttribute( "style:name", refName );
1779 xmlWriter->addAttribute( "style:family", "data-style" );
1780
1781 xmlWriter->startElement( "number:year" );
1782 xmlWriter->addAttribute( "number:style", "long" );
1783 xmlWriter->endElement(); // number:year
1784
1785 xmlWriter->startElement( "number:text");
1786 xmlWriter->addTextNode( "/" );
1787 xmlWriter->endElement(); // number:text
1788
1789 xmlWriter->startElement( "number:month" );
1790 xmlWriter->addAttribute( "number:textual", "false" );
1791 xmlWriter->addAttribute( "number:style", "long" );
1792 xmlWriter->endElement(); // number:month
1793
1794 xmlWriter->startElement( "number:text");
1795 xmlWriter->addTextNode( "/" );
1796 xmlWriter->endElement(); // number:text
1797
1798 xmlWriter->startElement( "number:day" );
1799 xmlWriter->addAttribute( "number:style", "long" );
1800 xmlWriter->endElement(); // number:day
1801
1802 xmlWriter->endElement(); // number:date-style
1803 }
1804 else if( valueFormat.lower() == "yyyy/mm/d" )
1805 {
1806 xmlWriter->startElement( "number:date-style" );
1807 xmlWriter->addAttribute( "style:name", refName );
1808 xmlWriter->addAttribute( "style:family", "data-style" );
1809
1810 xmlWriter->startElement( "number:year" );
1811 xmlWriter->addAttribute( "number:style", "long" );
1812 xmlWriter->endElement(); // number:year
1813
1814 xmlWriter->startElement( "number:text");
1815 xmlWriter->addTextNode( "/" );
1816 xmlWriter->endElement(); // number:text
1817
1818 xmlWriter->startElement( "number:month" );
1819 xmlWriter->addAttribute( "number:textual", "false" );
1820 xmlWriter->addAttribute( "number:style", "long" );
1821 xmlWriter->endElement(); // number:month
1822
1823 xmlWriter->startElement( "number:text");
1824 xmlWriter->addTextNode( "/" );
1825 xmlWriter->endElement(); // number:text
1826
1827 xmlWriter->startElement( "number:day" );
1828 xmlWriter->addAttribute( "number:style", "short" );
1829 xmlWriter->endElement(); // number:day
1830
1831 xmlWriter->endElement(); // number:date-style
1832 }
1833 else if( (valueFormat.lower() == "yyyy-mm-dd") || (valueFormat.lower() == "yyyy\\-mm\\-dd") )
1834 {
1835 xmlWriter->startElement( "number:date-style" );
1836 xmlWriter->addAttribute( "style:name", refName );
1837 xmlWriter->addAttribute( "style:family", "data-style" );
1838
1839 xmlWriter->startElement( "number:year" );
1840 xmlWriter->addAttribute( "number:style", "long" );
1841 xmlWriter->endElement(); // number:year
1842
1843 xmlWriter->startElement( "number:text");
1844 xmlWriter->addTextNode( "-" );
1845 xmlWriter->endElement(); // number:text
1846
1847 xmlWriter->startElement( "number:month" );
1848 xmlWriter->addAttribute( "number:textual", "false" );
1849 xmlWriter->addAttribute( "number:style", "long" );
1850 xmlWriter->endElement(); // number:month
1851
1852 xmlWriter->startElement( "number:text");
1853 xmlWriter->addTextNode( "-" );
1854 xmlWriter->endElement(); // number:text
1855
1856 xmlWriter->startElement( "number:day" );
1857 xmlWriter->addAttribute( "number:style", "long" );
1858 xmlWriter->endElement(); // number:day
1859
1860 xmlWriter->endElement(); // number:date-style
1861 }
1862 else if( (valueFormat.lower() == "yyyy-mm-d") || (valueFormat.lower() == "yyyy\\-mm\\-d") )
1863 {
1864 xmlWriter->startElement( "number:date-style" );
1865 xmlWriter->addAttribute( "style:name", refName );
1866 xmlWriter->addAttribute( "style:family", "data-style" );
1867
1868 xmlWriter->startElement( "number:year" );
1869 xmlWriter->addAttribute( "number:style", "long" );
1870 xmlWriter->endElement(); // number:year
1871
1872 xmlWriter->startElement( "number:text");
1873 xmlWriter->addTextNode( "-" );
1874 xmlWriter->endElement(); // number:text
1875
1876 xmlWriter->startElement( "number:month" );
1877 xmlWriter->addAttribute( "number:textual", "false" );
1878 xmlWriter->addAttribute( "number:style", "long" );
1879 xmlWriter->endElement(); // number:month
1880
1881 xmlWriter->startElement( "number:text");
1882 xmlWriter->addTextNode( "-" );
1883 xmlWriter->endElement(); // number:text
1884
1885 xmlWriter->startElement( "number:day" );
1886 xmlWriter->addAttribute( "number:style", "short" );
1887 xmlWriter->endElement(); // number:day
1888
1889 xmlWriter->endElement(); // number:date-style
1890 }
1891
1892 else if( valueFormat == "h:mm AM/PM" )
1893 {
1894 xmlWriter->startElement( "number:time-style" );
1895 xmlWriter->addAttribute( "style:name", refName );
1896 xmlWriter->addAttribute( "style:family", "data-style" );
1897
1898 xmlWriter->startElement( "number:hours" );
1899 xmlWriter->addAttribute( "number:style", "short" );
1900 xmlWriter->endElement(); // number:hour
1901
1902 xmlWriter->startElement( "number:text");
1903 xmlWriter->addTextNode( ":" );
1904 xmlWriter->endElement(); // number:text
1905
1906 xmlWriter->startElement( "number:minutes" );
1907 xmlWriter->addAttribute( "number:style", "long" );
1908 xmlWriter->endElement(); // number:minutes
1909
1910 xmlWriter->startElement( "number:text");
1911 xmlWriter->addTextNode( " " );
1912 xmlWriter->endElement(); // number:text
1913
1914 xmlWriter->startElement( "number:am-pm" );
1915 xmlWriter->endElement(); // number:am-pm
1916
1917 xmlWriter->endElement(); // number:time-style
1918 }
1919 else if( valueFormat == "h:mm:ss AM/PM" )
1920 {
1921 xmlWriter->startElement( "number:time-style" );
1922 xmlWriter->addAttribute( "style:name", refName );
1923 xmlWriter->addAttribute( "style:family", "data-style" );
1924
1925 xmlWriter->startElement( "number:hours" );
1926 xmlWriter->addAttribute( "number:style", "short" );
1927 xmlWriter->endElement(); // number:hour
1928
1929 xmlWriter->startElement( "number:text");
1930 xmlWriter->addTextNode( ":" );
1931 xmlWriter->endElement(); // number:text
1932
1933 xmlWriter->startElement( "number:minutes" );
1934 xmlWriter->addAttribute( "number:style", "long" );
1935 xmlWriter->endElement(); // number:minutes
1936
1937 xmlWriter->startElement( "number:text");
1938 xmlWriter->addTextNode( ":" );
1939 xmlWriter->endElement(); // number:text
1940
1941 xmlWriter->startElement( "number:seconds" );
1942 xmlWriter->addAttribute( "number:style", "long" );
1943 xmlWriter->endElement(); // number:minutes
1944
1945 xmlWriter->startElement( "number:text");
1946 xmlWriter->addTextNode( " " );
1947 xmlWriter->endElement(); // number:text
1948
1949 xmlWriter->startElement( "number:am-pm" );
1950 xmlWriter->endElement(); // number:am-pm
1951
1952 xmlWriter->endElement(); // number:time-style
1953 }
1954 else if( valueFormat == "h:mm" )
1955 {
1956 xmlWriter->startElement( "number:time-style" );
1957 xmlWriter->addAttribute( "style:name", refName );
1958 xmlWriter->addAttribute( "style:family", "data-style" );
1959
1960 xmlWriter->startElement( "number:hours" );
1961 xmlWriter->addAttribute( "number:style", "short" );
1962 xmlWriter->endElement(); // number:hour
1963
1964 xmlWriter->startElement( "number:text");
1965 xmlWriter->addTextNode( ":" );
1966 xmlWriter->endElement(); // number:text
1967
1968 xmlWriter->startElement( "number:minutes" );
1969 xmlWriter->addAttribute( "number:style", "long" );
1970 xmlWriter->endElement(); // number:minutes
1971
1972 xmlWriter->endElement(); // number:time-style
1973 }
1974 else if( valueFormat == "h:mm:ss" )
1975 {
1976 xmlWriter->startElement( "number:time-style" );
1977 xmlWriter->addAttribute( "style:name", refName );
1978 xmlWriter->addAttribute( "style:family", "data-style" );
1979
1980 xmlWriter->startElement( "number:hours" );
1981 xmlWriter->addAttribute( "number:style", "short" );
1982 xmlWriter->endElement(); // number:hour
1983
1984 xmlWriter->startElement( "number:text");
1985 xmlWriter->addTextNode( ":" );
1986 xmlWriter->endElement(); // number:text
1987
1988 xmlWriter->startElement( "number:minutes" );
1989 xmlWriter->addAttribute( "number:style", "long" );
1990 xmlWriter->endElement(); // number:minutes
1991
1992 xmlWriter->startElement( "number:text");
1993 xmlWriter->addTextNode( ":" );
1994 xmlWriter->endElement(); // number:text
1995
1996 xmlWriter->startElement( "number:seconds" );
1997 xmlWriter->addAttribute( "number:style", "long" );
1998 xmlWriter->endElement(); // number:minutes
1999
2000 xmlWriter->endElement(); // number:time-style
2001 }
2002 else if( valueFormat == "[h]:mm" )
2003 {
2004 xmlWriter->startElement( "number:time-style" );
2005 xmlWriter->addAttribute( "style:name", refName );
2006 xmlWriter->addAttribute( "style:family", "data-style" );
2007 xmlWriter->addAttribute( "number:truncate-on-overflow", "false" );
2008
2009 xmlWriter->startElement( "number:hours" );
2010 xmlWriter->addAttribute( "number:style", "short" );
2011 xmlWriter->endElement(); // number:hour
2012
2013 xmlWriter->startElement( "number:text");
2014 xmlWriter->addTextNode( ":" );
2015 xmlWriter->endElement(); // number:text
2016
2017 xmlWriter->startElement( "number:minutes" );
2018 xmlWriter->addAttribute( "number:style", "long" );
2019 xmlWriter->endElement(); // number:minutes
2020
2021 xmlWriter->endElement(); // number:time-style
2022 }
2023 else if( valueFormat == "[h]:mm:ss" )
2024 {
2025 xmlWriter->startElement( "number:time-style" );
2026 xmlWriter->addAttribute( "style:name", refName );
2027 xmlWriter->addAttribute( "style:family", "data-style" );
2028 xmlWriter->addAttribute( "number:truncate-on-overflow", "false" );
2029
2030 xmlWriter->startElement( "number:hours" );
2031 xmlWriter->addAttribute( "number:style", "short" );
2032 xmlWriter->endElement(); // number:hour
2033
2034 xmlWriter->startElement( "number:text");
2035 xmlWriter->addTextNode( ":" );
2036 xmlWriter->endElement(); // number:text
2037
2038 xmlWriter->startElement( "number:minutes" );
2039 xmlWriter->addAttribute( "number:style", "long" );
2040 xmlWriter->endElement(); // number:minutes
2041
2042 xmlWriter->startElement( "number:text");
2043 xmlWriter->addTextNode( ":" );
2044 xmlWriter->endElement(); // number:text
2045
2046 xmlWriter->startElement( "number:seconds" );
2047 xmlWriter->addAttribute( "number:style", "long" );
2048 xmlWriter->endElement(); // number:minutes
2049
2050 xmlWriter->endElement(); // number:time-style
2051 }
2052 else if( valueFormat == "mm:ss" )
2053 {
2054 xmlWriter->startElement( "number:time-style" );
2055 xmlWriter->addAttribute( "style:name", refName );
2056 xmlWriter->addAttribute( "style:family", "data-style" );
2057
2058 xmlWriter->startElement( "number:minutes" );
2059 xmlWriter->addAttribute( "number:style", "long" );
2060 xmlWriter->endElement(); // number:minutes
2061
2062 xmlWriter->startElement( "number:text");
2063 xmlWriter->addTextNode( ":" );
2064 xmlWriter->endElement(); // number:text
2065
2066 xmlWriter->startElement( "number:seconds" );
2067 xmlWriter->addAttribute( "number:style", "long" );
2068 xmlWriter->endElement(); // number:minutes
2069
2070 xmlWriter->endElement(); // number:time-style
2071 }
2072 else if( valueFormat == "mm:ss.0" )
2073 {
2074 xmlWriter->startElement( "number:time-style" );
2075 xmlWriter->addAttribute( "style:name", refName );
2076 xmlWriter->addAttribute( "style:family", "data-style" );
2077
2078 xmlWriter->startElement( "number:minutes" );
2079 xmlWriter->addAttribute( "number:style", "long" );
2080 xmlWriter->endElement(); // number:minutes
2081
2082 xmlWriter->startElement( "number:text");
2083 xmlWriter->addTextNode( ":" );
2084 xmlWriter->endElement(); // number:text
2085
2086 xmlWriter->startElement( "number:seconds" );
2087 xmlWriter->addAttribute( "number:style", "long" );
2088
2089 xmlWriter->endElement(); // number:minutes
2090 xmlWriter->startElement( "number:text");
2091 xmlWriter->addTextNode( ".0" );
2092 xmlWriter->endElement(); // number:text
2093
2094
2095 xmlWriter->endElement(); // number:time-style
2096 }
2097 else if( valueFormat == "[mm]:ss" )
2098 {
2099 xmlWriter->startElement( "number:time-style" );
2100 xmlWriter->addAttribute( "style:name", refName );
2101 xmlWriter->addAttribute( "style:family", "data-style" );
2102 xmlWriter->addAttribute( "number:truncate-on-overflow", "false" );
2103
2104 xmlWriter->startElement( "number:minutes" );
2105 xmlWriter->addAttribute( "number:style", "long" );
2106 xmlWriter->endElement(); // number:minutes
2107
2108 xmlWriter->startElement( "number:text");
2109 xmlWriter->addTextNode( ":" );
2110 xmlWriter->endElement(); // number:text
2111
2112 xmlWriter->startElement( "number:seconds" );
2113 xmlWriter->addAttribute( "number:style", "long" );
2114 xmlWriter->endElement(); // number:minutes
2115
2116 xmlWriter->endElement(); // number:time-style
2117 }
2118 else if( valueFormat == "[ss]" )
2119 {
2120 xmlWriter->startElement( "number:time-style" );
2121 xmlWriter->addAttribute( "style:name", refName );
2122 xmlWriter->addAttribute( "style:family", "data-style" );
2123 xmlWriter->addAttribute( "number:truncate-on-overflow", "false" );
2124
2125 xmlWriter->startElement( "number:seconds" );
2126 xmlWriter->addAttribute( "number:style", "long" );
2127 xmlWriter->endElement(); // number:minutes
2128
2129 xmlWriter->endElement(); // number:time-style
2130 }
2131
2132}
Provides color based on RGB values.
Defines alignment information for cell format.
unsigned indentLevel() const
Returns the indentation level.
bool wrap() const
Returns true if the text should be wrapped at right border.
unsigned alignY() const
Returns horizontal alignment.
bool isNull() const
Returns true if it is a default alignment information.
unsigned alignX() const
Returns horizontal alignment.
Defines background information for cell.
unsigned pattern() const
Returns pattern for this background.
bool isNull() const
Returns true if it is a default background information.
Color foregroundColor() const
Returns the foreground color of the background area.
Color backgroundColor() const
Returns the background color of the background area.
Defines borders information for cell.
const Pen & leftBorder() const
Returns pen style, width and color for left border.
const Pen & rightBorder() const
Returns pen style, width and color for right border.
bool isNull() const
Returns true if it is a default border information.
const Pen & topBorder() const
Returns pen style, width and color for top border.
const Pen & bottomBorder() const
Returns pen style, width and color for bottom border.
Defines font information for cell format.
bool italic() const
Returns true if italic has been set.
bool strikeout() const
Returns true if strikeout has been set.
bool isNull() const
Returns true if it is a default font information.
bool subscript() const
Returns true if subscript has been set.
bool superscript() const
Returns true if superscript has been set.
double fontSize() const
Returns the size of font (in points).
const UString & fontFamily() const
Returns the name of font family, e.g "Helvetica".
Color color() const
Returns the color of the font.
bool underline() const
Returns true if underline has been set.
bool bold() const
Returns true if bold has been set.
FormatFont & font() const
Returns a constant reference to the formatting information of this format.
const UString & valueFormat() const
Returns the formatting string to display the value of this format.
FormatAlignment & alignment() const
Returns a constant reference to the alignment information of this format.
FormatBorders & borders() const
Returns a reference to the borders information of this format.
FormatBackground & background() const
Returns a reference to the background information of this format.
Provides a wrapper for cell value.
Definition value.h:43
bool isInteger() const
Returns true if the type of this value is integer.
Definition value.h:129
bool isBoolean() const
Returns true if the type of this value is Boolean.
Definition value.h:124
double asFloat() const
Returns the floating-point value of this value.
Definition value.cpp:226
bool isFloat() const
Returns true if the type of this value is floating-point.
Definition value.h:134
UString asString() const
Returns the string value of this value.
Definition value.cpp:248
bool isString() const
Returns true if the type of this value is string.
Definition value.h:145
bool asBoolean() const
Returns the boolean value of this value.
Definition value.cpp:180