xlnt/source/cell/cell.cpp

821 lines
18 KiB
C++
Raw Normal View History

2015-12-25 06:10:02 +08:00
// 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
2014-05-22 05:48:51 +08:00
#include <algorithm>
2014-05-21 22:20:30 +08:00
#include <sstream>
2014-08-14 06:56:34 +08:00
#include <xlnt/cell/cell.hpp>
#include <xlnt/cell/cell_reference.hpp>
#include <xlnt/cell/comment.hpp>
2015-11-03 22:06:01 +08:00
#include <xlnt/packaging/document_properties.hpp>
#include <xlnt/packaging/relationship.hpp>
2015-11-23 01:41:27 +08:00
#include <xlnt/serialization/encoding.hpp>
#include <xlnt/styles/color.hpp>
2015-11-23 01:41:27 +08:00
#include <xlnt/styles/style.hpp>
#include <xlnt/utils/date.hpp>
#include <xlnt/utils/datetime.hpp>
#include <xlnt/utils/time.hpp>
#include <xlnt/utils/timedelta.hpp>
#include <xlnt/utils/exceptions.hpp>
#include <xlnt/utils/utf8string.hpp>
2014-08-14 06:56:34 +08:00
#include <xlnt/workbook/workbook.hpp>
#include <xlnt/worksheet/column_properties.hpp>
#include <xlnt/worksheet/row_properties.hpp>
2015-10-19 03:30:46 +08:00
#include <xlnt/worksheet/worksheet.hpp>
2014-08-14 06:56:34 +08:00
#include <detail/cell_impl.hpp>
#include <detail/comment_impl.hpp>
2014-05-21 22:20:30 +08:00
2014-07-26 04:39:25 +08:00
namespace xlnt {
const std::unordered_map<std::string, int> &cell::error_codes()
2015-10-30 01:46:56 +08:00
{
static const std::unordered_map<std::string, int> *codes =
new std::unordered_map<std::string, int>({ { "#NULL!", 0 }, { "#DIV/0!", 1 }, { "#VALUE!", 2 },
{ "#REF!", 3 }, { "#NAME?", 4 }, { "#NUM!", 5 },
2015-11-03 05:45:05 +08:00
{ "#N/A!", 6 } });
2015-11-03 05:45:05 +08:00
return *codes;
2014-07-26 04:39:25 +08:00
};
2014-05-21 22:20:30 +08:00
2015-11-23 01:41:27 +08:00
std::string cell::check_string(const std::string &to_check)
{
// so we can modify it
std::string s = to_check;
if (s.size() == 0)
{
return s;
}
auto wb_encoding = get_parent().get_parent().get_encoding();
//XXX: use utfcpp for this!
switch(wb_encoding)
{
case encoding::latin1: break; // all bytes are valid in latin1
case encoding::ascii:
for (char c : s)
{
if (c < 0)
{
throw xlnt::unicode_decode_error(c);
}
}
break;
case encoding::utf8:
{
if(!utf8string::is_valid(s))
2015-11-23 01:41:27 +08:00
{
throw xlnt::unicode_decode_error('0');
}
break;
}
case encoding::utf16:
{
if(!utf8string::from_utf16(s).is_valid())
2015-11-23 01:41:27 +08:00
{
throw xlnt::unicode_decode_error('0');
}
break;
}
case encoding::utf32:
{
if(!utf8string::from_utf32(s).is_valid())
{
throw xlnt::unicode_decode_error('0');
}
2015-11-23 01:41:27 +08:00
break;
}
default:
// other encodings not supported yet
break;
} // switch(wb_encoding)
// check encoding?
if (s.size() > 32767)
{
s = s.substr(0, 32767); // max string length in Excel
}
for (char c : s)
{
if (c >= 0 && (c <= 8 || c == 11 || c == 12 || (c >= 14 && c <= 31)))
{
throw xlnt::illegal_character_error(c);
}
}
return s;
}
2014-07-26 04:39:25 +08:00
cell::cell() : d_(nullptr)
2014-07-20 04:59:05 +08:00
{
}
2014-07-26 04:39:25 +08:00
cell::cell(detail::cell_impl *d) : d_(d)
2014-05-21 22:20:30 +08:00
{
}
2014-07-26 04:39:25 +08:00
cell::cell(worksheet worksheet, const cell_reference &reference) : d_(nullptr)
2014-05-21 22:20:30 +08:00
{
2014-07-26 04:39:25 +08:00
cell self = worksheet.get_cell(reference);
d_ = self.d_;
2014-05-21 22:20:30 +08:00
}
template <typename T>
cell::cell(worksheet worksheet, const cell_reference &reference, const T &initial_value) : cell(worksheet, reference)
2014-05-21 22:20:30 +08:00
{
2014-07-26 04:39:25 +08:00
set_value(initial_value);
2014-05-21 22:20:30 +08:00
}
2014-07-26 04:39:25 +08:00
bool cell::garbage_collectible() const
2014-05-21 22:20:30 +08:00
{
2015-10-24 02:42:36 +08:00
return !(get_data_type() != type::null || is_merged() || has_comment() || has_formula() || has_style());
2014-05-21 22:20:30 +08:00
}
template <>
2015-11-11 09:47:07 +08:00
XLNT_FUNCTION void cell::set_value(bool b)
2014-05-21 22:20:30 +08:00
{
d_->value_numeric_ = b ? 1 : 0;
d_->type_ = type::boolean;
2014-05-21 22:20:30 +08:00
}
template <>
2015-11-11 09:47:07 +08:00
XLNT_FUNCTION void cell::set_value(std::int8_t i)
2014-05-21 22:20:30 +08:00
{
d_->value_numeric_ = static_cast<long double>(i);
d_->type_ = type::numeric;
2014-05-21 22:20:30 +08:00
}
template <>
2015-11-11 09:47:07 +08:00
XLNT_FUNCTION void cell::set_value(std::int16_t i)
2014-05-31 06:42:25 +08:00
{
d_->value_numeric_ = static_cast<long double>(i);
d_->type_ = type::numeric;
2014-05-31 06:42:25 +08:00
}
template <>
2015-11-11 09:47:07 +08:00
XLNT_FUNCTION void cell::set_value(std::int32_t i)
{
d_->value_numeric_ = static_cast<long double>(i);
d_->type_ = type::numeric;
}
template <>
2015-11-11 09:47:07 +08:00
XLNT_FUNCTION void cell::set_value(std::int64_t i)
{
d_->value_numeric_ = static_cast<long double>(i);
d_->type_ = type::numeric;
}
template <>
2015-11-11 09:47:07 +08:00
XLNT_FUNCTION void cell::set_value(std::uint8_t i)
{
d_->value_numeric_ = static_cast<long double>(i);
d_->type_ = type::numeric;
}
template <>
2015-11-11 09:47:07 +08:00
XLNT_FUNCTION void cell::set_value(std::uint16_t i)
{
d_->value_numeric_ = static_cast<long double>(i);
d_->type_ = type::numeric;
}
template <>
2015-11-11 09:47:07 +08:00
XLNT_FUNCTION void cell::set_value(std::uint32_t i)
{
d_->value_numeric_ = static_cast<long double>(i);
d_->type_ = type::numeric;
}
template <>
2015-11-11 09:47:07 +08:00
XLNT_FUNCTION void cell::set_value(std::uint64_t i)
{
d_->value_numeric_ = static_cast<long double>(i);
d_->type_ = type::numeric;
}
2015-11-11 09:47:07 +08:00
#ifdef _MSC_VER
template <>
2015-11-11 09:47:07 +08:00
XLNT_FUNCTION void cell::set_value(unsigned long i)
{
d_->value_numeric_ = static_cast<long double>(i);
d_->type_ = type::numeric;
}
#endif
2015-10-17 07:46:21 +08:00
#ifdef __linux
template <>
2015-11-11 09:47:07 +08:00
XLNT_FUNCTION void cell::set_value(long long i)
2015-10-02 13:57:39 +08:00
{
d_->value_numeric_ = static_cast<long double>(i);
d_->type_ = type::numeric;
2015-10-02 13:57:39 +08:00
}
template <>
2015-11-11 09:47:07 +08:00
XLNT_FUNCTION void cell::set_value(unsigned long long i)
2015-10-02 13:57:39 +08:00
{
d_->value_numeric_ = static_cast<long double>(i);
d_->type_ = type::numeric;
2015-10-02 13:57:39 +08:00
}
#endif
2015-10-02 13:57:39 +08:00
template <>
2015-11-11 09:47:07 +08:00
XLNT_FUNCTION void cell::set_value(float f)
{
d_->value_numeric_ = static_cast<long double>(f);
d_->type_ = type::numeric;
}
template <>
2015-11-11 09:47:07 +08:00
XLNT_FUNCTION void cell::set_value(double d)
2014-05-31 06:42:25 +08:00
{
d_->value_numeric_ = static_cast<long double>(d);
d_->type_ = type::numeric;
2014-05-31 06:42:25 +08:00
}
template <>
2015-11-11 09:47:07 +08:00
XLNT_FUNCTION void cell::set_value(long double d)
{
d_->value_numeric_ = static_cast<long double>(d);
d_->type_ = type::numeric;
}
2014-05-31 06:42:25 +08:00
template <>
2015-11-11 09:47:07 +08:00
XLNT_FUNCTION void cell::set_value(std::string s)
{
2015-11-23 01:41:27 +08:00
d_->set_string(check_string(s), get_parent().get_parent().get_guess_types());
2015-11-03 03:22:13 +08:00
if (get_data_type() == type::string && !s.empty())
{
get_parent().get_parent().add_shared_string(s);
}
}
template <>
2015-11-11 09:47:07 +08:00
XLNT_FUNCTION void cell::set_value(char const *c)
{
set_value(std::string(c));
}
template <>
2015-11-11 09:47:07 +08:00
XLNT_FUNCTION void cell::set_value(cell c)
{
2015-10-15 06:05:13 +08:00
d_->type_ = c.d_->type_;
d_->value_numeric_ = c.d_->value_numeric_;
d_->value_string_ = c.d_->value_string_;
d_->hyperlink_ = c.d_->hyperlink_;
d_->has_hyperlink_ = c.d_->has_hyperlink_;
d_->formula_ = c.d_->formula_;
2015-10-19 03:30:46 +08:00
d_->style_id_ = c.d_->style_id_;
2015-10-15 06:05:13 +08:00
set_comment(c.get_comment());
}
template <>
2015-11-11 09:47:07 +08:00
XLNT_FUNCTION void cell::set_value(date d)
2014-05-21 22:20:30 +08:00
{
2015-10-19 03:30:46 +08:00
d_->type_ = type::numeric;
d_->value_numeric_ = d.to_number(get_base_date());
2015-10-24 02:42:36 +08:00
set_number_format(number_format::date_yyyymmdd2());
2014-05-21 22:20:30 +08:00
}
template <>
2015-11-11 09:47:07 +08:00
XLNT_FUNCTION void cell::set_value(datetime d)
2014-05-21 22:20:30 +08:00
{
2015-10-19 03:30:46 +08:00
d_->type_ = type::numeric;
d_->value_numeric_ = d.to_number(get_base_date());
2015-10-24 02:42:36 +08:00
set_number_format(number_format::date_datetime());
2014-05-21 22:20:30 +08:00
}
template <>
2015-11-11 09:47:07 +08:00
XLNT_FUNCTION void cell::set_value(time t)
2014-05-21 22:20:30 +08:00
{
2015-10-19 03:30:46 +08:00
d_->type_ = type::numeric;
d_->value_numeric_ = t.to_number();
2015-10-24 02:42:36 +08:00
set_number_format(number_format::date_time6());
2014-05-21 22:20:30 +08:00
}
template <>
2015-11-11 09:47:07 +08:00
XLNT_FUNCTION void cell::set_value(timedelta t)
2014-05-21 22:20:30 +08:00
{
2015-10-19 03:30:46 +08:00
d_->type_ = type::numeric;
d_->value_numeric_ = t.to_number();
2015-10-24 02:42:36 +08:00
set_number_format(number_format::date_timedelta());
2014-05-21 22:20:30 +08:00
}
2014-07-26 04:39:25 +08:00
row_t cell::get_row() const
2014-05-21 22:20:30 +08:00
{
return d_->row_;
2014-05-21 22:20:30 +08:00
}
column_t cell::get_column() const
2014-05-21 22:20:30 +08:00
{
return d_->column_;
2014-05-21 22:20:30 +08:00
}
2014-07-26 04:39:25 +08:00
void cell::set_merged(bool merged)
2014-06-05 06:42:17 +08:00
{
d_->is_merged_ = merged;
2014-06-05 06:42:17 +08:00
}
2014-07-26 04:39:25 +08:00
bool cell::is_merged() const
2014-06-11 05:12:15 +08:00
{
return d_->is_merged_;
2014-06-11 05:12:15 +08:00
}
2014-07-26 04:39:25 +08:00
bool cell::is_date() const
2014-06-05 06:42:17 +08:00
{
return get_data_type() == type::numeric && get_number_format().is_date_format();
2014-06-05 06:42:17 +08:00
}
2014-07-26 04:39:25 +08:00
cell_reference cell::get_reference() const
2014-05-21 22:20:30 +08:00
{
return { d_->column_, d_->row_ };
2014-05-21 22:20:30 +08:00
}
2014-07-26 04:39:25 +08:00
bool cell::operator==(std::nullptr_t) const
2014-07-25 05:31:46 +08:00
{
2014-07-26 04:39:25 +08:00
return d_ == nullptr;
2014-07-25 05:31:46 +08:00
}
2014-05-21 22:20:30 +08:00
2014-07-26 04:39:25 +08:00
bool cell::operator==(const cell &comparand) const
2014-05-21 22:20:30 +08:00
{
return d_ == comparand.d_;
2014-05-21 22:20:30 +08:00
}
2014-07-26 04:39:25 +08:00
cell &cell::operator=(const cell &rhs)
2014-05-31 06:42:25 +08:00
{
*d_ = *rhs.d_;
2014-05-21 22:20:30 +08:00
return *this;
}
bool operator<(cell left, cell right)
2014-07-20 04:59:05 +08:00
{
2014-07-26 04:39:25 +08:00
return left.get_reference() < right.get_reference();
2014-07-20 04:59:05 +08:00
}
std::string cell::to_repr() const
2014-05-21 22:20:30 +08:00
{
2014-06-06 05:42:15 +08:00
return "<Cell " + worksheet(d_->parent_).get_title() + "." + get_reference().to_string() + ">";
2014-05-21 22:20:30 +08:00
}
2014-06-11 05:12:15 +08:00
relationship cell::get_hyperlink() const
{
if (!d_->has_hyperlink_)
2014-06-11 05:12:15 +08:00
{
throw std::runtime_error("no hyperlink set");
}
return d_->hyperlink_;
}
bool cell::has_hyperlink() const
{
return d_->has_hyperlink_;
}
2014-05-21 22:20:30 +08:00
void cell::set_hyperlink(const std::string &hyperlink)
2014-06-11 05:12:15 +08:00
{
if (hyperlink.length() == 0 || std::find(hyperlink.begin(), hyperlink.end(), ':') == hyperlink.end())
2014-06-11 05:12:15 +08:00
{
throw data_type_exception();
}
d_->has_hyperlink_ = true;
2014-07-20 02:43:48 +08:00
d_->hyperlink_ = worksheet(d_->parent_).create_relationship(relationship::type::hyperlink, hyperlink);
2014-06-11 05:12:15 +08:00
if (get_data_type() == type::null)
2014-06-11 05:12:15 +08:00
{
2014-07-26 04:39:25 +08:00
set_value(hyperlink);
2014-06-11 05:12:15 +08:00
}
}
void cell::set_formula(const std::string &formula)
2014-06-11 05:12:15 +08:00
{
if (formula.length() == 0)
2014-07-25 05:31:46 +08:00
{
throw data_type_exception();
}
if (formula[0] == '=')
{
d_->formula_ = formula.substr(1);
}
else
{
d_->formula_ = formula;
}
2014-07-25 05:31:46 +08:00
}
bool cell::has_formula() const
{
2014-07-26 04:39:25 +08:00
return !d_->formula_.empty();
2014-07-25 05:31:46 +08:00
}
std::string cell::get_formula() const
2014-07-25 05:31:46 +08:00
{
if (d_->formula_.empty())
2014-06-11 05:12:15 +08:00
{
throw data_type_exception();
}
2014-07-26 04:39:25 +08:00
return d_->formula_;
2014-07-25 05:31:46 +08:00
}
void cell::clear_formula()
{
2014-07-26 04:39:25 +08:00
d_->formula_.clear();
2014-06-11 05:12:15 +08:00
}
2014-05-31 06:42:25 +08:00
void cell::set_comment(const xlnt::comment &c)
2014-07-20 02:43:48 +08:00
{
if (c.d_ != d_->comment_.get())
{
throw xlnt::attribute_error();
}
if (!has_comment())
{
get_parent().increment_comments();
}
*get_comment().d_ = *c.d_;
2014-07-20 02:43:48 +08:00
}
void cell::clear_comment()
{
if (has_comment())
2014-07-20 02:43:48 +08:00
{
get_parent().decrement_comments();
2014-07-20 02:43:48 +08:00
}
d_->comment_ = nullptr;
2014-07-20 02:43:48 +08:00
}
2014-07-25 05:31:46 +08:00
bool cell::has_comment() const
{
return d_->comment_ != nullptr;
2014-07-25 05:31:46 +08:00
}
void cell::set_error(const std::string &error)
2014-06-11 05:12:15 +08:00
{
if (error.length() == 0 || error[0] != '#')
2014-06-11 05:12:15 +08:00
{
throw data_type_exception();
}
d_->value_string_ = error;
d_->type_ = type::error;
2014-06-11 05:12:15 +08:00
}
2014-05-31 06:42:25 +08:00
cell cell::offset(int column, int row)
2014-07-20 02:43:48 +08:00
{
2014-07-26 04:39:25 +08:00
return get_parent().get_cell(cell_reference(d_->column_ + column, d_->row_ + row));
2014-07-20 02:43:48 +08:00
}
2014-07-20 02:43:48 +08:00
worksheet cell::get_parent()
{
return worksheet(d_->parent_);
}
2014-07-26 04:39:25 +08:00
const worksheet cell::get_parent() const
{
return worksheet(d_->parent_);
}
comment cell::get_comment()
2014-07-20 02:43:48 +08:00
{
if (d_->comment_ == nullptr)
{
d_->comment_.reset(new detail::comment_impl());
get_parent().increment_comments();
}
return comment(d_->comment_.get());
2014-07-20 02:43:48 +08:00
}
2015-11-03 05:45:05 +08:00
//TODO: this shares a lot of code with worksheet::get_point_pos, try to reduce repition
2014-07-26 04:39:25 +08:00
std::pair<int, int> cell::get_anchor() const
{
static const double DefaultColumnWidth = 51.85;
static const double DefaultRowHeight = 15.0;
2015-11-03 05:45:05 +08:00
auto points_to_pixels = [](long double value, long double dpi)
{
return static_cast<int>(std::ceil(value * dpi / 72));
};
auto left_columns = d_->column_ - 1;
2014-07-26 04:39:25 +08:00
int left_anchor = 0;
auto default_width = points_to_pixels(DefaultColumnWidth, 96.0);
for (column_t column_index = 1; column_index <= left_columns; column_index++)
2014-07-26 04:39:25 +08:00
{
if (get_parent().has_column_properties(column_index))
2014-07-26 04:39:25 +08:00
{
2015-10-29 03:08:54 +08:00
auto cdw = get_parent().get_column_properties(column_index).width;
2014-07-26 04:39:25 +08:00
if (cdw > 0)
2014-07-26 04:39:25 +08:00
{
left_anchor += points_to_pixels(cdw, 96.0);
continue;
}
}
left_anchor += default_width;
}
auto top_rows = d_->row_ - 1;
2014-07-26 04:39:25 +08:00
int top_anchor = 0;
auto default_height = points_to_pixels(DefaultRowHeight, 96.0);
2015-11-03 05:45:05 +08:00
for (row_t row_index = 1; row_index <= top_rows; row_index++)
2014-07-26 04:39:25 +08:00
{
if (get_parent().has_row_properties(row_index))
2014-07-26 04:39:25 +08:00
{
2015-10-29 03:08:54 +08:00
auto rdh = get_parent().get_row_properties(row_index).height;
2014-07-26 04:39:25 +08:00
if (rdh > 0)
2014-07-26 04:39:25 +08:00
{
top_anchor += points_to_pixels(rdh, 96.0);
continue;
}
}
top_anchor += default_height;
}
return { left_anchor, top_anchor };
2014-07-26 04:39:25 +08:00
}
cell::type cell::get_data_type() const
{
return d_->type_;
}
void cell::set_data_type(type t)
{
d_->type_ = t;
}
2015-10-19 03:30:46 +08:00
const number_format &cell::get_number_format() const
{
if (d_->has_style_)
2015-10-21 01:53:47 +08:00
{
return get_parent().get_parent().get_number_format(d_->style_id_);
}
else
{
return get_parent().get_parent().get_number_formats().front();
}
}
2015-10-19 03:30:46 +08:00
const font &cell::get_font() const
{
2015-11-23 01:41:27 +08:00
if (d_->has_style_)
{
auto font_id = get_parent().get_parent().get_styles()[d_->style_id_].get_font_id();
return get_parent().get_parent().get_font(font_id);
}
else
{
return get_parent().get_parent().get_font(0);
}
}
const fill &cell::get_fill() const
{
2015-10-19 03:30:46 +08:00
return get_parent().get_parent().get_fill(d_->style_id_);
}
2015-10-19 03:30:46 +08:00
const border &cell::get_border() const
{
2015-10-19 03:30:46 +08:00
return get_parent().get_parent().get_border(d_->style_id_);
}
2015-10-19 03:30:46 +08:00
const alignment &cell::get_alignment() const
{
2015-10-19 03:30:46 +08:00
return get_parent().get_parent().get_alignment(d_->style_id_);
}
2015-10-19 03:30:46 +08:00
const protection &cell::get_protection() const
{
2015-10-19 03:30:46 +08:00
return get_parent().get_parent().get_protection(d_->style_id_);
}
2015-10-19 03:30:46 +08:00
bool cell::pivot_button() const
{
2015-10-19 03:30:46 +08:00
return get_parent().get_parent().get_pivot_button(d_->style_id_);
}
2015-10-19 03:30:46 +08:00
bool cell::quote_prefix() const
{
2015-10-19 03:30:46 +08:00
return get_parent().get_parent().get_quote_prefix(d_->style_id_);
}
void cell::clear_value()
{
d_->value_numeric_ = 0;
d_->value_string_.clear();
d_->formula_.clear();
d_->type_ = cell::type::null;
}
template <>
2015-11-11 09:47:07 +08:00
XLNT_FUNCTION bool cell::get_value() const
{
return d_->value_numeric_ != 0;
}
template <>
2015-11-11 09:47:07 +08:00
XLNT_FUNCTION std::int8_t cell::get_value() const
{
return static_cast<std::int8_t>(d_->value_numeric_);
}
template <>
2015-11-11 09:47:07 +08:00
XLNT_FUNCTION std::int16_t cell::get_value() const
{
return static_cast<std::int16_t>(d_->value_numeric_);
}
template <>
2015-11-11 09:47:07 +08:00
XLNT_FUNCTION std::int32_t cell::get_value() const
{
return static_cast<std::int32_t>(d_->value_numeric_);
}
template <>
2015-11-11 09:47:07 +08:00
XLNT_FUNCTION std::int64_t cell::get_value() const
{
return static_cast<std::int64_t>(d_->value_numeric_);
}
template <>
2015-11-11 09:47:07 +08:00
XLNT_FUNCTION std::uint8_t cell::get_value() const
{
return static_cast<std::uint8_t>(d_->value_numeric_);
}
template <>
2015-11-11 09:47:07 +08:00
XLNT_FUNCTION std::uint16_t cell::get_value() const
{
return static_cast<std::uint16_t>(d_->value_numeric_);
}
template <>
2015-11-11 09:47:07 +08:00
XLNT_FUNCTION std::uint32_t cell::get_value() const
{
return static_cast<std::uint32_t>(d_->value_numeric_);
}
template <>
2015-11-11 09:47:07 +08:00
XLNT_FUNCTION std::uint64_t cell::get_value() const
{
return static_cast<std::uint64_t>(d_->value_numeric_);
}
2015-10-17 07:46:21 +08:00
#ifdef __linux
template <>
2015-11-11 09:47:07 +08:00
XLNT_FUNCTION long long int cell::get_value() const
2015-10-17 07:46:21 +08:00
{
return static_cast<long long int>(d_->value_numeric_);
}
#endif
template <>
2015-11-11 09:47:07 +08:00
XLNT_FUNCTION float cell::get_value() const
{
return static_cast<float>(d_->value_numeric_);
}
template <>
2015-11-11 09:47:07 +08:00
XLNT_FUNCTION double cell::get_value() const
{
return static_cast<double>(d_->value_numeric_);
}
template <>
2015-11-11 09:47:07 +08:00
XLNT_FUNCTION long double cell::get_value() const
{
return d_->value_numeric_;
}
template <>
2015-11-11 09:47:07 +08:00
XLNT_FUNCTION time cell::get_value() const
{
return time::from_number(d_->value_numeric_);
}
template <>
2015-11-11 09:47:07 +08:00
XLNT_FUNCTION datetime cell::get_value() const
{
2015-10-19 03:30:46 +08:00
return datetime::from_number(d_->value_numeric_, get_base_date());
}
template <>
2015-11-11 09:47:07 +08:00
XLNT_FUNCTION date cell::get_value() const
{
2015-10-19 03:30:46 +08:00
return date::from_number(static_cast<int>(d_->value_numeric_), get_base_date());
}
template <>
2015-11-11 09:47:07 +08:00
XLNT_FUNCTION timedelta cell::get_value() const
{
2015-10-19 03:30:46 +08:00
return timedelta::from_number(d_->value_numeric_);
}
2015-11-23 01:41:27 +08:00
void cell::set_font(const font &font_)
{
d_->has_style_ = true;
d_->style_id_ = get_parent().get_parent().set_font(font_, d_->style_id_);
}
2015-10-19 03:30:46 +08:00
void cell::set_number_format(const number_format &number_format_)
{
2015-10-21 01:53:47 +08:00
d_->has_style_ = true;
2015-10-19 03:30:46 +08:00
d_->style_id_ = get_parent().get_parent().set_number_format(number_format_, d_->style_id_);
}
template <>
2015-11-11 09:47:07 +08:00
XLNT_FUNCTION std::string cell::get_value() const
{
return d_->value_string_;
}
bool cell::has_value() const
{
return d_->type_ != cell::type::null;
}
std::string cell::to_string() const
{
2015-10-19 03:30:46 +08:00
auto nf = get_number_format();
switch (get_data_type())
{
case cell::type::null:
return "";
case cell::type::numeric:
return get_number_format().format(get_value<long double>(), get_base_date());
case cell::type::string:
case cell::type::formula:
case cell::type::error:
return get_number_format().format(get_value<std::string>());
case cell::type::boolean:
return get_value<long double>() == 0 ? "FALSE" : "TRUE";
default:
return "";
}
}
2015-10-19 03:30:46 +08:00
std::size_t cell::get_style_id() const
{
return d_->style_id_;
}
2015-10-24 02:42:36 +08:00
bool cell::has_style() const
{
return d_->has_style_;
}
void cell::set_style_id(std::size_t style_id)
{
d_->style_id_ = style_id;
d_->has_style_ = true;
}
2015-10-19 03:30:46 +08:00
calendar cell::get_base_date() const
{
return get_parent().get_parent().get_properties().excel_base_date;
}
std::ostream &operator<<(std::ostream &stream, const xlnt::cell &cell)
{
return stream << cell.to_string();
}
2014-05-31 06:42:25 +08:00
} // namespace xlnt