Serialisation of sheetPr and printOptions elements

This commit is contained in:
Crzyrndm 2018-06-24 14:01:27 +12:00
parent 93323f334d
commit d2d0c2ab55
8 changed files with 342 additions and 141 deletions

View File

@ -149,28 +149,6 @@ public:
/// </summary>
void fit_to_width(bool fit_to_width);
/// <summary>
/// Sets whether the worksheet should be centered horizontall on the page if it takes
/// up less than a full page.
/// </summary>
void horizontal_centered(bool horizontal_centered);
/// <summary>
/// Returns whether horizontal centering has been enabled.
/// </summary>
bool horizontal_centered() const;
/// <summary>
/// Sets whether the worksheet should be vertically centered on the page if it takes
/// up less than a full page.
/// </summary>
void vertical_centered(bool vertical_centered);
/// <summary>
/// Returns whether vertical centering has been enabled.
/// </summary>
bool vertical_centered() const;
/// <summary>
/// Sets the factor by which the page should be scaled during printing.
/// </summary>
@ -225,16 +203,6 @@ private:
/// </summary>
bool fit_to_width_;
/// <summary>
/// Whether or not to center the content horizontally
/// </summary>
bool horizontal_centered_;
/// <summary>
/// Whether or not to center the conent vertically
/// </summary>
bool vertical_centered_;
/// <summary>
/// The amount to scale the worksheet
/// </summary>

View File

@ -0,0 +1,58 @@
// Copyright (c) 2014-2018 Thomas Fussell
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, WRISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE
//
// @license: http://www.opensource.org/licenses/mit-license.php
// @author: see AUTHORS file
#pragma once
#include <xlnt/xlnt_config.hpp>
#include <xlnt/utils/optional.hpp>
namespace xlnt {
struct print_options
{
/// <summary>
/// if both grid_lines_set and this are true, grid lines are printed
/// </summary>
optional<bool> print_grid_lines;
/// <summary>
/// if both print grid lines and this are true, grid lines are printed
/// </summary>
optional<bool> grid_lines_set;
/// <summary>
/// print row and column headings
/// </summary>
optional<bool> print_headings;
/// <summary>
/// center on page horizontally
/// </summary>
optional<bool> horizontal_centered;
/// <summary>
/// center on page vertically
/// </summary>
optional<bool> vertical_centered;
};
} // namespace xlnt

View File

@ -0,0 +1,81 @@
// Copyright (c) 2014-2018 Thomas Fussell
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, WRISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE
//
// @license: http://www.opensource.org/licenses/mit-license.php
// @author: see AUTHORS file
#pragma once
#include <string>
#include <xlnt/xlnt_config.hpp>
#include <xlnt/utils/optional.hpp>
#include <xlnt/cell/cell_reference.hpp>
namespace xlnt {
struct sheet_pr
{
/// <summary>
/// is horizontally synced to the anchor point
/// </summary>
optional<bool> sync_horizontal_;
/// <summary>
/// is vertically synced to the anchor point
/// </summary>
optional<bool> sync_vertical_;
/// <summary>
/// Anchor point for worksheet's window
/// </summary>
optional<cell_reference> sync_ref_;
/// <summary>
/// Lotus compatibility option
/// </summary>
optional<bool> transition_evaluation_;
/// <summary>
/// Lotus compatibility option
/// </summary>
optional<bool> transition_entry_;
/// <summary>
/// worksheet is published
/// </summary>
optional<bool> published_;
/// <summary>
/// stable name of the sheet
/// </summary>
optional<std::string> code_name_;
/// <summary>
/// worksheet has one or more autofilters or advanced filters on
/// </summary>
optional<bool> filter_mode;
/// <summary>
/// whether the conditional formatting calculations shall be evaluated
/// </summary>
optional<bool> enable_format_condition_calculation_;
};
} // namespace xlnt

View File

