Commit a5466ab7 authored by ElenaSubbotina's avatar ElenaSubbotina

XlsFormatReader - external data (dde, workbook, ..)

parent dfd54ff5
......@@ -501,7 +501,7 @@ namespace DocFileFormat
facet.widen((char*)bytes, (char*)bytes + size, &result[0]);
for (long i=0; i < result.length(); i++)
for (size_t i=0; i < result.length(); i++)
{
STLCollection->push_back(result[i]);
}
......@@ -536,7 +536,7 @@ namespace DocFileFormat
delete [] pStrUtf16;
return GetSTLCollectionFromLocale(STLCollection, bytes,size);
}
for (long i=0; i < nLength; i++)
for (unsigned int i = 0; i < nLength; i++)
{
STLCollection->push_back(pStrUtf16[i]);
}
......@@ -566,7 +566,7 @@ namespace DocFileFormat
delete [] pStrUtf32;
return GetSTLCollectionFromLocale(STLCollection, bytes, size);
}
for (long i=0; i < nLength; i++)
for (unsigned int i = 0; i < nLength; i++)
{
STLCollection->push_back(pStrUtf32[i]);
}
......@@ -652,7 +652,7 @@ namespace DocFileFormat
NSUnicodeConverter::CUnicodeConverter oConverter;
std::wstring unicode_string = oConverter.toUnicode((char*)bytes, size, sCodePage.c_str());
for (long i=0; i < unicode_string.size(); i++)
for (size_t i = 0; i < unicode_string.size(); i++)
{
STLCollection->push_back(unicode_string[i]);
}
......
......@@ -154,7 +154,7 @@ namespace cpdoccore
if (val)
{
std::wstring tmp = *val;
XmlUtils::GetLower(tmp);
tmp = XmlUtils::GetLower(tmp);
return optional<bool>::Type((tmp == xml_char_value_type::trueVal));
}
else
......
......@@ -55,8 +55,8 @@ public:
void add_format(std::wstring const & condition, std::wstring const & format)
{
std::wstring c = condition;
XmlUtils::GetLower(c);
std::wstring c = XmlUtils::GetLower(condition);
XmlUtils::replace_all( c, L" ", L"");
XmlUtils::replace_all( c, L"\t", L"");
......
......@@ -46,8 +46,7 @@ std::wostream & operator << (std::wostream & _Wostream, const Bool & _Val)
}
Bool Bool::parse(const std::wstring & Str)
{
std::wstring tmp = Str;
XmlUtils::GetLower(tmp);
std::wstring tmp = XmlUtils::GetLower(Str);
if (tmp == L"0" || tmp == L"false") return Bool(false);
else return Bool(true);
......
......@@ -104,8 +104,7 @@ void styles_container::add_style( const std::wstring & Name,
map_[n] = pos;
// TODO: как правильно??
std::wstring lName = Name;
XmlUtils::GetLower(lName);
std::wstring lName = XmlUtils::GetLower(Name);
//if ( boost::algorithm::contains(lName, L"internet_20_link") )
if (lName == L"internet_20_link")///???????????????
hyperlink_style_pos_ = pos;
......
......@@ -514,49 +514,31 @@ const std::wstring tab2sheet_name(const short tabid, std::vector<std::wstring>&
return L"#REF";
}
//
const std::wstring xti2sheets(const unsigned short ixti, std::vector<std::wstring>& xti_parsed)
const std::wstring xti_indexes2sheet_name(const short tabFirst, const short tabLast, std::vector<std::wstring>& names, const std::wstring prefix)
{
if(ixti >= 0 && static_cast<unsigned short>(ixti) < xti_parsed.size())
{
return xti_parsed[ixti];
}
return L"#REF!";
}
//
const std::wstring xti_indexes2sheet_name(const short itabFirst, const short itabLast, std::vector<std::wstring>& sheets_names)
{
if(-1 == itabFirst)
if(-1 == tabFirst)
{
return L"#REF";
}
static boost::wregex correct_sheet_name(L"^\\'.+?\\'$");
static boost::wregex test_sheet_name(L"[\\s)(\\':.-]+");
static boost::wregex test_sheet_name(L"[\\s)(\\'&:-]+"); //.??? 6442946.xls
std::wstring sheet_first = prefix + tab2sheet_name(tabFirst, names);
std::wstring sheet_first = tab2sheet_name(itabFirst, sheets_names);
if(!boost::regex_search(sheet_first.begin(), sheet_first.end(), correct_sheet_name))
{
if(boost::regex_search(sheet_first.begin(), sheet_first.end(), test_sheet_name))
{
sheet_first = boost::algorithm::replace_all_copy(sheet_first, L"'", L"''");
sheet_first = std::wstring(L"\'") + sheet_first + std::wstring(L"\'");
sheet_first = std::wstring(L"'") + sheet_first + std::wstring(L"'");
}
}
else
{
//todooo найти хоть один файл где в апострофах уже есть внутренний не экранированный апостроф
//static boost::wregex test_sheet_name1(L"[\']+");
//if(boost::regex_search(sheet_first.begin() + 1, sheet_first.end() - 1, test_sheet_name1))
//{
// sheet_first = boost::algorithm::replace_all_copy(sheet_first.begin()+1, sheet_first.end() - 1 , L"'", L"''");
// sheet_first = std::wstring(L"\'") + sheet_first + std::wstring(L"\'");
//}
}
std::wstring sheet_last;
if (itabLast != itabFirst)
if (tabLast != tabFirst)
{
sheet_last = tab2sheet_name(itabLast, sheets_names);
sheet_last = prefix + tab2sheet_name(tabLast, names);
if(!boost::regex_search(sheet_last.begin(), sheet_last.end(), correct_sheet_name))
{
......@@ -572,20 +554,6 @@ const std::wstring xti_indexes2sheet_name(const short itabFirst, const short ita
return sheet_first + sheet_last;
}
const std::wstring make3dRef(const unsigned short ixti, const std::wstring cell_ref, std::vector<std::wstring>& xti_parsed, bool full_ref)
{
std::wstring sheets_prefix = xti2sheets(ixti, xti_parsed);
if(L"#REF!" == sheets_prefix)
{
return sheets_prefix;
}
else if (!sheets_prefix.empty()) sheets_prefix += L"!";
else if (sheets_prefix.empty() && full_ref) sheets_prefix += L"#REF!";
return sheets_prefix + cell_ref;
}
} //namespace XMLSTUFF
......@@ -95,13 +95,7 @@ namespace STR
namespace XMLSTUFF
{;
// Makes a new tag and append it to parent (no attributes set)
//BiffStructurePtr createElement(const std::wstring & tag_name, BiffStructurePtr & parent);
const std::wstring make3dRef(const unsigned short ixti, const std::wstring cell_ref, std::vector<std::wstring>& xti_parsed, bool full_ref = false);
//const unsigned short sheetsnames2ixti(const std::wstring str, MSXML2::IXMLDOMDocumentPtr doc);
const std::wstring xti_indexes2sheet_name(const short itabFirst, const short itabLast, std::vector<std::wstring>& sheets_names);
const std::wstring xti_indexes2sheet_name(const short tabFirst, const short tabLast, std::vector<std::wstring>& names, const std::wstring prefix = L"");
}
......@@ -245,7 +245,7 @@ const bool CFRecord::isEOF() const
{
if(rdPtr > size_)
{
throw;// EXCEPT::LE::WrongFormatInterpretation(__FUNCTION__);
true;//throw;
}
return rdPtr >= size_;
}
......
......@@ -32,14 +32,12 @@
#pragma once
#include "BiffRecord.h"
#include <Logic/Biff_structures/BookExt_Conditional11.h>
#include <Logic/Biff_structures/BookExt_Conditional12.h>
#include "../Biff_structures/BookExt_Conditional11.h"
#include "../Biff_structures/BookExt_Conditional12.h"
namespace XLS
{
// Logical representation of BookExt record in BIFF8
class BookExt: public BiffRecord
{
BIFF_RECORD_DEFINE_TYPE_INFO(BookExt)
......@@ -49,13 +47,11 @@ public:
~BookExt();
BaseObjectPtr clone();
void readFields(CFRecord& record);
static const ElementType type = typeBookExt;
static const ElementType type = typeBookExt;
//-----------------------------
_UINT32 cb;
bool fDontAutoRecover;
......
......@@ -31,7 +31,6 @@
*/
#include "CRN.h"
#include <Logic/Biff_structures/SerAr.h>
namespace XLS
{
......@@ -40,12 +39,10 @@ CRN::CRN()
{
}
CRN::~CRN()
{
}
BaseObjectPtr CRN::clone()
{
return BaseObjectPtr(new CRN(*this));
......@@ -55,10 +52,12 @@ BaseObjectPtr CRN::clone()
void CRN::readFields(CFRecord& record)
{
record >> colLast >> colFirst >> row;
for(int i = 0; i < colLast - colFirst + 1; ++i)
{
unsigned char rec_type;
record >> rec_type;
SerArPtr ser(SerAr::createSerAr(rec_type));
record >> *ser;
crnOper.push_back(ser);
......
......@@ -32,13 +32,11 @@
#pragma once
#include "BiffRecord.h"
#include <Logic/Biff_structures/SerAr.h>
#include "../Biff_structures/SerAr.h"
namespace XLS
{
// Logical representation of CRN record in BIFF8
class CRN: public BiffRecord
{
BIFF_RECORD_DEFINE_TYPE_INFO(CRN)
......@@ -48,18 +46,16 @@ public:
~CRN();
BaseObjectPtr clone();
void readFields(CFRecord& record);
static const ElementType type = typeCRN;
static const ElementType type = typeCRN;
//-----------------------------
unsigned char colLast;
unsigned char colFirst;
_UINT16 row;
BiffStructurePtrVector crnOper;
};
} // namespace XLS
......
......@@ -53,7 +53,10 @@ BaseObjectPtr CodeName::clone()
void CodeName::readFields(CFRecord& record)
{
XLUnicodeString codeName;
record >> codeName;
value = codeName.value();
}
} // namespace XLS
......
......@@ -37,8 +37,6 @@
namespace XLS
{
// Logical representation of CodeName record in BIFF8
class CodeName: public BiffRecord
{
BIFF_RECORD_DEFINE_TYPE_INFO(CodeName)
......@@ -49,14 +47,11 @@ public:
BaseObjectPtr clone();
void readFields(CFRecord& record);
static const ElementType type = typeCodeName;
//-----------------------------
XLUnicodeString codeName;
static const ElementType type = typeCodeName;
std::wstring value;
};
} // namespace XLS
......
......@@ -35,8 +35,8 @@
namespace XLS
{
ExternName::ExternName(const unsigned short supporting_link_type)
: supbook_cch(supporting_link_type), cf(0)
ExternName::ExternName(const unsigned short supporting_link_type, bool bOle)
: supbook_cch(supporting_link_type), cf(-1), bOleVirtualPath(bOle)
{
}
......@@ -70,53 +70,40 @@ void ExternName::readFields(CFRecord& record)
}
else
{
if(fOle && !fOleLink) // DDE data item
if(fOle && !fOleLink)
{
body = BiffStructurePtr(new ExternDdeLinkNoOper);
}
if(!fOle && fOleLink) // DDE data item
if(!fOle && fOleLink)
{
body = BiffStructurePtr(new ExternOleDdeLink);
}
// Nu i kak ya dolzhen opredelit', DDE eto ili OLE?!!!
// V Mikrosofte vse ebanutye - pust' sami parsyat, debily
if(!fOle && !fOleLink)
{
body = BiffStructurePtr(new ExternDocName);
}
// This fills in the gaps between AddinUdfs if the body is not AddinUdf. The simplest way to maintain indexing from my point of view.
}
body->load(record);
if(0x3A01 != supbook_cch)
{
std::wstring name;
if(!fOle && !fOleLink)
{
ExternDocName* n = dynamic_cast<ExternDocName*>(body.get());
if (n->ixals > 0)
if (bOleVirtualPath)
{
//from SupBook
body = BiffStructurePtr(new ExternOleDdeLink);
}
else
{
name = n->nameDefinition.getAssembledFormula();
if (name.empty())
name = n->extName.value();
body = BiffStructurePtr(new ExternDocName);
}
}
if(fOle && !fOleLink) // DDE data item
{
ExternDdeLinkNoOper* n = dynamic_cast<ExternDdeLinkNoOper*>(body.get());
name = n->linkName.value();
}
if(!fOle && fOleLink)
{
ExternOleDdeLink* n = dynamic_cast<ExternOleDdeLink*>(body.get());
name = n->linkName.value();
}
record.getGlobalWorkbookInfo()->arExternalNames.push_back(name);
}
body->load(record);
//cache
switch(cf)
{
case 0: // is text
break;
case 5: //csv (,)
case 6: //Microsoft Symbolic Link (SYLK).
case 8: //biff8
case 44: //unicode text
case 63: //biff12
break;
}
}
......
......@@ -48,11 +48,10 @@ class ExternName: public BiffRecord
BIFF_RECORD_DEFINE_TYPE_INFO(ExternName)
BASE_OBJECT_DEFINE_CLASS_NAME(ExternName)
public:
ExternName(const unsigned short supporting_link_type);
ExternName(const unsigned short supporting_link_type, bool bOle);
~ExternName();
BaseObjectPtr clone();
void readFields(CFRecord& record);
......@@ -64,24 +63,13 @@ public:
bool fWantPict;
bool fOle;
bool fOleLink;
_UINT16 cf;
short cf;
bool fIcon;
BiffStructurePtr body;
//-----------------------------
_UINT16 supbook_cch;
//if(0x3A01 == supbook_cch)
//{
// if(!body)
// {
// body = BiffStructurePtr(new AddinUdf);
// }
//}
//else
//{
//}
_UINT16 supbook_cch;
bool bOleVirtualPath;
};
typedef boost::shared_ptr<ExternName> ExternNamePtr;
......
......@@ -58,14 +58,14 @@ void ExternSheet::readFields(CFRecord& record)
if (record.getGlobalWorkbookInfo()->Version < 0x0600)
{
unsigned char type;
//record.skipNunBytes(record.getDataSize() - record.getRdPtr());
ShortXLAnsiString stName;
record >> type >> stName;
std::wstring name = stName.value();
//int type = stName.value().substr(0, 1).c_str()[0];
if (!name.empty())
record.getGlobalWorkbookInfo()->arExternalNames.push_back(name);
name = stName.value();
//int type = stName.value().substr(0, 1).c_str()[0];
//if (!name.empty())
// record.getGlobalWorkbookInfo()->arExternalNames.push_back(name);
}
else
......
......@@ -32,13 +32,11 @@
#pragma once
#include "BiffRecord.h"
#include <Logic/Biff_structures/XTI.h>
#include "../Biff_structures/XTI.h"
namespace XLS
{
// Logical representation of ExternSheet record in BIFF8
class ExternSheet: public BiffRecord
{
BIFF_RECORD_DEFINE_TYPE_INFO(ExternSheet)
......@@ -48,15 +46,15 @@ public:
~ExternSheet();
BaseObjectPtr clone();
void readFields(CFRecord& record);
static const ElementType type = typeExternSheet;
static const ElementType type = typeExternSheet;
//-----------------------------
ForwardOnlyParam<_UINT16> cXTI;
BiffStructurePtrVector rgXTI;
_UINT16 cXTI;
BiffStructurePtrVector rgXTI;
//------------------------------------------------
std::wstring name; //biff5
};
} // namespace XLS
......
......@@ -52,7 +52,7 @@ BaseObjectPtr ObProj::clone()
void ObProj::readFields(CFRecord& record)
{
// the tag doesn't contain data
//vba present in file .. выше .. по наличию собствено стороджа
}
} // namespace XLS
......
......@@ -36,8 +36,6 @@
namespace XLS
{
// Logical representation of ObProj record in BIFF8
class ObProj: public BiffRecord
{
BIFF_RECORD_DEFINE_TYPE_INFO(ObProj)
......@@ -47,13 +45,10 @@ public:
~ObProj();
BaseObjectPtr clone();
void readFields(CFRecord& record);
static const ElementType type = typeObProj;
};
} // namespace XLS
......
......@@ -32,13 +32,10 @@
#pragma once
#include "BiffRecord.h"
#include <Logic/Biff_structures/SheetId.h>
#include "../Biff_structures/SheetId.h"
namespace XLS
{
// Logical representation of RRTabId record in BIFF8
class RRTabId: public BiffRecord
{
BIFF_RECORD_DEFINE_TYPE_INFO(RRTabId)
......@@ -48,7 +45,6 @@ public:
~RRTabId();
BaseObjectPtr clone();
void readFields(CFRecord& record);
......
......@@ -36,8 +36,6 @@
namespace XLS
{
// Logical representation of RecalcId record in BIFF8
class RecalcId: public BiffRecord
{
BIFF_RECORD_DEFINE_TYPE_INFO(RecalcId)
......@@ -47,16 +45,12 @@ public:
~RecalcId();
BaseObjectPtr clone();
void readFields(CFRecord& record);
static const ElementType type = typeRecalcId;
//-----------------------------
_UINT32 dwBuild;
};
} // namespace XLS
......
......@@ -35,7 +35,7 @@
namespace XLS
{
SupBook::SupBook()
SupBook::SupBook() : bOleLink(false), bSimple(false), bPath(false)
{
}
......@@ -55,20 +55,131 @@ void SupBook::readFields(CFRecord& record)
record >> ctab >> cch;
if(0x0001 <= cch && 0x00ff >= cch)
{
virtPath.setSize(cch);
record >> virtPath;
//virtPath.EscapeUrlW(); //todooo проверить спец символы !!!
//if(virtPath.isConformToVirtPath() && !virtPath.isConformToOleLink())
XLUnicodeStringNoCch temp;
temp.setSize(cch);
record >> temp;
origin = temp.value();
while(!record.isEOF())
{
record >> rgst;
XLUnicodeString temp2;
record >> temp2;
rgst.push_back(temp2.value());
}
}
}
//virt-path = volume / unc-volume / rel-volume / transfer-protocol / startup / alt-startup / library / simple-file-path / ole-link
//ole-link = path-string %x0003 path-string
//simple-file-path = [%x0001]
//file-path startup = %x0001 %x0006 file-path
//alt-startup = %x0001 %x0007 file-path
//library = %x0001 %x0008 file-path
//transfer-protocol = %x0001 %x0005 count transfer-path
//transfer-path = transfer-base-path / "[" transfer-base-path "]" sheet-name
//transfer-base-path = transfer-type "://" file-path
//transfer-type = "ftp" / "http" / "https"
//rel-volume = %x0001 %x0002 file-path
//...
bool bFilePathType = false;
if (!origin.empty())
{
std::wstring sTmp = origin;
const unsigned short SupBook::getSupportingLinkType() const
{
return cch;
while(true)
{
int pos = sTmp.find(L"\x0001");
if (pos >= 0)
{
if (bSimple)
{
bFilePathType = true;
bPath = true; //xls_result.xls
}
else bSimple = true; //file name or file path
virtPath.push_back(sTmp.substr(0, pos));
sTmp = sTmp.substr(pos + 1);
continue;
}
pos = sTmp.find(L"\x0002");
if (pos >= 0)
{
if (bSimple)
bPath = true;
virtPath.push_back(sTmp.substr(0, pos));
sTmp = sTmp.substr(pos + 1);
continue;
}
pos = sTmp.find(L"\x0003");
if (pos >= 0)
{
if (bPath)
{
if (bFilePathType)
{
virtPath.back() += L"file:///" + sTmp.substr(0, 1) + L":\\" + sTmp.substr(1, pos - 1);
bFilePathType = false;
}
else
virtPath.back() += L"/" + sTmp.substr(0, pos);
}
else
{
bOleLink = true;
virtPath.push_back(sTmp.substr(0, pos));
}
sTmp = sTmp.substr(pos + 1);
continue;
}
pos = sTmp.find(L"\x0004");
if (pos >= 0)
{
virtPath.push_back(sTmp.substr(0, pos));
sTmp = sTmp.substr(pos + 1);
continue;
}
pos = sTmp.find(L"\x0005");
if (pos >= 0)
{
virtPath.push_back(sTmp.substr(0, pos));
//skip http size
sTmp = sTmp.substr(pos + 2);
continue;
}
pos = sTmp.find(L"\x0006");
if (pos >= 0)
{
virtPath.push_back(sTmp.substr(0, pos));
sTmp = sTmp.substr(pos + 1);
continue;
}
pos = sTmp.find(L"\x0007");
if (pos >= 0)
{
virtPath.push_back(sTmp.substr(0, pos));
sTmp = sTmp.substr(pos + 1);
continue;
}
pos = sTmp.find(L"\x0008");
if (pos >= 0)
{
virtPath.push_back(sTmp.substr(0, pos));
sTmp = sTmp.substr(pos + 1);
continue;
}
break;
}
if (bPath)
{
virtPath.back() += L"/" + sTmp;
}
else
{
virtPath.push_back(sTmp);
}
}
}
......
......@@ -37,8 +37,6 @@
namespace XLS
{
// Logical representation of SupBook record in BIFF8
class SupBook: public BiffRecord
{
BIFF_RECORD_DEFINE_TYPE_INFO(SupBook)
......@@ -47,22 +45,23 @@ public:
SupBook();
~SupBook();
const unsigned short getSupportingLinkType() const;
BaseObjectPtr clone();
void readFields(CFRecord& record);
static const ElementType type = typeSupBook;
_UINT16 ctab;
_UINT16 cch;
std::wstring origin;
std::vector<std::wstring> rgst;
//-----------------------------
_UINT16 ctab;
_UINT16 cch;
XLUnicodeStringNoCch virtPath;
XLUnicodeString rgst;
std::vector<std::wstring> virtPath;
bool bOleLink;
bool bSimple;
bool bPath;
};
typedef boost::shared_ptr<SupBook> SupBookPtr;
......
......@@ -35,9 +35,6 @@
namespace XLS
{
// Logical representation of UsesELFs record in BIFF8
class UsesELFs: public BiffRecord
{
BIFF_RECORD_DEFINE_TYPE_INFO(UsesELFs)
......@@ -47,15 +44,12 @@ public:
~UsesELFs();
BaseObjectPtr clone();
void readFields(CFRecord& record);
static const ElementType type = typeUsesELFs;
static const ElementType type = typeUsesELFs;
//-----------------------------
Boolean<unsigned short> useselfs;
};
} // namespace XLS
......
......@@ -36,8 +36,6 @@
namespace XLS
{
// Logical representation of XCT record in BIFF8
class XCT: public BiffRecord
{
BIFF_RECORD_DEFINE_TYPE_INFO(XCT)
......@@ -50,9 +48,8 @@ public:
void readFields(CFRecord& record);
static const ElementType type = typeXCT;
static const ElementType type = typeXCT;
//-----------------------------
_UINT16 ccrn;
_UINT16 itab;
bool itab_exist;
......
......@@ -46,7 +46,6 @@ void AddinUdf::load(CFRecord& record)
{
record.skipNunBytes(4); // reserved
record >> udfName;
record.getGlobalWorkbookInfo()->AddinUdfs.push_back(udfName);
unsigned short cb;
record >> cb;
......
......@@ -32,7 +32,7 @@
#pragma once
#include "BiffStructure.h"
#include <Logic/Biff_structures/BiffString.h>
#include "BiffString.h"
namespace XLS
{
......@@ -47,8 +47,7 @@ public:
virtual void load(CFRecord& record);
static const ElementType type = typeAddinUdf;
static const ElementType type = typeAddinUdf;
ShortXLUnicodeString udfName;
};
......
......@@ -33,7 +33,7 @@
#include "BiffStructure.h"
#include "CellRef.h"
#include <Logic/Biff_structures/BitMarkedStructs.h>
#include "BitMarkedStructs.h"
namespace XLS
{
......@@ -51,7 +51,6 @@ public:
virtual void load(CFRecord& record);
const CellRef getLocation() const;
static const ElementType type = typeCell;
......
......@@ -32,7 +32,7 @@
#pragma once
#include "BiffStructure.h"
#include <Logic/Biff_structures/BiffString.h>
#include "BiffString.h"
namespace XLS
{
......@@ -47,7 +47,6 @@ public:
virtual void load(CFRecord& record);
static const ElementType type = typeExternDdeLinkNoOper;
ShortXLUnicodeString linkName;
......
......@@ -48,6 +48,7 @@ void ExternDocName::load(CFRecord& record)
record >> ixals;
record.skipNunBytes(2); // reserved
record >> extName;
nameDefinition.load(record);
}
......
......@@ -31,9 +31,8 @@
*/
#pragma once
#include "BiffStructure.h"
#include <Logic/Biff_structures/ExtNameParsedFormula.h>
#include <Logic/Biff_structures/BiffString.h>
#include "ExtNameParsedFormula.h"
#include "BiffString.h"
namespace XLS
{
......@@ -50,7 +49,6 @@ public:
virtual void load(CFRecord& record);
unsigned short ixals;
ShortXLUnicodeString extName;
ExtNameParsedFormula nameDefinition;
......
......@@ -32,8 +32,8 @@
#pragma once
#include "BiffStructure.h"
#include <Logic/Biff_structures/MOper.h>
#include <Logic/Biff_structures/BiffString.h>
#include "MOper.h"
#include "BiffString.h"
namespace XLS
{
......@@ -48,7 +48,6 @@ public:
virtual void load(CFRecord& record);
static const ElementType type = typeExternOleDdeLink;
_UINT32 lStgName;
......
......@@ -32,11 +32,11 @@
#include "MOper.h"
#include <Binary/CFRecord.h>
#include <simple_xml_writer.h>
namespace XLS
{
BiffStructurePtr MOper::clone()
{
return BiffStructurePtr(new MOper(*this));
......@@ -45,16 +45,52 @@ BiffStructurePtr MOper::clone()
void MOper::load(CFRecord& record)
{
record >> colLast >> rowLast;
for(int i = 0; i < (colLast + 1) * (rowLast + 1); ++i)
{
unsigned char rec_type;
record >> rec_type;
SerArPtr ser(SerAr::createSerAr(rec_type));
record >> *ser;
extOper.push_back(ser);
}
}
int MOper::serialize(std::wostream & strm)
{
if (extOper.empty()) return 0;
CP_XML_WRITER(strm)
{
CP_XML_NODE(L"values")
{
for(size_t i = 0; i < extOper.size(); ++i)
{
CP_XML_NODE(L"value")
{
switch(extOper[i]->fixed_type)
{
case SerAr::typeSerNil: CP_XML_ATTR(L"t", L"nil"); break;
case SerAr::typeSerNum: CP_XML_ATTR(L"t", L"n"); break;
case SerAr::typeSerStr: CP_XML_ATTR(L"t", L"str"); break;
case SerAr::typeSerBool: CP_XML_ATTR(L"t", L"b"); break;
case SerAr::typeSerErr: CP_XML_ATTR(L"t", L"e"); break;
}
CP_XML_NODE(L"val")
{
if (extOper[i]->fixed_type == SerAr::typeSerStr)
{
CP_XML_ATTR(L"xml:space", L"preserve");
}
CP_XML_STREAM() << extOper[i]->toString();
}
}
}
}
}
return 0;
}
} // namespace XLS
......@@ -32,8 +32,8 @@
#pragma once
#include "BiffStructure.h"
#include <Logic/Biff_structures/SerAr.h>
#include <Logic/Biff_structures/BitMarkedStructs.h>
#include "SerAr.h"
#include "BitMarkedStructs.h"
namespace XLS
{
......@@ -49,7 +49,7 @@ public:
static const ElementType type = typeMOper;
virtual void load(CFRecord& record);
int serialize(std::wostream & strm);
ColunByteU colLast;
RwU rowLast;
......
......@@ -111,6 +111,7 @@ void PtgArea3d::assemble(AssemblerStack& ptg_stack, PtgQueue& extra_data, bool f
if (global_info->Version < 0x0600)
{
ixti = ixals;
if (ixals == 0xffff)
{
std::wstring prefix = XMLSTUFF::xti_indexes2sheet_name(itabFirst, itabLast, global_info->sheets_names);
......@@ -118,14 +119,14 @@ void PtgArea3d::assemble(AssemblerStack& ptg_stack, PtgQueue& extra_data, bool f
ptg_stack.push(prefix + range_ref);
}
else
{//external !!
ptg_stack.push(XMLSTUFF::make3dRef(ixals, range_ref, global_info->xti_parsed, full_ref));
}
}
else
if (ixti != 0xffff)
{
ptg_stack.push(XMLSTUFF::make3dRef(ixti, range_ref, global_info->xti_parsed, full_ref));
std::wstring link = global_info->arXti[ixti].link;
if (!link.empty() && !range_ref.empty())
link += L"!";
ptg_stack.push(link + range_ref); // full_ref ???
}
}
......
......@@ -46,9 +46,10 @@ BiffStructurePtr PtgAreaErr3d::clone()
void PtgAreaErr3d::loadFields(CFRecord& record)
{
global_info = record.getGlobalWorkbookInfo();
record >> ixti;
record.skipNunBytes(8); // unused
global_info = record.getGlobalWorkbookInfo();
}
......@@ -62,9 +63,11 @@ void PtgAreaErr3d::assemble(AssemblerStack& ptg_stack, PtgQueue& extra_data, boo
extra_data.pop();
return;
}
ptg_stack.push(XMLSTUFF::make3dRef(ixti, L"#REF!", global_info->xti_parsed));
std::wstring link = global_info->arXti[ixti].link;
if (!link.empty())
link += L"!";
ptg_stack.push(link + L"#REF!"); // full_ref ???
}
......
......@@ -79,6 +79,7 @@ void PtgNameX::loadFields(CFRecord& record)
void PtgNameX::assemble(AssemblerStack& ptg_stack, PtgQueue& extra_data, bool full_ref)
{
RevNamePtr tab_id;
if(!extra_data.empty() && (tab_id = boost::dynamic_pointer_cast<RevName>(extra_data.front())))
{
Log::error("PtgNameX struct for revisions is not assemble.");
......@@ -87,39 +88,32 @@ void PtgNameX::assemble(AssemblerStack& ptg_stack, PtgQueue& extra_data, bool fu
return;
}
std::wstring _Name;
if(nameindex > 0 && nameindex <= global_info->AddinUdfs.size() && !(_Name = global_info->AddinUdfs[nameindex - 1]).empty())
{
ptg_stack.push(_Name);
}
else if(ixti > 0 && ixti <= global_info->xti_parsed.size())
if(ixti >= 0 && ixti < global_info->arXti.size())
{
std::wstring sheet = global_info->xti_parsed[ixti-1];
std::wstring link = global_info->arXti[ixti].link;
std::wstring name;
if (!sheet.empty()) sheet += L"!";
if (nameindex > 0 && nameindex <= global_info->arDefineNames.size())
if (global_info->arXti[ixti].pNames && nameindex > 0)
{
_Name = global_info->arDefineNames[nameindex - 1];
name = global_info->arXti[ixti].pNames->at(nameindex - 1);
}
if (sheet.empty() && _Name.empty() && nameindex <= global_info->arExternalNames.size() && nameindex > 0)
if (!link.empty() && !name.empty())
{
_Name = global_info->arExternalNames[nameindex - 1];
ptg_stack.push(link + L"!" + name);
}
ptg_stack.push(sheet + _Name);
else if (!name.empty())
{
ptg_stack.push(name);
}
else
ptg_stack.push(link);
}
else
{
Log::warning("PtgNameX structure is not assemble.");
//ptg_stack.push(L"#UNDEFINED_EXTERN_NAME(" + STR::int2wstr(nameindex) + L")!");
ptg_stack.push(L""); // This would let us to continue without an error
ptg_stack.push(L"");
}
// Example of result: "[1]!range"
// in the formula window it looks like: "'D:\Projects\AVSWorksheetConverter\bin\InFiles\Blank2003_range.xls'!range"
}
......
......@@ -106,6 +106,7 @@ void PtgRef3d::assemble(AssemblerStack& ptg_stack, PtgQueue& extra_data, bool fu
if (global_info->Version < 0x0600)
{
ixti = ixals;
if (ixals == 0xffff)
{
std::wstring prefix = XMLSTUFF::xti_indexes2sheet_name(itabFirst, itabLast, global_info->sheets_names);
......@@ -113,15 +114,14 @@ void PtgRef3d::assemble(AssemblerStack& ptg_stack, PtgQueue& extra_data, bool fu
ptg_stack.push(prefix + cell_ref);
}
else
{
ptg_stack.push(XMLSTUFF::make3dRef(ixals, cell_ref, global_info->xti_parsed, full_ref)); // from External !
}
}
else
if (ixti != 0xffff)
{
cell_ref = XMLSTUFF::make3dRef(ixti, cell_ref, global_info->xti_parsed, full_ref);
ptg_stack.push(cell_ref);
std::wstring link = global_info->arXti[ixti].link;
if (!link.empty() && !cell_ref.empty())
link += L"!";
ptg_stack.push(link + cell_ref); // full_ref ???
}
}
......
......@@ -57,9 +57,10 @@ BiffStructurePtr PtgRefErr3d::clone()
void PtgRefErr3d::loadFields(CFRecord& record)
{
global_info = record.getGlobalWorkbookInfo();
record >> ixti;
record.skipNunBytes(4); // unused
global_info = record.getGlobalWorkbookInfo();
}
......@@ -75,7 +76,14 @@ void PtgRefErr3d::assemble(AssemblerStack& ptg_stack, PtgQueue& extra_data, bool
return;
}
ptg_stack.push(XMLSTUFF::make3dRef(ixti, L"#REF!", global_info->xti_parsed));
if (ixti != 0xffff)
{
std::wstring link = global_info->arXti[ixti].link;
if (!link.empty())
link += L"!";
ptg_stack.push(link + L"#REF!"); // full_ref ???
}
}
......
......@@ -56,7 +56,7 @@ public:
virtual const std::wstring toString() const = 0;
static const ElementType type = typeSerAr;
static const ElementType type = typeSerAr;
SerType fixed_type;
};
......
......@@ -32,7 +32,7 @@
#pragma once
#include "SerAr.h"
#include <Logic/Biff_structures/BiffString.h>
#include "BiffString.h"
namespace XLS
{
......
......@@ -31,6 +31,10 @@
*/
#include "XTI.h"
#include "../GlobalsSubstream.h"
#include "../Biff_unions/SUPBOOK.h"
#include "../Biff_records/SupBook.h"
#include <Binary/CFRecord.h>
namespace XLS
......@@ -48,17 +52,6 @@ void XTI::load(CFRecord& record)
return;
record >> iSupBook >> itabFirst >> itabLast;
if (itabFirst < 0 && itabLast < 0)
{
record.getGlobalWorkbookInfo()->xti_parsed.push_back(L"");
}
else
{
std::wstring name = XMLSTUFF::xti_indexes2sheet_name(itabFirst, itabLast, record.getGlobalWorkbookInfo()->sheets_names);
if (name == L"#REF") name += L"!";
record.getGlobalWorkbookInfo()->xti_parsed.push_back( name );
}
}
......
......@@ -48,7 +48,6 @@ public:
virtual void load(CFRecord& record);
unsigned short iSupBook;
short itabFirst;
short itabLast;
......
......@@ -72,7 +72,7 @@ const bool DVAXIS::loadContentRead(BinReaderProcessor& proc)
bool ok = loadContent(proc);
if(ok)
{
id = proc.getGlobalWorkbookInfo()->GenerateAXESId();
id = proc.getGlobalWorkbookInfo()->last_Axes_id++;
}
return ok;
}
......
......@@ -67,7 +67,6 @@ public:
BaseObjectPtr m_TABLESTYLES;
BaseObjectPtr m_THEME;
GlobalWorkbookInfoPtr global_info;
};
......
......@@ -105,7 +105,7 @@ const bool FORMULA::loadContent(BinProcessor& proc)
m_sharedIndex = shared_formulas_locations_ref_.size();
shared_formulas_locations_ref_.push_back(shr_formula.ref_);
}
//proc.optional<SUB>(); // I haven't found any mention about SUB in the docs
//proc.optional<SUB>();
}
if ((formula) && (formula->fShrFmla))
......
......@@ -67,7 +67,7 @@ const bool IVAXIS::loadContentRead(BinReaderProcessor& proc)
bool ok = loadContent(proc);
if(ok)
{
id = proc.getGlobalWorkbookInfo()->GenerateAXESId();
id = proc.getGlobalWorkbookInfo()->last_Axes_id++;
}
return ok;
}
......
......@@ -36,8 +36,6 @@
namespace XLS
{
// Logical representation of LBL union of records
class LBL: public CompositeObject
{
BASE_OBJECT_DEFINE_CLASS_NAME(LBL)
......@@ -51,13 +49,14 @@ public:
int serialize(std::wostream & stream);
static const ElementType type = typeLBL;
static const ElementType type = typeLBL;
BaseObjectPtr m_Lbl;
BaseObjectPtr m_Lbl;
BaseObjectPtr m_NamePublish;
BaseObjectPtr m_NameCmt;
BaseObjectPtr m_NameFnGrp12;
//-------------------------------------------------------
bool isSerialize;
};
} // namespace XLS
......
......@@ -76,65 +76,26 @@ const bool LBL::loadContent(BinProcessor& proc)
if (!lbl) return false;
std::wstring name;
std::wstring comment;
if (lbl->fBuiltin) name = lbl->Name.value().get_value_or(L"");
if (name.empty()) name = lbl->Name_bin.value();
std::wstring value = lbl->rgce.getAssembledFormula(lbl->fWorkbookParam/*lbl->itab == 0 ? true : false*/);
NameCmt namecmt(name);
if (proc.optional(namecmt))
{
if (name.empty())
name = namecmt.name.value();
comment = namecmt.comment.value();
m_NameCmt = elements_.back();
elements_.pop_back();
}
if (proc.optional<NameFnGrp12>())
{
m_NameFnGrp12 = elements_.back();
elements_.pop_back();
}
if (proc.optional<NamePublish>())
{
m_NamePublish = elements_.back();
elements_.pop_back();
}
GlobalWorkbookInfoPtr global_info_ = proc.getGlobalWorkbookInfo();
if (!value.empty() && !name.empty())
{
int ind_sheet = lbl->itab;
std::map<std::wstring, std::vector<std::wstring>>::iterator it = global_info_->mapDefineNames.find(name);
if (it != global_info_->mapDefineNames.end())
{
while ( it->second.size() <= ind_sheet)
{
it->second.push_back(L"");
}
it->second[ind_sheet] = value;
//it->second.push_back(value);
}
else
{
std::vector<std::wstring> ar(ind_sheet + 1);
ar[ind_sheet] = value;
//ar.push_back(value);
global_info_->mapDefineNames.insert(std::make_pair(name, ar));
}
isSerialize = true;
}
else
{
if (lbl->fFunc)
{
if (name == L"FORMULA") //"general_formulas.xls"
name = L"_xludf." + name;
}
}
global_info_->arDefineNames.push_back(name);// для имен функций - todooo ... не все функции корректны !! БДИ !!
return true;
}
int LBL::serialize(std::wostream & stream)
......@@ -149,7 +110,7 @@ int LBL::serialize(std::wostream & stream)
int res = 0;
if ((lbl->itab == 0) && (res = value.find(L"#REF!")) >= 0)
if ((lbl->itab == 0) && (res = value.find(L"#REF")) >= 0)
{
for (size_t i = 0 ; i < lbl->rgce.rgce.sequence.size(); i++)
{
......@@ -171,6 +132,8 @@ int LBL::serialize(std::wostream & stream)
}
}
if (value == L"#REF") value = L"#REF!";
CP_XML_WRITER(stream)
{
CP_XML_NODE(L"definedName")
......@@ -189,6 +152,10 @@ int LBL::serialize(std::wostream & stream)
{
CP_XML_ATTR(L"localSheetId", lbl->itab - 1);
}
if (lbl->fHidden)
{
CP_XML_ATTR(L"hidden", 1);
}
CP_XML_STREAM() << xml::utils::replace_text_to_xml(value);
}
......
......@@ -83,6 +83,7 @@ int PIVOTPI::serialize(std::wostream & strm)
}
}
}
return 0;
}
} // namespace XLS
......@@ -64,7 +64,7 @@ const bool SERIESAXIS::loadContentRead(BinReaderProcessor& proc)
bool ok = loadContent(proc);
if(ok)
{
id = proc.getGlobalWorkbookInfo()->GenerateAXESId();
id = proc.getGlobalWorkbookInfo()->last_Axes_id++;
}
return ok;
}
......
......@@ -31,17 +31,21 @@
*/
#pragma once
#include <Logic/CompositeObject.h>
#include "../CompositeObject.h"
namespace XLS
{
// Logical representation of SUPBOOK union of records
class SUPBOOK: public CompositeObject
{
BASE_OBJECT_DEFINE_CLASS_NAME(SUPBOOK)
public:
struct _xct
{
BaseObjectPtr m_XCT;
std::vector<BaseObjectPtr> m_arCRN;
};
SUPBOOK();
~SUPBOOK();
......@@ -49,11 +53,27 @@ public:
virtual const bool loadContent(BinProcessor& proc);
static const ElementType type = typeSUPBOOK;
int serialize(std::wostream & strm);
static const ElementType type = typeSUPBOOK;
BaseObjectPtr m_SupBook;
BaseObjectPtr m_ExternSheet;
BaseObjectPtr m_SupBook;
BaseObjectPtr m_ExternSheet;
std::vector<BaseObjectPtr> m_arExternName;
std::vector<_xct> m_arXCT;
GlobalWorkbookInfoPtr global_info;
std::vector<std::wstring> arNames;
bool IsExternal();
std::wstring sExternPathLink;
int nExternIndex;
private:
int serialize_book(std::wostream & strm);
int serialize_dde(std::wostream & strm);
};
} // namespace XLS
......
......@@ -31,25 +31,22 @@
*/
#include "SUPBOOK.h"
#include <Logic/Biff_records/SupBook.h>
#include <Logic/Biff_records/ExternName.h>
#include <Logic/Biff_records/ExternSheet.h>
#include <Logic/Biff_records/Continue.h>
#include <Logic/Biff_records/XCT.h>
#include <Logic/Biff_records/CRN.h>
namespace XLS
{
#include "../Biff_records/SupBook.h"
#include "../Biff_records/ExternName.h"
#include "../Biff_records/ExternSheet.h"
#include "../Biff_records/Continue.h"
#include "../Biff_records/XCT.h"
#include "../Biff_records/CRN.h"
SUPBOOK::SUPBOOK()
namespace XLS
{
}
SUPBOOK::SUPBOOK() : nExternIndex(-1)
{}
SUPBOOK::~SUPBOOK()
{
}
{}
class Parenthesis_SUPBOOK_1: public ABNFParenthesis
{
......@@ -82,6 +79,8 @@ BaseObjectPtr SUPBOOK::clone()
// SUPBOOK = SupBook [*ExternName *(XCT *CRN)] [ExternSheet] *Continue
const bool SUPBOOK::loadContent(BinProcessor& proc)
{
global_info = proc.getGlobalWorkbookInfo();
SupBook supbook;
if(!proc.mandatory(supbook))
{
......@@ -90,30 +89,292 @@ const bool SUPBOOK::loadContent(BinProcessor& proc)
m_SupBook = elements_.back();
elements_.pop_back();
if (supbook.cch != 0x0401 && supbook.cch != 0x3A01 )
if(0x3A01 != supbook.cch && 0x0401 != supbook.cch)
{
proc.getGlobalWorkbookInfo()->arExternalNames.clear();
nExternIndex = global_info->last_Extern_id++;
}
while(true)
{
ExternName extern_name(supbook.getSupportingLinkType());
ExternName extern_name(supbook.cch, supbook.bOleLink);
if(!proc.optional(extern_name))
{
break;
}
m_arExternName.push_back(elements_.front()); elements_.pop_front();
//--------------------------------------------------------------------------------------------
std::wstring name;
ExternDocName* docName = dynamic_cast<ExternDocName*>(extern_name.body.get());
if(docName)
{
if (docName->ixals > 0 && !supbook.rgst.empty())
{
name = supbook.rgst[docName->ixals];
}
else
{
name = docName->nameDefinition.getAssembledFormula();
if (name.empty())
{
name = docName->extName.value();
}
}
}
ExternDdeLinkNoOper* ddeLink = dynamic_cast<ExternDdeLinkNoOper*>(extern_name.body.get());
if (ddeLink)
{
name = ddeLink->linkName.value();
}
ExternOleDdeLink* oleDdeLink = dynamic_cast<ExternOleDdeLink*>(extern_name.body.get());
if (oleDdeLink)
{
name = oleDdeLink->linkName.value();
}
AddinUdf *addinUdf = dynamic_cast<AddinUdf*>(extern_name.body.get());
if (addinUdf)
{
name = addinUdf->udfName.value(); //_xll.name(
}
if ( std::wstring::npos != name.find(L";") )
name = L"'" + name + L"'";
arNames.push_back(name);
}
int count = proc.repeated<Parenthesis_SUPBOOK_1>(0, 0);
while(!elements_.empty())
{
if ("XCT" == elements_.front()->getClassName())
{
_xct xcf;
xcf.m_XCT = elements_.front();
count--;
m_arXCT.push_back(xcf);
}
else
{
if (m_arXCT.empty())
{
break; // error !!!
}
m_arXCT.back().m_arCRN.push_back(elements_.front());
}
elements_.pop_front();
}
if (proc.optional<ExternSheet>())
{
m_ExternSheet = elements_.back();
elements_.pop_back();
}
//proc.repeated<Continue>(0, 0);
return true;
}
bool SUPBOOK::IsExternal()
{
SupBook *book = dynamic_cast<SupBook*>(m_SupBook.get());
if (!book) return false;
if(0x3A01 == book->cch || 0x0401 == book->cch)
{
return false;
}
return true;
}
int SUPBOOK::serialize(std::wostream & strm)
{
SupBook *book = dynamic_cast<SupBook*>(m_SupBook.get());
if (!book) return 0;
if(0x3A01 == book->cch || 0x0401 == book->cch)
{
return 0;
}
if (book->bOleLink)
{
serialize_dde(strm);
}
else
{
serialize_book(strm);
}
return 0;
}
int SUPBOOK::serialize_book(std::wostream & strm)
{
SupBook *book = dynamic_cast<SupBook*>(m_SupBook.get());
CP_XML_WRITER(strm)
{
CP_XML_NODE(L"externalBook")
{
CP_XML_ATTR(L"xmlns:r", L"http://schemas.openxmlformats.org/officeDocument/2006/relationships");
CP_XML_ATTR(L"r:id", L"rId1");
sExternPathLink = book->virtPath.back();
if (!m_arXCT.empty() && !book->rgst.empty())
{
CP_XML_NODE(L"sheetNames")
{
for (size_t i = 0; i < m_arXCT.size(); i++)
{
CP_XML_NODE(L"sheetName")
{
std::wstring sheet;
XCT * name = dynamic_cast<XCT*>(m_arXCT[i].m_XCT.get());
if ((name) && (name->itab_exist))
sheet = book->rgst[name->itab];
else
sheet = L"Sheet " + std::to_wstring(i + 1);
CP_XML_ATTR(L"val", sheet);
}
}
}
CP_XML_NODE(L"sheetDataSet")
{
for (size_t i = 0; i < m_arXCT.size(); i++)
{
XCT * name = dynamic_cast<XCT*>(m_arXCT[i].m_XCT.get());
if (!name) continue;
CP_XML_NODE(L"sheetData")
{
CP_XML_ATTR(L"sheetId", i);
int current_row = -1;
for (size_t j = 0; j < m_arXCT[i].m_arCRN.size(); j++)
{
CRN * cell = dynamic_cast<CRN*>(m_arXCT[i].m_arCRN[j].get());
if (!cell) continue;
if (cell->row != current_row)
{
CP_XML_NODE(L"row")
{
current_row = cell->row;
CP_XML_ATTR(L"r", cell->row + 1);
for (size_t k = j; k < m_arXCT[i].m_arCRN.size(); k++)
{
cell = dynamic_cast<CRN*>(m_arXCT[i].m_arCRN[k].get());
if (cell->row != current_row)
{
j = k - 1;
break;
}
for (unsigned char col = cell->colFirst, v = 0; col <= cell->colLast; col++, v++)
{
CP_XML_NODE(L"cell")
{
SerAr* val = dynamic_cast<SerAr*>(cell->crnOper[v].get());
CellRef ref(cell->row, col, true, true);
CP_XML_ATTR(L"r", ref.toString());
std::wstring strVal = val->toString();
if (val->fixed_type == SerAr::typeSerStr)
{
if (0 == strVal.find(L"\""))
strVal = strVal.substr(1, strVal.length() - 2);
}
switch (val->fixed_type)
{
case SerAr::typeSerNil: CP_XML_ATTR(L"t", L"nil"); break;
case SerAr::typeSerNum: CP_XML_ATTR(L"t", L"n"); break;
case SerAr::typeSerStr: CP_XML_ATTR(L"t", L"str"); break;
case SerAr::typeSerBool: CP_XML_ATTR(L"t", L"b"); break;
case SerAr::typeSerErr: CP_XML_ATTR(L"t", L"e"); break;
}
CP_XML_NODE(L"v")
{
CP_XML_STREAM() << strVal;
}
}
}
}
}
}
}
}
}
}
}
else if (!book->rgst.empty())
{
CP_XML_NODE(L"sheetNames")
{
for (size_t i = 0; i < book->rgst.size(); i++)
{
CP_XML_NODE(L"sheetName")
{
CP_XML_ATTR(L"val", book->rgst[i]);
}
}
}
CP_XML_NODE(L"sheetDataSet")
{
for (size_t i = 0; i < book->rgst.size(); i++)
{
CP_XML_NODE(L"sheetData")
{
CP_XML_ATTR(L"sheetId", i);
CP_XML_ATTR(L"refreshError", 1);
}
}
}
}
}
}
return 0;
}
int SUPBOOK::serialize_dde(std::wostream & strm)
{
SupBook *book = dynamic_cast<SupBook*>(m_SupBook.get());
CP_XML_WRITER(strm)
{
CP_XML_NODE(L"ddeLink")
{
CP_XML_ATTR(L"xmlns:r", L"http://schemas.openxmlformats.org/officeDocument/2006/relationships");
CP_XML_ATTR(L"ddeService", book->virtPath[0]);
CP_XML_ATTR(L"ddeTopic", book->virtPath[1]);
CP_XML_NODE(L"ddeItems")
{
for (size_t i = 0; i < m_arExternName.size(); i++)
{
ExternName * external_name = dynamic_cast<ExternName*>(m_arExternName[i].get());
if (!external_name) continue;
ExternOleDdeLink *oleDdeLink = dynamic_cast<ExternOleDdeLink*>(external_name->body.get());
if ((oleDdeLink) && (oleDdeLink->lStgName == 0))
{
CP_XML_NODE(L"ddeItem")
{
CP_XML_ATTR(L"name", oleDdeLink->linkName.value());
CP_XML_ATTR(L"advise", external_name->fWantAdvise);
oleDdeLink->moper.serialize(CP_XML_STREAM());
}
}
//ole items in oleLink
}
}
}
}
return 0;
}
} // namespace XLS
......@@ -100,7 +100,8 @@ GlobalWorkbookInfo::GlobalWorkbookInfo(const unsigned short code_page, XlsConver
fill_x_ids[FillInfo(0, 0, 0)] = 0;
fill_x_ids[FillInfo(17, 64, 65)] = 1;
last_AXES_id = initial_AXES_id;
last_Axes_id = 0x2000000;
last_Extern_id = 1;
Version = 0x0600;
......@@ -119,6 +120,9 @@ GlobalWorkbookInfo::GlobalWorkbookInfo(const unsigned short code_page, XlsConver
defaultDigitFontSize = std::pair<float, float>(0, 0);
applicationFonts = NULL;
bVbaProjectExist = false;
bMacrosExist = false;
idPivotCache = 0;
}
......@@ -173,11 +177,6 @@ void GlobalWorkbookInfo::RegisterPaletteColor(int id, const std::wstring & rgb)
colors_palette.insert(std::make_pair(id, rgb));
}
unsigned int GlobalWorkbookInfo::GenerateAXESId()
{
return last_AXES_id += 1;
}
void GlobalWorkbookInfo::GetDigitFontSizePixels()
{
if (defaultDigitFontSize.first > 0.01) return;
......
......@@ -81,81 +81,87 @@ public:
void GetDigitFontSizePixels();
unsigned int GenerateAXESId();
bool bVbaProjectExist;
bool bMacrosExist;
unsigned short CodePage;
CRYPT::DecryptorPtr decryptor;
std::wstring password;
unsigned short CodePage;
CRYPT::DecryptorPtr decryptor;
std::wstring password;
std::vector<std::wstring> sheets_state;
std::vector<std::wstring> sheets_names;
std::vector<std::wstring> xti_parsed;
std::vector<std::wstring> AddinUdfs;
boost::unordered_map<BorderInfo, int> border_x_ids;
boost::unordered_map<FillInfo, int> fill_x_ids;
std::vector<std::wstring> sheets_state;
std::vector<std::wstring> sheets_names;
boost::unordered_map<BorderInfo, int> border_x_ids;
boost::unordered_map<FillInfo, int> fill_x_ids;
std::map<int, FillInfoExt> fonts_color_ext;
std::map<int, int> fonts_charsets;
std::map<int, std::wstring> colors_palette;
std::map<int, FillInfoExt> fonts_color_ext;
std::map<int, int> fonts_charsets;
std::map<int, std::wstring> colors_palette;
std::vector<BaseObjectPtr> *m_arFonts;
std::vector<BaseObjectPtr> *m_arFonts;
unsigned int current_sheet;
unsigned int current_sheet;
unsigned int last_AXES_id;
const static unsigned int initial_AXES_id = 0x2000000;
unsigned int last_Axes_id;
unsigned int last_Extern_id;
short idPivotCache;
std::map<int, int> mapPivotCacheIndex; //streamIdCache, write index order
std::unordered_map<int, BaseObjectPtr> mapPivotCacheStream;//streamIdCache, object
std::vector<int> arPivotCacheStream; //order streamIdCache = iCache
short idPivotCache;
std::map<int, int> mapPivotCacheIndex; //streamIdCache, write index order
std::unordered_map<int, BaseObjectPtr> mapPivotCacheStream;//streamIdCache, object
std::vector<int> arPivotCacheStream; //order streamIdCache = iCache
std::vector<bool> arPivotCacheFields;
std::vector<bool> arPivotCacheFieldShortSize;
std::vector<bool> arPivotCacheFields;
std::vector<bool> arPivotCacheFieldShortSize;
std::vector<_sx_name> arPivotSxNames;
std::vector<std::wstring> arPivotCacheSxNames;
std::vector<_sx_name> arPivotSxNames;
std::vector<std::wstring> arPivotCacheSxNames;
std::unordered_map<std::wstring, std::wstring> mapPivotCacheExternal;
std::map<std::wstring, std::vector<std::wstring>> mapDefineNames;
std::vector<std::wstring> arDefineNames;
std::vector<std::wstring> arExternalNames;
unsigned int startAddedSharedStrings;
std::vector<std::wstring> arAddedSharedStrings;
std::vector<std::pair<boost::shared_array<char>, size_t> > bin_data;
struct _xti
{
int iSup;
std::wstring link;
std::vector<std::wstring>* pNames = NULL;
};
std::vector<_xti> arXti;
unsigned int startAddedSharedStrings;
std::vector<std::wstring> arAddedSharedStrings;
struct _sheet_size_info
{
_sheet_size_info() : defaultColumnWidth(8.), defaultRowHeight (14.4) {}
std::map<int, double> customColumnsWidth;
std::map<int, double> customRowsHeight;
std::map<int, double> customColumnsWidth;
std::map<int, double> customRowsHeight;
double defaultColumnWidth;
double defaultRowHeight;
double defaultColumnWidth = 8.0;
double defaultRowHeight = 14.4;
};
std::vector<_sheet_size_info> sheet_size_info;
std::vector<_sheet_size_info> sheet_size_info;
std::pair<float, float> defaultDigitFontSize;
CApplicationFonts *applicationFonts;
std::wstring fontsDirectory;
std::pair<float, float> defaultDigitFontSize;
CApplicationFonts *applicationFonts;
std::wstring fontsDirectory;
int Version;
int Version;
int cmt_rules;
int cellXfs_count;
int cellStyleXfs_count;
int cellStyleDxfs_count;
int cmt_rules;
int cellXfs_count;
int cellStyleXfs_count;
int cellStyleDxfs_count;
std::wstringstream users_Dxfs_stream;
std::wstringstream connections_stream;
std::wstringstream users_Dxfs_stream;
std::wstringstream connections_stream;
int connectionId;
int connectionId;
XlsConverter *xls_converter;
XlsConverter *xls_converter;
};
......
......@@ -53,7 +53,9 @@ public:
virtual const bool loadContent(BinProcessor& proc);
static const ElementType type = typeGlobalsSubstream;
static const ElementType type = typeGlobalsSubstream;
int serialize_format(std::wostream & _stream);
BaseObjectPtr m_THEME;
BaseObjectPtr m_Formating;
......@@ -64,12 +66,17 @@ public:
BaseObjectPtr m_Country;
BaseObjectPtr m_WriteProtect;
BaseObjectPtr m_PROTECTION;
BaseObjectPtr m_RRTabId;
BaseObjectPtr m_FNGROUPS;
BaseObjectPtr m_BookExt;
BaseObjectPtr m_CodeName;
std::vector<BaseObjectPtr> m_arHFPicture;
std::vector<BaseObjectPtr> m_arLBL;
std::vector<BaseObjectPtr> m_arMSODRAWINGGROUP;
std::vector<BaseObjectPtr> m_arWindow1;
std::vector<BaseObjectPtr> m_arUserBView;
std::vector<BaseObjectPtr> m_arBUNDLESHEET;
std::vector<BaseObjectPtr> m_arSUPBOOK;
std::vector<BaseObjectPtr> m_arPIVOTCACHEDEFINITION;
......@@ -80,6 +87,8 @@ public:
private:
void LoadHFPicture();
void UpdateXti();
void UpdateDefineNames();
};
} // namespace XLS
......@@ -82,7 +82,6 @@ const bool WorkbookStreamObject::loadContent(BinProcessor& proc)
bool WorksheetSubstream_found = false;
size_t ws_index = 0;
// Find all substreams in this stream
while(to_continue)
{
unsigned short substream_type = 0;
......@@ -102,8 +101,8 @@ const bool WorkbookStreamObject::loadContent(BinProcessor& proc)
if((proc.mandatory(global_substream)) && (elements_.size() > 0))
{
GlobalsSubstream_found = true;
m_GlobalsSubstream = elements_.back();
elements_.pop_back();
m_GlobalsSubstream = elements_.back(); elements_.pop_back();
}
if (!GlobalsSubstream_found) return false;
}
......@@ -120,8 +119,8 @@ const bool WorkbookStreamObject::loadContent(BinProcessor& proc)
if ((proc.mandatory(worksheet_substream)) && (elements_.size() > 0))
{
WorksheetSubstream_found = true;
m_arWorksheetSubstream.push_back(elements_.back());
elements_.pop_back();
m_arWorksheetSubstream.push_back(elements_.back()); elements_.pop_back();
}
}
break;
......@@ -136,8 +135,8 @@ const bool WorkbookStreamObject::loadContent(BinProcessor& proc)
if ((proc.mandatory<ChartSheetSubstream>()) && (elements_.size() > 0))
{
WorksheetSubstream_found = true;
m_arWorksheetSubstream.push_back(elements_.back());
elements_.pop_back();
m_arWorksheetSubstream.push_back(elements_.back()); elements_.pop_back();
}
}
break;
......@@ -152,14 +151,17 @@ const bool WorkbookStreamObject::loadContent(BinProcessor& proc)
if ((proc.mandatory<MacroSheetSubstream>()) && (elements_.size() > 0))
{
WorksheetSubstream_found = true;
m_arMacroSheetSubstream.push_back(elements_.back());
elements_.pop_back();
m_arMacroSheetSubstream.push_back(elements_.back()); elements_.pop_back();
}
}
break;
default:
Log::warning("WARNING: Substream of unsupported type " + STR::int2str(substream_type, 10) +
" The substream is skipped! Sorry.");
if (substream_type != 0)
{
Log::warning("WARNING: Substream of unsupported type " + STR::int2str(substream_type, 10) +
" The substream is skipped!");
}
proc.SeekToEOF();
proc.optional<EOF_T>();
......
......@@ -60,28 +60,29 @@
#include "../XlsFormat/Logic/Biff_unions/PIVOTVIEW.h"
#include "../XlsFormat/Logic/Biff_unions/PIVOTCACHE.h"
#include "../XlsFormat/Logic/Biff_unions/PIVOTCACHEDEFINITION.h"
#include <Logic/Biff_records/BkHim.h>
#include <Logic/Biff_records/HLink.h>
#include <Logic/Biff_records/MsoDrawingGroup.h>
#include <Logic/Biff_records/MsoDrawing.h>
#include <Logic/Biff_records/Obj.h>
#include <Logic/Biff_records/TxO.h>
#include <Logic/Biff_records/IMDATA.h>
#include <Logic/Biff_records/Note.h>
#include <Logic/Biff_structures/URLMoniker.h>
#include <Logic/Biff_structures/FileMoniker.h>
#include <Logic/Biff_structures/ODRAW/OfficeArtBStoreContainer.h>
#include <Logic/Biff_structures/ODRAW/SimpleOfficeArtContainers.h>
#include <Logic/Biff_structures/ODRAW/OfficeArtFOPT.h>
#include <Logic/Biff_structures/ODRAW/OfficeArtFOPTE.h>
#include <Logic/Biff_structures/ODRAW/OfficeArtFSP.h>
#include <Logic/Biff_structures/ODRAW/OfficeArtBlip.h>
#include <Logic/Biff_structures/ODRAW/OfficeArtFSPGR.h>
#include <Logic/Biff_structures/ODRAW/OfficeArtClientAnchorSheet.h>
#include <Logic/Biff_structures/ODRAW/OfficeArtClientAnchorHF.h>
#include "../XlsFormat/Logic/Biff_unions/SUPBOOK.h"
#include "../XlsFormat/Logic/Biff_records/BkHim.h"
#include "../XlsFormat/Logic/Biff_records/HLink.h"
#include "../XlsFormat/Logic/Biff_records/MsoDrawingGroup.h"
#include "../XlsFormat/Logic/Biff_records/MsoDrawing.h"
#include "../XlsFormat/Logic/Biff_records/Obj.h"
#include "../XlsFormat/Logic/Biff_records/TxO.h"
#include "../XlsFormat/Logic/Biff_records/IMDATA.h"
#include "../XlsFormat/Logic/Biff_records/Note.h"
#include "../XlsFormat/Logic/Biff_structures/URLMoniker.h"
#include "../XlsFormat/Logic/Biff_structures/FileMoniker.h"
#include "../XlsFormat/Logic/Biff_structures/ODRAW/OfficeArtBStoreContainer.h"
#include "../XlsFormat/Logic/Biff_structures/ODRAW/SimpleOfficeArtContainers.h"
#include "../XlsFormat/Logic/Biff_structures/ODRAW/OfficeArtFOPT.h"
#include "../XlsFormat/Logic/Biff_structures/ODRAW/OfficeArtFOPTE.h"
#include "../XlsFormat/Logic/Biff_structures/ODRAW/OfficeArtFSP.h"
#include "../XlsFormat/Logic/Biff_structures/ODRAW/OfficeArtBlip.h"
#include "../XlsFormat/Logic/Biff_structures/ODRAW/OfficeArtFSPGR.h"
#include "../XlsFormat/Logic/Biff_structures/ODRAW/OfficeArtClientAnchorSheet.h"
#include "../XlsFormat/Logic/Biff_structures/ODRAW/OfficeArtClientAnchorHF.h"
#include "xlsx_conversion_context.h"
#include "xlsx_package.h"
......@@ -541,6 +542,8 @@ void XlsConverter::convert(XLS::GlobalsSubstream* global)
{
convert((ODRAW::OfficeArtDgContainer*)global->m_arHFPictureDrawing[i].get());
}
global->serialize_format(xlsx_context->workbook_format());
for (size_t i = 0 ; i < global->m_arWindow1.size(); i++)
{
......@@ -551,11 +554,17 @@ void XlsConverter::convert(XLS::GlobalsSubstream* global)
global->m_arUserBView[i]->serialize(xlsx_context->custom_views());
}
for (size_t i = 0 ; i < global->m_arSUPBOOK.size(); i++)
{
convert((XLS::SUPBOOK*)global->m_arSUPBOOK[i].get());
}
for (size_t i = 0 ; i < global->m_arPIVOTCACHEDEFINITION.size(); i++)
{
convert((XLS::PIVOTCACHEDEFINITION*)global->m_arPIVOTCACHEDEFINITION[i].get());
}
xlsx_context->get_pivots_context().add_connections(xls_global_info->connections_stream.str());
}
typedef boost::unordered_map<XLS::FillInfo, int> mapFillInfo;
......@@ -1968,4 +1977,22 @@ void XlsConverter::convert(XLS::PIVOTCACHEDEFINITION * pivot_cached)
{
xlsx_context->get_pivots_context().add_cache_external(xls_global_info->mapPivotCacheExternal);
}
}
\ No newline at end of file
}
void XlsConverter::convert(XLS::SUPBOOK * external)
{
if (external == NULL) return;
if (external->IsExternal() == false) return;
xlsx_context->start_external();
external->serialize(xlsx_context->current_external().externalData());
if (!external->sExternPathLink.empty()) //???
{
xlsx_context->current_external().add_rels(false, L"rId1", external->sExternPathLink, oox::external_items::typeExternalLink);
}
xlsx_context->end_external();
}
......@@ -72,6 +72,7 @@ namespace XLS
class IMDATA;
class PIVOTVIEW;
class PIVOTCACHEDEFINITION;
class SUPBOOK;
class Note;
class TxO;
......@@ -121,6 +122,7 @@ public:
void convert(XLS::IMDATA * imadata);
void convert(XLS::PIVOTVIEW * pivot_view);
void convert(XLS::PIVOTCACHEDEFINITION * pivot_cached);
void convert(XLS::SUPBOOK * external);
void convert(ODRAW::OfficeArtRecord * art);
void convert(ODRAW::OfficeArtBStoreContainer* art_bstore, int start_id = 0);
......
......@@ -41,7 +41,7 @@ class rels;
class external_items
{
public:
enum Type { typeUnknown = 0, typeImage, typeChart, typeShape, typeTable, typeHyperlink, typeComment, typeMedia, typeGroup};
enum Type { typeUnknown = 0, typeImage, typeChart, typeShape, typeTable, typeHyperlink, typeComment, typeMedia, typeGroup, typeExternalLink};
external_items()
{
......
......@@ -58,9 +58,11 @@ std::wstring get_rel_type(external_items::Type type)
{
case external_items::typeImage:
return L"http://schemas.openxmlformats.org/officeDocument/2006/relationships/image";
case external_items::typeChart:
case external_items::typeChart:
return L"http://schemas.openxmlformats.org/officeDocument/2006/relationships/chart";
default:
case external_items::typeExternalLink:
return L"http://schemas.openxmlformats.org/officeDocument/2006/relationships/externalLinkPath";
default:
return L"";
}
}
......
......@@ -57,8 +57,6 @@ typedef std::vector<element_ptr> element_ptr_array;
class document;
/// \class element
class element
{
public:
......
......@@ -96,6 +96,17 @@ oox_chart_context & xlsx_conversion_context::current_chart()
throw std::runtime_error("internal error");
}
}
oox_external_context & xlsx_conversion_context::current_external()
{
if (!externals_.empty())
{
return *externals_.back().get();
}
else
{
throw std::runtime_error("internal error");
}
}
bool xlsx_conversion_context::start_table(const std::wstring & name)
{
sheets_.push_back(xlsx_xml_worksheet::create(name));
......@@ -130,6 +141,15 @@ void xlsx_conversion_context::end_chart()
{
}
void xlsx_conversion_context::start_external()
{
externals_.push_back(oox_external_context::create());
}
void xlsx_conversion_context::end_external()
{
}
void xlsx_conversion_context::end_table()
{
get_table_context().serialize_hyperlinks(current_sheet().hyperlinks());
......@@ -148,7 +168,7 @@ void xlsx_conversion_context::end_document()
std::wstringstream workbook_content;
unsigned int count = 0;
// добавляем таблицы
for (size_t i = 0; i < sheets_.size(); i++)
{
xlsx_xml_worksheet_ptr & sheet = sheets_[i];
......@@ -221,6 +241,7 @@ void xlsx_conversion_context::end_document()
output_document_->get_xl_files().add_charts(content);
}
//workbook_content << L"<calcPr iterateCount=\"100\" refMode=\"A1\" iterate=\"false\" iterateDelta=\"0.0001\" />";
output_document_->get_xl_files().set_sharedStrings( package::simple_element::create(L"sharedStrings.xml", xlsx_shared_strings_.str()) );
......@@ -235,8 +256,12 @@ void xlsx_conversion_context::end_document()
CP_XML_ATTR(L"xmlns", L"http://schemas.openxmlformats.org/spreadsheetml/2006/main");
CP_XML_ATTR(L"xmlns:r", L"http://schemas.openxmlformats.org/officeDocument/2006/relationships");
CP_XML_ATTR(L"xmlns:mc", L"http://schemas.openxmlformats.org/markup-compatibility/2006");
CP_XML_ATTR(L"mc:Ignorable", L"x15");
CP_XML_ATTR(L"xmlns:x15", L"http://schemas.microsoft.com/office/spreadsheetml/2010/11/main");
CP_XML_NODE(L"bookViews")
CP_XML_STREAM() << xlsx_workbook_pr_.str();
CP_XML_NODE(L"bookViews")
{
CP_XML_STREAM() << xlsx_workbook_views_.str();
}
......@@ -245,7 +270,27 @@ void xlsx_conversion_context::end_document()
{
CP_XML_STREAM() << workbook_content.str();
}
if (externals_.empty() == false)
{
CP_XML_NODE(L"externalReferences")
{
for (size_t i = 0; i < externals_.size(); i++)
{
std::wstring rId = L"extId" + std::to_wstring(i+1);
CP_XML_NODE(L"externalReference")
{
CP_XML_ATTR(L"r:id", rId);
}
package::external_content_ptr content = package::external_content::create();
externals_[i]->dump_rels(content->get_rels());
externals_[i]->write_to(content->content());
output_document_->get_xl_files().add_external(content);
}
}
}
CP_XML_NODE(L"definedNames")
{
CP_XML_STREAM() << xlsx_defined_names_.str();
......
......@@ -42,6 +42,7 @@
#include "xlsx_chart_context.h"
#include "xlsx_comments_context.h"
#include "xlsx_pivots_context.h"
#include "xlsx_external_context.h"
#include "xlsx_output_xml.h"
......@@ -72,16 +73,21 @@ public:
void start_chart();
void end_chart();
void start_external();
void end_external();
std::wostream & shared_strings() { return xlsx_shared_strings_; }
std::wostream & defined_names() { return xlsx_defined_names_; }
std::wostream & workbook_views() { return xlsx_workbook_views_; }
std::wostream & custom_views() { return xlsx_custom_views_; }
std::wostream & workbook_format() { return xlsx_workbook_pr_; }
xlsx_text_context & get_text_context() { return xlsx_text_context_; }
xlsx_table_context & get_table_context() { return xlsx_table_context_; }
xlsx_xml_worksheet & current_sheet();
oox_chart_context & current_chart();
oox_external_context & current_external();
xlsx_pivots_context & get_pivots_context() {return xlsx_pivots_context_;}
xlsx_drawing_context & get_drawing_context();
......@@ -90,6 +96,8 @@ public:
xlsx_comments_context_handle & get_comments_context_handle();
external_items & get_mediaitems() { return mediaitems_; }
void add_exteranal_content(std::wstring content);
private:
void create_new_sheet(std::wstring const & name);
......@@ -100,8 +108,10 @@ private:
std::vector<xlsx_xml_worksheet_ptr> sheets_;
std::vector<oox_chart_context_ptr> charts_;
//std::wstringstream defaultOutput_;
std::vector<oox_external_context_ptr> externals_;
//std::wstringstream defaultOutput_;
//std::pair<float,float> maxDigitSize_;
//num_format_context num_format_context_;
//size_t default_style_;
......@@ -116,6 +126,7 @@ private:
std::wstringstream xlsx_defined_names_;
std::wstringstream xlsx_workbook_views_;
std::wstringstream xlsx_custom_views_;
std::wstringstream xlsx_workbook_pr_;
xlsx_drawing_context_handle xlsx_drawing_context_handle_;
xlsx_comments_context_handle xlsx_comments_context_handle_;
......
......@@ -38,7 +38,7 @@
#include <boost/shared_array.hpp>
#include "../Common/common.h"
#include <Logic/Biff_structures/ODRAW/OfficeArtFOPTE.h>
#include "../XlsFormat/Logic/Biff_structures/ODRAW/OfficeArtFOPTE.h"
#include "xlsx_drawings.h"
......
......@@ -97,6 +97,15 @@ _CP_PTR(pivot_table_content) pivot_table_content::create()
return boost::make_shared<pivot_table_content>();
}
//--------------------------------------------------------------------------------------------
external_content::external_content() : rels_file_(rels_file::create(L""))
{
}
_CP_PTR(external_content) external_content::create()
{
return boost::make_shared<external_content>();
}
//--------------------------------------------------------------------------------------------
sheet_content::sheet_content() : rels_(rels_file::create(L""))
{
......@@ -247,6 +256,11 @@ void xl_files::write(const std::wstring & RootPath)
charts_files_.set_main_document(get_main_document());
charts_files_.write(path);
}
{
externals_files_.set_rels(&rels_files_);
externals_files_.set_main_document(get_main_document());
externals_files_.write(path);
}
if (drawings_)
{
......@@ -318,6 +332,10 @@ void xl_files::add_charts(chart_content_ptr chart)
{
charts_files_.add_chart(chart);
}
void xl_files::add_external(external_content_ptr external)
{
externals_files_.add_external(external);
}
void xl_files::add_pivot_cache(pivot_cache_content_ptr pivot_cache)
{
pivot_cache_files_.add_pivot_cache(pivot_cache);
......@@ -448,6 +466,47 @@ void xl_charts_files::write(const std::wstring & RootPath)
}
}
//----------------------------------------------------------------------------------------
void xl_externals_files::add_external(external_content_ptr external)
{
externals_.push_back(external);
}
void xl_externals_files::write(const std::wstring & RootPath)
{
std::wstring path = RootPath + FILE_SEPARATOR_STR + L"externalLinks";
NSDirectory::CreateDirectory(path.c_str());
content_type & contentTypes = this->get_main_document()->content_type().get_content_type();
static const std::wstring kWSConType = L"application/vnd.openxmlformats-officedocument.spreadsheetml.externalLink+xml";
for (size_t i = 0; i < externals_.size(); i++)
{
if (!externals_[i]) continue;
const std::wstring fileName = std::wstring(L"externalLink") + std::to_wstring(i + 1) + L".xml";
contentTypes.add_override(std::wstring(L"/xl/externalLinks/") + fileName, kWSConType);
package::simple_element(fileName, externals_[i]->str()).write(path);
if (externals_[i]->get_rels().empty() == false)
{
rels_files relFiles;
externals_[i]->rels_file_->set_file_name(fileName + L".rels");
relFiles.add_rel_file(externals_[i]->rels_file_);
relFiles.write(path);
}
if (rels_)
{
const std::wstring id = std::wstring(L"extId") + std::to_wstring(i + 1);
static const std::wstring kWSRel = L"http://schemas.openxmlformats.org/officeDocument/2006/relationships/externalLink";
const std::wstring fileRef = std::wstring(L"externalLinks/") + fileName;
rels_->add(id, kWSRel, fileRef);
}
}
}
//----------------------------------------------------------------------------------------
xl_drawings_ptr xl_drawings::create(const std::vector<drawing_elm> & elms)
{
return boost::make_shared<xl_drawings>(boost::ref(elms));
......
......@@ -103,6 +103,24 @@ private:
};
typedef _CP_PTR(pivot_table_content) pivot_table_content_ptr;
//------------------------------------------------------------------------
class external_content : boost::noncopyable
{
public:
external_content();
static _CP_PTR(external_content) create();
std::wostream & content() { return content_; }
rels & get_rels() { return rels_file_->get_rels(); }
std::wstring str() { return content_.str(); }
friend class xl_externals_files;
private:
std::wstringstream content_;
rels_file_ptr rels_file_;
};
typedef _CP_PTR(external_content) external_content_ptr;
//------------------------------------------------------------------------
class sheets_files : public element
{
public:
......@@ -121,7 +139,6 @@ public:
rels_files * rels_;
};
class xl_charts_files : public element
{
public:
......@@ -133,6 +150,22 @@ public:
std::vector<chart_content_ptr> charts_;
};
class xl_externals_files : public element
{
public:
xl_externals_files(){}
void set_rels(rels_files * rels)
{
rels_ = rels;
}
void add_external(external_content_ptr external);
virtual void write(const std::wstring & RootPath);
std::vector<external_content_ptr> externals_;
rels_files * rels_;
};
class xl_pivot_table_files : public element
{
public:
......@@ -205,6 +238,7 @@ private:
rels_files * rels_;
};
//------------------------------------------------------------------------
class xl_files : public element
{
......@@ -224,6 +258,7 @@ public:
void set_vml_drawings (element_ptr Element);
void set_comments (element_ptr Element);
void add_charts (chart_content_ptr chart);
void add_external (external_content_ptr external);
void add_pivot_cache (pivot_cache_content_ptr cache);
void add_pivot_table (pivot_table_content_ptr table);
......@@ -232,6 +267,7 @@ private:
rels_files rels_files_;
sheets_files sheets_files_;
xl_charts_files charts_files_;
xl_externals_files externals_files_;
xl_pivot_cache_files pivot_cache_files_;
xl_pivot_table_files pivot_table_files_;
......
......@@ -392,6 +392,14 @@
RelativePath="..\XlsXlsxConverter\xlsx_drawings.h"
>
</File>
<File
RelativePath="..\XlsXlsxConverter\xlsx_external_context.cpp"
>
</File>
<File
RelativePath="..\XlsXlsxConverter\xlsx_external_context.h"
>
</File>
<File
RelativePath="..\XlsXlsxConverter\xlsx_hyperlinks.cpp"
>
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment