Files
core/OdfFile/Reader/Format/table_xlsx.cpp
ElenaSubbotina 33c6640ce0 fix bug #75754
2025-07-09 18:15:26 +03:00

1487 lines
53 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 "table.h"
#include <xml/utils.h>
#include "odf_document.h"
#include <xml/simple_xml_writer.h>
#include <boost/lexical_cast.hpp>
#include "serialize_elements.h"
#include "odfcontext.h"
#include "number_style.h"
#include "calcs_styles.h"
#include "search_table_cell.h"
#include "../../Reader/Converter/xlsx_utils.h"
#include "../../Reader/Converter/xlsx_cell_format.h"
#include "../../Formulas/formulasconvert.h"
namespace cpdoccore {
using namespace odf_types;
namespace odf_reader {
static formulasconvert::odf2oox_converter formulas_converter;
int table_table_cell_content::xlsx_convert(oox::xlsx_conversion_context & Context, text_format_properties_ptr text_properties, bool need_cache)
{
if (elements_.empty()) return -1;
Context.get_table_context().start_cell_content();
Context.get_text_context()->set_cell_text_properties(text_properties);
for (size_t i = 0 ; i < elements_.size(); i++)
{
elements_[i]->xlsx_convert(Context);
if ((i < elements_.size() - 1) && (elements_[i + 1]->get_type() == typeTextP))
{
Context.get_text_context()->start_paragraph(L"");
Context.get_text_context()->start_span(L"");
Context.get_text_context()->add_text(L"\n");
Context.get_text_context()->end_span();
Context.get_text_context()->end_paragraph();
}
}
const int sharedStrId = Context.get_table_context().end_cell_content(need_cache);
return sharedStrId;
}
void table_table_row::xlsx_convert(oox::xlsx_conversion_context & Context)
{
bool bEndTable = Context.get_table_context().state()->get_end_table();
if (attlist_.table_number_rows_repeated_ > 1 && empty())
{
Context.get_table_context().state()->add_empty_row(attlist_.table_number_rows_repeated_, bHeader);
return;
}
if (attlist_.table_number_rows_repeated_ > 0x0f00 && empty_content_cells(false) || bEndTable)//0xf000 - conv_KDZO3J3xLIbZ5fC0HR0__xlsx.ods
{
Context.get_table_context().state()->set_end_table();
Context.get_table_context().state()->add_empty_row(attlist_.table_number_rows_repeated_, bHeader);
return; //conv_hSX8n3lVbhALjt0aafg__xlsx.ods, conv_MA2CauoNfX_7ejKS5eg__xlsx.ods
}
std::wostream & strm = Context.current_sheet().sheetData();
///обработка чтилей для роу -
size_t Default_Cell_style_in_row_ = 0;
const std::wstring rowStyleName = attlist_.table_style_name_.get_value_or(L"");
const std::wstring defaultCellStyleName = attlist_.table_default_cell_style_name_.get_value_or( L"");
style_instance * instStyle_CellDefault =
Context.root()->odf_context().styleContainer().style_by_name(defaultCellStyleName, style_family::TableCell, false/*false*/);
style_table_cell_properties * prop_CellDefault = NULL;
if ((instStyle_CellDefault) && (instStyle_CellDefault->content()))
prop_CellDefault = instStyle_CellDefault->content()->get_style_table_cell_properties();
//кастомные настройки стиля ячеек в данном роу
if (prop_CellDefault) //проверим что есть вообще кастом для роу- а потом уже посчитаем стиль
{
odf_reader::style_table_cell_properties_attlist cellFormatProperties = calc_table_cell_properties(instStyle_CellDefault);
Default_Cell_style_in_row_ = Context.get_style_manager().xfId(NULL,NULL, &cellFormatProperties, NULL, L"", 0, true);
}
else //стиля ячеек для строки нет глянем что там внутри строки в последней ячейке
{
//возьмем стиль из последнего cell если он повторяющийся (тогда и ячейки вхолостую ненадо писать)
int ind_last_cell = content_.size()-1;
table_table_cell *last_cell = NULL;
if (ind_last_cell > 0)
last_cell = dynamic_cast<table_table_cell *>(content_[ind_last_cell].get());
}
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
bool skip_next_row = false;
std::wstring ht = L"";
double row_height = 0.0;
bool bBreakAfter = false, bBreakBefore = false;
odf_read_context & odfContext = Context.root()->odf_context();
odf_reader::style_instance * rowStyle = odfContext.styleContainer().style_by_name(rowStyleName, odf_types::style_family::TableRow,false/*false*/);
if ((rowStyle) && (rowStyle->content()))
{
const odf_reader::style_table_row_properties * prop = rowStyle->content()->get_style_table_row_properties();
if ((prop) && (prop->attlist_.style_row_height_))
{
row_height = prop->attlist_.style_row_height_->get_value_unit(odf_types::length::pt);
if ((prop->attlist_.style_use_optimal_row_height_) &&
(*prop->attlist_.style_use_optimal_row_height_==true))
{
//автоматическая подстройка высоты.
//нету в оох
//todooo высилить по текущему шрифту размер у (двойной) и сравнить с заданным - перебить !!!
}
std::wstringstream ht_s;
ht_s.precision(3);
ht_s << std::fixed << row_height;
ht = ht_s.str();
}
if ((prop->attlist_.common_break_attlist_.fo_break_before_) &&
(prop->attlist_.common_break_attlist_.fo_break_before_->get_type() == odf_types::fo_break::Page))
{
bBreakBefore = true;
}
else if ((prop) && ((prop->attlist_.common_break_attlist_.fo_break_after_) &&
(prop->attlist_.common_break_attlist_.fo_break_after_->get_type() == odf_types::fo_break::Page)))
{
bBreakAfter = true;
}
}
int row_current = Context.current_table_row() + 1;
bool hidden = attlist_.table_visibility_.get_type() == table_visibility::Collapse;
bool filter = attlist_.table_visibility_.get_type() == table_visibility::Filter;
for (unsigned int i = 0; i < attlist_.table_number_rows_repeated_; ++i)
{
Context.get_table_context().state()->start_row(rowStyleName, defaultCellStyleName, bHeader);
if (bBreakBefore) Context.get_table_context().state()->set_row_break_before();
if (bBreakAfter) Context.get_table_context().state()->set_row_break_after();
if (!skip_next_row)
{
CP_XML_WRITER(strm)
{
CP_XML_NODE(L"row")
{
CP_XML_ATTR(L"r", Context.current_table_row() + 1);
if (false == Context.get_table_context().state()->group_rows_.empty())
{
//std::wstring str_spans = std::to_wstring(Context.get_table_context().state()->group_row_.count);
//str_spans = str_spans + L":";
int columns = Context.get_table_context().columns_count();
if (columns > 0x4000) columns = 0x4000;
std::wstring str_spans = L"1:" + std::to_wstring(columns);
ht = L"";
CP_XML_ATTR(L"collapsed", Context.get_table_context().state()->group_rows_.back());
CP_XML_ATTR(L"outlineLevel", Context.get_table_context().state()->group_rows_.size());
CP_XML_ATTR(L"spans", str_spans);
if (Context.get_table_context().state()->group_rows_.back()) hidden = false;
}
if (hidden || filter)
{
CP_XML_ATTR(L"hidden", 1);
}
if (!ht.empty())
{
CP_XML_ATTR(L"ht", ht);
CP_XML_ATTR(L"customHeight", 1);
}
if (Default_Cell_style_in_row_ > 0)
{
CP_XML_ATTR(L"customFormat", 1);
CP_XML_ATTR(L"s", Default_Cell_style_in_row_ );
}
CP_XML_STREAM();
for (size_t i = 0 ; i < content_.size(); i++)
{
office_element_ptr & elm = content_[i];
if (i == content_.size() - 1) //mark last cell in row (for skip empty styled)
{
table_table_cell *cell = dynamic_cast<table_table_cell*> (elm.get());
table_covered_table_cell *covered_cell = dynamic_cast<table_covered_table_cell*>(elm.get());
if (cell) cell->last_cell_ = true;
else if (covered_cell) covered_cell->last_cell_ = true;
}
elm->xlsx_convert(Context);
}
}
}
}
Context.get_table_context().state()->end_row();
if (Context.get_table_context().state()->is_empty_row() && Context.get_table_context().state()->group_rows_.empty())
{
skip_next_row = true;
if (attlist_.table_number_rows_repeated_ > 0xf000)
break;//Уведомление_оручении.ods (1 лист)
}
if (content_.size() > 0 && attlist_.table_number_rows_repeated_ > 1000)
{
table_table_cell * table_cell = dynamic_cast<table_table_cell *>(content_[0].get());
if ((table_cell) && (table_cell->attlist_.table_number_columns_repeated_ > 1000))
{
break;//Уведомление_оручении.ods (2 лист)
}
}
}
Context.get_table_metrics().add_rows(attlist_.table_number_rows_repeated_, !hidden ? row_height : 0.0);
}
void table_table_rows::xlsx_convert(oox::xlsx_conversion_context & Context)
{
for (size_t i = 0; i < content_.size(); i++)
{
content_[i]->xlsx_convert(Context);
}
}
void table_table_header_rows::xlsx_convert(oox::xlsx_conversion_context & Context)
{
for (size_t i = 0; i < content_.size(); i++)
{
content_[i]->xlsx_convert(Context);
}
}
void table_rows::xlsx_convert(oox::xlsx_conversion_context & Context)
{
if (table_table_rows_)
table_table_rows_->xlsx_convert(Context);
else
{
while (table_table_row_.size() > 1)
{
table_table_row* row_last = dynamic_cast<table_table_row*>(table_table_row_[table_table_row_.size() - 1].get());
table_table_row* row_last_1 = dynamic_cast<table_table_row*>(table_table_row_[table_table_row_.size() - 2].get());
std::wstring style = row_last->attlist_.table_style_name_.get_value_or(L"");
std::wstring style_1 = row_last->attlist_.table_style_name_.get_value_or(L"");
if (style != style_1)break;
if (row_last_1->empty_content_cells() == false) break;
if (row_last->empty_content_cells() == false) break;
row_last_1->attlist_.table_number_rows_repeated_ += row_last->attlist_.table_number_rows_repeated_;
table_table_row_.pop_back();
}
for (size_t i = 0; i < table_table_row_.size(); i++)
{
table_table_row_[i]->xlsx_convert(Context);
}
}
}
void table_rows_no_group::xlsx_convert(oox::xlsx_conversion_context & Context)
{
table_rows_1_.xlsx_convert(Context);
if (table_table_header_rows_)
table_table_header_rows_->xlsx_convert(Context);
table_rows_2_.xlsx_convert(Context);
}
void table_rows_and_groups::xlsx_convert(oox::xlsx_conversion_context & Context)
{
for (size_t i = 0; i < content_.size(); i++)
{
content_[i]->xlsx_convert(Context);
}
}
void table_table_row_group::xlsx_convert(oox::xlsx_conversion_context & Context)
{
Context.get_table_context().state()->start_table_row_group(attlist_.table_display_);
table_rows_and_groups_.xlsx_convert(Context);
Context.get_table_context().state()->end_table_row_group();
}
void table_table::xlsx_convert(oox::xlsx_conversion_context & Context)
{
std::wstring tableStyleName = attlist_.table_style_name_.get_value_or(L"");
std::wstring tableName = attlist_.table_name_.get_value_or(L"");
_CP_LOG << L"[info][xlsx] process table \"" << tableName << L"\"\n" << std::endl;
if (office_forms_)
{
office_forms_->xlsx_convert(Context);
}
std::wstring externalRef;
std::wstring externalRef2;
if (table_table_source_)
{
table_table_source* table_source = dynamic_cast<table_table_source*>( table_table_source_.get() );
if ( table_source)
{
if (table_source->table_linked_source_attlist_.xlink_attlist_.href_)
{
externalRef = *table_source->table_linked_source_attlist_.xlink_attlist_.href_;
}
if (table_source->attlist_.table_table_name_)
{
externalRef2 = tableName; // - used in formula
tableName = *table_source->attlist_.table_table_name_; // - only link to file
size_t pos = externalRef2.find(L"#");
if (pos != std::wstring::npos) externalRef2 = externalRef2.substr(0, pos);
XmlUtils::replace_all(externalRef2, L"'", L"");
}
}
}
Context.start_table(tableName, tableStyleName, externalRef2);
if (attlist_.table_protected_)
{
Context.get_table_context().set_protection(true, attlist_.table_protection_key_.get_value_or(L""),
attlist_.table_protection_key_digest_algorithm_.get_value_or(L""));
table_table_protection* prot = dynamic_cast<table_table_protection*>( table_protection_.get() );
if (prot)
{
if (prot->select_protected_cells)
Context.get_table_context().state()->set_protection_select_protected_cells(*prot->select_protected_cells);
if (prot->select_unprotected_cells)
Context.get_table_context().state()->set_protection_select_unprotected_cells(*prot->select_unprotected_cells);
if (prot->insert_columns)
Context.get_table_context().state()->set_protection_insert_columns(*prot->insert_columns);
if (prot->insert_rows)
Context.get_table_context().state()->set_protection_insert_rows(*prot->insert_rows);
if (prot->delete_columns)
Context.get_table_context().state()->set_protection_delete_columns(*prot->delete_columns);
if (prot->delete_rows)
Context.get_table_context().state()->set_protection_delete_rows(*prot->delete_rows);
}
}
if (attlist_.table_print_ranges_)
{
Context.get_table_context().set_print_area(*attlist_.table_print_ranges_);
}
table_columns_and_groups_.xlsx_convert(Context);
// check last rows for equal style and empties - collapsed
//<table:table-row table:style-name="ro3" table:number-rows-repeated="65353">
// <table:table-cell table:style-name="ce14" table:number-columns-repeated="5"/>
// <table:table-cell table:number-columns-repeated="1019"/>
//</table:table-row>
//<table:table-row table:style-name="ro3" table:number-rows-repeated="983017">
// <table:table-cell table:number-columns-repeated="1024"/>
//</table:table-row>
//<table:table-row table:style-name="ro3">
// <table:table-cell table:number-columns-repeated="1024"/>
//</table:table-row>
if (table_rows_and_groups_.content_.empty() == false && table_rows_and_groups_.content_.back()->get_type() == typeTableTableRowNoGroup)
{
table_rows_no_group * rows = dynamic_cast<table_rows_no_group*>(table_rows_and_groups_.content_.back().get());
rows->table_rows_1_.remove_equals_empty();
rows->table_rows_2_.remove_equals_empty();
}
table_rows_and_groups_.xlsx_convert(Context);
if (table_shapes_)
table_shapes_->xlsx_convert(Context);
if (conditional_formats_)
conditional_formats_->xlsx_convert(Context);
if (sparkline_groups_)
{
sparkline_groups_->xlsx_convert(Context);
}
for (size_t i = 0 ; i < table_named_.size(); i++)
{
table_named_[i]->xlsx_convert(Context);
}
Context.end_table();
}
void table_columns::xlsx_convert(oox::xlsx_conversion_context & Context)
{
if (table_table_columns_)
table_table_columns_->xlsx_convert(Context);
for (size_t i = 0; i < table_table_column_.size(); i++)
{
table_table_column_[i]->xlsx_convert(Context);
}
}
void table_columns_no_group::xlsx_convert(oox::xlsx_conversion_context & Context)
{
table_columns_1_.xlsx_convert(Context);
if (table_table_header_columns_)
table_table_header_columns_->xlsx_convert(Context);
table_columns_2_.xlsx_convert(Context);
}
void table_columns_and_groups::xlsx_convert(oox::xlsx_conversion_context & Context)
{
for (size_t i = 0; i < content_.size(); i++)
{
office_element_ptr & elm = content_[i];
elm->xlsx_convert(Context);
}
}
void table_table_header_columns::xlsx_convert(oox::xlsx_conversion_context & Context)
{
for (size_t i = 0; i < content_.size(); i++)
{
content_[i]->xlsx_convert(Context);
}
}
void table_table_column_group::xlsx_convert(oox::xlsx_conversion_context & Context)
{
Context.get_table_context().state()->start_table_column_group(attlist_.table_display_);
table_columns_and_groups_.xlsx_convert(Context);
Context.get_table_context().state()->end_table_column_group();
}
namespace {
// see ECMA-376 page 1768
double pixToSize(double pixels, double maxDigitSize)
{
if (pixels < 8) pixels = 8; //УВЕДОМЛЕНИЕ О ПРИБЫТИИ ИНОСТРАННОГО ГРАЖДАНИНА.ods
return (int(( pixels /*/ 0.75*/ - 5)/ maxDigitSize * 100. + 0.5)) /100. * 0.98; // * 9525. * 72.0 / (360000.0 * 2.54);
}
}
void table_table_column::xlsx_convert(oox::xlsx_conversion_context & Context)
{
std::wostream & strm = Context.current_sheet().cols();
const unsigned int columnsRepeated = attlist_.table_number_columns_repeated_;
const std::wstring styleName = attlist_.table_style_name_.get_value_or(L"");
const std::wstring defaultCellStyleName = attlist_.table_default_cell_style_name_.get_value_or(L"");
int cMin = 0, cMax = 0;
Context.start_table_column(columnsRepeated, defaultCellStyleName, cMin, cMax, bHeader);
if ( cMin > 16384 ) return;
if ( cMax > 16384 ) return;
double pt_width = 0.0;
double cm_width = 0.0;
double in_width = 0.0;
CP_XML_WRITER(strm)
{
CP_XML_NODE(L"col")
{
bool hidden = attlist_.table_visibility_.get_type() == table_visibility::Collapse;
if (false == Context.get_table_context().state()->group_columns_.empty())
{
CP_XML_ATTR(L"outlineLevel", Context.get_table_context().state()->group_columns_.size());
CP_XML_ATTR(L"collapsed", Context.get_table_context().state()->group_columns_.back());
if (Context.get_table_context().state()->group_columns_.back()) hidden = false;
}
if (hidden)
{
CP_XML_ATTR(L"hidden", L"true");
}
CP_XML_ATTR(L"max", cMax);
CP_XML_ATTR(L"min", (cMin + 1));
if (attlist_.table_style_name_)
{
if (style_instance * inst =
Context.root()->odf_context().styleContainer().style_by_name(defaultCellStyleName, style_family::TableCell, false/*false*/))
{
if (inst->content())
{
if (const style_table_cell_properties * prop = inst->content()->get_style_table_cell_properties())
{//сделать проверку чтоб сюда не попал дефолтный, то сть пустой стиль
odf_reader::style_table_cell_properties_attlist cellFormatProperties = calc_table_cell_properties(inst);
bool set_default = false;
if (columnsRepeated > 100) set_default = true;
size_t style_ = Context.get_style_manager().xfId(NULL, NULL, &cellFormatProperties, NULL, L"", 0, set_default);
//if (set_default)
// CP_XML_ATTR(L"style", style_ );
}
}
}
_CP_OPT(double) width;
const std::wstring colStyleName = attlist_.table_style_name_.get_value_or(L"");
if (style_instance * inst = Context.root()->odf_context().styleContainer().style_by_name(colStyleName, style_family::TableColumn, false))
{
if (inst->content())
{
if (const style_table_column_properties * prop = inst->content()->get_style_table_column_properties())
{
if ((prop->attlist_.loext_column_width_sym_) && (*prop->attlist_.loext_column_width_sym_ > 0))
{
width = *prop->attlist_.loext_column_width_sym_;
CP_XML_ATTR(L"width", *width);
CP_XML_ATTR(L"customWidth", true);
Context.table_column_last_width(*width);
}
if (prop->attlist_.style_column_width_)
{
pt_width = prop->attlist_.style_column_width_->get_value_unit(length::pt);
cm_width = prop->attlist_.style_column_width_->get_value_unit(length::cm);
in_width = prop->attlist_.style_column_width_->get_value_unit(length::inch);
if (!width)
{
if (hidden)
{
in_width = 0.0;
}
const double pixDpi = in_width * 96.;
width = pixToSize(pixDpi, Context.getMaxDigitSize().first);
// see ECMA-376 page 1768
if (in_width > 0)
CP_XML_ATTR(L"width", *width);
CP_XML_ATTR(L"customWidth", true);
Context.table_column_last_width(*width);
}
}
if ((prop->attlist_.common_break_attlist_.fo_break_before_) &&
(prop->attlist_.common_break_attlist_.fo_break_before_->get_type() == odf_types::fo_break::Page))
{
Context.get_table_context().state()->set_column_break_before();
}
else if ((prop->attlist_.common_break_attlist_.fo_break_after_) &&
(prop->attlist_.common_break_attlist_.fo_break_after_->get_type() == odf_types::fo_break::Page))
{
Context.get_table_context().state()->set_column_break_after();
}
}
}
}
if (!width)//??? default set
{
width = 11.52;
CP_XML_ATTR(L"width", *width);
CP_XML_ATTR(L"customWidth", false);
Context.table_column_last_width(*width);
}
}
} // col
} // CP_XML_WRITER
if (pt_width < 1)
{
pt_width = 2.26 * 28.34467120181406; // 2.26 cm default
}
Context.get_table_metrics().add_cols(cMax - cMin, pt_width);
Context.end_table_column();
}
namespace {
std::wstring SearchCellDataStyle(oox::xlsx_conversion_context & Context, std::wstring const & styleName)
{
odf_read_context & odfContext = Context.root()->odf_context();
std::wstring styleStr = styleName;
for (;;)
{
style_instance * styleInstance =
odfContext.styleContainer().style_by_name(styleStr, style_family::TableCell,false);
if (!styleInstance->data_style_name().empty())
return styleInstance->data_style_name();
if (!styleInstance->parent_name().empty())
styleStr = styleInstance->parent_name();
else
break;
}
return L"";
}
std::wstring SearchCellDataStyle(oox::xlsx_conversion_context & Context, style_instance * styleInstance)
{
if (!styleInstance)
return L"";
odf_read_context & odfContext = Context.root()->odf_context();
for (;;)
{
if (!styleInstance->data_style_name().empty())
return styleInstance->data_style_name();
if (styleInstance->parent())
styleInstance = styleInstance->parent();
else
break;
}
return L"";
}
std::wstring CalcCellDataStyle(oox::xlsx_conversion_context & Context,
std::wstring const & defaultColumnCellStyleName,
std::wstring const & defaultRowCellStyleName,
std::wstring const & cellStyleName
)
{
odf_read_context & odfContext = Context.root()->odf_context();
style_instance * defaultCellStyle = odfContext.styleContainer().style_default_by_type(style_family::TableCell);
style_instance * defaultColumnCellStyle = odfContext.styleContainer().style_by_name (defaultColumnCellStyleName, style_family::TableCell,false);
style_instance * defaultRowCellStyle = odfContext.styleContainer().style_by_name(defaultRowCellStyleName, style_family::TableCell,false);
style_instance * cellStyle = odfContext.styleContainer().style_by_name(cellStyleName, style_family::TableCell,false);
std::wstring data_style = L"";
if (defaultCellStyle)
data_style = SearchCellDataStyle(Context, defaultCellStyle);
{
std::wstring ds1 = SearchCellDataStyle(Context, defaultColumnCellStyle);
if (!ds1.empty())
data_style = ds1;
}
{
std::wstring ds1 = SearchCellDataStyle(Context, defaultRowCellStyle);
if (!ds1.empty())
data_style = ds1;
}
{
std::wstring ds1 = SearchCellDataStyle(Context, cellStyle);
if (!ds1.empty())
data_style = ds1;
}
return data_style;
}
}
void table_table_cell::xlsx_convert(oox::xlsx_conversion_context & Context)
{
bool bExternalTable = !Context.current_sheet().external_ref().empty();
std::wostream & strm = Context.current_sheet().sheetData();
const common_value_and_type_attlist & attr = attlist_.common_value_and_type_attlist_;
std::wstring formula = attlist_.table_formula_.get_value_or(L"");
// вычислить стиль для ячейки
std::wstring cellStyleName = attlist_.table_style_name_.get_value_or(L"");
std::wstring columnStyleName = Context.get_table_context().default_column_cell_style();
std::wstring rowStyleName = Context.get_table_context().default_row_cell_style();
if (attlist_.table_number_columns_repeated_ > 1)
columnStyleName.clear(); // могут быть разные стили колонок Book 24.ods
odf_read_context & odfContext = Context.root()->odf_context();
style_instance *defaultCellStyle = NULL, *defaultColumnCellStyle = NULL, *defaultRowCellStyle = NULL, *cellStyle = NULL;
try
{
if (is_present_hyperlink_)
{
defaultCellStyle = odfContext.styleContainer().style_by_name(L"Hyperlink", style_family::TableCell, true);
}
if (!defaultCellStyle)
{
defaultCellStyle = odfContext.styleContainer().style_default_by_type(style_family::TableCell);
}
defaultColumnCellStyle = odfContext.styleContainer().style_by_name(columnStyleName, style_family::TableCell, false);
defaultRowCellStyle = odfContext.styleContainer().style_by_name(rowStyleName, style_family::TableCell, false);
cellStyle = odfContext.styleContainer().style_by_name(cellStyleName, style_family::TableCell, false);
}
catch(...)
{
_CP_LOG << L"[error]: style wrong\n";
}
std::wstring data_style = CalcCellDataStyle(Context, columnStyleName, rowStyleName, cellStyleName);
// стили не наследуются
std::vector<const style_instance *> instances;
instances.push_back(defaultCellStyle);
if (defaultColumnCellStyle)
instances.push_back(defaultColumnCellStyle);
if (defaultRowCellStyle)
{
if (instances.size() > 1)
instances[1] = defaultRowCellStyle;
else
instances.push_back(defaultRowCellStyle);
}
if (cellStyle)
{
if (instances.size() > 1)
instances[1] = cellStyle;
else
instances.push_back(cellStyle);
}
text_format_properties_ptr textFormatProperties = calc_text_properties_content (instances);
paragraph_format_properties parFormatProperties = calc_paragraph_properties_content (instances);
style_table_cell_properties_attlist cellFormatProperties = calc_table_cell_properties (instances);
//-------------------------------------------------------------------------------------------------------------------------------
std::wstring num_format;
office_value_type::type num_format_type = office_value_type::Custom;
if (false == data_style.empty())
{
num_format = Context.get_num_format_context().find_complex_format(data_style, num_format_type);
if (num_format.empty())
{
office_element_ptr elm = odfContext.numberStyles().find_by_style_name(data_style);
number_style_base *num_style = dynamic_cast<number_style_base*>(elm.get());
if (num_style)
{
Context.get_num_format_context().start_complex_format(data_style);
num_style->oox_convert(Context.get_num_format_context());
Context.get_num_format_context().end_complex_format();
num_format = Context.get_num_format_context().get_last_format();
num_format_type = Context.get_num_format_context().type();
}
}
}
//------------------------------------------------------------------------
std::wstring number_val;
_CP_OPT(bool) bool_val;
_CP_OPT(std::wstring) str_val;
oox::XlsxCellType::type xlsx_value_type = oox::XlsxCellType::s;
office_value_type::type odf_value_type = office_value_type::Custom;
if (attr.office_value_type_)
odf_value_type = attr.office_value_type_->get_type();
if ((odf_value_type == office_value_type::Float) ||
(odf_value_type == office_value_type::Custom && attr.office_value_))// ??
{
xlsx_value_type = oox::XlsxCellType::n;
number_val = attr.office_value_.get_value_or(L"");
if (num_format_type == office_value_type::Time ||
num_format_type == office_value_type::Date ||
num_format_type == office_value_type::Currency)
{//тип формата данных из стиля не соответствует формату анных ячейки
num_format.clear();
num_format_type = office_value_type::Custom;
}
}
else if (odf_value_type == office_value_type::Percentage)
{
xlsx_value_type = oox::XlsxCellType::n;
number_val = attr.office_value_.get_value_or(L"");
if (num_format_type == office_value_type::Time ||
num_format_type == office_value_type::Date ||
num_format_type == office_value_type::Currency)
{//тип формата данных из стиля не соответствует формату анных ячейки
num_format.clear();
num_format_type = office_value_type::Percentage;
}
}
else if (odf_value_type == office_value_type::Currency)
{
xlsx_value_type = oox::XlsxCellType::n;
number_val = attr.office_value_.get_value_or(L"");
}
else if ((odf_value_type == office_value_type::Date) ||
(odf_value_type == office_value_type::Custom && attr.office_date_value_))
{
if (attr.office_date_value_)
{
int y, m, d;
_CP_OPT(int) h, min, sec;
if (oox::parseDateTime(attr.office_date_value_.get(), y, m, d, h, min, sec))
{
boost::int64_t intDate = oox::convertDate(y, m, d);
_CP_OPT(double) dTime;
if (h && min)
{
dTime = oox::convertTime(*h, *min, sec.get_value_or(0));
}
if (intDate > 0)
{
if (dTime)
{
number_val = XmlUtils::ToString(*dTime + intDate);
}
else
{
number_val = boost::lexical_cast<std::wstring>(intDate);
}
xlsx_value_type = oox::XlsxCellType::n;
if (num_format_type == office_value_type::Currency)
{//тип формата данных из стиля не соответствует формату данных ячейки
num_format.clear();
num_format_type = office_value_type::Date;
}
if (num_format.empty())
num_format = Context.get_num_format_context().get_last_date_format();
}
else
{
str_val = attr.office_date_value_.get();
}
}
}
}
else if ((odf_value_type == office_value_type::Time) ||
(odf_value_type == office_value_type::Custom && attr.office_time_value_))
{
if (attr.office_time_value_)
{
const std::wstring tv = attr.office_time_value_.get();
int h, m;
double s;
if (oox::parseTime(tv, h, m, s))
{
double dTime = oox::convertTime(h, m, s);
if (dTime >= 0)
{
number_val = boost::lexical_cast<std::wstring>(dTime);
xlsx_value_type = oox::XlsxCellType::n;
if (num_format_type == office_value_type::Currency)
{//тип формата данных из стиля не соответствует формату анных ячейки
num_format.clear();
num_format_type = office_value_type::Time;
}
if (num_format.empty())
num_format = Context.get_num_format_context().get_last_time_format();
}
else
{
str_val = tv;
}
}
}
}
else if ((odf_value_type == office_value_type::Boolean) ||
(odf_value_type == office_value_type::Custom && attr.office_boolean_value_))
{
xlsx_value_type = oox::XlsxCellType::b;
if (attr.office_boolean_value_) bool_val = oox::parseBoolVal(attr.office_boolean_value_.get());
num_format.clear();
num_format_type = office_value_type::Boolean;
}
else if ((odf_value_type == office_value_type::String) ||
(odf_value_type == office_value_type::Custom && attr.office_string_value_))
{
xlsx_value_type = oox::XlsxCellType::str;
if (attr.office_string_value_) str_val = attr.office_string_value_.get();
num_format.clear();
num_format_type = office_value_type::String;
}
//----------------------------------------------------------------------------------------------------------------------------------
bool is_style_visible = (!cellStyleName.empty() || defaultColumnCellStyle || !num_format.empty()) ? true : false;
if (count_paragraph > 1)
{
is_style_visible = true;
cellFormatProperties.fo_wrap_option_ = odf_types::wrap_option::Wrap;
}
if (bExternalTable)
{
is_style_visible = false;
xlsx_value_type = oox::XlsxCellType::str;
}
oox::xlsx_cell_format cellFormat;
cellFormat.set_cell_type(xlsx_value_type);
cellFormat.set_num_format(oox::odf_string_to_build_in(odf_value_type));
bool is_data_visible = ( false == content_.elements_.empty() ||
attlist_.table_content_validation_name_ || !formula.empty() || !number_val.empty() || str_val || bool_val );
if (attlist_.table_number_columns_repeated_ < 199 && last_cell_) last_cell_ = false;
unsigned int cell_repeated_max = Context.current_table_column() + attlist_.table_number_columns_repeated_ + 1;
if (cell_repeated_max >= 1024 && cellStyleName.empty() && last_cell_ && !is_data_visible)
{//Book 24.ods
return;
}
size_t xfId_last_set = 0;
if (is_style_visible)
{
xfId_last_set = Context.get_style_manager().xfId(textFormatProperties, &parFormatProperties, &cellFormatProperties,
&cellFormat, num_format, num_format_type, false, is_style_visible);
}
bool need_cache_convert = false;
if (number_val.empty() && !bool_val)
{
if (false == formula.empty())
xlsx_value_type = oox::XlsxCellType::str;
else
{
need_cache_convert = true;
}
}
//---------------------------------------------------------------------------------------------------------
int sharedStringId = -1;
int empty_cell_count = 0;
bool skip_next_cell = false;
for (unsigned int r = 0; r < attlist_.table_number_columns_repeated_; ++r)
{
Context.start_table_cell ( attlist_extra_.table_number_columns_spanned_ - 1 ,
attlist_extra_.table_number_rows_spanned_ - 1 );
if (is_style_visible)
Context.set_current_cell_style_id(xfId_last_set);
//---------------------------------------------------------------------------------------------------------
if (bExternalTable)
{
std::wstringstream str;
content_.text_to_stream(str);
str_val = str.str();
}
else
{
sharedStringId = content_.xlsx_convert(Context, textFormatProperties, need_cache_convert);
}
if (xlsx_value_type == oox::XlsxCellType::str || xlsx_value_type == oox::XlsxCellType::inlineStr)
{
int index = Context.get_table_context().in_database_range();
if (index >= 0)
{
if (sharedStringId >= 0)
{
std::wstringstream strm;
content_.text_to_stream(strm);
Context.get_table_context().set_database_range_value(index, strm.str());
}
else if (str_val)
{
Context.get_table_context().set_database_range_value(index, str_val.get());
}
}
}
if (sharedStringId >= 0)
{
xlsx_value_type = oox::XlsxCellType::s;//в случае текста, если он есть берем кэшированное значение
}
//---------------------------------------------------------------------------------------------------------
if (skip_next_cell)
{
Context.end_table_cell();
break;
}
// пустые ячейки пропускаем.
if ( is_data_visible || ((cellStyle || defaultColumnCellStyle) && is_style_visible))
{
std::wstring ref = oox::getCellAddress(Context.current_table_column(), Context.current_table_row());
if (attlist_.table_content_validation_name_)
{
Context.get_dataValidations_context().activate(*attlist_.table_content_validation_name_, /*ref*/Context.current_table_column(), Context.current_table_row());
}
CP_XML_WRITER(strm)
{
CP_XML_NODE(bExternalTable ? L"cell" : L"c")
{
CP_XML_ATTR(L"r", ref);
if (false == bExternalTable)
{
CP_XML_ATTR(L"s", xfId_last_set);
}
std::wstring type = oox::cellType2Str(xlsx_value_type);
if (false == type.empty()) CP_XML_ATTR(L"t", type);
if (false == bExternalTable && false == formula.empty())
{
const std::wstring xlsxFormula = formulas_converter.convert(formula);
if (!xlsxFormula.empty())
{
CP_XML_NODE(L"f")
{
if (attlist_extra_.table_number_matrix_columns_spanned_ && attlist_extra_.table_number_matrix_rows_spanned_)
{
std::wstring ref = oox::getCellAddress(Context.current_table_column(), Context.current_table_row());
ref += L":";
ref += oox::getCellAddress(Context.current_table_column() + *attlist_extra_.table_number_matrix_columns_spanned_ - 1,
Context.current_table_row() + *attlist_extra_.table_number_matrix_rows_spanned_ - 1);
CP_XML_ATTR(L"ref", ref);
CP_XML_ATTR(L"t", L"array");
CP_XML_ATTR(L"aca", false);
}
CP_XML_CONTENT(XmlUtils::EncodeXmlString(xlsxFormula));
}
}
}
if (sharedStringId >= 0 && xlsx_value_type == oox::XlsxCellType::s)
{
CP_XML_NODE(L"v") { CP_XML_CONTENT(sharedStringId); }
}
else if ((xlsx_value_type == oox::XlsxCellType::str || xlsx_value_type == oox::XlsxCellType::inlineStr) && str_val)
{
CP_XML_NODE(L"v") { CP_XML_CONTENT(XmlUtils::EncodeXmlString(str_val.get())); }
}
else if (!number_val.empty())
{
CP_XML_NODE(L"v") { CP_XML_CONTENT(number_val);}
}
else if (xlsx_value_type == oox::XlsxCellType::b && bool_val)
{
CP_XML_NODE(L"v") { CP_XML_CONTENT((int)(bool_val.get())); }
}
}
if ( is_data_visible || (cellStyle && is_style_visible && !last_cell_))
{
Context.get_table_context().state()->non_empty_row();
empty_cell_count = 0 ;
}
else
{
empty_cell_count++;
//Уведомление_оручении.ods - 13 повторов пустых с cellStyle=NULL - нужные !!!
if (empty_cell_count > 19 && last_cell_&& (attlist_.table_number_columns_repeated_> 299 || cellStyle == NULL))
{//пишем простыню только если задан стиль тока для этих ячеек
skip_next_cell = true;
}
}
}
}
else
{
if (last_cell_) // Vehicle log book.ods (row = 24 and more)
skip_next_cell = true;
}
Context.end_table_cell();
}
}
void table_covered_table_cell::xlsx_convert(oox::xlsx_conversion_context & Context)
{
bool bExternalTable = !Context.current_sheet().external_ref().empty();
std::wostream & strm = Context.current_sheet().sheetData();
const common_value_and_type_attlist & attr = attlist_.common_value_and_type_attlist_;
office_value_type::type odf_value_type = office_value_type::Custom;
oox::XlsxCellType::type xlsx_value_type = oox::XlsxCellType::s;
std::wstring formula = attlist_.table_formula_.get_value_or(L"");
std::wstring number_val;
_CP_OPT(bool) bool_val;
_CP_OPT(std::wstring) str_val;
std::wstring num_format;
size_t xfId_last_set = 0;
int empty_cell_count = 0;
bool skip_next_cell = false;
bool is_style_visible = true;
bool is_data_visible = false;
// вычислить стиль для ячейки
std::wstring cellStyleName = attlist_.table_style_name_.get_value_or(L"");
std::wstring columnStyleName = Context.get_table_context().default_column_cell_style();
std::wstring rowStyleName = Context.get_table_context().default_row_cell_style();
if (attlist_.table_number_columns_repeated_ > 1)
columnStyleName.clear(); // могут быть разные стили колонок Book 24.ods
odf_read_context & odfContext = Context.root()->odf_context();
style_instance *defaultCellStyle=NULL, *defaultColumnCellStyle = NULL, *defaultRowCellStyle =NULL, *cellStyle = NULL;
try
{
defaultCellStyle = odfContext.styleContainer().style_default_by_type(style_family::TableCell);
defaultColumnCellStyle = odfContext.styleContainer().style_by_name(columnStyleName, style_family::TableCell, false);
defaultRowCellStyle = odfContext.styleContainer().style_by_name(rowStyleName, style_family::TableCell, false);
cellStyle = odfContext.styleContainer().style_by_name(cellStyleName, style_family::TableCell, false);
}
catch(...)
{
_CP_LOG << L"[error]: style wrong\n";
}
std::wstring data_style = CalcCellDataStyle(Context, columnStyleName, rowStyleName, cellStyleName);
// стили не наследуются
std::vector<const style_instance *> instances;
instances.push_back(defaultCellStyle);
if (defaultColumnCellStyle)
instances.push_back(defaultColumnCellStyle);
if (defaultRowCellStyle)
{
if (instances.size() > 1)
instances[1] = defaultRowCellStyle;
else
instances.push_back(defaultRowCellStyle);
}
if (cellStyle)
{
if (instances.size() > 1)
instances[1] = cellStyle;
else
instances.push_back(cellStyle);
}
text_format_properties_ptr textFormatProperties = calc_text_properties_content (instances);
paragraph_format_properties parFormatProperties = calc_paragraph_properties_content (instances);
style_table_cell_properties_attlist cellFormatProperties = calc_table_cell_properties (instances);
if (attr.office_value_type_)
odf_value_type = attr.office_value_type_->get_type();
if ((odf_value_type == office_value_type::Float) ||
(odf_value_type == office_value_type::Custom && attr.office_value_))
{
xlsx_value_type = oox::XlsxCellType::n;
number_val = attr.office_value_.get_value_or(L"");
}
else if (odf_value_type == office_value_type::Percentage)
{
xlsx_value_type = oox::XlsxCellType::n;
number_val = attr.office_value_.get_value_or(L"");
}
else if (odf_value_type == office_value_type::Currency)
{
xlsx_value_type = oox::XlsxCellType::n;
number_val = attr.office_value_.get_value_or(L"");
}
else if ((odf_value_type == office_value_type::Date) ||
(odf_value_type == office_value_type::Custom && attr.office_date_value_))
{
xlsx_value_type = oox::XlsxCellType::n;
if (attr.office_date_value_)
{
int y, m, d;
_CP_OPT(int) h, min, s;
if (oox::parseDateTime(attr.office_date_value_.get(), y, m, d, h, min, s))
{
boost::int64_t intDate = oox::convertDate(y, m, d);
_CP_OPT(double) dTime;
if (h && min)
{
dTime = oox::convertTime(*h, *min, s.get_value_or(0));
}
if (intDate > 0)
{
if (dTime)
{
number_val = XmlUtils::ToString(*dTime + intDate);
}
else
{
number_val = std::to_wstring(intDate);
}
}
else
{
str_val = attr.office_date_value_.get();
}
}
}
}
else if ((odf_value_type == office_value_type::Time) ||
(odf_value_type == office_value_type::Custom && attr.office_time_value_))
{
xlsx_value_type = oox::XlsxCellType::n;
if (attr.office_time_value_)
{
const std::wstring tv = attr.office_time_value_.get();
int h,m;
double s;
if (oox::parseTime(tv, h, m, s))
{
number_val = boost::lexical_cast<std::wstring>(oox::convertTime(h, m, s));
}
}
}
else if ((odf_value_type == office_value_type::Boolean) ||
(odf_value_type == office_value_type::Custom && attr.office_boolean_value_))
{
xlsx_value_type = oox::XlsxCellType::b;
if (attr.office_boolean_value_) bool_val = oox::parseBoolVal(attr.office_boolean_value_.get());
}
else if ((odf_value_type == office_value_type::String) ||
(odf_value_type == office_value_type::Custom && attr.office_string_value_))
{
xlsx_value_type = oox::XlsxCellType::str;
if (attr.office_string_value_) str_val = attr.office_string_value_.get();
}
if (!data_style.empty())
{
num_format = Context.get_num_format_context().find_complex_format(data_style, odf_value_type);
if (num_format.empty())
{
office_element_ptr elm = odfContext.numberStyles().find_by_style_name(data_style);
number_style_base *num_style = dynamic_cast<number_style_base*>(elm.get());
if (num_style)
{
Context.get_num_format_context().start_complex_format(data_style);
num_style->oox_convert(Context.get_num_format_context());
Context.get_num_format_context().end_complex_format();
num_format = Context.get_num_format_context().get_last_format();
}
}
}
is_style_visible = (!cellStyleName.empty() || defaultColumnCellStyle) ? true : false;
if (bExternalTable)
{
is_style_visible = false;
xlsx_value_type = oox::XlsxCellType::inlineStr;
}
oox::xlsx_cell_format cellFormat;
cellFormat.set_cell_type(xlsx_value_type);
cellFormat.set_num_format(oox::odf_string_to_build_in(odf_value_type));
if ( content_.elements_.size() > 0 || attlist_.table_content_validation_name_ ||
!formula.empty() ||
( xlsx_value_type == oox::XlsxCellType::n && !number_val.empty()) ||
( xlsx_value_type == oox::XlsxCellType::b && bool_val) ||
(( xlsx_value_type == oox::XlsxCellType::str || oox::XlsxCellType::inlineStr) && str_val)) is_data_visible = true;
if (attlist_.table_number_columns_repeated_ < 199 && last_cell_) last_cell_ = false;
int cell_repeated_max = Context.current_table_column() + attlist_.table_number_columns_repeated_ + 1;
if (cell_repeated_max >= 1024 && cellStyleName.empty() && last_cell_ && !is_data_visible)
{//Book 24.ods
return;
}
if (is_style_visible)
{
xfId_last_set = Context.get_style_manager().xfId(textFormatProperties, &parFormatProperties, &cellFormatProperties, &cellFormat, num_format, false, is_style_visible);
}
for (unsigned int r = 0; r < attlist_.table_number_columns_repeated_; ++r)
{
Context.start_table_covered_cell ();
if (attlist_.table_content_validation_name_)
{
Context.get_dataValidations_context().activate(*attlist_.table_content_validation_name_, /*ref*/Context.current_table_column(), Context.current_table_row());
}
if (is_style_visible)
Context.set_current_cell_style_id(xfId_last_set);
const int sharedStringId = content_.xlsx_convert(Context, textFormatProperties);
if (xlsx_value_type == oox::XlsxCellType::str && sharedStringId >= 0)
xlsx_value_type = oox::XlsxCellType::s;//в случае текста, если он есть берем кэшированное значение
if (skip_next_cell) break;
// пустые ячейки пропускаем.
if ( is_data_visible || ((cellStyle || defaultColumnCellStyle) && is_style_visible))
{
CP_XML_WRITER(strm)
{
CP_XML_NODE(L"c")
{
CP_XML_ATTR(L"r", oox::getCellAddress(Context.current_table_column(), Context.current_table_row()));
std::wstring type = oox::cellType2Str(xlsx_value_type);
if (false == type.empty()) CP_XML_ATTR(L"t", type);
CP_XML_ATTR(L"s", xfId_last_set);
if (!formula.empty())
{
const std::wstring xlsxFormula = formulas_converter.convert(formula);
if (!xlsxFormula.empty())
{
CP_XML_NODE(L"f")
{
CP_XML_CONTENT(xlsxFormula);
}
}
}
if (sharedStringId >= 0 && xlsx_value_type == oox::XlsxCellType::s)
{
CP_XML_NODE(L"v") { CP_XML_CONTENT(sharedStringId); }
}
else if ((xlsx_value_type == oox::XlsxCellType::str || xlsx_value_type == oox::XlsxCellType::inlineStr) && str_val)
{
CP_XML_NODE(L"v") { CP_XML_CONTENT(str_val.get()); }
}
else if (xlsx_value_type == oox::XlsxCellType::n && !number_val.empty())
{
CP_XML_NODE(L"v") { CP_XML_CONTENT(number_val);}
}
else if (xlsx_value_type == oox::XlsxCellType::b && bool_val)
{
CP_XML_NODE(L"v") { CP_XML_CONTENT((int)(bool_val.get())); }
}
}
if ( is_data_visible || (cellStyle && is_style_visible && !last_cell_))
{
Context.get_table_context().state()->non_empty_row();
empty_cell_count = 0 ;
}
else
{
empty_cell_count++;
//Уведомление_оручении.ods - 13 повторов пустых с cellStyle=NULL - нужные !!!
if (empty_cell_count > 19 && last_cell_&& (attlist_.table_number_columns_repeated_> 299 || cellStyle == NULL))
{//пишем простыню только если задан стиль тока для этих ячеек
skip_next_cell = true;
}
}
}
}
else
{
if (last_cell_) // Vehicle log book.ods (row = 24 and more)
skip_next_cell = true;
}
Context.end_table_covered_cell();
}
}
void table_content_validations::xlsx_convert(oox::xlsx_conversion_context & Context)
{
for (size_t i = 0 ; i < content_.size(); i++)
{
content_[i]->xlsx_convert(Context);
}
}
void table_content_validation::xlsx_convert(oox::xlsx_conversion_context & Context)
{
std::wstring name = table_name_.get_value_or(L"");
Context.get_dataValidations_context().add(name, table_base_cell_address_.get_value_or(L""));
Context.get_dataValidations_context().add_formula(name, table_condition_.get_value_or(L""));
for (size_t i = 0 ; i < content_.size(); i++)
{
if (content_[i]->get_type() == typeTableErrorMassage)
{
table_error_message* error = dynamic_cast<table_error_message*>(content_[i].get());
Context.get_text_context()->start_only_text();
for (size_t j = 0 ; j < error->content_.size(); j++)
{
error->content_[j]->xlsx_convert(Context);
}
std::wstring content = Context.get_text_context()->end_only_text();
Context.get_dataValidations_context().add_error_msg(name, error->table_title_.get_value_or(L""), content,
error->table_display_ ? error->table_display_->get() : true,
error->table_message_type_.get_value_or(message_type::stop).get_type());
}
else if (content_[i]->get_type() == typeTableHelpMassage)
{
table_help_message* help = dynamic_cast<table_help_message*>(content_[i].get());
Context.get_text_context()->start_only_text();
for (size_t j = 0 ; j < help->content_.size(); j++)
{
help->content_[j]->xlsx_convert(Context);
}
std::wstring content = Context.get_text_context()->end_only_text();
Context.get_dataValidations_context().add_help_msg(name, help->table_title_.get_value_or(L""), content,
help->table_display_ ? help->table_display_->get() : true);
}
content_[i]->xlsx_convert(Context);
}
}
void table_error_message::xlsx_convert(oox::xlsx_conversion_context & Context)
{
}
void table_help_message::xlsx_convert(oox::xlsx_conversion_context & Context)
{
}
}
}