@ -37,6 +37,8 @@
#include <xlnt/worksheet/row_properties.hpp>
#include <xlnt/worksheet/sheet_format_properties.hpp>
#include <xlnt/worksheet/sheet_view.hpp>
#include <xlnt/worksheet/print_options.hpp>
#include <xlnt/worksheet/sheet_pr.hpp>
#include <detail/implementations/cell_impl.hpp>
namespace xlnt {
@ -83,6 +85,8 @@ struct worksheet_impl
column_breaks_ = other.column_breaks_;
row_breaks_ = other.row_breaks_;
extension_list_ = other.extension_list_;
sheet_properties_ = other.sheet_properties_;
print_options_ = other.print_options_;
for (auto &row : cell_map_)
{
@ -125,6 +129,8 @@ struct worksheet_impl
std::vector<row_t> row_breaks_;
std::unordered_map<std::string, comment> comments_;
optional<print_options> print_options_;
optional<sheet_pr> sheet_properties_;
optional<ext_list> extension_list_;
};

View File

@ -26,13 +26,6 @@
#include <sstream>
#include <unordered_map>
#include <detail/constants.hpp>
#include <detail/header_footer/header_footer_code.hpp>
#include <detail/implementations/workbook_impl.hpp>
#include <detail/serialization/custom_value_traits.hpp>
#include <detail/serialization/vector_streambuf.hpp>
#include <detail/serialization/xlsx_consumer.hpp>
#include <detail/serialization/zstream.hpp>
#include <xlnt/cell/cell.hpp>
#include <xlnt/cell/comment.hpp>
#include <xlnt/cell/hyperlink.hpp>
@ -42,6 +35,13 @@
#include <xlnt/workbook/workbook.hpp>
#include <xlnt/worksheet/selection.hpp>
#include <xlnt/worksheet/worksheet.hpp>
#include <detail/constants.hpp>
#include <detail/header_footer/header_footer_code.hpp>
#include <detail/implementations/workbook_impl.hpp>
#include <detail/serialization/custom_value_traits.hpp>
#include <detail/serialization/vector_streambuf.hpp>
#include <detail/serialization/xlsx_consumer.hpp>
#include <detail/serialization/zstream.hpp>
namespace std {
@ -368,7 +368,8 @@ std::string xlsx_consumer::read_worksheet_begin(const std::string &rel_id)
target_.d_->sheet_title_rel_id_map_.end(),
[&](const std::pair<std::string, std::string> &p) {
return p.second == rel_id;
})->first;
})
->first;
auto ws = worksheet(current_worksheet_);
@ -381,6 +382,44 @@ std::string xlsx_consumer::read_worksheet_begin(const std::string &rel_id)
if (current_worksheet_element == qn("spreadsheetml", "sheetPr")) // CT_SheetPr 0-1
{
sheet_pr props;
if (parser().attribute_present("syncHorizontal"))
{ // optional, boolean, false
props.sync_horizontal_.set(parser().attribute<bool>("syncHorizontal"));
}
if (parser().attribute_present("syncVertical"))
{// optional, boolean, false
props.sync_vertical_.set(parser().attribute<bool>("syncVertical"));
}
if (parser().attribute_present("syncRef"))
{ // optional, ST_Ref, false
props.sync_ref_.set(cell_reference(parser().attribute("syncRef")));
}
if (parser().attribute_present("transitionEvaluation"))
{ // optional, boolean, false
props.transition_evaluation_.set(parser().attribute<bool>("transitionEvaluation"));
}
if (parser().attribute_present("transitionEntry"))
{// optional, boolean, false
props.transition_entry_.set(parser().attribute<bool>("transitionEntry"));
}
if (parser().attribute_present("published"))
{// optional, boolean, true
props.published_.set(parser().attribute<bool>("published"));
}
if (parser().attribute_present("codeName"))
{ // optional, string
props.code_name_.set(parser().attribute<std::string>("codeName"));
}
if (parser().attribute_present("filterMode"))
{// optional, boolean, false
props.filter_mode.set(parser().attribute<bool>("filterMode"));
}
if (parser().attribute_present("enableFormatConditionsCalculation"))
{// optional, boolean, true
props.enable_format_condition_calculation_.set(parser().attribute<bool>("enableFormatConditionsCalculation"));
}
ws.d_->sheet_properties_.set(props);
while (in_element(current_worksheet_element))
{
auto sheet_pr_child_element = expect_start_element(xml::content::simple);
@ -408,16 +447,6 @@ std::string xlsx_consumer::read_worksheet_begin(const std::string &rel_id)
expect_end_element(sheet_pr_child_element);
}
skip_attribute("syncHorizontal"); // optional, boolean, false
skip_attribute("syncVertical"); // optional, boolean, false
skip_attribute("syncRef"); // optional, ST_Ref, false
skip_attribute("transitionEvaluation"); // optional, boolean, false
skip_attribute("transitionEntry"); // optional, boolean, false
skip_attribute("published"); // optional, boolean, true
skip_attribute("codeName"); // optional, string
skip_attribute("filterMode"); // optional, boolean, false
skip_attribute("enableFormatConditionsCalculation"); // optional, boolean, true
}
else if (current_worksheet_element == qn("spreadsheetml", "dimension")) // CT_SheetDimension 0-1
{
@ -589,9 +618,11 @@ std::string xlsx_consumer::read_worksheet_begin(const std::string &rel_id)
}
auto custom = parser().attribute_present("customWidth")
? is_true(parser().attribute("customWidth")) : false;
? is_true(parser().attribute("customWidth"))
: false;
auto hidden = parser().attribute_present("hidden")
? is_true(parser().attribute("hidden")) : false;
? is_true(parser().attribute("hidden"))
: false;
auto best_fit = parser().attribute_present("bestFit")
? is_true(parser().attribute("bestFit"))
: false;
@ -774,7 +805,6 @@ void xlsx_consumer::read_worksheet_sheetdata()
cell.error(value_string);
}
}
}
expect_end_element(qn("spreadsheetml", "row"));
@ -926,7 +956,28 @@ worksheet xlsx_consumer::read_worksheet_end(const std::string &rel_id)
}
else if (current_worksheet_element == qn("spreadsheetml", "printOptions")) // CT_PrintOptions 0-1
{
print_options opts;
if (parser().attribute_present("gridLines"))
{
opts.print_grid_lines.set(parser().attribute<bool>("gridLines"));
}
if (parser().attribute_present("gridLinesSet"))
{
opts.print_grid_lines.set(parser().attribute<bool>("gridLinesSet"));
}
if (parser().attribute_present("headings"))
{
opts.print_grid_lines.set(parser().attribute<bool>("headings"));
}
if (parser().attribute_present("horizontalCentered"))
{
opts.print_grid_lines.set(parser().attribute<bool>("horizontalCentered"));
}
if (parser().attribute_present("verticalCentered"))
{
opts.print_grid_lines.set(parser().attribute<bool>("verticalCentered"));
}
ws.d_->print_options_.set(opts);
skip_remaining_content(current_worksheet_element);
}
else if (current_worksheet_element == qn("spreadsheetml", "pageMargins")) // CT_PageMargins 0-1
@ -1061,7 +1112,8 @@ worksheet xlsx_consumer::read_worksheet_end(const std::string &rel_id)
{
auto count = parser().attribute_present("count") ? parser().attribute<std::size_t>("count") : 0;
auto manual_break_count = parser().attribute_present("manualBreakCount")
? parser().attribute<std::size_t>("manualBreakCount") : 0;
? parser().attribute<std::size_t>("manualBreakCount")
: 0;
while (in_element(qn("spreadsheetml", "rowBreaks")))
{
@ -1189,8 +1241,7 @@ bool xlsx_consumer::has_cell()
std::vector<relationship> xlsx_consumer::read_relationships(const path &part)
{
const auto part_rels_path = part.parent().append("_rels")
.append(part.filename() + ".rels").relative_to(path("/"));
const auto part_rels_path = part.parent().append("_rels").append(part.filename() + ".rels").relative_to(path("/"));
std::vector<xlnt::relationship> relationships;
if (!archive_->has_file(part_rels_path)) return relationships;
@ -1496,9 +1547,11 @@ void xlsx_consumer::read_custom_properties()
void xlsx_consumer::read_office_document(const std::string &content_type) // CT_Workbook
{
if (content_type != "application/vnd."
if (content_type !=
"application/vnd."
"openxmlformats-officedocument.spreadsheetml.sheet.main+xml"
&& content_type != "application/vnd."
&& content_type !=
"application/vnd."
"openxmlformats-officedocument.spreadsheetml.template.main+xml")
{
throw xlnt::invalid_file(content_type);
@ -1574,7 +1627,8 @@ void xlsx_consumer::read_office_document(const std::string &content_type) // CT_
{
target_.base_date(parser().attribute_present("date1904") // optional, bool=false
&& is_true(parser().attribute("date1904"))
? calendar::mac_1904 : calendar::windows_1900);
? calendar::mac_1904
: calendar::windows_1900);
skip_attribute("showObjects"); // optional, ST_Objects="all"
skip_attribute("showBorderUnselectedTables"); // optional, bool=true
skip_attribute("filterPrivacy"); // optional, bool=false
@ -1785,7 +1839,8 @@ void xlsx_consumer::read_office_document(const std::string &content_type) // CT_
target_.d_->sheet_title_rel_id_map_.end(),
[&](const std::pair<std::string, std::string> &p) {
return p.second == worksheet_rel.id();
})->first;
})
->first;
auto id = sheet_title_id_map_[title];
auto index = sheet_title_index_map_[title];
@ -2273,28 +2328,32 @@ void xlsx_consumer::read_stylesheet()
record.first.border_applied = is_true(parser().attribute("applyBorder"));
}
record.first.border_id = parser().attribute_present("borderId")
? parser().attribute<std::size_t>("borderId") : 0;
? parser().attribute<std::size_t>("borderId")
: 0;
if (parser().attribute_present("applyFill"))
{
record.first.fill_applied = is_true(parser().attribute("applyFill"));
}
record.first.fill_id = parser().attribute_present("fillId")
? parser().attribute<std::size_t>("fillId") : 0;
? parser().attribute<std::size_t>("fillId")
: 0;
if (parser().attribute_present("applyFont"))
{
record.first.font_applied = is_true(parser().attribute("applyFont"));
}
record.first.font_id = parser().attribute_present("fontId")
? parser().attribute<std::size_t>("fontId") : 0;
? parser().attribute<std::size_t>("fontId")
: 0;
if (parser().attribute_present("applyNumberFormat"))
{
record.first.number_format_applied = is_true(parser().attribute("applyNumberFormat"));
}
record.first.number_format_id = parser().attribute_present("numFmtId")
? parser().attribute<std::size_t>("numFmtId") : 0;
? parser().attribute<std::size_t>("numFmtId")
: 0;
auto apply_alignment_present = parser().attribute_present("applyAlignment");
if (apply_alignment_present)
@ -2820,7 +2879,8 @@ rich_text xlsx_consumer::read_rich_text(const xml::qname &parent)
auto text_element = expect_start_element(xml::content::mixed);
const auto xml_space = qn("xml", "space");
const auto preserve_space = parser().attribute_present(xml_space)
? parser().attribute(xml_space) == "preserve" : false;
? parser().attribute(xml_space) == "preserve"
: false;
skip_attributes();
auto text = read_text();
@ -2872,12 +2932,14 @@ rich_text xlsx_consumer::read_rich_text(const xml::qname &parent)
else if (current_run_property_element == xml::qname(xmlns, "b"))
{
run.second.get().bold(parser().attribute_present("val")
? is_true(parser().attribute("val")) : true);
? is_true(parser().attribute("val"))
: true);
}
else if (current_run_property_element == xml::qname(xmlns, "i"))
{
run.second.get().italic(parser().attribute_present("val")
? is_true(parser().attribute("val")) : true);
? is_true(parser().attribute("val"))
: true);
}
else if (current_run_property_element == xml::qname(xmlns, "u"))
{
@ -2972,4 +3034,4 @@ manifest &xlsx_consumer::manifest()
}
} // namespace detail
} // namepsace xlnt
} // namespace xlnt

