Files
DocumentServer-v-9.2.0/core/OdfFile/Reader/Converter/xlsxconversioncontext.cpp
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

1003 lines
34 KiB
C++

/*
* (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 "xlsxconversioncontext.h"
#include <iostream>
#include <xml/simple_xml_writer.h>
#include "measuredigits.h"
#include "xlsx_package.h"
#include "xlsx_utils.h"
#include "xlsx_cell_format.h"
#include "../Format/odf_document.h"
#include "../Format/odfcontext.h"
#include "../Format/calcs_styles.h"
namespace cpdoccore {
namespace odf_reader
{
class odf_document;
}
namespace oox {
namespace package
{
class xlsx_document;
}
xlsx_conversion_context::xlsx_conversion_context(odf_reader::odf_document * odfDocument) :
odf_document_ (odfDocument),
output_document_ (NULL),
num_format_context_ (odf_document_->odf_context()),
xlsx_text_context_ (odf_document_->odf_context()),
xlsx_table_context_ (this, xlsx_text_context_),
math_context_ (odf_document_->odf_context().fontContainer(), true),
xlsx_style_ (this),
maxDigitSize_ (std::make_pair(-1.f, -1.f) ),
default_style_ ( (std::numeric_limits<size_t>::max)() )
{
mediaitems_ = boost::make_shared<mediaitems>(odf_document_->get_folder());
drawing_context_handle_ = boost::make_shared<xlsx_drawing_context_handle>(mediaitems_);
}
std::unordered_map<std::wstring, int> xlsx_conversion_context::mapExternalLink_;
void xlsx_conversion_context::set_output_document (package::xlsx_document * document)
{
output_document_ = document;
}
xlsx_conversion_context::~xlsx_conversion_context()
{
}
void xlsx_conversion_context::set_font_directory(std::wstring pathFonts)
{
mediaitems_->set_font_directory(pathFonts);
}
void xlsx_conversion_context::set_drawing_context_handle(xlsx_drawing_context_handle_ptr &handle)
{
drawing_context_handle_ = handle;
}
void xlsx_conversion_context::set_mediaitems(mediaitems_ptr &items)
{
mediaitems_ = items;
}
void xlsx_conversion_context::start_chart(std::wstring name)
{
charts_.push_back(oox_chart_context_ptr(new oox_chart_context(mediaitems_, name)));
//добавляем новую форму для диаграммы
//в ней будет информационная часть - и она пишется каждый раз в свою xml (их - по числу диаграмм)
//этот контекст нужно передавать в файл
}
void xlsx_conversion_context::end_chart()
{
}
void xlsx_conversion_context::start_document()
{
odf_reader::odf_read_context & odfContext = root()->odf_context();
std::vector<const odf_reader::style_instance *> instances;
instances.push_back(odfContext.styleContainer().style_default_by_type(odf_types::style_family::TableCell));
instances.push_back(odfContext.styleContainer().style_by_name(L"Default", odf_types::style_family::TableCell, false));
odf_reader::text_format_properties_ptr textFormatProperties = calc_text_properties_content(instances);
odf_reader::paragraph_format_properties parFormatProperties = calc_paragraph_properties_content(instances);
odf_reader::style_table_cell_properties_attlist cellFormatProperties = calc_table_cell_properties(instances);
oox::xlsx_cell_format cellFormat;
cellFormat.set_cell_type(XlsxCellType::s);
cellFormat.set_num_format(oox::odf_string_to_build_in(0));
default_style_ = get_style_manager().xfId(textFormatProperties, &parFormatProperties, &cellFormatProperties, &cellFormat, L"", 0, true);
}
void xlsx_conversion_context::end_document()
{
std::wstringstream workbook_content;
if (sheets_.empty())
{ // owncloud new document ... oO
start_table(L"Sheet1", L"", L"");
current_sheet().cols() << L"<col min=\"1\" max=\"1024\" width=\"11.6\" customWidth=\"0\"/>";
end_table();
}
std::map<std::wstring, std::vector<std::pair<std::wstring, std::wstring>>> map_external_sheets;
int sheet_id = 1;
for (size_t i = 0; i < sheets_.size(); i++)
{
xlsx_xml_worksheet_ptr& sheet = sheets_[i];
std::wstring external_ref = sheet->external_ref();
if (false == external_ref.empty())
{
std::wstringstream external_content;
sheet->write_external_to(external_content);
std::map<std::wstring, std::vector<std::pair<std::wstring, std::wstring>>>::iterator pFind = map_external_sheets.find(external_ref);
if (pFind != map_external_sheets.end())
{
pFind->second.push_back(std::make_pair(sheet->name(), external_content.str()));
}
else
{
std::vector<std::pair<std::wstring, std::wstring>> ext_sheet;
ext_sheet.push_back(std::make_pair(sheet->name(), external_content.str()));
map_external_sheets.insert(std::make_pair(sheet->external_ref(), ext_sheet));
}
continue;
}
const std::wstring id = std::wstring(L"sId") + std::to_wstring(sheet_id++);
package::sheet_content_ptr content = package::sheet_content::create();
////////////////////////////////////////////////////////////////////////////////////////////
const std::pair<std::wstring, std::wstring> p1 = sheet->get_drawing_link();
if (!p1.first.empty())
{
const std::wstring dId = p1.second;
static const std::wstring kType = L"http://schemas.openxmlformats.org/officeDocument/2006/relationships/drawing";
const std::wstring dName = std::wstring(L"../drawings/" + p1.first);
content->add_rel(relationship(dId, kType, dName));
}
//////////////////////////////////////////////////////////////////////////////////////////////////
content->add_rels(sheet->sheet_rels());
/////////////////////////////////////////////////////////////////////////////////////////////////
const std::pair<std::wstring, std::wstring> p2 = sheet->get_comments_link();
if (!p2.first.empty())
{
const std::wstring dId = p2.second;
static const std::wstring kType = L"http://schemas.openxmlformats.org/officeDocument/2006/relationships/comments";
const std::wstring dName = std::wstring(L"../" + p2.first);
content->add_rel(relationship(dId, kType, dName));
}
const std::pair<std::wstring, std::wstring> p3 = sheet->get_vml_drawing_link();
if (!p3.first.empty())
{
const std::wstring dId = p3.second;
static const std::wstring kType = L"http://schemas.openxmlformats.org/officeDocument/2006/relationships/vmlDrawing";
const std::wstring dName = std::wstring(L"../drawings/" + p3.first);
content->add_rel(relationship(dId, kType, dName));
}
/////////////////////////////////////////////////////////////////////////////////////////////////
sheet->write_to(content->content());
output_document_->get_xl_files().add_sheet(content);
/////////////////////////////////////////////
CP_XML_WRITER(workbook_content)
{
CP_XML_NODE(L"sheet")
{
CP_XML_ATTR(L"name", XmlUtils::EncodeXmlString(sheet->name())); // ms office ! ограничение на длину имени 31!!!
CP_XML_ATTR(L"sheetId", i + 1);
CP_XML_ATTR(L"state", sheet->hidden() ? L"hidden" : L"visible");
CP_XML_ATTR(L"r:id", id);
}
}
}
for (std::map<std::wstring, std::wstring>::iterator it = control_props_.begin(); it != control_props_.end(); ++it)
{
output_document_->get_xl_files().add_control_props( package::simple_element::create(it->first, it->second) );
}
for (size_t i = 0; i < charts_.size(); i++)
{
package::chart_content_ptr content = package::chart_content::create();
charts_[i]->serialize(content->content());
charts_[i]->dump_rels(content->get_rel_file()->get_rels());
output_document_->get_xl_files().add_charts(content);
}
for (size_t i = 0; i < table_parts_.size(); i++)
{
output_document_->get_xl_files().add_table_part(table_parts_[i]);
}
//workbook_content << L"<calcPr iterateCount=\"100\" refMode=\"A1\" iterate=\"false\" iterateDelta=\"0.0001\" />";
{
std::wstringstream strm;
get_text_context()->serialize_shared_strings(strm);
output_document_->get_xl_files().set_sharedStrings( package::simple_element::create(L"sharedStrings.xml", strm.str()) );
}
{
std::wstringstream strm;
xlsx_style_.xlsx_serialize(strm);
output_document_->get_xl_files().set_styles( package::simple_element::create(L"styles.xml", strm.str()) );
}
{
std::wstringstream strm_workbook;
CP_XML_WRITER(strm_workbook)
{
CP_XML_NODE(L"workbook")
{
CP_XML_ATTR(L"xmlns", L"http://schemas.openxmlformats.org/spreadsheetml/2006/main");
CP_XML_ATTR(L"xmlns:r", L"http://schemas.openxmlformats.org/officeDocument/2006/relationships");
CP_XML_ATTR(L"xmlns:mc", L"http://schemas.openxmlformats.org/markup-compatibility/2006");
CP_XML_ATTR(L"mc:Ignorable", L"x15 xr xr6 xr10 xr2");
CP_XML_ATTR(L"xmlns:x15", L"http://schemas.microsoft.com/office/spreadsheetml/2010/11/main");
CP_XML_ATTR(L"xmlns:xr", L"http://schemas.microsoft.com/office/spreadsheetml/2014/revision");
CP_XML_ATTR(L"xmlns:xr6", L"http://schemas.microsoft.com/office/spreadsheetml/2016/revision6");
CP_XML_ATTR(L"xmlns:xr10", L"http://schemas.microsoft.com/office/spreadsheetml/2016/revision10");
CP_XML_ATTR(L"xmlns:xr2", L"http://schemas.microsoft.com/office/spreadsheetml/2015/revision2");
_CP_OPT(std::wstring) str = root()->odf_context().Settings().find_by_name(L"IsDocumentShared");
if (str)
{
CP_XML_NODE(L"fileSharing")
{
str = root()->odf_context().Settings().find_by_name(L"LoadReadonly");
if (str) CP_XML_ATTR(L"readOnlyRecommended", *str);
if (false == root()->odf_context().DocProps().dc_creator_.empty())
{
CP_XML_ATTR(L"userName", root()->odf_context().DocProps().dc_creator_);
str = root()->odf_context().Settings().find_by_name(L"modify:algorithm-name");
if (str) CP_XML_ATTR(L"algorithmName", *str);
str = root()->odf_context().Settings().find_by_name(L"modify:hash");
if (str) CP_XML_ATTR(L"hashValue", *str);
str = root()->odf_context().Settings().find_by_name(L"modify:salt");
if (str) CP_XML_ATTR(L"saltValue", *str);
str = root()->odf_context().Settings().find_by_name(L"modify:iteration-count");
if (str) CP_XML_ATTR(L"spinCount", *str);
}
}
}
if (table_structure_protected_)
{
CP_XML_NODE(L"workbookProtection")
{
CP_XML_ATTR(L"lockStructure", 1);
}
}
serialize_bookViews (CP_XML_STREAM());
CP_XML_NODE(L"sheets")
{
CP_XML_STREAM() << workbook_content.str();
}
if (false == mapExternalLink_.empty())
{
CP_XML_NODE(L"externalReferences")
{
for (std::unordered_map<std::wstring, int>::iterator it = mapExternalLink_.begin();
it != mapExternalLink_.end(); ++it)
{
package::external_links_content_ptr content = package::external_links_content::create();
content->rId() = L"extRef" + std::to_wstring(it->second);
{
CP_XML_WRITER(content->content())
{
CP_XML_NODE(L"externalLink")
{
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_NODE(L"externalBook")
{
CP_XML_ATTR(L"xmlns:r", L"http://schemas.openxmlformats.org/officeDocument/2006/relationships");
CP_XML_ATTR(L"r:id", L"rId1");
std::map<std::wstring, std::vector<std::pair<std::wstring, std::wstring>>>::iterator pFind = map_external_sheets.find(it->first);
if (pFind != map_external_sheets.end())
{
CP_XML_NODE(L"sheetNames")
{
for (auto ex : pFind->second)
{
CP_XML_NODE(L"sheetName")
{
CP_XML_ATTR(L"val", ex.first);
}
}
}
CP_XML_NODE(L"sheetDataSet")
{
for (size_t x = 0; x < pFind->second.size(); ++x)
{
CP_XML_NODE(L"sheetData")
{
CP_XML_ATTR(L"sheetId", x);
CP_XML_STREAM() << pFind->second[x].second;
}
}
}
}
}
}
}
}
content->get_rels().add(relationship(L"rId1", mediaitems::get_rel_type(typeExternalLink), it->first, L"External"));
output_document_->get_xl_files().add_external_links(content);
CP_XML_NODE(L"externalReference")
{
CP_XML_ATTR(L"r:id", content->rId());
}
}
}
}
get_xlsx_defined_names().xlsx_serialize(CP_XML_STREAM());
int pivot_cache_count = xlsx_pivots_context_.get_count();
if (pivot_cache_count > 0)
{
CP_XML_NODE(L"pivotCaches")
{
for (int i = 0; i < pivot_cache_count; i++)
{
std::wstring rId = L"pcId" + std::to_wstring(i+1);
static const std::wstring sType = L"http://schemas.openxmlformats.org/officeDocument/2006/relationships/pivotCacheDefinition";
const std::wstring sName = std::wstring(L"../pivotCache/pivotCacheDefinition" + std::to_wstring(i + 1) + L".xml");
package::pivot_cache_content_ptr content = package::pivot_cache_content::create();
CP_XML_NODE(L"pivotCache")
{
CP_XML_ATTR(L"cacheId", std::to_wstring(i));
CP_XML_ATTR(L"r:id", rId);
}
xlsx_pivots_context_.dump_rels_cache(i, content->get_rels());
xlsx_pivots_context_.write_cache_definitions_to(i, content->definitions());
xlsx_pivots_context_.write_cache_records_to(i, content->records());
output_document_->get_xl_files().add_pivot_cache(content);
}
}
}
int pivot_view_count = xlsx_pivots_context_.get_count();
if (pivot_view_count > 0)
{
for (int i = 0; i < pivot_view_count; i++)
{
package::pivot_table_content_ptr content = package::pivot_table_content::create();
xlsx_pivots_context_.dump_rels_view(i, content->get_rels());
xlsx_pivots_context_.write_table_view_to(i, content->content());
output_document_->get_xl_files().add_pivot_table(content);
}
}
if (xlsx_pivots_context_.is_connections())
{
std::wstringstream strm;
xlsx_pivots_context_.write_connections_to(strm);
output_document_->get_xl_files().set_connections( package::simple_element::create(L"connections.xml", strm.str()) );
}
}
}
output_document_->get_xl_files().set_workbook( package::simple_element::create(L"workbook.xml", strm_workbook.str()) );
output_document_->get_content_types_file().set_media(get_mediaitems());
output_document_->get_xl_files().set_media(get_mediaitems());
package::xl_drawings_ptr drawings = package::xl_drawings::create(drawing_context_handle_->content(), drawing_context_handle_->content_vml());
output_document_->get_xl_files().set_drawings(drawings);
package::xl_comments_ptr comments = package::xl_comments::create(xlsx_comments_context_handle_.content());
output_document_->get_xl_files().set_comments(comments);
}
}
void xlsx_conversion_context::serialize_bookViews(std::wostream & strm)
{
odf_reader::settings_container &settings = odf_document_->odf_context().Settings();
if (settings.get_views_count() < 1) return;
CP_XML_WRITER(strm)
{
CP_XML_NODE(L"bookViews")
{
for (int i = 0; i < settings.get_views_count(); i++)
{
_CP_OPT(std::wstring) sActiveTable = settings.find_view_by_name(L"ActiveTable", i);
_CP_OPT(std::wstring) sAreaWidth = settings.find_view_by_name(L"VisibleAreaWidth", i);
_CP_OPT(std::wstring) sAreaHeight = settings.find_view_by_name(L"VisibleAreaHeight", i);
_CP_OPT(std::wstring) sAreaTop = settings.find_view_by_name(L"VisibleAreaTop", i);
_CP_OPT(std::wstring) sAreaLeft = settings.find_view_by_name(L"VisibleAreaLeft", i);
CP_XML_NODE(L"workbookView")
{
if (sActiveTable)
{
for (size_t i = 0; i < sheets_.size(); i++)
{
if (sheets_[i]->external_ref().empty() && sheets_[i]->name() == *sActiveTable)
{
CP_XML_ATTR(L"activeTab", i);
break;
}
}
}
if (sAreaWidth) CP_XML_ATTR(L"windowWidth", *sAreaWidth);
if (sAreaHeight) CP_XML_ATTR(L"windowHeight", *sAreaHeight);
if (sAreaTop) CP_XML_ATTR(L"yWindow", *sAreaTop);
if (sAreaLeft) CP_XML_ATTR(L"xWindow", *sAreaLeft);
CP_XML_ATTR(L"showSheetTabs", true);
CP_XML_ATTR(L"showVerticalScroll", true);
CP_XML_ATTR(L"showHorizontalScroll",true);
}
}
}
}
}
void xlsx_conversion_context::serialize_calcPr (std::wostream & strm)
{
}
void xlsx_conversion_context::start_body()
{}
void xlsx_conversion_context::end_body()
{}
oox_chart_context & xlsx_conversion_context::current_chart()
{
if (!charts_.empty())
{
return *charts_.back().get();
}
else
{
throw std::runtime_error("internal error");
}
}
xlsx_xml_worksheet & xlsx_conversion_context::current_sheet(int index)
{
if (!sheets_.empty())
{
if (index < 0) return *sheets_.back().get();
else return *sheets_[index].get();
}
else
{
throw std::runtime_error("internal error");
}
}
int xlsx_conversion_context::find_sheet_by_name(std::wstring tableName)
{
if (tableName.empty()) return -1;
if (0 == tableName.find(L"'"))
{
tableName = tableName.substr(1, tableName.length() - 2);
}
for (size_t i = 0; i < sheets_.size(); i++)
{
if (false == sheets_[i]->external_ref().empty() && sheets_[i]->name() == tableName)
return i;
}
return -1;
}
bool xlsx_conversion_context::start_table(const std::wstring& tableName, const std::wstring& tableStyleName, const std::wstring& externalRef)
{
get_table_context().start_table(tableName, tableStyleName, sheets_.size());
sheets_.push_back(xlsx_xml_worksheet::create(tableName, get_table_context().state()->get_table_hidden(), externalRef));
current_sheet().cols() << L"<cols>";
return true;
}
void xlsx_conversion_context::end_table()
{
if (false == get_table_context().state()->rowsHeaders_.empty())
{//first only ???
int header_start = get_table_context().state()->rowsHeaders_.front().first + 1;
int header_end = get_table_context().state()->rowsHeaders_.front().first + get_table_context().state()->rowsHeaders_.front().second;
std::wstring ref = L"'" + get_table_context().state()->tableName_ + L"'!$" + std::to_wstring(header_start) + L":$" + std::to_wstring(header_end);
get_table_context().set_print_titles(ref);
}
const std::wstring external_ref = current_sheet().external_ref();
if (false == external_ref.empty())
{
return;
}
const double lastWidht = table_column_last_width();
if (lastWidht > 0.0)
{
unsigned int cMin = get_table_context().columns_count() + 1;
unsigned int cMax = (std::max)((unsigned int)1024, get_table_context().columns_count() + 100);
if (cMin < 16384)
{
if (cMax > 16384) cMax = 16384;
CP_XML_WRITER(current_sheet().cols())
{
CP_XML_NODE(L"col")
{
//CP_XML_ATTR(L"collapsed", L"false");
//CP_XML_ATTR(L"hidden", L"false");
CP_XML_ATTR(L"max", cMax);
CP_XML_ATTR(L"min", cMin);
//CP_XML_ATTR(L"style", 0);
CP_XML_ATTR(L"width", lastWidht);
CP_XML_ATTR(L"customWidth", 1);
}
}
}
}
current_sheet().cols() << L"</cols>";
get_table_context().serialize_table_format (current_sheet().sheetFormat());
get_table_context().serialize_page_properties (current_sheet().page_properties());
get_table_context().serialize_header_footer (current_sheet().header_footer());
get_table_context().serialize_condFormattingEx (current_sheet().conditionalFormattingEx());
get_table_context().serialize_condFormatting (current_sheet().conditionalFormatting());
get_table_context().serialize_tableParts (current_sheet().tableParts(), current_sheet().sheet_rels());
get_table_context().serialize_autofilter (current_sheet().autofilter());
get_table_context().serialize_sort (current_sheet().sort());
get_table_context().serialize_merge_cells (current_sheet().mergeCells());
get_table_context().serialize_data_validation (current_sheet().dataValidations());
get_table_context().serialize_data_validation_x14 (current_sheet().dataValidationsX14());
get_table_context().serialize_protection (current_sheet().protection());
get_table_context().serialize_breaks (current_sheet().breaks());
get_drawing_context().set_odf_packet_path (root()->get_folder());
get_drawing_context().process_objects (get_table_metrics());
get_table_context().serialize_hyperlinks (current_sheet().hyperlinks());
get_table_context().serialize_ole_objects (current_sheet().ole_objects());
get_table_context().serialize_controls (current_sheet().controls());
get_table_context().dump_rels_hyperlinks (current_sheet().sheet_rels());
get_table_context().dump_rels_ole_objects (current_sheet().sheet_rels());
typedef std::multimap<std::wstring, int> _mapPivotsTableView;
std::pair<_mapPivotsTableView::iterator, _mapPivotsTableView::iterator> range;
range = mapPivotsTableView_.equal_range(current_sheet().name());
for (_mapPivotsTableView::iterator it = range.first; it != range.second; ++it)
{
current_sheet().sheet_rels().add(oox::relationship(L"pvId" + std::to_wstring(it->second),
L"http://schemas.openxmlformats.org/officeDocument/2006/relationships/pivotTable",
L"../pivotTables/pivotTable" + std::to_wstring(it->second) + L".xml"));
}
if (false == get_drawing_context().empty())
{
std::wstringstream strm;
get_drawing_context().serialize(strm);
const std::pair<std::wstring, std::wstring> drawingName
= drawing_context_handle_->add_drawing_xml(strm.str(), get_drawing_context().get_drawings() );
current_sheet().set_drawing_link(drawingName.first, drawingName.second);
}
if (false == get_drawing_context().vml_empty())
{
std::wstringstream strm;
get_drawing_context().serialize_vml(strm);
const std::pair<std::wstring, std::wstring> vml_drawingName
= drawing_context_handle_->add_drawing_vml(strm.str(), get_drawing_context().get_drawings() );
current_sheet().set_vml_drawing_link(vml_drawingName.first, vml_drawingName.second);
}
//get_table_context().serialize_background (current_sheet().picture());
if (false == get_comments_context().empty())
{
std::wstringstream strm;
get_comments_context().serialize(strm);
const std::pair<std::wstring, std::wstring> commentsName
= xlsx_comments_context_handle_.add_comments_xml(strm.str(), get_comments_context().get_comments() );
current_sheet().set_comments_link(commentsName.first, commentsName.second);
}
get_table_context().end_table();
}
void xlsx_conversion_context::add_control_props(const std::wstring & rid, const std::wstring & target, const std::wstring & props)
{
if (rid.empty()) return;
if (props.empty()) return;
control_props_.insert(std::make_pair(target, props));
current_sheet().sheet_rels().add(oox::relationship(rid,
L"http://schemas.openxmlformats.org/officeDocument/2006/relationships/ctrlProp",
L"../ctrlProps/" + target));
}
void xlsx_conversion_context::start_table_column(unsigned int repeated, const std::wstring & defaultCellStyleName, int & cMin, int & cMax, bool bHeader)
{
cMin = get_table_context().columns_count();
get_table_context().start_column(repeated, defaultCellStyleName, bHeader);
cMax = get_table_context().columns_count();
}
void xlsx_conversion_context::end_table_column()
{
}
int xlsx_conversion_context::current_table_column()
{
return xlsx_table_context_.current_column();
}
int xlsx_conversion_context::current_table_row()
{
return xlsx_table_context_.current_row();
}
std::wstring xlsx_conversion_context::current_cell_address()
{
int col = current_table_column();
int row = current_table_row();
return oox::getCellAddress(col < 0 ? 0 : col, row < 0 ? 0 : row); //under covered cell
}
void xlsx_conversion_context::start_office_spreadsheet(const odf_reader::office_element * elm)
{
spreadsheet_ = elm;
}
void xlsx_conversion_context::set_table_structure_protected(bool val)
{
table_structure_protected_ = val;
}
const odf_reader::office_element * xlsx_conversion_context::get_spreadsheet()
{
return spreadsheet_;
}
void xlsx_conversion_context::end_office_spreadsheet()
{}
void xlsx_conversion_context::start_paragraph(const std::wstring & styleName)
{
get_text_context()->start_paragraph(styleName);
}
void xlsx_conversion_context::end_paragraph()
{
if (get_text_context()->is_drawing_context())
{
get_drawing_context().process_objects(get_table_metrics());
if (false == get_drawing_context().empty())
{
std::wstringstream strm;
get_drawing_context().serialize(strm, L"a", true);
get_text_context()->add_paragraph(strm.str());
}
}
get_text_context()->end_paragraph();
}
void xlsx_conversion_context::start_span(const std::wstring & styleName)
{
get_text_context()->start_span(styleName);
}
void xlsx_conversion_context::end_span()
{
get_text_context()->end_span();
}
void xlsx_conversion_context::start_table_cell(size_t columnsSpanned, size_t rowsSpanned)
{
get_table_context().start_cell(columnsSpanned, rowsSpanned);
}
bool xlsx_conversion_context::in_table_cell()
{
return get_table_context().state()->in_cell;
}
void xlsx_conversion_context::end_table_cell()
{
get_table_context().end_cell();
}
void xlsx_conversion_context::start_table_covered_cell()
{
get_table_context().start_covered_cell();
}
void xlsx_conversion_context::end_table_covered_cell()
{
get_table_context().end_covered_cell();
}
void xlsx_conversion_context::set_current_cell_style_id(unsigned int xfId)
{
return get_table_context().set_current_cell_style_id(xfId);
}
int xlsx_conversion_context::get_current_cell_style_id()
{
return get_table_context().get_current_cell_style_id();
}
int xlsx_conversion_context::add_dxfId_style(const std::wstring& color, bool cellColor)
{
int dxfId = -1;
odf_reader::style_instance* instStyle =
root()->odf_context().styleContainer().style_default_by_type(odf_types::style_family::TableCell);
if (instStyle)
{
odf_reader::text_format_properties_ptr textFormats = calc_text_properties_content(instStyle);
odf_reader::graphic_format_properties_ptr graphicFormats = calc_graphic_properties_content(instStyle);
odf_reader::style_table_cell_properties_attlist cellFormats = calc_table_cell_properties(instStyle);
odf_types::color odf_color(color);
if (cellColor)
{
cellFormats.common_background_color_attlist_.fo_background_color_ = odf_color;
}
else
{
if (!textFormats)
textFormats = odf_reader::text_format_properties_ptr(new odf_reader::text_format_properties());
textFormats->fo_color_ = odf_color;
}
dxfId = get_style_manager().dxfId(textFormats, graphicFormats, &cellFormats);
}
return dxfId;
}
int xlsx_conversion_context::get_dxfId_style(const std::wstring &style_name)
{
if (style_name.empty()) return -1;
int dxfId = -1;
odf_reader::style_instance * instStyle =
root()->odf_context().styleContainer().style_by_name(style_name, odf_types::style_family::TableCell, false);
if (!instStyle)
instStyle = root()->odf_context().styleContainer().style_by_display_name(style_name, odf_types::style_family::TableCell, false);
if (instStyle)
{
odf_reader::text_format_properties_ptr textFormats = calc_text_properties_content(instStyle);
odf_reader::graphic_format_properties_ptr graphicFormats = calc_graphic_properties_content(instStyle);
odf_reader::style_table_cell_properties_attlist cellFormats = calc_table_cell_properties(instStyle);
dxfId = get_style_manager().dxfId(textFormats, graphicFormats, &cellFormats);
}
return dxfId;
}
std::pair<double, double> xlsx_conversion_context::getMaxDigitSize()
{
if (maxDigitSize_.first <= 0.1)
{
std::wstring font_name;
int font_size = 10;
std::vector<const odf_reader::style_instance *> instances;
odf_reader::odf_read_context & odfContext = root()->odf_context();
odf_reader::style_instance *inst = odfContext.styleContainer().style_default_by_type(odf_types::style_family::TableCell);
if (inst) instances.push_back(inst);
inst = odfContext.styleContainer().style_by_name(L"Default", odf_types::style_family::TableCell, false);
if (inst) instances.push_back(inst);
else
{
inst = odfContext.styleContainer().style_by_name(L"Normal", odf_types::style_family::TableCell, false);
if (inst) instances.push_back(inst);
}
odf_reader::text_format_properties_ptr textFormatProperties = calc_text_properties_content(instances);
if (textFormatProperties)
{
if (textFormatProperties->fo_font_family_)
font_name = textFormatProperties->fo_font_family_.get();
else
{
std::wstring style_font_name;
if (textFormatProperties->style_font_name_) style_font_name = textFormatProperties->style_font_name_.get();
else if (textFormatProperties->style_font_name_complex_) style_font_name = textFormatProperties->style_font_name_complex_.get();
else if (textFormatProperties->style_font_name_asian_) style_font_name = textFormatProperties->style_font_name_asian_.get();
odf_reader::fonts_container & fonts = odf_document_->odf_context().fontContainer();
odf_reader::font_instance * font = fonts.font_by_style_name(style_font_name);
if (font)
{
font_name = font->name();
}
}
if ((textFormatProperties->fo_font_size_) && (textFormatProperties->fo_font_size_->get_type() == odf_types::font_size::Length))
font_size = (int)(0.5 + textFormatProperties->fo_font_size_->get_length().get_value_unit(odf_types::length::pt));
}
if (font_name.empty()) font_name = L"Arial";
maxDigitSize_ = utils::GetMaxDigitSizePixels(font_name.c_str(), font_size, 96., 0, mediaitems_->applicationFonts());
}
return maxDigitSize_;
}
void xlsx_conversion_context::process_styles()
{
}
xlsx_table_metrics & xlsx_conversion_context::get_table_metrics()
{
return get_table_context().get_table_metrics();
}
void xlsx_conversion_context::start_drawing_context()
{//todooo если делать множественную вложенность -> vector
if (xlsx_drawing_context_) return;
xlsx_drawing_context_ = boost::shared_ptr<xlsx_drawing_context>(new xlsx_drawing_context(get_drawing_context_handle(), true));
}
void xlsx_conversion_context::end_drawing_context()
{
xlsx_drawing_context_.reset();
}
xlsx_drawing_context & xlsx_conversion_context::get_drawing_context()
{
if (xlsx_drawing_context_)
return *xlsx_drawing_context_;
else
return get_table_context().get_drawing_context();
}
xlsx_conditionalFormatting_context & xlsx_conversion_context::get_conditionalFormatting_context()
{
return get_table_context().state()->get_conditionalFormatting_context();
}
xlsx_drawing_context_handle_ptr & xlsx_conversion_context::get_drawing_context_handle()
{
return drawing_context_handle_;
}
xlsx_comments_context & xlsx_conversion_context::get_comments_context()
{
return get_table_context().get_comments_context();
}
xlsx_comments_context_handle & xlsx_conversion_context::get_comments_context_handle()
{
return xlsx_comments_context_handle_;
}
void xlsx_conversion_context::table_column_last_width(double w)
{
return get_table_context().table_column_last_width(w);
}
double xlsx_conversion_context::table_column_last_width()
{
return get_table_context().table_column_last_width();
}
void xlsx_conversion_context::start_hyperlink(const std::wstring & styleName)
{
xlsx_text_context_.start_hyperlink();
xlsx_text_context_.start_span(styleName);
get_table_context().start_hyperlink();
}
void xlsx_conversion_context::end_hyperlink(std::wstring const & href)
{
if (xlsx_text_context_.is_drawing_context() == false)
{
std::wstring content = xlsx_text_context_.end_span2();
xlsx_text_context_.end_hyperlink(get_table_context().end_hyperlink(current_cell_address(), href, L""));
}
else
{
std::wstring hId = get_table_context().get_drawing_context().add_hyperlink(href); // на внешний объект
xlsx_text_context_.end_hyperlink(hId);
xlsx_text_context_.end_span2();
}
}
void xlsx_conversion_context::add_pivot_sheet_source (const std::wstring & sheet_name, int index_table_view)
{//ващето в либре жесткая привязка что на одном листе тока одна сводная может быть ..
mapPivotsTableView_.insert(std::make_pair(sheet_name, index_table_view));
}
void xlsx_conversion_context::add_jsaProject(const std::string &content)
{
if (content.empty()) return;
output_document_->get_xl_files().add_jsaProject(content);
output_document_->get_content_types_file().add_or_find_default(L"bin");
}
void xlsx_conversion_context::start_text_context()
{
minor_text_contexts_.push_back(new xlsx_text_context(odf_document_->odf_context()));
}
void xlsx_conversion_context::end_text_context()
{
if (false == minor_text_contexts_.empty())
{
delete minor_text_contexts_.back();
minor_text_contexts_.pop_back();
}
}
xlsx_text_context* xlsx_conversion_context::get_text_context()
{
if (false == minor_text_contexts_.empty())
{
return minor_text_contexts_.back();
}
else
{
return &xlsx_text_context_;
}
}
}
}