File indexing completed on 2025-01-19 13:27:34
0001 /* 0002 * This file is part of Office 2007 Filters for Calligra 0003 * Copyright (C) 2002 Laurent Montel <lmontel@mandrakesoft.com> 0004 * Copyright (C) 2003 David Faure <faure@kde.org> 0005 * Copyright (C) 2002, 2003, 2004 Nicolas GOUTTE <goutte@kde.org> 0006 * Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). 0007 * 0008 * Contact: Suresh Chande suresh.chande@nokia.com 0009 * 0010 * This library is free software; you can redistribute it and/or 0011 * modify it under the terms of the GNU Lesser General Public License 0012 * version 2.1 as published by the Free Software Foundation. 0013 * 0014 * This library is distributed in the hope that it will be useful, but 0015 * WITHOUT ANY WARRANTY; without even the implied warranty of 0016 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 0017 * Lesser General Public License for more details. 0018 * 0019 * You should have received a copy of the GNU Lesser General Public 0020 * License along with this library; if not, write to the Free Software 0021 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 0022 * 02110-1301 USA 0023 * 0024 */ 0025 0026 #include "XlsxUtils.h" 0027 #include "XlsxImport.h" 0028 #include "XlsxXmlDocumentReader.h" 0029 #include "XlsxXmlSharedStringsReader.h" 0030 #include "XlsxXmlStylesReader.h" 0031 #include "XlsxXmlCommentsReader.h" 0032 0033 #include <MsooXmlUtils.h> 0034 #include <MsooXmlSchemas.h> 0035 #include <MsooXmlContentTypes.h> 0036 #include <MsooXmlRelationships.h> 0037 #include "MsooXmlThemesReader.h" 0038 0039 #include <memory> 0040 0041 #include <QColor> 0042 #include <QFile> 0043 #include <QFont> 0044 #include <QPen> 0045 #include <QRegExp> 0046 #include <QImage> 0047 0048 #include <kpluginfactory.h> 0049 0050 #include <KoEmbeddedDocumentSaver.h> 0051 #include <KoDocumentInfo.h> 0052 #include <KoDocument.h> 0053 #include <KoFilterChain.h> 0054 #include <KoPageLayout.h> 0055 #include <KoXmlWriter.h> 0056 0057 K_PLUGIN_FACTORY_WITH_JSON(XlsxImportFactory, "calligra_filter_xlsx2ods.json", registerPlugin<XlsxImport>();) 0058 0059 Q_LOGGING_CATEGORY(lcXlsxImport, "calligra.filter.xlsx2ods") 0060 0061 enum XlsxDocumentType { 0062 XlsxDocument, 0063 XlsxTemplate, 0064 XlsxMacroDocument 0065 }; 0066 0067 class XlsxImport::Private 0068 { 0069 public: 0070 Private() : type(XlsxDocument), macrosEnabled(false) { 0071 } 0072 0073 const char* mainDocumentContentType() const 0074 { 0075 if (type == XlsxMacroDocument) 0076 return MSOOXML::ContentTypes::spreadsheetMacroDocument; 0077 if (type == XlsxTemplate) 0078 return MSOOXML::ContentTypes::spreadsheetTemplate; 0079 return MSOOXML::ContentTypes::spreadsheetDocument; 0080 } 0081 0082 XlsxDocumentType type; 0083 bool macrosEnabled; 0084 }; 0085 0086 XlsxImport::XlsxImport(QObject* parent, const QVariantList &) 0087 : MSOOXML::MsooXmlImport(QLatin1String("spreadsheet"), parent), d(new Private) 0088 { 0089 } 0090 0091 XlsxImport::~XlsxImport() 0092 { 0093 delete d; 0094 } 0095 0096 bool XlsxImport::acceptsSourceMimeType(const QByteArray& mime) const 0097 { 0098 qCDebug(lcXlsxImport) << "Entering XLSX Import filter: from " << mime; 0099 if (mime == "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet") { 0100 d->type = XlsxDocument; 0101 d->macrosEnabled = false; 0102 } 0103 else if (mime == "application/vnd.openxmlformats-officedocument.spreadsheetml.template") { 0104 d->type = XlsxTemplate; 0105 d->macrosEnabled = false; 0106 } 0107 else if (mime == "application/vnd.ms-excel.sheet.macroEnabled") { 0108 d->type = XlsxMacroDocument; 0109 d->macrosEnabled = true; 0110 } 0111 else if (mime == "application/vnd.ms-excel.sheet.macroEnabled.12") { 0112 d->type = XlsxDocument; 0113 d->macrosEnabled = true; 0114 } 0115 else if (mime == "application/vnd.ms-excel.template.macroEnabled.12") { 0116 d->type = XlsxTemplate; 0117 d->macrosEnabled = true; 0118 } 0119 else { 0120 return false; 0121 } 0122 return true; 0123 } 0124 0125 bool XlsxImport::acceptsDestinationMimeType(const QByteArray& mime) const 0126 { 0127 qCDebug(lcXlsxImport) << "Entering XLSX Import filter: to " << mime; 0128 return mime == "application/vnd.oasis.opendocument.spreadsheet"; 0129 } 0130 0131 KoFilter::ConversionStatus XlsxImport::parseParts(KoOdfWriters *writers, 0132 MSOOXML::MsooXmlRelationships *relationships, QString& errorMessage) 0133 { 0134 // more here... 0135 // 0. temporary styles 0136 //! @todo create styles in XlsxXmlDocumentReader (XLSX defines styles in workbook.xml) 0137 0138 writers->mainStyles->insertRawOdfStyles( 0139 KoGenStyles::DocumentStyles, 0140 " <!-- COPIED -->" 0141 "\n <style:default-style style:family=\"table-cell\">" 0142 "\n <style:table-cell-properties />" 0143 "\n <style:paragraph-properties style:tab-stop-distance=\"1.27cm\"/>" 0144 "\n <style:text-properties style:font-name=\"Albany AMT\" fo:language=\"en\" fo:country=\"US\" style:font-name-asian=\"Arial\" style:language-asian=\"zxx\" style:country-asian=\"none\" style:font-name-complex=\"Tahoma\" style:language-complex=\"zxx\" style:country-complex=\"none\"/>" 0145 "\n </style:default-style>" 0146 "\n <number:number-style style:name=\"N0\">" 0147 "\n <number:number number:min-integer-digits=\"1\"/>" 0148 "\n </number:number-style>" 0149 "\n <number:currency-style style:name=\"N104P0\" style:volatile=\"true\">" 0150 "\n <number:currency-symbol number:language=\"en\" number:country=\"US\">$</number:currency-symbol>" 0151 "\n <number:number number:decimal-places=\"2\" number:min-integer-digits=\"1\" number:grouping=\"true\"/>" 0152 "\n </number:currency-style>" 0153 "\n <number:currency-style style:name=\"N104\">" 0154 "\n <style:text-properties fo:color=\"#ff0000\"/>" 0155 "\n <number:text>-</number:text>" 0156 "\n <number:currency-symbol number:language=\"en\" number:country=\"US\">$</number:currency-symbol>" 0157 "\n <number:number number:decimal-places=\"2\" number:min-integer-digits=\"1\" number:grouping=\"true\"/>" 0158 "\n <style:map style:condition=\"value()>=0\" style:apply-style-name=\"N104P0\"/>" 0159 "\n </number:currency-style>" 0160 "\n <number:number-style style:name=\"N5000\" number:language=\"en\" number:country=\"US\">" 0161 "\n <number:number number:min-integer-digits=\"1\"/>" 0162 "\n </number:number-style>" 0163 "\n <number:currency-style style:name=\"N5116P0\" style:volatile=\"true\" number:language=\"en\" number:country=\"US\">" 0164 "\n <number:currency-symbol/>" 0165 "\n <number:number number:decimal-places=\"0\" number:min-integer-digits=\"1\" number:grouping=\"true\"/>" 0166 "\n <number:text> </number:text>" 0167 "\n </number:currency-style>" 0168 "\n <number:currency-style style:name=\"N5116\" number:language=\"en\" number:country=\"US\">" 0169 "\n <number:text>(</number:text>" 0170 "\n <number:currency-symbol/>" 0171 "\n <number:number number:decimal-places=\"0\" number:min-integer-digits=\"1\" number:grouping=\"true\"/>" 0172 "\n <number:text>)</number:text>" 0173 "\n <style:map style:condition=\"value()>=0\" style:apply-style-name=\"N5116P0\"/>" 0174 "\n </number:currency-style>" 0175 "\n <number:currency-style style:name=\"N5117P0\" style:volatile=\"true\" number:language=\"en\" number:country=\"US\">" 0176 "\n <number:currency-symbol/>" 0177 "\n <number:number number:decimal-places=\"0\" number:min-integer-digits=\"1\" number:grouping=\"true\"/>" 0178 "\n <number:text> </number:text>" 0179 "\n </number:currency-style>" 0180 "\n <number:currency-style style:name=\"N5117\" number:language=\"en\" number:country=\"US\">" 0181 "\n <style:text-properties fo:color=\"#ff0000\"/>" 0182 "\n <number:text>(</number:text>" 0183 "\n <number:currency-symbol/>" 0184 "\n <number:number number:decimal-places=\"0\" number:min-integer-digits=\"1\" number:grouping=\"true\"/>" 0185 "\n <number:text>)</number:text>" 0186 "\n <style:map style:condition=\"value()>=0\" style:apply-style-name=\"N5117P0\"/>" 0187 "\n </number:currency-style>" 0188 "\n <number:currency-style style:name=\"N5118P0\" style:volatile=\"true\" number:language=\"en\" number:country=\"US\">" 0189 "\n <number:currency-symbol/>" 0190 "\n <number:number number:decimal-places=\"2\" number:min-integer-digits=\"1\" number:grouping=\"true\"/>" 0191 "\n <number:text> </number:text>" 0192 "\n </number:currency-style>" 0193 "\n <number:currency-style style:name=\"N5118\" number:language=\"en\" number:country=\"US\">" 0194 "\n <number:text>(</number:text>" 0195 "\n <number:currency-symbol/>" 0196 "\n <number:number number:decimal-places=\"2\" number:min-integer-digits=\"1\" number:grouping=\"true\"/>" 0197 "\n <number:text>)</number:text>" 0198 "\n <style:map style:condition=\"value()>=0\" style:apply-style-name=\"N5118P0\"/>" 0199 "\n </number:currency-style>" 0200 "\n <number:currency-style style:name=\"N5119P0\" style:volatile=\"true\" number:language=\"en\" number:country=\"US\">" 0201 "\n <number:currency-symbol/>" 0202 "\n <number:number number:decimal-places=\"2\" number:min-integer-digits=\"1\" number:grouping=\"true\"/>" 0203 "\n <number:text> </number:text>" 0204 "\n </number:currency-style>" 0205 "\n <number:currency-style style:name=\"N5119\" number:language=\"en\" number:country=\"US\">" 0206 "\n <style:text-properties fo:color=\"#ff0000\"/>" 0207 "\n <number:text>(</number:text>" 0208 "\n <number:currency-symbol/>" 0209 "\n <number:number number:decimal-places=\"2\" number:min-integer-digits=\"1\" number:grouping=\"true\"/>" 0210 "\n <number:text>)</number:text>" 0211 "\n <style:map style:condition=\"value()>=0\" style:apply-style-name=\"N5119P0\"/>" 0212 "\n </number:currency-style>" 0213 "\n <number:date-style style:name=\"N5120\" number:language=\"en\" number:country=\"US\">" 0214 "\n <number:month/>" 0215 "\n <number:text>/</number:text>" 0216 "\n <number:day/>" 0217 "\n <number:text>/</number:text>" 0218 "\n <number:year number:style=\"long\"/>" 0219 "\n </number:date-style>" 0220 "\n <number:date-style style:name=\"N5121\" number:language=\"en\" number:country=\"US\">" 0221 "\n <number:day/>" 0222 "\n <number:text>-</number:text>" 0223 "\n <number:month number:textual=\"true\"/>" 0224 "\n <number:text>-</number:text>" 0225 "\n <number:year/>" 0226 "\n </number:date-style>" 0227 "\n <number:date-style style:name=\"N5122\" number:language=\"en\" number:country=\"US\">" 0228 "\n <number:day/>" 0229 "\n <number:text>-</number:text>" 0230 "\n <number:month number:textual=\"true\"/>" 0231 "\n </number:date-style>" 0232 "\n <number:date-style style:name=\"N5123\" number:language=\"en\" number:country=\"US\">" 0233 "\n <number:month number:textual=\"true\"/>" 0234 "\n <number:text>-</number:text>" 0235 "\n <number:year/>" 0236 "\n </number:date-style>" 0237 "\n <number:time-style style:name=\"N5124\" number:language=\"en\" number:country=\"US\">" 0238 "\n <number:hours/>" 0239 "\n <number:text>:</number:text>" 0240 "\n <number:minutes number:style=\"long\"/>" 0241 "\n <number:text> </number:text>" 0242 "\n <number:am-pm/>" 0243 "\n </number:time-style>" 0244 "\n <number:time-style style:name=\"N5125\" number:language=\"en\" number:country=\"US\">" 0245 "\n <number:hours/>" 0246 "\n <number:text>:</number:text>" 0247 "\n <number:minutes number:style=\"long\"/>" 0248 "\n <number:text>:</number:text>" 0249 "\n <number:seconds number:style=\"long\"/>" 0250 "\n <number:text> </number:text>" 0251 "\n <number:am-pm/>" 0252 "\n </number:time-style>" 0253 "\n <number:time-style style:name=\"N5126\" number:language=\"en\" number:country=\"US\">" 0254 "\n <number:hours/>" 0255 "\n <number:text>:</number:text>" 0256 "\n <number:minutes number:style=\"long\"/>" 0257 "\n </number:time-style>" 0258 "\n <number:time-style style:name=\"N5127\" number:language=\"en\" number:country=\"US\">" 0259 "\n <number:hours/>" 0260 "\n <number:text>:</number:text>" 0261 "\n <number:minutes number:style=\"long\"/>" 0262 "\n <number:text>:</number:text>" 0263 "\n <number:seconds number:style=\"long\"/>" 0264 "\n </number:time-style>" 0265 "\n <number:date-style style:name=\"N5128\" number:language=\"en\" number:country=\"US\">" 0266 "\n <number:month/>" 0267 "\n <number:text>/</number:text>" 0268 "\n <number:day/>" 0269 "\n <number:text>/</number:text>" 0270 "\n <number:year number:style=\"long\"/>" 0271 "\n <number:text> </number:text>" 0272 "\n <number:hours/>" 0273 "\n <number:text>:</number:text>" 0274 "\n <number:minutes number:style=\"long\"/>" 0275 "\n </number:date-style>" 0276 "\n <number:number-style style:name=\"N5129P0\" style:volatile=\"true\" number:language=\"en\" number:country=\"US\">" 0277 "\n <number:number number:decimal-places=\"0\" number:min-integer-digits=\"1\" number:grouping=\"true\"/>" 0278 "\n <number:text> </number:text>" 0279 "\n </number:number-style>" 0280 "\n <number:number-style style:name=\"N5129\" number:language=\"en\" number:country=\"US\">" 0281 "\n <number:text>(</number:text>" 0282 "\n <number:number number:decimal-places=\"0\" number:min-integer-digits=\"1\" number:grouping=\"true\"/>" 0283 "\n <number:text>)</number:text>" 0284 "\n <style:map style:condition=\"value()>=0\" style:apply-style-name=\"N5129P0\"/>" 0285 "\n </number:number-style>" 0286 "\n <number:number-style style:name=\"N5130P0\" style:volatile=\"true\" number:language=\"en\" number:country=\"US\">" 0287 "\n <number:number number:decimal-places=\"0\" number:min-integer-digits=\"1\" number:grouping=\"true\"/>" 0288 "\n <number:text> </number:text>" 0289 "\n </number:number-style>" 0290 "\n <number:number-style style:name=\"N5130\" number:language=\"en\" number:country=\"US\">" 0291 "\n <style:text-properties fo:color=\"#ff0000\"/>" 0292 "\n <number:text>(</number:text>" 0293 "\n <number:number number:decimal-places=\"0\" number:min-integer-digits=\"1\" number:grouping=\"true\"/>" 0294 "\n <number:text>)</number:text>" 0295 "\n <style:map style:condition=\"value()>=0\" style:apply-style-name=\"N5130P0\"/>" 0296 "\n </number:number-style>" 0297 "\n <number:number-style style:name=\"N5131P0\" style:volatile=\"true\" number:language=\"en\" number:country=\"US\">" 0298 "\n <number:number number:decimal-places=\"2\" number:min-integer-digits=\"1\" number:grouping=\"true\"/>" 0299 "\n <number:text> </number:text>" 0300 "\n </number:number-style>" 0301 "\n <number:number-style style:name=\"N5131\" number:language=\"en\" number:country=\"US\">" 0302 "\n <number:text>(</number:text>" 0303 "\n <number:number number:decimal-places=\"2\" number:min-integer-digits=\"1\" number:grouping=\"true\"/>" 0304 "\n <number:text>)</number:text>" 0305 "\n <style:map style:condition=\"value()>=0\" style:apply-style-name=\"N5131P0\"/>" 0306 "\n </number:number-style>" 0307 "\n <number:number-style style:name=\"N5132P0\" style:volatile=\"true\" number:language=\"en\" number:country=\"US\">" 0308 "\n <number:number number:decimal-places=\"2\" number:min-integer-digits=\"1\" number:grouping=\"true\"/>" 0309 "\n <number:text> </number:text>" 0310 "\n </number:number-style>" 0311 "\n <number:number-style style:name=\"N5132\" number:language=\"en\" number:country=\"US\">" 0312 "\n <style:text-properties fo:color=\"#ff0000\"/>" 0313 "\n <number:text>(</number:text>" 0314 "\n <number:number number:decimal-places=\"2\" number:min-integer-digits=\"1\" number:grouping=\"true\"/>" 0315 "\n <number:text>)</number:text>" 0316 "\n <style:map style:condition=\"value()>=0\" style:apply-style-name=\"N5132P0\"/>" 0317 "\n </number:number-style>" 0318 "\n <number:number-style style:name=\"N5133P0\" style:volatile=\"true\" number:language=\"en\" number:country=\"US\">" 0319 "\n <number:text> </number:text>" 0320 "\n <number:number number:decimal-places=\"0\" number:min-integer-digits=\"1\" number:grouping=\"true\"/>" 0321 "\n <number:text> </number:text>" 0322 "\n </number:number-style>" 0323 "\n <number:number-style style:name=\"N5133P1\" style:volatile=\"true\" number:language=\"en\" number:country=\"US\">" 0324 "\n <number:text> (</number:text>" 0325 "\n <number:number number:decimal-places=\"0\" number:min-integer-digits=\"1\" number:grouping=\"true\"/>" 0326 "\n <number:text>)</number:text>" 0327 "\n </number:number-style>" 0328 "\n <number:number-style style:name=\"N5133P2\" style:volatile=\"true\" number:language=\"en\" number:country=\"US\">" 0329 "\n <number:text> - </number:text>" 0330 "\n </number:number-style>" 0331 "\n <number:text-style style:name=\"N5133\" number:language=\"en\" number:country=\"US\">" 0332 "\n <number:text> </number:text>" 0333 "\n <number:text-content/>" 0334 "\n <number:text> </number:text>" 0335 "\n <style:map style:condition=\"value()>0\" style:apply-style-name=\"N5133P0\"/>" 0336 "\n <style:map style:condition=\"value()<0\" style:apply-style-name=\"N5133P1\"/>" 0337 "\n <style:map style:condition=\"value()=0\" style:apply-style-name=\"N5133P2\"/>" 0338 "\n </number:text-style>" 0339 "\n <number:currency-style style:name=\"N5134P0\" style:volatile=\"true\" number:language=\"en\" number:country=\"US\">" 0340 "\n <number:text> </number:text>" 0341 "\n <number:currency-symbol/>" 0342 "\n <number:number number:decimal-places=\"0\" number:min-integer-digits=\"1\" number:grouping=\"true\"/>" 0343 "\n <number:text> </number:text>" 0344 "\n </number:currency-style>" 0345 "\n <number:currency-style style:name=\"N5134P1\" style:volatile=\"true\" number:language=\"en\" number:country=\"US\">" 0346 "\n <number:text> </number:text>" 0347 "\n <number:currency-symbol/>" 0348 "\n <number:text>(</number:text>" 0349 "\n <number:number number:decimal-places=\"0\" number:min-integer-digits=\"1\" number:grouping=\"true\"/>" 0350 "\n <number:text>)</number:text>" 0351 "\n </number:currency-style>" 0352 "\n <number:currency-style style:name=\"N5134P2\" style:volatile=\"true\" number:language=\"en\" number:country=\"US\">" 0353 "\n <number:text> </number:text>" 0354 "\n <number:currency-symbol/>" 0355 "\n <number:text>- </number:text>" 0356 "\n </number:currency-style>" 0357 "\n <number:text-style style:name=\"N5134\" number:language=\"en\" number:country=\"US\">" 0358 "\n <number:text> </number:text>" 0359 "\n <number:text-content/>" 0360 "\n <number:text> </number:text>" 0361 "\n <style:map style:condition=\"value()>0\" style:apply-style-name=\"N5134P0\"/>" 0362 "\n <style:map style:condition=\"value()<0\" style:apply-style-name=\"N5134P1\"/>" 0363 "\n <style:map style:condition=\"value()=0\" style:apply-style-name=\"N5134P2\"/>" 0364 "\n </number:text-style>" 0365 "\n <number:number-style style:name=\"N5135P0\" style:volatile=\"true\" number:language=\"en\" number:country=\"US\">" 0366 "\n <number:text> </number:text>" 0367 "\n <number:number number:decimal-places=\"2\" number:min-integer-digits=\"1\" number:grouping=\"true\"/>" 0368 "\n <number:text> </number:text>" 0369 "\n </number:number-style>" 0370 "\n <number:number-style style:name=\"N5135P1\" style:volatile=\"true\" number:language=\"en\" number:country=\"US\">" 0371 "\n <number:text> (</number:text>" 0372 "\n <number:number number:decimal-places=\"2\" number:min-integer-digits=\"1\" number:grouping=\"true\"/>" 0373 "\n <number:text>)</number:text>" 0374 "\n </number:number-style>" 0375 "\n <number:number-style style:name=\"N5135P2\" style:volatile=\"true\" number:language=\"en\" number:country=\"US\">" 0376 "\n <number:text> -</number:text>" 0377 "\n <number:number number:decimal-places=\"0\" number:min-integer-digits=\"0\"/>" 0378 "\n <number:text> </number:text>" 0379 "\n </number:number-style>" 0380 "\n <number:text-style style:name=\"N5135\" number:language=\"en\" number:country=\"US\">" 0381 "\n <number:text> </number:text>" 0382 "\n <number:text-content/>" 0383 "\n <number:text> </number:text>" 0384 "\n <style:map style:condition=\"value()>0\" style:apply-style-name=\"N5135P0\"/>" 0385 "\n <style:map style:condition=\"value()<0\" style:apply-style-name=\"N5135P1\"/>" 0386 "\n <style:map style:condition=\"value()=0\" style:apply-style-name=\"N5135P2\"/>" 0387 "\n </number:text-style>" 0388 "\n <number:currency-style style:name=\"N5136P0\" style:volatile=\"true\" number:language=\"en\" number:country=\"US\">" 0389 "\n <number:text> </number:text>" 0390 "\n <number:currency-symbol/>" 0391 "\n <number:number number:decimal-places=\"2\" number:min-integer-digits=\"1\" number:grouping=\"true\"/>" 0392 "\n <number:text> </number:text>" 0393 "\n </number:currency-style>" 0394 "\n <number:currency-style style:name=\"N5136P1\" style:volatile=\"true\" number:language=\"en\" number:country=\"US\">" 0395 "\n <number:text> </number:text>" 0396 "\n <number:currency-symbol/>" 0397 "\n <number:text>(</number:text>" 0398 "\n <number:number number:decimal-places=\"2\" number:min-integer-digits=\"1\" number:grouping=\"true\"/>" 0399 "\n <number:text>)</number:text>" 0400 "\n </number:currency-style>" 0401 "\n <number:currency-style style:name=\"N5136P2\" style:volatile=\"true\" number:language=\"en\" number:country=\"US\">" 0402 "\n <number:text> </number:text>" 0403 "\n <number:currency-symbol/>" 0404 "\n <number:text>-</number:text>" 0405 "\n <number:number number:decimal-places=\"0\" number:min-integer-digits=\"0\"/>" 0406 "\n <number:text> </number:text>" 0407 "\n </number:currency-style>" 0408 "\n <number:text-style style:name=\"N5136\" number:language=\"en\" number:country=\"US\">" 0409 "\n <number:text> </number:text>" 0410 "\n <number:text-content/>" 0411 "\n <number:text> </number:text>" 0412 "\n <style:map style:condition=\"value()>0\" style:apply-style-name=\"N5136P0\"/>" 0413 "\n <style:map style:condition=\"value()<0\" style:apply-style-name=\"N5136P1\"/>" 0414 "\n <style:map style:condition=\"value()=0\" style:apply-style-name=\"N5136P2\"/>" 0415 "\n </number:text-style>" 0416 "\n <number:time-style style:name=\"N5137\" number:language=\"en\" number:country=\"US\">" 0417 "\n <number:minutes number:style=\"long\"/>" 0418 "\n <number:text>:</number:text>" 0419 "\n <number:seconds number:style=\"long\"/>" 0420 "\n </number:time-style>" 0421 "\n <number:time-style style:name=\"N5138\" number:language=\"en\" number:country=\"US\" number:truncate-on-overflow=\"false\">" 0422 "\n <number:hours/>" 0423 "\n <number:text>:</number:text>" 0424 "\n <number:minutes number:style=\"long\"/>" 0425 "\n <number:text>:</number:text>" 0426 "\n <number:seconds number:style=\"long\"/>" 0427 "\n </number:time-style>" 0428 "\n <number:time-style style:name=\"N5139\" number:language=\"en\" number:country=\"US\">" 0429 "\n <number:minutes number:style=\"long\"/>" 0430 "\n <number:text>:</number:text>" 0431 "\n <number:seconds number:style=\"long\" number:decimal-places=\"1\"/>" 0432 "\n </number:time-style>" 0433 "\n <number:number-style style:name=\"N5140\" number:language=\"en\" number:country=\"US\">" 0434 "\n <number:scientific-number number:decimal-places=\"1\" number:min-integer-digits=\"3\" number:min-exponent-digits=\"1\"/>" 0435 "\n </number:number-style>" 0436 "\n <style:style style:name=\"Default\" style:family=\"table-cell\"/>" 0437 "\n <style:style style:name=\"Result\" style:family=\"table-cell\" style:parent-style-name=\"Default\">" 0438 "\n <style:text-properties fo:font-style=\"italic\" style:text-underline-style=\"solid\" style:text-underline-width=\"auto\" style:text-underline-color=\"font-color\" fo:font-weight=\"bold\"/>" 0439 "\n </style:style>" 0440 "\n <style:style style:name=\"Result2\" style:family=\"table-cell\" style:parent-style-name=\"Result\" style:data-style-name=\"N104\"/>" 0441 "\n <style:style style:name=\"Heading\" style:family=\"table-cell\" style:parent-style-name=\"Default\">" 0442 "\n <style:table-cell-properties style:text-align-source=\"fix\" style:repeat-content=\"false\"/>" 0443 "\n <style:paragraph-properties fo:text-align=\"center\"/>" 0444 "\n <style:text-properties fo:font-size=\"16pt\" fo:font-style=\"italic\" fo:font-weight=\"bold\"/>" 0445 "\n </style:style>" 0446 "\n <style:style style:name=\"Heading1\" style:family=\"table-cell\" style:parent-style-name=\"Heading\">" 0447 "\n <style:table-cell-properties style:rotation-angle=\"90\"/>" 0448 "\n </style:style>" 0449 "\n <style:style style:name=\"Excel_20_Built-in_20_Normal\" style:display-name=\"Excel Built-in Normal\" style:family=\"table-cell\" style:parent-style-name=\"Default\" style:data-style-name=\"N5000\">" 0450 "\n <style:table-cell-properties style:cell-protect=\"protected\" style:print-content=\"true\" style:diagonal-bl-tr=\"none\" style:diagonal-tl-br=\"none\" style:text-align-source=\"value-type\" style:repeat-content=\"false\" fo:background-color=\"transparent\" fo:wrap-option=\"no-wrap\" fo:border=\"none\" style:direction=\"ltr\" style:rotation-angle=\"0\" style:rotation-align=\"none\" style:shrink-to-fit=\"false\" style:vertical-align=\"bottom\"/>" 0451 "\n <style:paragraph-properties fo:margin-left=\"0cm\" style:writing-mode=\"page\"/>" 0452 "\n <style:text-properties fo:color=\"#000000\" style:text-outline=\"false\" style:text-line-through-style=\"none\" style:font-name=\"Calibri\" fo:font-size=\"11pt\" fo:font-style=\"normal\" fo:text-shadow=\"none\" style:text-underline-style=\"none\" fo:font-weight=\"normal\" style:font-size-asian=\"11pt\" style:font-style-asian=\"normal\" style:font-weight-asian=\"normal\" style:font-size-complex=\"11pt\" style:font-style-complex=\"normal\" style:font-weight-complex=\"normal\"/>" 0453 "\n </style:style>" 0454 "\n <!-- /COPIED -->" 0455 ); 0456 0457 writers->mainStyles->insertRawOdfStyles( 0458 KoGenStyles::MasterStyles, 0459 " <!-- COPIED -->" 0460 "\n <style:master-page style:name=\"Default\" style:page-layout-name=\"pm1\">" 0461 "\n <style:header>" 0462 "\n <text:p>" 0463 "\n <text:sheet-name>" "???" "</text:sheet-name>" 0464 "\n </text:p>" 0465 "\n </style:header>" 0466 "\n <style:header-left style:display=\"false\"/>" 0467 "\n <style:footer>" 0468 "\n <text:p>Page <text:page-number>1</text:page-number></text:p>" 0469 "\n </style:footer>" 0470 "\n <style:footer-left style:display=\"false\"/>" 0471 "\n </style:master-page>" 0472 "\n <style:master-page style:name=\"Report\" style:page-layout-name=\"pm2\">" 0473 "\n <style:header>" 0474 "\n <style:region-left>" 0475 "\n <text:p><text:sheet-name>" "???" "</text:sheet-name> (<text:title>" "???" "</text:title>)</text:p>" 0476 "\n </style:region-left>" 0477 "\n <style:region-right>" 0478 "\n <text:p><text:date style:data-style-name=\"N2\" text:date-value=\"2009-07-18\">07/18/2009</text:date>, <text:time>21:48:12</text:time></text:p>" 0479 "\n </style:region-right>" 0480 "\n </style:header>" 0481 "\n <style:header-left style:display=\"false\"/>" 0482 "\n <style:footer>" 0483 "\n <text:p>Page <text:page-number>1</text:page-number> / <text:page-count>99</text:page-count></text:p>" 0484 "\n </style:footer>" 0485 "\n <style:footer-left style:display=\"false\"/>" 0486 "\n </style:master-page>" 0487 "\n <style:master-page style:name=\"PageStyle_5f_Test_20_sheet_20__5f_1\" style:display-name=\"PageStyle_Test sheet _1\" style:page-layout-name=\"pm3\">" 0488 "\n <style:header style:display=\"false\"/>" 0489 "\n <style:header-left style:display=\"false\"/>" 0490 "\n <style:footer style:display=\"false\"/>" 0491 "\n <style:footer-left style:display=\"false\"/>" 0492 "\n </style:master-page>" 0493 "\n <style:master-page style:name=\"PageStyle_5f_Test_20_sheet_20__5f_2\" style:display-name=\"PageStyle_Test sheet _2\" style:page-layout-name=\"pm4\">" 0494 "\n <style:header style:display=\"false\"/>" 0495 "\n <style:header-left style:display=\"false\"/>" 0496 "\n <style:footer style:display=\"false\"/>" 0497 "\n <style:footer-left style:display=\"false\"/>" 0498 "\n </style:master-page>" 0499 "\n <!-- COPIED -->" 0500 ); 0501 0502 writers->mainStyles->insertRawOdfStyles( 0503 KoGenStyles::StylesXmlAutomaticStyles, 0504 " <!-- COPIED -->" 0505 "\n <style:page-layout style:name=\"pm1\">" 0506 "\n <style:page-layout-properties style:first-page-number=\"continue\" style:writing-mode=\"lr-tb\"/>" 0507 "\n <style:header-style>" 0508 "\n <style:header-footer-properties fo:min-height=\"0.751cm\" fo:margin-left=\"0cm\" fo:margin-right=\"0cm\" fo:margin-bottom=\"0.25cm\"/>" 0509 "\n </style:header-style>" 0510 "\n <style:footer-style>" 0511 "\n <style:header-footer-properties fo:min-height=\"0.751cm\" fo:margin-left=\"0cm\" fo:margin-right=\"0cm\" fo:margin-top=\"0.25cm\"/>" 0512 "\n </style:footer-style>" 0513 "\n </style:page-layout>" 0514 "\n <style:page-layout style:name=\"pm2\">" 0515 "\n <style:page-layout-properties style:writing-mode=\"lr-tb\"/>" 0516 "\n <style:header-style>" 0517 "\n <style:header-footer-properties fo:min-height=\"0.751cm\" fo:margin-left=\"0cm\" fo:margin-right=\"0cm\" fo:margin-bottom=\"0.25cm\" fo:border=\"0.088cm solid #000000\" fo:padding=\"0.018cm\" fo:background-color=\"#c0c0c0\">" 0518 "\n <style:background-image/>" 0519 "\n </style:header-footer-properties>" 0520 "\n </style:header-style>" 0521 "\n <style:footer-style>" 0522 "\n <style:header-footer-properties fo:min-height=\"0.751cm\" fo:margin-left=\"0cm\" fo:margin-right=\"0cm\" fo:margin-top=\"0.25cm\" fo:border=\"0.088cm solid #000000\" fo:padding=\"0.018cm\" fo:background-color=\"#c0c0c0\">" 0523 "\n <style:background-image/>" 0524 "\n </style:header-footer-properties>" 0525 "\n </style:footer-style>" 0526 "\n </style:page-layout>" 0527 "\n <style:page-layout style:name=\"pm3\">" 0528 "\n <style:page-layout-properties fo:page-width=\"21.001cm\" fo:page-height=\"29.7cm\" style:num-format=\"1\" style:print-orientation=\"portrait\" fo:margin-top=\"1.905cm\" fo:margin-bottom=\"1.905cm\" fo:margin-left=\"1.778cm\" fo:margin-right=\"1.778cm\" style:print-page-order=\"ttb\" style:first-page-number=\"continue\" style:scale-to=\"100%\" style:writing-mode=\"lr-tb\" style:print=\"charts drawings objects zero-values\"/>" 0529 "\n <style:header-style>" 0530 "\n <style:header-footer-properties fo:min-height=\"0.75cm\" fo:margin-left=\"0cm\" fo:margin-right=\"0cm\" fo:margin-bottom=\"0.25cm\"/>" 0531 "\n </style:header-style>" 0532 "\n <style:footer-style>" 0533 "\n <style:header-footer-properties fo:min-height=\"0.75cm\" fo:margin-left=\"0cm\" fo:margin-right=\"0cm\" fo:margin-top=\"0.25cm\"/>" 0534 "\n </style:footer-style>" 0535 "\n </style:page-layout>" 0536 "\n <style:page-layout style:name=\"pm4\">" 0537 "\n <style:page-layout-properties fo:page-width=\"21.59cm\" fo:page-height=\"27.94cm\" style:num-format=\"1\" style:print-orientation=\"portrait\" fo:margin-top=\"1.905cm\" fo:margin-bottom=\"1.905cm\" fo:margin-left=\"1.778cm\" fo:margin-right=\"1.778cm\" style:print-page-order=\"ttb\" style:first-page-number=\"continue\" style:scale-to=\"100%\" style:writing-mode=\"lr-tb\" style:print=\"charts drawings objects zero-values\"/>" 0538 "\n <style:header-style>" 0539 "\n <style:header-footer-properties fo:min-height=\"0.75cm\" fo:margin-left=\"0cm\" fo:margin-right=\"0cm\" fo:margin-bottom=\"0.25cm\"/>" 0540 "\n </style:header-style>" 0541 "\n <style:footer-style>" 0542 "\n <style:header-footer-properties fo:min-height=\"0.75cm\" fo:margin-left=\"0cm\" fo:margin-right=\"0cm\" fo:margin-top=\"0.25cm\"/>" 0543 "\n </style:footer-style>" 0544 "\n </style:page-layout>" 0545 "\n <!-- /COPIED -->" 0546 ); 0547 0548 // Todo, find out whether these are defaults for xlsx or whether they can be read somewhere 0549 writers->body->startElement("table:calculation-settings"); 0550 writers->body->addAttribute("table:case-sensitive", "false"); 0551 writers->body->addAttribute("table:automatic-find-labels", "false"); 0552 writers->body->addAttribute("table:use-regular-expressions", "false"); 0553 writers->body->addAttribute("table:use-wildcards", "true"); 0554 writers->body->endElement(); // table:calculation-settings 0555 0556 // 1. parse themes 0557 QList<QByteArray> partNames = this->partNames(d->mainDocumentContentType()); 0558 0559 // following is a workaround till the patch at https://bugs.freedesktop.org/show_bug.cgi?id=30417 is applied 0560 // so we are able to proper handle this case already before using the mimetype. 0561 if (partNames.isEmpty() && d->type != XlsxMacroDocument) { 0562 QList<QByteArray> macroPartNames = this->partNames(MSOOXML::ContentTypes::spreadsheetMacroDocument); 0563 if (macroPartNames.count() == 1 && acceptsSourceMimeType("application/vnd.ms-excel.sheet.macroEnabled")) { 0564 partNames = macroPartNames; 0565 } 0566 } 0567 0568 if (partNames.count() != 1) { 0569 errorMessage = i18n("Unable to find part for type %1", d->mainDocumentContentType()); 0570 return KoFilter::WrongFormat; 0571 } 0572 const QString spreadPathAndFile(partNames.first()); 0573 QString spreadPath, spreadFile; 0574 MSOOXML::Utils::splitPathAndFile(spreadPathAndFile, &spreadPath, &spreadFile); 0575 0576 MSOOXML::DrawingMLTheme themes; 0577 const QString spreadThemePathAndFile(relationships->targetForType( 0578 spreadPath, spreadFile, 0579 QLatin1String(MSOOXML::Schemas::officeDocument::relationships) + "/theme")); 0580 qCDebug(lcXlsxImport) << QLatin1String(MSOOXML::Schemas::officeDocument::relationships) + "/theme"; 0581 0582 QString spreadThemePath, spreadThemeFile; 0583 MSOOXML::Utils::splitPathAndFile(spreadThemePathAndFile, &spreadThemePath, &spreadThemeFile); 0584 0585 MSOOXML::MsooXmlThemesReader themesReader(writers); 0586 MSOOXML::MsooXmlThemesReaderContext themecontext(themes, relationships, (MSOOXML::MsooXmlImport*)this, 0587 spreadThemePath, spreadThemeFile); 0588 0589 KoFilter::ConversionStatus status 0590 = loadAndParseDocument(&themesReader, spreadThemePathAndFile, errorMessage, &themecontext); 0591 Q_UNUSED(status); 0592 reportProgress(5); 0593 0594 // 2. parse styles 0595 XlsxStyles styles; 0596 XlsxXmlStylesReaderContext colorContext(styles, true, this, &themes); 0597 { 0598 // In first round we read color overrides, in 2nd round we can actually use them. 0599 XlsxXmlStylesReader stylesReader(writers); 0600 RETURN_IF_ERROR(loadAndParseDocumentIfExists( 0601 MSOOXML::ContentTypes::spreadsheetStyles, &stylesReader, writers, errorMessage, &colorContext)) 0602 reportProgress(15); 0603 XlsxXmlStylesReaderContext context2(styles, false, this, &themes); 0604 context2.colorIndices = colorContext.colorIndices; // Overriding default colors potentially 0605 RETURN_IF_ERROR(loadAndParseDocumentIfExists( 0606 MSOOXML::ContentTypes::spreadsheetStyles, &stylesReader, writers, errorMessage, &context2)) 0607 } 0608 0609 reportProgress(30); 0610 0611 // 3. parse shared strings 0612 QVector<QString> sharedStrings; 0613 { 0614 XlsxXmlSharedStringsReader sharedStringsReader(writers); 0615 XlsxXmlSharedStringsReaderContext context(sharedStrings, &themes, colorContext.colorIndices); 0616 RETURN_IF_ERROR(loadAndParseDocumentIfExists( 0617 MSOOXML::ContentTypes::spreadsheetSharedStrings, &sharedStringsReader, writers, errorMessage, &context)) 0618 } 0619 0620 reportProgress(35); 0621 0622 // 4. parse comments 0623 XlsxComments comments; 0624 { 0625 XlsxXmlCommentsReader commentsReader(writers); 0626 XlsxXmlCommentsReaderContext context(comments, &themes, colorContext.colorIndices); 0627 RETURN_IF_ERROR( loadAndParseDocumentFromFileIfExists( 0628 //! @todo only support "xl/comments1.xml" filename for comments? 0629 "xl/comments1.xml", &commentsReader, writers, errorMessage, &context) ) 0630 } 0631 0632 reportProgress(40); 0633 0634 // 5. parse document 0635 { 0636 XlsxXmlDocumentReaderContext context(*this, &themes, sharedStrings, comments, styles, *relationships, "workbook.xml", "xl"); 0637 XlsxXmlDocumentReader documentReader(writers); 0638 RETURN_IF_ERROR(loadAndParseDocument(d->mainDocumentContentType(), &documentReader, writers, errorMessage, &context)) 0639 } 0640 0641 reportProgress(100); 0642 0643 // more here... 0644 return KoFilter::OK; 0645 } 0646 0647 #include "XlsxImport.moc"