View File

@ -2224,9 +2224,46 @@ void xlsx_producer::write_worksheet(const relationship &rel)
write_attribute(xml::qname(xmlns_mc, "Ignorable"), "x14ac");
}
if (ws.has_page_setup())
if (ws.d_->sheet_properties_.is_set())
{
write_start_element(xmlns, "sheetPr");
auto &props = ws.d_->sheet_properties_.get();
if (props.sync_horizontal_.is_set())
{
write_attribute("syncHorizontal", props.sync_horizontal_.get());
}
if (props.sync_vertical_.is_set())
{
write_attribute("syncVertical", props.sync_vertical_.get());
}
if (props.sync_ref_.is_set())
{
write_attribute("syncRef", props.sync_ref_.get().to_string());
}
if (props.transition_evaluation_.is_set())
{
write_attribute("transitionEvaluation", props.transition_evaluation_.get());
}
if (props.transition_entry_.is_set())
{
write_attribute("transitionEntry", props.transition_entry_.get());
}
if (props.published_.is_set())
{
write_attribute("published", props.published_.get());
}
if (props.code_name_.is_set())
{
write_attribute("codeName", props.code_name_.get());
}
if (props.filter_mode.is_set())
{
write_attribute("filterMode", props.filter_mode.get());
}
if (props.enable_format_condition_calculation_.is_set())
{
write_attribute("enableFormatConditionsCalculation", props.enable_format_condition_calculation_.get());
}
write_start_element(xmlns, "outlinePr");
write_attribute("summaryBelow", "1");
@ -2706,11 +2743,30 @@ void xlsx_producer::write_worksheet(const relationship &rel)
write_end_element(xmlns, "hyperlinks");
}
if (ws.has_page_setup())
if (ws.d_->print_options_.is_set())
{
auto &opts = ws.d_->print_options_.get();
write_start_element(xmlns, "printOptions");
write_attribute("horizontalCentered", write_bool(ws.page_setup().horizontal_centered()));
write_attribute("verticalCentered", write_bool(ws.page_setup().vertical_centered()));
if (opts.print_grid_lines.is_set())
{
write_attribute("gridLines", write_bool(opts.print_grid_lines.get()));
}
if (opts.grid_lines_set.is_set())
{
write_attribute("gridLineSet", write_bool(opts.grid_lines_set.get()));
}
if (opts.print_headings.is_set())
{
write_attribute("headings", write_bool(opts.print_headings.get()));
}
if (opts.horizontal_centered.is_set())
{
write_attribute("horizontalCentered", write_bool(opts.horizontal_centered.get()));
}
if (opts.vertical_centered.is_set())
{
write_attribute("verticalCentered", write_bool(opts.vertical_centered.get()));
}
write_end_element(xmlns, "printOptions");
}

