mirror of
https://github.com/tfussell/xlnt.git
synced 2024-03-22 13:11:17 +08:00
general API improvements
This commit is contained in:
parent
720edc143f
commit
31b546b1d5
|
@ -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>
|
||||
|
|
62
include/xlnt/cell/text.cpp
Normal file
62
include/xlnt/cell/text.cpp
Normal 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
|
49
include/xlnt/cell/text.hpp
Normal file
49
include/xlnt/cell/text.hpp
Normal 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
|
46
include/xlnt/cell/text_run.cpp
Normal file
46
include/xlnt/cell/text_run.cpp
Normal 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
|
44
include/xlnt/cell/text_run.hpp
Normal file
44
include/xlnt/cell/text_run.hpp
Normal 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
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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"));
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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_;
|
||||
|
|
|
@ -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());
|
||||
|
|
|
@ -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())
|
||||
{
|
||||
|
|
|
@ -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()
|
||||
|
|
|
@ -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,7 +164,12 @@ 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_;
|
||||
}
|
||||
|
@ -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();
|
||||
}
|
||||
|
|
|
@ -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());
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue
Block a user