diff --git a/include/xlnt/workbook/workbook.hpp b/include/xlnt/workbook/workbook.hpp index d4f00c06..33228910 100644 --- a/include/xlnt/workbook/workbook.hpp +++ b/include/xlnt/workbook/workbook.hpp @@ -827,6 +827,11 @@ private: /// void garbage_collect_formulae(); + /// + /// Update extended workbook properties titlesOfParts and headingPairs when sheets change. + /// + void update_sheet_properties(); + /// /// An opaque pointer to a structure that holds all of the data relating to this workbook. /// diff --git a/source/detail/xlsx_producer.cpp b/source/detail/xlsx_producer.cpp index be65eb96..ac5c8ad1 100755 --- a/source/detail/xlsx_producer.cpp +++ b/source/detail/xlsx_producer.cpp @@ -252,6 +252,11 @@ void xlsx_producer::write_property(const std::string &name, const variant &value write_start_element(constants::ns("vt"), "lpwstr"); } + if (!custom && ns == constants::ns("dcterms") && (name == "created" || name == "modified")) + { + write_attribute(xml::qname(constants::ns("xsi"), "type"), "dcterms:W3CDTF"); + } + write_characters(value.get()); if (custom) diff --git a/source/workbook/tests/test_round_trip.hpp b/source/workbook/tests/test_round_trip.hpp index d730a402..0c9086ed 100644 --- a/source/workbook/tests/test_round_trip.hpp +++ b/source/workbook/tests/test_round_trip.hpp @@ -24,6 +24,7 @@ public: std::vector destination; source_workbook.save(destination); + source_workbook.save("temp.xlsx"); std::ifstream source_stream(source.string(), std::ios::binary); diff --git a/source/workbook/workbook.cpp b/source/workbook/workbook.cpp index ed14078a..8b346759 100644 --- a/source/workbook/workbook.cpp +++ b/source/workbook/workbook.cpp @@ -759,6 +759,8 @@ worksheet workbook::create_sheet() workbook_rel.target(), relationship_type::worksheet, relative_sheet_uri, target_mode::internal); d_->sheet_title_rel_id_map_[title] = ws_rel; + update_sheet_properties(); + return worksheet(&d_->worksheets_.back()); } @@ -1007,9 +1009,10 @@ void workbook::remove_sheet(worksheet ws) } auto ws_rel_id = d_->sheet_title_rel_id_map_.at(ws.title()); - auto wb_rel = d_->manifest_.relationship(xlnt::path("/"), xlnt::relationship_type::office_document); + auto wb_rel = d_->manifest_.relationship(path("/"), xlnt::relationship_type::office_document); auto ws_rel = d_->manifest_.relationship(wb_rel.target().path(), ws_rel_id); - d_->manifest_.unregister_override_type(ws_rel.target().path()); + auto ws_part = d_->manifest_.canonicalize({wb_rel, ws_rel}).resolve(path("/")); + d_->manifest_.unregister_override_type(ws_part); auto rel_id_map = d_->manifest_.unregister_relationship(wb_rel.target(), ws_rel_id); d_->sheet_title_rel_id_map_.erase(ws.title()); d_->worksheets_.erase(match_iter); @@ -1020,6 +1023,8 @@ void workbook::remove_sheet(worksheet ws) title_rel_id_pair.second = rel_id_map.count(title_rel_id_pair.second) > 0 ? rel_id_map[title_rel_id_pair.second] : title_rel_id_pair.second; } + + update_sheet_properties(); } worksheet workbook::create_sheet(std::size_t index) @@ -1054,6 +1059,8 @@ worksheet workbook::create_sheet_with_rel(const std::string &title, const relati workbook_rel.target(), relationship_type::worksheet, rel.target(), target_mode::internal); d_->sheet_title_rel_id_map_[title] = ws_rel; + update_sheet_properties(); + return worksheet(&d_->worksheets_.back()); } @@ -1499,4 +1506,18 @@ void workbook::garbage_collect_formulae() } } +void workbook::update_sheet_properties() +{ + if (has_extended_property(extended_property::titles_of_parts)) + { + extended_property(extended_property::titles_of_parts, sheet_titles()); + } + + if (has_extended_property(extended_property::heading_pairs)) + { + extended_property(extended_property::heading_pairs, + std::vector{variant("Worksheets"), variant(static_cast(sheet_count()))}); + } +} + } // namespace xlnt diff --git a/source/worksheet/worksheet.cpp b/source/worksheet/worksheet.cpp index 445de53a..1c8cb0f8 100644 --- a/source/worksheet/worksheet.cpp +++ b/source/worksheet/worksheet.cpp @@ -275,8 +275,8 @@ void worksheet::title(const std::string &title) throw invalid_sheet_title(title); } - auto same_title = - std::find_if(workbook().begin(), workbook().end(), [&](worksheet ws) { return ws.title() == title; }); + auto same_title = std::find_if(workbook().begin(), workbook().end(), + [&](worksheet ws) { return ws.title() == title; }); if (same_title != workbook().end() && *same_title != *this) { @@ -286,6 +286,8 @@ void worksheet::title(const std::string &title) workbook().d_->sheet_title_rel_id_map_[title] = workbook().d_->sheet_title_rel_id_map_[d_->title_]; workbook().d_->sheet_title_rel_id_map_.erase(d_->title_); d_->title_ = title; + + workbook().update_sheet_properties(); } cell_reference worksheet::frozen_panes() const