diff --git a/.gitignore b/.gitignore index 2de37aca..c57a8996 100644 --- a/.gitignore +++ b/.gitignore @@ -1,7 +1,6 @@ bin/ lib/ -build/genie/*/ -build/cmake/build/ +build/ docs/_*/ docs/doxyxml/ *.obj diff --git a/cmake/CMakeLists.txt b/cmake/CMakeLists.txt index 394eec49..5e7d93dc 100644 --- a/cmake/CMakeLists.txt +++ b/cmake/CMakeLists.txt @@ -28,5 +28,5 @@ foreach(OUTPUTCONFIG ${CMAKE_CONFIGURATION_TYPES}) set(CMAKE_RUNTIME_OUTPUT_DIRECTORY_${OUTPUTCONFIG} ${CMAKE_BINARY_DIR}/../bin) endforeach(OUTPUTCONFIG CMAKE_CONFIGURATION_TYPES) -include(xlnt.cmake) include(xlnt.test.cmake) +include(xlnt.cmake) diff --git a/cmake/build-linux.sh b/cmake/build-linux.sh deleted file mode 100755 index 57fabcae..00000000 --- a/cmake/build-linux.sh +++ /dev/null @@ -1,11 +0,0 @@ -ACTION=$1 - -if [ "$ACTION" = "clean" ]; then - rm -rf build - exit 0 -fi - -mkdir build -cd build -cmake .. -make diff --git a/cmake/build-osx.sh b/cmake/build-osx.sh deleted file mode 100755 index b64028e3..00000000 --- a/cmake/build-osx.sh +++ /dev/null @@ -1,11 +0,0 @@ -ACTION=$1 - -if [ "$ACTION" = "clean" ]; then - rm -rf build - exit 0 -fi - -mkdir ../build -cd ../build -cmake -G "Unix Makefiles" ../cmake -make diff --git a/cmake/clean b/cmake/clean index 72d557ae..d71cb22e 100755 --- a/cmake/clean +++ b/cmake/clean @@ -9,4 +9,3 @@ dirs = ['../bin', '../lib', '../build'] for dir in dirs: if os.path.isdir(dir): shutil.rmtree(dir) - diff --git a/cmake/configure b/cmake/configure new file mode 100755 index 00000000..bc4079d1 --- /dev/null +++ b/cmake/configure @@ -0,0 +1,19 @@ +#!/usr/bin/env python3 + +import os +import subprocess +import sys + +os.chdir(os.path.dirname(os.path.abspath(__file__))) + +if not os.path.isdir('../build'): + os.mkdir('../build') + +generator = 'Unix Makefiles' + +if sys.platform == 'darwin': + generator = 'Unix Makefiles' +elif sys.platform == 'win32': + generator = 'Visual Studio 14 2015' + +subprocess.call(['cmake3', '-G', generator, '../cmake'], cwd='../build') diff --git a/cmake/xlnt.test.cmake b/cmake/xlnt.test.cmake index 9aa95873..2b599a97 100644 --- a/cmake/xlnt.test.cmake +++ b/cmake/xlnt.test.cmake @@ -5,20 +5,28 @@ include_directories(../source) include_directories(../third-party/pugixml/src) include_directories(../third-party/cxxtest) -add_executable(xlnt.test ../tests/runner-autogen.cpp) +FILE(GLOB TEST_HEADERS ../tests/*.hpp) +FILE(GLOB TEST_HELPERS_HEADERS ../tests/helpers/*.hpp) +FILE(GLOB TEST_HELPERS_SOURCES ../tests/helpers/*.cpp) + +add_executable(xlnt.test ../tests/runner-autogen.cpp ${TEST_HEADERS} ${TEST_HELPERS_HEADERS} ${TEST_HELPERS_SOURCES}) + +source_group(runner FILES ../tests/runner-autogen.cpp) +source_group(tests FILES ${TEST_HEADERS}) +source_group(helpers FILES ${TEST_HELPERS_HEADERS} ${TEST_HELPERS_SOURCES}) target_link_libraries(xlnt.test xlnt) -add_custom_target (test-runner +add_custom_target (generate-test-runner COMMAND ${CMAKE_CURRENT_SOURCE_DIR}/generate-tests.sh COMMENT "Generating test runner tests/runner-autogen.cpp" ) -add_dependencies(xlnt.test test-runner) +add_dependencies(xlnt.test generate-test-runner) add_custom_command( - TARGET xlnt.test - POST_BUILD - COMMAND ${CMAKE_CURRENT_SOURCE_DIR}/../bin/xlnt.test - VERBATIM + TARGET xlnt.test + POST_BUILD + COMMAND ${CMAKE_CURRENT_SOURCE_DIR}/../bin/xlnt.test + VERBATIM ) diff --git a/include/xlnt/serialization/workbook_serializer.hpp b/include/xlnt/serialization/workbook_serializer.hpp index c8fbb19f..1b342d73 100644 --- a/include/xlnt/serialization/workbook_serializer.hpp +++ b/include/xlnt/serialization/workbook_serializer.hpp @@ -52,9 +52,6 @@ class workbook_serializer xml_document write_properties_app() const; xml_document write_properties_core() const; - std::vector read_sheets(); - std::vector detect_worksheets(); - xml_node write_named_ranges() const; private: diff --git a/source/cell/cell.cpp b/source/cell/cell.cpp index 8e3206ad..b04e2815 100644 --- a/source/cell/cell.cpp +++ b/source/cell/cell.cpp @@ -910,6 +910,7 @@ template <> void cell::set_value(std::string s) { d_->set_string(s, get_parent().get_parent().get_guess_types()); + if(!s.empty()) get_parent().get_parent().add_shared_string(s); } template <> diff --git a/source/serialization/excel_serializer.cpp b/source/serialization/excel_serializer.cpp index 9a59720b..de62c4b2 100644 --- a/source/serialization/excel_serializer.cpp +++ b/source/serialization/excel_serializer.cpp @@ -44,16 +44,27 @@ bool load_workbook(xlnt::zip_file &archive, bool guess_types, bool data_only, xl wb.set_guess_types(guess_types); wb.set_data_only(data_only); + if(!archive.has_file(xlnt::constants::ArcContentTypes)) + { + throw xlnt::invalid_file_exception("missing [Content Types].xml"); + } + xlnt::manifest_serializer ms(wb.get_manifest()); ms.read_manifest(xlnt::xml_serializer::deserialize(archive.read(xlnt::constants::ArcContentTypes))); if (ms.determine_document_type() != "excel") { - throw xlnt::invalid_file_exception(""); + throw xlnt::invalid_file_exception("package is not an OOXML SpreadsheetML"); } wb.clear(); - + + if(archive.has_file(xlnt::constants::ArcCore)) + { + xlnt::workbook_serializer workbook_serializer_(wb); + workbook_serializer_.read_properties_core(xlnt::xml_serializer::deserialize(archive.read(xlnt::constants::ArcCore))); + } + auto workbook_relationships = xlnt::relationship_serializer::read_relationships(archive, xlnt::constants::ArcWorkbook); @@ -72,14 +83,17 @@ bool load_workbook(xlnt::zip_file &archive, bool guess_types, bool data_only, xl ? xlnt::calendar::mac_1904 : xlnt::calendar::windows_1900; - xlnt::shared_strings_serializer shared_strings_serializer_; - std::vector shared_strings; - shared_strings_serializer_.read_shared_strings( - xlnt::xml_serializer::deserialize(archive.read(xlnt::constants::ArcSharedString)), shared_strings); - - for (auto shared_string : shared_strings) + if(archive.has_file(xlnt::constants::ArcSharedString)) { - wb.add_shared_string(shared_string); + xlnt::shared_strings_serializer shared_strings_serializer_; + std::vector shared_strings; + shared_strings_serializer_.read_shared_strings( + xlnt::xml_serializer::deserialize(archive.read(xlnt::constants::ArcSharedString)), shared_strings); + + for (auto shared_string : shared_strings) + { + wb.add_shared_string(shared_string); + } } xlnt::style_serializer style_reader_(wb); @@ -91,8 +105,13 @@ bool load_workbook(xlnt::zip_file &archive, bool guess_types, bool data_only, xl { auto rel = wb.get_relationship(sheet_node.get_attribute("r:id")); auto ws = wb.create_sheet(sheet_node.get_attribute("name"), rel); - auto ws_filename = "xl/" + rel.get_target_uri(); + //TODO: this is really bad + auto ws_filename = (rel.get_target_uri().substr(0, 3) != "xl/" ? "xl/" : "") + rel.get_target_uri(); + + auto sheet_type = wb.get_manifest().get_override_type(ws_filename); + if(sheet_type != "application/vnd.openxmlformats-officedocument.spreadsheetml.worksheet+xml") continue; + xlnt::worksheet_serializer worksheet_serializer(ws); worksheet_serializer.read_worksheet(xlnt::xml_serializer::deserialize(archive.read(ws_filename))); } @@ -123,8 +142,13 @@ std::string excel_serializer::repair_central_directory(const std::string &origin bool excel_serializer::load_stream_workbook(std::istream &stream, bool guess_types, bool data_only) { - std::vector bytes((std::istream_iterator(stream)), std::istream_iterator()); - + std::vector bytes; + + while (stream.good()) + { + bytes.push_back(stream.get()); + } + return load_virtual_workbook(bytes, guess_types, data_only); } @@ -196,7 +220,7 @@ void excel_serializer::write_worksheets() workbook::index_from_ws_filename(relationship.get_target_uri()) == index) { worksheet_serializer serializer_(ws); - std::string ws_filename = "xl/" + relationship.get_target_uri(); + std::string ws_filename = (relationship.get_target_uri().substr(0, 3) != "xl/" ? "xl/" : "") + relationship.get_target_uri(); archive_.writestr(ws_filename, serializer_.write_worksheet().to_string()); break; } diff --git a/source/serialization/workbook_serializer.cpp b/source/serialization/workbook_serializer.cpp index 7deb0182..a86a5f15 100644 --- a/source/serialization/workbook_serializer.cpp +++ b/source/serialization/workbook_serializer.cpp @@ -59,47 +59,10 @@ workbook_serializer::workbook_serializer(workbook &wb) : workbook_(wb) { } -std::vector workbook_serializer::read_sheets() -{ - /* - std::string ns; - - for(auto child : doc.children()) - { - std::string name = child.name(); - - if(name.find(':') != std::string::npos) - { - auto colon_index = name.find(':'); - ns = name.substr(0, colon_index); - break; - } - } - - auto with_ns = [&](const std::string &base) { return ns.empty() ? base : ns + ":" + base; }; - - auto root_node = doc.get_child(with_ns("workbook")); - auto sheets_node = root_node.get_child(with_ns("sheets")); - */ - std::vector sheets; - /* - // store temp because pugixml iteration uses the internal char array multiple times - auto sheet_element_name = with_ns("sheet"); - - for(auto sheet_node : sheets_node.children(sheet_element_name)) - { - std::string id = sheet_node.attribute("r:id").as_string(); - std::string name = sheet_node.attribute("name").as_string(); - sheets.push_back(std::make_pair(id, name)); - } - */ - return sheets; -} - void workbook_serializer::read_properties_core(const xml_document &xml) { auto &props = workbook_.get_properties(); - auto root_node = xml.get_child("dc:coreProperties"); + auto root_node = xml.get_child("cp:coreProperties"); props.excel_base_date = calendar::windows_1900; @@ -123,45 +86,6 @@ void workbook_serializer::read_properties_core(const xml_document &xml) } } -/// -/// Return a list of worksheets. -/// content types has a list of paths but no titles -/// workbook has a list of titles and relIds but no paths -/// workbook_rels has a list of relIds and paths but no titles -/// -std::vector workbook_serializer::detect_worksheets() -{ - static const std::string ValidWorksheet = - "application/vnd.openxmlformats-officedocument.spreadsheetml.worksheet+xml"; - - std::vector valid_sheets; - - for (const auto &content_type : workbook_.get_manifest().get_override_types()) - { - if (content_type.get_content_type() == ValidWorksheet) - { - valid_sheets.push_back(content_type.get_part_name()); - } - } - - auto &workbook_relationships = workbook_.get_relationships(); - std::vector> result; - - for (const auto &ws : read_sheets()) - { - auto rel = *std::find_if(workbook_relationships.begin(), workbook_relationships.end(), - [&](const relationship &r) { return r.get_id() == ws.first; }); - auto target = rel.get_target_uri(); - - if (std::find(valid_sheets.begin(), valid_sheets.end(), "/" + target) != valid_sheets.end()) - { - result.push_back({ target, ws.second }); - } - } - - return result; -} - xml_document workbook_serializer::write_properties_core() const { auto &props = workbook_.get_properties(); diff --git a/source/serialization/worksheet_serializer.cpp b/source/serialization/worksheet_serializer.cpp index bbd0bf43..2d259c91 100644 --- a/source/serialization/worksheet_serializer.cpp +++ b/source/serialization/worksheet_serializer.cpp @@ -189,8 +189,8 @@ bool worksheet_serializer::read_worksheet(const xml_document &xml) auto min = static_cast(std::stoull(col_node.get_attribute("min"))); auto max = static_cast(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"; + auto column_style = col_node.has_attribute("style") ? std::stoull(col_node.get_attribute("style")) : 0; for (auto column = min; column <= max; column++) { @@ -217,8 +217,6 @@ bool worksheet_serializer::read_worksheet(const xml_document &xml) xml_document worksheet_serializer::write_worksheet() const { - sheet_.get_cell("A1"); - xml_document xml; auto root_node = xml.add_child("worksheet"); @@ -228,17 +226,17 @@ xml_document worksheet_serializer::write_worksheet() const auto sheet_pr_node = root_node.add_child("sheetPr"); + auto outline_pr_node = sheet_pr_node.add_child("outlinePr"); + + outline_pr_node.add_attribute("summaryBelow", "1"); + outline_pr_node.add_attribute("summaryRight", "1"); + if (!sheet_.get_page_setup().is_default()) { auto page_set_up_pr_node = sheet_pr_node.add_child("pageSetUpPr"); page_set_up_pr_node.add_attribute("fitToPage", sheet_.get_page_setup().fit_to_page() ? "1" : "0"); } - auto outline_pr_node = sheet_pr_node.add_child("outlinePr"); - - outline_pr_node.add_attribute("summaryBelow", "1"); - outline_pr_node.add_attribute("summaryRight", "1"); - auto dimension_node = root_node.add_child("dimension"); dimension_node.add_attribute("ref", sheet_.calculate_dimension().to_string()); @@ -529,13 +527,35 @@ xml_document worksheet_serializer::write_worksheet() const } auto page_margins_node = root_node.add_child("pageMargins"); + + //TODO: there must be a better way to do this + auto remove_trailing_zeros = [](const std::string &n) + { + auto decimal = n.find('.'); + + if (decimal == std::string::npos) return n; + + auto index = n.size() - 1; + + while (index >= decimal && n[index] == '0') + { + index--; + } + + if(index == decimal) + { + return n.substr(0, decimal); + } + + return n.substr(0, index + 1); + }; - 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())); + page_margins_node.add_attribute("left", remove_trailing_zeros(std::to_string(sheet_.get_page_margins().get_left()))); + page_margins_node.add_attribute("right", remove_trailing_zeros(std::to_string(sheet_.get_page_margins().get_right()))); + page_margins_node.add_attribute("top", remove_trailing_zeros(std::to_string(sheet_.get_page_margins().get_top()))); + page_margins_node.add_attribute("bottom", remove_trailing_zeros(std::to_string(sheet_.get_page_margins().get_bottom()))); + page_margins_node.add_attribute("header", remove_trailing_zeros(std::to_string(sheet_.get_page_margins().get_header()))); + page_margins_node.add_attribute("footer", remove_trailing_zeros(std::to_string(sheet_.get_page_margins().get_footer()))); if (!sheet_.get_page_setup().is_default()) { diff --git a/source/workbook/manifest.cpp b/source/workbook/manifest.cpp index 1209ef1e..6d932315 100644 --- a/source/workbook/manifest.cpp +++ b/source/workbook/manifest.cpp @@ -85,11 +85,13 @@ bool manifest::has_override_type(const std::string &part_name) const void manifest::add_default_type(const std::string &extension, const std::string &content_type) { + if(has_default_type(extension)) return; default_types_.push_back(default_type(extension, content_type)); } void manifest::add_override_type(const std::string &part_name, const std::string &content_type) { + if(has_override_type(part_name)) return; override_types_.push_back(override_type(part_name, content_type)); } diff --git a/source/workbook/workbook.cpp b/source/workbook/workbook.cpp index 63116a39..40e20f6f 100644 --- a/source/workbook/workbook.cpp +++ b/source/workbook/workbook.cpp @@ -42,9 +42,20 @@ workbook_impl::workbook_impl() workbook::workbook() : d_(new detail::workbook_impl()) { create_sheet("Sheet"); + create_relationship("rId2", "sharedStrings.xml", relationship::type::shared_strings); create_relationship("rId3", "styles.xml", relationship::type::styles); create_relationship("rId4", "theme/theme1.xml", relationship::type::theme); + + d_->manifest_.add_default_type("rels", "application/vnd.openxmlformats-package.relationships+xml"); + d_->manifest_.add_default_type("xml", "application/xml"); + + d_->manifest_.add_override_type("/xl/workbook.xml", "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet.main+xml"); + d_->manifest_.add_override_type("/xl/theme/theme1.xml", "application/vnd.openxmlformats-officedocument.theme+xml"); + d_->manifest_.add_override_type("/xl/styles.xml", "application/vnd.openxmlformats-officedocument.spreadsheetml.styles+xml"); + d_->manifest_.add_override_type("/xl/sharedStrings.xml", "application/vnd.openxmlformats-officedocument.spreadsheetml.sharedStrings+xml"); + d_->manifest_.add_override_type("/docProps/core.xml", "application/vnd.openxmlformats-package.core-properties+xml"); + d_->manifest_.add_override_type("/docProps/app.xml", "application/vnd.openxmlformats-officedocument.extended-properties+xml"); } workbook::iterator::iterator(workbook &wb, std::size_t index) : wb_(wb), index_(index) @@ -158,11 +169,15 @@ worksheet workbook::create_sheet() { title = "Sheet" + std::to_string(++index); } + + std::string sheet_filename = "worksheets/sheet" + std::to_string(d_->worksheets_.size() + 1) + ".xml"; d_->worksheets_.push_back(detail::worksheet_impl(this, title)); create_relationship("rId" + std::to_string(d_->relationships_.size() + 1), - "xl/worksheets/sheet" + std::to_string(d_->worksheets_.size()) + ".xml", + sheet_filename, relationship::type::worksheet); + + d_->manifest_.add_override_type("/xl/" + sheet_filename, "application/vnd.openxmlformats-officedocument.spreadsheetml.worksheet+xml"); return worksheet(&d_->worksheets_.back()); } @@ -300,7 +315,7 @@ void workbook::remove_sheet(worksheet ws) throw std::runtime_error("worksheet not owned by this workbook"); } - auto sheet_filename = "xl/worksheets/sheet" + std::to_string(d_->worksheets_.size()) + ".xml"; + auto sheet_filename = "worksheets/sheet" + std::to_string(d_->worksheets_.size()) + ".xml"; auto rel_iter = std::find_if(d_->relationships_.begin(), d_->relationships_.end(), [=](relationship &r) { return r.get_target_uri() == sheet_filename; }); @@ -558,6 +573,11 @@ void workbook::add_font(const font &font_) void workbook::add_number_format(const number_format &number_format_) { d_->number_formats_.push_back(number_format_); + + if(number_format_.get_id() == -1) + { + d_->number_formats_.back().set_id(d_->next_custom_format_id_++); + } } void workbook::set_code_name(const std::string & /*code_name*/) @@ -867,6 +887,12 @@ const std::vector &workbook::get_shared_strings() const void workbook::add_shared_string(const std::string &shared) { + //TODO: inefficient, use a set or something? + for(auto &s : d_->shared_strings_) + { + if(s == shared) return; + } + d_->shared_strings_.push_back(shared); } diff --git a/tests/data/writer/expected/sheet1.xml b/tests/data/writer/expected/sheet1.xml index d1364307..fee251a7 100644 --- a/tests/data/writer/expected/sheet1.xml +++ b/tests/data/writer/expected/sheet1.xml @@ -3,7 +3,7 @@ - + diff --git a/tests/data/writer/expected/sheet1_auto_filter.xml b/tests/data/writer/expected/sheet1_auto_filter.xml index 84b14444..9567e6b1 100644 --- a/tests/data/writer/expected/sheet1_auto_filter.xml +++ b/tests/data/writer/expected/sheet1_auto_filter.xml @@ -3,7 +3,7 @@ - + diff --git a/tests/data/writer/expected/sheet1_bool.xml b/tests/data/writer/expected/sheet1_bool.xml index 88e483a2..abb97fca 100644 --- a/tests/data/writer/expected/sheet1_bool.xml +++ b/tests/data/writer/expected/sheet1_bool.xml @@ -3,7 +3,7 @@ - + diff --git a/tests/data/writer/expected/sheet1_formula.xml b/tests/data/writer/expected/sheet1_formula.xml index 6fe9f9b4..5ae93c09 100644 --- a/tests/data/writer/expected/sheet1_formula.xml +++ b/tests/data/writer/expected/sheet1_formula.xml @@ -3,7 +3,7 @@ - + diff --git a/tests/data/writer/expected/sheet1_freeze_panes_both.xml b/tests/data/writer/expected/sheet1_freeze_panes_both.xml index 82890580..9adb1468 100644 --- a/tests/data/writer/expected/sheet1_freeze_panes_both.xml +++ b/tests/data/writer/expected/sheet1_freeze_panes_both.xml @@ -3,7 +3,7 @@ - + diff --git a/tests/data/writer/expected/sheet1_freeze_panes_horiz.xml b/tests/data/writer/expected/sheet1_freeze_panes_horiz.xml index c7c09c40..55569e7a 100644 --- a/tests/data/writer/expected/sheet1_freeze_panes_horiz.xml +++ b/tests/data/writer/expected/sheet1_freeze_panes_horiz.xml @@ -3,7 +3,7 @@ - + diff --git a/tests/data/writer/expected/sheet1_freeze_panes_vert.xml b/tests/data/writer/expected/sheet1_freeze_panes_vert.xml index cdd57dd0..5fad8fb9 100644 --- a/tests/data/writer/expected/sheet1_freeze_panes_vert.xml +++ b/tests/data/writer/expected/sheet1_freeze_panes_vert.xml @@ -3,7 +3,7 @@ - + diff --git a/tests/data/writer/expected/sheet1_height.xml b/tests/data/writer/expected/sheet1_height.xml index 64fc8929..8b1732a6 100644 --- a/tests/data/writer/expected/sheet1_height.xml +++ b/tests/data/writer/expected/sheet1_height.xml @@ -3,7 +3,7 @@ - + diff --git a/tests/test_props.hpp b/tests/test_props.hpp index af35fd24..e6f13590 100644 --- a/tests/test_props.hpp +++ b/tests/test_props.hpp @@ -14,12 +14,9 @@ class test_props : public CxxTest::TestSuite public: void test_read_properties_core() { - xlnt::zip_file archive(PathHelper::GetDataDirectory() + "/genuine/empty.xlsx"); - auto content = archive.read("docProps/core.xml"); + auto path = PathHelper::GetDataDirectory() + "/genuine/empty.xlsx"; xlnt::workbook wb; - xlnt::workbook_serializer serializer(wb); - xlnt::xml_document xml; - serializer.read_properties_core(xml); + wb.load(path); auto &prop = wb.get_properties(); TS_ASSERT_EQUALS(prop.creator, "*.*"); TS_ASSERT_EQUALS(prop.last_modified_by, "Charlie Clark"); @@ -29,19 +26,18 @@ public: void test_read_sheets_titles() { - xlnt::zip_file archive(PathHelper::GetDataDirectory() + "/genuine/empty.xlsx"); - auto content = archive.read("docProps/core.xml"); + auto path = PathHelper::GetDataDirectory() + "/genuine/empty.xlsx"; const std::vector expected_titles = {"Sheet1 - Text", "Sheet2 - Numbers", "Sheet3 - Formulas", "Sheet4 - Dates"}; std::size_t i = 0; xlnt::workbook wb; - xlnt::workbook_serializer serializer(wb); + wb.load(path); - for(auto sheet : serializer.read_sheets()) + for(auto sheet : wb) { - TS_ASSERT_EQUALS(sheet.second, expected_titles.at(i++)); + TS_ASSERT_EQUALS(sheet.get_title(), expected_titles.at(i++)); } } @@ -59,19 +55,18 @@ public: void test_read_sheets_titles_libre() { - xlnt::zip_file archive(PathHelper::GetDataDirectory() + "/genuine/empty_libre.xlsx"); - auto content = archive.read("docProps/core.xml"); + auto path = PathHelper::GetDataDirectory() + "/genuine/empty_libre.xlsx"; const std::vector expected_titles = {"Sheet1 - Text", "Sheet2 - Numbers", "Sheet3 - Formulas", "Sheet4 - Dates"}; std::size_t i = 0; xlnt::workbook wb; - xlnt::workbook_serializer serializer(wb); + wb.load(path); - for(auto sheet : serializer.read_sheets()) + for(auto sheet : wb) { - TS_ASSERT_EQUALS(sheet.second, expected_titles.at(i++)); + TS_ASSERT_EQUALS(sheet.get_title(), expected_titles.at(i++)); } } @@ -83,8 +78,6 @@ public: prop.last_modified_by = "SOMEBODY"; prop.created = xlnt::datetime(2010, 4, 1, 20, 30, 00); prop.modified = xlnt::datetime(2010, 4, 5, 14, 5, 30); - TS_FAIL(""); - return; xlnt::workbook_serializer serializer(wb); xlnt::xml_document xml = serializer.write_properties_core(); TS_ASSERT(Helper::compare_xml(PathHelper::GetDataDirectory() + "/writer/expected/core.xml", xml)); @@ -97,8 +90,6 @@ public: wb.create_sheet(); xlnt::workbook_serializer serializer(wb); xlnt::xml_document xml = serializer.write_properties_app(); - TS_FAIL(""); - return; TS_ASSERT(Helper::compare_xml(PathHelper::GetDataDirectory() + "/writer/expected/app.xml", xml)); } }; diff --git a/tests/test_read.hpp b/tests/test_read.hpp index 54ab0748..6b083e85 100644 --- a/tests/test_read.hpp +++ b/tests/test_read.hpp @@ -326,65 +326,17 @@ public: TS_ASSERT(ws.get_cell("A5").get_value() == 49380); TS_ASSERT(!ws.get_cell("A5").has_formula()); } - - void test_detect_worksheets() - { - { - auto path = PathHelper::GetDataDirectory("/reader/bug137.xlsx"); - xlnt::zip_file archive(path); - - std::vector> expected = - { - {"xl/worksheets/sheet1.xml", "Sheet1"} - }; - - xlnt::workbook wb; - xlnt::workbook_serializer serializer(wb); - TS_ASSERT_EQUALS(serializer.detect_worksheets(), expected); - } - { - auto path = PathHelper::GetDataDirectory("/reader/contains_chartsheets.xlsx"); - xlnt::zip_file archive(path); - - std::vector> expected = - { - {"xl/worksheets/sheet1.xml", "data"}, - {"xl/worksheets/sheet2.xml", "moredata"} - }; - - xlnt::workbook wb; - xlnt::workbook_serializer serializer(wb); - TS_ASSERT_EQUALS(serializer.detect_worksheets(), expected); - } - - { - auto path = PathHelper::GetDataDirectory("/reader/bug304.xlsx"); - xlnt::zip_file archive(path); - - std::vector> expected = - { - {"xl/worksheets/sheet3.xml", "Sheet1"}, - {"xl/worksheets/sheet2.xml", "Sheet2"}, - {"xl/worksheets/sheet.xml", "Sheet3"} - }; - - xlnt::workbook wb; - xlnt::workbook_serializer serializer(wb); - TS_ASSERT_EQUALS(serializer.detect_worksheets(), expected); - } - } - void test_read_rels() { { std::vector expected = { - {xlnt::relationship::type::theme, "rId3", "xl/theme/theme1.xml"}, - {xlnt::relationship::type::worksheet, "rId2", "xl/worksheets/sheet1.xml"}, - {xlnt::relationship::type::chartsheet, "rId1", "xl/chartsheets/sheet1.xml"}, - {xlnt::relationship::type::shared_strings, "rId5", "xl/sharedStrings.xml"}, - {xlnt::relationship::type::styles, "rId4", "xl/styles.xml"} + {xlnt::relationship::type::theme, "rId3", "theme/theme1.xml"}, + {xlnt::relationship::type::worksheet, "rId2", "worksheets/sheet1.xml"}, + {xlnt::relationship::type::chartsheet, "rId1", "chartsheets/sheet1.xml"}, + {xlnt::relationship::type::shared_strings, "rId5", "sharedStrings.xml"}, + {xlnt::relationship::type::styles, "rId4", "styles.xml"} }; auto path = PathHelper::GetDataDirectory("/reader/bug137.xlsx"); @@ -397,13 +349,13 @@ public: std::vector expected = { {xlnt::relationship::type::custom_xml, "rId8", "../customXml/item3.xml"}, - {xlnt::relationship::type::worksheet, "rId3", "xl/worksheets/sheet.xml"}, + {xlnt::relationship::type::worksheet, "rId3", "/xl/worksheets/sheet.xml"}, {xlnt::relationship::type::custom_xml, "rId7", "../customXml/item2.xml"}, - {xlnt::relationship::type::worksheet, "rId2", "xl/worksheets/sheet2.xml"}, - {xlnt::relationship::type::worksheet, "rId1", "xl/worksheets/sheet3.xml"}, + {xlnt::relationship::type::worksheet, "rId2", "/xl/worksheets/sheet2.xml"}, + {xlnt::relationship::type::worksheet, "rId1", "/xl/worksheets/sheet3.xml"}, {xlnt::relationship::type::custom_xml, "rId6", "../customXml/item1.xml"}, - {xlnt::relationship::type::styles, "rId5", "xl/styles.xml"}, - {xlnt::relationship::type::theme, "rId4", "xl/theme/theme.xml"} + {xlnt::relationship::type::styles, "rId5", "/xl/styles.xml"}, + {xlnt::relationship::type::theme, "rId4", "/xl/theme/theme.xml"} }; auto path = PathHelper::GetDataDirectory("/reader/bug304.xlsx"); @@ -436,12 +388,7 @@ public: auto path = PathHelper::GetDataDirectory("/reader/contains_chartsheets.xlsx"); xlnt::workbook wb; - xlnt::manifest_serializer serializer(wb.get_manifest()); - - xlnt::zip_file archive; - archive.load(path); - - serializer.read_manifest(xlnt::xml_serializer::deserialize(archive.read("[Content Types].xml"))); + wb.load(path); auto &result = wb.get_manifest().get_override_types(); @@ -453,35 +400,8 @@ public: for(std::size_t i = 0; i < expected.size(); i++) { - TS_ASSERT_EQUALS(result[i].get_part_name(), expected[i].first); - TS_ASSERT_EQUALS(result[i].get_content_type(), expected[i].second); - } - } - - void test_read_sheets() - { - { - auto path = PathHelper::GetDataDirectory("/reader/bug137.xlsx"); - - xlnt::workbook wb; - xlnt::workbook_serializer serializer(wb); - - auto sheets = serializer.read_sheets(); - std::vector> expected = - {{"rId1", "Chart1"}, {"rId2", "Sheet1"}}; - TS_ASSERT_EQUALS(sheets, expected); - } - - { - auto path = PathHelper::GetDataDirectory("/reader/bug304.xlsx"); - - xlnt::workbook wb; - xlnt::workbook_serializer serializer(wb); - - auto sheets = serializer.read_sheets(); - std::vector> expected = - {{"rId1", "Sheet1"}, {"rId2", "Sheet2"}, {"rId3", "Sheet3"}}; - TS_ASSERT_EQUALS(sheets, expected); + TS_ASSERT(wb.get_manifest().has_override_type(expected[i].first)); + TS_ASSERT_EQUALS(wb.get_manifest().get_override_type(expected[i].first), expected[i].second); } } diff --git a/tests/test_style_writer.hpp b/tests/test_style_writer.hpp index 5de61e99..fdece5ad 100644 --- a/tests/test_style_writer.hpp +++ b/tests/test_style_writer.hpp @@ -16,11 +16,9 @@ public: xlnt::xml_document observed; writer.write_number_formats(observed.add_child("numFmts")); std::string expected = - "" " " " " - " " - ""; + " "; auto diff = Helper::compare_xml(expected, observed); TS_ASSERT(diff); } diff --git a/tests/test_worksheet.hpp b/tests/test_worksheet.hpp index 230a90c6..db268384 100644 --- a/tests/test_worksheet.hpp +++ b/tests/test_worksheet.hpp @@ -643,7 +643,7 @@ public: xlnt::worksheet_serializer serializer(ws); auto observed = serializer.write_worksheet(); - auto expected_string = + auto expected_string = "" " " " " @@ -703,8 +703,8 @@ public: void test_merge() { - xlnt::worksheet ws(wb_); - std::vector string_table = {"Cell A1", "Cell B1"}; + xlnt::workbook clean_wb; // for shared strings + xlnt::worksheet ws(clean_wb); auto expected_string1 = "" @@ -775,7 +775,7 @@ public: { xlnt::worksheet_serializer serializer(ws); auto observed = serializer.write_worksheet(); - + xlnt::xml_document expected; expected.from_string(expected_string2); @@ -855,7 +855,7 @@ public: xlnt::xml_document expected; expected.from_string(expected_string); - + TS_ASSERT(Helper::compare_xml(expected, observed)); } @@ -904,13 +904,13 @@ public: " " ""; - xlnt::xml_document expected; - expected.from_string(expected_xml_string); - { xlnt::worksheet_serializer serializer(ws); auto observed = serializer.write_worksheet(); + xlnt::xml_document expected; + expected.from_string(expected_xml_string); + TS_ASSERT(Helper::compare_xml(expected, observed)); } @@ -936,6 +936,9 @@ public: xlnt::worksheet_serializer serializer(ws); auto observed = serializer.write_worksheet(); + xlnt::xml_document expected; + expected.from_string(expected_xml_string); + TS_ASSERT(Helper::compare_xml(expected, observed)); } } diff --git a/tests/test_write.hpp b/tests/test_write.hpp index 4fd940ed..f07451de 100644 --- a/tests/test_write.hpp +++ b/tests/test_write.hpp @@ -138,7 +138,9 @@ public: void test_write_hyperlink() { - auto ws = wb_.create_sheet(); + xlnt::workbook clean_wb; + auto ws = clean_wb.get_active_sheet(); + ws.get_cell("A1").set_value("test"); ws.get_cell("A1").set_hyperlink("http://test.com"); diff --git a/tests/test_write_workbook.hpp b/tests/test_write_workbook.hpp index 78949f9b..65bb5210 100644 --- a/tests/test_write_workbook.hpp +++ b/tests/test_write_workbook.hpp @@ -98,7 +98,7 @@ public: xlnt::zip_file archive; xlnt::relationship_serializer::write_relationships(wb.get_relationships(), "xl/workbook.xml", archive); xlnt::xml_document observed; - observed.from_string(archive.read("xl/workbook/_rels/workbook.xml.rels")); + observed.from_string(archive.read("xl/_rels/workbook.xml.rels")); auto filename = "workbook.xml.rels"; auto diff = Helper::compare_xml(PathHelper::read_file(filename), observed); TS_ASSERT(!diff);