mirror of
https://github.com/tfussell/xlnt.git
synced 2024-03-22 13:11:17 +08:00
replace pugiconfig.hpp with local header, fix some constness, dry up code
This commit is contained in:
parent
06fcc6f3d0
commit
7316e2184c
|
@ -92,6 +92,7 @@ public:
|
|||
// characteristics
|
||||
bool garbage_collectible() const;
|
||||
bool is_date() const;
|
||||
std::size_t get_xf_index() const;
|
||||
|
||||
// position
|
||||
cell_reference get_reference() const;
|
||||
|
@ -110,16 +111,24 @@ public:
|
|||
style &get_style();
|
||||
const style &get_style() const;
|
||||
void set_style(const style &s);
|
||||
|
||||
// style shortcuts
|
||||
std::string get_number_format();
|
||||
std::string get_number_format() const;
|
||||
void set_number_format(const std::string &format_code);
|
||||
std::size_t get_xf_index() const;
|
||||
font get_font() const;
|
||||
font &get_font();
|
||||
const font &get_font() const;
|
||||
fill &get_fill();
|
||||
const fill &get_fill() const;
|
||||
border get_border() const;
|
||||
alignment get_alignment() const;
|
||||
protection get_protection() const;
|
||||
border &get_border();
|
||||
const border &get_border() const;
|
||||
alignment &get_alignment();
|
||||
const alignment &get_alignment() const;
|
||||
protection &get_protection();
|
||||
const protection &get_protection() const;
|
||||
bool pivot_button();
|
||||
bool pivot_button() const;
|
||||
bool quote_prefix();
|
||||
bool quote_prefix() const;
|
||||
|
||||
// comment
|
||||
|
|
|
@ -41,30 +41,34 @@ public:
|
|||
|
||||
style copy() const;
|
||||
|
||||
font get_font() const;
|
||||
font &get_font();
|
||||
const font &get_font() const;
|
||||
void set_font(font font);
|
||||
|
||||
fill &get_fill();
|
||||
const fill &get_fill() const;
|
||||
void set_fill(fill &fill);
|
||||
|
||||
border get_border() const;
|
||||
border &get_border();
|
||||
const border &get_border() const;
|
||||
void set_border(border borders);
|
||||
|
||||
alignment get_alignment() const;
|
||||
alignment &get_alignment();
|
||||
const alignment get_alignment() const;
|
||||
void set_alignment(alignment alignment);
|
||||
|
||||
number_format &get_number_format() { return number_format_; }
|
||||
const number_format &get_number_format() const { return number_format_; }
|
||||
void set_number_format(number_format number_format);
|
||||
|
||||
protection get_protection() const;
|
||||
protection &get_protection();
|
||||
const protection &get_protection() const;
|
||||
void set_protection(protection protection);
|
||||
|
||||
bool pivot_button() const;
|
||||
bool pivot_button();
|
||||
void set_pivot_button(bool pivot);
|
||||
|
||||
bool quote_prefix() const;
|
||||
bool quote_prefix();
|
||||
void set_quote_prefix(bool quote);
|
||||
|
||||
private:
|
||||
|
|
|
@ -278,6 +278,7 @@ public:
|
|||
// extents
|
||||
row_t get_lowest_row() const;
|
||||
row_t get_highest_row() const;
|
||||
row_t get_next_row() const;
|
||||
column_t get_lowest_column() const;
|
||||
column_t get_highest_column() const;
|
||||
range_reference calculate_dimension() const;
|
||||
|
@ -297,6 +298,7 @@ public:
|
|||
std::vector<range_reference> get_merged_ranges() const;
|
||||
|
||||
// append
|
||||
void append();
|
||||
void append(const std::vector<std::string> &cells);
|
||||
void append(const std::vector<int> &cells);
|
||||
void append(const std::vector<date> &cells);
|
||||
|
|
211
source/cell.cpp
211
source/cell.cpp
|
@ -16,102 +16,6 @@
|
|||
#include "detail/cell_impl.hpp"
|
||||
#include "detail/comment_impl.hpp"
|
||||
|
||||
namespace {
|
||||
|
||||
// return s after checking encoding, size, and illegal characters
|
||||
std::string check_string(std::string s)
|
||||
{
|
||||
if (s.size() == 0)
|
||||
{
|
||||
return s;
|
||||
}
|
||||
|
||||
// check encoding?
|
||||
|
||||
if (s.size() > 32767)
|
||||
{
|
||||
s = s.substr(0, 32767); // max string length in Excel
|
||||
}
|
||||
|
||||
for (unsigned char c : s)
|
||||
{
|
||||
if (c <= 8 || c == 11 || c == 12 || (c >= 14 && c <= 31))
|
||||
{
|
||||
throw xlnt::illegal_character_error(static_cast<char>(c));
|
||||
}
|
||||
}
|
||||
|
||||
return s;
|
||||
}
|
||||
|
||||
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 xlnt::color xlnt::color::black(0);
|
||||
|
@ -278,7 +182,7 @@ void cell::set_value(long double d)
|
|||
template<>
|
||||
void cell::set_value(std::string s)
|
||||
{
|
||||
set_value_guess_type(s);
|
||||
d_->set_string(s, get_parent().get_parent().get_guess_types());
|
||||
}
|
||||
|
||||
template<>
|
||||
|
@ -286,101 +190,39 @@ void cell::set_value(char const *c)
|
|||
{
|
||||
set_value(std::string(c));
|
||||
}
|
||||
|
||||
template<>
|
||||
void cell::set_value(cell c)
|
||||
{
|
||||
}
|
||||
|
||||
template<>
|
||||
void cell::set_value(date d)
|
||||
{
|
||||
d_->is_date_ = true;
|
||||
auto code = xlnt::number_format::format::date_yyyymmdd2;
|
||||
auto number_format = xlnt::number_format(code);
|
||||
get_style().set_number_format(number_format);
|
||||
auto base_date = get_parent().get_parent().get_properties().excel_base_date;
|
||||
d_->value_numeric_ = d.to_number(base_date);
|
||||
d_->type_ = type::numeric;
|
||||
d_->set_date(d.to_number(base_date), xlnt::number_format::format::date_yyyymmdd2);
|
||||
}
|
||||
|
||||
template<>
|
||||
void cell::set_value(datetime d)
|
||||
{
|
||||
d_->is_date_ = true;
|
||||
auto code = xlnt::number_format::format::date_datetime;
|
||||
auto number_format = xlnt::number_format(code);
|
||||
get_style().set_number_format(number_format);
|
||||
auto base_date = get_parent().get_parent().get_properties().excel_base_date;
|
||||
d_->value_numeric_ = d.to_number(base_date);
|
||||
d_->type_ = type::numeric;
|
||||
d_->set_date(d.to_number(base_date), xlnt::number_format::format::date_datetime);
|
||||
}
|
||||
|
||||
template<>
|
||||
void cell::set_value(time t)
|
||||
{
|
||||
d_->is_date_ = true;
|
||||
auto code = xlnt::number_format::format::date_time6;
|
||||
auto number_format = xlnt::number_format(code);
|
||||
get_style().set_number_format(number_format);
|
||||
d_->value_numeric_ = t.to_number();
|
||||
d_->type_ = type::numeric;
|
||||
d_->set_date(t.to_number(), xlnt::number_format::format::date_time6);
|
||||
}
|
||||
|
||||
template<>
|
||||
void cell::set_value(timedelta t)
|
||||
{
|
||||
auto code = xlnt::number_format::format::date_timedelta;
|
||||
auto number_format = xlnt::number_format(code);
|
||||
get_style().set_number_format(number_format);
|
||||
d_->value_numeric_ = t.to_number();
|
||||
d_->type_ = type::numeric;
|
||||
d_->set_date(t.to_number(), xlnt::number_format::format::date_timedelta);
|
||||
d_->is_date_ = false; // a timedelta isn't actually a date, still uses mostly the same code
|
||||
}
|
||||
|
||||
void cell::set_value_guess_type(const std::string &s)
|
||||
{
|
||||
d_->is_date_ = false;
|
||||
auto temp = check_string(s);
|
||||
d_->value_string_ = temp;
|
||||
d_->type_ = type::string;
|
||||
|
||||
if (temp.size() > 1 && temp.front() == '=')
|
||||
{
|
||||
d_->formula_ = temp;
|
||||
d_->type_ = type::formula;
|
||||
d_->value_string_.clear();
|
||||
}
|
||||
else if(ErrorCodes.find(s) != ErrorCodes.end())
|
||||
{
|
||||
d_->value_string_ = s;
|
||||
d_->type_ = type::error;
|
||||
}
|
||||
else if(get_parent().get_parent().get_guess_types())
|
||||
{
|
||||
auto percentage = cast_percentage(s);
|
||||
|
||||
if (percentage.first)
|
||||
{
|
||||
d_->value_numeric_ = percentage.second;
|
||||
d_->type_ = type::numeric;
|
||||
get_style().get_number_format().set_format_code(xlnt::number_format::format::percentage);
|
||||
}
|
||||
else
|
||||
{
|
||||
auto time = cast_time(s);
|
||||
|
||||
if (time.first)
|
||||
{
|
||||
set_value(time.second);
|
||||
}
|
||||
else
|
||||
{
|
||||
auto numeric = cast_numeric(s);
|
||||
|
||||
if (numeric.first)
|
||||
{
|
||||
set_value(numeric.second);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bool cell::has_style() const
|
||||
{
|
||||
return d_->style_ != nullptr;
|
||||
|
@ -428,22 +270,12 @@ bool cell::operator==(const cell &comparand) const
|
|||
|
||||
style &cell::get_style()
|
||||
{
|
||||
if(d_->style_ == nullptr)
|
||||
{
|
||||
d_->style_.reset(new style());
|
||||
}
|
||||
|
||||
return *d_->style_;
|
||||
return d_->get_style(true);
|
||||
}
|
||||
|
||||
const style &cell::get_style() const
|
||||
{
|
||||
if(d_->style_ == nullptr)
|
||||
{
|
||||
d_->style_.reset(new style());
|
||||
}
|
||||
|
||||
return *d_->style_;
|
||||
return d_->get_style();
|
||||
}
|
||||
|
||||
void cell::set_style(const xlnt::style &s)
|
||||
|
@ -662,12 +494,17 @@ std::size_t cell::get_xf_index() const
|
|||
return d_->xf_index_;
|
||||
}
|
||||
|
||||
std::string cell::get_number_format()
|
||||
{
|
||||
return get_style().get_number_format().get_format_code_string();
|
||||
}
|
||||
|
||||
std::string cell::get_number_format() const
|
||||
{
|
||||
return get_style().get_number_format().get_format_code_string();
|
||||
}
|
||||
|
||||
font cell::get_font() const
|
||||
font &cell::get_font()
|
||||
{
|
||||
return get_style().get_font();
|
||||
}
|
||||
|
@ -682,27 +519,27 @@ const fill &cell::get_fill() const
|
|||
return get_style().get_fill();
|
||||
}
|
||||
|
||||
border cell::get_border() const
|
||||
border &cell::get_border()
|
||||
{
|
||||
return get_style().get_border();
|
||||
}
|
||||
|
||||
alignment cell::get_alignment() const
|
||||
alignment &cell::get_alignment()
|
||||
{
|
||||
return get_style().get_alignment();
|
||||
}
|
||||
|
||||
protection cell::get_protection() const
|
||||
protection &cell::get_protection()
|
||||
{
|
||||
return get_style().get_protection();
|
||||
}
|
||||
|
||||
bool cell::pivot_button() const
|
||||
bool cell::pivot_button()
|
||||
{
|
||||
return get_style().pivot_button();
|
||||
}
|
||||
|
||||
bool cell::quote_prefix() const
|
||||
bool cell::quote_prefix()
|
||||
{
|
||||
return get_style().quote_prefix();
|
||||
}
|
||||
|
|
|
@ -1,12 +1,112 @@
|
|||
#pragma once
|
||||
|
||||
#include <cstdlib>
|
||||
|
||||
#include <xlnt/cell/cell.hpp>
|
||||
#include <xlnt/cell/comment.hpp>
|
||||
#include <xlnt/common/exceptions.hpp>
|
||||
#include <xlnt/common/datetime.hpp>
|
||||
#include <xlnt/common/types.hpp>
|
||||
#include <xlnt/common/relationship.hpp>
|
||||
|
||||
#include "comment_impl.hpp"
|
||||
|
||||
namespace {
|
||||
|
||||
// return s after checking encoding, size, and illegal characters
|
||||
std::string check_string(std::string s)
|
||||
{
|
||||
if (s.size() == 0)
|
||||
{
|
||||
return s;
|
||||
}
|
||||
|
||||
// check encoding?
|
||||
|
||||
if (s.size() > 32767)
|
||||
{
|
||||
s = s.substr(0, 32767); // max string length in Excel
|
||||
}
|
||||
|
||||
for (unsigned char c : s)
|
||||
{
|
||||
if (c <= 8 || c == 11 || c == 12 || (c >= 14 && c <= 31))
|
||||
{
|
||||
throw xlnt::illegal_character_error(static_cast<char>(c));
|
||||
}
|
||||
}
|
||||
|
||||
return s;
|
||||
}
|
||||
|
||||
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 {
|
||||
|
||||
class style;
|
||||
|
@ -22,7 +122,85 @@ struct cell_impl
|
|||
cell_impl(worksheet_impl *parent, column_t column, row_t row);
|
||||
cell_impl(const cell_impl &rhs);
|
||||
cell_impl &operator=(const cell_impl &rhs);
|
||||
|
||||
style &get_style(bool create_if_null)
|
||||
{
|
||||
if(style_ == nullptr && create_if_null)
|
||||
{
|
||||
style_.reset(new style());
|
||||
}
|
||||
|
||||
return *style_;
|
||||
}
|
||||
|
||||
const style &get_style() const
|
||||
{
|
||||
if(style_ == nullptr)
|
||||
{
|
||||
throw std::runtime_error("call has_style to check if const cell has a style before accessing it");
|
||||
}
|
||||
|
||||
return *style_;
|
||||
}
|
||||
|
||||
void set_date(long double number, xlnt::number_format::format format_code)
|
||||
{
|
||||
is_date_ = true;
|
||||
auto number_format = xlnt::number_format(format_code);
|
||||
get_style(true).set_number_format(number_format);
|
||||
value_numeric_ = number;
|
||||
type_ = cell::type::numeric;
|
||||
}
|
||||
|
||||
void set_string(const std::string &s, bool guess_types)
|
||||
{
|
||||
is_date_ = false;
|
||||
value_string_ = check_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::ErrorCodes.find(s) != cell::ErrorCodes.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;
|
||||
get_style(true).get_number_format().set_format_code(xlnt::number_format::format::percentage);
|
||||
}
|
||||
else
|
||||
{
|
||||
auto time = cast_time(s);
|
||||
|
||||
if (time.first)
|
||||
{
|
||||
set_date(time.second.to_number(), xlnt::number_format::format::date_time6);
|
||||
}
|
||||
else
|
||||
{
|
||||
auto numeric = cast_numeric(s);
|
||||
|
||||
if (numeric.first)
|
||||
{
|
||||
value_numeric_ = numeric.second;
|
||||
type_ = cell::type::numeric;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
cell::type type_;
|
||||
|
||||
worksheet_impl *parent_;
|
||||
|
|
8
source/detail/include_pugixml.hpp
Normal file
8
source/detail/include_pugixml.hpp
Normal file
|
@ -0,0 +1,8 @@
|
|||
#pragma once
|
||||
|
||||
/// <summary>
|
||||
/// Define this here so we don't have to modify pugiconfig.hpp in pugixml source tree.
|
||||
/// </summary>
|
||||
#define PUGIXML_HAS_LONG_LONG
|
||||
|
||||
#include <pugixml.hpp>
|
|
@ -16,22 +16,22 @@ void style::set_number_format(xlnt::number_format format)
|
|||
number_format_ = format;
|
||||
}
|
||||
|
||||
border style::get_border() const
|
||||
border &style::get_border()
|
||||
{
|
||||
return border_;
|
||||
}
|
||||
|
||||
bool style::pivot_button() const
|
||||
bool style::pivot_button()
|
||||
{
|
||||
return pivot_button_;
|
||||
}
|
||||
|
||||
bool style::quote_prefix() const
|
||||
bool style::quote_prefix()
|
||||
{
|
||||
return quote_prefix_;
|
||||
}
|
||||
|
||||
alignment style::get_alignment() const
|
||||
alignment &style::get_alignment()
|
||||
{
|
||||
return alignment_;
|
||||
}
|
||||
|
@ -46,12 +46,12 @@ const fill &style::get_fill() const
|
|||
return fill_;
|
||||
}
|
||||
|
||||
font style::get_font() const
|
||||
font &style::get_font()
|
||||
{
|
||||
return font_;
|
||||
}
|
||||
|
||||
protection style::get_protection() const
|
||||
protection &style::get_protection()
|
||||
{
|
||||
return protection_;
|
||||
}
|
||||
|
|
|
@ -3,7 +3,6 @@
|
|||
#include <fstream>
|
||||
#include <set>
|
||||
#include <sstream>
|
||||
#include <pugixml.hpp>
|
||||
|
||||
#ifdef _WIN32
|
||||
#include <Windows.h>
|
||||
|
@ -22,10 +21,13 @@
|
|||
#include <xlnt/writer/style_writer.hpp>
|
||||
|
||||
#include "detail/cell_impl.hpp"
|
||||
#include "detail/include_pugixml.hpp"
|
||||
#include "detail/workbook_impl.hpp"
|
||||
#include "detail/worksheet_impl.hpp"
|
||||
|
||||
static std::string CreateTemporaryFilename()
|
||||
namespace {
|
||||
|
||||
static std::string create_temporary_filename()
|
||||
{
|
||||
#ifdef _WIN32
|
||||
std::array<TCHAR, MAX_PATH> buffer;
|
||||
|
@ -44,6 +46,8 @@ static std::string CreateTemporaryFilename()
|
|||
return "/tmp/xlsx.xlnt";
|
||||
#endif
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
namespace xlnt {
|
||||
namespace detail {
|
||||
|
@ -258,30 +262,39 @@ range workbook::get_named_range(const std::string &name)
|
|||
|
||||
bool workbook::load(const std::istream &stream)
|
||||
{
|
||||
std::string temp_file = CreateTemporaryFilename();
|
||||
std::string temp_file = create_temporary_filename();
|
||||
|
||||
std::ofstream tmp;
|
||||
|
||||
tmp.open(temp_file, std::ios::out | std::ios::binary);
|
||||
tmp << stream.rdbuf();
|
||||
tmp.close();
|
||||
|
||||
load(temp_file);
|
||||
|
||||
std::remove(temp_file.c_str());
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool workbook::load(const std::vector<unsigned char> &data)
|
||||
{
|
||||
std::string temp_file = CreateTemporaryFilename();
|
||||
std::string temp_file = create_temporary_filename();
|
||||
|
||||
std::ofstream tmp;
|
||||
tmp.open(temp_file, std::ios::out | std::ios::binary);
|
||||
|
||||
for(auto c : data)
|
||||
{
|
||||
tmp.put(c);
|
||||
}
|
||||
|
||||
tmp.close();
|
||||
|
||||
load(temp_file);
|
||||
|
||||
std::remove(temp_file.c_str());
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -326,12 +339,14 @@ bool workbook::load(const std::string &filename)
|
|||
auto sheets_node = root_node.child("sheets");
|
||||
|
||||
std::vector<std::string> shared_strings;
|
||||
|
||||
if(f.has_file("xl/sharedStrings.xml"))
|
||||
{
|
||||
shared_strings = xlnt::reader::read_shared_string(f.read("xl/sharedStrings.xml"));
|
||||
}
|
||||
|
||||
std::vector<int> number_format_ids;
|
||||
|
||||
if(f.has_file("xl/styles.xml"))
|
||||
{
|
||||
pugi::xml_document styles_doc;
|
||||
|
@ -526,15 +541,19 @@ void workbook::clear()
|
|||
|
||||
bool workbook::save(std::vector<unsigned char> &data)
|
||||
{
|
||||
auto temp_file = CreateTemporaryFilename();
|
||||
auto temp_file = create_temporary_filename();
|
||||
save(temp_file);
|
||||
|
||||
std::ifstream tmp;
|
||||
tmp.open(temp_file, std::ios::in | std::ios::binary);
|
||||
|
||||
auto char_data = std::vector<char>((std::istreambuf_iterator<char>(tmp)),
|
||||
std::istreambuf_iterator<char>());
|
||||
data = std::vector<unsigned char>(char_data.begin(), char_data.end());
|
||||
tmp.close();
|
||||
|
||||
std::remove(temp_file.c_str());
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
|
|
@ -412,7 +412,23 @@ void worksheet::unmerge_cells(column_t start_column, row_t start_row, column_t e
|
|||
unmerge_cells(xlnt::range_reference(start_column, start_row, end_column, end_row));
|
||||
}
|
||||
|
||||
void worksheet::append()
|
||||
{
|
||||
get_cell(cell_reference(1, get_next_row()));
|
||||
}
|
||||
|
||||
void worksheet::append(const std::vector<std::string> &cells)
|
||||
{
|
||||
xlnt::cell_reference next(1, get_next_row());
|
||||
|
||||
for(auto cell : cells)
|
||||
{
|
||||
get_cell(next).set_value(cell);
|
||||
next.set_column_index(next.get_column_index() + 1);
|
||||
}
|
||||
}
|
||||
|
||||
row_t worksheet::get_next_row() const
|
||||
{
|
||||
int row = get_highest_row() + 1;
|
||||
|
||||
|
@ -421,51 +437,46 @@ void worksheet::append(const std::vector<std::string> &cells)
|
|||
row = 1;
|
||||
}
|
||||
|
||||
int column = 1;
|
||||
|
||||
for(auto cell : cells)
|
||||
{
|
||||
get_cell(cell_reference(column++, row)).set_value(cell);
|
||||
}
|
||||
return row;
|
||||
}
|
||||
|
||||
void worksheet::append(const std::vector<int> &cells)
|
||||
{
|
||||
int row = get_highest_row();
|
||||
int column = 1;
|
||||
xlnt::cell_reference next(1, get_next_row());
|
||||
|
||||
for(auto cell : cells)
|
||||
{
|
||||
get_cell(cell_reference(column++, row)).set_value(cell);
|
||||
get_cell(next).set_value(cell);
|
||||
next.set_column_index(next.get_column_index() + 1);
|
||||
}
|
||||
}
|
||||
|
||||
void worksheet::append(const std::vector<date> &cells)
|
||||
{
|
||||
int row = get_highest_row();
|
||||
int column = 1;
|
||||
xlnt::cell_reference next(1, get_next_row());
|
||||
|
||||
for(auto cell : cells)
|
||||
{
|
||||
get_cell(cell_reference(column++, row)).set_value(cell);
|
||||
get_cell(next).set_value(cell);
|
||||
next.set_column_index(next.get_column_index() + 1);
|
||||
}
|
||||
}
|
||||
|
||||
void worksheet::append(const std::vector<cell> &cells)
|
||||
{
|
||||
int row = get_highest_row();
|
||||
int column = 1;
|
||||
xlnt::cell_reference next(1, get_next_row());
|
||||
|
||||
for(auto cell : cells)
|
||||
{
|
||||
get_cell(cell_reference(column++, row)) = cell;
|
||||
get_cell(next).set_value(cell);
|
||||
next.set_column_index(next.get_column_index() + 1);
|
||||
}
|
||||
}
|
||||
|
||||
void worksheet::append(const std::unordered_map<std::string, std::string> &cells)
|
||||
{
|
||||
int row = get_highest_row();
|
||||
|
||||
auto row = get_next_row();
|
||||
|
||||
for(auto cell : cells)
|
||||
{
|
||||
get_cell(cell_reference(cell.first, row)).set_value(cell.second);
|
||||
|
@ -474,8 +485,8 @@ void worksheet::append(const std::unordered_map<std::string, std::string> &cells
|
|||
|
||||
void worksheet::append(const std::unordered_map<int, std::string> &cells)
|
||||
{
|
||||
int row = get_highest_row();
|
||||
|
||||
auto row = get_next_row();
|
||||
|
||||
for(auto cell : cells)
|
||||
{
|
||||
get_cell(cell_reference(cell.first, row)).set_value(cell.second);
|
||||
|
@ -484,12 +495,12 @@ void worksheet::append(const std::unordered_map<int, std::string> &cells)
|
|||
|
||||
void worksheet::append(const std::vector<int>::const_iterator begin, const std::vector<int>::const_iterator end)
|
||||
{
|
||||
int row = get_highest_row();
|
||||
int column = 1;
|
||||
xlnt::cell_reference next(1, get_next_row());
|
||||
|
||||
for(auto i = begin; i != end; i++)
|
||||
{
|
||||
get_cell(cell_reference(column++, row)).set_value(*i);
|
||||
get_cell(next).set_value(*i);
|
||||
next.set_column_index(next.get_column_index() + 1);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -374,7 +374,7 @@ public:
|
|||
ws.get_parent().add_font(font);
|
||||
|
||||
auto cell = xlnt::cell(ws, "A1");
|
||||
TS_ASSERT(cell.get_font() == font);
|
||||
TS_ASSERT_EQUALS(cell.get_font(), font);
|
||||
}
|
||||
|
||||
void test_fill()
|
||||
|
|
|
@ -514,7 +514,7 @@ public:
|
|||
void test_positioning_point()
|
||||
{
|
||||
xlnt::worksheet ws(wb_);
|
||||
TS_ASSERT_EQUALS(ws.get_point_pos(40, 150), "C3");
|
||||
TS_ASSERT_EQUALS(ws.get_point_pos(150, 40), "C3");
|
||||
}
|
||||
|
||||
void test_positioning_roundtrip()
|
||||
|
@ -552,6 +552,10 @@ public:
|
|||
void test_max_column()
|
||||
{
|
||||
xlnt::worksheet ws(wb_);
|
||||
ws[xlnt::cell_reference("F1")].set_value(10);
|
||||
ws[xlnt::cell_reference("F2")].set_value(32);
|
||||
ws[xlnt::cell_reference("F3")].set_formula("=F1+F2");
|
||||
ws[xlnt::cell_reference("A4")].set_formula("=A1+A2+A3");
|
||||
TS_ASSERT_EQUALS(ws.get_highest_column(), 6);
|
||||
}
|
||||
|
||||
|
@ -564,6 +568,10 @@ public:
|
|||
void test_max_row()
|
||||
{
|
||||
xlnt::worksheet ws(wb_);
|
||||
ws.append();
|
||||
ws.append(std::vector<int> { 5 });
|
||||
ws.append();
|
||||
ws.append(std::vector<int> { 4 });
|
||||
TS_ASSERT_EQUALS(ws.get_highest_row(), 4);
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue
Block a user