general API improvements

This commit is contained in:
Thomas Fussell 2016-05-11 19:24:53 -04:00
parent 720edc143f
commit 31b546b1d5
15 changed files with 414 additions and 170 deletions

View File

@ -44,6 +44,7 @@ class font;
class number_format;
class protection;
class relationship;
class workbook;
class worksheet;
struct date;
@ -329,16 +330,26 @@ public:
/// <summary>
/// Return the worksheet that owns this cell.
/// </summary>
worksheet get_parent();
worksheet get_worksheet();
/// <summary>
/// Return the worksheet that owns this cell.
/// </summary>
const worksheet get_parent() const;
const worksheet get_worksheet() const;
/// <summary>
/// Return the workbook of the worksheet that owns this cell.
/// </summary>
workbook &get_workbook();
/// <summary>
/// Return the workbook of the worksheet that owns this cell.
/// </summary>
const workbook &get_workbook() const;
/// <summary>
/// Shortcut to return the base date of the parent workbook.
/// Equivalent to get_parent().get_parent().get_properties().excel_base_date
/// Equivalent to get_workbook().get_properties().excel_base_date
/// </summary>
calendar get_base_date() const;
@ -390,6 +401,8 @@ private:
friend class worksheet;
friend struct detail::cell_impl;
void guess_type_and_set_value(const std::string &value);
/// <summary>
/// Private constructor to create a cell from its implementation.
/// </summary>

View File

@ -0,0 +1,62 @@
// Copyright (c) 2014-2016 Thomas Fussell
// Copyright (c) 2010-2015 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
#include <xlnt/cell/text.hpp>
#include <xlnt/cell/text_run.hpp>
namespace xlnt {
void text::clear()
{
runs_.clear();
}
void text::set_plain_string(const std::string &s)
{
clear();
add_run(text_run(s));
}
std::string text::get_plain_string() const
{
std::string plain_string;
for (const auto &run : runs_)
{
plain_string.append(run.get_string());
}
return plain_string;
}
std::vector<text_run> text::get_runs()
{
return runs_;
}
void text::add_run(const text_run &t)
{
runs_.push_back(t);
}
} // namespace xlnt

View File

@ -0,0 +1,49 @@
// Copyright (c) 2016 Thomas Fussell
//
// 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 <string>
#include <vector>
#include <xlnt/xlnt_config.hpp> // for XLNT_CLASS, XLNT_FUNCTION
#include <xlnt/cell/text_run.hpp>
namespace xlnt {
class text_run;
class XLNT_CLASS text
{
public:
void clear();
void set_plain_string(const std::string &s);
std::string get_plain_string() const;
std::vector<text_run> get_runs();
void add_run(const text_run &t);
void set_run(const std::vector<text_run> &parts);
private:
std::vector<text_run> runs_;
};
} // namespace xlnt

View File

@ -0,0 +1,46 @@
// Copyright (c) 2014-2016 Thomas Fussell
//
// 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
#include <xlnt/cell/text_run.hpp>
namespace xlnt {
text_run::text_run() : text_run("")
{
}
text_run::text_run(const std::string &string) : string_(string)
{
}
std::string text_run::get_string() const
{
return string_;
}
void text_run::set_string(const std::string &string)
{
string_ = string;
}
} // namespace xlnt

View File

@ -0,0 +1,44 @@
// Copyright (c) 2016 Thomas Fussell
//
// 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 <string>
#include <xlnt/xlnt_config.hpp> // for XLNT_CLASS, XLNT_FUNCTION
namespace xlnt {
class XLNT_CLASS text_run
{
public:
text_run();
text_run(const std::string &string);
std::string get_string() const;
void set_string(const std::string &string);
private:
std::string string_;
};
} // namespace xlnt

View File

@ -72,7 +72,8 @@ public:
worksheet(workbook &parent_workbook, const std::string &title = std::string());
std::string to_string() const;
workbook &get_parent() const;
workbook &get_workbook();
const workbook &get_workbook() const;
void garbage_collect();
// title

View File

