Commit 4d836c18 authored by ElenaSubbotina's avatar ElenaSubbotina

XlsFormat - mso storage (customXml)

parent e08b6542
......@@ -126,9 +126,6 @@ public:
std::pair<boost::shared_array<unsigned char>, size_t> listdata_data;
std::pair<boost::shared_array<unsigned char>, size_t> controls_data;
std::map<int, std::pair<boost::shared_array<unsigned char>, size_t> > embeddings_data; //parsing ???
std::map<int, std::pair<boost::shared_array<unsigned char>, size_t> > link_data;
struct _xti
{
int iSup;
......
......@@ -246,6 +246,41 @@ XlsConverter::XlsConverter(const std::wstring & xlsFileName, const std::wstring
xls_global_info->listdata_data = std::make_pair(buffer, size);
}
if (xls_file->storage_->isDirectory(L"MsoDataStore"))
{
std::list<std::wstring> msoStores = xls_file->storage_->entries(L"MsoDataStore");
int index = 0;
for (std::list<std::wstring>::iterator it = msoStores.begin(); it != msoStores.end(); it++)
{
XLS::CFStreamPtr item_stream = xls_file->getNamedStream(L"MsoDataStore/" + *it + L"/Item");
XLS::CFStreamPtr props_stream = xls_file->getNamedStream(L"MsoDataStore/" + *it + L"/Properties");
if (!item_stream || !props_stream) continue;
unsigned long item_size = item_stream->getStreamSize();
unsigned long props_size = props_stream->getStreamSize();
oox::package::customXml_content_ptr content = oox::package::customXml_content::create();
char *item_buffer = new char[item_size];
if (item_buffer)
{
item_stream->read(item_buffer, item_size);
content->set_item(item_buffer, item_size);
delete []item_buffer;
}
char *props_buffer = new char[props_size];
if (props_buffer)
{
props_stream->read(props_buffer, props_size);
content->set_props(props_buffer, props_size);
delete []props_buffer;
}
output_document->add_customXml(content);
}
}
}
catch(...)
{
......
......@@ -67,6 +67,7 @@ static std::wstring get_mime_type(const std::wstring & extension)
return L"";
}
//--------------------------------------------------------------------------------------------------------------------------
content_types_file::content_types_file() : filename_(L"[Content_Types].xml")
{}
......@@ -122,12 +123,21 @@ void content_types_file::set_media(external_items & _Mediaitems)
}
/////////////////////////////////////////////////////////////////////////
//--------------------------------------------------------------------------------------------------------------------------
simple_element_ptr simple_element::create(const std::wstring & FileName, const std::wstring & Content)
{
return boost::make_shared<simple_element>(FileName, Content);
}
simple_element::simple_element(const std::wstring & fileName, const std::wstring & content) : filename_(fileName), content_(content)
{
}
simple_element_ptr simple_element::create(const std::wstring & FileName, const std::string & contentUtf8)
{
return boost::make_shared<simple_element>(FileName, contentUtf8);
}
simple_element::simple_element(const std::wstring & fileName, const std::string & contentUtf8) : filename_(fileName), content_utf8_(contentUtf8)
{
}
void simple_element::write(const std::wstring & RootPath)
{
std::wstring name_ = RootPath + FILE_SEPARATOR_STR + filename_;
......@@ -135,13 +145,21 @@ void simple_element::write(const std::wstring & RootPath)
NSFile::CFileBinary file;
if ( file.CreateFileW(name_) == true)
{
std::string root = "<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"yes\"?>";
file.WriteFile((BYTE*)root.c_str(), root.length());
file.WriteStringUTF8(content_);
if (!content_utf8_.empty())
{
file.WriteFile((BYTE*)content_utf8_.c_str(), content_utf8_.size());
}
else
{
std::string root = "<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"yes\"?>";
file.WriteFile((BYTE*)root.c_str(), root.length());
file.WriteStringUTF8(content_);
}
file.CloseFile();
}
}
//--------------------------------------------------------------------------------------------------------------------------
rels_file::rels_file(std::wstring const & FileName) : filename_(FileName)
{};
......@@ -149,7 +167,6 @@ rels_file_ptr rels_file::create(std::wstring const & FileName)
{
return boost::make_shared<rels_file>( boost::ref(FileName) );
}
void rels_file::write(const std::wstring & RootPath)
{
std::wstringstream resStream;
......@@ -194,13 +211,6 @@ _CP_PTR(chart_content) chart_content::create()
return boost::make_shared<chart_content>();
}
//----------------------------------------------------------------------------------------
simple_element_ptr simple_element::create(const std::wstring & FileName, const std::wstring & Content)
{
return boost::make_shared<simple_element>(FileName, Content);
}
////////////
void core_file::write(const std::wstring & RootPath)
{
std::wstringstream resStream;
......
......@@ -98,16 +98,19 @@ typedef boost::shared_ptr<simple_element> simple_element_ptr;
class simple_element : public element
{
public:
simple_element(const std::wstring & FileName, const std::wstring & content);
static simple_element_ptr create(const std::wstring & FileName, const std::wstring & content);
simple_element(const std::wstring & FileName, const std::string & contentUtf8);
static simple_element_ptr create(const std::wstring & FileName, const std::string & contentUtf8);
virtual void write(const std::wstring & RootPath);
simple_element(const std::wstring & FileName, const std::wstring & content);
static simple_element_ptr create(const std::wstring & FileName, const std::wstring & content);
virtual void write(const std::wstring & RootPath);
std::wstring get_filename() {return filename_;}
private:
std::wstring filename_;
std::wstring content_;
std::wstring filename_;
std::wstring content_;
std::string content_utf8_;
};
class rels_file;
......@@ -121,7 +124,6 @@ public:
void set_file_name(std::wstring const & fileName) { filename_ = fileName;}
static rels_file_ptr create(std::wstring const & FileName);
public:
virtual void write(const std::wstring & RootPath);
rels & get_rels() { return rels_; }
......@@ -193,6 +195,27 @@ private:
rels_file_ptr rels_file_;
};
//------------------------------------------------------------------------
class customXml_content;
typedef _CP_PTR(customXml_content) customXml_content_ptr;
class customXml_content : boost::noncopyable
{
public:
customXml_content();
static _CP_PTR(customXml_content) create();
void set_item (char* data, size_t size) {content_item = std::string(data, size);}
void set_props (char* data, size_t size) {content_props = std::string(data, size);}
std::string item() { return content_item; }
std::string props() { return content_props; }
friend class xl_customXml_files;
private:
std::string content_item;
std::string content_props;
};
//------------------------------------------------------------------------
class document : public element
{
public:
......
......@@ -58,23 +58,36 @@ xlsx_content_types_file::xlsx_content_types_file()
content_type_.add_override(L"/docProps/core.xml", L"application/vnd.openxmlformats-package.core-properties+xml");
}
xlsx_document::xlsx_document()
xlsx_document::xlsx_document()
{
xl_files_.set_main_document(this);
rels_file_ptr relFile = rels_file::create(L".rels");
rels_file_ptr relFile = rels_file::create(L".rels");
relFile->get_rels().add(relationship(L"rId1", L"http://schemas.openxmlformats.org/officeDocument/2006/relationships/officeDocument", L"xl/workbook.xml"));
relFile->get_rels().add(relationship(L"rId2", L"http://schemas.openxmlformats.org/officedocument/2006/relationships/metadata/core-properties", L"docProps/core.xml"));
relFile->get_rels().add(relationship(L"rId3", L"http://schemas.openxmlformats.org/officeDocument/2006/relationships/extended-properties", L"docProps/app.xml"));
rels_files_.add_rel_file( relFile );
{
xl_files_.set_main_document(this);
}
{
customXml_files_.set_rels(xl_files_.get_rels());
customXml_files_.set_main_document(this);
}
}
void xlsx_document::add_customXml(customXml_content_ptr customXml)
{
customXml_files_.add_customXml(customXml);
}
void xlsx_document::write(const std::wstring & RootPath)
{
xl_files_.write(RootPath);
docProps_files_.write(RootPath);
content_type_.write(RootPath);
customXml_files_.write(RootPath);
docProps_files_.write(RootPath);
content_type_.write(RootPath);
rels_files_.write(RootPath);
}
......@@ -115,6 +128,14 @@ _CP_PTR(activeX_content) activeX_content::create()
return boost::make_shared<activeX_content>();
}
//--------------------------------------------------------------------------------------------
customXml_content::customXml_content()
{
}
_CP_PTR(customXml_content) customXml_content::create()
{
return boost::make_shared<customXml_content>();
}
//--------------------------------------------------------------------------------------------
sheet_content::sheet_content() : rels_(rels_file::create(L""))
{
......@@ -281,6 +302,7 @@ void xl_files::write(const std::wstring & RootPath)
externals_files_.set_main_document(get_main_document());
externals_files_.write(path);
}
if (drawings_)
{
drawings_->set_main_document(get_main_document());
......@@ -510,6 +532,7 @@ void xl_activeX_files::write(const std::wstring & RootPath)
if (activeXs_.empty()) return;
std::wstring path = RootPath + FILE_SEPARATOR_STR + L"activeX";
//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.ms-office.activeX+xml";
......@@ -535,6 +558,56 @@ void xl_activeX_files::write(const std::wstring & RootPath)
}
}
//----------------------------------------------------------------------------------------
void xl_customXml_files::add_customXml(customXml_content_ptr customXml)
{
customXmls_.push_back(customXml);
}
void xl_customXml_files::write(const std::wstring & RootPath)
{
if (customXmls_.empty()) return;
std::wstring path = RootPath + FILE_SEPARATOR_STR + L"customXml";
NSDirectory::CreateDirectory(path.c_str());
std::wstring path_rels = path + FILE_SEPARATOR_STR + L"_rels";
NSDirectory::CreateDirectory(path_rels.c_str());
content_type & contentTypes = this->get_main_document()->content_type().get_content_type();
static const std::wstring kWSConType = L"application/vnd.openxmlformats-officedocument.customXmlProperties+xml";
for (size_t i = 0; i < customXmls_.size(); i++)
{
if (!customXmls_[i])continue;
const std::wstring fileNameItem = std::wstring(L"item") + std::to_wstring(i + 1) + L".xml";
const std::wstring fileNameProps = std::wstring(L"itemProps") + std::to_wstring(i + 1) + L".xml";
contentTypes.add_override(std::wstring(L"/customXml/") + fileNameProps, kWSConType);
package::simple_element(fileNameItem, customXmls_[i]->item()).write(path);
package::simple_element(fileNameProps, customXmls_[i]->props()).write(path);
{
rels_file_ptr rels_file = rels_file::create(fileNameItem + L".rels");
rels_file->get_rels().add(relationship(L"rId1",
L"http://schemas.openxmlformats.org/officeDocument/2006/relationships/customXmlProps",
fileNameProps));
rels_file->write(path_rels);
}
if (rels_)
{
const std::wstring id = std::wstring(L"cstId") + std::to_wstring(i + 1);
static const std::wstring kWSRel = L"http://schemas.openxmlformats.org/officeDocument/2006/relationships/customXml";
const std::wstring fileRef = std::wstring(L"../customXml/") + fileNameItem;
rels_->add(id, kWSRel, fileRef);
}
}
}
//----------------------------------------------------------------------------------------
void xl_externals_files::add_external(external_content_ptr external)
{
externals_.push_back(external);
......@@ -545,7 +618,7 @@ 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";
......@@ -564,7 +637,7 @@ void xl_externals_files::write(const std::wstring & RootPath)
rels_files relFiles;
externals_[i]->rels_file_->set_file_name(fileName + L".rels");
relFiles.add_rel_file(externals_[i]->rels_file_);
relFiles.add_rel_file(externals_[i]->rels_file_);
relFiles.write(path);
}
if (rels_)
......
......@@ -160,6 +160,21 @@ public:
std::vector<activeX_content_ptr> activeXs_;
};
class xl_customXml_files : public element
{
public:
xl_customXml_files(){}
void set_rels(rels_files * rels)
{
rels_ = rels;
}
void add_customXml(customXml_content_ptr customXml);
virtual void write(const std::wstring & RootPath);
std::vector<customXml_content_ptr> customXmls_;
rels_files * rels_;
};
class xl_query_table_files : public element
{
public:
......@@ -272,9 +287,10 @@ class xl_files : public element
public:
xl_files();
public:
virtual void write(const std::wstring & RootPath);
rels_files *get_rels() {return &rels_files_;}
void set_workbook (element_ptr Element);
void set_styles (element_ptr Element);
void set_sharedStrings (element_ptr Element);
......@@ -304,9 +320,8 @@ private:
xl_query_table_files query_tables_files_;
xl_control_props_files control_props_files_;
element_ptr theme_;
element_ptr workbook_;
element_ptr theme_;
element_ptr workbook_;
element_ptr connections_;
element_ptr styles_;
......@@ -324,14 +339,18 @@ class xlsx_document : public document
{
public:
xlsx_document();
virtual content_types_file & content_type() { return content_type_; }
virtual void write(const std::wstring & RootPath);
virtual content_types_file & content_type() { return content_type_; }
xl_files & get_xl_files() { return xl_files_; }
xl_files & get_xl_files() { return xl_files_; }
void add_customXml(customXml_content_ptr customXml);
private:
xlsx_content_types_file content_type_;
xl_files xl_files_;
xl_customXml_files customXml_files_;
docProps_files docProps_files_;
rels_files rels_files_;
......
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