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

866 lines
26 KiB
C++
Raw 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 <xml/simple_xml_writer.h>
#include "../../Common/logging.h"
#include "xlsx_table_state.h"
#include "xlsx_utils.h"
#include "xlsxconversioncontext.h"
#include "../Format/odf_document.h"
#include "../Format/odfcontext.h"
#include "../Format/style_table_properties.h"
#include "../../DataTypes/stylefamily.h"
#include "../../Formulas/formulasconvert.h"
#include "../../../OfficeCryptReader/source/CryptTransform.h"
namespace cpdoccore {
namespace oox {
void xlsx_data_range::serialize_autofilter(std::wostream& _Wostream)
{
if (!filter_button && filter_conditions.empty()) return;
CP_XML_WRITER(_Wostream)
{
CP_XML_NODE(L"autoFilter")
{
CP_XML_ATTR(L"ref", ref);
serialize_filterColumn(CP_XML_STREAM(), 0);
}
}
}
void xlsx_data_range::serialize_sort (std::wostream & _Wostream)
{
if (bySort.empty()) return;
CP_XML_WRITER(_Wostream)
{
CP_XML_NODE(L"sortState")
{
CP_XML_ATTR(L"ref", ref);
CP_XML_ATTR(L"xmlns:xlrd2", "http://schemas.microsoft.com/office/spreadsheetml/2017/richdata2");
if (!byRow)
CP_XML_ATTR(L"columnSort", true);
std::wstring ref_base, ref2, ref1;
size_t col_base, row_base, col_2, row_2;
size_t pos = ref.find(L":");
if (pos != std::wstring::npos)
{
ref_base = ref.substr(0, pos);
ref2 = ref.substr(pos + 1);
}
bool bSplit = getCellAddressInv(ref_base, col_base, row_base) && getCellAddressInv(ref2, col_2, row_2);
for (size_t i = 0 ; bSplit && i < bySort.size(); i++)
{
bool in_range = true;
if (byRow)
{
if (col_base + bySort[i].first > col_2) in_range = false;
ref1 = getCellAddress(col_base + bySort[i].first + (withHeader ? 1 : 0), row_base);
ref2 = getCellAddress(col_base + bySort[i].first + (withHeader ? 1 : 0), row_2);
}
else
{
if ( bySort[i].first > row_2) in_range = false;
ref1 = getCellAddress(col_base, row_base + bySort[i].first + (withHeader ? 1 : 0));
ref2 = getCellAddress(col_2, row_base + bySort[i].first + (withHeader ? 1 : 0));
}
if (in_range)
{
CP_XML_NODE(L"sortCondition")
{
CP_XML_ATTR(L"ref", ref1 + L":" + ref2);
if (bySort[i].second)
CP_XML_ATTR(L"descending", 1);
}
}
}
}
}
}
void xlsx_data_range::serialize_filterColumn(std::wostream& _Wostream, int indexCol)
{
CP_XML_WRITER(_Wostream)
{
CP_XML_NODE(L"filterColumn")
{
CP_XML_ATTR(L"colId", indexCol);
if (bFilterAndOr && filter_conditions.size() > 1)
{
CP_XML_NODE(L"customFilters")
{
if (*bFilterAndOr)
CP_XML_ATTR(L"and", 1);
else
CP_XML_ATTR(L"and", 0);
for (size_t i = 0; i < filter_conditions.size(); ++i)
{
CP_XML_NODE(L"customFilter")
{
switch (filter_conditions[i].operator_)
{
case 15: // !empty
case 0: CP_XML_ATTR(L"operator", L"notEqual"); break;
case 14: // empty
case 1: CP_XML_ATTR(L"operator", L"equal"); break;
case 2: CP_XML_ATTR(L"operator", L"LessThan"); break;
case 3: CP_XML_ATTR(L"operator", L"greaterThan"); break;
case 13: // bottom values
case 4: CP_XML_ATTR(L"operator", L"lessThanOrEqual"); break;
case 17: // top values
case 5: CP_XML_ATTR(L"operator", L"greaterThanOrEqual"); break;
}
CP_XML_ATTR(L"val", filter_conditions[i].value);
}
}
}
}
else if (1 == filter_conditions.size())
{
if (filter_conditions[0].type == 3/*odf_types::table_data_type::background_color*/ ||
filter_conditions[0].type == 4/*odf_types::table_data_type::text_color*/)
{
CP_XML_NODE(L"colorFilter")
{
if (filter_conditions[0].type == 3)
CP_XML_ATTR(L"cellColor", L"1");
CP_XML_ATTR(L"dxfId", filter_conditions[0].value);
}
}
else if (filter_conditions[0].operator_ == 17/*odf_types::table_operator::TopValues*/)
{
CP_XML_NODE(L"top10")
{
CP_XML_ATTR(L"val", filter_conditions[0].value);
}
}
}
}
}
}
//-------------------------------------------------------------------------------------------------------------------------
xlsx_table_state::xlsx_table_state(xlsx_conversion_context * Context, std::wstring styleName, std::wstring tableName, int tableId)
: context_ (Context),
table_style_ (styleName),
tableName_ (tableName),
tableId_ (tableId),
current_table_column_ (-1),
current_table_row_ (-1),
columns_spanned_num_ (0),
columns_count_ (0),
xlsx_drawing_context_ (Context->get_drawing_context_handle()),
xlsx_comments_context_ (Context->get_comments_context_handle()),
table_column_last_width_(0.0),
in_cell(false),
bEndTable(false),
bRTL(false),
bHidden(false)
{
odf_reader::style_table_properties * table_prop = NULL;
odf_reader::style_instance * tableStyle = context_->root()->odf_context().styleContainer().style_by_name(table_style_, odf_types::style_family::Table, false);
if ((tableStyle) && (tableStyle->content()))
table_prop = tableStyle->content()->get_style_table_properties();
if (table_prop)
{
if (table_prop->content().common_writing_mode_attlist_.style_writing_mode_)
{
if (table_prop->content().common_writing_mode_attlist_.style_writing_mode_->get_type() == odf_types::writing_mode::RlTb)
bRTL = true;
}
if ((table_prop->content().table_display_) && (false == table_prop->content().table_display_))
{
bHidden = true;
}
}
}
void xlsx_table_state::start_column(unsigned int repeated, const std::wstring & defaultCellStyleName, bool bHeader)
{
for (unsigned int i = 0; i < repeated; ++i)
column_default_cell_style_name_.push_back(defaultCellStyleName);
if (bHeader)
{
if ((false == columnsHeaders_.empty()) && (columnsHeaders_.back().first + columnsHeaders_.back().second == columns_count_))
{
columnsHeaders_.back().second += repeated;
}
else
{
columnsHeaders_.push_back(std::make_pair(columns_count_, repeated));
}
}
columns_count_ += repeated;
columns_.push_back(repeated);
}
void xlsx_table_state::set_rtl(bool val)
{
bRTL = val;
}
void xlsx_table_state::set_protection(bool val, const std::wstring &key, const std::wstring &algorithm)
{
protection.bEnabled = val;
protection.protect_key = key;
size_t pos = algorithm.find(L"#");
if (pos != std::wstring::npos)
{
protection.protect_key_algorithm = algorithm.substr(pos + 1);
}
//test
//CRYPT::odfWriteProtect protect;
//protect.SetProtectKey(DecodeBase64(protect_key));
//protect.SetPassword(L"123");
//bool res = protect.Verify();
}
void xlsx_table_state::set_protection_select_protected_cells(bool val)
{
protection.selectLockedCells = !val;
}
void xlsx_table_state::set_protection_select_unprotected_cells(bool val)
{
protection.selectUnockedCells = !val;
}
void xlsx_table_state::set_protection_insert_columns(bool val)
{
protection.insertColumns = !val;
}
void xlsx_table_state::set_protection_insert_rows(bool val)
{
protection.insertRows = !val;
}
void xlsx_table_state::set_protection_delete_columns(bool val)
{
protection.deleteColumns = !val;
}
void xlsx_table_state::set_protection_delete_rows(bool val)
{
protection.deleteRows = !val;
}
unsigned int xlsx_table_state::columns_count() const
{
return columns_count_;
}
void xlsx_table_state::start_table_row_group(bool collapsed)
{
group_rows_.push_back(collapsed);
}
void xlsx_table_state::end_table_row_group()
{
group_rows_.pop_back();
}
void xlsx_table_state::start_table_column_group(bool collapsed)
{
group_columns_.push_back(collapsed);
}
void xlsx_table_state::end_table_column_group()
{
group_columns_.pop_back();
}
void xlsx_table_state::add_empty_row(int count, bool bHeader)
{
if (bHeader)
{
if ((false == rowsHeaders_.empty()) && (rowsHeaders_.back().first + rowsHeaders_.back().second == current_table_row_))
{
rowsHeaders_.back().second += count;
}
else
{
rowsHeaders_.push_back(std::make_pair(current_table_row_ + 1, count));
}
}
current_table_row_ += count;
}
void xlsx_table_state::start_row(const std::wstring & StyleName, const std::wstring & defaultCellStyleName, bool bHeader)
{
empty_row_ = true;
// reset column num, column spanned style
current_table_row_++;
if (bHeader)
{
if ((false == rowsHeaders_.empty()) && (rowsHeaders_.back().first + rowsHeaders_.back().second == current_table_row_))
{
rowsHeaders_.back().second += 1;
}
else
{
rowsHeaders_.push_back(std::make_pair(current_table_row_, 1));
}
}
current_table_column_ = -1;
columns_spanned_style_ = L"";
row_default_cell_style_name_ = defaultCellStyleName;
// set row style name
table_row_style_ = StyleName;
}
void xlsx_table_state::set_column_break_before()
{
column_breaks_.push_back(columns_count_ - columns_.back());
}
void xlsx_table_state::set_column_break_after()
{
column_breaks_.push_back(columns_count_ + 1 - columns_.back());
}
void xlsx_table_state::set_row_break_before()
{
row_breaks_.push_back(current_table_row_);
}
void xlsx_table_state::set_row_break_after()
{
row_breaks_.push_back(current_table_row_ + 1);
}
void xlsx_table_state::non_empty_row()
{
empty_row_= false;
}
bool xlsx_table_state::is_empty_row() const
{
return empty_row_;
}
std::wstring xlsx_table_state::default_row_cell_style() const
{
return row_default_cell_style_name_;
}
std::wstring xlsx_table_state::default_column_cell_style() const
{
if (current_table_column_ + 1 < (int)column_default_cell_style_name_.size())
return column_default_cell_style_name_.at(current_table_column_ + 1);
else
{
//непонятная хрень!! - неправильно сформирован ods???
return L"";
}
}
void xlsx_table_state::end_row()
{
in_cell = false;
table_row_style_ = L"";
}
std::wstring xlsx_table_state::current_row_style() const
{
return table_row_style_;
}
void xlsx_table_state::start_cell(size_t columnsSpanned, size_t rowsSpanned)
{
current_table_column_++;
// в случае если объединение имеет место добавляем запись о нем
if (columnsSpanned != 0 || rowsSpanned != 0)
{
xlsx_merge_cells_.add_merge(current_table_column_, current_table_row_, columnsSpanned, rowsSpanned);
}
//if ( current_columns_spaned() > 0 )
//{
// _CP_LOG << L"[warning] current columns spanned > 0\n";
//}
columns_spanned_num_ = static_cast<int>(columnsSpanned);
// обновляем вектор, в котором хранятся информация об объединении строк
// добавляем в него новый столбец
for (size_t i = 0; i <= columns_spanned_num_; ++i)
{
if (current_table_column_+i >= (int)(rows_spanned_.size()))
rows_spanned_.push_back(xlsx_row_spanned());
}
if ((int)rows_spanned_.size() <= current_table_column_)
{
_CP_LOG << L"[warning] set_rows_spanned error\n";
}
else
{
//if (rows_spanned_[current_table_column_].num() > 0)
//{
// _CP_LOG << L"[warning] current rows spanned > 0\n";
//}
rows_spanned_[current_table_column_].num(static_cast<unsigned int>(rowsSpanned));
rows_spanned_[current_table_column_].column_spanned(static_cast<unsigned int>(columnsSpanned));
for (size_t i = 0; i <= columns_spanned_num_; ++i)
{
rows_spanned_[current_table_column_ + i].set_style_id(-1);
}
}
in_cell = true;
}
void xlsx_table_state::end_cell()
{
in_cell = false;
}
void xlsx_table_state::set_current_cell_style_id(unsigned int xfId)
{
for (size_t i = 0; i <= columns_spanned_num_; ++i)
{
rows_spanned_[current_table_column_ + i].set_style_id((int)xfId);
}
}
int xlsx_table_state::get_current_cell_style_id()
{
return rows_spanned_[current_table_column_].get_style_id();
}
void xlsx_table_state::start_covered_cell()
{
current_table_column_++;
// обновляем вектор, в котором хранятся информация об объединении строк
// добавляем в него новый столбец
if (current_table_column_ >= (int)(rows_spanned_.size()))
rows_spanned_.push_back(xlsx_row_spanned());
// использовали текущую ячейку, уменьшаем счетчики оставшихся объединенных ячеек
// для столбцов и строк
if (columns_spanned_num_ > 0)
columns_spanned_num_--;
if (rows_spanned_[current_table_column_].num() > 0)
rows_spanned_[current_table_column_].decrease();
if (current_table_column_ > 0)
{
const unsigned int pred = rows_spanned_[current_table_column_ - 1].column_spanned();
if (pred > 0)
{
rows_spanned_[current_table_column_].column_spanned(pred - 1);
rows_spanned_[current_table_column_].num(rows_spanned_[current_table_column_ - 1].num());
}
}
}
void xlsx_table_state::end_covered_cell()
{
}
int xlsx_table_state::current_column() const
{
return current_table_column_;
}
int xlsx_table_state::current_row() const
{
return current_table_row_;
}
unsigned int xlsx_table_state::current_columns_spaned() const
{
return columns_spanned_num_;
}
unsigned int xlsx_table_state::current_rows_spanned(unsigned int Column) const
{
if (rows_spanned_.size() <= Column)
{
_CP_LOG << L"[warning] current_rows_spanned error\n";
return 0;
}
else
{
return rows_spanned_[Column].num();
}
}
double charsToSize(unsigned int charsCount, double maxDigitSize)
{
return 1.0 * int((maxDigitSize * charsCount + 5.0) / maxDigitSize * 256.0) / 256.0;
}
void xlsx_table_state::serialize_page_properties (std::wostream & strm)
{
_CP_OPT(std::wstring) masterPageName = context_->root()->odf_context().styleContainer().master_page_name_by_name(table_style_);
if (!masterPageName) return;
odf_reader::style_master_page* master_style_ = context_->root()->odf_context().pageLayoutContainer().master_page_by_name(*masterPageName);
if (!master_style_) return;
if (!master_style_->attlist_.style_page_layout_name_) return;
odf_reader::page_layout_instance * page_layout = context_->root()->odf_context().pageLayoutContainer().page_layout_by_name(*master_style_->attlist_.style_page_layout_name_);
if (!page_layout) return;
page_layout->xlsx_serialize(strm, *context_);
}
void xlsx_table_state::serialize_header_footer (std::wostream & strm)
{
_CP_OPT(std::wstring) masterPageName = context_->root()->odf_context().styleContainer().master_page_name_by_name(table_style_);
if (!masterPageName) return;
odf_reader::style_master_page* master_style_ = context_->root()->odf_context().pageLayoutContainer().master_page_by_name(*masterPageName);
if (!master_style_) return;
odf_reader::style_header *header_odd = dynamic_cast<odf_reader::style_header*> (master_style_->style_header_.get());
odf_reader::style_header_first *header_first = dynamic_cast<odf_reader::style_header_first*> (master_style_->style_header_first_.get());
odf_reader::style_header_left *header_even = dynamic_cast<odf_reader::style_header_left*> (master_style_->style_header_left_.get());
odf_reader::style_footer *footer_odd = dynamic_cast<odf_reader::style_footer*> (master_style_->style_footer_.get());
odf_reader::style_footer_first *footer_first = dynamic_cast<odf_reader::style_footer_first*> (master_style_->style_footer_first_.get());
odf_reader::style_footer_left *footer_even = dynamic_cast<odf_reader::style_footer_left*> (master_style_->style_footer_left_.get());
if (!header_odd && !header_first && !header_even &&
!footer_odd && !footer_first && !footer_even) return;
CP_XML_WRITER(strm)
{
CP_XML_NODE(L"headerFooter")
{
if ((header_even && header_even->attlist_.style_display_) || (footer_even && footer_even->attlist_.style_display_))
{
CP_XML_ATTR(L"differentOddEven", 1);
}
if ((header_first && header_first->attlist_.style_display_ /*&& !header_first->content_.empty()*/) ||
(footer_first && footer_first->attlist_.style_display_/* && !footer_first->content_.empty()*/))
{
CP_XML_ATTR(L"differentFirst", 1);
}
if (header_odd) header_odd->xlsx_serialize(CP_XML_STREAM(), *context_);
if (footer_odd) footer_odd->xlsx_serialize(CP_XML_STREAM(), *context_);
if (header_even) header_even->xlsx_serialize(CP_XML_STREAM(), *context_);
if (footer_even) footer_even->xlsx_serialize(CP_XML_STREAM(), *context_);
if (header_first) header_first->xlsx_serialize(CP_XML_STREAM(), *context_);
if (footer_first) footer_first->xlsx_serialize(CP_XML_STREAM(), *context_);
}
}
}
void xlsx_table_state::serialize_background (std::wostream & strm)
{
if (tableBackground_.empty()) return;
CP_XML_WRITER(strm)
{
CP_XML_NODE(L"picture")
{
CP_XML_ATTR(L"r:id", tableBackground_);
}
}
}
void xlsx_table_state::serialize_protection (std::wostream & strm)
{
if (!protection.bEnabled) return;
CP_XML_WRITER(strm)
{
CP_XML_NODE(L"sheetProtection")
{
//convert protection odf->ooxml impossible without password !!!
//CP_XML_ATTR(L"algorithmName", );
//CP_XML_ATTR(L"hashValue", );
//CP_XML_ATTR(L"saltValue", );
//CP_XML_ATTR(L"spinCount", );
CP_XML_ATTR(L"sheet", 1);
CP_XML_ATTR(L"objects", 0);
CP_XML_ATTR(L"scenarios", 0);
CP_XML_ATTR(L"formatCells", 1);
CP_XML_ATTR(L"formatColumns", 1);
CP_XML_ATTR(L"formatRows", 1);
CP_XML_ATTR(L"insertColumns", protection.insertColumns);
CP_XML_ATTR(L"insertRows", protection.insertRows);
CP_XML_ATTR(L"insertHyperlinks", 1);
CP_XML_ATTR(L"deleteColumns", protection.deleteColumns);
CP_XML_ATTR(L"deleteRows", protection.deleteRows);
CP_XML_ATTR(L"selectLockedCells", protection.selectLockedCells);
CP_XML_ATTR(L"sort", 1);
CP_XML_ATTR(L"autoFilter", 1);
CP_XML_ATTR(L"pivotTables", 1);
CP_XML_ATTR(L"selectUnlockedCells", protection.selectUnockedCells);
}
}
}
void xlsx_table_state::serialize_table_format (std::wostream & strm)
{
odf_reader::odf_read_context & odfContext = context_->root()->odf_context();
CP_XML_WRITER(strm)
{
odf_reader::style_table_properties * table_prop = NULL;
odf_reader::style_instance * tableStyle = odfContext.styleContainer().style_by_name(table_style_, odf_types::style_family::Table, false);
if ((tableStyle) && (tableStyle->content()))
table_prop = tableStyle->content()->get_style_table_properties();
if (table_prop)
{
CP_XML_NODE(L"sheetPr")
{
//at filterMode="false">
if (table_prop->content().tableooo_tab_color_)
{
CP_XML_NODE(L"tabColor")
{
CP_XML_ATTR(L"rgb", table_prop->content().tableooo_tab_color_->get_hex_value());
}
}
//<pageSetUpPr fitToPage="true"/>
}
}
int columns = (std::max)(current_table_column_, (int)columns_count_);
int rows = (std::max)(current_table_row_, 1);
if (columns < 1024 && columns > 1 &&
rows < 1024 && rows > 1)
{
CP_XML_NODE(L"dimension")
{
if (current_table_column_ < 0) current_table_column_ = columns_count_;
std::wstring ref2 = getCellAddress( current_table_column_, current_table_row_);
CP_XML_ATTR(L"ref", L"A1:" + ref2);
}
}
if (odfContext.Settings().get_views_count() > 0)
{
CP_XML_NODE(L"sheetViews")
{
CP_XML_NODE(L"sheetView")
{
CP_XML_ATTR(L"workbookViewId", 0);
if (bRTL)
CP_XML_ATTR(L"rightToLeft", 1);
std::wstring s_col, s_row;
bool bXSplit = false, bYSplit = false;
int nXSplit = 0, nYSplit = 0;
for (int i = 0; i < odfContext.Settings().get_table_view_count(0, tableName_); i++)
{
std::pair<std::wstring, std::wstring> value = odfContext.Settings().get_table_view(0, tableName_, i);
if (value.first == L"ZoomValue")
{
CP_XML_ATTR(L"zoomScale", value.second);
CP_XML_ATTR(L"zoomScaleNormal", value.second);
}
if (value.first == L"ShowGrid") CP_XML_ATTR(L"showGridLines", value.second);
else if (value.first == L"CursorPositionX") s_col = value.second;
else if (value.first == L"CursorPositionY") s_row = value.second;
else if (value.first == L"HorizontalSplitMode") bXSplit = (value.second == L"2");
else if (value.first == L"VerticalSplitMode") bYSplit = (value.second == L"2");
else if (value.first == L"HorizontalSplitPosition") nXSplit = boost::lexical_cast<int>(value.second);
else if (value.first == L"VerticalSplitPosition") nYSplit = boost::lexical_cast<int>(value.second);
}
int col = -1, row = -1;
try
{
if (!s_col.empty()) col = boost::lexical_cast<int>(s_col);
if (!s_row.empty()) row = boost::lexical_cast<int>(s_row);
}
catch(...){}
if (bXSplit || bYSplit)
{
CP_XML_NODE(L"pane")
{
CP_XML_ATTR(L"xSplit", bXSplit ? nXSplit : 0);
CP_XML_ATTR(L"ySplit", bYSplit ? nYSplit : 0);
CP_XML_ATTR(L"topLeftCell", getCellAddress(nXSplit, nYSplit));
//CP_XML_ATTR(L"activePane", L"bottomLeft");
CP_XML_ATTR(L"activePane", L"topLeft");
CP_XML_ATTR(L"state", L"frozen");
}
}
if (col >= 0 && row >= 0)
{
CP_XML_NODE(L"selection")
{
CP_XML_ATTR(L"activeCell", getCellAddress(col, row));
CP_XML_ATTR(L"activeCellId", 0);
//CP_XML_ATTR(L"pane", ((bXSplit || bYSplit) ? L"bottomLeft" : L"topLeft"));
CP_XML_ATTR(L"activePane", L"topLeft");
CP_XML_ATTR(L"sqref", getCellAddress(col, row));
}
}
}
}
// -showRowColHeaders
}
double default_height = (2 * context_->getMaxDigitSize().second * 72. / 96. * 100.) /100.;//in point size.
odf_reader::style_instance * rowDefStyle = odfContext.styleContainer().style_default_by_type(odf_types::style_family::TableRow);
if ((rowDefStyle) && (rowDefStyle->content()))
{
const odf_reader::style_table_row_properties * prop = rowDefStyle->content()->get_style_table_row_properties();
if ( (prop) && (prop->attlist_.style_row_height_))
{
default_height = prop->attlist_.style_row_height_->get_value_unit(odf_types::length::pt);
}
std::wstringstream ht_s;
ht_s.precision(1);
ht_s << std::fixed << default_height;
CP_XML_NODE(L"sheetFormatPr")
{
CP_XML_ATTR(L"defaultRowHeight", ht_s.str());
}
}
}
}
void xlsx_table_state::serialize_breaks(std::wostream & strm)
{
if (column_breaks_.empty() && row_breaks_.empty()) return;
CP_XML_WRITER(strm)
{
if (false == row_breaks_.empty())
{
CP_XML_NODE(L"rowBreaks")
{
CP_XML_ATTR(L"count", row_breaks_.size());
CP_XML_ATTR(L"manualBreakCount", row_breaks_.size());
for (size_t i = 0; i < row_breaks_.size(); i++)
{
CP_XML_NODE(L"brk")
{
CP_XML_ATTR(L"id", row_breaks_[i]);
CP_XML_ATTR(L"max", 16383);
CP_XML_ATTR(L"man", 1);
}
}
}
}
if (false == column_breaks_.empty())
{
CP_XML_NODE(L"colBreaks")
{
CP_XML_ATTR(L"count", column_breaks_.size());
CP_XML_ATTR(L"manualBreakCount", column_breaks_.size());
for (size_t i = 0; i < column_breaks_.size(); i++)
{
CP_XML_NODE(L"brk")
{
CP_XML_ATTR(L"id", column_breaks_[i]);
CP_XML_ATTR(L"max", 1048575);
CP_XML_ATTR(L"man", 1);
}
}
}
}
}
}
void xlsx_table_state::serialize_merge_cells(std::wostream & strm)
{
return xlsx_merge_cells_.xlsx_serialize(strm);
}
void xlsx_table_state::serialize_ole_objects(std::wostream & strm)
{
return xlsx_drawing_context_.get_drawings()->serialize_objects(strm);
}
void xlsx_table_state::serialize_controls(std::wostream & strm)
{
return xlsx_drawing_context_.get_drawings()->serialize_controls(strm);
}
void xlsx_table_state::serialize_hyperlinks(std::wostream & strm)
{
return xlsx_hyperlinks_.xlsx_serialize(strm);
}
void xlsx_table_state::serialize_condFormatting(std::wostream & strm)
{
return xlsx_conditionalFormatting_context_.serialize(strm);
}
void xlsx_table_state::serialize_condFormattingEx(std::wostream& strm)
{
return xlsx_conditionalFormatting_context_.serializeEx(strm);
}
void xlsx_table_state::dump_rels_hyperlinks(rels & Rels)
{
return xlsx_hyperlinks_.dump_rels(Rels);
}
void xlsx_table_state::dump_rels_ole_objects(rels & Rels)
{
return get_drawing_context().get_drawings()->dump_rels_sheet(Rels);
}
void xlsx_table_state::start_hyperlink()
{
}
std::wstring xlsx_table_state::end_hyperlink(std::wstring const & ref, std::wstring const & href, std::wstring const & display)
{
return xlsx_hyperlinks_.add(ref, href, display);
}
}
}