From 6fc611fdfc70199dafc7de2a8d28fa18cd48ac13 Mon Sep 17 00:00:00 2001 From: ElenaSubbotina Date: Tue, 4 Jul 2017 18:50:39 +0300 Subject: [PATCH] XlsFormat - convert pivot tables --- .../XlsFormat/Logic/Biff_records/SXDI.cpp | 19 +++- .../XlsFormat/Logic/Biff_records/SXDI.h | 2 + .../XlsFormat/Logic/Biff_records/SXDtr.cpp | 13 ++- .../XlsFormat/Logic/Biff_records/SXDtr.h | 2 + .../XlsFormat/Logic/Biff_records/SXLI.cpp | 27 +++--- .../XlsFormat/Logic/Biff_records/SXVI.cpp | 8 +- .../XlsFormat/Logic/Biff_unions/DBB.cpp | 11 +++ .../source/XlsFormat/Logic/Biff_unions/DBB.h | 7 +- .../XlsFormat/Logic/Biff_unions/DREF.cpp | 6 ++ .../XlsFormat/Logic/Biff_unions/FDB.cpp | 96 ++++++++++++++----- .../source/XlsFormat/Logic/Biff_unions/FDB.h | 6 ++ .../Biff_unions/PIVOTCACHEDEFINITION.cpp | 1 + .../XlsFormat/Logic/Biff_unions/PIVOTLI.cpp | 52 ++++++++-- .../XlsFormat/Logic/Biff_unions/PIVOTLI.h | 8 +- .../XlsFormat/Logic/Biff_unions/PIVOTPI.cpp | 23 ++++- .../XlsFormat/Logic/Biff_unions/PIVOTPI.h | 2 + .../XlsFormat/Logic/Biff_unions/PIVOTVD.cpp | 71 ++++++++++++-- .../XlsFormat/Logic/Biff_unions/PIVOTVIEW.cpp | 34 ++++--- .../XlsFormat/Logic/Biff_unions/SXOPER.cpp | 10 ++ .../XlsFormat/Logic/Biff_unions/SXOPER.h | 5 + .../XlsFormat/Logic/Biff_unions/SXRANGE.cpp | 8 +- .../source/XlsXlsxConverter/XlsConverter.cpp | 9 +- .../xlsx_conversion_context.cpp | 4 - .../source/XlsXlsxConverter/xlsx_package.cpp | 30 +++--- .../XlsXlsxConverter/xlsx_pivots_context.cpp | 14 +-- .../XlsXlsxConverter/xlsx_pivots_context.h | 2 +- 26 files changed, 352 insertions(+), 118 deletions(-) diff --git a/ASCOfficeXlsFile2/source/XlsFormat/Logic/Biff_records/SXDI.cpp b/ASCOfficeXlsFile2/source/XlsFormat/Logic/Biff_records/SXDI.cpp index 7c054841d3..3e353f1c4e 100644 --- a/ASCOfficeXlsFile2/source/XlsFormat/Logic/Biff_records/SXDI.cpp +++ b/ASCOfficeXlsFile2/source/XlsFormat/Logic/Biff_records/SXDI.cpp @@ -39,12 +39,10 @@ SXDI::SXDI() { } - SXDI::~SXDI() { } - BaseObjectPtr SXDI::clone() { return BaseObjectPtr(new SXDI(*this)); @@ -61,5 +59,22 @@ void SXDI::readFields(CFRecord& record) } } +int SXDI::serialize(std::wostream & strm) +{ + CP_XML_WRITER(strm) + { + CP_XML_NODE(L"dataField") + { + if (stName.value().empty() == false) + CP_XML_ATTR(L"name", stName.value()); + + CP_XML_ATTR(L"fld", isxvdData); + CP_XML_ATTR(L"baseField", df); + CP_XML_ATTR(L"baseItem", isxvi); + CP_XML_ATTR(L"numFmtId", ifmt); + } + } + return 0; +} } // namespace XLS diff --git a/ASCOfficeXlsFile2/source/XlsFormat/Logic/Biff_records/SXDI.h b/ASCOfficeXlsFile2/source/XlsFormat/Logic/Biff_records/SXDI.h index f0d44cecb7..1ca7d02874 100644 --- a/ASCOfficeXlsFile2/source/XlsFormat/Logic/Biff_records/SXDI.h +++ b/ASCOfficeXlsFile2/source/XlsFormat/Logic/Biff_records/SXDI.h @@ -49,6 +49,8 @@ public: void readFields(CFRecord& record); + int serialize(std::wostream & strm); + static const ElementType type = typeSXDI; short isxvdData; diff --git a/ASCOfficeXlsFile2/source/XlsFormat/Logic/Biff_records/SXDtr.cpp b/ASCOfficeXlsFile2/source/XlsFormat/Logic/Biff_records/SXDtr.cpp index b484e8181c..0354bb0086 100644 --- a/ASCOfficeXlsFile2/source/XlsFormat/Logic/Biff_records/SXDtr.cpp +++ b/ASCOfficeXlsFile2/source/XlsFormat/Logic/Biff_records/SXDtr.cpp @@ -53,6 +53,15 @@ void SXDtr::readFields(CFRecord& record) { record >> yr >> mon >> dom >> hr >> min >> sec; } + +std::wstring SXDtr::get_string_date() +{ + std::wstringstream s; + s << yr << L"-" << (mon < 10 ? L"0" : L"") << mon << L"-" << (dom < 10 ? L"0" : L"") << dom << L"T" + << (hr < 10 ? L"0" : L"") << hr << L":" << (min < 10 ? L"0" : L"") << min << L":" << (sec < 10 ? L"0" : L"") << sec; + + return s.str(); +} int SXDtr::serialize(std::wostream & strm) { @@ -60,10 +69,8 @@ int SXDtr::serialize(std::wostream & strm) { CP_XML_NODE(L"d") { - std::wstringstream s; - s << yr << L"-" << mon << L"-" << dom << L"T" << hr << L":" << min << L":" << sec; - CP_XML_ATTR(L"v", s.str()); + CP_XML_ATTR(L"v", get_string_date()); } } diff --git a/ASCOfficeXlsFile2/source/XlsFormat/Logic/Biff_records/SXDtr.h b/ASCOfficeXlsFile2/source/XlsFormat/Logic/Biff_records/SXDtr.h index 14ec1b1a99..74bb684e62 100644 --- a/ASCOfficeXlsFile2/source/XlsFormat/Logic/Biff_records/SXDtr.h +++ b/ASCOfficeXlsFile2/source/XlsFormat/Logic/Biff_records/SXDtr.h @@ -59,6 +59,8 @@ public: unsigned char min; unsigned char sec; + std::wstring get_string_date(); + }; } // namespace XLS diff --git a/ASCOfficeXlsFile2/source/XlsFormat/Logic/Biff_records/SXLI.cpp b/ASCOfficeXlsFile2/source/XlsFormat/Logic/Biff_records/SXLI.cpp index 03c97c23bb..2ee4705ed8 100644 --- a/ASCOfficeXlsFile2/source/XlsFormat/Logic/Biff_records/SXLI.cpp +++ b/ASCOfficeXlsFile2/source/XlsFormat/Logic/Biff_records/SXLI.cpp @@ -50,17 +50,15 @@ BaseObjectPtr SXLI::clone() } void SXLI::readFields(CFRecord& record) -{// 0 or 2 records SXLIItem - int size_item = (record.getDataSize() - record.getRdPtr()) / 2; - - if (size_item < 8) +{ + while(true) { - //?? - return; - } + int size_item = record.getDataSize() - record.getRdPtr(); - for (int k = 0; k < 2; k++) - { + if (size_item < 8) + { + break; + } SXLIItem item; unsigned short flags; @@ -74,12 +72,13 @@ void SXLI::readFields(CFRecord& record) item.fGrand = GETBIT(flags, 11); item.fMultiDataOnAxis = GETBIT(flags, 12); - int count = (size_item - 8) / 2; - - for (int i = 0; i < count; i++) + //if (!item.fGrand && item.itmType != 0x000E) { - short val; record >> val; - item.rgisxvi.push_back(val); + for (short i = 0; i < item.isxviMac; i++) + { + short val; record >> val; + item.rgisxvi.push_back(val); + } } m_arItems.push_back(item); } diff --git a/ASCOfficeXlsFile2/source/XlsFormat/Logic/Biff_records/SXVI.cpp b/ASCOfficeXlsFile2/source/XlsFormat/Logic/Biff_records/SXVI.cpp index c0171cc673..38c89f00d7 100644 --- a/ASCOfficeXlsFile2/source/XlsFormat/Logic/Biff_records/SXVI.cpp +++ b/ASCOfficeXlsFile2/source/XlsFormat/Logic/Biff_records/SXVI.cpp @@ -73,10 +73,6 @@ int SXVI::serialize(std::wostream & strm) { CP_XML_NODE(L"item") { - if (itmType == 0) - { - CP_XML_ATTR(L"x", iCache); - } if (fMissing) CP_XML_ATTR(L"m", 1); if (fHidden) @@ -86,6 +82,10 @@ int SXVI::serialize(std::wostream & strm) if (fFormula) CP_XML_ATTR(L"f", 1); + if (itmType == 0) + { + CP_XML_ATTR(L"x", iCache); + } switch(itmType) { case 0x0001: CP_XML_ATTR(L"t", L"default"); break; diff --git a/ASCOfficeXlsFile2/source/XlsFormat/Logic/Biff_unions/DBB.cpp b/ASCOfficeXlsFile2/source/XlsFormat/Logic/Biff_unions/DBB.cpp index f96c84385e..1a8f7742a6 100644 --- a/ASCOfficeXlsFile2/source/XlsFormat/Logic/Biff_unions/DBB.cpp +++ b/ASCOfficeXlsFile2/source/XlsFormat/Logic/Biff_unions/DBB.cpp @@ -40,6 +40,11 @@ namespace XLS DBB::DBB() { + bString = false; + bDate = false; + bNumber = false; + bEmpty = false; + fShortIitms = false; } @@ -64,6 +69,12 @@ const bool DBB::loadContent(BinProcessor& proc) while(count--) { m_arSXOPER.push_back(elements_.front()); elements_.pop_front(); + SXOPER* operatr = dynamic_cast(m_arSXOPER.back().get()); + + bString |= operatr->bString; + bDate |= operatr->bDate; + bNumber |= operatr->bNumber; + bEmpty |= operatr->bEmpty; } if (!m_SXDBB && m_arSXOPER.empty()) diff --git a/ASCOfficeXlsFile2/source/XlsFormat/Logic/Biff_unions/DBB.h b/ASCOfficeXlsFile2/source/XlsFormat/Logic/Biff_unions/DBB.h index 7fb1c8a792..2e9d9ccf28 100644 --- a/ASCOfficeXlsFile2/source/XlsFormat/Logic/Biff_unions/DBB.h +++ b/ASCOfficeXlsFile2/source/XlsFormat/Logic/Biff_unions/DBB.h @@ -55,7 +55,12 @@ public: std::vector m_arSXOPER; //--------------------------------------------------- - bool fShortIitms; + bool fShortIitms; + + bool bString; + bool bDate; + bool bNumber; + bool bEmpty; }; } // namespace XLS diff --git a/ASCOfficeXlsFile2/source/XlsFormat/Logic/Biff_unions/DREF.cpp b/ASCOfficeXlsFile2/source/XlsFormat/Logic/Biff_unions/DREF.cpp index 27820bfef2..39bf32aec2 100644 --- a/ASCOfficeXlsFile2/source/XlsFormat/Logic/Biff_unions/DREF.cpp +++ b/ASCOfficeXlsFile2/source/XlsFormat/Logic/Biff_unions/DREF.cpp @@ -95,6 +95,12 @@ int DREF::serialize(std::wostream & strm) } else if(ref) { + CP_XML_ATTR(L"type", L"worksheet"); + CP_XML_NODE(L"worksheetSource") + { + CP_XML_ATTR(L"ref", ref->ref.toString()); + CP_XML_ATTR(L"sheet", ref->stFile); + } } } } diff --git a/ASCOfficeXlsFile2/source/XlsFormat/Logic/Biff_unions/FDB.cpp b/ASCOfficeXlsFile2/source/XlsFormat/Logic/Biff_unions/FDB.cpp index a64262dc62..5963142f1e 100644 --- a/ASCOfficeXlsFile2/source/XlsFormat/Logic/Biff_unions/FDB.cpp +++ b/ASCOfficeXlsFile2/source/XlsFormat/Logic/Biff_unions/FDB.cpp @@ -74,14 +74,16 @@ private: FDB::FDB() { + bString = false; + bDate = false; + bNumber = false; + bEmpty = false; } - FDB::~FDB() { } - BaseObjectPtr FDB::clone() { return BaseObjectPtr(new FDB(*this)); @@ -123,10 +125,15 @@ const bool FDB::loadContent(BinProcessor& proc) while(count > 0) { - SXOPER * oper = dynamic_cast (elements_.front().get()); - if (oper) + SXOPER * operatr = dynamic_cast (elements_.front().get()); + if (operatr) { m_arGRPSXOPER.push_back(elements_.front()); + + //bString |= operatr->bString; + //bDate |= operatr->bDate; + //bNumber |= operatr->bNumber; + //bEmpty |= operatr->bEmpty; } else { @@ -150,6 +157,13 @@ const bool FDB::loadContent(BinProcessor& proc) while(count--) { m_arSRCSXOPER.push_back(elements_.front()); elements_.pop_front(); + + SXOPER* operatr = dynamic_cast (m_arSRCSXOPER.back().get()); + + bString |= operatr->bString; + bDate |= operatr->bDate; + bNumber |= operatr->bNumber; + bEmpty |= operatr->bEmpty; } return true; @@ -167,7 +181,15 @@ int FDB::serialize(std::wostream & strm) CP_XML_NODE(L"cacheField") { CP_XML_ATTR(L"name", fdb->stFieldName.value()); - CP_XML_ATTR(L"numFmtId", fdb_type->wTypeSql); + + if (fdb_type->wTypeSql > 0) + { + CP_XML_ATTR(L"numFmtId", fdb_type->wTypeSql); + } + if (m_arSRCSXOPER.empty()) + { + CP_XML_ATTR(L"databaseField", 0); + } switch(fdb_type->wTypeSql)//format code { @@ -189,32 +211,60 @@ int FDB::serialize(std::wostream & strm) { //{formula } - //caption, databaseFields, .. if (m_arSRCSXOPER.empty() == false) { CP_XML_NODE(L"sharedItems") { - //CP_XML_ATTR(L"containsSemiMixedTypes", 0); - CP_XML_ATTR(L"containsNonDate", fdb->fNonDates); - CP_XML_ATTR(L"containsDate", fdb->fDateInField); - CP_XML_ATTR(L"containsNumber", fdb->fNumField); - CP_XML_ATTR(L"containsBlank", fdb->fTextEtcField); - //CP_XML_ATTR(L"containsString", 0); + //использовать поля присутствия из xls низя - они частенько записаны неверно!! + //if (!fdb->fNonDates) CP_XML_ATTR(L"containsNonDate", fdb->fNonDates); + //if (fdb->fDateInField) CP_XML_ATTR(L"containsDate", fdb->fDateInField); + //if (fdb->fNumField) CP_XML_ATTR(L"containsNumber", fdb->fNumField); + ////CP_XML_ATTR(L"containsBlank", fdb->fTextEtcField); + + //if (m_arSRCSXOPER.empty()) + //{ + // if (!fdb->fTextEtcField) + // { + // CP_XML_ATTR(L"containsString", 0); + // } + // else if (fdb->fNumField || fdb->fDateInField) + // { + // CP_XML_ATTR(L"containsBlank", 1); + // CP_XML_ATTR(L"containsString", 0); + // } + //} + if ((bDate & bNumber) || (bNumber & bString)) + { + CP_XML_ATTR(L"containsSemiMixedTypes", 1); + } + else if ( bDate & bString) + { + CP_XML_ATTR(L"containsMixedTypes", 1); + } + else if (!bEmpty && !bString) + { + CP_XML_ATTR(L"containsSemiMixedTypes", 0); + } + if (bNumber) CP_XML_ATTR(L"containsNumber", 1); + if (bDate) CP_XML_ATTR(L"containsDate", 1); + if (!bString) CP_XML_ATTR(L"containsString", 0); + if (bEmpty) CP_XML_ATTR(L"containsBlank", 1); + if (fdb->fnumMinMaxValid) { - if (fdb->fDateInField) - { - CP_XML_ATTR(L"minDate", 0); // "2007-11-18T00:00:00" - CP_XML_ATTR(L"maxDate", 0); // "2007-12-25T00:00:00" - } - else if (fdb->fNumField) - { - CP_XML_ATTR(L"minValue", 0); - CP_XML_ATTR(L"maxValue", 0); - } + //if (fdb->fDateInField) + //{ + // CP_XML_ATTR(L"minDate", 0); // "2007-11-18T00:00:00" + // CP_XML_ATTR(L"maxDate", 0); // "2007-12-25T00:00:00" + //} + //else if (fdb->fNumField) + //{ + // CP_XML_ATTR(L"minValue", 0); + // CP_XML_ATTR(L"maxValue", 0); + //} } - CP_XML_ATTR(L"count", fdb->catm); + CP_XML_ATTR(L"count", m_arSRCSXOPER.size()); for (size_t i = 0; i < m_arSRCSXOPER.size(); i++) { diff --git a/ASCOfficeXlsFile2/source/XlsFormat/Logic/Biff_unions/FDB.h b/ASCOfficeXlsFile2/source/XlsFormat/Logic/Biff_unions/FDB.h index 1dc5ff8602..348712d734 100644 --- a/ASCOfficeXlsFile2/source/XlsFormat/Logic/Biff_unions/FDB.h +++ b/ASCOfficeXlsFile2/source/XlsFormat/Logic/Biff_unions/FDB.h @@ -59,6 +59,12 @@ public: std::vector m_arGRPSXOPER; BaseObjectPtr m_SXRANGE; std::vector m_arSxIsxoper; + + bool bString; + bool bDate; + bool bNumber; + bool bEmpty; + }; } // namespace XLS diff --git a/ASCOfficeXlsFile2/source/XlsFormat/Logic/Biff_unions/PIVOTCACHEDEFINITION.cpp b/ASCOfficeXlsFile2/source/XlsFormat/Logic/Biff_unions/PIVOTCACHEDEFINITION.cpp index fb98abc581..1ad080c006 100644 --- a/ASCOfficeXlsFile2/source/XlsFormat/Logic/Biff_unions/PIVOTCACHEDEFINITION.cpp +++ b/ASCOfficeXlsFile2/source/XlsFormat/Logic/Biff_unions/PIVOTCACHEDEFINITION.cpp @@ -116,6 +116,7 @@ int PIVOTCACHEDEFINITION::serialize_definitions(std::wostream & strm) { CP_XML_ATTR(L"r:id", L"rId1" ); } + CP_XML_ATTR(L"enableRefresh", 1); CP_XML_ATTR(L"refreshedBy", db->rgb.value()); CP_XML_ATTR(L"refreshedDate", db_ex->numDate.data.value); CP_XML_ATTR(L"recordCount", db->crdbUsed); diff --git a/ASCOfficeXlsFile2/source/XlsFormat/Logic/Biff_unions/PIVOTLI.cpp b/ASCOfficeXlsFile2/source/XlsFormat/Logic/Biff_unions/PIVOTLI.cpp index dbfb353c87..f15d86d6b0 100644 --- a/ASCOfficeXlsFile2/source/XlsFormat/Logic/Biff_unions/PIVOTLI.cpp +++ b/ASCOfficeXlsFile2/source/XlsFormat/Logic/Biff_unions/PIVOTLI.cpp @@ -31,29 +31,26 @@ */ #include "PIVOTLI.h" -#include -#include + +#include "../Biff_records/SXLI.h" +#include "../Biff_records/Continue.h" namespace XLS { - PIVOTLI::PIVOTLI() { } - PIVOTLI::~PIVOTLI() { } - BaseObjectPtr PIVOTLI::clone() { return BaseObjectPtr(new PIVOTLI(*this)); } - // PIVOTLI = SXLI *Continue const bool PIVOTLI::loadContent(BinProcessor& proc) { @@ -61,10 +58,53 @@ const bool PIVOTLI::loadContent(BinProcessor& proc) { return false; } + m_SXLI = elements_.back(); + elements_.pop_back(); + proc.repeated(0, 0); return true; } +int PIVOTLI::serialize(std::wostream & strm) +{ + SXLI* line_items = dynamic_cast(m_SXLI.get()); + if (!line_items) return 0; + + CP_XML_WRITER(strm) + { + for (size_t i = 0; i < line_items->m_arItems.size(); i++) + { + CP_XML_NODE(L"i") + { + switch(line_items->m_arItems[i].itmType) + { + case 0x0001: CP_XML_ATTR(L"t", L"default"); break; + case 0x0002: CP_XML_ATTR(L"t", L"sum"); break; + case 0x0003: CP_XML_ATTR(L"t", L"countA"); break; + case 0x0004: CP_XML_ATTR(L"t", L"count"); break; + case 0x0005: CP_XML_ATTR(L"t", L"avg"); break; + case 0x0006: CP_XML_ATTR(L"t", L"max"); break; + case 0x0007: CP_XML_ATTR(L"t", L"min"); break; + case 0x0008: CP_XML_ATTR(L"t", L"product"); break; + case 0x0009: CP_XML_ATTR(L"t", L"stdDev"); break; + case 0x000A: CP_XML_ATTR(L"t", L"stdDevP"); break; + case 0x000B: CP_XML_ATTR(L"t", L"var"); break; + case 0x000C: CP_XML_ATTR(L"t", L"varP"); break; + case 0x000D: CP_XML_ATTR(L"t", L"grand"); break; + case 0x000E: CP_XML_ATTR(L"t", L"blank"); break; + } + + for (size_t j = 0; j < line_items->m_arItems[i].rgisxvi.size(); j++) + { + CP_XML_NODE(L"x") + { + CP_XML_ATTR(L"v", line_items->m_arItems[i].rgisxvi[j]); + } + } + } + } + } +} } // namespace XLS diff --git a/ASCOfficeXlsFile2/source/XlsFormat/Logic/Biff_unions/PIVOTLI.h b/ASCOfficeXlsFile2/source/XlsFormat/Logic/Biff_unions/PIVOTLI.h index 98041e02d8..36d8239895 100644 --- a/ASCOfficeXlsFile2/source/XlsFormat/Logic/Biff_unions/PIVOTLI.h +++ b/ASCOfficeXlsFile2/source/XlsFormat/Logic/Biff_unions/PIVOTLI.h @@ -36,8 +36,6 @@ namespace XLS { - -// Logical representation of PIVOTLI union of records class PIVOTLI: public CompositeObject { BASE_OBJECT_DEFINE_CLASS_NAME(PIVOTLI) @@ -49,7 +47,11 @@ public: virtual const bool loadContent(BinProcessor& proc); - static const ElementType type = typePIVOTLI; + int serialize(std::wostream & strm); + + static const ElementType type = typePIVOTLI; + + BaseObjectPtr m_SXLI; }; } // namespace XLS diff --git a/ASCOfficeXlsFile2/source/XlsFormat/Logic/Biff_unions/PIVOTPI.cpp b/ASCOfficeXlsFile2/source/XlsFormat/Logic/Biff_unions/PIVOTPI.cpp index 76a37b04ba..fcf34f3b7c 100644 --- a/ASCOfficeXlsFile2/source/XlsFormat/Logic/Biff_unions/PIVOTPI.cpp +++ b/ASCOfficeXlsFile2/source/XlsFormat/Logic/Biff_unions/PIVOTPI.cpp @@ -31,13 +31,12 @@ */ #include "PIVOTPI.h" -#include -#include +#include "../Biff_records/SXPI.h" +#include "../Biff_records/Continue.h" namespace XLS { - PIVOTPI::PIVOTPI() { } @@ -53,7 +52,6 @@ BaseObjectPtr PIVOTPI::clone() return BaseObjectPtr(new PIVOTPI(*this)); } - // PIVOTPI = SXPI *Continue const bool PIVOTPI::loadContent(BinProcessor& proc) { @@ -69,5 +67,22 @@ const bool PIVOTPI::loadContent(BinProcessor& proc) return true; } +int PIVOTPI::serialize(std::wostream & strm) +{ + SXPI* page_items = dynamic_cast(m_SXPI.get()); + if (!page_items) return 0; + + CP_XML_WRITER(strm) + { + for (size_t i = 0; i < page_items->m_arItems.size(); i++) + { + CP_XML_NODE(L"pageField") + { + CP_XML_ATTR(L"fld", page_items->m_arItems[i].isxvd); + CP_XML_ATTR(L"hier",0); + } + } + } +} } // namespace XLS diff --git a/ASCOfficeXlsFile2/source/XlsFormat/Logic/Biff_unions/PIVOTPI.h b/ASCOfficeXlsFile2/source/XlsFormat/Logic/Biff_unions/PIVOTPI.h index 31d5cfd22c..ffe657377a 100644 --- a/ASCOfficeXlsFile2/source/XlsFormat/Logic/Biff_unions/PIVOTPI.h +++ b/ASCOfficeXlsFile2/source/XlsFormat/Logic/Biff_unions/PIVOTPI.h @@ -47,6 +47,8 @@ public: virtual const bool loadContent(BinProcessor& proc); + int serialize(std::wostream & strm); + static const ElementType type = typePIVOTPI; BaseObjectPtr m_SXPI; diff --git a/ASCOfficeXlsFile2/source/XlsFormat/Logic/Biff_unions/PIVOTVD.cpp b/ASCOfficeXlsFile2/source/XlsFormat/Logic/Biff_unions/PIVOTVD.cpp index d69e67c9f8..505672ca0e 100644 --- a/ASCOfficeXlsFile2/source/XlsFormat/Logic/Biff_unions/PIVOTVD.cpp +++ b/ASCOfficeXlsFile2/source/XlsFormat/Logic/Biff_unions/PIVOTVD.cpp @@ -80,20 +80,73 @@ int PIVOTVD::serialize(std::wostream & strm) Sxvd* vd = dynamic_cast(m_Sxvd.get()); SXVDEx* vd_ex = dynamic_cast(m_SXVDEx.get()); + if (!vd || !vd_ex) return 0; + CP_XML_WRITER(strm) { CP_XML_NODE(L"pivotField") { - //CP_XML_ATTR(L"axis", ); - //CP_XML_ATTR(L"compact", ); - //CP_XML_ATTR(L"outline", ); - //CP_XML_ATTR(L"subtotalTop", ); - //CP_XML_ATTR(L"showAll", ); - //CP_XML_ATTR(L"includeNewItemsInFilter", ); - //CP_XML_ATTR(L"sortType", ); - //CP_XML_ATTR(L"rankBy", ); - //CP_XML_ATTR(L"axis", ); + if (vd->sxaxis.bRw) CP_XML_ATTR(L"axis", L"axisRow"); + else if (vd->sxaxis.bCol) CP_XML_ATTR(L"axis", L"axisCol"); + else if (vd->sxaxis.bPage) CP_XML_ATTR(L"axis", L"axisPage"); + else if (vd->sxaxis.bData) + { + CP_XML_ATTR(L"dataField", 1); + } + + CP_XML_ATTR(L"compact", 0); + + if (vd_ex->ifmt > 0) + { + CP_XML_ATTR(L"numFmtId", vd_ex->ifmt); + } + if (vd->stName.value().empty() == false) + CP_XML_ATTR(L"name", vd->stName.value()); + + if (vd->fCounta) CP_XML_ATTR(L"countASubtotal", 1); + if (vd->fCount) CP_XML_ATTR(L"countSubtotal", 1); + if (vd->fDefault) CP_XML_ATTR(L"defaultSubtotal", 1); + if (vd->fSum) CP_XML_ATTR(L"sumSubtotal", 1); + if (vd->fAverage) CP_XML_ATTR(L"avgSubtotal", 1); + if (vd->fMax) CP_XML_ATTR(L"maxSubtotal", 1); + if (vd->fMin) CP_XML_ATTR(L"minSubtotal", 1); + if (vd->fProduct) CP_XML_ATTR(L"productSubtotal", 1); + if (vd->fStdev) CP_XML_ATTR(L"stdSubtotal", 1); + if (vd->fStdevp) CP_XML_ATTR(L"stdDevSubtotal", 1); + if (vd->fVariance) CP_XML_ATTR(L"varSubtotal", 1); + if (vd->fVariancep) CP_XML_ATTR(L"varPSubtotal", 1); + + CP_XML_ATTR(L"outline", vd_ex->fOutline); + CP_XML_ATTR(L"subtotalTop", vd_ex->fSubtotalAtTop); + CP_XML_ATTR(L"showAll", vd_ex->fShowAllItems); + + if (vd_ex->fNotDragToData) CP_XML_ATTR(L"dragToData", 0); + if (!vd_ex->fDragToRow) CP_XML_ATTR(L"dragToRow", 0); + if (!vd_ex->fDragToColumn) CP_XML_ATTR(L"dragToCol", 0); + if (!vd_ex->fDragToPage) CP_XML_ATTR(L"dragToPage", 0); + + if (vd_ex->fHideNewItems) CP_XML_ATTR(L"hideNewItems", 1); + if (vd_ex->fInsertBlankRow) CP_XML_ATTR(L"insertBlankRow", 1); + if (vd_ex->fPageBreaksBetweenItems) CP_XML_ATTR(L"insertPageBreak", 1); + if (!vd_ex->fTopAutoShow) CP_XML_ATTR(L"topAutoShow", 0); + //if (!vd_ex->fDragToHide) CP_XML_ATTR(L"dragOff", 0); //?? + if (vd_ex->fServerBased) CP_XML_ATTR(L"serverField", 1); + + //CP_XML_ATTR(L"", vd_ex->fCalculatedField); + CP_XML_ATTR(L"includeNewItemsInFilter", 1); + + //CP_XML_ATTR(L"nonAutoSortDefault", !vd_ex->fAutoSort); + if (vd_ex->fAutoSort) + { + // vd_ex->isxdiAutoSort + + if (vd_ex->fAscendSort) CP_XML_ATTR(L"sortType", L"ascending"); + } + if (vd_ex->isxdiAutoShow >= 0) + { + CP_XML_ATTR(L"rankBy", vd_ex->isxdiAutoShow); + } if (!m_arSXVI.empty()) { CP_XML_NODE(L"items") diff --git a/ASCOfficeXlsFile2/source/XlsFormat/Logic/Biff_unions/PIVOTVIEW.cpp b/ASCOfficeXlsFile2/source/XlsFormat/Logic/Biff_unions/PIVOTVIEW.cpp index 6ed1b69aa0..18cb41229a 100644 --- a/ASCOfficeXlsFile2/source/XlsFormat/Logic/Biff_unions/PIVOTVIEW.cpp +++ b/ASCOfficeXlsFile2/source/XlsFormat/Logic/Biff_unions/PIVOTVIEW.cpp @@ -107,7 +107,10 @@ int PIVOTVIEW::serialize(std::wostream & strm) CP_XML_ATTR(L"applyPatternFormats", view->fAtrPat); CP_XML_ATTR(L"applyAlignmentFormats", view->fAtrAlc); CP_XML_ATTR(L"applyWidthHeightFormats", view->fAtrProc); - CP_XML_ATTR(L"dataCaption", view->stData.value()); + if (!view->stData.value().empty()) + { + CP_XML_ATTR(L"dataCaption", view->stData.value()); + } //updatedVersion="2" //asteriskTotals="1" //showMemberPropertyTips="0" @@ -144,14 +147,15 @@ int PIVOTVIEW::serialize(std::wostream & strm) ivd->serialize(CP_XML_STREAM()); } } - CP_XML_NODE(L"rowItems") + if (core->m_arPIVOTLI.size() == 2)//0 or 2 { - CP_XML_ATTR(L"count", view->cRw); - //for (size_t i = 0; i < m_arPIVOTLI.size(); i++) - //{ - // PIVOTLI* line = dynamic_cast(m_arPIVOTLI[i].get()); - // m_arPIVOTIVD[i]->serialize(CP_XML_STREAM()); - //} + CP_XML_NODE(L"rowItems") + { + CP_XML_ATTR(L"count", view->cRw); + + PIVOTLI* line = dynamic_cast(core->m_arPIVOTLI[0].get()); + line->serialize(CP_XML_STREAM()); + } } if (core->m_arPIVOTIVD.size() == 2)//0 or 2 { @@ -163,13 +167,15 @@ int PIVOTVIEW::serialize(std::wostream & strm) ivd->serialize(CP_XML_STREAM()); } } - CP_XML_NODE(L"colItems") + if (core->m_arPIVOTLI.size() == 2)//0 or 2 { - CP_XML_ATTR(L"count", view->cCol); - //for (size_t i = 0; i < m_arPIVOTLI.size(); i++) - //{ - // m_arPIVOTIVD[i]->serialize(CP_XML_STREAM()); - //} + CP_XML_NODE(L"colItems") + { + CP_XML_ATTR(L"count", view->cCol); + + PIVOTLI* line = dynamic_cast(core->m_arPIVOTLI[1].get()); + line->serialize(CP_XML_STREAM()); + } } if (core->m_PIVOTPI) { diff --git a/ASCOfficeXlsFile2/source/XlsFormat/Logic/Biff_unions/SXOPER.cpp b/ASCOfficeXlsFile2/source/XlsFormat/Logic/Biff_unions/SXOPER.cpp index 5f0131f829..2d130fb8d5 100644 --- a/ASCOfficeXlsFile2/source/XlsFormat/Logic/Biff_unions/SXOPER.cpp +++ b/ASCOfficeXlsFile2/source/XlsFormat/Logic/Biff_unions/SXOPER.cpp @@ -43,6 +43,10 @@ namespace XLS SXOPER::SXOPER() { + bString = false; + bDate = false; + bNumber = false; + bEmpty = false; } SXOPER::~SXOPER() @@ -59,21 +63,27 @@ const bool SXOPER::loadContent(BinProcessor& proc) { if(proc.optional()) { + bEmpty = true; } else if(proc.optional()) { + bNumber = true; } else if(proc.optional()) { + bNumber = true; } else if(proc.optional()) { + bNumber = true; } else if(proc.optional()) { + bString = true; } else if(proc.optional()) { + bDate =true; } else return false; diff --git a/ASCOfficeXlsFile2/source/XlsFormat/Logic/Biff_unions/SXOPER.h b/ASCOfficeXlsFile2/source/XlsFormat/Logic/Biff_unions/SXOPER.h index e2f2c3afa0..7c39d53f74 100644 --- a/ASCOfficeXlsFile2/source/XlsFormat/Logic/Biff_unions/SXOPER.h +++ b/ASCOfficeXlsFile2/source/XlsFormat/Logic/Biff_unions/SXOPER.h @@ -52,6 +52,11 @@ public: static const ElementType type = typeSXOPER; BaseObjectPtr m_element; + + bool bString; + bool bDate; + bool bNumber; + bool bEmpty; }; } // namespace XLS diff --git a/ASCOfficeXlsFile2/source/XlsFormat/Logic/Biff_unions/SXRANGE.cpp b/ASCOfficeXlsFile2/source/XlsFormat/Logic/Biff_unions/SXRANGE.cpp index a043e4e45c..0cdf9e38e1 100644 --- a/ASCOfficeXlsFile2/source/XlsFormat/Logic/Biff_unions/SXRANGE.cpp +++ b/ASCOfficeXlsFile2/source/XlsFormat/Logic/Biff_unions/SXRANGE.cpp @@ -140,12 +140,8 @@ int SXRANGE::serialize(std::wostream & strm) SXDtr* startDate = dynamic_cast(m_arSXDtr[0].get()); SXDtr* endDate = dynamic_cast(m_arSXDtr[1].get()); - std::wstringstream s_start, s_end; - s_start << startDate->yr << L"-" << startDate->mon << L"-" << startDate->dom << L"T" << startDate->hr << L":" << startDate->min << L":" << startDate->sec; - s_end << endDate->yr << L"-" << endDate->mon << L"-" << endDate->dom << L"T" << endDate->hr << L":" << endDate->min << L":" << endDate->sec; - - CP_XML_ATTR(L"startDate", s_start.str()); - CP_XML_ATTR(L"endDate", s_end.str()); + CP_XML_ATTR(L"startDate", startDate->get_string_date()); + CP_XML_ATTR(L"endDate", endDate->get_string_date()); } if (m_arSXNum.size() == 3) { diff --git a/ASCOfficeXlsFile2/source/XlsXlsxConverter/XlsConverter.cpp b/ASCOfficeXlsFile2/source/XlsXlsxConverter/XlsConverter.cpp index 7a843dda31..22972155e4 100644 --- a/ASCOfficeXlsFile2/source/XlsXlsxConverter/XlsConverter.cpp +++ b/ASCOfficeXlsFile2/source/XlsXlsxConverter/XlsConverter.cpp @@ -1920,7 +1920,14 @@ void XlsConverter::convert(XLS::PIVOTVIEW * pivot_view) pivot_view->serialize(strm); - xlsx_context->get_pivots_context().add_view(strm.str(), pivot_view->indexCache); + int index_view = xlsx_context->get_pivots_context().add_view(strm.str(), pivot_view->indexCache); + + if (index_view > 0) + { + xlsx_context->current_sheet().sheet_rels().add(oox::relationship(L"pvId" + std::to_wstring(index_view), + L"http://schemas.openxmlformats.org/officeDocument/2006/relationships/pivotTable", + L"../pivotTables/pivotTable" + std::to_wstring(index_view) + L".xml")); + } } void XlsConverter::convert(XLS::PIVOTCACHEDEFINITION * pivot_cached) diff --git a/ASCOfficeXlsFile2/source/XlsXlsxConverter/xlsx_conversion_context.cpp b/ASCOfficeXlsFile2/source/XlsXlsxConverter/xlsx_conversion_context.cpp index dd04616e2b..a4e8bb4b17 100644 --- a/ASCOfficeXlsFile2/source/XlsXlsxConverter/xlsx_conversion_context.cpp +++ b/ASCOfficeXlsFile2/source/XlsXlsxConverter/xlsx_conversion_context.cpp @@ -285,10 +285,6 @@ void xlsx_conversion_context::end_document() { for (int i = 0; i < pivot_view_count; i++) { - //std::wstring rId = L"pvId" + std::to_wstring(i+1); - //static const std::wstring sType = L"http://schemas.openxmlformats.org/officeDocument/2006/relationships/pivotTable"; - //const std::wstring sName = std::wstring(L"../pivotTables/pivotTable" + std::to_wstring(i + 1) + L".xml"); - package::pivot_table_content_ptr content = package::pivot_table_content::create(); xlsx_pivots_context_.dump_rels_view(i, content->get_rels()); diff --git a/ASCOfficeXlsFile2/source/XlsXlsxConverter/xlsx_package.cpp b/ASCOfficeXlsFile2/source/XlsXlsxConverter/xlsx_package.cpp index 1a97c99b04..4011869df9 100644 --- a/ASCOfficeXlsFile2/source/XlsXlsxConverter/xlsx_package.cpp +++ b/ASCOfficeXlsFile2/source/XlsXlsxConverter/xlsx_package.cpp @@ -176,16 +176,20 @@ void xl_files::write(const std::wstring & RootPath) std::wstring path = RootPath + FILE_SEPARATOR_STR + L"xl"; NSDirectory::CreateDirectory(path.c_str()); - sheets_files_.set_rels(&rels_files_); + { + pivot_cache_files_.set_rels(&rels_files_); + pivot_cache_files_.set_main_document(get_main_document()); + pivot_cache_files_.write(path); + } + { + pivot_table_files_.set_main_document(get_main_document()); + pivot_table_files_.write(path); + } + + sheets_files_.set_rels(&rels_files_); sheets_files_.set_main_document( this->get_main_document() ); sheets_files_.write(path); - int index = 1; - if (true) - { - //workbook_->hyperlinks->write(path); - rels_files_.add( relationship( L"hId1", L"http://schemas.openxmlformats.org/officeDocument/2006/relationships/officeDocument", L"xl/workbook.xml" ) ); - } if (sharedStrings_) { sharedStrings_->write(path); @@ -217,15 +221,7 @@ void xl_files::write(const std::wstring & RootPath) charts_files_.set_main_document(get_main_document()); charts_files_.write(path); } - { - pivot_cache_files_.set_rels(&rels_files_); - pivot_cache_files_.set_main_document(get_main_document()); - pivot_cache_files_.write(path); - } - { - pivot_table_files_.set_main_document(get_main_document()); - pivot_table_files_.write(path); - } + if (drawings_) { drawings_->set_main_document(get_main_document()); @@ -340,7 +336,7 @@ void xl_pivot_cache_files::write(const std::wstring & RootPath) { const std::wstring fileNameR = std::wstring(L"pivotCacheRecords") + std::to_wstring(i + 1) + L".xml"; - contentTypes.add_override(std::wstring(L"/xl/pivotCache/") + fileNameR, kWSConTypeD); + contentTypes.add_override(std::wstring(L"/xl/pivotCache/") + fileNameR, kWSConTypeR); package::simple_element(fileNameR, content_records).write(path); } diff --git a/ASCOfficeXlsFile2/source/XlsXlsxConverter/xlsx_pivots_context.cpp b/ASCOfficeXlsFile2/source/XlsXlsxConverter/xlsx_pivots_context.cpp index 18658dbd7e..460d69d583 100644 --- a/ASCOfficeXlsFile2/source/XlsXlsxConverter/xlsx_pivots_context.cpp +++ b/ASCOfficeXlsFile2/source/XlsXlsxConverter/xlsx_pivots_context.cpp @@ -31,14 +31,11 @@ */ #include "xlsx_pivots_context.h" - #include #include namespace oox { - - class xlsx_pivots_context::Impl { public: @@ -73,13 +70,14 @@ int xlsx_pivots_context::get_cache_count() { return (int)impl_->caches_.size(); } + void xlsx_pivots_context::dump_rels_cache(int index, rels & Rels) { - if (impl_->caches_[index].recordsData_.empty()) + if (impl_->caches_[index].recordsData_.empty() == false) { Rels.add(relationship(L"rId1", L"http://schemas.openxmlformats.org/officeDocument/2006/relationships/pivotCacheRecords", - L"pivotCacheRecords" + std::to_wstring(index) + L".xml", L"")); + L"pivotCacheRecords" + std::to_wstring(index + 1) + L".xml", L"")); } } void xlsx_pivots_context::dump_rels_view(int index, rels & Rels) @@ -104,10 +102,14 @@ void xlsx_pivots_context::write_table_view_to(int index, std::wostream & strm) { strm << impl_->views_[index].data_; } -void xlsx_pivots_context::add_view(std::wstring table_view, int indexCache) +int xlsx_pivots_context::add_view(std::wstring table_view, int indexCache) { + if (table_view.empty()) return 0; + Impl::_pivot_view v = {table_view, indexCache}; impl_->views_.push_back(v); + + return (int)impl_->views_.size(); } int xlsx_pivots_context::get_view_count() diff --git a/ASCOfficeXlsFile2/source/XlsXlsxConverter/xlsx_pivots_context.h b/ASCOfficeXlsFile2/source/XlsXlsxConverter/xlsx_pivots_context.h index 8b3345cdff..d2ff9ae438 100644 --- a/ASCOfficeXlsFile2/source/XlsXlsxConverter/xlsx_pivots_context.h +++ b/ASCOfficeXlsFile2/source/XlsXlsxConverter/xlsx_pivots_context.h @@ -43,7 +43,7 @@ public: xlsx_pivots_context(); ~xlsx_pivots_context(); - void add_view(std::wstring table_view, int indexCache); + int add_view(std::wstring table_view, int indexCache); int get_view_count(); void add_cache(std::wstring definitions, std::wstring records);