diff --git a/include/xlnt/serialization/style_serializer.hpp b/include/xlnt/serialization/style_serializer.hpp index 5da0b181..a98f6924 100644 --- a/include/xlnt/serialization/style_serializer.hpp +++ b/include/xlnt/serialization/style_serializer.hpp @@ -190,7 +190,7 @@ public: /// Read all named styles from named_style_node and cell_styles_node and add them to workbook. /// Return true on success. /// - bool read_named_styles(const xml_node &named_styles_node, const xml_node &cell_styles_node); + bool read_named_styles(const xml_node &cell_styles_node, const xml_node &cell_style_formats_node); /// /// Read all borders from number_formats_node and add them to workbook. diff --git a/include/xlnt/workbook/workbook.hpp b/include/xlnt/workbook/workbook.hpp index e9cf7bd2..07568d18 100644 --- a/include/xlnt/workbook/workbook.hpp +++ b/include/xlnt/workbook/workbook.hpp @@ -187,6 +187,8 @@ public: const cell_style &get_style(std::size_t style_index) const; std::size_t add_style(const cell_style &style); void clear_styles(); + std::vector &get_styles(); + const std::vector &get_styles() const; // Named Styles bool has_named_style(const std::string &name); diff --git a/source/serialization/style_serializer.cpp b/source/serialization/style_serializer.cpp index 96cd5385..197e722c 100644 --- a/source/serialization/style_serializer.cpp +++ b/source/serialization/style_serializer.cpp @@ -357,17 +357,15 @@ cell_style style_serializer::read_cell_style(const xml_node &style_node) return s; } -named_style style_serializer::read_named_style(const xml_node &named_style_node, const xml_node &style_parent_node) +named_style style_serializer::read_named_style(const xml_node &cell_style_node, const xml_node &cell_style_format_node) { named_style s; - s.set_name(named_style_node.get_attribute("name")); - s.set_hidden(named_style_node.has_attribute("hidden") && is_true(named_style_node.get_attribute("hidden"))); - s.set_builtin_id(std::stoull(named_style_node.get_attribute("builtinId"))); + s.set_name(cell_style_node.get_attribute("name")); + s.set_hidden(cell_style_node.has_attribute("hidden") && is_true(cell_style_node.get_attribute("hidden"))); + s.set_builtin_id(std::stoull(cell_style_node.get_attribute("builtinId"))); - auto base_style_id = std::stoull(named_style_node.get_attribute("xfId")); - auto base_style_node = style_parent_node.get_children().at(base_style_id); - auto base_style = read_cell_style(base_style_node); + auto base_style = read_cell_style(cell_style_format_node); //TODO shouldn't have to set apply after set_X() s.set_alignment(base_style.get_alignment()); @@ -441,14 +439,35 @@ bool style_serializer::read_cell_styles(const xlnt::xml_node &cell_styles_node) return true; } -bool style_serializer::read_named_styles(const xlnt::xml_node &named_styles_node, const xlnt::xml_node &cell_styles_node) +bool style_serializer::read_named_styles(const xlnt::xml_node &cell_styles_node, const xlnt::xml_node &cell_style_formats_node) { - for (auto named_style_node : named_styles_node.get_children()) + std::size_t style_index = 0; + + for (auto cell_style_format_node : cell_style_formats_node.get_children()) { - auto ns = read_named_style(named_style_node, cell_styles_node); - auto named_style_index = std::stoull(named_style_node.get_attribute("xfId")); + for (auto cell_style_node : cell_styles_node.get_children()) + { + auto cell_style_format_index = std::stoull(cell_style_node.get_attribute("xfId")); + + if (cell_style_format_index == style_index) + { + auto ns = read_named_style(cell_style_node, cell_style_format_node); + named_styles_[style_index] = ns; + + break; + } + } - named_styles_[named_style_index] = ns; + style_index++; + } + + if (named_styles_.empty()) + { + named_style ns; + ns.set_name("Standard"); + ns.set_hidden(false); + ns.set_builtin_id(0); + named_styles_[0] = ns; } return true; @@ -477,6 +496,11 @@ bool style_serializer::read_number_formats(const xml_node &number_formats_node) number_formats_.push_back(nf); } + + if (number_formats_.empty()) + { + number_formats_.push_back(number_format::general()); + } return true; } @@ -730,23 +754,27 @@ color style_serializer::read_color(const xml_node &color_node) void style_serializer::initialize_vectors() { - std::unordered_set> cell_styles_set; + bool any_style = false; for (auto ws : workbook_) { for (auto row : ws) { - for (auto c : row) + for (auto cell : row) { - if (c.has_style()) + if (cell.has_style()) { - cell_styles_set.insert(c.get_style()); + any_style = true; } } } } - cell_styles_.assign(cell_styles_set.begin(), cell_styles_set.end()); + if (any_style) + { + cell_styles_.assign(workbook_.get_styles().begin(), workbook_.get_styles().end()); + } + colors_.clear(); borders_.clear(); fills_.clear(); diff --git a/source/styles/tests/test_stylesheet.hpp b/source/styles/tests/test_stylesheet.hpp index de95d9db..c92dd0c5 100644 --- a/source/styles/tests/test_stylesheet.hpp +++ b/source/styles/tests/test_stylesheet.hpp @@ -74,16 +74,6 @@ public: TS_ASSERT_EQUALS(s.get_number_formats().size(), 1); } - void test_merge_named_styles() - { - xlnt::xml_document doc; - auto xml = PathHelper::read_file(PathHelper::GetDataDirectory("/reader/styles/complex-styles.xml")); - doc.from_string(xml); - xlnt::workbook wb; - xlnt::style_serializer s(wb); - TS_ASSERT(s.read_stylesheet(doc)); - TS_ASSERT_EQUALS(wb.get_named_styles().size(), 3); - } /* void _test_unprotected_cell() { diff --git a/source/workbook/workbook.cpp b/source/workbook/workbook.cpp index 8e1f6fb4..5b176efb 100644 --- a/source/workbook/workbook.cpp +++ b/source/workbook/workbook.cpp @@ -736,4 +736,14 @@ named_style &workbook::create_named_style(const std::string &name) return d_->named_styles_.back(); } +std::vector &workbook::get_styles() +{ + return d_->cell_styles_; +} + +const std::vector &workbook::get_styles() const +{ + return d_->cell_styles_; +} + } // namespace xlnt