2015-10-30 07:37:07 +08:00
# include <sstream>
2015-10-30 01:46:56 +08:00
# include <xlnt/s11n/worksheet_serializer.hpp>
# include <xlnt/cell/cell.hpp>
# include <xlnt/cell/cell_reference.hpp>
# include <xlnt/s11n/xml_document.hpp>
# include <xlnt/s11n/xml_node.hpp>
2015-10-30 07:37:07 +08:00
# include <xlnt/workbook/workbook.hpp>
2015-10-30 01:46:56 +08:00
# include <xlnt/worksheet/range.hpp>
# include <xlnt/worksheet/range_reference.hpp>
# include "detail/constants.hpp"
namespace {
bool is_integral ( long double d )
{
return d = = static_cast < long long int > ( d ) ;
}
} // namepsace
namespace xlnt {
2015-10-31 06:54:04 +08:00
worksheet_serializer : : worksheet_serializer ( worksheet sheet ) : sheet_ ( sheet )
{
}
2015-10-30 07:37:07 +08:00
2015-10-31 06:54:04 +08:00
bool worksheet_serializer : : read_worksheet ( const xml_document & xml )
2015-10-30 07:37:07 +08:00
{
2015-10-31 06:54:04 +08:00
auto & root_node = xml . get_child ( " worksheet " ) ;
2015-10-30 07:37:07 +08:00
auto & dimension_node = root_node . get_child ( " dimension " ) ;
std : : string dimension = dimension_node . get_attribute ( " ref " ) ;
auto full_range = xlnt : : range_reference ( dimension ) ;
auto sheet_data_node = root_node . get_child ( " sheetData " ) ;
2015-10-30 01:46:56 +08:00
2015-10-30 07:37:07 +08:00
if ( root_node . has_child ( " mergeCells " ) )
{
auto merge_cells_node = root_node . get_child ( " mergeCells " ) ;
auto count = std : : stoull ( merge_cells_node . get_attribute ( " count " ) ) ;
for ( auto merge_cell_node : merge_cells_node . get_children ( ) )
{
if ( merge_cell_node . get_name ( ) ! = " mergeCell " )
{
continue ;
}
sheet_ . merge_cells ( merge_cell_node . get_attribute ( " ref " ) ) ;
count - - ;
}
if ( count ! = 0 )
{
throw std : : runtime_error ( " mismatch between count and actual number of merged cells " ) ;
}
}
2015-10-31 06:54:04 +08:00
auto & shared_strings = sheet_ . get_parent ( ) . get_shared_strings ( ) ;
2015-10-30 07:37:07 +08:00
for ( auto row_node : sheet_data_node . get_children ( ) )
{
if ( row_node . get_name ( ) ! = " row " )
{
continue ;
}
auto row_index = static_cast < row_t > ( std : : stoull ( row_node . get_attribute ( " r " ) ) ) ;
2015-10-31 06:54:04 +08:00
if ( row_node . has_attribute ( " ht " ) )
2015-10-30 07:37:07 +08:00
{
sheet_ . get_row_properties ( row_index ) . height = std : : stold ( row_node . get_attribute ( " ht " ) ) ;
}
std : : string span_string = row_node . get_attribute ( " spans " ) ;
auto colon_index = span_string . find ( ' : ' ) ;
column_t min_column = 0 ;
column_t max_column = 0 ;
if ( colon_index ! = std : : string : : npos )
{
min_column = static_cast < column_t > ( std : : stoll ( span_string . substr ( 0 , colon_index ) ) ) ;
max_column = static_cast < column_t > ( std : : stoll ( span_string . substr ( colon_index + 1 ) ) ) ;
}
else
{
min_column = static_cast < column_t > ( full_range . get_top_left ( ) . get_column_index ( ) ) ;
max_column = static_cast < column_t > ( full_range . get_bottom_right ( ) . get_column_index ( ) ) ;
}
for ( column_t i = min_column ; i < = max_column ; i + + )
{
std : : string address = xlnt : : cell_reference : : column_string_from_index ( i ) + std : : to_string ( row_index ) ;
xml_node cell_node ;
bool cell_found = false ;
for ( auto & check_cell_node : row_node . get_children ( ) )
{
if ( check_cell_node . get_name ( ) ! = " c " )
{
continue ;
}
if ( check_cell_node . has_attribute ( " r " ) & & check_cell_node . get_attribute ( " r " ) = = address )
{
cell_node = check_cell_node ;
cell_found = true ;
break ;
}
}
if ( cell_found )
{
bool has_value = cell_node . has_child ( " v " ) ;
std : : string value_string = has_value ? cell_node . get_child ( " v " ) . get_text ( ) : " " ;
2015-10-31 06:54:04 +08:00
bool has_type = cell_node . has_attribute ( " t " ) ;
2015-10-30 07:37:07 +08:00
std : : string type = has_type ? cell_node . get_attribute ( " t " ) : " " ;
2015-10-31 06:54:04 +08:00
bool has_style = cell_node . has_attribute ( " s " ) ;
2015-10-30 07:37:07 +08:00
int style_id = has_style ? std : : stoull ( cell_node . get_attribute ( " s " ) ) : 0 ;
bool has_formula = cell_node . has_child ( " f " ) ;
bool has_shared_formula = has_formula & & cell_node . get_child ( " f " ) . has_attribute ( " t " ) & & cell_node . get_child ( " f " ) . get_attribute ( " t " ) = = " shared " ;
auto cell = sheet_ . get_cell ( address ) ;
if ( has_formula & & ! has_shared_formula & & ! sheet_ . get_parent ( ) . get_data_only ( ) )
{
std : : string formula = cell_node . get_child ( " f " ) . get_text ( ) ;
cell . set_formula ( formula ) ;
}
if ( has_type & & type = = " inlineStr " ) // inline string
{
std : : string inline_string = cell_node . get_child ( " is " ) . get_child ( " t " ) . get_text ( ) ;
cell . set_value ( inline_string ) ;
}
else if ( has_type & & type = = " s " & & ! has_formula ) // shared string
{
auto shared_string_index = std : : stoull ( value_string ) ;
2015-10-31 06:54:04 +08:00
auto shared_string = shared_strings . at ( shared_string_index ) ;
2015-10-30 07:37:07 +08:00
cell . set_value ( shared_string ) ;
}
else if ( has_type & & type = = " b " ) // boolean
{
cell . set_value ( value_string ! = " 0 " ) ;
}
else if ( has_type & & type = = " str " )
{
cell . set_value ( value_string ) ;
}
else if ( has_value & & ! value_string . empty ( ) )
{
if ( ! value_string . empty ( ) & & value_string [ 0 ] = = ' # ' )
{
cell . set_error ( value_string ) ;
}
else
{
cell . set_value ( std : : stold ( value_string ) ) ;
}
}
if ( has_style )
{
cell . set_style_id ( style_id ) ;
}
}
}
}
auto & cols_node = root_node . get_child ( " cols " ) ;
for ( auto col_node : cols_node . get_children ( ) )
{
if ( col_node . get_name ( ) ! = " col " )
{
continue ;
}
auto min = static_cast < column_t > ( std : : stoull ( col_node . get_attribute ( " min " ) ) ) ;
auto max = static_cast < column_t > ( std : : stoull ( col_node . get_attribute ( " max " ) ) ) ;
auto width = std : : stold ( col_node . get_attribute ( " width " ) ) ;
auto column_style = std : : stoull ( col_node . get_attribute ( " style " ) ) ;
bool custom = col_node . get_attribute ( " customWidth " ) = = " 1 " ;
for ( auto column = min ; column < = max ; column + + )
{
if ( ! sheet_ . has_column_properties ( column ) )
{
sheet_ . add_column_properties ( column , column_properties ( ) ) ;
}
sheet_ . get_column_properties ( min ) . width = width ;
sheet_ . get_column_properties ( min ) . style = column_style ;
sheet_ . get_column_properties ( min ) . custom = custom ;
}
}
if ( root_node . has_child ( " autoFilter " ) )
{
auto & auto_filter_node = root_node . get_child ( " autoFilter " ) ;
xlnt : : range_reference ref ( auto_filter_node . get_attribute ( " ref " ) ) ;
sheet_ . auto_filter ( ref ) ;
}
return true ;
}
2015-10-31 06:54:04 +08:00
xml_document worksheet_serializer : : write_worksheet ( ) const
2015-10-30 01:46:56 +08:00
{
2015-10-30 07:37:07 +08:00
sheet_ . get_cell ( " A1 " ) ;
2015-10-30 01:46:56 +08:00
2015-10-31 06:54:04 +08:00
xml_document xml ;
auto root_node = xml . add_child ( " worksheet " ) ;
2015-10-30 01:46:56 +08:00
xml . add_namespace ( " " , constants : : Namespaces . at ( " spreadsheetml " ) ) ;
xml . add_namespace ( " r " , constants : : Namespaces . at ( " r " ) ) ;
2015-10-31 06:54:04 +08:00
auto sheet_pr_node = root_node . add_child ( " sheetPr " ) ;
2015-10-30 01:46:56 +08:00
2015-10-30 07:37:07 +08:00
if ( ! sheet_ . get_page_setup ( ) . is_default ( ) )
2015-10-30 01:46:56 +08:00
{
2015-10-31 06:54:04 +08:00
auto page_set_up_pr_node = sheet_pr_node . add_child ( " pageSetUpPr " ) ;
2015-10-30 07:37:07 +08:00
page_set_up_pr_node . add_attribute ( " fitToPage " , sheet_ . get_page_setup ( ) . fit_to_page ( ) ? " 1 " : " 0 " ) ;
2015-10-30 01:46:56 +08:00
}
2015-10-31 06:54:04 +08:00
auto outline_pr_node = sheet_pr_node . add_child ( " outlinePr " ) ;
2015-10-30 01:46:56 +08:00
outline_pr_node . add_attribute ( " summaryBelow " , " 1 " ) ;
outline_pr_node . add_attribute ( " summaryRight " , " 1 " ) ;
2015-10-31 06:54:04 +08:00
auto dimension_node = root_node . add_child ( " dimension " ) ;
2015-10-30 07:37:07 +08:00
dimension_node . add_attribute ( " ref " , sheet_ . calculate_dimension ( ) . to_string ( ) ) ;
2015-10-30 01:46:56 +08:00
2015-10-31 06:54:04 +08:00
auto sheet_views_node = root_node . add_child ( " sheetViews " ) ;
auto sheet_view_node = sheet_views_node . add_child ( " sheetView " ) ;
2015-10-30 01:46:56 +08:00
sheet_view_node . add_attribute ( " workbookViewId " , " 0 " ) ;
std : : string active_pane = " bottomRight " ;
2015-10-30 07:37:07 +08:00
if ( sheet_ . has_frozen_panes ( ) )
2015-10-30 01:46:56 +08:00
{
auto pane_node = sheet_view_node . add_child ( " pane " ) ;
2015-10-30 07:37:07 +08:00
if ( sheet_ . get_frozen_panes ( ) . get_column_index ( ) > 1 )
2015-10-30 01:46:56 +08:00
{
2015-10-30 07:37:07 +08:00
pane_node . add_attribute ( " xSplit " , std : : to_string ( sheet_ . get_frozen_panes ( ) . get_column_index ( ) - 1 ) ) ;
2015-10-30 01:46:56 +08:00
active_pane = " topRight " ;
}
2015-10-30 07:37:07 +08:00
if ( sheet_ . get_frozen_panes ( ) . get_row ( ) > 1 )
2015-10-30 01:46:56 +08:00
{
2015-10-30 07:37:07 +08:00
pane_node . add_attribute ( " ySplit " , std : : to_string ( sheet_ . get_frozen_panes ( ) . get_row ( ) - 1 ) ) ;
2015-10-30 01:46:56 +08:00
active_pane = " bottomLeft " ;
}
2015-10-30 07:37:07 +08:00
if ( sheet_ . get_frozen_panes ( ) . get_row ( ) > 1 & & sheet_ . get_frozen_panes ( ) . get_column_index ( ) > 1 )
2015-10-30 01:46:56 +08:00
{
auto top_right_node = sheet_view_node . add_child ( " selection " ) ;
top_right_node . add_attribute ( " pane " , " topRight " ) ;
auto bottom_left_node = sheet_view_node . add_child ( " selection " ) ;
bottom_left_node . add_attribute ( " pane " , " bottomLeft " ) ;
active_pane = " bottomRight " ;
}
2015-10-30 07:37:07 +08:00
pane_node . add_attribute ( " topLeftCell " , sheet_ . get_frozen_panes ( ) . to_string ( ) ) ;
2015-10-30 01:46:56 +08:00
pane_node . add_attribute ( " activePane " , active_pane ) ;
pane_node . add_attribute ( " state " , " frozen " ) ;
}
auto selection_node = sheet_view_node . add_child ( " selection " ) ;
2015-10-30 07:37:07 +08:00
if ( sheet_ . has_frozen_panes ( ) )
2015-10-30 01:46:56 +08:00
{
2015-10-30 07:37:07 +08:00
if ( sheet_ . get_frozen_panes ( ) . get_row ( ) > 1 & & sheet_ . get_frozen_panes ( ) . get_column_index ( ) > 1 )
2015-10-30 01:46:56 +08:00
{
selection_node . add_attribute ( " pane " , " bottomRight " ) ;
}
2015-10-30 07:37:07 +08:00
else if ( sheet_ . get_frozen_panes ( ) . get_row ( ) > 1 )
2015-10-30 01:46:56 +08:00
{
selection_node . add_attribute ( " pane " , " bottomLeft " ) ;
}
2015-10-30 07:37:07 +08:00
else if ( sheet_ . get_frozen_panes ( ) . get_column_index ( ) > 1 )
2015-10-30 01:46:56 +08:00
{
selection_node . add_attribute ( " pane " , " topRight " ) ;
}
}
std : : string active_cell = " A1 " ;
selection_node . add_attribute ( " activeCell " , active_cell ) ;
selection_node . add_attribute ( " sqref " , active_cell ) ;
auto sheet_format_pr_node = root_node . add_child ( " sheetFormatPr " ) ;
sheet_format_pr_node . add_attribute ( " baseColWidth " , " 10 " ) ;
sheet_format_pr_node . add_attribute ( " defaultRowHeight " , " 15 " ) ;
bool has_column_properties = false ;
2015-10-30 07:37:07 +08:00
for ( auto column = sheet_ . get_lowest_column ( ) ; column < = sheet_ . get_highest_column ( ) ; column + + )
2015-10-30 01:46:56 +08:00
{
2015-10-30 07:37:07 +08:00
if ( sheet_ . has_column_properties ( column ) )
2015-10-30 01:46:56 +08:00
{
has_column_properties = true ;
break ;
}
}
if ( has_column_properties )
{
auto cols_node = root_node . add_child ( " cols " ) ;
2015-10-30 07:37:07 +08:00
for ( auto column = sheet_ . get_lowest_column ( ) ; column < = sheet_ . get_highest_column ( ) ; column + + )
2015-10-30 01:46:56 +08:00
{
2015-10-30 07:37:07 +08:00
const auto & props = sheet_ . get_column_properties ( column ) ;
2015-10-30 01:46:56 +08:00
auto col_node = cols_node . add_child ( " col " ) ;
col_node . add_attribute ( " min " , std : : to_string ( column ) ) ;
col_node . add_attribute ( " max " , std : : to_string ( column ) ) ;
col_node . add_attribute ( " width " , std : : to_string ( props . width ) ) ;
col_node . add_attribute ( " style " , std : : to_string ( props . style ) ) ;
col_node . add_attribute ( " customWidth " , props . custom ? " 1 " : " 0 " ) ;
}
}
std : : unordered_map < std : : string , std : : string > hyperlink_references ;
auto sheet_data_node = root_node . add_child ( " sheetData " ) ;
2015-10-31 06:54:04 +08:00
const auto & shared_strings = sheet_ . get_parent ( ) . get_shared_strings ( ) ;
2015-10-30 01:46:56 +08:00
2015-10-30 07:37:07 +08:00
for ( auto row : sheet_ . rows ( ) )
2015-10-30 01:46:56 +08:00
{
row_t min = static_cast < row_t > ( row . num_cells ( ) ) ;
row_t max = 0 ;
bool any_non_null = false ;
for ( auto cell : row )
{
min = std : : min ( min , cell_reference : : column_index_from_string ( cell . get_column ( ) ) ) ;
max = std : : max ( max , cell_reference : : column_index_from_string ( cell . get_column ( ) ) ) ;
if ( ! cell . garbage_collectible ( ) )
{
any_non_null = true ;
}
}
if ( ! any_non_null )
{
continue ;
}
auto row_node = sheet_data_node . add_child ( " row " ) ;
row_node . add_attribute ( " r " , std : : to_string ( row . front ( ) . get_row ( ) ) ) ;
row_node . add_attribute ( " spans " , ( std : : to_string ( min ) + " : " + std : : to_string ( max ) ) ) ;
2015-10-30 07:37:07 +08:00
if ( sheet_ . has_row_properties ( row . front ( ) . get_row ( ) ) )
2015-10-30 01:46:56 +08:00
{
row_node . add_attribute ( " customHeight " , " 1 " ) ;
2015-10-30 07:37:07 +08:00
auto height = sheet_ . get_row_properties ( row . front ( ) . get_row ( ) ) . height ;
2015-10-30 01:46:56 +08:00
if ( height = = std : : floor ( height ) )
{
row_node . add_attribute ( " ht " , std : : to_string ( static_cast < long long int > ( height ) ) + " .0 " ) ;
}
else
{
row_node . add_attribute ( " ht " , std : : to_string ( height ) ) ;
}
}
//row_node.add_attribute("x14ac:dyDescent", 0.25);
for ( auto cell : row )
{
if ( ! cell . garbage_collectible ( ) )
{
if ( cell . has_hyperlink ( ) )
{
hyperlink_references [ cell . get_hyperlink ( ) . get_id ( ) ] = cell . get_reference ( ) . to_string ( ) ;
}
auto cell_node = row_node . add_child ( " c " ) ;
cell_node . add_attribute ( " r " , cell . get_reference ( ) . to_string ( ) ) ;
if ( cell . get_data_type ( ) = = cell : : type : : string )
{
if ( cell . has_formula ( ) )
{
cell_node . add_attribute ( " t " , " str " ) ;
cell_node . add_child ( " f " ) . set_text ( cell . get_formula ( ) ) ;
cell_node . add_child ( " v " ) . set_text ( cell . to_string ( ) ) ;
continue ;
}
int match_index = - 1 ;
2015-10-31 06:54:04 +08:00
for ( std : : size_t i = 0 ; i < shared_strings . size ( ) ; i + + )
2015-10-30 01:46:56 +08:00
{
2015-10-31 06:54:04 +08:00
if ( shared_strings [ i ] = = cell . get_value < std : : string > ( ) )
2015-10-30 01:46:56 +08:00
{
match_index = static_cast < int > ( i ) ;
break ;
}
}
if ( match_index = = - 1 )
{
if ( cell . get_value < std : : string > ( ) . empty ( ) )
{
cell_node . add_attribute ( " t " , " s " ) ;
}
else
{
cell_node . add_attribute ( " t " , " inlineStr " ) ;
auto inline_string_node = cell_node . add_child ( " is " ) ;
2015-10-30 07:37:07 +08:00
inline_string_node . add_child ( " t " ) . set_text ( cell . get_value < std : : string > ( ) ) ;
2015-10-30 01:46:56 +08:00
}
}
else
{
cell_node . add_attribute ( " t " , " s " ) ;
auto value_node = cell_node . add_child ( " v " ) ;
2015-10-30 07:37:07 +08:00
value_node . set_text ( std : : to_string ( match_index ) ) ;
2015-10-30 01:46:56 +08:00
}
}
else
{
if ( cell . get_data_type ( ) ! = cell : : type : : null )
{
if ( cell . get_data_type ( ) = = cell : : type : : boolean )
{
cell_node . add_attribute ( " t " , " b " ) ;
auto value_node = cell_node . add_child ( " v " ) ;
2015-10-30 07:37:07 +08:00
value_node . set_text ( cell . get_value < bool > ( ) ? " 1 " : " 0 " ) ;
2015-10-30 01:46:56 +08:00
}
else if ( cell . get_data_type ( ) = = cell : : type : : numeric )
{
if ( cell . has_formula ( ) )
{
2015-10-30 07:37:07 +08:00
cell_node . add_child ( " f " ) . set_text ( cell . get_formula ( ) ) ;
cell_node . add_child ( " v " ) . set_text ( cell . to_string ( ) ) ;
2015-10-30 01:46:56 +08:00
continue ;
}
cell_node . add_attribute ( " t " , " n " ) ;
auto value_node = cell_node . add_child ( " v " ) ;
2015-10-30 07:37:07 +08:00
2015-10-30 01:46:56 +08:00
if ( is_integral ( cell . get_value < long double > ( ) ) )
{
2015-10-30 07:37:07 +08:00
value_node . set_text ( std : : to_string ( cell . get_value < long long > ( ) ) ) ;
2015-10-30 01:46:56 +08:00
}
else
{
std : : stringstream ss ;
ss . precision ( 20 ) ;
ss < < cell . get_value < long double > ( ) ;
ss . str ( ) ;
2015-10-30 07:37:07 +08:00
value_node . set_text ( ss . str ( ) ) ;
2015-10-30 01:46:56 +08:00
}
}
}
else if ( cell . has_formula ( ) )
{
2015-10-30 07:37:07 +08:00
cell_node . add_child ( " f " ) . set_text ( cell . get_formula ( ) ) ;
2015-10-30 01:46:56 +08:00
cell_node . add_child ( " v " ) ;
continue ;
}
}
2015-10-30 07:37:07 +08:00
if ( cell . has_style ( ) )
2015-10-30 01:46:56 +08:00
{
2015-10-30 07:37:07 +08:00
cell_node . add_attribute ( " s " , std : : to_string ( cell . get_style_id ( ) ) ) ;
2015-10-30 01:46:56 +08:00
}
}
}
}
2015-10-30 07:37:07 +08:00
if ( sheet_ . has_auto_filter ( ) )
2015-10-30 01:46:56 +08:00
{
auto auto_filter_node = root_node . add_child ( " autoFilter " ) ;
2015-10-30 07:37:07 +08:00
auto_filter_node . add_attribute ( " ref " , sheet_ . get_auto_filter ( ) . to_string ( ) ) ;
2015-10-30 01:46:56 +08:00
}
2015-10-30 07:37:07 +08:00
if ( ! sheet_ . get_merged_ranges ( ) . empty ( ) )
2015-10-30 01:46:56 +08:00
{
auto merge_cells_node = root_node . add_child ( " mergeCells " ) ;
2015-10-30 07:37:07 +08:00
merge_cells_node . add_attribute ( " count " , std : : to_string ( sheet_ . get_merged_ranges ( ) . size ( ) ) ) ;
2015-10-30 01:46:56 +08:00
2015-10-30 07:37:07 +08:00
for ( auto merged_range : sheet_ . get_merged_ranges ( ) )
2015-10-30 01:46:56 +08:00
{
auto merge_cell_node = merge_cells_node . add_child ( " mergeCell " ) ;
merge_cell_node . add_attribute ( " ref " , merged_range . to_string ( ) ) ;
}
}
2015-10-30 07:37:07 +08:00
if ( ! sheet_ . get_relationships ( ) . empty ( ) )
2015-10-30 01:46:56 +08:00
{
auto hyperlinks_node = root_node . add_child ( " hyperlinks " ) ;
2015-10-30 07:37:07 +08:00
for ( const auto & relationship : sheet_ . get_relationships ( ) )
2015-10-30 01:46:56 +08:00
{
auto hyperlink_node = hyperlinks_node . add_child ( " hyperlink " ) ;
hyperlink_node . add_attribute ( " display " , relationship . get_target_uri ( ) ) ;
hyperlink_node . add_attribute ( " ref " , hyperlink_references . at ( relationship . get_id ( ) ) ) ;
hyperlink_node . add_attribute ( " r:id " , relationship . get_id ( ) ) ;
}
}
2015-10-30 07:37:07 +08:00
if ( ! sheet_ . get_page_setup ( ) . is_default ( ) )
2015-10-30 01:46:56 +08:00
{
auto print_options_node = root_node . add_child ( " printOptions " ) ;
2015-10-30 07:37:07 +08:00
print_options_node . add_attribute ( " horizontalCentered " , sheet_ . get_page_setup ( ) . get_horizontal_centered ( ) ? " 1 " : " 0 " ) ;
print_options_node . add_attribute ( " verticalCentered " , sheet_ . get_page_setup ( ) . get_vertical_centered ( ) ? " 1 " : " 0 " ) ;
2015-10-30 01:46:56 +08:00
}
auto page_margins_node = root_node . add_child ( " pageMargins " ) ;
2015-10-30 07:37:07 +08:00
page_margins_node . add_attribute ( " left " , std : : to_string ( sheet_ . get_page_margins ( ) . get_left ( ) ) ) ;
page_margins_node . add_attribute ( " right " , std : : to_string ( sheet_ . get_page_margins ( ) . get_right ( ) ) ) ;
page_margins_node . add_attribute ( " top " , std : : to_string ( sheet_ . get_page_margins ( ) . get_top ( ) ) ) ;
page_margins_node . add_attribute ( " bottom " , std : : to_string ( sheet_ . get_page_margins ( ) . get_bottom ( ) ) ) ;
page_margins_node . add_attribute ( " header " , std : : to_string ( sheet_ . get_page_margins ( ) . get_header ( ) ) ) ;
page_margins_node . add_attribute ( " footer " , std : : to_string ( sheet_ . get_page_margins ( ) . get_footer ( ) ) ) ;
2015-10-30 01:46:56 +08:00
2015-10-30 07:37:07 +08:00
if ( ! sheet_ . get_page_setup ( ) . is_default ( ) )
2015-10-30 01:46:56 +08:00
{
auto page_setup_node = root_node . add_child ( " pageSetup " ) ;
2015-10-30 07:37:07 +08:00
std : : string orientation_string = sheet_ . get_page_setup ( ) . get_orientation ( ) = = page_setup : : orientation : : landscape ? " landscape " : " portrait " ;
2015-10-30 01:46:56 +08:00
page_setup_node . add_attribute ( " orientation " , orientation_string ) ;
2015-10-30 07:37:07 +08:00
page_setup_node . add_attribute ( " paperSize " , std : : to_string ( static_cast < int > ( sheet_ . get_page_setup ( ) . get_paper_size ( ) ) ) ) ;
page_setup_node . add_attribute ( " fitToHeight " , sheet_ . get_page_setup ( ) . fit_to_height ( ) ? " 1 " : " 0 " ) ;
page_setup_node . add_attribute ( " fitToWidth " , sheet_ . get_page_setup ( ) . fit_to_width ( ) ? " 1 " : " 0 " ) ;
2015-10-30 01:46:56 +08:00
}
2015-10-30 07:37:07 +08:00
if ( ! sheet_ . get_header_footer ( ) . is_default ( ) )
2015-10-30 01:46:56 +08:00
{
auto header_footer_node = root_node . add_child ( " headerFooter " ) ;
auto odd_header_node = header_footer_node . add_child ( " oddHeader " ) ;
std : : string header_text = " &L& \" Calibri,Regular \" &K000000Left Header Text&C& \" Arial,Regular \" &6&K445566Center Header Text&R& \" Arial,Bold \" &8&K112233Right Header Text " ;
2015-10-30 07:37:07 +08:00
odd_header_node . set_text ( header_text ) ;
2015-10-30 01:46:56 +08:00
auto odd_footer_node = header_footer_node . add_child ( " oddFooter " ) ;
std : : string footer_text = " &L& \" Times New Roman,Regular \" &10&K445566Left Footer Text_x000D_And &D and &T&C& \" Times New Roman,Bold \" &12&K778899Center Footer Text &Z&F on &A&R& \" Times New Roman,Italic \" &14&KAABBCCRight Footer Text &P of &N " ;
2015-10-30 07:37:07 +08:00
odd_footer_node . set_text ( footer_text ) ;
2015-10-30 01:46:56 +08:00
}
2015-10-31 06:54:04 +08:00
return xml ;
2015-10-30 01:46:56 +08:00
}
} // namespace xlnt