From 65962951f175e642f9dfb7eb88dc2b690735cc48 Mon Sep 17 00:00:00 2001 From: Thomas Fussell Date: Fri, 13 Jun 2014 17:06:23 -0400 Subject: [PATCH] start making reader/writer actually use package structure --- include/xlnt/cell/cell_value.h | 98 ++++++++++++++++++++++++ include/xlnt/common/datetime.hpp | 6 ++ include/xlnt/common/zip_file.hpp | 4 +- include/xlnt/reader/reader.hpp | 6 +- include/xlnt/workbook/workbook.hpp | 3 + include/xlnt/writer/writer.hpp | 5 ++ include/xlnt/xlnt.hpp | 2 + source/document_properties.cpp | 10 +++ source/reader.cpp | 27 +++++++ source/workbook.cpp | 70 ++++++++++++------ source/writer.cpp | 28 +++++-- source/zip_file.cpp | 4 +- tests/runner-autogen.cpp | 14 ++-- tests/test_props.hpp | 115 +++++++++++++---------------- tests/test_read.hpp | 2 +- 15 files changed, 289 insertions(+), 105 deletions(-) create mode 100644 include/xlnt/cell/cell_value.h create mode 100644 source/document_properties.cpp diff --git a/include/xlnt/cell/cell_value.h b/include/xlnt/cell/cell_value.h new file mode 100644 index 00000000..6bd4a9c9 --- /dev/null +++ b/include/xlnt/cell/cell_value.h @@ -0,0 +1,98 @@ +// Copyright (c) 2014 Thomas Fussell +// Copyright (c) 2010-2014 openpyxl +// +// 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 +#include +#include + +#include "../styles/style.hpp" +#include "../common/types.hpp" + +namespace xlnt { + +struct date; +struct datetime; +struct time; + +class cell_value +{ +public: + enum class type + { + null, + numeric, + string, + formula, + boolean, + error + }; + + std::string to_string() const; + + type get_data_type() const; + + void set_null(); + + cell_value &operator=(const cell_value &rhs); + cell_value &operator=(bool value); + cell_value &operator=(int value); + cell_value &operator=(double value); + cell_value &operator=(long int value); + cell_value &operator=(long long value); + cell_value &operator=(long double value); + cell_value &operator=(const std::string &value); + cell_value &operator=(const char *value); + cell_value &operator=(const date &value); + cell_value &operator=(const time &value); + cell_value &operator=(const datetime &value); + + bool operator==(const cell_value &comparand) const; + bool operator==(std::nullptr_t) const; + bool operator==(bool comparand) const; + bool operator==(int comparand) const; + bool operator==(double comparand) const; + bool operator==(const std::string &comparand) const; + bool operator==(const char *comparand) const; + bool operator==(const date &comparand) const; + bool operator==(const time &comparand) const; + bool operator==(const datetime &comparand) const; + + friend bool operator==(std::nullptr_t, const cell_value &cell); + friend bool operator==(bool comparand, const cell_value &cell); + friend bool operator==(int comparand, const cell_value &cell); + friend bool operator==(double comparand, const cell_value &cell); + friend bool operator==(const std::string &comparand, const cell_value &cell); + friend bool operator==(const char *comparand, const cell_value &cell); + friend bool operator==(const date &comparand, const cell_value &cell); + friend bool operator==(const time &comparand, const cell_value &cell); + friend bool operator==(const datetime &comparand, const cell_value &cell); +}; + +inline std::ostream &operator<<(std::ostream &stream, const xlnt::cell_value &value) +{ + return stream << value.to_string(); +} + +} // namespace xlnt diff --git a/include/xlnt/common/datetime.hpp b/include/xlnt/common/datetime.hpp index 41b0943c..3ba22690 100644 --- a/include/xlnt/common/datetime.hpp +++ b/include/xlnt/common/datetime.hpp @@ -26,6 +26,12 @@ namespace xlnt { +enum calendar +{ + windows_1900, + mac_1904 +}; + struct date { static date today(); diff --git a/include/xlnt/common/zip_file.hpp b/include/xlnt/common/zip_file.hpp index 60fb8b8f..14d54e27 100644 --- a/include/xlnt/common/zip_file.hpp +++ b/include/xlnt/common/zip_file.hpp @@ -95,8 +95,8 @@ public: zip_file(const std::string &filename, file_mode mode, file_access access = file_access::read); ~zip_file(); - - std::string get_file_contents(const std::string &filename); + + std::string get_file_contents(const std::string &filename) const; void set_file_contents(const std::string &filename, const std::string &contents); diff --git a/include/xlnt/reader/reader.hpp b/include/xlnt/reader/reader.hpp index fb287307..3f9e0cde 100644 --- a/include/xlnt/reader/reader.hpp +++ b/include/xlnt/reader/reader.hpp @@ -32,7 +32,9 @@ namespace xlnt { class workbook; class worksheet; - +class document_properties; +class zip_file; + class reader { public: @@ -44,6 +46,8 @@ public: static void read_worksheet(worksheet ws, const std::string &xml_string, const std::vector &string_table); static std::vector read_shared_string(const std::string &xml_string); static std::string read_dimension(const std::string &xml_string); + static document_properties read_properties_core(const std::string &xml_string); + static std::vector> read_sheets(const zip_file &archive); }; } // namespace xlnt diff --git a/include/xlnt/workbook/workbook.hpp b/include/xlnt/workbook/workbook.hpp index 91987eb8..3003359d 100644 --- a/include/xlnt/workbook/workbook.hpp +++ b/include/xlnt/workbook/workbook.hpp @@ -62,6 +62,9 @@ public: workbook(const workbook &) = delete; void read_workbook_settings(const std::string &xml_source); + + void create_relationship(const std::string &id, const std::string &target, const std::string &type); + relationship get_relationship(const std::string &id) const; //getters worksheet get_active_sheet(); diff --git a/include/xlnt/writer/writer.hpp b/include/xlnt/writer/writer.hpp index bcd5ee8d..d82f9822 100644 --- a/include/xlnt/writer/writer.hpp +++ b/include/xlnt/writer/writer.hpp @@ -24,12 +24,15 @@ #pragma once #include +#include +#include #include namespace xlnt { class workbook; class worksheet; +class document_properties; class writer { @@ -44,6 +47,8 @@ public: static std::string write_workbook_rels(const workbook &wb); static std::string write_worksheet_rels(worksheet ws, int drawing_id, int comments_id); static std::string write_string_table(const std::vector &string_table); + static std::string write_properties_core(const document_properties &prop); + static std::string write_properties_app(const workbook &wb); }; } // namespace xlnt diff --git a/include/xlnt/xlnt.hpp b/include/xlnt/xlnt.hpp index 406dea10..ed368d75 100644 --- a/include/xlnt/xlnt.hpp +++ b/include/xlnt/xlnt.hpp @@ -44,3 +44,5 @@ const std::string download_url = "https://github.com/tfussell/xlnt/archive/maste #include "common/exceptions.hpp" #include "reader/reader.hpp" #include "common/string_table.hpp" +#include "common/zip_file.hpp" +#include "workbook/document_properties.hpp" diff --git a/source/document_properties.cpp b/source/document_properties.cpp new file mode 100644 index 00000000..b47d378d --- /dev/null +++ b/source/document_properties.cpp @@ -0,0 +1,10 @@ +#include "workbook/document_properties.hpp" + +namespace xlnt { + +document_properties::document_properties() : created(1900, 1, 1), modified(1900, 1, 1) +{ + +} + +} // namespace xlnt \ No newline at end of file diff --git a/source/reader.cpp b/source/reader.cpp index f642cceb..4240d2c9 100644 --- a/source/reader.cpp +++ b/source/reader.cpp @@ -7,9 +7,36 @@ #include "worksheet/range_reference.hpp" #include "workbook/workbook.hpp" #include "worksheet/worksheet.hpp" +#include "workbook/document_properties.hpp" +#include "common/zip_file.hpp" namespace xlnt { +std::vector> reader::read_sheets(const zip_file &archive) +{ + auto xml_source = archive.get_file_contents("xl/workbook.xml"); + pugi::xml_document doc; + doc.load(xml_source.c_str()); + std::vector> sheets; + for(auto sheet_node : doc.child("workbook").child("sheets").children("sheet")) + { + 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; +} + +document_properties reader::read_properties_core(const std::string &xml_string) +{ + document_properties props; + pugi::xml_document doc; + doc.load(xml_string.c_str()); + auto root_node = doc.child("cp:coreProperties"); + props.creator = root_node.child("dc:creator").text().as_string(); + return props; +} + std::string reader::read_dimension(const std::string &xml_string) { pugi::xml_document doc; diff --git a/source/workbook.cpp b/source/workbook.cpp index c8cb603a..e5d2157c 100644 --- a/source/workbook.cpp +++ b/source/workbook.cpp @@ -313,6 +313,11 @@ bool workbook::load(const std::string &filename) } auto workbook_relationships = reader::read_relationships(f.get_file_contents("xl/_rels/workbook.xml.rels")); + + for(auto relationship : workbook_relationships) + { + create_relationship(relationship.first, relationship.second.first, relationship.second.second); + } pugi::xml_document doc; doc.load(f.get_file_contents("xl/workbook.xml").c_str()); @@ -334,15 +339,33 @@ bool workbook::load(const std::string &filename) for(auto sheet_node : sheets_node.children("sheet")) { - auto relation_id = sheet_node.attribute("r:id").as_string(); + std::string relation_id = sheet_node.attribute("r:id").as_string(); auto ws = create_sheet(sheet_node.attribute("name").as_string()); std::string sheet_filename("xl/"); - sheet_filename += workbook_relationships[relation_id].first; + sheet_filename += get_relationship(relation_id).get_target_uri(); xlnt::reader::read_worksheet(ws, f.get_file_contents(sheet_filename).c_str(), shared_strings); } return true; } + +void workbook::create_relationship(const std::string &id, const std::string &target, const std::string &type) +{ + d_->relationships_.push_back(relationship(type, id, target)); +} + +relationship workbook::get_relationship(const std::string &id) const +{ + for(auto &rel : d_->relationships_) + { + if(rel.get_id() == id) + { + return rel; + } + } + + throw std::runtime_error(""); +} int workbook::get_base_year() const { @@ -497,11 +520,17 @@ bool workbook::save(const std::string &filename) {"/xl/styles.xml", "application/vnd.openxmlformats-officedocument.spreadsheetml.styles+xml"}, {"/xl/workbook.xml", "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet.main+xml"}, {"/docProps/app.xml", "application/vnd.openxmlformats-officedocument.extended-properties+xml"}, - {"/xl/worksheets/sheet1.xml", "application/vnd.openxmlformats-officedocument.spreadsheetml.worksheet+xml"}, {"/docProps/core.xml", "application/vnd.openxmlformats-package.core-properties+xml"}, {"/xl/theme/theme1.xml", "application/vnd.openxmlformats-officedocument.theme+xml"} } }; + + int ws_index = 1; + for(auto ws : *this) + { + auto sheet_filename = "/xl/worksheets/sheet" + std::to_string(ws_index++) + ".xml"; + content_types.second[sheet_filename] = "application/vnd.openxmlformats-officedocument.spreadsheetml.worksheet+xml"; + } f.set_file_contents("[Content_Types].xml", writer::write_content_types(content_types)); @@ -511,38 +540,35 @@ bool workbook::save(const std::string &filename) {"rId2", {"docProps/core.xml", "http://schemas.openxmlformats.org/package/2006/relationships/metadata/core-properties"}}, {"rId1", {"xl/workbook.xml", "http://schemas.openxmlformats.org/officeDocument/2006/relationships/officeDocument"}} }; + f.set_file_contents("_rels/.rels", writer::write_relationships(root_rels)); std::vector>> workbook_rels = { - {"rId1", {"worksheets/sheet1.xml", "http://schemas.openxmlformats.org/officeDocument/2006/relationships/worksheet"}}, + {"rId1", {"sharedStrings.xml", "http://schemas.openxmlformats.org/officeDocument/2006/relationships/sharedStrings"}}, {"rId2", {"styles.xml", "http://schemas.openxmlformats.org/officeDocument/2006/relationships/styles"}}, {"rId3", {"theme/theme1.xml", "http://schemas.openxmlformats.org/officeDocument/2006/relationships/theme"}} }; - f.set_file_contents("xl/_rels/workbook.xml.rels", writer::write_relationships(workbook_rels)); - - pugi::xml_document doc; - auto root_node = doc.append_child("workbook"); - root_node.append_attribute("xmlns").set_value("http://schemas.openxmlformats.org/spreadsheetml/2006/main"); - root_node.append_attribute("xmlns:r").set_value("http://schemas.openxmlformats.org/officeDocument/2006/relationships"); - auto sheets_node = root_node.append_child("sheets"); - - int i = 0; + + ws_index = 2; + for(auto ws : *this) + { + auto sheet_filename = "worksheets/sheet" + std::to_string(ws_index++) + ".xml"; + workbook_rels.push_back({"rId" + std::to_string(ws_index + 1), {sheet_filename, "http://schemas.openxmlformats.org/officeDocument/2006/relationships/worksheet"}}); + } + + f.set_file_contents("xl/_rels/workbook.xml.rels", writer::write_relationships(workbook_rels)); + + int i = 0; + for(auto ws : *this) { - auto sheet_node = sheets_node.append_child("sheet"); - sheet_node.append_attribute("name").set_value(ws.get_title().c_str()); - sheet_node.append_attribute("sheetId").set_value(std::to_string(i + 1).c_str()); - sheet_node.append_attribute("r:id").set_value((std::string("rId") + std::to_string(i + 1)).c_str()); std::string filename = "xl/worksheets/sheet"; f.set_file_contents(filename + std::to_string(i + 1) + ".xml", xlnt::writer::write_worksheet(ws)); i++; } - - std::stringstream ss; - doc.save(ss); - - f.set_file_contents("xl/workbook.xml", ss.str()); + + f.set_file_contents("xl/workbook.xml", writer::write_workbook(*this)); return true; } diff --git a/source/writer.cpp b/source/writer.cpp index 6b6bbc94..204bd108 100644 --- a/source/writer.cpp +++ b/source/writer.cpp @@ -35,15 +35,31 @@ std::string writer::write_string_table(const std::vector &string_ta return ss.str(); } -std::string writer::write_workbook_rels(const workbook &/*wb*/) +std::string writer::write_properties_core(const document_properties &/*prop*/) { - static const std::vector>> rels = + return ""; +} + +std::string writer::write_properties_app(const workbook &/*wb*/) +{ + return ""; +} + +std::string writer::write_workbook_rels(const workbook &wb) +{ + std::vector>> rels = { - {"rId1", {"worksheets/sheet1.xml", "http://schemas.openxmlformats.org/officeDocument/2006/relationships/worksheet"}}, - {"rId2", {"sharedStrings.xml", "http://schemas.openxmlformats.org/officeDocument/2006/relationships/sharedStrings"}}, - {"rId3", {"styles.xml", "http://schemas.openxmlformats.org/officeDocument/2006/relationships/styles"}}, - {"rId4", {"theme/theme1.xml", "http://schemas.openxmlformats.org/officeDocument/2006/relationships/theme"}} + {"rId1", {"sharedStrings.xml", "http://schemas.openxmlformats.org/officeDocument/2006/relationships/sharedStrings"}}, + {"rId2", {"styles.xml", "http://schemas.openxmlformats.org/officeDocument/2006/relationships/styles"}}, + {"rId3", {"theme/theme1.xml", "http://schemas.openxmlformats.org/officeDocument/2006/relationships/theme"}} }; + + int i = 0; + for(auto worksheet : wb) + { + rels.push_back({"rId" + std::to_string(i + 4), {"worksheets/sheet1.xml", "http://schemas.openxmlformats.org/officeDocument/2006/relationships/worksheet"}}); + i++; + } return write_relationships(rels); } diff --git a/source/zip_file.cpp b/source/zip_file.cpp index 7a7c790c..f87533e7 100644 --- a/source/zip_file.cpp +++ b/source/zip_file.cpp @@ -57,9 +57,9 @@ zip_file::~zip_file() change_state(state::closed); } -std::string zip_file::get_file_contents(const std::string &filename) +std::string zip_file::get_file_contents(const std::string &filename) const { - return files_[filename]; + return files_.at(filename); } void zip_file::set_file_contents(const std::string &filename, const std::string &contents) diff --git a/tests/runner-autogen.cpp b/tests/runner-autogen.cpp index 6ea03b74..09c7e416 100644 --- a/tests/runner-autogen.cpp +++ b/tests/runner-autogen.cpp @@ -565,41 +565,41 @@ public: static test_props suite_test_props; static CxxTest::List Tests_test_props = { 0, 0 }; -CxxTest::StaticSuiteDescription suiteDescription_test_props( "../../tests/test_props.hpp", 8, "test_props", suite_test_props, Tests_test_props ); +CxxTest::StaticSuiteDescription suiteDescription_test_props( "../../tests/test_props.hpp", 10, "test_props", suite_test_props, Tests_test_props ); static class TestDescription_suite_test_props_test_read_properties_core : public CxxTest::RealTestDescription { public: - TestDescription_suite_test_props_test_read_properties_core() : CxxTest::RealTestDescription( Tests_test_props, suiteDescription_test_props, 25, "test_read_properties_core" ) {} + TestDescription_suite_test_props_test_read_properties_core() : CxxTest::RealTestDescription( Tests_test_props, suiteDescription_test_props, 13, "test_read_properties_core" ) {} void runTest() { suite_test_props.test_read_properties_core(); } } testDescription_suite_test_props_test_read_properties_core; static class TestDescription_suite_test_props_test_read_sheets_titles : public CxxTest::RealTestDescription { public: - TestDescription_suite_test_props_test_read_sheets_titles() : CxxTest::RealTestDescription( Tests_test_props, suiteDescription_test_props, 36, "test_read_sheets_titles" ) {} + TestDescription_suite_test_props_test_read_sheets_titles() : CxxTest::RealTestDescription( Tests_test_props, suiteDescription_test_props, 30, "test_read_sheets_titles" ) {} void runTest() { suite_test_props.test_read_sheets_titles(); } } testDescription_suite_test_props_test_read_sheets_titles; static class TestDescription_suite_test_props_test_read_properties_core2 : public CxxTest::RealTestDescription { public: - TestDescription_suite_test_props_test_read_properties_core2() : CxxTest::RealTestDescription( Tests_test_props, suiteDescription_test_props, 57, "test_read_properties_core2" ) {} + TestDescription_suite_test_props_test_read_properties_core2() : CxxTest::RealTestDescription( Tests_test_props, suiteDescription_test_props, 42, "test_read_properties_core2" ) {} void runTest() { suite_test_props.test_read_properties_core2(); } } testDescription_suite_test_props_test_read_properties_core2; static class TestDescription_suite_test_props_test_read_sheets_titles2 : public CxxTest::RealTestDescription { public: - TestDescription_suite_test_props_test_read_sheets_titles2() : CxxTest::RealTestDescription( Tests_test_props, suiteDescription_test_props, 64, "test_read_sheets_titles2" ) {} + TestDescription_suite_test_props_test_read_sheets_titles2() : CxxTest::RealTestDescription( Tests_test_props, suiteDescription_test_props, 50, "test_read_sheets_titles2" ) {} void runTest() { suite_test_props.test_read_sheets_titles2(); } } testDescription_suite_test_props_test_read_sheets_titles2; static class TestDescription_suite_test_props_test_write_properties_core : public CxxTest::RealTestDescription { public: - TestDescription_suite_test_props_test_write_properties_core() : CxxTest::RealTestDescription( Tests_test_props, suiteDescription_test_props, 72, "test_write_properties_core" ) {} + TestDescription_suite_test_props_test_write_properties_core() : CxxTest::RealTestDescription( Tests_test_props, suiteDescription_test_props, 62, "test_write_properties_core" ) {} void runTest() { suite_test_props.test_write_properties_core(); } } testDescription_suite_test_props_test_write_properties_core; static class TestDescription_suite_test_props_test_write_properties_app : public CxxTest::RealTestDescription { public: - TestDescription_suite_test_props_test_write_properties_app() : CxxTest::RealTestDescription( Tests_test_props, suiteDescription_test_props, 84, "test_write_properties_app" ) {} + TestDescription_suite_test_props_test_write_properties_app() : CxxTest::RealTestDescription( Tests_test_props, suiteDescription_test_props, 73, "test_write_properties_app" ) {} void runTest() { suite_test_props.test_write_properties_app(); } } testDescription_suite_test_props_test_write_properties_app; diff --git a/tests/test_props.hpp b/tests/test_props.hpp index f267c503..c28ea839 100644 --- a/tests/test_props.hpp +++ b/tests/test_props.hpp @@ -4,91 +4,78 @@ #include #include +#include "helpers/path_helper.hpp" +#include "helpers/helper.hpp" class test_props : public CxxTest::TestSuite { public: - class TestReaderProps - { - void setup_class(int cls) - { - //cls.genuine_filename = os.path.join(DATADIR, "genuine", "empty.xlsx"); - //cls.archive = ZipFile(cls.genuine_filename, "r", ZIP_DEFLATED); - } - - void teardown_class(int cls) - { - //cls.archive.close(); - } - }; - void test_read_properties_core() { - //content = archive.read(ARC_CORE) - // prop = read_properties_core(content) - // TS_ASSERT_EQUALS(prop.creator, "*.*") - // eacute = chr(233) - // TS_ASSERT_EQUALS(prop.last_modified_by, "Aur" + eacute + "lien Camp" + eacute + "as") - // TS_ASSERT_EQUALS(prop.created, datetime(2010, 4, 9, 20, 43, 12)) - // TS_ASSERT_EQUALS(prop.modified, datetime(2011, 2, 9, 13, 49, 32)) + xlnt::zip_file archive(PathHelper::GetDataDirectory() + "/genuine/empty.xlsx", xlnt::file_mode::open); + auto content = archive.get_file_contents("docProps/core.xml"); + auto prop = xlnt::reader::read_properties_core(content); + TS_ASSERT_EQUALS(prop.creator, "*.*"); + unsigned char eacute = 233; + std::string modified_by = "Aur"; + modified_by.append(1, eacute); + modified_by += "lien Camp"; + modified_by.append(1, eacute); + modified_by += "as"; + TS_ASSERT_EQUALS(prop.last_modified_by, modified_by); + TS_ASSERT_EQUALS(prop.created, xlnt::datetime(2010, 4, 9, 20, 43, 12)); + TS_ASSERT_EQUALS(prop.modified, xlnt::datetime(2011, 2, 9, 13, 49, 32)); } void test_read_sheets_titles() { - //content = archive.read(ARC_WORKBOOK); - //sheet_titles = read_sheets_titles(content); - //TS_ASSERT_EQUALS(sheet_titles, \ - // ["Sheet1 - Text", "Sheet2 - Numbers", "Sheet3 - Formulas", "Sheet4 - Dates"]); + xlnt::zip_file archive(PathHelper::GetDataDirectory() + "/genuine/empty.xlsx", xlnt::file_mode::open); + auto content = archive.get_file_contents("docProps/core.xml"); + std::vector expected_titles = {"Sheet1 - Text", "Sheet2 - Numbers", "Sheet3 - Formulas", "Sheet4 - Dates"}; + int i = 0; + for(auto sheet : xlnt::reader::read_sheets(archive)) + { + TS_ASSERT_EQUALS(sheet.second, expected_titles[i++]); + } } - // Just tests that the correct date / time format is returned from LibreOffice saved version + void test_read_properties_core2() + { + xlnt::zip_file archive(PathHelper::GetDataDirectory() + "/genuine/empty_libre.xlsx", xlnt::file_mode::open); + auto content = archive.get_file_contents("docProps/core.xml"); + auto prop = xlnt::reader::read_properties_core(content); + TS_ASSERT_EQUALS(prop.excel_base_date, xlnt::calendar::windows_1900); + } - void setup_class(int cls) + void test_read_sheets_titles2() + { + xlnt::zip_file archive(PathHelper::GetDataDirectory() + "/genuine/empty_libre.xlsx", xlnt::file_mode::open); + auto content = archive.get_file_contents("docProps/core.xml"); + std::vector expected_titles = {"Sheet1 - Text", "Sheet2 - Numbers", "Sheet3 - Formulas", "Sheet4 - Dates"}; + int i = 0; + for(auto sheet : xlnt::reader::read_sheets(archive)) { - //cls.genuine_filename = os.path.join(DATADIR, "genuine", "empty_libre.xlsx") - // cls.archive = ZipFile(cls.genuine_filename, "r", ZIP_DEFLATED) - } - - void teardown_class(int cls) - { - //cls.archive.close() - } - - void test_read_properties_core2() - { - // content = archive.read(ARC_CORE) - // prop = read_properties_core(content) - // TS_ASSERT_EQUALS(prop.excel_base_date, CALENDAR_WINDOWS_1900) - } - - void test_read_sheets_titles2() - { - //content = archive.read(ARC_WORKBOOK) - // sheet_titles = read_sheets_titles(content) - // TS_ASSERT_EQUALS(sheet_titles, \ - // ["Sheet1 - Text", "Sheet2 - Numbers", "Sheet3 - Formulas", "Sheet4 - Dates"]) + TS_ASSERT_EQUALS(sheet.second, expected_titles[i++]); } + } void test_write_properties_core() { - //prop.creator = "TEST_USER" - // prop.last_modified_by = "SOMEBODY" - // prop.created = datetime(2010, 4, 1, 20, 30, 00) - // prop.modified = datetime(2010, 4, 5, 14, 5, 30) - // content = write_properties_core(prop) - // assert_equals_file_content( - // os.path.join(DATADIR, "writer", "expected", "core.xml"), - // content) + xlnt::document_properties prop; + prop.creator = "TEST_USER"; + 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); + auto content = xlnt::writer::write_properties_core(prop); + TS_ASSERT(Helper::EqualsFileContent(PathHelper::GetDataDirectory() + "/writer/expected/core.xml", content)); } void test_write_properties_app() { - //wb = Workbook() - // wb.create_sheet() - // wb.create_sheet() - // content = write_properties_app(wb) - // assert_equals_file_content( - // os.path.join(DATADIR, "writer", "expected", "app.xml"), - // content) + xlnt::workbook wb; + wb.create_sheet(); + wb.create_sheet(); + auto content = xlnt::writer::write_properties_app(wb); + TS_ASSERT(Helper::EqualsFileContent(PathHelper::GetDataDirectory() + "/writer/expected/app.xml", content)); } }; diff --git a/tests/test_read.hpp b/tests/test_read.hpp index ee5e55a7..94c68110 100644 --- a/tests/test_read.hpp +++ b/tests/test_read.hpp @@ -38,7 +38,7 @@ public: void test_read_standard_workbook_from_fileobj() { auto path = PathHelper::GetDataDirectory() + "/genuine/empty.xlsx"; - std::ifstream fo(path); + std::ifstream fo(path, std::ios::binary); xlnt::workbook wb; wb.load(fo); }