Files
Yajbir Singh f1b860b25c
Some checks failed
check / markdownlint (push) Has been cancelled
check / spellchecker (push) Has been cancelled
updated
2025-12-11 19:03:17 +05:30

2734 lines
85 KiB
C++
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

/*
* (c) Copyright Ascensio System SIA 2010-2023
*
* This program is a free software product. You can redistribute it and/or
* modify it under the terms of the GNU Affero General Public License (AGPL)
* version 3 as published by the Free Software Foundation. In accordance with
* Section 7(a) of the GNU AGPL its Section 15 shall be amended to the effect
* that Ascensio System SIA expressly excludes the warranty of non-infringement
* of any third-party rights.
*
* This program is distributed WITHOUT ANY WARRANTY; without even the implied
* warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. For
* details, see the GNU AGPL at: http://www.gnu.org/licenses/agpl-3.0.html
*
* You can contact Ascensio System SIA at 20A-6 Ernesta Birznieka-Upish
* street, Riga, Latvia, EU, LV-1050.
*
* The interactive user interfaces in modified source and object code versions
* of the Program must display Appropriate Legal Notices, as required under
* Section 5 of the GNU AGPL version 3.
*
* Pursuant to Section 7(b) of the License you must retain the original Product
* logo when distributing the program. Pursuant to Section 7(e) we decline to
* grant you any rights under trademark law for use of our trademarks.
*
* All the Product's GUI elements, including illustrations and icon sets, as
* well as technical writing content are licensed under the terms of the
* Creative Commons Attribution-ShareAlike 4.0 International. See the License
* terms at http://creativecommons.org/licenses/by-sa/4.0/legalcode
*
*/
#include "XlsConverter.h"
#include "../Format/Binary/CompoundFile.h"
#include "../Format/Binary/CFStreamCacheReader.h"
#include "../Format/Logic/GlobalWorkbookInfo.h"
#include "../Format/Logic/WorkbookStreamObject.h"
#include "../Format/Logic/WorksheetSubstream.h"
#include "../Format/Logic/GlobalsSubstream.h"
#include "../Format/Logic/ChartSheetSubstream.h"
#include "../Format/Logic/MacroSheetSubstream.h"
#include "../Format/Logic/EncryptionStream.h"
#include "../Format/Logic/BinProcessor.h"
#include "../../Common/SummaryInformation/PropertySetStream.h"
#include "../Format/Logic/Biff_unions/FORMATTING.h"
#include "../Format/Logic/Biff_unions/THEME.h"
#include "../Format/Logic/Biff_unions/GLOBALS.h"
#include "../Format/Logic/Biff_unions/COLUMNS.h"
#include "../Format/Logic/Biff_unions/SHAREDSTRINGS.h"
#include "../Format/Logic/Biff_unions/HLINK.h"
#include "../Format/Logic/Biff_unions/LBL.h"
#include "../Format/Logic/Biff_unions/OBJECTS.h"
#include "../Format/Logic/Biff_unions/MSODRAWINGGROUP.h"
#include "../Format/Logic/Biff_unions/OBJ.h"
#include "../Format/Logic/Biff_unions/IMDATAOBJECT.h"
#include "../Format/Logic/Biff_unions/TEXTOBJECT.h"
#include "../Format/Logic/Biff_unions/CHART.h"
#include "../Format/Logic/Biff_unions/BACKGROUND.h"
#include "../Format/Logic/Biff_unions/PIVOTVIEW.h"
#include "../Format/Logic/Biff_unions/PIVOTCACHE.h"
#include "../Format/Logic/Biff_unions/PIVOTCACHEDEFINITION.h"
#include "../Format/Logic/Biff_unions/SUPBOOK.h"
#include "../Format/Logic/Biff_unions/QUERYTABLE.h"
#include "../Format/Logic/Biff_unions/FEAT.h"
#include "../Format/Logic/Biff_unions/FEAT11.h"
#include "../Format/Logic/Biff_records/BkHim.h"
#include "../Format/Logic/Biff_records/HLink.h"
#include "../Format/Logic/Biff_records/MsoDrawingGroup.h"
#include "../Format/Logic/Biff_records/MsoDrawing.h"
#include "../Format/Logic/Biff_records/Obj.h"
#include "../Format/Logic/Biff_records/TxO.h"
#include "../Format/Logic/Biff_records/IMDATA.h"
#include "../Format/Logic/Biff_records/Note.h"
#include "../Format/Logic/Biff_records/WsBool.h"
#include "../Format/Logic/Biff_records/Theme.h"
#include "../Format/Logic/Biff_records/Format.h"
#include "../Format/Logic/Biff_records/CalcMode.h"
#include "../Format/Logic/Biff_structures/URLMoniker.h"
#include "../Format/Logic/Biff_structures/FileMoniker.h"
#include "../Format/Logic/Biff_structures/ODRAW/OfficeArtBStoreContainer.h"
#include "../Format/Logic/Biff_structures/ODRAW/SimpleOfficeArtContainers.h"
#include "../Format/Logic/Biff_structures/ODRAW/OfficeArtFOPT.h"
#include "../Format/Logic/Biff_structures/ODRAW/OfficeArtFOPTE.h"
#include "../Format/Logic/Biff_structures/ODRAW/OfficeArtTertiaryFOPT.h"
#include "../Format/Logic/Biff_structures/ODRAW/OfficeArtFSP.h"
#include "../Format/Logic/Biff_structures/ODRAW/OfficeArtBlip.h"
#include "../Format/Logic/Biff_structures/ODRAW/OfficeArtFSPGR.h"
#include "../Format/Logic/Biff_structures/ODRAW/OfficeArtClientAnchorSheet.h"
#include "../Format/Logic/Biff_structures/ODRAW/OfficeArtClientAnchorHF.h"
#include "xlsx_conversion_context.h"
#include "xlsx_package.h"
#include "../../Common/Utils/simple_xml_writer.h"
#include "../../../OOXML/Base/Unit.h"
#include "../../../DesktopEditor/common/File.h"
#include "../../../DesktopEditor/raster/BgraFrame.h"
#include <boost/make_shared.hpp>
#if !defined(_WIN32) && !defined(_WIN64)
typedef struct tagBITMAPINFOHEADER
{
_UINT32 biSize;
_INT32 biWidth;
_INT32 biHeight;
_UINT16 biPlanes;
_UINT16 biBitCount;
_UINT32 biCompression;
_UINT32 biSizeImage;
_INT32 biXPelsPerMeter;
_INT32 biYPelsPerMeter;
_UINT32 biClrUsed;
_UINT32 biClrImportant;
} BITMAPINFOHEADER;
typedef struct tagBITMAPCOREHEADER {
_UINT32 bcSize; /* used to get to color table */
_UINT16 bcWidth;
_UINT16 bcHeight;
_UINT16 bcPlanes;
_UINT16 bcBitCount;
} BITMAPCOREHEADER;
#endif
XlsConverter::XlsConverter()
{
output_document = NULL;
xlsx_context = NULL;
is_older_version = false;
is_encrypted = false;
}
XlsConverter::XlsConverter(const std::wstring & xlsFileName, const std::wstring & xlsxFilePath, const std::wstring & password, const std::wstring & fontsPath, const std::wstring & tempPath, const int lcid_user, bool & bMacros)
{
xlsx_path = xlsxFilePath;
output_document = NULL;
xlsx_context = NULL;
is_older_version = false;
is_encrypted = false;
output_document = new oox::package::xlsx_document();
_UINT16 workbook_code_page = XLS::WorkbookStreamObject::DefaultCodePage;
try
{
xls_file = boost::shared_ptr<XLS::CompoundFile>(new XLS::CompoundFile(xlsFileName, XLS::CompoundFile::cf_ReadMode));
if (xls_file->isError())
{
xls_global_info = boost::shared_ptr<XLS::GlobalWorkbookInfo>(new XLS::GlobalWorkbookInfo(workbook_code_page, this));
xls_global_info->lcid_user = lcid_user;
xls_global_info->fontsDirectory = fontsPath;
xls_global_info->password = password;
xls_global_info->tempDirectory = tempPath;
xls_global_info->CodePage = 0;
xls_global_info->Version = 0;
XLS::GlobalWorkbookInfo::_sheet_info sheet_info;
xls_global_info->sheets_info.push_back(sheet_info);
XLS::StreamCacheReaderPtr file_reader(new XLS::FileStreamCacheReader(xlsFileName, xls_global_info));
xls_document = boost::shared_ptr<XLS::WorkbookStreamObject>(new XLS::WorkbookStreamObject(workbook_code_page));
XLS::BinReaderProcessor proc(file_reader, xls_document.get(), true);
XLS::BaseObjectPtr stream = XLS::BaseObjectPtr(new XLS::WorksheetSubstream(0));
if (proc.mandatory(*stream.get()))
{
XLS::WorksheetSubstream *worksheet = dynamic_cast<XLS::WorksheetSubstream*>(stream.get());
XLS::WorkbookStreamObject *workbook = dynamic_cast<XLS::WorkbookStreamObject*>(xls_document.get());
if (workbook)
{
workbook->m_arWorksheetSubstream.push_back(stream);
workbook->m_GlobalsSubstream = XLS::BaseObjectPtr(new XLS::GlobalsSubstream(0));
XLS::GlobalsSubstream* globals = dynamic_cast<XLS::GlobalsSubstream*>(workbook->m_GlobalsSubstream.get());
if (globals)
{
globals->m_Formating = worksheet->m_Formating;
globals->UpdateXFC();
}
}
}
else
{
return;
}
}
else
{
OLEPS::PropertySetStream summary_stream;
summary_stream.read(xls_file->getNamedStream(L"SummaryInformation"));
summary_stream.read(xls_file->getNamedStream(L"DocumentSummaryInformation"), true);
workbook_code_page = summary_stream.GetCodePage();
output_document->get_docProps_files().set_app_content(summary_stream.GetApp());
output_document->get_docProps_files().set_core_content(summary_stream.GetCore());
//--------------------------------------------------------------------------------------------------------------------
if( 0/*error*/ == workbook_code_page)//|| 65001 /*UTF-8*/ == workbook_code_page || 1200/* UTF-16 */ == workbook_code_page
{
workbook_code_page = XLS::WorkbookStreamObject::DefaultCodePage;
}
xls_global_info = boost::shared_ptr<XLS::GlobalWorkbookInfo>(new XLS::GlobalWorkbookInfo(workbook_code_page, this));
xls_global_info->lcid_user = lcid_user;
xls_global_info->fontsDirectory = fontsPath;
xls_global_info->password = password;
xls_global_info->tempDirectory = tempPath;
//--------------------------------------------------------------------------------------------------------------------
XLS::StreamCacheReaderPtr workbook_stream(new XLS::CFStreamCacheReader(xls_file->getWorkbookStream(), xls_global_info));
xls_document = boost::shared_ptr<XLS::WorkbookStreamObject>(new XLS::WorkbookStreamObject(workbook_code_page));
XLS::BinReaderProcessor workbook_proc(workbook_stream, xls_document.get() , true);
if (false == workbook_proc.mandatory(*xls_document.get()))
{
// test open list
xls_file->getWorkbookStream()->seekFromBegin(0);
XLS::StreamCacheReaderPtr worksheet_stream(new XLS::CFStreamCacheReader(xls_file->getWorkbookStream(), xls_global_info));
XLS::BaseObjectPtr worksheet_object = XLS::BaseObjectPtr(new XLS::WorksheetSubstream(0));
XLS::BinReaderProcessor worksheet_proc(worksheet_stream, xls_document.get(), true);
if (worksheet_proc.mandatory(*worksheet_object.get()))
{
XLS::WorksheetSubstream* worksheet = dynamic_cast<XLS::WorksheetSubstream*>(worksheet_object.get());
XLS::WorkbookStreamObject* workbook = dynamic_cast<XLS::WorkbookStreamObject*>(xls_document.get());
if (workbook)
{
workbook->m_arWorksheetSubstream.push_back(worksheet_object);
workbook->m_GlobalsSubstream = XLS::BaseObjectPtr(new XLS::GlobalsSubstream(0));
XLS::GlobalsSubstream* globals = dynamic_cast<XLS::GlobalsSubstream*>(workbook->m_GlobalsSubstream.get());
if (globals)
{
globals->m_Formating = worksheet->m_Formating;
globals->UpdateXFC();
}
}
}
else
{
return; //error
}
}
if (xls_global_info->decryptor)
{
is_encrypted = true;
if (xls_global_info->decryptor->IsVerify() == false) return;
}
//--------------------------------------------------------------------------------------------------------------------
XLS::EncryptionSummaryStream encryption_summary(xls_file->getNamedStream(L"encryption"), xls_global_info->decryptor);
//--------------------------------------------------------------------------------------------------------------------
if (xls_file->storage_->isDirectory(L"_SX_DB_CUR"))
{
std::list<std::wstring> listStream = xls_file->storage_->entries(L"_SX_DB_CUR");
int last_index = 0;
for (std::list<std::wstring>::iterator it = listStream.begin(); it != listStream.end(); ++it)
{
XLS::CFStreamPtr pivot_cache_stream = xls_file->getNamedStream(L"_SX_DB_CUR/" + *it);
if (!pivot_cache_stream) continue;
//if (pivot_cache_stream->getStreamSize() < 1) continue;
XLS::StreamCacheReaderPtr pivot_cache_reader(new XLS::CFStreamCacheReader(pivot_cache_stream, xls_global_info));
XLS::BaseObjectPtr pivot_cache = boost::shared_ptr<XLS::PIVOTCACHE>(new XLS::PIVOTCACHE());
XLS::BinReaderProcessor proc(pivot_cache_reader , pivot_cache.get(), true);
proc.mandatory(*pivot_cache.get());
int index = XmlUtils::GetHex(*it); //hexadecimal digits uniquely identifying
xls_global_info->mapPivotCacheStream.insert(std::make_pair(index, pivot_cache));
last_index = index;
}
}
if (bMacros)
{
if (xls_file->storage_->isDirectory(L"_VBA_PROJECT_CUR"))
{
// if false == global_info_->bVbaProjectExist ??
std::wstring xl_path = xlsx_path + FILE_SEPARATOR_STR + L"xl";
NSDirectory::CreateDirectory(xl_path.c_str());
std::wstring sVbaProjectFile = xl_path + FILE_SEPARATOR_STR + L"vbaProject.bin";
POLE::Storage *storageVbaProject = new POLE::Storage(sVbaProjectFile.c_str());
if ((storageVbaProject) && (storageVbaProject->open(true, true)))
{
xls_file->copy(0, L"_VBA_PROJECT_CUR/", storageVbaProject, false);
storageVbaProject->close();
delete storageVbaProject;
output_document->get_xl_files().add_vba_project();
}
}
else if (xls_global_info->bMacrosExist)
output_document->get_xl_files().set_macros_enabled();
else
bMacros = false;
}
XLS::CFStreamPtr controls = xls_file->getNamedStream(L"Ctls");
if(controls)
{
unsigned long size = controls->getStreamSize();
boost::shared_array<BYTE> buffer(new BYTE[size]);
controls->read(buffer.get(), size);
xls_global_info->controls_data = std::make_pair(buffer, size);
}
else
{
xls_global_info->controls_data = encryption_summary.GetStream(L"Ctls");
}
XLS::CFStreamPtr listdata = xls_file->getNamedStream(L"List Data");
if(listdata)
{
unsigned long size = listdata->getStreamSize();
boost::shared_array<BYTE> buffer(new BYTE[size]);
listdata->read(buffer.get(), size);
xls_global_info->listdata_data = std::make_pair(buffer, size);
}
else
{
xls_global_info->listdata_data = encryption_summary.GetStream(L"List Data");
}
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);
}
}
XLS::CFStreamPtr toolbar_data = xls_file->getNamedStream(L"XCB");
if(toolbar_data)
{
std::wstring xl_path = xlsx_path + FILE_SEPARATOR_STR + L"xl";
NSDirectory::CreateDirectory(xl_path.c_str());
std::wstring sToolbarsFile = xl_path + FILE_SEPARATOR_STR + L"attachedToolbars.bin";
NSFile::CFileBinary file;
if (file.CreateFileW(sToolbarsFile))
{
unsigned long size = toolbar_data->getStreamSize();
boost::shared_array<BYTE> buffer(new BYTE[size]);
toolbar_data->read(buffer.get(), size);
file.WriteFile(buffer.get(), size);
file.CloseFile();
output_document->get_xl_files().add_attachedToolbars();
}
}
}
}
catch(...)
{
return;
}
if (xls_global_info->Version < 0x0600)
{
std::wstring sVer = STR::int2hex_wstr(xls_global_info->Version);
Log::error("Version xls is old !!! - " + std::string(sVer.begin(), sVer.end()));
is_older_version = true;
}
xlsx_context = new oox::xlsx_conversion_context(output_document);
}
XlsConverter::~XlsConverter()
{
if (xlsx_context) delete xlsx_context;
if (output_document) delete output_document;
}
bool XlsConverter::isError()
{
if (!xlsx_context) return true;
if (!output_document) return true;
return false;
}
void XlsConverter::write()
{
if (!output_document)return;
output_document->write(xlsx_path);
delete output_document; output_document = NULL;
}
void XlsConverter::convertDocument()
{
if (!xls_document) return;
if (!output_document) return;
if (!xlsx_context) return;
xlsx_context->start_document();
convert((XLS::WorkbookStreamObject*)xls_document.get());
xlsx_context->end_document();
}
void XlsConverter::convert(XLS::BaseObject *xls_unknown)
{
if (xls_unknown == NULL) return;
XLS::ElementType type = xls_unknown->get_type();
switch (type)
{
case XLS::typeHLINK:
{
XLS::HLINK * hlink = dynamic_cast<XLS::HLINK*>(xls_unknown);
convert(hlink);
}break;
case XLS::typeLBL:
{
XLS::LBL * lbl = dynamic_cast<XLS::LBL*>(xls_unknown);
convert(lbl);
}break;
case XLS::typeOBJECTS:
{
XLS::OBJECTS * obj = dynamic_cast<XLS::OBJECTS*>(xls_unknown);
convert(obj, NULL);
}break;
case XLS::typeTxO:
{
XLS::TxO * txo = dynamic_cast<XLS::TxO*>(xls_unknown);
convert(txo);
}break;
case XLS::typeObj:
{
XLS::Obj * obj = dynamic_cast<XLS::Obj*>(xls_unknown);
convert(obj);
}break;
case XLS::typeAnyObject:
default:
{
for (std::list<XLS::BaseObjectPtr>::iterator it = xls_unknown->elements_.begin(); it != xls_unknown->elements_.end(); ++it)
{
(*it)->serialize(xlsx_context->current_sheet().sheetData());
}
}
}
}
void XlsConverter::convert(XLS::WorkbookStreamObject* woorkbook)
{
if (woorkbook == NULL) return;
convert(dynamic_cast<XLS::GlobalsSubstream*>(woorkbook->m_GlobalsSubstream.get()));
for (size_t i = 0 ; i < woorkbook->m_arWorksheetSubstream.size(); i++)
{
xlsx_context->start_sheet();
convert(dynamic_cast<XLS::WorksheetSubstream*>(woorkbook->m_arWorksheetSubstream[i].get()));
xlsx_context->end_sheet();
}
for (size_t i = 0 ; i < woorkbook->m_arChartSheetSubstream.size(); i++)
{
xlsx_context->start_sheet();
convert_chart_sheet(dynamic_cast<XLS::ChartSheetSubstream*>(woorkbook->m_arChartSheetSubstream[i].get()));
xlsx_context->end_sheet();
}
for (size_t i = 0 ; i < woorkbook->m_arMacroSheetSubstream.size(); i++)
{
xlsx_context->start_sheet();
convert(dynamic_cast<XLS::MacroSheetSubstream*>(woorkbook->m_arMacroSheetSubstream[i].get()));
xlsx_context->end_sheet();
}
for (std::list<XLS::BaseObjectPtr>::iterator it = woorkbook->elements_.begin(); it != woorkbook->elements_.end(); ++it)
{
convert(it->get());
}
xlsx_context->add_connections(xls_global_info->connections_stream.str());
}
void XlsConverter::convert_common (XLS::CommonSubstream* sheet)
{
if (sheet == NULL) return;
xls_global_info->current_sheet = sheet->ws_index_ + 1;
XLS::GLOBALS *globals = dynamic_cast<XLS::GLOBALS *>(sheet->m_GLOBALS.get());
if (globals)
{
globals->serialize_formatPr(xlsx_context->current_sheet().sheetFormat());
if (xlsx_context->workbook_calcpr().rdbuf()->in_avail() == 0)
globals->serialize_calcPr(xlsx_context->workbook_calcpr());
}
if (!sheet->m_arWINDOW.empty())
{
sheet->m_arWINDOW[0]->serialize(xlsx_context->current_sheet().sheetViews());
}
sheet->serialize_format(xlsx_context->current_sheet().sheetProperties());
if (sheet->m_PROTECTION)
{
sheet->m_PROTECTION->serialize(xlsx_context->current_sheet().protection());
}
if (sheet->m_COLUMNS)
{
sheet->m_COLUMNS->serialize(xlsx_context->current_sheet().cols());
}
if (sheet->m_CELLTABLE)
{
sheet->m_CELLTABLE->serialize(xlsx_context->current_sheet().sheetData());
}
if (sheet->m_SORTANDFILTER)
{
sheet->m_SORTANDFILTER->serialize(xlsx_context->current_sheet().sheetSortAndFilters());
}
if (sheet->m_PAGESETUP)
{
sheet->m_PAGESETUP->serialize(xlsx_context->current_sheet().pageProperties());
}
if (globals)
{
if (globals->m_HorizontalPageBreaks)
{
globals->m_HorizontalPageBreaks->serialize(xlsx_context->current_sheet().pageProperties());
}
if (globals->m_VerticalPageBreaks)
{
globals->m_VerticalPageBreaks->serialize(xlsx_context->current_sheet().pageProperties());
}
//if (globals->m_CalcMode)
//{
// CP_XML_WRITER(xlsx_context->current_sheet().sheetCalcPr())
// {
// CP_XML_NODE(L"sheetCalcPr")
// {
// XLS::CalcMode *calcMode = dynamic_cast<XLS::CalcMode *>(globals->m_CalcMode.get());
// CP_XML_ATTR(L"fullCalcOnLoad", calcMode->nAutoRecalc > 0 ? 1 : 0);
// }
// }
//}
}
if (sheet->m_arCUSTOMVIEW.size() > 0)
{
CP_XML_WRITER(xlsx_context->current_sheet().customViews())
{
CP_XML_NODE(L"customSheetViews")
{
for (size_t i = 0 ; i < sheet->m_arCUSTOMVIEW.size(); i++)
{
sheet->m_arCUSTOMVIEW[i]->serialize(CP_XML_STREAM());
}
}
}
}
if (sheet->m_BACKGROUND)
{
convert(dynamic_cast<XLS::BACKGROUND*>(sheet->m_BACKGROUND.get()));
}
for (size_t i = 0 ; i < sheet->m_arHFPictureDrawing.size(); i++)
{
convert((ODRAW::OfficeArtDgContainer*)sheet->m_arHFPictureDrawing[i].get());
}
//for (size_t i = 0 ; i < sheet->m_arFEAT.size(); i++)
//{
// convert(dynamic_cast<XLS::FEAT*>(sheet->m_arFEAT.get()));
//}
for (size_t i = 0 ; i < sheet->m_arFEAT11.size(); i++)
{
convert(dynamic_cast<XLS::FEAT11*>(sheet->m_arFEAT11[i].get()));
}
}
void XlsConverter::convert (XLS::WorksheetSubstream* sheet)
{
if (sheet == NULL) return;
if (xls_global_info->sheets_info.empty()) return;
std::wstring name = xls_global_info->sheets_info[sheet->ws_index_].name;
if (name.empty())
name = L"Sheet_" + std::to_wstring(sheet->ws_index_ + 1);
xlsx_context->set_sheet_type(1);
xlsx_context->set_sheet_name(name) ;
xlsx_context->set_sheet_id(sheet->ws_index_ + 1);
xlsx_context->set_sheet_state(xls_global_info->sheets_info[sheet->ws_index_].state);
if (sheet->m_GLOBALS)
{
XLS::GLOBALS * globals = dynamic_cast<XLS::GLOBALS *>(sheet->m_GLOBALS.get());
XLS::COLUMNS * columns = dynamic_cast<XLS::COLUMNS *>(sheet->m_COLUMNS.get());
if (columns)
{
globals->m_DefColWidth = columns->m_DefColWidth;
}
globals->m_DxGCol = sheet->m_DxGCol;
if (globals->is_dialog)
xlsx_context->set_sheet_type(2);
}
convert_common(dynamic_cast<XLS::CommonSubstream*>(sheet));
convert((XLS::OBJECTS*)sheet->m_OBJECTS.get(), sheet);
if (sheet->m_Dimensions)
{
sheet->m_Dimensions->serialize(xlsx_context->current_sheet().dimension());
}
if (sheet->m_arMergeCells.size() > 0)
{
CP_XML_WRITER(xlsx_context->current_sheet().mergeCells())
{
CP_XML_NODE(L"mergeCells")
{
for (size_t i = 0 ; i < sheet->m_arMergeCells.size(); i++)
{
sheet->m_arMergeCells[i]->serialize(CP_XML_STREAM());
}
}
}
}
for (size_t i = 0 ; i < sheet->m_arHLINK.size(); i++)
{
convert((XLS::HLINK*)sheet->m_arHLINK[i].get());
}
if (sheet->m_CONDFMTS)
{
sheet->m_CONDFMTS->serialize(xlsx_context->current_sheet().conditionalFormatting());
}
if (sheet->m_DVAL)
{
sheet->m_DVAL->serialize(xlsx_context->current_sheet().dataValidations());
}
if (!sheet->m_arNote.empty() && xls_global_info->Version < 0x0600)
{
xlsx_context->get_drawing_context().start_drawing(0);
for (size_t i = 0 ; i < sheet->m_arNote.size(); i++)
{
xlsx_context->get_drawing_context().start_drawing(0x0019);
convert(dynamic_cast<XLS::Note*>(sheet->m_arNote[i].get()));
xlsx_context->get_drawing_context().end_drawing();
}
xlsx_context->get_drawing_context().end_group();
}
for (size_t i = 0; i < sheet->m_arQUERYTABLE.size(); i++)
{
convert(dynamic_cast<XLS::QUERYTABLE*>(sheet->m_arQUERYTABLE[i].get()));
}
for (size_t i = 0; i < sheet->m_arPIVOTVIEW.size(); i++)
{
convert((XLS::PIVOTVIEW*)sheet->m_arPIVOTVIEW[i].get());
}
}
void XlsConverter::convert (XLS::MacroSheetSubstream* sheet)
{
if (sheet == NULL) return;
xls_global_info->current_sheet = sheet->ws_index_ + 1;
std::wstring name = xls_global_info->sheets_info[sheet->ws_index_].name;
if (name.empty())
name = L"MacroSheet_" + std::to_wstring(sheet->ws_index_ + 1);
xlsx_context->set_sheet_type(4);
xlsx_context->set_sheet_name(name) ;
xlsx_context->set_sheet_id(sheet->ws_index_ + 1);
xlsx_context->set_sheet_state(xls_global_info->sheets_info[sheet->ws_index_].state);
if (sheet->m_GLOBALS)
{
XLS::GLOBALS * globals = dynamic_cast<XLS::GLOBALS *>(sheet->m_GLOBALS.get());
XLS::COLUMNS * columns = dynamic_cast<XLS::COLUMNS *>(sheet->m_COLUMNS.get());
if (columns)
{
globals->m_DefColWidth = columns->m_DefColWidth;
}
globals->m_DxGCol = sheet->m_DxGCol;
if (globals->is_dialog)
xlsx_context->set_sheet_type(2);
}
convert_common(dynamic_cast<XLS::CommonSubstream*>(sheet));
convert((XLS::OBJECTS*)sheet->m_OBJECTS.get(), NULL);
if (sheet->m_Dimensions)
{
sheet->m_Dimensions->serialize(xlsx_context->current_sheet().dimension());
}
if (!sheet->m_arNote.empty() && xls_global_info->Version < 0x0600)
{
xlsx_context->get_drawing_context().start_drawing(0);
for (size_t i = 0 ; i < sheet->m_arNote.size(); i++)
{
xlsx_context->get_drawing_context().start_drawing(0x0019);
convert(dynamic_cast<XLS::Note*>(sheet->m_arNote[i].get()));
xlsx_context->get_drawing_context().end_drawing();
}
xlsx_context->get_drawing_context().end_group();
}
}
void XlsConverter::convert(XLS::GlobalsSubstream* globals)
{
if (globals == NULL) return;
convert_theme();
convert((XLS::FORMATTING*)globals->m_Formating.get());
convert((XLS::SHAREDSTRINGS*)globals->m_SHAREDSTRINGS.get());
for (size_t i = 0 ; i < globals->m_arLBL.size(); i++)
{
convert((XLS::LBL*)globals->m_arLBL[i].get());
}
for (size_t i = 0 ; i < globals->m_arMSODRAWINGGROUP.size(); i++)
{
convert((XLS::MSODRAWINGGROUP*)globals->m_arMSODRAWINGGROUP[i].get());
}
for (size_t i = 0 ; i < globals->m_arHFPictureDrawing.size(); i++)
{
convert((ODRAW::OfficeArtDggContainer*)globals->m_arHFPictureDrawing[i].get());
}
globals->serialize_protection(xlsx_context->workbook_protection());
globals->serialize_format(xlsx_context->workbook_format());
for (size_t i = 0 ; i < globals->m_arWindow1.size(); i++)
{
globals->m_arWindow1[i]->serialize(xlsx_context->workbook_views());
}
for (size_t i = 0 ; i < globals->m_arUserBView.size(); i++)
{
globals->m_arUserBView[i]->serialize(xlsx_context->custom_views());
}
for (size_t i = 0 ; i < globals->m_arSUPBOOK.size(); i++)
{
convert((XLS::SUPBOOK*)globals->m_arSUPBOOK[i].get());
}
for (size_t i = 0 ; i < xls_global_info->arPIVOTCACHEDEFINITION.size(); i++)
{
convert((XLS::PIVOTCACHEDEFINITION*)xls_global_info->arPIVOTCACHEDEFINITION[i].get());
}
}
void XlsConverter::convert_chart_sheet(XLS::ChartSheetSubstream* chartsheet)
{
if (chartsheet == NULL) return;
xls_global_info->current_sheet = chartsheet->ws_index_ + 1;
std::wstring name = xls_global_info->sheets_info[chartsheet->ws_index_].name;
if (name.empty())
name = L"ChartSheet_" + std::to_wstring(chartsheet->ws_index_ + 1);
xlsx_context->set_sheet_type(3);
xlsx_context->set_sheet_name(name) ;
xlsx_context->set_sheet_id(chartsheet->ws_index_ + 1);
xlsx_context->set_sheet_state(xls_global_info->sheets_info[chartsheet->ws_index_].state);
convert_common(dynamic_cast<XLS::CommonSubstream*>(chartsheet));
if (xlsx_context->get_drawing_context().start_drawing(0x0005))
{
xlsx_context->get_drawing_context().set_id(1);
convert(chartsheet);
xlsx_context->get_drawing_context().end_drawing();
}
}
typedef boost::unordered_map<XLS::FillInfo, int> mapFillInfo;
typedef boost::unordered_map<XLS::BorderInfo, int> mapBorderInfo;
typedef boost::unordered_map<XLS::FontInfo, int> mapFontInfo;
void XlsConverter::convert(XLS::FORMATTING* formating)
{
if (formating == NULL) return;
std::wstringstream strm;
CP_XML_WRITER(strm)
{
CP_XML_NODE(L"styleSheet")
{
CP_XML_ATTR(L"xmlns", L"http://schemas.openxmlformats.org/spreadsheetml/2006/main");
CP_XML_ATTR(L"xmlns:mc", L"http://schemas.openxmlformats.org/markup-compatibility/2006");
CP_XML_ATTR(L"mc:Ignorable", L"x14ac x16r2");
CP_XML_ATTR(L"xmlns:x14ac", L"http://schemas.microsoft.com/office/spreadsheetml/2009/9/ac");
CP_XML_ATTR(L"xmlns:x16r2", L"http://schemas.microsoft.com/office/spreadsheetml/2015/02/main");
CP_XML_NODE(L"numFmts")
{
CP_XML_ATTR(L"count", xls_global_info->m_mapNumFormats.size());
for (std::map<_UINT16, XLS::BaseObjectPtr>::iterator it = xls_global_info->m_mapNumFormats.begin(); it != xls_global_info->m_mapNumFormats.end(); ++it)
{
XLS::Format* fmt = dynamic_cast<XLS::Format*>(it->second.get());
if (fmt->ifmt < 5 || (fmt->ifmt > 8 && fmt->ifmt < 23) || (fmt->ifmt > 36 && fmt->ifmt < 41) || (fmt->ifmt > 44 && fmt->ifmt < 50))
continue;
std::map<_UINT16, _UINT16>::iterator pFind = xls_global_info->mapUsedFormatCode.find(fmt->ifmt);
if (pFind != xls_global_info->mapUsedFormatCode.end())
{
CP_XML_STREAM() << L"<numFmt";
{
CP_XML_STREAM() << L" numFmtId=\"" << fmt->ifmt_used << L"\"";
CP_XML_STREAM() << L" formatCode=\"" << fmt->stFormat << L"\"";
}
CP_XML_STREAM() << L"/>";
}
}
}
CP_XML_NODE(L"fonts")
{
std::vector<XLS::FontInfo> fonts_out;
fonts_out.resize(xls_global_info->font_x_ids.size());
for (mapFontInfo::iterator it = xls_global_info->font_x_ids.begin(); it != xls_global_info->font_x_ids.end(); ++it)
{
fonts_out[it->second] = it->first;
}
CP_XML_ATTR(L"count", fonts_out.size());
for (size_t i = 0 ;i < fonts_out.size(); i++)
{
fonts_out[i].serialize(CP_XML_STREAM());
}
}
CP_XML_NODE(L"fills")
{
std::vector<XLS::FillInfo> fills_out;
fills_out.resize(xls_global_info->fill_x_ids.size());
for (mapFillInfo::iterator it = xls_global_info->fill_x_ids.begin(); it != xls_global_info->fill_x_ids.end(); ++it)
{
fills_out[it->second] = it->first;
}
CP_XML_ATTR(L"count", fills_out.size());
for (size_t i = 0 ;i < fills_out.size(); i++)
{
fills_out[i].serialize(CP_XML_STREAM());
}
}
CP_XML_NODE(L"borders")
{
std::vector<XLS::BorderInfo> borders_out;
borders_out.resize(xls_global_info->border_x_ids.size());
for (mapBorderInfo::iterator it = xls_global_info->border_x_ids.begin(); it != xls_global_info->border_x_ids.end(); ++it)
{
borders_out[it->second] = it->first;
}
CP_XML_ATTR(L"count", borders_out.size());
for (size_t i = 0 ;i < borders_out.size(); i++)
{
borders_out[i].serialize(CP_XML_STREAM());
}
}
formating->serialize(CP_XML_STREAM());
}
}
output_document->get_xl_files().set_styles( oox::package::simple_element::create(L"styles.xml", strm.str()) );
}
std::wstring XlsConverter::GetTargetMoniker(XLS::BiffStructure *moniker)
{
if (moniker == NULL) return L"";
if (moniker->getClassName() == "URLMoniker")
{
OSHARED::URLMoniker* urlMoniker = dynamic_cast<OSHARED::URLMoniker* >(moniker);
if (urlMoniker)return urlMoniker->url;
}
else if (moniker->getClassName() == "FileMoniker")
{
OSHARED::FileMoniker* fileMoniker = dynamic_cast<OSHARED::FileMoniker* >(moniker);
if (fileMoniker)
{
if (!fileMoniker->unicodePath.empty()) return fileMoniker->unicodePath;
else return std::wstring(fileMoniker->ansiPath.begin(), fileMoniker->ansiPath.end());//codePage ??? todooo
}
}
return L"";
}
void XlsConverter::convert(XLS::MSODRAWINGGROUP * mso_drawing)
{
if ( mso_drawing == NULL) return;
XLS::MsoDrawingGroup * mso_group = dynamic_cast<XLS::MsoDrawingGroup*>(mso_drawing->m_MsoDrawingGroup.get());
if (mso_group == NULL) return;
//files
convert (dynamic_cast<ODRAW::OfficeArtBStoreContainer*>(mso_group->rgChildRec.m_OfficeArtBStoreContainer.get()));
}
std::wstring XlsConverter::WriteMediaFile(char *data, int size, std::wstring type_ext, int id)
{
if (size < 1 || !data) return L"";
if (id < 0) id = xlsx_context->get_mediaitems().count_image + 1000; // 1000 - встроенные в поток , 3000 - footer/header
xlsx_context->get_mediaitems().create_media_path(xlsx_path);
bool res = false;
std::wstring file_name = L"image" + std::to_wstring(id);
if (type_ext == L"dib_data")
{
bool bPNG = false;
int offset = 0, biSizeImage = 0;
CBgraFrame frame;
BITMAPINFOHEADER * header = (BITMAPINFOHEADER *)data;
if (header->biWidth > 100000 || header->biHeight > 100000)
{
//biff8
//Formulas Matriciais - A Outra Dimensão do Excel.xls 775x20 todoooo найти еще файлы
//Planilha Bastter Blue 7.0 Free.xls 10x3836
//biff 5
//test-picture.xls
offset = 12; //sizeof(BITMAPCOREHEADER)
BITMAPCOREHEADER * header_core = (BITMAPCOREHEADER *)data;
frame.put_Height (header_core->bcHeight );
frame.put_Width (header_core->bcWidth );
int sz_bitmap = header_core->bcHeight * header_core->bcWidth * header_core->bcBitCount/ 8;
//if (header_core->bcWidth % 2 != 0 && sz_bitmap < size - offset)
// header_core->bcWidth++;
///???? todooo непонятно .. в biff5 нужно флипать картинку, в biff8 не ясно ( -
int stride = - (size - offset) / header_core->bcHeight;
frame.put_Stride (stride/*header_core->bcBitCount * header_core->bcWidth /8 */);
biSizeImage = size - offset;
if (-stride >= header_core->bcWidth && header_core->bcBitCount >=24 )
{
bPNG = true;
}
}
else
{
offset = 40; //sizeof(BITMAPINFOHEADER)
frame.put_Height (header->biHeight );
frame.put_Width (header->biWidth );
int sz_bitmap = header->biHeight * header->biWidth * header->biBitCount/ 8;
//if (header->biWidth % 2 != 0 && sz_bitmap < size -offset)
// header->biWidth++;
int stride = -(size - offset) / header->biHeight;
if (-stride >= header->biWidth && header->biBitCount >= 24)
{
bPNG = true;
}
frame.put_Stride (stride/*header->biBitCount * header->biWidth /8*/);
biSizeImage = header->biSizeImage;
}
if (bPNG)
{
frame.put_Data((unsigned char*)data + offset);
file_name += std::wstring(L".png");
res = frame.SaveFile(xlsx_context->get_mediaitems().media_path() + file_name, 4/*CXIMAGE_FORMAT_PNG*/);
frame.put_Data(NULL);
if (res = false)
{
//
}
}
else if (biSizeImage > 0)
{
//тут паттерные картинки
file_name += std::wstring(L".bmp");
NSFile::CFileBinary file;
if (file.CreateFileW(xlsx_context->get_mediaitems().media_path() + file_name))
{
WORD vtType = 0x4D42; file.WriteFile((BYTE*)&vtType, 2);
DWORD dwLen = biSizeImage; file.WriteFile((BYTE*)&dwLen, 4);
DWORD dwRes = 0; file.WriteFile((BYTE*)&dwRes, 4);
DWORD dwOffset = 2; file.WriteFile((BYTE*)&dwOffset, 4);
file.WriteFile((BYTE*)data, size);
file.CloseFile();
res = true;
}
}
}
else if (type_ext == L"pict")
{
//NSFile::CFileBinary file;
//std::wstring tempPICT = file.CreateTempFileWithUniqueName(xls_global_info->tempDirectory, L"pct");
//if (file.CreateFileW(tempPICT))
//{
// file.WriteFile((BYTE*)data, size);
// file.CloseFile();
//}
CBgraFrame bgraFrame;
if (bgraFrame.Decode((BYTE*)data, size))
{
file_name += L".png";
bgraFrame.SaveFile(xlsx_context->get_mediaitems().media_path() + file_name, 4); // png
}
//NSFile::CFileBinary::Remove(tempPICT);
}
else
{
file_name += type_ext;
NSFile::CFileBinary file;
if (file.CreateFileW(xlsx_context->get_mediaitems().media_path() + file_name))
{
file.WriteFile((BYTE*)data, size);
file.CloseFile();
}
}
//------------------------------------------------------------------------------------------
//------------------------------------------------------------------------------------------
res = true;
if (res)
{
xlsx_context->get_mediaitems().add_image(L"media/" + file_name, id);
return L"media/" + file_name;
}
return L"";
}
void XlsConverter::convert(ODRAW::OfficeArtBStoreContainer* art_bstore, int start_id)
{
if (art_bstore == NULL) return;
if (art_bstore->rgfb.size() < 1) return;
for (size_t i = 0 ; i < art_bstore->rgfb.size(); i++)
{
int bin_id = i + start_id + 1;
WriteMediaFile(art_bstore->rgfb[i]->pict_data, art_bstore->rgfb[i]->pict_size, art_bstore->rgfb[i]->pict_type, bin_id);
}
}
void XlsConverter::convert(XLS::FEAT11 * shared_feature)
{
if (!shared_feature) return;
for (size_t i = 0; i < shared_feature->m_arFEAT.size(); i++)
{
xlsx_context->start_table();
std::wstringstream strm;
shared_feature->serialize(strm, i);
xlsx_context->get_tables_context().add_table(strm.str());
xlsx_context->end_table();
}
}
void XlsConverter::convert(XLS::HLINK * HLINK_)
{
if (!HLINK_) return;
XLS::HLink * hLink = dynamic_cast<XLS::HLink*>(HLINK_->m_HLink.get());
if (!hLink) return;
std::wstring target;
bool bExternal = false;
if (hLink->hyperlink.hlstmfHasMoniker)
{
target = GetTargetMoniker(hLink->hyperlink.oleMoniker.data.get());
bExternal = true;
}
else if (hLink->hyperlink.hlstmfHasLocationStr)
{
target = hLink->hyperlink.location;
}
std::wstring display = hLink->hyperlink.displayName;
if (display.empty()) display = target;
xlsx_context->get_sheet_context().add_hyperlink( hLink->ref8.toString(), target, display, bExternal);
}
void XlsConverter::convert(XLS::LBL * def_name)
{
if (def_name == NULL) return;
def_name->serialize(xlsx_context->defined_names());
}
void XlsConverter::convert(XLS::IMDATA * imdata)
{
if (imdata == NULL) return;
if (imdata->lcb < 1 || imdata->pData == NULL) return;
bool bInternal = false;
std::wstring type_image;
if (imdata->cf == 0x09 && imdata->env == 0x01) type_image = L".wmf";
if ((imdata->cf == 0x09 || imdata->cf == 0x02)
&& imdata->env == 0x02) type_image = L"pict";
if (imdata->cf == 0x09) type_image = L"dib_data";
if (imdata->cf == 0x0e) type_image = L""; //native aka unknown
std::wstring target = WriteMediaFile(imdata->pData.get(), imdata->lcb, type_image);
xlsx_context->get_drawing_context().set_fill_texture(target);
}
void XlsConverter::convert(XLS::BACKGROUND * back)
{
if (back == NULL) return;
XLS::BkHim * bkHim = dynamic_cast<XLS::BkHim*>(back->m_BkHim.get());
if (bkHim->lcb < 1 || bkHim->pData == NULL) return;
bool bInternal = false;
std::wstring target = WriteMediaFile(bkHim->pData.get(), bkHim->lcb, L"dib_data");
std::wstring rId = xlsx_context->get_mediaitems().find_image(target, bInternal);
xlsx_context->current_sheet().sheet_rels().add(oox::relationship(rId, oox::external_items::typeImage, std::wstring(L"../") + target, !bInternal));
if (rId.empty()) return;
CP_XML_WRITER(xlsx_context->current_sheet().picture_background())
{
CP_XML_NODE(L"picture")
{
CP_XML_ATTR(L"r:id", rId);
}
}
}
void XlsConverter::convert_theme()
{
if (xls_global_info->sTheme.empty()) return;
oox::package::theme_content_ptr content =
oox::package::theme_content::create((char*)xls_global_info->sTheme.c_str(), xls_global_info->sTheme.length());
output_document->get_xl_files().add_theme(content);
}
struct _group_object
{
_group_object() {spgr = NULL; ind = count = 0;}
ODRAW::OfficeArtSpgrContainer *spgr;
int ind;
int count;
};
void XlsConverter::convert_old(XLS::OBJECTS* objects, XLS::WorksheetSubstream * sheet)
{
int count = 0;
for ( std::list<XLS::BaseObjectPtr>::iterator elem = objects->elements_.begin(); elem != objects->elements_.end(); elem++)
{
count++;
short type_object = -1;
XLS::OBJ * OBJ = dynamic_cast<XLS::OBJ*> (elem->get());
XLS::IMDATAOBJECT * IMDATAOBJECT = NULL;
XLS::CHART * CHART = NULL;
std::list<XLS::BaseObjectPtr>::iterator elem_next = boost::next(elem);
if ( elem_next !=objects->elements_.end() )
{
IMDATAOBJECT = dynamic_cast<XLS::IMDATAOBJECT*> (elem_next->get());
CHART = dynamic_cast<XLS::CHART*> (elem_next->get());
}
XLS::Obj * obj = OBJ ? dynamic_cast<XLS::Obj *>(OBJ->m_Obj.get()) : NULL;
XLS::IMDATA * image_obj = IMDATAOBJECT ? dynamic_cast<XLS::IMDATA *>(IMDATAOBJECT->m_IMDATA.get()) : NULL;
XLS::ChartSheetSubstream * chart = CHART ? dynamic_cast<XLS::ChartSheetSubstream *>(CHART->m_ChartSheetSubstream.get()) : NULL;
if (!obj)continue;
type_object = obj->cmo.ot;
//-----------------------------------------------------------------------------
if (type_object < 0)continue;
if (type_object == 0)
continue;
if (obj->cmo.fUIObj)
{
continue; // automatically inserted by the application
}
if (xlsx_context->get_drawing_context().start_drawing(type_object))
{
convert(obj->old_version.anchor.get());
if (obj->old_version.bFill)
xlsx_context->get_drawing_context().set_fill_old_version(obj->old_version.fill);
else
xlsx_context->get_drawing_context().set_fill_type(oox::fillNone); //no fill
xlsx_context->get_drawing_context().set_name(obj->old_version.name);
xlsx_context->get_drawing_context().set_line_old_version(obj->old_version.line);
xlsx_context->get_drawing_context().set_flag_old_version(obj->old_version.flag, obj->old_version.flag2);
for (size_t i = 0 ; i < obj->old_version.additional.size(); i++)
{
convert(obj->old_version.additional[i].get());
}
convert(image_obj);
convert(chart);
convert(obj);
xlsx_context->get_drawing_context().end_drawing();
}
if (IMDATAOBJECT || CHART)
{
elem++;
count++;
}
}
}
void XlsConverter::convert(XLS::OBJECTS* objects, XLS::WorksheetSubstream * sheet)
{
if (objects == NULL) return;
if (xls_global_info->Version < 0x0600)
return convert_old(objects, sheet);
std::vector<_group_object> group_objects;
_group_object gr;
gr.spgr = dynamic_cast<ODRAW::OfficeArtSpgrContainer*>(objects->m_MsoDrawing.get()->rgChildRec.m_OfficeArtSpgrContainer.get());
if (gr.spgr == NULL)
return;
gr.count = gr.spgr->child_records.size();
group_objects.push_back(gr);
if ((group_objects.back().spgr) && (group_objects.back().ind < group_objects.back().spgr->child_records.size()))
{
ODRAW::OfficeArtSpContainer *s = dynamic_cast<ODRAW::OfficeArtSpContainer*>(group_objects.back().spgr->child_records[group_objects.back().ind].get());
if (s)
{
ODRAW::OfficeArtFSP *fsp = dynamic_cast<ODRAW::OfficeArtFSP*>(s->m_OfficeArtFSP.get());
if ((fsp) && (fsp->fPatriarch)) group_objects.back().ind++;
}
}
int count = 0;
for ( std::list<XLS::BaseObjectPtr>::iterator elem = objects->elements_.begin(); elem != objects->elements_.end(); elem++)
{
count++;
short type_object = -1;
XLS::OBJ * OBJ = dynamic_cast<XLS::OBJ*> (elem->get());
XLS::TEXTOBJECT * TEXTOBJECT = NULL;
XLS::CHART * CHART = NULL;
std::list<XLS::BaseObjectPtr>::iterator elem_next = boost::next(elem);
if ( elem_next !=objects->elements_.end() )
{
TEXTOBJECT = dynamic_cast<XLS::TEXTOBJECT*>(elem_next->get());
CHART = dynamic_cast<XLS::CHART*> (elem_next->get());
}
XLS::Obj * obj = NULL;
XLS::TxO * text_obj = NULL;
XLS::ChartSheetSubstream * chart = NULL;
if (OBJ) obj = dynamic_cast<XLS::Obj *>(OBJ->m_Obj.get());
if (TEXTOBJECT) text_obj = dynamic_cast<XLS::TxO *>(TEXTOBJECT->m_TxO.get());
if (CHART) chart = dynamic_cast<XLS::ChartSheetSubstream *>(CHART->m_ChartSheetSubstream.get());
if (obj) type_object = obj->cmo.ot;
if (chart) type_object = 0x0005;
if (text_obj)
{
if (type_object < 0) type_object = 0x0006;
}
//-----------------------------------------------------------------------------
if (type_object < 0) continue;
if (group_objects.empty())
break; /// что то с объектами не то ! 2006 02.xls
if (type_object == 0)
{
_group_object gr;
if (group_objects.back().ind < group_objects.back().spgr->child_records.size())
{
gr.spgr = dynamic_cast<ODRAW::OfficeArtSpgrContainer*>(group_objects.back().spgr->child_records[group_objects.back().ind++].get());
gr.count = gr.spgr ? gr.spgr->child_records.size() : 0;
group_objects.push_back(gr);
}
else //сюда попадать не должно !!!!
continue;
}
if (obj->cmo.fUIObj)
{
group_objects.back().ind++;
continue; // automatically inserted by the application
}
ODRAW::OfficeArtSpContainer *sp = NULL;
if ((group_objects.size() > 0) && (group_objects.back().spgr ) && ( group_objects.back().ind < group_objects.back().count))
{
sp = dynamic_cast<ODRAW::OfficeArtSpContainer*>(group_objects.back().spgr->child_records[group_objects.back().ind++].get());
}
if (xlsx_context->get_drawing_context().start_drawing(type_object))
{
convert(sp);
if ((!sp) || (!sp->m_OfficeArtAnchor))
{
if ((group_objects.size() > 0) && (group_objects.back().spgr ) && ( group_objects.back().ind < group_objects.back().count))
{
sp = dynamic_cast<ODRAW::OfficeArtSpContainer*>(group_objects.back().spgr->child_records[group_objects.back().ind++].get());
}
convert(sp, true);
}
if (type_object == 0x19)
{
text_obj->preserve_enabled = true;
for (size_t i = 0 ; sheet && i < sheet->m_arNote.size(); i++)
{
XLS::Note* note = dynamic_cast<XLS::Note*>(sheet->m_arNote[i].get());
if ((note) && (note->note_sh.idObj == obj->cmo.id))
{
convert(note);
break;
}
}
}
convert(text_obj);
convert(chart);
convert(obj);
xlsx_context->get_drawing_context().end_drawing();
}
if (TEXTOBJECT || CHART)
{
elem++;
count++;
}
while ((group_objects.size() >0) && (group_objects.back().ind >= group_objects.back().count))
{
group_objects.back().spgr = NULL;
group_objects.pop_back();
xlsx_context->get_drawing_context().end_group();
}
}
}
void XlsConverter::convert(ODRAW::OfficeArtSpgrContainer * spgr)
{
if (spgr == NULL) return;
if (spgr->anchor_type_ != ODRAW::OfficeArtRecord::CA_HF) return;
for (size_t i = 0; i < spgr->child_records.size(); i++)
{
ODRAW::OfficeArtSpContainer* SpContainer = dynamic_cast<ODRAW::OfficeArtSpContainer*>(spgr->child_records[i].get());
if (SpContainer)
{
ODRAW::OfficeArtFSP* fsp = dynamic_cast<ODRAW::OfficeArtFSP*>(SpContainer->m_OfficeArtFSP.get());
if ((fsp) && (fsp->fHaveSpt))
{
int type_object = 2;//rect
if (xlsx_context->get_drawing_context().start_drawing(type_object))
{
xlsx_context->get_drawing_context().set_mode_HF(true);
convert(spgr->child_records[i].get());
xlsx_context->get_drawing_context().end_drawing();
}
}
}
}
}
void XlsConverter::convert(ODRAW::OfficeArtSpContainer *sp, bool anchor_only)
{
if (sp == NULL) return;
if (!anchor_only)
{
convert(sp->m_OfficeArtFSP.get());
for (size_t i = 0; i < sp->child_records.size(); i++)
{
convert(sp->child_records[i].get());
}
}
convert(sp->m_OfficeArtAnchor.get());
}
void XlsConverter::convert(ODRAW::OfficeArtRecord * art)
{
if (art == NULL) return;
std::wstringstream strm;
switch(art->get_type())
{
case XLS::typeOfficeArtFOPT://properties
{
convert(dynamic_cast<ODRAW::OfficeArtFOPT *>(art));
}break;
case XLS::typeOfficeArtTertiaryFOPT://properties
{
convert(dynamic_cast<ODRAW::OfficeArtTertiaryFOPT *>(art));
}break;
case XLS::typeOfficeArtFSP:
{
convert(dynamic_cast<ODRAW::OfficeArtFSP *>(art));
}break;
case XLS::typeOfficeArtFSPGR:
{
ODRAW::OfficeArtFSPGR * ch = dynamic_cast<ODRAW::OfficeArtFSPGR *>(art);
xlsx_context->get_drawing_context().set_group_anchor(ch->_x, ch->_y, ch->_cx, ch->_cy);
}break;
case XLS::typeOfficeArtClientAnchorHF:
{
ODRAW::OfficeArtClientAnchorHF * hf = dynamic_cast<ODRAW::OfficeArtClientAnchorHF *>(art);
xlsx_context->get_drawing_context().set_child_anchor(0, 0, hf->_cx * 3 / 5, hf->_cy * 3 / 5);
}break;
case XLS::typeOfficeArtChildAnchor:
{
ODRAW::OfficeArtChildAnchor * ch = dynamic_cast<ODRAW::OfficeArtChildAnchor *>(art);
xlsx_context->get_drawing_context().set_child_anchor(ch->_x, ch->_y, ch->_cx, ch->_cy);
}break;
case XLS::typeOfficeArtClientAnchorSheet:
{
ODRAW::OfficeArtClientAnchorSheet * ch = dynamic_cast<ODRAW::OfficeArtClientAnchorSheet *>(art);
ch->calculate();
ch->calculate_1();
if (xlsx_context->get_drawing_context().getType() == oox::external_items::typeGroup &&
xlsx_context->get_drawing_context().getLevel() == 1)
{
xlsx_context->get_drawing_context().set_child_anchor(ch->_x, ch->_y, ch->_cx, ch->_cy);
}
xlsx_context->get_drawing_context().set_sheet_anchor(ch->colL, ch->_dxL, ch->rwT, ch->_dyT, ch->colR, ch->_dxR, ch->rwB, ch->_dyB,
ch->_x, ch->_y, ch->_cx, ch->_cy);
}break;
case XLS::typeOfficeArtBStoreContainer:
{
convert (dynamic_cast<ODRAW::OfficeArtBStoreContainer *>(art), 3000);
}break;
case XLS::typeOfficeArtSpContainer:
{
convert (dynamic_cast<ODRAW::OfficeArtSpContainer *>(art));
}break;
case XLS::typeOfficeArtSpgrContainer:
{
convert (dynamic_cast<ODRAW::OfficeArtSpgrContainer *>(art));
}break;
case XLS::typeOfficeArtDgContainer:
{
ODRAW::OfficeArtDgContainer * dg = dynamic_cast<ODRAW::OfficeArtDgContainer *>(art);
for (size_t i = 0 ; i < dg->child_records.size(); i++) //a-la msodrawing for headers/footers
{
convert(dg->child_records[i].get());
}
for (size_t i = 0; i < dg->m_OfficeArtSpContainer.size(); i++)
{
convert(dg->m_OfficeArtSpContainer[i].get());
}
convert(dg->m_OfficeArtSpgrContainer.get());
}break;
case XLS::typeOfficeArtDggContainer:
{
ODRAW::OfficeArtDggContainer* dg = dynamic_cast<ODRAW::OfficeArtDggContainer*>(art);
convert(dg->m_OfficeArtBStoreContainer.get());
}break;
default:
break;
}
}
void XlsConverter::convert(ODRAW::OfficeArtFSP * fsp)
{
if (fsp == NULL) return;
if (fsp->fFlipH) xlsx_context->get_drawing_context().set_FlipH();
if (fsp->fFlipV) xlsx_context->get_drawing_context().set_FlipV();
xlsx_context->get_drawing_context().set_id(fsp->spid);
xlsx_context->get_drawing_context().set_shape_id(fsp->shape_id);
}
void XlsConverter::convert_fill_style(std::vector<ODRAW::OfficeArtFOPTEPtr> & props)
{
if (props.empty()) return;
for (size_t i = 0 ; i < props.size() ; i++)
{
switch(props[i]->opid)
{
case ODRAW::fillType:
{
switch(props[i]->op)
{
case 1://fillPattern:
{
xlsx_context->get_drawing_context().set_fill_type(oox::fillPattern);
//texture + change black to color2, white to color1
}break;
case 2://fillTexture :
{
xlsx_context->get_drawing_context().set_fill_type(oox::fillTexture);
xlsx_context->get_drawing_context().set_fill_texture_mode(0);
}break;
case 3://fillPicture :
{
xlsx_context->get_drawing_context().set_fill_type(oox::fillTexture);
xlsx_context->get_drawing_context().set_fill_texture_mode(1);
}break;
case 4://fillShadeCenter://1 color
case 5://fillShadeShape:
{
xlsx_context->get_drawing_context().set_fill_type(oox::fillGradientOne);
}break;//
case 6://fillShadeTitle://2 colors and more
case 7://fillShade :
case 8://fillShadeScale:
{
xlsx_context->get_drawing_context().set_fill_type(oox::fillGradient);
}break;
case 9://fillBackground:
{
xlsx_context->get_drawing_context().set_fill_type(oox::fillNone);
}break;
case 0:
default:
{ //undefined
xlsx_context->get_drawing_context().set_fill_type(oox::fillUndefined);
}break;
}
}break;
case ODRAW::fillColor:
case ODRAW::fillColorExt:
{
ODRAW::FillColor * fill = (ODRAW::FillColor *)(props[i].get());
ODRAW::OfficeArtCOLORREF color((_UINT32)fill->op);
if (!color.sColorRGB.empty())
xlsx_context->get_drawing_context().set_fill_color(color.nColorRGB, color.sColorRGB);
else if (color. fPaletteIndex)
{
std::map<int, std::wstring>::iterator it = xls_global_info->colors_palette.find(color.index);
if (it != xls_global_info->colors_palette.end())
{
//убрать 0!!! todooo
xlsx_context->get_drawing_context().set_fill_color(0, it->second);
}
}
else
xlsx_context->get_drawing_context().set_fill_color(color.index, color.fSchemeIndex ? 1 : 3 );
}break;
case ODRAW::fillOpacity:
{
ODRAW::FixedPoint * fixed_point = static_cast<ODRAW::FixedPoint *>(props[i].get());
xlsx_context->get_drawing_context().set_fill_opacity(fixed_point->dVal);
}break;
case ODRAW::fillBackColor:
case ODRAW::fillBackColorExt:
{
ODRAW::FillColor * fill = (ODRAW::FillColor *)(props[i].get());
ODRAW::OfficeArtCOLORREF color((_UINT32)fill->op);
if (!color.sColorRGB.empty())
xlsx_context->get_drawing_context().set_fill_color(color.nColorRGB,color.sColorRGB, true );
else if (color. fPaletteIndex)
{
std::map<int, std::wstring>::iterator it = xls_global_info->colors_palette.find(color.index);
if (it != xls_global_info->colors_palette.end())
{
//todooo убрать 0 !!!
xlsx_context->get_drawing_context().set_fill_color(0, it->second, true );
}
}
else
xlsx_context->get_drawing_context().set_fill_color(color.index, color.fSchemeIndex ? 1 : 3, true );
}break;
case ODRAW::fillBackOpacity:
{
ODRAW::FixedPoint * fixed_point = static_cast<ODRAW::FixedPoint *>(props[i].get());
xlsx_context->get_drawing_context().set_fill_opacity(fixed_point->dVal, true);
}break;
case ODRAW::fillBlip:
{
std::wstring target;
ODRAW::FillBlip *fillBlip = (ODRAW::FillBlip *)(props[i].get());
if ((fillBlip) && (fillBlip->blip))
{
target = WriteMediaFile(fillBlip->blip->pict_data,fillBlip->blip->pict_size, fillBlip->blip->pict_type);
}
else
{
bool isIternal = false;
std::wstring rId = xlsx_context->get_mediaitems().find_image(props[i]->op , target, isIternal);
}
xlsx_context->get_drawing_context().set_fill_texture(target);
}break;
case ODRAW::fillAngle:
{
ODRAW::FillAngle * angle = (ODRAW::FillAngle *)(props[i].get());
xlsx_context->get_drawing_context().set_fill_angle(angle->dVal);
}break;
case ODRAW::fillFocus:
{
xlsx_context->get_drawing_context().set_fill_focus(props[i]->op);
}break;
case ODRAW::fillShadeType:
{
ODRAW::FillShadeType *shadeType = dynamic_cast<ODRAW::FillShadeType*>(props[i].get());
}break;
case ODRAW::fillShadePreset:
{
}break;
case ODRAW::fillShadeColors:
{
ODRAW::FillShadeColors *shadeColors = dynamic_cast<ODRAW::FillShadeColors*>(props[i].get());
for (size_t i = 0 ; (shadeColors) && (i < shadeColors->complex.data.size()); i++)
{
ODRAW::OfficeArtCOLORREF & color = shadeColors->complex.data[i].color;
std::wstring strColor;
if (!color.sColorRGB.empty()) strColor = color.sColorRGB;
else if (color. fPaletteIndex)
{
std::map<int, std::wstring>::iterator it = xls_global_info->colors_palette.find(color.index);
if (it != xls_global_info->colors_palette.end()) strColor = it->second;
}
if (!strColor.empty())
xlsx_context->get_drawing_context().add_fill_colors( shadeColors->complex.data[i].dPosition, strColor);
else
{
xlsx_context->get_drawing_context().add_fill_colors( shadeColors->complex.data[i].dPosition,
color.index, color.fSchemeIndex ? 1 : 3 );
}
}
}break;
case ODRAW::fillStyleBooleanProperties:
{
ODRAW::FillStyleBooleanProperties * bools = (ODRAW::FillStyleBooleanProperties *)(props[i].get());
if (bools)
{
if (bools->fUsefFilled && bools->fFilled == false)
xlsx_context->get_drawing_context().set_fill_type(oox::fillNone);
}
}break;
default:
{
i =i;
}break;
}
}
}
void XlsConverter::convert_line_style(std::vector<ODRAW::OfficeArtFOPTEPtr> & props)
{
if (props.empty()) return;
for (size_t i = 0 ; i < props.size() ; i++)
{
switch(props[i]->opid)
{
case ODRAW::lineColor:
{
ODRAW::OfficeArtCOLORREF color((_UINT32)props[i]->op);
if (!color.sColorRGB.empty())
xlsx_context->get_drawing_context().set_line_color(color.nColorRGB, color.sColorRGB);
else if (color. fPaletteIndex)
{
std::map<int, std::wstring>::iterator it = xls_global_info->colors_palette.find(color.index);
if (it != xls_global_info->colors_palette.end())
{
//todooo убрать 0 !!
xlsx_context->get_drawing_context().set_line_color(0, it->second);
}
}
else
xlsx_context->get_drawing_context().set_line_color(color.index, color.fSchemeIndex ? 1 : 3 );
}break;
case ODRAW::lineType:
{
xlsx_context->get_drawing_context().set_line_type(props[i]->op);
}break;
case ODRAW::lineFillBlip: //blip
{
}break;
case ODRAW::lineWidth:
xlsx_context->get_drawing_context().set_line_width(props[i]->op);
{
}break;
case ODRAW::lineStyle:
{
xlsx_context->get_drawing_context().set_line_style(props[i]->op);
}break;
case ODRAW::lineDashing:
{
xlsx_context->get_drawing_context().set_line_dash(props[i]->op);
}break;
case ODRAW::lineStartArrowhead:
{
xlsx_context->get_drawing_context().set_arrow_start(props[i]->op);
}break;
case ODRAW::lineEndArrowhead:
{
xlsx_context->get_drawing_context().set_arrow_end(props[i]->op);
}break;
case ODRAW::lineStartArrowWidth:
{
xlsx_context->get_drawing_context().set_arrow_start_width(props[i]->op);
}break;
case ODRAW::lineStartArrowLength:
{
xlsx_context->get_drawing_context().set_arrow_start_length(props[i]->op);
}break;
case ODRAW::lineEndArrowWidth:
{
xlsx_context->get_drawing_context().set_arrow_end_width(props[i]->op);
}break;
case ODRAW::lineEndArrowLength:
{
xlsx_context->get_drawing_context().set_arrow_end_length(props[i]->op);
}break;
case ODRAW::lineStyleBooleanProperties:
{
ODRAW::LineStyleBooleanProperties * bools = (ODRAW::LineStyleBooleanProperties *)(props[i].get());
if (bools)
{
if (bools->fUsefLine && bools->fLine == false)
xlsx_context->get_drawing_context().set_line_type(5); //no line
if (bools->fUsefArrowheadsOK && bools->fArrowheadsOK)
{
xlsx_context->get_drawing_context().set_line_arrow(true);
}
}
}break;
case ODRAW::lineMiterLimit:
{
xlsx_context->get_drawing_context().set_line_miter(props[i]->op);
}break;
case ODRAW::lineJoinStyle:
{
xlsx_context->get_drawing_context().set_line_join(props[i]->op);
}break;
case ODRAW::lineEndCapStyle:
{
xlsx_context->get_drawing_context().set_line_endcap(props[i]->op);
}break;
}
}
}
void XlsConverter::convert_blip(std::vector<ODRAW::OfficeArtFOPTEPtr> & props)
{
if (props.empty()) return;
for (size_t i = 0 ; i < props.size() ; i++)
{
switch(props[i]->opid)
{
case ODRAW::cropFromTop:
{
ODRAW::FixedPoint * fixed_point = static_cast<ODRAW::FixedPoint *>(props[i].get());
xlsx_context->get_drawing_context().set_picture_crop_top(fixed_point->dVal * 10);
}break;
case ODRAW::cropFromBottom:
{
ODRAW::FixedPoint * fixed_point = static_cast<ODRAW::FixedPoint *>(props[i].get());
xlsx_context->get_drawing_context().set_picture_crop_bottom(fixed_point->dVal * 10);
}break;
case ODRAW::cropFromLeft:
{
ODRAW::FixedPoint * fixed_point = static_cast<ODRAW::FixedPoint *>(props[i].get());
xlsx_context->get_drawing_context().set_picture_crop_left(fixed_point->dVal * 10);
}break;
case ODRAW::cropFromRight:
{
ODRAW::FixedPoint * fixed_point = static_cast<ODRAW::FixedPoint *>(props[i].get());
xlsx_context->get_drawing_context().set_picture_crop_right(fixed_point->dVal * 10);
}break;
case ODRAW::pib:
{
bool isIternal = false;
std::wstring target;
int id = props[i]->op;
if (xlsx_context->get_drawing_context().get_mode_HF())
id += 3000;
std::wstring rId = xlsx_context->get_mediaitems().find_image(id , target, isIternal);
xlsx_context->get_drawing_context().set_picture(target);
}break;
case ODRAW::pibName:
{
ODRAW::AnyString *str = dynamic_cast<ODRAW::AnyString*>(props[i].get());
xlsx_context->get_drawing_context().set_picture_name(str->string_);
}break;
case ODRAW::pibFlags:
{
}break;
case ODRAW::pictureTransparent:
{
ODRAW::OfficeArtCOLORREF color((_UINT32)props[i]->op);
if (!color.sColorRGB.empty())
xlsx_context->get_drawing_context().set_picture_transparent(color.nColorRGB, color.sColorRGB);
//...
}break;
case ODRAW::pictureContrast:
{
int val = 0;
if (props[i]->op == 0x7FFFFFFF)
{
val = 100;
}
else if (props[i]->op == 0x00010000)
{
val = 0;
}
else if (props[i]->op > 0x00010000)
{
val = 51. / (props[i]->op / 65536.);
val = (50 - val) * 2;
}
else
{
val = (100. * props[i]->op / 65536. + 0.5) - 100;
}
xlsx_context->get_drawing_context().set_picture_contrast(val);
}break;
case ODRAW::pictureBrightness:
{
int val = ((_INT32)props[i]->op * 100. + 0.5) / 0x00008000;
xlsx_context->get_drawing_context().set_picture_brightness(val);
}break;
case ODRAW::pictureGamma:
{
}break;
case ODRAW::pictureId:
{
}break;
case ODRAW::pictureDblCrMod:
{
}break;
case ODRAW::pictureFillCrMod:
{
}break;
case ODRAW::pictureLineCrMod:
{
}break;
case ODRAW::pibPrint:
{
}break;
case ODRAW::pibPrintName:
{
}break;
case ODRAW::pibPrintFlags:
{
}break;
case ODRAW::blipBooleanProperties:
{
ODRAW::BlipBooleanProperties * bools = (ODRAW::BlipBooleanProperties *)(props[i].get());
if (bools)
{
if (bools->fUsefPictureGray && bools->fPictureGray)
xlsx_context->get_drawing_context().set_picture_grayscale(true);
if (bools->fUsefPictureBiLevel && bools->fPictureBiLevel)
xlsx_context->get_drawing_context().set_picture_biLevel(50);
}
}break;
}
}
}
void XlsConverter::convert_geometry(std::vector<ODRAW::OfficeArtFOPTEPtr> & props)
{
if (props.empty()) return;
_CP_OPT(oox::_rect) rect;
std::vector<_CP_OPT(int)> adjustValues(9);
for (size_t i = 0 ; i < props.size() ; i++)
{
switch(props[i]->opid)
{
case ODRAW::geoLeft: if (!rect) rect = oox::_rect(); rect->x = props[i]->op; break;
case ODRAW::geoTop: if (!rect) rect = oox::_rect(); rect->y = props[i]->op; break;
case ODRAW::geoRight: if (!rect) rect = oox::_rect(); rect->cx = props[i]->op; break;
case ODRAW::geoBottom: if (!rect) rect = oox::_rect(); rect->cy = props[i]->op; break;
case ODRAW::shapePath:
xlsx_context->get_drawing_context().set_custom_path(props[i]->op); break;
case ODRAW::pVertices:
{
ODRAW::PVertices * v = (ODRAW::PVertices *)(props[i].get());
xlsx_context->get_drawing_context().set_custom_verticles(v->complex.data);
}break;
case ODRAW::pSegmentInfo:
{
ODRAW::PSegmentInfo * s = (ODRAW::PSegmentInfo *)(props[i].get());
xlsx_context->get_drawing_context().set_custom_segments(s->complex.data);
}break;
case ODRAW::adjustValue: //0x0147
case ODRAW::adjust2Value:
case ODRAW::adjust3Value:
case ODRAW::adjust4Value:
case ODRAW::adjust5Value:
case ODRAW::adjust6Value:
case ODRAW::adjust7Value:
case ODRAW::adjust8Value:
case ODRAW::adjust9Value:
case ODRAW::adjust10Value:
{
adjustValues[props[i]->opid - 0x0147] = props[i]->op ;
}break;
case ODRAW::pConnectionSites:
{
ODRAW::PConnectionSites * a = (ODRAW::PConnectionSites *)(props[i].get());
xlsx_context->get_drawing_context().set_custom_connection(a->complex.data);
}break;
case ODRAW::pConnectionSitesDir:
{
ODRAW::PConnectionSitesDir * a = (ODRAW::PConnectionSitesDir *)(props[i].get());
xlsx_context->get_drawing_context().set_custom_connectionDir(a->complex.data);
}break;
case ODRAW::xLimo:
{
xlsx_context->get_drawing_context().set_custom_x_limo(props[i]->op);
}break;
case ODRAW::yLimo:
{
xlsx_context->get_drawing_context().set_custom_y_limo(props[i]->op);
}break;
case ODRAW::pAdjustHandles:
{
ODRAW::PAdjustHandles * a = (ODRAW::PAdjustHandles *)(props[i].get());
xlsx_context->get_drawing_context().set_custom_adjustHandles(a->complex.data);
}break;
case ODRAW::pGuides:
{
ODRAW::PGuides* s = (ODRAW::PGuides *)(props[i].get());
xlsx_context->get_drawing_context().set_custom_guides(s->complex.data);
}break;
case ODRAW::pInscribe:
{
ODRAW::PInscribe * a = (ODRAW::PInscribe *)(props[i].get());
xlsx_context->get_drawing_context().set_custom_inscribe(a->complex.data);
}break;
//case ODRAW::cxk:
// {
// ODRAW::cxk * a = (ODRAW::cxk *)(props[i].get());
// xlsx_context->get_drawing_context().set_custom_cxk(a->complex.data);
// }break;
}
}
if (rect)
{
rect->cy -= rect->y;
rect->cx -= rect->x;
xlsx_context->get_drawing_context().set_custom_rect(*rect);
}
xlsx_context->get_drawing_context().set_custom_adjustValues(adjustValues);
}
void XlsConverter::convert_geometry_text(std::vector<ODRAW::OfficeArtFOPTEPtr> & props)
{
if (props.empty()) return;
for (size_t i = 0 ; i < props.size() ; i++)
{
switch(props[i]->opid)
{
case ODRAW::gtextUNICODE://word art text
{
ODRAW::AnyString *str = dynamic_cast<ODRAW::AnyString*>(props[i].get());
if (str) xlsx_context->get_drawing_context().set_wordart_text(str->string_);
}break;
case ODRAW::gtextFont:
{
ODRAW::AnyString *str = dynamic_cast<ODRAW::AnyString*>(props[i].get());
if (str)
{
xlsx_context->get_drawing_context().set_wordart_font(str->string_);
}
}break;
case ODRAW::gtextSize:
{
xlsx_context->get_drawing_context().set_wordart_size((INT)((props[i]->op >> 16) & 0x0000FFFF));
}break;
case ODRAW::gtextSpacing:
{
ODRAW::FixedPoint *val = dynamic_cast<ODRAW::FixedPoint*>(props[i].get());
if (val) xlsx_context->get_drawing_context().set_wordart_spacing(val->dVal);
}break;
case ODRAW::gtextAlign:
{
switch (props[i]->op)
{
case ODRAW::alignTextLeft:
xlsx_context->get_drawing_context().set_text_align(1); break;
case ODRAW::alignTextCenter:
xlsx_context->get_drawing_context().set_text_align(2); break;
case ODRAW::alignTextRight:
xlsx_context->get_drawing_context().set_text_align(3); break;
case ODRAW::alignTextWordJust:
xlsx_context->get_drawing_context().set_text_align(4); break;
case ODRAW::alignTextLetterJust:
xlsx_context->get_drawing_context().set_text_align(5); break;
}
}break;
case 0xff:
{
ODRAW::GeometryTextBooleanProperties *bools = dynamic_cast<ODRAW::GeometryTextBooleanProperties*>(props[i].get());
if (bools)
{
if (bools->fUsegFBold && bools->fBold) xlsx_context->get_drawing_context().set_wordart_bold (true);
if (bools->fUsegFItalic && bools->fItalic) xlsx_context->get_drawing_context().set_wordart_italic (true);
if (bools->fUsegFVertical && bools->fVertical) xlsx_context->get_drawing_context().set_wordart_vertical(true);
if (bools->fUsegFUnderline && bools->fUnderline) xlsx_context->get_drawing_context().set_wordart_underline(true);
if (bools->fUsegFStrikethrough && bools->fStrikethrough)xlsx_context->get_drawing_context().set_wordart_strike(true);
//if (bools->fUsegFShrinkFit && bools->fShrinkFit)
}
}break;
}
}
}
void XlsConverter::convert_text(std::vector<ODRAW::OfficeArtFOPTEPtr> & props)
{
if (props.empty()) return;
RECT text_margin = {0x00016530, 0x0000b298, 0x00016530, 0x0000b298};
for (size_t i = 0 ; i < props.size() ; i++)
{
switch(props[i]->opid)
{
case ODRAW::lTxid: break;
case ODRAW::txdir: break;
case ODRAW::dxTextLeft: text_margin.left = props[i]->op; break;
case ODRAW::dxTextRight: text_margin.right = props[i]->op; break;
case ODRAW::dyTextTop: text_margin.top = props[i]->op; break;
case ODRAW::dyTextBottom: text_margin.bottom = props[i]->op; break;
case ODRAW::WrapText:
{
xlsx_context->get_drawing_context().set_text_wrap(props[i]->op);
}break;
case ODRAW::txflTextFlow:
{
xlsx_context->get_drawing_context().set_text_vertical(props[i]->op);
}break;
case ODRAW::textBooleanProperties:
{
ODRAW::TextBooleanProperties *bools = dynamic_cast<ODRAW::TextBooleanProperties*>(props[i].get());
if (bools)
{
if (bools->fUsefFitShapeToText)
{
xlsx_context->get_drawing_context().set_text_fit_shape(bools->fFitShapeToText);
}
if (bools->fUsefAutoTextMargin)
{
}
}
}break;
case ODRAW::anchorText:
{
switch (props[i]->op)
{
case ODRAW::anchorTop:
case ODRAW::anchorTopBaseline:
{
xlsx_context->get_drawing_context().set_text_align (1);
xlsx_context->get_drawing_context().set_text_vert_align (1);
}break;
case ODRAW::anchorMiddle:
{
xlsx_context->get_drawing_context().set_text_align (1);
xlsx_context->get_drawing_context().set_text_vert_align (2);
}break;
case ODRAW::anchorBottom:
case ODRAW::anchorBottomBaseline:
{
xlsx_context->get_drawing_context().set_text_align (1);
xlsx_context->get_drawing_context().set_text_vert_align (3);
}break;
case ODRAW::anchorTopCentered:
case ODRAW::anchorTopCenteredBaseline:
{
xlsx_context->get_drawing_context().set_text_align (2);
xlsx_context->get_drawing_context().set_text_vert_align (1);
}break;
case ODRAW::anchorMiddleCentered:
{
xlsx_context->get_drawing_context().set_text_align (2);
xlsx_context->get_drawing_context().set_text_vert_align (2);
}break;
case ODRAW::anchorBottomCentered:
case ODRAW::anchorBottomCenteredBaseline:
{
xlsx_context->get_drawing_context().set_text_align (2);
xlsx_context->get_drawing_context().set_text_vert_align (3);
}break;
}
}break;
default:
int j = 0;
break;
}
}
xlsx_context->get_drawing_context().set_text_margin(text_margin);
}
void XlsConverter::convert_shadow(std::vector<ODRAW::OfficeArtFOPTEPtr> & props)
{
if (props.empty()) return;
xlsx_context->get_drawing_context().set_shadow_enabled(true);
for (size_t i = 0 ; i < props.size() ; i++)
{
switch(props[i]->opid)
{
case ODRAW::shadowType:
{
xlsx_context->get_drawing_context().set_shadow_type(props[i]->op);
}break;
case ODRAW::shadowColor:
{
ODRAW::OfficeArtCOLORREF color((_UINT32)props[i]->op);
if (!color.sColorRGB.empty())
xlsx_context->get_drawing_context().set_shadow_color(color.nColorRGB, color.sColorRGB);
}break;
case ODRAW::shadowHighlight:
{
ODRAW::OfficeArtCOLORREF color((_UINT32)props[i]->op);
if (!color.sColorRGB.empty())
xlsx_context->get_drawing_context().set_shadow_highlight(color.nColorRGB, color.sColorRGB);
}break;
case ODRAW::shadowCrMod:
{
}break;
case ODRAW::shadowOpacity:
{
ODRAW::FixedPoint * fixed_point = static_cast<ODRAW::FixedPoint *>(props[i].get());
xlsx_context->get_drawing_context().set_shadow_opacity(fixed_point->dVal);
}break;
case ODRAW::shadowOffsetX:
{
xlsx_context->get_drawing_context().set_shadow_offsetX((_INT32)props[i]->op);
}break;
case ODRAW::shadowOffsetY:
{
xlsx_context->get_drawing_context().set_shadow_offsetY((_INT32)props[i]->op);
}break;
//case ODRAW::shadowSecondOffsetX:
//{
//}break;
//case ODRAW::shadowSecondOffsetY:
//{
//}break;
case ODRAW::shadowScaleXToX:
{
ODRAW::FixedPoint * fixed_point = static_cast<ODRAW::FixedPoint *>(props[i].get());
xlsx_context->get_drawing_context().set_shadow_scaleX2X(fixed_point->dVal);
}break;
case ODRAW::shadowScaleYToX:
{
}break;
case ODRAW::shadowScaleXToY:
{
}break;
case ODRAW::shadowScaleYToY:
{
ODRAW::FixedPoint * fixed_point = static_cast<ODRAW::FixedPoint *>(props[i].get());
xlsx_context->get_drawing_context().set_shadow_scaleY2Y(fixed_point->dVal);
}break;
//case ODRAW::shadowPerspectiveX:
//{
//}break;
//case ODRAW::shadowPerspectiveY:
//{
//}break;
//case ODRAW::shadowWeight:
//{
//}break;
case ODRAW::shadowOriginX:
{
ODRAW::FixedPoint * fixed_point = static_cast<ODRAW::FixedPoint *>(props[i].get());
xlsx_context->get_drawing_context().set_shadow_originX(fixed_point->dVal);
}break;
case ODRAW::shadowOriginY:
{
ODRAW::FixedPoint * fixed_point = static_cast<ODRAW::FixedPoint *>(props[i].get());
xlsx_context->get_drawing_context().set_shadow_originY(fixed_point->dVal);
}break;
}
}
}
void XlsConverter::convert_shape(std::vector<ODRAW::OfficeArtFOPTEPtr> & props)
{
if (props.empty()) return;
for (size_t i = 0 ; i < props.size() ; i++)
{
}
}
void XlsConverter::convert_group_shape(std::vector<ODRAW::OfficeArtFOPTEPtr> & props)
{
if (props.empty()) return;
for (size_t i = 0 ; i < props.size() ; i++)
{
switch(props[i]->opid)
{
case 0x380:
{
ODRAW::AnyString *str = dynamic_cast<ODRAW::AnyString*>(props[i].get());
xlsx_context->get_drawing_context().set_name(str->string_);
}break;
case 0x381:
{
ODRAW::AnyString *str = dynamic_cast<ODRAW::AnyString*>(props[i].get());
xlsx_context->get_drawing_context().set_description(str->string_);
}break;
case 0x0382:
{
ODRAW::PihlShape *pihlShape = dynamic_cast<ODRAW::PihlShape*>(props[i].get());
if (pihlShape)
{
std::wstring sTarget;
bool bExternal = false;
if (pihlShape->complex.hyperlink.hlstmfHasMoniker)
{
sTarget = GetTargetMoniker(pihlShape->complex.hyperlink.oleMoniker.data.get());
bExternal = true;
}
else if (pihlShape->complex.hyperlink.hlstmfHasLocationStr)
{
sTarget = pihlShape->complex.hyperlink.location;
}
std::wstring sDisplay = pihlShape->complex.hyperlink.displayName;
if (sDisplay.empty()) sDisplay = sTarget;
xlsx_context->get_drawing_context().set_hyperlink( sTarget, sDisplay, bExternal);
}
}break;
case 0x03A9:
{
ODRAW::MetroBlob *alternative_data = dynamic_cast<ODRAW::MetroBlob*>(props[i].get());
if (alternative_data)
{
xlsx_context->get_drawing_context().set_alternative_drawing( alternative_data->xmlString);
}
}break;
case 0x03BF:
{
ODRAW::GroupShapeBooleanProperties *bools = dynamic_cast<ODRAW::GroupShapeBooleanProperties*>(props[i].get());
if (bools)
{
if (bools->fHidden && bools->fUsefHidden)
xlsx_context->get_drawing_context().set_hidden(true);
}
}break;
}
}
}
void XlsConverter::convert(XLS::Note* note)
{
if (note == NULL) return;
note->note_sh.calculate();
xlsx_context->get_comments_context().set_ref (note->note_sh.ref_, note->note_sh.col, note->note_sh.row);
xlsx_context->get_comments_context().set_author (note->note_sh.stAuthor);
xlsx_context->get_comments_context().set_visibly(note->note_sh.fShow);
xlsx_context->get_drawing_context().set_object_id (xlsx_context->get_comments_context().get_id());
xlsx_context->get_drawing_context().set_object_visible (note->note_sh.fShow);
xlsx_context->get_drawing_context().set_object_anchor (note->note_sh.col, note->note_sh.row);
if (xls_global_info->Version < 0x0600)
{
//todooo размеры произвольные .. можно сделать оценку по размеру строки
xlsx_context->get_drawing_context().set_sheet_anchor(0, 0, 0, 0, 0, 0, 0, 0, note->note_sh.x_, note->note_sh.y_, 120 * 12700., 64 * 12700.);
xlsx_context->get_drawing_context().set_text(std::wstring(L"<t>") + note->note_sh.stText.value() + std::wstring(L"</t>"));
}
}
void XlsConverter::convert_transform(std::vector<ODRAW::OfficeArtFOPTEPtr> & props)
{
for (size_t i = 0 ; i < props.size() ; i++)
{
switch(props[i]->opid)
{
case 0x0004:
{
ODRAW::FixedPoint * fixed_point = static_cast<ODRAW::FixedPoint *>(props[i].get());
xlsx_context->get_drawing_context().set_rotation(fixed_point->dVal);
}break;
}
}
}
void XlsConverter::convert(ODRAW::OfficeArtTertiaryFOPT * fort)
{
if (fort == NULL) return;
convert_shape (fort->fopt.Shape_props);
convert_group_shape (fort->fopt.GroupShape_props);
convert_transform (fort->fopt.Transform_props);
convert_blip (fort->fopt.Blip_props);
convert_geometry (fort->fopt.Geometry_props);
convert_fill_style (fort->fopt.FillStyle_props);
convert_line_style (fort->fopt.LineStyle_props);
convert_shadow (fort->fopt.Shadow_props);
convert_text (fort->fopt.Text_props);
convert_geometry_text (fort->fopt.GeometryText_props);
}
void XlsConverter::convert(ODRAW::OfficeArtFOPT * fort)
{
if (fort == NULL) return;
convert_shape (fort->fopt.Shape_props);
convert_group_shape (fort->fopt.GroupShape_props);
convert_transform (fort->fopt.Transform_props);
convert_geometry (fort->fopt.Geometry_props);
convert_fill_style (fort->fopt.FillStyle_props);
convert_blip (fort->fopt.Blip_props);
convert_line_style (fort->fopt.LineStyle_props);
convert_shadow (fort->fopt.Shadow_props);
convert_text (fort->fopt.Text_props);
convert_geometry_text (fort->fopt.GeometryText_props);
}
void XlsConverter::convert(XLS::SHAREDSTRINGS* sharedstrings)
{
int count = xls_global_info->startAddedSharedStrings + xls_global_info->arAddedSharedStrings.size();
CP_XML_WRITER(xlsx_context->shared_strings())
{
CP_XML_NODE(L"sst")
{
CP_XML_ATTR(L"uniqueCount", count);
CP_XML_ATTR(L"xmlns", "http://schemas.openxmlformats.org/spreadsheetml/2006/main");
if (sharedstrings)
{
for (std::list<XLS::BaseObjectPtr>::iterator it = sharedstrings->elements_.begin(); it != sharedstrings->elements_.end(); ++it)
{
(*it)->serialize(CP_XML_STREAM());
}
}
for (size_t i = 0 ; i < xls_global_info->arAddedSharedStrings.size(); i++)
{
CP_XML_NODE(L"si")
{
CP_XML_NODE(L"t")
{
CP_XML_ATTR(L"xml:space", "preserve");
CP_XML_STREAM() << STR::escape_ST_Xstring(XmlUtils::EncodeXmlString(xls_global_info->arAddedSharedStrings[i]));
}
}
}
}
}
}
void XlsConverter::convert(XLS::TxO * text_obj)
{
if (text_obj == NULL) return;
int rot = text_obj->rot;
if (rot > 0)
{
switch(rot)
{
case 1: //text appears top to bottom; letters are upright
{
xlsx_context->get_drawing_context().set_text_vertical(5);
}break;
case 2: //text is rotated 90 degrees counterclockwise
{
if (text_obj->hAlignment == (unsigned char)1) text_obj->hAlignment = 3;
else if (text_obj->hAlignment == (unsigned char)3) text_obj->hAlignment = 1;
xlsx_context->get_drawing_context().set_text_vertical(2);
}break;
case 3: //text is rotated 90 degrees clockwise
{
if (text_obj->vAlignment == (unsigned char)1) text_obj->vAlignment = 3;
else if (text_obj->vAlignment == (unsigned char)3) text_obj->vAlignment = 1;
xlsx_context->get_drawing_context().set_text_vertical(3);
}break;
}
}
xlsx_context->get_drawing_context().set_text_align (text_obj->hAlignment);
xlsx_context->get_drawing_context().set_text_vert_align (text_obj->vAlignment);
std::wstringstream strm, strm_vml;
text_obj->serialize(strm);
xlsx_context->get_drawing_context().set_text(strm.str());
text_obj->serialize_vml(strm_vml);
xlsx_context->get_drawing_context().set_text_vml(strm_vml.str());
}
void XlsConverter::convert(XLS::Obj * obj)
{
if ( obj == NULL ) return;
//controls & objects
if ( obj->cmo.ot == 8 && obj->pictFmla.fExist && obj->pictFlags.fExist)
{
std::wstring info;
if (obj->pictFmla.fmla.bFmlaExist)
{
if (obj->pictFmla.fmla.bInfoExist)
info = obj->pictFmla.fmla.embedInfo.strClass.value();
}
if (obj->pictFlags.fCtl && obj->pictFlags.fPrstm && xls_global_info->controls_data.first)//Controls Storage
{
//binary data
xlsx_context->get_mediaitems().create_activeX_path(xlsx_path);
std::wstring target_bin;
std::wstring objectId_bin = xlsx_context->get_mediaitems().add_control_activeX(target_bin);
NSFile::CFileBinary file;
if ( file.CreateFileW(xlsx_context->get_mediaitems().activeX_path() + target_bin) )
{
file.WriteFile(xls_global_info->controls_data.first.get() + obj->pictFmla.lPosInCtlStm, obj->pictFmla.cbBufInCtlStm);
file.CloseFile();
}
std::wstring objectId_xml = xlsx_context->start_activeX();
xlsx_context->get_drawing_context().set_control_activeX(objectId_xml);
xlsx_context->current_activeX().setDataBinRid(objectId_bin, target_bin);
xlsx_context->current_activeX().setProgId(info);
xlsx_context->current_activeX().setLicense(obj->pictFmla.key.keyBuf);
}
else if (!obj->pictFlags.fPrstm)
{
std::wstring object_stream;
if (obj->pictFlags.fDde) object_stream = L"LNK";
else object_stream = L"MBD";
object_stream += XmlUtils::ToString(obj->pictFmla.lPosInCtlStm, L"%08X") + L"/";
if (xls_file->storage_->isDirectory(object_stream))
{
xlsx_context->get_mediaitems().create_embeddings_path(xlsx_path);
std::wstring target;
if (xls_file->storage_->exists(object_stream + L"Workbook")) target = L".xls";
if (xls_file->storage_->exists(object_stream + L"WordDocument")) target = L".doc";
std::wstring objectId = xlsx_context->get_mediaitems().add_embedding(target, info);
POLE::Storage *storageOle = new POLE::Storage((xlsx_context->get_mediaitems().embeddings_path() + target).c_str());
if ((storageOle) && (storageOle->open(true, true)))
{
xls_file->copy(0, object_stream, storageOle, false, true);
storageOle->close();
delete storageOle;
}
xlsx_context->current_sheet().sheet_rels().add(oox::relationship(
objectId, L"http://schemas.openxmlformats.org/officeDocument/2006/relationships/oleObject", L"../embeddings/" + target));
xlsx_context->get_drawing_context().set_ole_object(objectId, info);
}
}
if (obj->pictFmla.key.fmlaLinkedCell.bFmlaExist)
{
std::wstring link = obj->pictFmla.key.fmlaLinkedCell.fmla.getAssembledFormula(true);
xlsx_context->get_drawing_context().set_object_link(link);
}
if (obj->pictFmla.key.fmlaListFillRange.bFmlaExist)
{
std::wstring link = obj->pictFmla.key.fmlaListFillRange.fmla.getAssembledFormula(true);
xlsx_context->get_drawing_context().set_object_fmlaRange(link);
}
}
if (obj->sbs.fExist)
{
xlsx_context->get_drawing_context().set_object_x_val(obj->sbs.iVal);
xlsx_context->get_drawing_context().set_object_x_min(obj->sbs.iMin);
xlsx_context->get_drawing_context().set_object_x_max(obj->sbs.iMax);
xlsx_context->get_drawing_context().set_object_x_inc(obj->sbs.dInc);
xlsx_context->get_drawing_context().set_object_x_page(obj->sbs.dPage);
xlsx_context->get_drawing_context().set_object_3D(!obj->sbs.fNo3d);
xlsx_context->get_drawing_context().set_object_hscroll(obj->sbs.fHoriz);
xlsx_context->get_drawing_context().set_object_dx(obj->sbs.dxScroll);
}
if (obj->list.fExist)
{
xlsx_context->get_drawing_context().set_object_x_sel(obj->list.iSel);
xlsx_context->get_drawing_context().set_object_x_sel_type(obj->list.wListSelType);
xlsx_context->get_drawing_context().set_object_lct(obj->list.lct);
xlsx_context->get_drawing_context().set_object_3D(!obj->list.fNo3d);
if (obj->list.fmla.bFmlaExist)
{
std::wstring link = obj->list.fmla.fmla.getAssembledFormula(true);
xlsx_context->get_drawing_context().set_object_fmlaRange(link);
}
if (obj->list.dropData)
{
xlsx_context->get_drawing_context().set_object_drop_style(obj->list.dropData->wStyle);
xlsx_context->get_drawing_context().set_object_drop_lines(obj->list.dropData->cLine);
}
}
if (obj->checkBox.fExist)
{
xlsx_context->get_drawing_context().set_object_checked(obj->checkBox.fChecked);
xlsx_context->get_drawing_context().set_object_3D(!obj->checkBox.fNo3d);
//unsigned short accel;
}
if (obj->radioButton.fExist)
{
//unsigned short idRadNext;
//Boolean<unsigned short> fFirstBtn;
}
if (obj->edit.fExist)
{
xlsx_context->get_drawing_context().set_object_multiLine(obj->edit.fMultiLine);
xlsx_context->get_drawing_context().set_object_vscroll(obj->edit.fVScroll);
//unsigned short ivtEdit;
//unsigned short id;
}
bool full_ref = false;
if (obj->cmo.ot > 0x06) full_ref = true;
if (obj->linkFmla.fExist && obj->linkFmla.fmla.bFmlaExist)
{
std::wstring link = obj->linkFmla.fmla.fmla.getAssembledFormula(full_ref);
xlsx_context->get_drawing_context().set_object_link(link);
}
if (obj->macro.fExist && obj->macro.fmla.bFmlaExist)
{
std::wstring macro = obj->macro.fmla.fmla.getAssembledFormula(full_ref);
xlsx_context->get_drawing_context().set_macro(macro);
}
}
void XlsConverter::convert(XLS::ChartSheetSubstream* chart)
{
if (chart == NULL) return;
chart->serialize(xlsx_context->current_chart().chartData());
//convert(chart->m_OBJECTSCHART.get());непонятные какие то текстбоксы - пустые и бз привязок
}
void XlsConverter::convert(XLS::PIVOTVIEW* pivot_view)
{
if (pivot_view == NULL) return;
std::wstringstream strm;
pivot_view->serialize(strm);
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)
{
if (pivot_cached == NULL) return;
std::wstringstream strmD, strmR;
pivot_cached->serialize_definitions(strmD);
pivot_cached->serialize_records(strmR);
xlsx_context->get_pivots_context().add_cache(strmD.str(), strmR.str());
if (!xls_global_info->mapPivotCacheExternal.empty())
{
xlsx_context->get_pivots_context().add_cache_external(xls_global_info->mapPivotCacheExternal);
}
}
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();
}
void XlsConverter::convert(XLS::QUERYTABLE* query_table)
{
if (query_table == NULL) return;
std::wstringstream strm;
query_table->serialize(strm);
xlsx_context->add_query_table(strm.str());
}