diff --git a/source/tests/WorksheetTestSuite.h b/source/tests/WorksheetTestSuite.h index bdf29c7f..38d1b4b9 100644 --- a/source/tests/WorksheetTestSuite.h +++ b/source/tests/WorksheetTestSuite.h @@ -3,6 +3,7 @@ #include #include +#include "pugixml.hpp" #include "../xlnt.h" class WorksheetTestSuite : public CxxTest::TestSuite @@ -14,321 +15,329 @@ public: void test_new_worksheet() { - ws = Worksheet(wb); - TS_ASSERT_EQUALS(wb, ws._parent); + xlnt::worksheet ws = wb.create_sheet(); + TS_ASSERT_EQUALS(&wb, &ws.get_parent()); } void test_new_sheet_name() { - wb.worksheets = []; - ws = Worksheet(wb, title = ""); - TS_ASSERT_EQUALS(repr(ws), ""); + xlnt::workbook wb; + wb.remove_sheet(wb.get_active_sheet()); + xlnt::worksheet ws = wb.create_sheet(); + TS_ASSERT_EQUALS(ws.to_string(), ""); } void test_get_cell() { - ws = Worksheet(wb); - cell = ws.cell("A1"); + xlnt::worksheet ws(wb); + auto cell = ws.cell("A1"); TS_ASSERT_EQUALS(cell.get_coordinate(), "A1"); } void test_set_bad_title() { std::string title(50, 'X'); - xlnt::workbook wb; wb.create_sheet(title); } void test_set_bad_title_character() { - assert_raises(SheetTitleException, Worksheet, wb, "["); - assert_raises(SheetTitleException, Worksheet, wb, "]"); - assert_raises(SheetTitleException, Worksheet, wb, "*"); - assert_raises(SheetTitleException, Worksheet, wb, ":"); - assert_raises(SheetTitleException, Worksheet, wb, "?"); - assert_raises(SheetTitleException, Worksheet, wb, "/"); - assert_raises(SheetTitleException, Worksheet, wb, "\\"); + TS_ASSERT_THROWS(wb.create_sheet("["), xlnt::bad_sheet_title); + TS_ASSERT_THROWS(wb.create_sheet("]"), xlnt::bad_sheet_title); + TS_ASSERT_THROWS(wb.create_sheet("*"), xlnt::bad_sheet_title); + TS_ASSERT_THROWS(wb.create_sheet(":"), xlnt::bad_sheet_title); + TS_ASSERT_THROWS(wb.create_sheet("?"), xlnt::bad_sheet_title); + TS_ASSERT_THROWS(wb.create_sheet("/"), xlnt::bad_sheet_title); + TS_ASSERT_THROWS(wb.create_sheet("\\"), xlnt::bad_sheet_title); } void test_worksheet_dimension() { - ws = Worksheet(wb); + xlnt::worksheet ws(wb); TS_ASSERT_EQUALS("A1:A1", ws.calculate_dimension()); - ws.cell("B12").value = "AAA"; + ws.cell("B12") = "AAA"; TS_ASSERT_EQUALS("A1:B12", ws.calculate_dimension()); } void test_worksheet_range() { - ws = Worksheet(wb); - xlrange = ws.range("A1:C4"); - assert isinstance(xlrange, tuple); - TS_ASSERT_EQUALS(4, len(xlrange)); - TS_ASSERT_EQUALS(3, len(xlrange[0])); + xlnt::worksheet ws(wb); + auto xlrange = ws.range("A1:C4"); + TS_ASSERT_EQUALS(4, xlrange.size()); + TS_ASSERT_EQUALS(3, xlrange[0].size()); } void test_worksheet_named_range() { - ws = Worksheet(wb); + xlnt::worksheet ws(wb); wb.create_named_range("test_range", ws, "C5"); - xlrange = ws.range("test_range"); - assert isinstance(xlrange, Cell); - TS_ASSERT_EQUALS(5, xlrange.row); + auto xlrange = ws.range("test_range"); + TS_ASSERT_EQUALS(1, xlrange.size()); + TS_ASSERT_EQUALS(1, xlrange[0].size()); + TS_ASSERT_EQUALS(5, xlrange[0][0].get_row()); } void test_bad_named_range() { - ws = Worksheet(wb); + xlnt::worksheet ws(wb); ws.range("bad_range"); } void test_named_range_wrong_sheet() { - ws1 = Worksheet(wb); - ws2 = Worksheet(wb); + xlnt::worksheet ws1(wb); + xlnt::worksheet ws2(wb); wb.create_named_range("wrong_sheet_range", ws1, "C5"); ws2.range("wrong_sheet_range"); } void test_cell_offset() { - ws = Worksheet(wb); - TS_ASSERT_EQUALS("C17", ws.cell("B15").offset(2, 1).get_coordinate()); + xlnt::worksheet ws(wb); + TS_ASSERT_EQUALS("C17", ws.cell("B15").get_offset(2, 1).get_coordinate()); } void test_range_offset() { - ws = Worksheet(wb); - xlrange = ws.range("A1:C4", 1, 3); - assert isinstance(xlrange, tuple); - TS_ASSERT_EQUALS(4, len(xlrange)); - TS_ASSERT_EQUALS(3, len(xlrange[0])); + xlnt::worksheet ws(wb); + auto xlrange = ws.range("A1:C4", 1, 3); + TS_ASSERT_EQUALS(4, xlrange.size()); + TS_ASSERT_EQUALS(3, xlrange[0].size()); TS_ASSERT_EQUALS("D2", xlrange[0][0].get_coordinate()); } void test_cell_alternate_coordinates() { - ws = Worksheet(wb); - cell = ws.cell(row = 8, column = 4); + xlnt::worksheet ws(wb); + auto cell = ws.cell(8, 4); TS_ASSERT_EQUALS("E9", cell.get_coordinate()); } - void test_cell_insufficient_coordinates() - { - ws = Worksheet(wb); - cell = ws.cell(row = 8); - } - void test_cell_range_name() { - ws = Worksheet(wb); + xlnt::worksheet ws(wb); wb.create_named_range("test_range_single", ws, "B12"); - assert_raises(CellCoordinatesException, ws.cell, "test_range_single"); - c_range_name = ws.range("test_range_single"); - c_range_coord = ws.range("B12"); - c_cell = ws.cell("B12"); + TS_ASSERT_THROWS(ws.cell("test_range_single"), xlnt::bad_cell_coordinates); + auto c_range_name = ws.range("test_range_single"); + auto c_range_coord = ws.range("B12"); + auto c_cell = ws.cell("B12"); TS_ASSERT_EQUALS(c_range_coord, c_range_name); TS_ASSERT_EQUALS(c_range_coord, c_cell); } void test_garbage_collect() { - ws = Worksheet(wb); - ws.cell("A1").value = ""; - ws.cell("B2").value = "0"; - ws.cell("C4").value = 0; + xlnt::worksheet ws(wb); + + ws.cell("A1") = ""; + ws.cell("B2") = "0"; + ws.cell("C4") = 0; + ws.garbage_collect(); - for i, cell in enumerate(ws.get_cell_collection()) + + std::set comparison_cells = {ws.cell("B2"), ws.cell("C4")}; + + for(auto cell : ws.get_cell_collection()) { - TS_ASSERT_EQUALS(cell, [ws.cell("B2"), ws.cell("C4")][i]); + auto match = std::find(comparison_cells.begin(), comparison_cells.end(), cell); + TS_ASSERT_DIFFERS(match, comparison_cells.end()); + comparison_cells.erase(match); } } void test_hyperlink_relationships() { - ws = Worksheet(wb); - TS_ASSERT_EQUALS(len(ws.relationships), 0); + xlnt::worksheet ws(wb); - ws.cell("A1").hyperlink = "http:test.com"; - TS_ASSERT_EQUALS(len(ws.relationships), 1); - TS_ASSERT_EQUALS("rId1", ws.cell("A1").hyperlink_rel_id); - TS_ASSERT_EQUALS("rId1", ws.relationships[0].id); - TS_ASSERT_EQUALS("http:test.com", ws.relationships[0].target); - TS_ASSERT_EQUALS("External", ws.relationships[0].target_mode); + TS_ASSERT_EQUALS(ws.get_relationships().size(), 0); - ws.cell("A2").hyperlink = "http:test2.com"; - TS_ASSERT_EQUALS(len(ws.relationships), 2); - TS_ASSERT_EQUALS("rId2", ws.cell("A2").hyperlink_rel_id); - TS_ASSERT_EQUALS("rId2", ws.relationships[1].id); - TS_ASSERT_EQUALS("http:test2.com", ws.relationships[1].target); - TS_ASSERT_EQUALS("External", ws.relationships[1].target_mode); + ws.cell("A1").set_hyperlink("http:test.com"); + TS_ASSERT_EQUALS(ws.get_relationships().size(), 1); + TS_ASSERT_EQUALS("rId1", ws.cell("A1").get_hyperlink_rel_id()); + TS_ASSERT_EQUALS("rId1", ws.get_relationships()[0].get_id()); + TS_ASSERT_EQUALS("http:test.com", ws.get_relationships()[0].get_target_uri()); + TS_ASSERT_EQUALS("External", ws.get_relationships()[0].get_target_mode()); + + ws.cell("A2").set_hyperlink("http:test2.com"); + TS_ASSERT_EQUALS(ws.get_relationships().size(), 2); + TS_ASSERT_EQUALS("rId2", ws.cell("A2").get_hyperlink_rel_id()); + TS_ASSERT_EQUALS("rId2", ws.get_relationships()[1].get_id()); + TS_ASSERT_EQUALS("http:test2.com", ws.get_relationships()[1].get_target_uri()); + TS_ASSERT_EQUALS("External", ws.get_relationships()[1].get_target_mode()); } void test_bad_relationship_type() { - rel = Relationship("bad_type"); + xlnt::relationship rel("bad_type"); } void test_append_list() { - ws = Worksheet(wb); + xlnt::worksheet ws(wb); - ws.append(["This is A1", "This is B1"]); + ws.append(std::vector {"This is A1", "This is B1"}); - TS_ASSERT_EQUALS("This is A1", ws.cell("A1").value); - TS_ASSERT_EQUALS("This is B1", ws.cell("B1").value); + TS_ASSERT_EQUALS("This is A1", ws.cell("A1")); + TS_ASSERT_EQUALS("This is B1", ws.cell("B1")); } void test_append_dict_letter() { - ws = Worksheet(wb); + xlnt::worksheet ws(wb); - ws.append({"A" : "This is A1", "C" : "This is C1"}); + ws.append(std::unordered_map {{"A", "This is A1"}, {"C", "This is C1"}}); - TS_ASSERT_EQUALS("This is A1", ws.cell("A1").value); - TS_ASSERT_EQUALS("This is C1", ws.cell("C1").value); + TS_ASSERT_EQUALS("This is A1", ws.cell("A1")); + TS_ASSERT_EQUALS("This is C1", ws.cell("C1")); } void test_append_dict_index() { - ws = Worksheet(wb); + xlnt::worksheet ws(wb); - ws.append({0 : "This is A1", 2 : "This is C1"}); + ws.append(std::unordered_map {{0, "This is A1"}, {2, "This is C1"}}); - TS_ASSERT_EQUALS("This is A1", ws.cell("A1").value); - TS_ASSERT_EQUALS("This is C1", ws.cell("C1").value); - } - - void test_bad_append() - { - ws = Worksheet(wb); - ws.append("test"); + TS_ASSERT_EQUALS("This is A1", ws.cell("A1")); + TS_ASSERT_EQUALS("This is C1", ws.cell("C1")); } void test_append_2d_list() { - ws = Worksheet(wb); + xlnt::worksheet ws(wb); - ws.append(["This is A1", "This is B1"]); - ws.append(["This is A2", "This is B2"]); + ws.append(std::vector {"This is A1", "This is B1"}); + ws.append(std::vector {"This is A2", "This is B2"}); - vals = ws.range("A1:B2"); + auto vals = ws.range("A1:B2"); - TS_ASSERT_EQUALS((("This is A1", "This is B1"), - ("This is A2", "This is B2"), ), flatten(vals)); + TS_ASSERT_EQUALS(vals[0][0], "This is A1"); + TS_ASSERT_EQUALS(vals[0][1], "This is B1"); + TS_ASSERT_EQUALS(vals[1][0], "This is A2"); + TS_ASSERT_EQUALS(vals[1][1], "This is A2"); } void test_rows() { - ws = Worksheet(wb); + xlnt::worksheet ws(wb); - ws.cell("A1").value = "first"; - ws.cell("C9").value = "last"; + ws.cell("A1") = "first"; + ws.cell("C9") = "last"; - rows = ws.rows; + auto rows = ws.rows(); - TS_ASSERT_EQUALS(len(rows), 9); + TS_ASSERT_EQUALS(rows.size(), 9); - TS_ASSERT_EQUALS(rows[0][0].value, "first"); - TS_ASSERT_EQUALS(rows[-1][-1].value, "last"); + TS_ASSERT_EQUALS(rows[0][0], "first"); + TS_ASSERT_EQUALS(rows[8][2], "last"); } void test_cols() { - ws = Worksheet(wb); + xlnt::worksheet ws(wb); - ws.cell("A1").value = "first"; - ws.cell("C9").value = "last"; + ws.cell("A1") = "first"; + ws.cell("C9") = "last"; - cols = ws.columns; + auto cols = ws.columns(); - TS_ASSERT_EQUALS(len(cols), 3); + TS_ASSERT_EQUALS(cols.size(), 3); - TS_ASSERT_EQUALS(cols[0][0].value, "first"); - TS_ASSERT_EQUALS(cols[-1][-1].value, "last"); + TS_ASSERT_EQUALS(cols[0][0], "first"); + TS_ASSERT_EQUALS(cols[8][2], "last"); } void test_auto_filter() { - ws = Worksheet(wb); - ws.auto_filter = ws.range("a1:f1"); - assert ws.auto_filter == "A1:F1"; + xlnt::worksheet ws(wb); - ws.auto_filter = ""; + /*ws.set_auto_filter(ws.range("a1:f1")); + TS_ASSERT_EQUALS(ws.get_auto_filter(), "A1:F1"); + + ws.set_auto_filter(""); assert ws.auto_filter is None; ws.auto_filter = "c1:g9"; - assert ws.auto_filter == "C1:G9"; + assert ws.auto_filter == "C1:G9";*/ } void test_page_margins() { - ws = Worksheet(wb); - ws.page_margins.left = 2.0; - ws.page_margins.right = 2.0; - ws.page_margins.top = 2.0; - ws.page_margins.bottom = 2.0; - ws.page_margins.header = 1.5; - ws.page_margins.footer = 1.5; - xml_string = write_worksheet(ws, None, None); - assert "" in xml_string; + xlnt::worksheet ws(wb); - ws = Worksheet(wb); - xml_string = write_worksheet(ws, None, None); - assert "" in xml_string; + + xlnt::worksheet ws2(wb); + xml_string = xlnt::writer::write_worksheet(ws2); + //assert "Cell B1" in xml_string; + std::unordered_map string_table = {{"", ""}, {"Cell A1", "Cell A1"}, {"Cell B1", "Cell B1"}}; + + ws.cell("A1") = "Cell A1"; + ws.cell("B1") = "Cell B1"; + auto xml_string = xlnt::writer::write_worksheet(ws);// , string_table); + /*assert "Cell B1" in xml_string; ws.merge_cells("A1:B1"); - xml_string = write_worksheet(ws, string_table, None); + xml_string = xlnt::writer::write_worksheet(ws, string_table, None); assert "Cell B1" not in xml_string; assert "" in xml_string; ws.unmerge_cells("A1:B1"); - xml_string = write_worksheet(ws, string_table, None); - assert "" not in xml_string; + xml_string = xlnt::writer::write_worksheet(ws, string_table, None); + assert "" not in xml_string;*/ } void test_freeze() { - ws = Worksheet(wb); - ws.freeze_panes = ws.cell("b2"); - assert ws.freeze_panes == "B2"; + xlnt::worksheet ws(wb); - ws.freeze_panes = ""; - assert ws.freeze_panes is None; + ws.set_freeze_panes(ws.cell("b2")); + TS_ASSERT_EQUALS(ws.get_freeze_panes().get_address(), "B2"); - ws.freeze_panes = "c5"; - assert ws.freeze_panes == "C5"; + ws.unfreeze_panes(); + TS_ASSERT_EQUALS(ws.get_freeze_panes(), nullptr); - ws.freeze_panes = ws.cell("A1"); - assert ws.freeze_panes is None; + ws.set_freeze_panes("c5"); + TS_ASSERT_EQUALS(ws.get_freeze_panes().get_address(), "C5"); + + ws.set_freeze_panes(ws.cell("A1")); + TS_ASSERT_EQUALS(ws.get_freeze_panes(), nullptr); } void test_printer_settings() { - ws = Worksheet(wb); - ws.page_setup.orientation = ws.ORIENTATION_LANDSCAPE; - ws.page_setup.paperSize = ws.PAPERSIZE_TABLOID; - ws.page_setup.fitToPage = True; - ws.page_setup.fitToHeight = 0; - ws.page_setup.fitToWidth = 1; - xml_string = write_worksheet(ws, None, None); - assert "" in xml_string; - assert "" in xml_string; + xlnt::worksheet ws(wb); - ws = Worksheet(wb); - xml_string = write_worksheet(ws, None, None); - assert "" in xml_string); + //TS_ASSERT("" in xml_string); + + xlnt::worksheet ws2(wb); + xml_string = xlnt::writer::write_worksheet(ws2); + //TS_ASSERT(" existing_xlsx = { 0x50, 0x4b, 0x03, 0x04, 0x14, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x21, 0x00, 0xf8, 0x17, 0x86, 0x86, 0x7a, 0x01, 0x00, 0x00, 0x10, 0x03, @@ -1370,17 +1361,28 @@ struct worksheet_struct void garbage_collect() { - throw not_implemented(); + for(auto map_iter = cell_map_.begin(); map_iter != cell_map_.end(); map_iter++) + { + if(map_iter->second.get_data_type() == cell::type::null) + { + map_iter = cell_map_.erase(map_iter); + } + } } - std::set get_cell_collection() + std::list get_cell_collection() { - throw not_implemented(); + std::list cells; + for(auto cell : cell_map_) + { + cells.push_front(xlnt::cell(cell.second)); + } + return cells; } std::string get_title() const { - throw not_implemented(); + return title_; } void set_title(const std::string &title) @@ -1427,33 +1429,76 @@ struct worksheet_struct int get_highest_row() const { - throw not_implemented(); + int highest = 0; + for(auto cell : cell_map_) + { + highest = (std::max)(highest, cell.second.get_row()); + } + return highest; } int get_highest_column() const { - throw not_implemented(); + int highest = 0; + for(auto cell : cell_map_) + { + highest = (std::max)(highest, xlnt::cell::column_index_from_string(cell.second.get_column())); + } + return highest; } std::string calculate_dimension() const { - throw not_implemented(); + int width = get_highest_column(); + std::string width_letter = xlnt::cell::get_column_letter(width); + int height = get_highest_row(); + return "A1:" + width_letter + std::to_string(height); } - range range(const std::string &range_string, int /*row_offset*/, int /*column_offset*/) + xlnt::range range(const std::string &range_string, int row_offset, int column_offset) { + xlnt::range r; + auto colon_index = range_string.find(':'); + if(colon_index != std::string::npos) { auto min_range = range_string.substr(0, colon_index); auto max_range = range_string.substr(colon_index + 1); - xlnt::range r; - r.push_back(std::vector()); - r[0].push_back(cell(min_range)); - r[0].push_back(cell(max_range)); - return r; + auto min_coord = xlnt::cell::coordinate_from_string(min_range); + auto max_coord = xlnt::cell::coordinate_from_string(max_range); + + if(column_offset != 0) + { + min_coord.column = xlnt::cell::get_column_letter(xlnt::cell::column_index_from_string(min_coord.column) + column_offset); + max_coord.column = xlnt::cell::get_column_letter(xlnt::cell::column_index_from_string(max_coord.column) + column_offset); + } + + std::unordered_map column_cache; + + for(int i = xlnt::cell::column_index_from_string(min_coord.column); + i <= xlnt::cell::column_index_from_string(max_coord.column); i++) + { + column_cache[i] = xlnt::cell::get_column_letter(i); + } + for(int row = min_coord.row + row_offset; row <= max_coord.row + row_offset; row++) + { + r.push_back(std::vector()); + for(int column = xlnt::cell::column_index_from_string(min_coord.column) + column_offset; + column <= xlnt::cell::column_index_from_string(max_coord.column) + column_offset; column++) + { + std::string coordinate = column_cache[column] + std::to_string(row); + r.back().push_back(cell(coordinate)); + } + } } - throw not_implemented(); + else + { + r.push_back(std::vector()); + r.back().push_back(cell(range_string)); + } + + return r; } relationship create_relationship(const std::string &relationship_type) @@ -1464,27 +1509,55 @@ struct worksheet_struct //void add_chart(chart chart); - void merge_cells(const std::string &/*range_string*/) + void merge_cells(const std::string &range_string) { - throw not_implemented(); + bool first = true; + for(auto row : range(range_string, 0, 0)) + { + for(auto cell : row) + { + cell.set_merged(true); + if(!first) + { + cell.bind_value(); + } + first = false; + } + } } - void merge_cells(int /*start_row*/, int /*start_column*/, int /*end_row*/, int /*end_column*/) + void merge_cells(int start_row, int start_column, int end_row, int end_column) { - throw not_implemented(); + auto range_string = xlnt::cell::get_column_letter(start_column + 1) + std::to_string(start_row + 1) + ":" + + xlnt::cell::get_column_letter(end_column + 1) + std::to_string(end_row + 1); + merge_cells(range_string); } - void unmerge_cells(const std::string &/*range_string*/) + void unmerge_cells(const std::string &range_string) { - throw not_implemented(); + bool first = true; + for(auto row : range(range_string, 0, 0)) + { + for(auto cell : row) + { + cell.set_merged(false); + if(!first) + { + cell.bind_value(); + } + first = false; + } + } } - void unmerge_cells(int /*start_row*/, int /*start_column*/, int /*end_row*/, int /*end_column*/) + void unmerge_cells(int start_row, int start_column, int end_row, int end_column) { - throw not_implemented(); + auto range_string = xlnt::cell::get_column_letter(start_column + 1) + std::to_string(start_row + 1) + ":" + + xlnt::cell::get_column_letter(end_column + 1) + std::to_string(end_row + 1); + merge_cells(range_string); } - void append(const std::vector &cells) + void append(const std::vector &cells) { for(auto cell : cells) { @@ -1492,7 +1565,7 @@ struct worksheet_struct } } - void append(const std::unordered_map &cells) + void append(const std::unordered_map &cells) { for(auto cell : cells) { @@ -1500,7 +1573,7 @@ struct worksheet_struct } } - void append(const std::unordered_map &cells) + void append(const std::unordered_map &cells) { for(auto cell : cells) { @@ -1508,14 +1581,14 @@ struct worksheet_struct } } - xlnt::range rows() const + xlnt::range rows() { - throw not_implemented(); + return range(calculate_dimension(), 0, 0); } - xlnt::range columns() const + xlnt::range columns() { - throw not_implemented(); + throw std::runtime_error("not implemented"); } void operator=(const worksheet_struct &other) = delete; @@ -1546,7 +1619,7 @@ void worksheet::garbage_collect() root_->garbage_collect(); } -std::set worksheet::get_cell_collection() +std::list worksheet::get_cell_collection() { return root_->get_cell_collection(); } @@ -1694,9 +1767,9 @@ cell worksheet::operator[](const std::string &address) return cell(address); } -std::string workbook::write_content_types(workbook &wb) +std::string writer::write_content_types(workbook &wb) { - std::set seen; + /*std::set seen; pugi::xml_node root; @@ -1793,12 +1866,13 @@ std::string workbook::write_content_types(workbook &wb) } } - return get_document_content(root); + return get_document_content(root);*/ + return ""; } -std::string workbook::write_root_rels(workbook wb) +std::string writer::write_root_rels(workbook &wb) { - root = Element("{%s}Relationships" % PKG_REL_NS); + /*root = Element("{%s}Relationships" % PKG_REL_NS); relation_tag = "{%s}Relationship" % PKG_REL_NS; SubElement(root, relation_tag, {"Id": "rId1", "Target" : ARC_WORKBOOK, "Type" : "%s/officeDocument" % REL_NS}); @@ -1827,7 +1901,8 @@ std::string workbook::write_root_rels(workbook wb) } } - return get_document_content(root); + return get_document_content(root);*/ + return ""; } workbook::workbook() : active_sheet_index_(0) @@ -1910,4 +1985,72 @@ std::string cell_struct::to_string() const return "title_ + "." + xlnt::cell::get_column_letter(column + 1) + std::to_string(row) + ">"; } +bool workbook::operator==(const workbook &rhs) const +{ + if(optimized_write_ == rhs.optimized_write_ + && optimized_read_ == rhs.optimized_read_ + && guess_types_ == rhs.guess_types_ + && data_only_ == rhs.data_only_ + && active_sheet_index_ == rhs.active_sheet_index_ + && encoding_ == rhs.encoding_) + { + if(worksheets_.size() != rhs.worksheets_.size()) + { + return false; + } + + for(int i = 0; i < worksheets_.size(); i++) + { + if(worksheets_[i] != rhs.worksheets_[i]) + { + return false; + } + } + + /* + if(named_ranges_.size() != rhs.named_ranges_.size()) + { + return false; + } + + for(int i = 0; i < named_ranges_.size(); i++) + { + if(named_ranges_[i] != rhs.named_ranges_[i]) + { + return false; + } + } + + if(relationships_.size() != rhs.relationships_.size()) + { + return false; + } + + for(int i = 0; i < relationships_.size(); i++) + { + if(relationships_[i] != rhs.relationships_[i]) + { + return false; + } + } + + if(drawings_.size() != rhs.drawings_.size()) + { + return false; + } + + for(int i = 0; i < drawings_.size(); i++) + { + if(drawings_[i] != rhs.drawings_[i]) + { + return false; + } + } + */ + + return true; + } + return false; +} + } diff --git a/source/xlnt.h b/source/xlnt.h index 11c8d17e..d082ed45 100644 --- a/source/xlnt.h +++ b/source/xlnt.h @@ -202,6 +202,26 @@ enum class encoding_type latin1 }; +class bad_sheet_title : public std::runtime_error +{ +public: + bad_sheet_title(const std::string &title) + : std::runtime_error(std::string("bad worksheet title: ") + title) + { + + } +}; + +class bad_cell_coordinates : public std::runtime_error +{ +public: + bad_cell_coordinates(int row, int column) + : std::runtime_error(std::string("bad cell coordinates: (") + std::to_string(row) + "," + std::to_string(column) + ")") + { + + } +}; + /// /// Represents a value type that may or may not have an assigned value. /// @@ -1133,6 +1153,9 @@ public: cell(worksheet &ws, const std::string &column, int row); cell(worksheet &ws, const std::string &column, int row, const std::string &initial_value); + int get_row() const; + std::string get_column() const; + encoding_type get_encoding() const; std::string to_string() const; @@ -1147,6 +1170,9 @@ public: bool bind_value(bool value); bool bind_value(const tm &value); + bool get_merged() const; + void set_merged(bool); + std::string get_hyperlink() const; void set_hyperlink(const std::string &value); @@ -1210,9 +1236,8 @@ inline std::ostream &operator<<(std::ostream &stream, const cell &cell) typedef std::vector> range; -class worksheet +struct page_setup { -public: enum class Break { None = 0, @@ -1248,15 +1273,29 @@ public: Landscape }; + Break break_; + SheetState sheet_state; + PaperSize paper_size; + Orientation orientation; + bool fit_to_page; + bool fit_to_height; + bool fit_to_width; +}; + +class worksheet +{ +public: + worksheet(workbook &parent); + void operator=(const worksheet &other); - cell operator[](const std::string &address); + xlnt::cell operator[](const std::string &address); std::string to_string() const; workbook &get_parent() const; void garbage_collect(); - std::set get_cell_collection(); + std::list get_cell_collection(); std::string get_title() const; void set_title(const std::string &title); - cell get_freeze_panes() const; + xlnt::cell get_freeze_panes() const; void set_freeze_panes(cell top_left_cell); void set_freeze_panes(const std::string &top_left_coordinate); void unfreeze_panes(); @@ -1265,7 +1304,8 @@ public: int get_highest_row() const; int get_highest_column() const; std::string calculate_dimension() const; - range range(const std::string &range_string, int row_offset, int column_offset); + xlnt::range range(const std::string &range_string); + xlnt::range range(const std::string &range_string, int row_offset, int column_offset); relationship create_relationship(const std::string &relationship_type); //void add_chart(chart chart); void merge_cells(const std::string &range_string); @@ -1281,6 +1321,8 @@ public: bool operator!=(const worksheet &other) const; bool operator==(std::nullptr_t) const; bool operator!=(std::nullptr_t) const; + std::vector get_relationships(); + page_setup &get_page_setup(); private: friend class workbook; @@ -1310,12 +1352,18 @@ private: drawing_struct *root_; }; -class workbook +class writer { public: static std::string write_content_types(workbook &wb); static std::string write_root_rels(workbook &wb); + static std::string write_worksheet(worksheet &ws); + static std::string get_document_content(const std::string &filename); +}; +class workbook +{ +public: //constructors workbook(); @@ -1382,6 +1430,8 @@ public: void save(const std::string &filename); void load(const std::string &filename); + bool operator==(const workbook &rhs) const; + private: bool optimized_write_; bool optimized_read_;