@ -27,6 +27,7 @@
#include <xlnt/cell/cell.hpp>
#include <xlnt/cell/cell_reference.hpp>
#include <xlnt/cell/comment.hpp>
#include <xlnt/cell/text.hpp>
#include <xlnt/packaging/document_properties.hpp>
#include <xlnt/packaging/relationship.hpp>
#include <xlnt/serialization/encoding.hpp>
@ -46,6 +47,77 @@
#include <detail/cell_impl.hpp>
#include <detail/comment_impl.hpp>
namespace {
std::pair<bool, long double> cast_numeric(const std::string &s)
{
const char *str = s.c_str();
char *str_end = nullptr;
auto result = std::strtold(str, &str_end);
if (str_end != str + s.size()) return{ false, 0 };
return{ true, result };
}
std::pair<bool, long double> cast_percentage(const std::string &s)
{
if (s.back() == '%')
{
auto number = cast_numeric(s.substr(0, s.size() - 1));
if (number.first)
{
return{ true, number.second / 100 };
}
}
return{ false, 0 };
}
std::pair<bool, xlnt::time> cast_time(const std::string &s)
{
xlnt::time result;
try
{
auto last_colon = s.find_last_of(':');
if (last_colon == std::string::npos) return{ false, result };
double seconds = std::stod(s.substr(last_colon + 1));
result.second = static_cast<int>(seconds);
result.microsecond = static_cast<int>((seconds - static_cast<double>(result.second)) * 1e6);
auto first_colon = s.find_first_of(':');
if (first_colon == last_colon)
{
auto decimal_pos = s.find('.');
if (decimal_pos != std::string::npos)
{
result.minute = std::stoi(s.substr(0, first_colon));
}
else
{
result.hour = std::stoi(s.substr(0, first_colon));
result.minute = result.second;
result.second = 0;
}
}
else
{
result.hour = std::stoi(s.substr(0, first_colon));
result.minute = std::stoi(s.substr(first_colon + 1, last_colon - first_colon - 1));
}
}
catch (std::invalid_argument)
{
return{ false, result };
}
return{ true, result };
}
} // namespace
namespace xlnt {
const std::unordered_map<std::string, int> &cell::error_codes()
@ -68,7 +140,7 @@ std::string cell::check_string(const std::string &to_check)
return s;
}
auto wb_encoding = get_parent().get_parent().get_encoding();
auto wb_encoding = get_workbook().get_encoding();
//XXX: use utfcpp for this!
switch(wb_encoding)
@ -263,14 +335,42 @@ XLNT_FUNCTION void cell::set_value(long double d)
d_->type_ = type::numeric;
}
template <>
XLNT_FUNCTION void cell::set_value(text t)
{
d_->value_text_ = t;
d_->type_ = type::string;
if (!t.get_plain_string().empty())
{
get_workbook().add_shared_string(t.get_plain_string());
}
}
template <>
XLNT_FUNCTION void cell::set_value(std::string s)
{
d_->set_string(check_string(s), get_parent().get_parent().get_guess_types());
s = check_string(s);
if (get_data_type() == type::string && !s.empty())
if (s.size() > 1 && s.front() == '=')
{
get_parent().get_parent().add_shared_string(s);
d_->type_ = type::formula;
set_formula(s);
}
else if (cell::error_codes().find(s) != cell::error_codes().end())
{
set_error(s);
}
else
{
text t;
t.set_plain_string(s);
set_value(t);
}
if (get_workbook().get_guess_types())
{
guess_type_and_set_value(s);
}
}
@ -285,7 +385,7 @@ XLNT_FUNCTION void cell::set_value(cell c)
{
d_->type_ = c.d_->type_;
d_->value_numeric_ = c.d_->value_numeric_;
d_->value_string_ = c.d_->value_string_;
d_->value_text_ = c.d_->value_text_;
d_->hyperlink_ = c.d_->hyperlink_;
d_->has_hyperlink_ = c.d_->has_hyperlink_;
d_->formula_ = c.d_->formula_;
@ -458,7 +558,7 @@ void cell::set_comment(const xlnt::comment &c)
if (!has_comment())
{
get_parent().increment_comments();
get_worksheet().increment_comments();
}
*get_comment().d_ = *c.d_;
@ -468,7 +568,7 @@ void cell::clear_comment()
{
if (has_comment())
{
get_parent().decrement_comments();
get_worksheet().decrement_comments();
}
d_->comment_ = nullptr;
@ -486,31 +586,40 @@ void cell::set_error(const std::string &error)
throw data_type_exception();
}
d_->value_string_ = error;
d_->value_text_.set_plain_string(error);
d_->type_ = type::error;
}
cell cell::offset(int column, int row)
{
return get_parent().get_cell(cell_reference(d_->column_ + column, d_->row_ + row));
return get_worksheet().get_cell(cell_reference(d_->column_ + column, d_->row_ + row));
}
worksheet cell::get_parent()
worksheet cell::get_worksheet()
{
return worksheet(d_->parent_);
}
const worksheet cell::get_parent() const
const worksheet cell::get_worksheet() const
{
return worksheet(d_->parent_);
}
workbook &cell::get_workbook()
{
return get_worksheet().get_workbook();
}
const workbook &cell::get_workbook() const
{
return get_worksheet().get_workbook();
}
comment cell::get_comment()
{
if (d_->comment_ == nullptr)
{
d_->comment_.reset(new detail::comment_impl());
get_parent().increment_comments();
get_worksheet().increment_comments();
}
return comment(d_->comment_.get());
@ -533,9 +642,9 @@ std::pair<int, int> cell::get_anchor() const
for (column_t column_index = 1; column_index <= left_columns; column_index++)
{
if (get_parent().has_column_properties(column_index))
if (get_worksheet().has_column_properties(column_index))
{
auto cdw = get_parent().get_column_properties(column_index).width;
auto cdw = get_worksheet().get_column_properties(column_index).width;
if (cdw > 0)
{
@ -553,9 +662,9 @@ std::pair<int, int> cell::get_anchor() const
for (row_t row_index = 1; row_index <= top_rows; row_index++)
{
if (get_parent().has_row_properties(row_index))
if (get_worksheet().has_row_properties(row_index))
{
auto rdh = get_parent().get_row_properties(row_index).height;
auto rdh = get_worksheet().get_row_properties(row_index).height;
if (rdh > 0)
{
@ -584,11 +693,11 @@ const number_format &cell::get_number_format() const
{
if (d_->has_style_)
{
return get_parent().get_parent().get_number_format(d_->style_id_);
return get_workbook().get_number_format(d_->style_id_);
}
else
{
return get_parent().get_parent().get_number_formats().front();
return get_workbook().get_number_formats().front();
}
}
@ -596,33 +705,33 @@ const font &cell::get_font() const
{
if (d_->has_style_)
{
auto font_id = get_parent().get_parent().get_cell_formats()[d_->style_id_].get_font_id();
return get_parent().get_parent().get_font(font_id);
auto font_id = get_workbook().get_cell_formats()[d_->style_id_].get_font_id();
return get_workbook().get_font(font_id);
}
else
{
return get_parent().get_parent().get_font(0);
return get_workbook().get_font(0);
}
}
const fill &cell::get_fill() const
{
return get_parent().get_parent().get_fill(get_parent().get_parent().get_cell_format(d_->style_id_).get_fill_id());
return get_workbook().get_fill(get_workbook().get_cell_format(d_->style_id_).get_fill_id());
}
const border &cell::get_border() const
{
return get_parent().get_parent().get_border(get_parent().get_parent().get_cell_format(d_->style_id_).get_border_id());
return get_workbook().get_border(get_workbook().get_cell_format(d_->style_id_).get_border_id());
}
const alignment &cell::get_alignment() const
{
return get_parent().get_parent().get_alignment(d_->style_id_);
return get_workbook().get_alignment(d_->style_id_);
}
const protection &cell::get_protection() const
{
return get_parent().get_parent().get_protection(d_->style_id_);
return get_workbook().get_protection(d_->style_id_);
}
bool cell::pivot_button() const
@ -638,7 +747,7 @@ bool cell::quote_prefix() const
void cell::clear_value()
{
d_->value_numeric_ = 0;
d_->value_string_.clear();
d_->value_text_.clear();
d_->formula_.clear();
d_->type_ = cell::type::null;
}
@ -750,43 +859,43 @@ XLNT_FUNCTION timedelta cell::get_value() const
void cell::set_border(const xlnt::border &border_)
{
d_->has_style_ = true;
d_->style_id_ = get_parent().get_parent().set_border(border_, d_->style_id_);
d_->style_id_ = get_workbook().set_border(border_, d_->style_id_);
}
void cell::set_fill(const xlnt::fill &fill_)
{
d_->has_style_ = true;
d_->style_id_ = get_parent().get_parent().set_fill(fill_, d_->style_id_);
d_->style_id_ = get_workbook().set_fill(fill_, d_->style_id_);
}
void cell::set_font(const font &font_)
{
d_->has_style_ = true;
d_->style_id_ = get_parent().get_parent().set_font(font_, d_->style_id_);
d_->style_id_ = get_workbook().set_font(font_, d_->style_id_);
}
void cell::set_number_format(const number_format &number_format_)
{
d_->has_style_ = true;
d_->style_id_ = get_parent().get_parent().set_number_format(number_format_, d_->style_id_);
d_->style_id_ = get_workbook().set_number_format(number_format_, d_->style_id_);
}
void cell::set_alignment(const xlnt::alignment &alignment_)
{
d_->has_style_ = true;
d_->style_id_ = get_parent().get_parent().set_alignment(alignment_, d_->style_id_);
d_->style_id_ = get_workbook().set_alignment(alignment_, d_->style_id_);
}
void cell::set_protection(const xlnt::protection &protection_)
{
d_->has_style_ = true;
d_->style_id_ = get_parent().get_parent().set_protection(protection_, d_->style_id_);
d_->style_id_ = get_workbook().set_protection(protection_, d_->style_id_);
}
template <>
XLNT_FUNCTION std::string cell::get_value() const
{
return d_->value_string_;
return d_->value_text_.get_plain_string();
}
bool cell::has_value() const
@ -833,7 +942,7 @@ void cell::set_style_id(std::size_t style_id)
calendar cell::get_base_date() const
{
return get_parent().get_parent().get_properties().excel_base_date;
return get_workbook().get_properties().excel_base_date;
}
std::ostream &operator<<(std::ostream &stream, const xlnt::cell &cell)
@ -851,4 +960,37 @@ void cell::set_quote_prefix(bool b)
d_->quote_prefix_ = b;
}
void cell::guess_type_and_set_value(const std::string &value)
{
auto percentage = cast_percentage(value);
if (percentage.first)
{
d_->value_numeric_ = percentage.second;
d_->type_ = cell::type::numeric;
set_number_format(xlnt::number_format::percentage());
}
else
{
auto time = cast_time(value);
if (time.first)
{
d_->type_ = cell::type::numeric;
set_number_format(number_format::date_time6());
d_->value_numeric_ = time.second.to_number();
}
else
{
auto numeric = cast_numeric(value);
if (numeric.first)
{
d_->value_numeric_ = numeric.second;
d_->type_ = cell::type::numeric;
}
}
}
}
} // namespace xlnt

View File

@ -391,7 +391,7 @@ public:
void test_number_format()
{
auto ws = wb.create_sheet();
ws.get_parent().add_number_format(xlnt::number_format("dd--hh--mm"));
ws.get_workbook().add_number_format(xlnt::number_format("dd--hh--mm"));
xlnt::cell cell(ws, "A1");
cell.set_number_format(xlnt::number_format("dd--hh--mm"));

View File

@ -26,76 +26,6 @@
#include "cell_impl.hpp"
#include "comment_impl.hpp"
namespace {
std::pair<bool, long double> cast_numeric(const std::string &s)
{
const char *str = s.c_str();
char *str_end = nullptr;
auto result = std::strtold(str, &str_end);
if (str_end != str + s.size()) return { false, 0 };
return { true, result };
}
std::pair<bool, long double> cast_percentage(const std::string &s)
{
if (s.back() == '%')
{
auto number = cast_numeric(s.substr(0, s.size() - 1));
if (number.first)
{
return { true, number.second / 100 };
}
}
return { false, 0 };
}
std::pair<bool, xlnt::time> cast_time(const std::string &s)
{
xlnt::time result;
try
{
auto last_colon = s.find_last_of(':');
if (last_colon == std::string::npos) return { false, result };
double seconds = std::stod(s.substr(last_colon + 1));
result.second = static_cast<int>(seconds);
result.microsecond = static_cast<int>((seconds - static_cast<double>(result.second)) * 1e6);
auto first_colon = s.find_first_of(':');
if (first_colon == last_colon)
{
auto decimal_pos = s.find('.');
if (decimal_pos != std::string::npos)
{
result.minute = std::stoi(s.substr(0, first_colon));
}
else
{
result.hour = std::stoi(s.substr(0, first_colon));
result.minute = result.second;
result.second = 0;
}
}
else
{
result.hour = std::stoi(s.substr(0, first_colon));
result.minute = std::stoi(s.substr(first_colon + 1, last_colon - first_colon - 1));
}
}
catch (std::invalid_argument)
{
return { false, result };
}
return { true, result };
}
} // namespace
namespace xlnt {
namespace detail {
@ -130,7 +60,7 @@ cell_impl &cell_impl::operator=(const cell_impl &rhs)
{
parent_ = rhs.parent_;
value_numeric_ = rhs.value_numeric_;
value_string_ = rhs.value_string_;
value_text_ = rhs.value_text_;
hyperlink_ = rhs.hyperlink_;
formula_ = rhs.formula_;
column_ = rhs.column_;
@ -154,54 +84,5 @@ cell cell_impl::self()
return xlnt::cell(this);
}
void cell_impl::set_string(const std::string &s, bool guess_types)
{
value_string_ = s;
type_ = cell::type::string;
if (value_string_.size() > 1 && value_string_.front() == '=')
{
formula_ = value_string_;
type_ = cell::type::formula;
value_string_.clear();
}
else if (cell::error_codes().find(s) != cell::error_codes().end())
{
type_ = cell::type::error;
}
else if (guess_types)
{
auto percentage = cast_percentage(s);
if (percentage.first)
{
value_numeric_ = percentage.second;
type_ = cell::type::numeric;
self().set_number_format(xlnt::number_format::percentage());
}
else
{
auto time = cast_time(s);
if (time.first)
{
type_ = cell::type::numeric;
self().set_number_format(number_format::date_time6());
value_numeric_ = time.second.to_number();
}
else
{
auto numeric = cast_numeric(s);
if (numeric.first)
{
value_numeric_ = numeric.second;
type_ = cell::type::numeric;
}
}
}
}
}
} // namespace detail
} // namespace xlnt

View File

@ -25,6 +25,7 @@
#include <cstdlib>
#include <xlnt/cell/cell.hpp>
#include <xlnt/cell/text.hpp>
#include <xlnt/cell/comment.hpp>
#include <xlnt/cell/index_types.hpp>
#include <xlnt/utils/exceptions.hpp>
@ -52,8 +53,6 @@ struct cell_impl
cell self();
void set_string(const std::string &s, bool guess_types);
cell::type type_;
worksheet_impl *parent_;
@ -61,7 +60,7 @@ struct cell_impl
column_t column_;
row_t row_;
std::string value_string_;
text value_text_;
long double value_numeric_;
std::string formula_;

View File

@ -335,7 +335,7 @@ public:
auto ws = wb.get_active_sheet();
TS_ASSERT(ws.get_formula_attributes().empty());
TS_ASSERT(ws.get_parent().get_data_only());
TS_ASSERT(ws.get_workbook().get_data_only());
TS_ASSERT(ws.get_cell("A2").get_data_type() == xlnt::cell::type::numeric);
TS_ASSERT(ws.get_cell("A2").get_value<int>() == 12345);
TS_ASSERT(!ws.get_cell("A2").has_formula());

View File

@ -86,7 +86,7 @@ bool worksheet_serializer::read_worksheet(const xml_document &xml)
}
}
auto &shared_strings = sheet_.get_parent().get_shared_strings();
auto &shared_strings = sheet_.get_workbook().get_shared_strings();
for (auto row_node : sheet_data_node.get_children())
{
@ -158,7 +158,7 @@ bool worksheet_serializer::read_worksheet(const xml_document &xml)
auto cell = sheet_.get_cell(address);
if (has_formula && !has_shared_formula && !sheet_.get_parent().get_data_only())
if (has_formula && !has_shared_formula && !sheet_.get_workbook().get_data_only())
{
std::string formula = cell_node.get_child("f").get_text();
cell.set_formula(formula);
@ -365,7 +365,7 @@ xml_document worksheet_serializer::write_worksheet() const
std::unordered_map<std::string, std::string> hyperlink_references;
auto sheet_data_node = root_node.add_child("sheetData");
const auto &shared_strings = sheet_.get_parent().get_shared_strings();
const auto &shared_strings = sheet_.get_workbook().get_shared_strings();
for (auto row : sheet_.rows())
{

View File

@ -13,7 +13,7 @@ public:
{
xlnt::workbook wb;
xlnt::worksheet ws(wb);
TS_ASSERT(ws.get_parent() == wb);
TS_ASSERT(ws.get_workbook() == wb);
}
void test_get_cell()

View File

@ -71,7 +71,7 @@ bool worksheet::has_frozen_panes() const
std::string worksheet::unique_sheet_name(const std::string &value) const
{
auto names = get_parent().get_sheet_names();
auto names = get_workbook().get_sheet_names();
auto match = std::find(names.begin(), names.end(), value);
std::size_t append = 0;
while (match != names.end())
@ -164,11 +164,16 @@ std::string worksheet::to_string() const
return "<Worksheet \"" + d_->title_ + "\">";
}
workbook &worksheet::get_parent() const
workbook &worksheet::get_workbook()
{
return *d_->parent_;
}
const workbook &worksheet::get_workbook() const
{
return *d_->parent_;
}
void worksheet::garbage_collect()
{
auto cell_map_iter = d_->cell_map_.begin();
@ -313,7 +318,7 @@ bool worksheet::has_row_properties(row_t row) const
range worksheet::get_named_range(const std::string &name)
{
if (!get_parent().has_named_range(name))
if (!get_workbook().has_named_range(name))
{
throw key_error();
}

View File

@ -52,6 +52,8 @@ public:
xlnt::xml_document expected_xml;
expected_xml.from_string(expected_contents);
auto observed_string = observed.to_string();
return compare_xml(expected_xml.get_root(), observed.get_root());
}