View File

@ -32,8 +32,6 @@ page_setup::page_setup()
fit_to_page_(false),
fit_to_height_(false),
fit_to_width_(false),
horizontal_centered_(false),
vertical_centered_(false),
scale_(1)
{
}
@ -98,26 +96,6 @@ void page_setup::fit_to_width(bool fit_to_width)
fit_to_width_ = fit_to_width;
}
void page_setup::horizontal_centered(bool horizontal_centered)
{
horizontal_centered_ = horizontal_centered;
}
bool page_setup::horizontal_centered() const
{
return horizontal_centered_;
}
void page_setup::vertical_centered(bool vertical_centered)
{
vertical_centered_ = vertical_centered;
}
bool page_setup::vertical_centered() const
{
return vertical_centered_;
}
void page_setup::scale(double scale)
{
scale_ = scale;

View File

@ -59,13 +59,5 @@ public:
xlnt_assert(!ps.fit_to_width());
ps.fit_to_width(true);
xlnt_assert(ps.fit_to_width());
xlnt_assert(!ps.horizontal_centered());
ps.horizontal_centered(true);
xlnt_assert(ps.horizontal_centered());
xlnt_assert(!ps.vertical_centered());
ps.vertical_centered(true);
xlnt_assert(ps.vertical_centered());
}
};