mirror of
https://github.com/tfussell/xlnt.git
synced 2024-03-22 13:11:17 +08:00
continue implementing styles
This commit is contained in:
parent
d1ea08fd13
commit
2f07e0ae62
|
@ -32,6 +32,8 @@
|
|||
|
||||
namespace xlnt {
|
||||
|
||||
enum class calendar;
|
||||
|
||||
class cell_reference;
|
||||
class comment;
|
||||
class relationship;
|
||||
|
@ -107,28 +109,22 @@ public:
|
|||
bool has_hyperlink() const;
|
||||
|
||||
// style
|
||||
bool has_style() const;
|
||||
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, int index = -1);
|
||||
font &get_font();
|
||||
std::size_t get_style_id() const;
|
||||
const number_format &get_number_format() const;
|
||||
void set_number_format(const number_format &format);
|
||||
const font &get_font() const;
|
||||
fill &get_fill();
|
||||
void set_font(const font &font_);
|
||||
const fill &get_fill() const;
|
||||
border &get_border();
|
||||
void set_fill(const fill &fill_);
|
||||
const border &get_border() const;
|
||||
alignment &get_alignment();
|
||||
void set_border(const border &border_);
|
||||
const alignment &get_alignment() const;
|
||||
protection &get_protection();
|
||||
void set_alignment(const alignment &alignment_);
|
||||
const protection &get_protection() const;
|
||||
bool pivot_button();
|
||||
void set_protection(const protection &protection_);
|
||||
void set_pivot_button(bool b);
|
||||
bool pivot_button() const;
|
||||
bool quote_prefix();
|
||||
void set_quote_prefix(bool b);
|
||||
bool quote_prefix() const;
|
||||
|
||||
// comment
|
||||
|
@ -168,6 +164,8 @@ public:
|
|||
worksheet get_parent();
|
||||
const worksheet get_parent() const;
|
||||
|
||||
calendar get_base_date() const;
|
||||
|
||||
// operators
|
||||
cell &operator=(const cell &rhs);
|
||||
|
||||
|
@ -178,8 +176,10 @@ public:
|
|||
friend bool operator<(cell left, cell right);
|
||||
|
||||
private:
|
||||
void set_value_guess_type(const std::string &s);
|
||||
friend class worksheet;
|
||||
friend struct detail::cell_impl;
|
||||
friend class style;
|
||||
|
||||
cell(detail::cell_impl *d);
|
||||
detail::cell_impl *d_;
|
||||
};
|
||||
|
|
|
@ -152,6 +152,8 @@ struct datetime
|
|||
/// </summary>
|
||||
struct timedelta
|
||||
{
|
||||
static timedelta from_number(long double number);
|
||||
|
||||
timedelta(int days_, int hours_, int minutes_ = 0, int seconds_ = 0, int microseconds_ = 0)
|
||||
: days(days_),
|
||||
hours(hours_),
|
||||
|
|
|
@ -31,5 +31,6 @@ namespace xlnt {
|
|||
class workbook;
|
||||
|
||||
xlnt::workbook load_workbook(const std::vector<std::uint8_t> &bytes);
|
||||
xlnt::workbook load_workbook(const std::string &filename);
|
||||
|
||||
} // namespace xlnt
|
||||
|
|
|
@ -64,6 +64,8 @@ public:
|
|||
&& indent_ == other.indent_;
|
||||
}
|
||||
|
||||
std::size_t hash() const { return 0; }
|
||||
|
||||
private:
|
||||
horizontal_alignment horizontal_ = horizontal_alignment::general;
|
||||
vertical_alignment vertical_ = vertical_alignment::bottom;
|
||||
|
|
|
@ -23,6 +23,8 @@
|
|||
// @author: see AUTHORS file
|
||||
#pragma once
|
||||
|
||||
#include <cstddef>
|
||||
|
||||
#include <xlnt/styles/color.hpp>
|
||||
|
||||
namespace xlnt {
|
||||
|
@ -103,6 +105,8 @@ public:
|
|||
&& diagonal_up == other.diagonal_up
|
||||
&& diagonal_down == other.diagonal_down;
|
||||
}
|
||||
|
||||
std::size_t hash() const { return 0; }
|
||||
};
|
||||
|
||||
} // namespace xlnt
|
||||
|
|
|
@ -60,10 +60,12 @@ public:
|
|||
color start_color = color::white;
|
||||
color end_color = color::black;
|
||||
|
||||
bool operator==(const fill &other) const
|
||||
virtual bool operator==(const fill &other) const
|
||||
{
|
||||
return type_ == other.type_;
|
||||
}
|
||||
|
||||
virtual std::size_t hash() const { return 0; }
|
||||
};
|
||||
|
||||
class pattern_fill : public fill
|
||||
|
@ -72,6 +74,8 @@ public:
|
|||
void set_pattern_type(const std::string &type) { type_ = type; }
|
||||
void set_foreground_color(const std::string &hex) { foreground_color_ = hex; }
|
||||
|
||||
std::size_t hash() const override { return 0; }
|
||||
|
||||
private:
|
||||
std::string type_;
|
||||
std::string foreground_color_;
|
||||
|
|
|
@ -29,6 +29,8 @@
|
|||
|
||||
namespace xlnt {
|
||||
|
||||
class style;
|
||||
|
||||
class font
|
||||
{
|
||||
public:
|
||||
|
@ -56,7 +58,15 @@ public:
|
|||
&& color_ == other.color_;
|
||||
}
|
||||
|
||||
int get_size() const { return size_; }
|
||||
std::string get_name() const { return name_; }
|
||||
bool is_bold() const { return bole_; }
|
||||
|
||||
std::size_t hash() const { return 0; }
|
||||
|
||||
private:
|
||||
friend class style;
|
||||
|
||||
std::string name_ = "Calibri";
|
||||
int size_ = 11;
|
||||
bool bold_ = false;
|
||||
|
|
|
@ -86,55 +86,27 @@ public:
|
|||
static std::string builtin_format_code(int index);
|
||||
static format lookup_format(int code);
|
||||
|
||||
static bool is_date_format(const std::string &format);
|
||||
static bool is_builtin(const std::string &format);
|
||||
|
||||
number_format() : format_code_(format::general), format_index_(0) {}
|
||||
number_format(format code) : format_code_(code), format_index_(reversed_builtin_formats().at(format_strings().at(code))) {}
|
||||
number_format();
|
||||
number_format(format code);
|
||||
number_format(const std::string &code);
|
||||
|
||||
format get_format_code() const { return format_code_; }
|
||||
format get_format_code() const;
|
||||
|
||||
void set_format_code(format format_code, int index = -1)
|
||||
{
|
||||
format_code_ = format_code;
|
||||
void set_format_code(format format_code);
|
||||
|
||||
if(format_code_ != format::unknown)
|
||||
{
|
||||
set_format_code_string(format_strings().at(format_code), index);
|
||||
}
|
||||
}
|
||||
void set_format_string(const std::string &format_code);
|
||||
std::string get_format_string() const;
|
||||
|
||||
void set_format_code_string(const std::string &format_code, int index)
|
||||
{
|
||||
custom_format_code_ = format_code;
|
||||
format_index_ = index;
|
||||
int get_format_index() const { return format_index_; }
|
||||
|
||||
const auto &reversed = reversed_builtin_formats();
|
||||
auto match = reversed.find(format_code);
|
||||
|
||||
format_code_ = format::unknown;
|
||||
|
||||
if(match != reversed.end())
|
||||
{
|
||||
format_index_ = match->second;
|
||||
|
||||
for(const auto &p : format_strings())
|
||||
{
|
||||
if(p.second == format_code)
|
||||
{
|
||||
format_code_ = p.first;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
std::string get_format_code_string() const;
|
||||
std::size_t hash() const;
|
||||
|
||||
private:
|
||||
std::string custom_format_code_ = "";
|
||||
format format_code_ = format::general;
|
||||
int format_index_ = 0;
|
||||
format format_code_;
|
||||
int format_index_;
|
||||
std::string format_string_;
|
||||
};
|
||||
|
||||
} // namespace xlnt
|
||||
|
|
|
@ -23,6 +23,8 @@
|
|||
// @author: see AUTHORS file
|
||||
#pragma once
|
||||
|
||||
#include <cstddef>
|
||||
|
||||
namespace xlnt {
|
||||
|
||||
class protection
|
||||
|
@ -48,6 +50,8 @@ public:
|
|||
return locked_ == other.locked_ && hidden_ == other.hidden_;
|
||||
}
|
||||
|
||||
std::size_t hash() const { return 0; }
|
||||
|
||||
private:
|
||||
type locked_;
|
||||
type hidden_;
|
||||
|
|
|
@ -23,64 +23,55 @@
|
|||
// @author: see AUTHORS file
|
||||
#pragma once
|
||||
|
||||
#include "font.hpp"
|
||||
#include "fill.hpp"
|
||||
#include "borders.hpp"
|
||||
#include "alignment.hpp"
|
||||
#include "color.hpp"
|
||||
#include "number_format.hpp"
|
||||
#include "protection.hpp"
|
||||
|
||||
namespace xlnt {
|
||||
namespace detail {
|
||||
|
||||
struct cell_impl;
|
||||
|
||||
} // namespace detail
|
||||
|
||||
class alignment;
|
||||
class border;
|
||||
class font;
|
||||
class fill;
|
||||
class number_format;
|
||||
class protection;
|
||||
|
||||
class cell;
|
||||
|
||||
class style
|
||||
{
|
||||
public:
|
||||
style(bool is_static = false) : static_(is_static) {}
|
||||
const style default_style();
|
||||
|
||||
style();
|
||||
style(const style &rhs);
|
||||
style &operator=(const style &rhs);
|
||||
|
||||
style copy() const;
|
||||
|
||||
font &get_font();
|
||||
std::size_t hash() const;
|
||||
|
||||
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;
|
||||
void set_border(border borders);
|
||||
|
||||
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 alignment &get_alignment() const;
|
||||
const number_format &get_number_format() const;
|
||||
const protection &get_protection() const;
|
||||
void set_protection(protection protection);
|
||||
|
||||
bool pivot_button();
|
||||
void set_pivot_button(bool pivot);
|
||||
|
||||
bool quote_prefix();
|
||||
void set_quote_prefix(bool quote);
|
||||
bool pivot_button() const;
|
||||
bool quote_prefix() const;
|
||||
|
||||
private:
|
||||
bool static_ = false;
|
||||
font font_;
|
||||
fill fill_;
|
||||
border border_;
|
||||
alignment alignment_;
|
||||
number_format number_format_;
|
||||
protection protection_;
|
||||
bool pivot_button_;
|
||||
bool quote_prefix_;
|
||||
cell get_parent();
|
||||
const cell get_parent() const;
|
||||
detail::cell_impl *parent_;
|
||||
std::size_t font_id_;
|
||||
std::size_t fill_id_;
|
||||
std::size_t border_id_;
|
||||
std::size_t alignment_id_;
|
||||
std::size_t number_format_id_;
|
||||
std::size_t protection_id_;
|
||||
std::size_t style_id_;
|
||||
};
|
||||
|
||||
} // namespace xlnt
|
||||
|
|
|
@ -41,11 +41,13 @@ class drawing;
|
|||
class fill;
|
||||
class font;
|
||||
class named_range;
|
||||
class number_format;
|
||||
class pattern_fill;
|
||||
class protection;
|
||||
class range;
|
||||
class range_reference;
|
||||
class relationship;
|
||||
class style;
|
||||
class worksheet;
|
||||
class zip_file;
|
||||
|
||||
|
@ -206,11 +208,36 @@ public:
|
|||
void add_color(color c);
|
||||
void add_number_format(const std::string &format);
|
||||
|
||||
const std::unordered_map<std::size_t, alignment> &get_alignments() const;
|
||||
const std::unordered_map<std::size_t, border> &get_borders() const;
|
||||
const std::unordered_map<std::size_t, fill> &get_fills() const;
|
||||
const std::unordered_map<std::size_t, font> &get_fonts() const;
|
||||
const std::unordered_map<std::size_t, number_format> &get_number_formats() const;
|
||||
const std::unordered_map<std::size_t, protection> &get_protections() const;
|
||||
|
||||
const number_format &get_number_format(std::size_t style_id) const;
|
||||
std::size_t set_number_format(const number_format &format, std::size_t style_id);
|
||||
const font &get_font(std::size_t style_id) const;
|
||||
std::size_t set_font(const font &font_, std::size_t style_id);
|
||||
const fill &get_fill(std::size_t style_id) const;
|
||||
std::size_t set_fill(const fill &fill_, std::size_t style_id);
|
||||
const border &get_border(std::size_t style_id) const;
|
||||
std::size_t set_border(const border &border_, std::size_t style_id);
|
||||
const alignment &get_alignment(std::size_t style_id) const;
|
||||
std::size_t set_alignment(const alignment &alignment_, std::size_t style_id);
|
||||
const protection &get_protection(std::size_t style_id) const;
|
||||
std::size_t set_protection(const protection &protection_, std::size_t style_id);
|
||||
bool get_pivot_button(std::size_t style_id) const;
|
||||
bool get_quote_prefix(std::size_t style_id) const;
|
||||
|
||||
void set_code_name(const std::string &code_name);
|
||||
|
||||
bool has_loaded_theme();
|
||||
std::string get_loaded_theme();
|
||||
|
||||
style get_style(std::size_t style_id);
|
||||
std::size_t add_style(style style_);
|
||||
|
||||
private:
|
||||
friend class worksheet;
|
||||
std::shared_ptr<detail::workbook_impl> d_;
|
||||
|
|
|
@ -39,10 +39,8 @@ public:
|
|||
style_writer(workbook &wb);
|
||||
style_writer(const style_writer &);
|
||||
style_writer &operator=(const style_writer &);
|
||||
std::unordered_map<std::size_t, std::string> get_style_by_hash() const;
|
||||
std::string write_table() const;
|
||||
std::vector<style> get_styles() const;
|
||||
|
||||
std::string write_table() const;
|
||||
std::string write_number_formats();
|
||||
|
||||
private:
|
||||
|
@ -56,7 +54,6 @@ private:
|
|||
void write_dxfs();
|
||||
void write_table_styles();
|
||||
|
||||
std::vector<style> style_list_;
|
||||
workbook &wb_;
|
||||
};
|
||||
|
||||
|
|
357
source/cell.cpp
357
source/cell.cpp
|
@ -6,12 +6,12 @@
|
|||
#include <xlnt/cell/cell_reference.hpp>
|
||||
#include <xlnt/cell/comment.hpp>
|
||||
#include <xlnt/common/datetime.hpp>
|
||||
#include <xlnt/common/relationship.hpp>
|
||||
#include <xlnt/worksheet/worksheet.hpp>
|
||||
#include <xlnt/common/exceptions.hpp>
|
||||
#include <xlnt/common/relationship.hpp>
|
||||
#include <xlnt/workbook/workbook.hpp>
|
||||
#include <xlnt/workbook/document_properties.hpp>
|
||||
#include <xlnt/common/exceptions.hpp>
|
||||
#include <xlnt/worksheet/worksheet.hpp>
|
||||
#include <xlnt/styles/color.hpp>
|
||||
|
||||
#include "detail/cell_impl.hpp"
|
||||
#include "detail/comment_impl.hpp"
|
||||
|
@ -87,6 +87,36 @@ std::vector<std::string> split_string(const std::string &string, char delim)
|
|||
return split;
|
||||
}
|
||||
|
||||
std::vector<std::string> split_string_any(const std::string &string, const std::string &delims)
|
||||
{
|
||||
std::vector<std::string> split;
|
||||
std::string::size_type previous_index = 0;
|
||||
auto separator_index = string.find_first_of(delims);
|
||||
|
||||
while(separator_index != std::string::npos)
|
||||
{
|
||||
auto part = string.substr(previous_index, separator_index - previous_index);
|
||||
|
||||
if(!part.empty())
|
||||
{
|
||||
split.push_back(part);
|
||||
}
|
||||
|
||||
previous_index = separator_index + 1;
|
||||
separator_index = string.find_first_of(delims, previous_index);
|
||||
}
|
||||
|
||||
split.push_back(string.substr(previous_index));
|
||||
|
||||
return split;
|
||||
}
|
||||
|
||||
bool is_date_format(const std::string &format_string)
|
||||
{
|
||||
auto not_in = format_string.find_first_not_of("/-:, mMyYdDhHsS");
|
||||
return not_in == std::string::npos;
|
||||
}
|
||||
|
||||
bool is_valid_color(const std::string &color)
|
||||
{
|
||||
static const std::vector<std::string> colors = { "Black", "Green"
|
||||
|
@ -288,14 +318,180 @@ format_sections parse_format_sections(const std::string &combined)
|
|||
return result;
|
||||
}
|
||||
|
||||
std::string format_section(long double number, const section &format)
|
||||
const std::vector<std::string> MonthNames =
|
||||
{
|
||||
if(number == static_cast<long long int>(number))
|
||||
"January",
|
||||
"February",
|
||||
"March",
|
||||
"April",
|
||||
"May",
|
||||
"June",
|
||||
"July",
|
||||
"August",
|
||||
"September",
|
||||
"October",
|
||||
"November",
|
||||
"December"
|
||||
};
|
||||
|
||||
std::string format_section(long double number, const section &format, xlnt::calendar base_date)
|
||||
{
|
||||
const std::string unquoted = "$+(:^'{<=-/)!&~}> ";
|
||||
std::string result;
|
||||
|
||||
if(is_date_format(format.value))
|
||||
{
|
||||
return std::to_string(static_cast<long long int>(number));
|
||||
const std::string date_unquoted = ",-/: ";
|
||||
|
||||
const std::vector<std::string> dates =
|
||||
{
|
||||
"m",
|
||||
"mm",
|
||||
"mmm",
|
||||
"mmmmm",
|
||||
"mmmmmm",
|
||||
"d",
|
||||
"dd",
|
||||
"ddd",
|
||||
"dddd",
|
||||
"yy",
|
||||
"yyyy"
|
||||
"h",
|
||||
"[h]",
|
||||
"hh",
|
||||
"m",
|
||||
"[m]",
|
||||
"mm",
|
||||
"s",
|
||||
"[s]",
|
||||
"ss",
|
||||
"AM/PM",
|
||||
"am/pm",
|
||||
"A/P",
|
||||
"a/p"
|
||||
};
|
||||
|
||||
auto split = split_string_any(format.value, date_unquoted);
|
||||
std::string::size_type index = 0, prev = 0;
|
||||
auto d = xlnt::datetime::from_number(number, base_date);
|
||||
bool processed_month = false;
|
||||
|
||||
for(auto part : split)
|
||||
{
|
||||
while(format.value.substr(index, part.size()) != part)
|
||||
{
|
||||
index++;
|
||||
}
|
||||
|
||||
return std::to_string(number);
|
||||
auto between = format.value.substr(prev, index - prev);
|
||||
result.append(between);
|
||||
|
||||
if(part == "m" && !processed_month)
|
||||
{
|
||||
result.append(std::to_string(d.month));
|
||||
processed_month = true;
|
||||
}
|
||||
if(part == "mm" && !processed_month)
|
||||
{
|
||||
if(d.month < 10)
|
||||
{
|
||||
result.append("0");
|
||||
}
|
||||
|
||||
result.append(std::to_string(d.month));
|
||||
processed_month = true;
|
||||
}
|
||||
if(part == "mmm" && !processed_month)
|
||||
{
|
||||
result.append(MonthNames.at(d.month - 1).substr(0, 3));
|
||||
processed_month = true;
|
||||
}
|
||||
if(part == "mmmm" && !processed_month)
|
||||
{
|
||||
result.append(MonthNames.at(d.month - 1));
|
||||
processed_month = true;
|
||||
}
|
||||
if(part == "d")
|
||||
{
|
||||
result.append(std::to_string(d.day));
|
||||
}
|
||||
if(part == "dd")
|
||||
{
|
||||
if(d.day < 10)
|
||||
{
|
||||
result.append("0");
|
||||
}
|
||||
|
||||
result.append(std::to_string(d.day));
|
||||
}
|
||||
if(part == "yyyy")
|
||||
{
|
||||
result.append(std::to_string(d.year));
|
||||
}
|
||||
|
||||
if(part == "h")
|
||||
{
|
||||
result.append(std::to_string(d.hour));
|
||||
processed_month = true;
|
||||
}
|
||||
if(part == "hh")
|
||||
{
|
||||
if(d.hour < 10)
|
||||
{
|
||||
result.append("0");
|
||||
}
|
||||
|
||||
result.append(std::to_string(d.hour));
|
||||
processed_month = true;
|
||||
}
|
||||
if(part == "m")
|
||||
{
|
||||
result.append(std::to_string(d.minute));
|
||||
}
|
||||
if(part == "mm")
|
||||
{
|
||||
if(d.minute < 10)
|
||||
{
|
||||
result.append("0");
|
||||
}
|
||||
|
||||
result.append(std::to_string(d.minute));
|
||||
}
|
||||
if(part == "s")
|
||||
{
|
||||
result.append(std::to_string(d.second));
|
||||
}
|
||||
if(part == "ss")
|
||||
{
|
||||
if(d.second < 10)
|
||||
{
|
||||
result.append("0");
|
||||
}
|
||||
|
||||
result.append(std::to_string(d.second));
|
||||
}
|
||||
|
||||
|
||||
|
||||
index += part.size();
|
||||
prev = index;
|
||||
}
|
||||
|
||||
if(index < format.value.size())
|
||||
{
|
||||
result.append(format.value.substr(index));
|
||||
}
|
||||
}
|
||||
else if(number == static_cast<long long int>(number))
|
||||
{
|
||||
result = std::to_string(static_cast<long long int>(number));
|
||||
}
|
||||
else
|
||||
{
|
||||
result = std::to_string(number);
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
std::string format_section(const std::string &text, const section &format)
|
||||
|
@ -334,21 +530,21 @@ std::string format_section(const std::string &text, const section &format)
|
|||
return first_part + middle_part + last_part;
|
||||
}
|
||||
|
||||
std::string format_number(long double number, const std::string &format)
|
||||
std::string format_number(long double number, const std::string &format, xlnt::calendar base_date)
|
||||
{
|
||||
auto sections = parse_format_sections(format);
|
||||
|
||||
if(number > 0)
|
||||
{
|
||||
return format_section(number, sections.first);
|
||||
return format_section(number, sections.first, base_date);
|
||||
}
|
||||
else if(number < 0)
|
||||
{
|
||||
return format_section(number, sections.second);
|
||||
return format_section(number, sections.second, base_date);
|
||||
}
|
||||
|
||||
// number == 0
|
||||
return format_section(number, sections.third);
|
||||
return format_section(number, sections.third, base_date);
|
||||
}
|
||||
|
||||
std::string format_text(const std::string &text, const std::string &format)
|
||||
|
@ -358,12 +554,6 @@ std::string format_text(const std::string &text, const std::string &format)
|
|||
return format_section(text, sections.fourth);
|
||||
}
|
||||
|
||||
bool is_date_format(const std::string &format_string)
|
||||
{
|
||||
auto not_in = format_string.find_first_not_of("/-:, mMyYdDhHsS");
|
||||
return not_in == std::string::npos;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
namespace xlnt {
|
||||
|
@ -411,7 +601,6 @@ bool cell::garbage_collectible() const
|
|||
template<>
|
||||
void cell::set_value(bool b)
|
||||
{
|
||||
d_->is_date_ = false;
|
||||
d_->value_numeric_ = b ? 1 : 0;
|
||||
d_->type_ = type::boolean;
|
||||
}
|
||||
|
@ -419,7 +608,6 @@ void cell::set_value(bool b)
|
|||
template<>
|
||||
void cell::set_value(std::int8_t i)
|
||||
{
|
||||
d_->is_date_ = false;
|
||||
d_->value_numeric_ = static_cast<long double>(i);
|
||||
d_->type_ = type::numeric;
|
||||
}
|
||||
|
@ -427,7 +615,6 @@ void cell::set_value(std::int8_t i)
|
|||
template<>
|
||||
void cell::set_value(std::int16_t i)
|
||||
{
|
||||
d_->is_date_ = false;
|
||||
d_->value_numeric_ = static_cast<long double>(i);
|
||||
d_->type_ = type::numeric;
|
||||
}
|
||||
|
@ -435,7 +622,6 @@ void cell::set_value(std::int16_t i)
|
|||
template<>
|
||||
void cell::set_value(std::int32_t i)
|
||||
{
|
||||
d_->is_date_ = false;
|
||||
d_->value_numeric_ = static_cast<long double>(i);
|
||||
d_->type_ = type::numeric;
|
||||
}
|
||||
|
@ -443,7 +629,6 @@ void cell::set_value(std::int32_t i)
|
|||
template<>
|
||||
void cell::set_value(std::int64_t i)
|
||||
{
|
||||
d_->is_date_ = false;
|
||||
d_->value_numeric_ = static_cast<long double>(i);
|
||||
d_->type_ = type::numeric;
|
||||
}
|
||||
|
@ -451,7 +636,6 @@ void cell::set_value(std::int64_t i)
|
|||
template<>
|
||||
void cell::set_value(std::uint8_t i)
|
||||
{
|
||||
d_->is_date_ = false;
|
||||
d_->value_numeric_ = static_cast<long double>(i);
|
||||
d_->type_ = type::numeric;
|
||||
}
|
||||
|
@ -459,7 +643,6 @@ void cell::set_value(std::uint8_t i)
|
|||
template<>
|
||||
void cell::set_value(std::uint16_t i)
|
||||
{
|
||||
d_->is_date_ = false;
|
||||
d_->value_numeric_ = static_cast<long double>(i);
|
||||
d_->type_ = type::numeric;
|
||||
}
|
||||
|
@ -467,7 +650,6 @@ void cell::set_value(std::uint16_t i)
|
|||
template<>
|
||||
void cell::set_value(std::uint32_t i)
|
||||
{
|
||||
d_->is_date_ = false;
|
||||
d_->value_numeric_ = static_cast<long double>(i);
|
||||
d_->type_ = type::numeric;
|
||||
}
|
||||
|
@ -475,7 +657,6 @@ void cell::set_value(std::uint32_t i)
|
|||
template<>
|
||||
void cell::set_value(std::uint64_t i)
|
||||
{
|
||||
d_->is_date_ = false;
|
||||
d_->value_numeric_ = static_cast<long double>(i);
|
||||
d_->type_ = type::numeric;
|
||||
}
|
||||
|
@ -484,7 +665,6 @@ void cell::set_value(std::uint64_t i)
|
|||
template<>
|
||||
void cell::set_value(unsigned long i)
|
||||
{
|
||||
d_->is_date_ = false;
|
||||
d_->value_numeric_ = static_cast<long double>(i);
|
||||
d_->type_ = type::numeric;
|
||||
}
|
||||
|
@ -494,7 +674,6 @@ void cell::set_value(unsigned long i)
|
|||
template<>
|
||||
void cell::set_value(long long i)
|
||||
{
|
||||
d_->is_date_ = false;
|
||||
d_->value_numeric_ = static_cast<long double>(i);
|
||||
d_->type_ = type::numeric;
|
||||
}
|
||||
|
@ -502,7 +681,6 @@ void cell::set_value(long long i)
|
|||
template<>
|
||||
void cell::set_value(unsigned long long i)
|
||||
{
|
||||
d_->is_date_ = false;
|
||||
d_->value_numeric_ = static_cast<long double>(i);
|
||||
d_->type_ = type::numeric;
|
||||
}
|
||||
|
@ -511,7 +689,6 @@ void cell::set_value(unsigned long long i)
|
|||
template<>
|
||||
void cell::set_value(float f)
|
||||
{
|
||||
d_->is_date_ = false;
|
||||
d_->value_numeric_ = static_cast<long double>(f);
|
||||
d_->type_ = type::numeric;
|
||||
}
|
||||
|
@ -519,7 +696,6 @@ void cell::set_value(float f)
|
|||
template<>
|
||||
void cell::set_value(double d)
|
||||
{
|
||||
d_->is_date_ = false;
|
||||
d_->value_numeric_ = static_cast<long double>(d);
|
||||
d_->type_ = type::numeric;
|
||||
}
|
||||
|
@ -527,7 +703,6 @@ void cell::set_value(double d)
|
|||
template<>
|
||||
void cell::set_value(long double d)
|
||||
{
|
||||
d_->is_date_ = false;
|
||||
d_->value_numeric_ = static_cast<long double>(d);
|
||||
d_->type_ = type::numeric;
|
||||
}
|
||||
|
@ -550,44 +725,43 @@ 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_->is_date_ = c.d_->is_date_;
|
||||
d_->hyperlink_ = c.d_->hyperlink_;
|
||||
d_->has_hyperlink_ = c.d_->has_hyperlink_;
|
||||
d_->formula_ = c.d_->formula_;
|
||||
set_style(c.get_style());
|
||||
d_->style_id_ = c.d_->style_id_;
|
||||
set_comment(c.get_comment());
|
||||
}
|
||||
|
||||
template<>
|
||||
void cell::set_value(date d)
|
||||
{
|
||||
auto base_date = get_parent().get_parent().get_properties().excel_base_date;
|
||||
d_->set_date(d.to_number(base_date), xlnt::number_format::format::date_yyyymmdd2);
|
||||
d_->type_ = type::numeric;
|
||||
d_->value_numeric_ = d.to_number(get_base_date());
|
||||
set_number_format(number_format(number_format::format::date_yyyymmdd2));
|
||||
}
|
||||
|
||||
template<>
|
||||
void cell::set_value(datetime d)
|
||||
{
|
||||
auto base_date = get_parent().get_parent().get_properties().excel_base_date;
|
||||
d_->set_date(d.to_number(base_date), xlnt::number_format::format::date_datetime);
|
||||
d_->type_ = type::numeric;
|
||||
d_->value_numeric_ = d.to_number(get_base_date());
|
||||
set_number_format(number_format(number_format::format::date_datetime));
|
||||
}
|
||||
|
||||
template<>
|
||||
void cell::set_value(time t)
|
||||
{
|
||||
d_->set_date(t.to_number(), xlnt::number_format::format::date_time6);
|
||||
d_->type_ = type::numeric;
|
||||
d_->value_numeric_ = t.to_number();
|
||||
set_number_format(number_format(number_format::format::date_time6));
|
||||
}
|
||||
|
||||
template<>
|
||||
void cell::set_value(timedelta t)
|
||||
{
|
||||
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
|
||||
}
|
||||
|
||||
bool cell::has_style() const
|
||||
{
|
||||
return d_->style_ != nullptr;
|
||||
d_->type_ = type::numeric;
|
||||
d_->value_numeric_ = t.to_number();
|
||||
set_number_format(number_format(number_format::format::date_timedelta));
|
||||
}
|
||||
|
||||
row_t cell::get_row() const
|
||||
|
@ -612,9 +786,9 @@ bool cell::is_merged() const
|
|||
|
||||
bool cell::is_date() const
|
||||
{
|
||||
if(get_data_type() == type::numeric && has_style())
|
||||
if(get_data_type() == type::numeric)
|
||||
{
|
||||
auto number_format = get_style().get_number_format().get_format_code_string();
|
||||
auto number_format = get_number_format().get_format_string();
|
||||
|
||||
if(number_format != "General")
|
||||
{
|
||||
|
@ -648,21 +822,6 @@ bool cell::operator==(const cell &comparand) const
|
|||
return d_ == comparand.d_;
|
||||
}
|
||||
|
||||
style &cell::get_style()
|
||||
{
|
||||
return d_->get_style(true);
|
||||
}
|
||||
|
||||
const style &cell::get_style() const
|
||||
{
|
||||
return d_->get_style();
|
||||
}
|
||||
|
||||
void cell::set_style(const xlnt::style &s)
|
||||
{
|
||||
get_style() = s;
|
||||
}
|
||||
|
||||
cell &cell::operator=(const cell &rhs)
|
||||
{
|
||||
*d_ = *rhs.d_;
|
||||
|
@ -874,54 +1033,44 @@ std::size_t cell::get_xf_index() const
|
|||
return d_->xf_index_;
|
||||
}
|
||||
|
||||
std::string cell::get_number_format()
|
||||
const number_format &cell::get_number_format() const
|
||||
{
|
||||
return get_style().get_number_format().get_format_code_string();
|
||||
return get_parent().get_parent().get_number_format(d_->style_id_);
|
||||
}
|
||||
|
||||
std::string cell::get_number_format() const
|
||||
const font &cell::get_font() const
|
||||
{
|
||||
return get_style().get_number_format().get_format_code_string();
|
||||
}
|
||||
|
||||
font &cell::get_font()
|
||||
{
|
||||
return get_style().get_font();
|
||||
}
|
||||
|
||||
fill &cell::get_fill()
|
||||
{
|
||||
return get_style().get_fill();
|
||||
return get_parent().get_parent().get_font(d_->style_id_);
|
||||
}
|
||||
|
||||
const fill &cell::get_fill() const
|
||||
{
|
||||
return get_style().get_fill();
|
||||
return get_parent().get_parent().get_fill(d_->style_id_);
|
||||
}
|
||||
|
||||
border &cell::get_border()
|
||||
const border &cell::get_border() const
|
||||
{
|
||||
return get_style().get_border();
|
||||
return get_parent().get_parent().get_border(d_->style_id_);
|
||||
}
|
||||
|
||||
alignment &cell::get_alignment()
|
||||
const alignment &cell::get_alignment() const
|
||||
{
|
||||
return get_style().get_alignment();
|
||||
return get_parent().get_parent().get_alignment(d_->style_id_);
|
||||
}
|
||||
|
||||
protection &cell::get_protection()
|
||||
const protection &cell::get_protection() const
|
||||
{
|
||||
return get_style().get_protection();
|
||||
return get_parent().get_parent().get_protection(d_->style_id_);
|
||||
}
|
||||
|
||||
bool cell::pivot_button()
|
||||
bool cell::pivot_button() const
|
||||
{
|
||||
return get_style().pivot_button();
|
||||
return get_parent().get_parent().get_pivot_button(d_->style_id_);
|
||||
}
|
||||
|
||||
bool cell::quote_prefix()
|
||||
bool cell::quote_prefix() const
|
||||
{
|
||||
return get_style().quote_prefix();
|
||||
return get_parent().get_parent().get_quote_prefix(d_->style_id_);
|
||||
}
|
||||
|
||||
void cell::clear_value()
|
||||
|
@ -1021,25 +1170,24 @@ time cell::get_value() const
|
|||
template<>
|
||||
datetime cell::get_value() const
|
||||
{
|
||||
return datetime::from_number(d_->value_numeric_, xlnt::calendar::windows_1900);
|
||||
return datetime::from_number(d_->value_numeric_, get_base_date());
|
||||
}
|
||||
|
||||
template<>
|
||||
date cell::get_value() const
|
||||
{
|
||||
return date::from_number(static_cast<int>(d_->value_numeric_), xlnt::calendar::windows_1900);
|
||||
return date::from_number(static_cast<int>(d_->value_numeric_), get_base_date());
|
||||
}
|
||||
|
||||
template<>
|
||||
timedelta cell::get_value() const
|
||||
{
|
||||
return timedelta(0, 0);
|
||||
//return timedelta::from_number(d_->value_numeric_);
|
||||
return timedelta::from_number(d_->value_numeric_);
|
||||
}
|
||||
|
||||
void cell::set_number_format(const std::string &format_string, int index)
|
||||
void cell::set_number_format(const number_format &number_format_)
|
||||
{
|
||||
get_style().get_number_format().set_format_code_string(format_string, index);
|
||||
d_->style_id_ = get_parent().get_parent().set_number_format(number_format_, d_->style_id_);
|
||||
}
|
||||
|
||||
template<>
|
||||
|
@ -1055,23 +1203,18 @@ bool cell::has_value() const
|
|||
|
||||
std::string cell::to_string() const
|
||||
{
|
||||
std::string number_format = "General";
|
||||
|
||||
if(has_style())
|
||||
{
|
||||
number_format = get_style().get_number_format().get_format_code_string();
|
||||
}
|
||||
auto nf = get_number_format();
|
||||
|
||||
switch(get_data_type())
|
||||
{
|
||||
case cell::type::null:
|
||||
return "";
|
||||
case cell::type::numeric:
|
||||
return format_number(get_value<long double>(), number_format);
|
||||
return format_number(get_value<long double>(), nf.get_format_string(), get_base_date());
|
||||
case cell::type::string:
|
||||
case cell::type::formula:
|
||||
case cell::type::error:
|
||||
return format_text(get_value<std::string>(), number_format);
|
||||
return format_text(get_value<std::string>(), nf.get_format_string());
|
||||
case cell::type::boolean:
|
||||
return get_value<long double>() == 0 ? "FALSE" : "TRUE";
|
||||
default:
|
||||
|
@ -1079,4 +1222,14 @@ std::string cell::to_string() const
|
|||
}
|
||||
}
|
||||
|
||||
std::size_t cell::get_style_id() const
|
||||
{
|
||||
return d_->style_id_;
|
||||
}
|
||||
|
||||
calendar cell::get_base_date() const
|
||||
{
|
||||
return get_parent().get_parent().get_properties().excel_base_date;
|
||||
}
|
||||
|
||||
} // namespace xlnt
|
||||
|
|
|
@ -187,4 +187,9 @@ double timedelta::to_number() const
|
|||
return days + hours / 24.0;
|
||||
}
|
||||
|
||||
timedelta timedelta::from_number(long double number)
|
||||
{
|
||||
return timedelta(static_cast<long long int>(number), 0);
|
||||
}
|
||||
|
||||
} // namespace xlnt
|
||||
|
|
|
@ -6,30 +6,6 @@
|
|||
namespace xlnt {
|
||||
namespace detail {
|
||||
|
||||
|
||||
cell::type type_;
|
||||
|
||||
worksheet_impl *parent_;
|
||||
|
||||
column_t column_;
|
||||
row_t row_;
|
||||
|
||||
std::string value_string_;
|
||||
long double value_numeric_;
|
||||
|
||||
std::string formula_;
|
||||
|
||||
bool has_hyperlink_;
|
||||
relationship hyperlink_;
|
||||
|
||||
bool is_merged_;
|
||||
bool is_date_;
|
||||
|
||||
std::size_t xf_index_;
|
||||
|
||||
std::unique_ptr<style> style_;
|
||||
std::unique_ptr<comment_impl> comment_;
|
||||
|
||||
cell_impl::cell_impl() : cell_impl(1, 1)
|
||||
{
|
||||
}
|
||||
|
@ -46,9 +22,8 @@ cell_impl::cell_impl(worksheet_impl *parent, column_t column, row_t row)
|
|||
value_numeric_(0),
|
||||
has_hyperlink_(false),
|
||||
is_merged_(false),
|
||||
is_date_(false),
|
||||
xf_index_(0),
|
||||
style_(nullptr),
|
||||
style_id_(1),
|
||||
comment_(nullptr)
|
||||
{
|
||||
}
|
||||
|
@ -68,14 +43,9 @@ cell_impl &cell_impl::operator=(const cell_impl &rhs)
|
|||
column_ = rhs.column_;
|
||||
row_ = rhs.row_;
|
||||
is_merged_ = rhs.is_merged_;
|
||||
is_date_ = rhs.is_date_;
|
||||
has_hyperlink_ = rhs.has_hyperlink_;
|
||||
type_ = rhs.type_;
|
||||
|
||||
if(rhs.style_ != nullptr)
|
||||
{
|
||||
style_.reset(new style(*rhs.style_));
|
||||
}
|
||||
style_id_ = rhs.style_id_;
|
||||
|
||||
if(rhs.comment_ != nullptr)
|
||||
{
|
||||
|
|
|
@ -8,6 +8,7 @@
|
|||
#include <xlnt/common/datetime.hpp>
|
||||
#include <xlnt/common/types.hpp>
|
||||
#include <xlnt/common/relationship.hpp>
|
||||
#include <xlnt/styles/number_format.hpp>
|
||||
|
||||
#include "comment_impl.hpp"
|
||||
|
||||
|
@ -123,37 +124,13 @@ struct cell_impl
|
|||
cell_impl(const cell_impl &rhs);
|
||||
cell_impl &operator=(const cell_impl &rhs);
|
||||
|
||||
style &get_style(bool create_if_null)
|
||||
cell self()
|
||||
{
|
||||
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;
|
||||
get_style(true).get_number_format().set_format_code(format_code);
|
||||
value_numeric_ = number;
|
||||
type_ = cell::type::numeric;
|
||||
return xlnt::cell(this);
|
||||
}
|
||||
|
||||
void set_string(const std::string &s, bool guess_types)
|
||||
{
|
||||
is_date_ = false;
|
||||
value_string_ = check_string(s);
|
||||
type_ = cell::type::string;
|
||||
|
||||
|
@ -175,7 +152,7 @@ struct cell_impl
|
|||
{
|
||||
value_numeric_ = percentage.second;
|
||||
type_ = cell::type::numeric;
|
||||
get_style(true).get_number_format().set_format_code(xlnt::number_format::format::percentage);
|
||||
self().set_number_format(xlnt::number_format(xlnt::number_format::format::percentage));
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -183,7 +160,9 @@ struct cell_impl
|
|||
|
||||
if (time.first)
|
||||
{
|
||||
set_date(time.second.to_number(), xlnt::number_format::format::date_time6);
|
||||
type_ = cell::type::numeric;
|
||||
self().set_number_format(xlnt::number_format(number_format::format::date_time6));
|
||||
value_numeric_ = time.second.to_number();
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -215,11 +194,10 @@ struct cell_impl
|
|||
relationship hyperlink_;
|
||||
|
||||
bool is_merged_;
|
||||
bool is_date_;
|
||||
|
||||
std::size_t xf_index_;
|
||||
std::size_t style_id_;
|
||||
|
||||
std::unique_ptr<style> style_;
|
||||
std::unique_ptr<comment_impl> comment_;
|
||||
};
|
||||
|
||||
|
|
|
@ -17,7 +17,22 @@ struct workbook_impl
|
|||
drawings_(other.drawings_),
|
||||
properties_(other.properties_),
|
||||
guess_types_(other.guess_types_),
|
||||
data_only_(other.data_only_)
|
||||
data_only_(other.data_only_),
|
||||
next_style_id_(other.next_style_id_),
|
||||
alignments_(other.alignments_),
|
||||
borders_(other.borders_),
|
||||
fills_(other.fills_),
|
||||
fonts_(other.fonts_),
|
||||
number_formats_(other.number_formats_),
|
||||
protections_(other.protections_),
|
||||
style_alignment_(other.style_alignment_),
|
||||
style_border_(other.style_border_),
|
||||
style_fill_(other.style_fill_),
|
||||
style_font_(other.style_font_),
|
||||
style_number_format_(other.style_number_format_),
|
||||
style_protection_(other.style_protection_),
|
||||
style_pivot_button_(other.style_pivot_button_),
|
||||
style_quote_prefix_(other.style_quote_prefix_)
|
||||
{
|
||||
}
|
||||
|
||||
|
@ -33,6 +48,21 @@ struct workbook_impl
|
|||
properties_ = other.properties_;
|
||||
guess_types_ = other.guess_types_;
|
||||
data_only_ = other.data_only_;
|
||||
next_style_id_ = other.next_style_id_;
|
||||
alignments_ = other.alignments_;
|
||||
borders_ = other.borders_;
|
||||
fills_ = other.fills_;
|
||||
fonts_ = other.fonts_;
|
||||
number_formats_ = other.number_formats_;
|
||||
protections_ = other.protections_;
|
||||
style_alignment_ = other.style_alignment_;
|
||||
style_border_ = other.style_border_;
|
||||
style_fill_ = other.style_fill_;
|
||||
style_font_ = other.style_font_;
|
||||
style_number_format_ = other.style_number_format_;
|
||||
style_protection_ = other.style_protection_;
|
||||
style_pivot_button_ = other.style_pivot_button_;
|
||||
style_quote_prefix_ = other.style_quote_prefix_;
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
@ -44,6 +74,22 @@ struct workbook_impl
|
|||
document_properties properties_;
|
||||
bool guess_types_;
|
||||
bool data_only_;
|
||||
|
||||
std::size_t next_style_id_;
|
||||
std::unordered_map<std::size_t, alignment> alignments_;
|
||||
std::unordered_map<std::size_t, border> borders_;
|
||||
std::unordered_map<std::size_t, fill> fills_;
|
||||
std::unordered_map<std::size_t, font> fonts_;
|
||||
std::unordered_map<std::size_t, number_format> number_formats_;
|
||||
std::unordered_map<std::size_t, protection> protections_;
|
||||
std::unordered_map<std::size_t, std::size_t> style_alignment_;
|
||||
std::unordered_map<std::size_t, std::size_t> style_border_;
|
||||
std::unordered_map<std::size_t, std::size_t> style_fill_;
|
||||
std::unordered_map<std::size_t, std::size_t> style_font_;
|
||||
std::unordered_map<std::size_t, std::size_t> style_number_format_;
|
||||
std::unordered_map<std::size_t, std::size_t> style_protection_;
|
||||
std::unordered_map<std::size_t, bool> style_pivot_button_;
|
||||
std::unordered_map<std::size_t, bool> style_quote_prefix_;
|
||||
};
|
||||
|
||||
} // namespace detail
|
||||
|
|
|
@ -124,6 +124,20 @@ const std::unordered_map<std::string, int> &number_format::reversed_builtin_form
|
|||
return formats;
|
||||
}
|
||||
|
||||
number_format::number_format() : number_format(format::general)
|
||||
{
|
||||
}
|
||||
|
||||
number_format::number_format(format code) : format_code_(code), format_index_(0)
|
||||
{
|
||||
set_format_code(code);
|
||||
}
|
||||
|
||||
number_format::number_format(const std::string &format_string) : number_format(format::general)
|
||||
{
|
||||
set_format_string(format_string);
|
||||
}
|
||||
|
||||
number_format::format number_format::lookup_format(int code)
|
||||
{
|
||||
if(builtin_formats().find(code) == builtin_formats().end())
|
||||
|
@ -142,14 +156,58 @@ number_format::format number_format::lookup_format(int code)
|
|||
return match->first;
|
||||
}
|
||||
|
||||
std::string number_format::get_format_code_string() const
|
||||
std::string number_format::get_format_string() const
|
||||
{
|
||||
if(builtin_formats().find(format_index_) == builtin_formats().end())
|
||||
{
|
||||
return custom_format_code_;
|
||||
}
|
||||
return format_string_;
|
||||
}
|
||||
|
||||
return builtin_formats().at(format_index_);
|
||||
number_format::format number_format::get_format_code() const
|
||||
{
|
||||
return format_code_;
|
||||
}
|
||||
|
||||
std::size_t number_format::hash() const
|
||||
{
|
||||
std::hash<std::string> hasher;
|
||||
return hasher(format_string_);
|
||||
}
|
||||
|
||||
void number_format::set_format_string(const std::string &format_string)
|
||||
{
|
||||
format_string_ = format_string;
|
||||
format_index_ = -1;
|
||||
format_code_ = format::unknown;
|
||||
|
||||
const auto &reversed = reversed_builtin_formats();
|
||||
|
||||
if(reversed.find(format_string) != reversed.end())
|
||||
{
|
||||
format_index_ = reversed.at(format_string);
|
||||
|
||||
for(const auto &pair : format_strings())
|
||||
{
|
||||
if(pair.second == format_string)
|
||||
{
|
||||
format_code_ = pair.first;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void number_format::set_format_code(xlnt::number_format::format format_code)
|
||||
{
|
||||
format_code_ = format_code;
|
||||
format_string_ = format_strings().at(format_code);
|
||||
|
||||
try
|
||||
{
|
||||
format_index_ = reversed_builtin_formats().at(format_string_);
|
||||
}
|
||||
catch(std::out_of_range)
|
||||
{
|
||||
format_index_ = -1;
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace xlnt
|
||||
|
|
|
@ -12,6 +12,7 @@
|
|||
#include <xlnt/workbook/workbook.hpp>
|
||||
#include <xlnt/worksheet/range_reference.hpp>
|
||||
#include <xlnt/worksheet/worksheet.hpp>
|
||||
#include <xlnt/styles/number_format.hpp>
|
||||
|
||||
namespace {
|
||||
|
||||
|
@ -164,20 +165,16 @@ void read_worksheet_common(xlnt::worksheet ws, const pugi::xml_node &root_node,
|
|||
|
||||
if(match != custom_number_formats.end())
|
||||
{
|
||||
ws.get_cell(address).get_style().get_number_format().set_format_code_string(match->second, number_format_id);
|
||||
xlnt::number_format nf(match->second);
|
||||
auto cell = ws.get_cell(address);
|
||||
cell.set_number_format(nf);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
ws.get_cell(address).get_style().get_number_format().set_format_code(format);
|
||||
}
|
||||
|
||||
//TODO: this is bad
|
||||
if(ws.get_cell(address).get_style().get_number_format().get_format_code_string().find_first_of("mdyhs") != std::string::npos)
|
||||
{
|
||||
auto base_date = ws.get_parent().get_properties().excel_base_date;
|
||||
auto converted = xlnt::datetime::from_number(std::stold(value_string), base_date);
|
||||
ws.get_cell(address).set_value(converted.to_number(xlnt::calendar::windows_1900));
|
||||
xlnt::number_format nf(format);
|
||||
auto cell = ws.get_cell(address);
|
||||
cell.set_number_format(nf);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,69 +1,92 @@
|
|||
#include <xlnt/cell/cell.hpp>
|
||||
#include <xlnt/styles/style.hpp>
|
||||
|
||||
#include "font.hpp"
|
||||
#include "number_format.hpp"
|
||||
#include "protection.hpp"
|
||||
|
||||
namespace {
|
||||
|
||||
template <class T>
|
||||
void hash_combine(std::size_t& seed, const T& v)
|
||||
{
|
||||
std::hash<T> hasher;
|
||||
seed ^= hasher(v) + 0x9e3779b9 + (seed<<6) + (seed>>2);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
namespace xlnt {
|
||||
|
||||
style::style(const style &rhs) : number_format_(rhs.number_format_), protection_(rhs.protection_)
|
||||
style::style()
|
||||
{
|
||||
}
|
||||
|
||||
void style::set_protection(xlnt::protection protection)
|
||||
style::style(const style &other)
|
||||
{
|
||||
protection_ = protection;
|
||||
}
|
||||
|
||||
void style::set_number_format(xlnt::number_format format)
|
||||
const cell style::get_parent() const
|
||||
{
|
||||
number_format_ = format;
|
||||
return cell(parent_);
|
||||
}
|
||||
|
||||
border &style::get_border()
|
||||
std::size_t style::hash() const
|
||||
{
|
||||
return border_;
|
||||
std::size_t seed = 100;
|
||||
std::hash<std::string> string_hash;
|
||||
auto font_ = get_font();
|
||||
hash_combine(seed, string_hash(font_.name_));
|
||||
hash_combine(seed, font_.size_);
|
||||
hash_combine(seed, static_cast<std::size_t>(font_.underline_));
|
||||
std::size_t bools = font_.bold_;
|
||||
bools = bools << 1 & font_.italic_;
|
||||
bools = bools << 1 & font_.strikethrough_;
|
||||
bools = bools << 1 & font_.superscript_;
|
||||
bools = bools << 1 & font_.subscript_;
|
||||
hash_combine(seed, bools);
|
||||
|
||||
return seed;
|
||||
}
|
||||
|
||||
bool style::pivot_button()
|
||||
const number_format &style::get_number_format() const
|
||||
{
|
||||
return pivot_button_;
|
||||
return get_parent().get_number_format();
|
||||
}
|
||||
|
||||
bool style::quote_prefix()
|
||||
const border &style::get_border() const
|
||||
{
|
||||
return quote_prefix_;
|
||||
return get_parent().get_border();
|
||||
}
|
||||
|
||||
alignment &style::get_alignment()
|
||||
const alignment &style::get_alignment() const
|
||||
{
|
||||
return alignment_;
|
||||
}
|
||||
|
||||
fill &style::get_fill()
|
||||
{
|
||||
return fill_;
|
||||
return get_parent().get_alignment();
|
||||
}
|
||||
|
||||
const fill &style::get_fill() const
|
||||
{
|
||||
return fill_;
|
||||
return get_parent().get_fill();
|
||||
}
|
||||
|
||||
font &style::get_font()
|
||||
const font &style::get_font() const
|
||||
{
|
||||
return font_;
|
||||
return get_parent().get_font();
|
||||
}
|
||||
|
||||
protection &style::get_protection()
|
||||
const protection &style::get_protection() const
|
||||
{
|
||||
return protection_;
|
||||
return get_parent().get_protection();
|
||||
}
|
||||
|
||||
void style::set_pivot_button(bool pivot)
|
||||
bool style::pivot_button() const
|
||||
{
|
||||
pivot_button_ = pivot;
|
||||
return get_parent().pivot_button();
|
||||
}
|
||||
|
||||
void style::set_quote_prefix(bool quote)
|
||||
bool style::quote_prefix() const
|
||||
{
|
||||
quote_prefix_ = quote;
|
||||
return get_parent().quote_prefix();
|
||||
}
|
||||
|
||||
} // namespace xlnt
|
||||
|
|
|
@ -1,6 +1,12 @@
|
|||
#include <sstream>
|
||||
#include <pugixml.hpp>
|
||||
|
||||
#include <xlnt/styles/alignment.hpp>
|
||||
#include <xlnt/styles/borders.hpp>
|
||||
#include <xlnt/styles/fill.hpp>
|
||||
#include <xlnt/styles/font.hpp>
|
||||
#include <xlnt/styles/number_format.hpp>
|
||||
#include <xlnt/styles/protection.hpp>
|
||||
#include <xlnt/writer/style_writer.hpp>
|
||||
#include <xlnt/workbook/workbook.hpp>
|
||||
#include <xlnt/worksheet/worksheet.hpp>
|
||||
|
@ -14,46 +20,6 @@ style_writer::style_writer(xlnt::workbook &wb) : wb_(wb)
|
|||
|
||||
}
|
||||
|
||||
std::unordered_map<std::size_t, std::string> style_writer::get_style_by_hash() const
|
||||
{
|
||||
std::unordered_map<std::size_t, std::string> styles;
|
||||
for(auto ws : wb_)
|
||||
{
|
||||
for(auto row : ws.rows())
|
||||
{
|
||||
for(auto cell : row)
|
||||
{
|
||||
if(cell.has_style())
|
||||
{
|
||||
styles[1] = "style";
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return styles;
|
||||
}
|
||||
|
||||
std::vector<style> style_writer::get_styles() const
|
||||
{
|
||||
std::vector<style> styles;
|
||||
|
||||
for(auto ws : wb_)
|
||||
{
|
||||
for(auto row : ws.rows())
|
||||
{
|
||||
for(auto cell : row)
|
||||
{
|
||||
if(cell.has_style())
|
||||
{
|
||||
styles.push_back(cell.get_style());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return styles;
|
||||
}
|
||||
|
||||
std::string style_writer::write_table() const
|
||||
{
|
||||
pugi::xml_document doc;
|
||||
|
@ -63,36 +29,53 @@ std::string style_writer::write_table() const
|
|||
style_sheet_node.append_attribute("mc:Ignorable").set_value("x14ac");
|
||||
style_sheet_node.append_attribute("xmlns:x14ac").set_value("http://schemas.microsoft.com/office/spreadsheetml/2009/9/ac");
|
||||
|
||||
std::vector<style> custom_styles;
|
||||
for(auto style : get_styles())
|
||||
auto num_fmts_node = style_sheet_node.append_child("numFmts");
|
||||
auto &num_fmts = wb_.get_number_formats();
|
||||
num_fmts_node.append_attribute("count").set_value(static_cast<int>(num_fmts.size()));
|
||||
int custom_index = 164;
|
||||
|
||||
for(auto &num_fmt : num_fmts)
|
||||
{
|
||||
if((int)style.get_number_format().get_format_code() > 163)
|
||||
auto num_fmt_node = num_fmts_node.append_child("numFmt");
|
||||
|
||||
if(num_fmt.second.get_format_code() == number_format::format::unknown)
|
||||
{
|
||||
custom_styles.push_back(style);
|
||||
num_fmt_node.append_attribute("numFmtId").set_value(custom_index++);
|
||||
}
|
||||
else
|
||||
{
|
||||
num_fmt_node.append_attribute("numFmtId").set_value(num_fmt.second.get_format_index());
|
||||
}
|
||||
|
||||
if(!custom_styles.empty())
|
||||
{
|
||||
|
||||
num_fmt_node.append_attribute("formatCode").set_value("General");
|
||||
}
|
||||
|
||||
auto fonts_node = style_sheet_node.append_child("fonts");
|
||||
fonts_node.append_attribute("count").set_value(1);
|
||||
auto &fonts = wb_.get_fonts();
|
||||
fonts_node.append_attribute("count").set_value(static_cast<int>(fonts.size()));
|
||||
fonts_node.append_attribute("x14ac:knownFonts").set_value(1);
|
||||
|
||||
for(auto &f : fonts)
|
||||
{
|
||||
auto font_node = fonts_node.append_child("font");
|
||||
auto size_node = font_node.append_child("sz");
|
||||
size_node.append_attribute("val").set_value(11);
|
||||
size_node.append_attribute("val").set_value(f.second.get_size());
|
||||
auto color_node = font_node.append_child("color");
|
||||
color_node.append_attribute("theme").set_value(1);
|
||||
auto name_node = font_node.append_child("name");
|
||||
name_node.append_attribute("val").set_value("Calibri");
|
||||
name_node.append_attribute("val").set_value(f.second.get_name().c_str());
|
||||
auto family_node = font_node.append_child("family");
|
||||
family_node.append_attribute("val").set_value(2);
|
||||
auto scheme_node = font_node.append_child("scheme");
|
||||
scheme_node.append_attribute("val").set_value("minor");
|
||||
|
||||
if(f.second.is_bold())
|
||||
{
|
||||
auto bold_node = font_node.append_child("b");
|
||||
bold_node.append_attribute("val").set_value(1);
|
||||
}
|
||||
}
|
||||
|
||||
auto fills_node = style_sheet_node.append_child("fills");
|
||||
fills_node.append_attribute("count").set_value(2);
|
||||
fills_node.append_child("fill").append_child("patternFill").append_attribute("patternType").set_value("none");
|
||||
|
|
|
@ -13,6 +13,12 @@
|
|||
#include <xlnt/common/zip_file.hpp>
|
||||
#include <xlnt/drawing/drawing.hpp>
|
||||
#include <xlnt/reader/reader.hpp>
|
||||
#include <xlnt/styles/alignment.hpp>
|
||||
#include <xlnt/styles/borders.hpp>
|
||||
#include <xlnt/styles/fill.hpp>
|
||||
#include <xlnt/styles/font.hpp>
|
||||
#include <xlnt/styles/number_format.hpp>
|
||||
#include <xlnt/styles/protection.hpp>
|
||||
#include <xlnt/workbook/document_properties.hpp>
|
||||
#include <xlnt/workbook/named_range.hpp>
|
||||
#include <xlnt/workbook/workbook.hpp>
|
||||
|
@ -56,9 +62,8 @@ static std::string create_temporary_filename()
|
|||
namespace xlnt {
|
||||
namespace detail {
|
||||
|
||||
workbook_impl::workbook_impl() : active_sheet_index_(0), guess_types_(false), data_only_(false)
|
||||
workbook_impl::workbook_impl() : active_sheet_index_(0), guess_types_(false), data_only_(false), next_style_id_(0)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
} // namespace detail
|
||||
|
@ -69,6 +74,14 @@ workbook::workbook() : d_(new detail::workbook_impl())
|
|||
create_relationship("rId2", "sharedStrings.xml", relationship::type::shared_strings);
|
||||
create_relationship("rId3", "styles.xml", relationship::type::styles);
|
||||
create_relationship("rId4", "theme/theme1.xml", relationship::type::theme);
|
||||
set_alignment(alignment(), 1);
|
||||
set_border(border(), 1);
|
||||
set_fill(fill(), 1);
|
||||
set_font(font(), 1);
|
||||
set_number_format(number_format(), 1);
|
||||
set_protection(protection(), 1);
|
||||
d_->style_pivot_button_[1] = false;
|
||||
d_->style_quote_prefix_[1] = false;
|
||||
}
|
||||
|
||||
workbook::iterator::iterator(workbook &wb, std::size_t index) : wb_(wb), index_(index)
|
||||
|
@ -658,53 +671,53 @@ void workbook::set_data_only(bool data_only)
|
|||
d_->data_only_ = data_only;
|
||||
}
|
||||
|
||||
void workbook::add_border(xlnt::border /*b*/)
|
||||
{
|
||||
void workbook::add_border(xlnt::border /*b*/)
|
||||
{
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
void workbook::add_alignment(xlnt::alignment /*a*/)
|
||||
{
|
||||
void workbook::add_alignment(xlnt::alignment /*a*/)
|
||||
{
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
void workbook::add_protection(xlnt::protection /*p*/)
|
||||
{
|
||||
void workbook::add_protection(xlnt::protection /*p*/)
|
||||
{
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
void workbook::add_number_format(const std::string &/*format*/)
|
||||
{
|
||||
void workbook::add_number_format(const std::string &/*format*/)
|
||||
{
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
void workbook::add_fill(xlnt::fill &/*f*/)
|
||||
{
|
||||
void workbook::add_fill(xlnt::fill &/*f*/)
|
||||
{
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
void workbook::add_font(xlnt::font /*f*/)
|
||||
{
|
||||
void workbook::add_font(xlnt::font /*f*/)
|
||||
{
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
void workbook::set_code_name(const std::string &/*code_name*/)
|
||||
{
|
||||
void workbook::set_code_name(const std::string &/*code_name*/)
|
||||
{
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
bool workbook::has_loaded_theme()
|
||||
{
|
||||
bool workbook::has_loaded_theme()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
std::string workbook::get_loaded_theme()
|
||||
{
|
||||
std::string workbook::get_loaded_theme()
|
||||
{
|
||||
return "";
|
||||
}
|
||||
}
|
||||
|
||||
std::vector<named_range> workbook::get_named_ranges() const
|
||||
{
|
||||
std::vector<named_range> workbook::get_named_ranges() const
|
||||
{
|
||||
std::vector<named_range> named_ranges;
|
||||
|
||||
for(auto ws : *this)
|
||||
|
@ -716,5 +729,183 @@ void workbook::set_data_only(bool data_only)
|
|||
}
|
||||
|
||||
return named_ranges;
|
||||
}
|
||||
}
|
||||
|
||||
std::size_t workbook::add_style(xlnt::style style_)
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
|
||||
const number_format &workbook::get_number_format(std::size_t style_id) const
|
||||
{
|
||||
return d_->number_formats_[d_->style_number_format_[style_id]];
|
||||
}
|
||||
|
||||
const font &workbook::get_font(std::size_t style_id) const
|
||||
{
|
||||
return d_->fonts_[d_->style_font_[style_id]];
|
||||
}
|
||||
|
||||
std::size_t workbook::set_font(const font &font_, std::size_t style_id)
|
||||
{
|
||||
auto hash = font_.hash();
|
||||
|
||||
if(d_->number_formats_.find(hash) == d_->number_formats_.end())
|
||||
{
|
||||
d_->fonts_[hash] = font_;
|
||||
}
|
||||
|
||||
d_->style_font_[d_->next_style_id_] = hash;
|
||||
|
||||
d_->style_alignment_[d_->next_style_id_] = d_->style_alignment_[style_id];
|
||||
d_->style_border_[d_->next_style_id_] = d_->style_border_[style_id];
|
||||
d_->style_fill_[d_->next_style_id_] = d_->style_fill_[style_id];
|
||||
d_->style_number_format_[d_->next_style_id_] = d_->style_number_format_[style_id];
|
||||
d_->style_protection_[d_->next_style_id_] = d_->style_protection_[style_id];
|
||||
d_->style_pivot_button_[d_->next_style_id_] = d_->style_pivot_button_[style_id];
|
||||
d_->style_quote_prefix_[d_->next_style_id_] = d_->style_quote_prefix_[style_id];
|
||||
|
||||
return d_->next_style_id_++;
|
||||
}
|
||||
|
||||
const fill &workbook::get_fill(std::size_t style_id) const
|
||||
{
|
||||
return d_->fills_[d_->style_fill_[style_id]];
|
||||
}
|
||||
|
||||
std::size_t workbook::set_fill(const fill &fill_, std::size_t style_id)
|
||||
{
|
||||
auto hash = fill_.hash();
|
||||
|
||||
if(d_->fills_.find(hash) == d_->fills_.end())
|
||||
{
|
||||
d_->fills_[hash] = fill_;
|
||||
}
|
||||
|
||||
d_->style_fill_[d_->next_style_id_] = hash;
|
||||
|
||||
d_->style_alignment_[d_->next_style_id_] = d_->style_alignment_[style_id];
|
||||
d_->style_border_[d_->next_style_id_] = d_->style_border_[style_id];
|
||||
d_->style_font_[d_->next_style_id_] = d_->style_font_[style_id];
|
||||
d_->style_number_format_[d_->next_style_id_] = d_->style_number_format_[style_id];
|
||||
d_->style_protection_[d_->next_style_id_] = d_->style_protection_[style_id];
|
||||
d_->style_pivot_button_[d_->next_style_id_] = d_->style_pivot_button_[style_id];
|
||||
d_->style_quote_prefix_[d_->next_style_id_] = d_->style_quote_prefix_[style_id];
|
||||
|
||||
return d_->next_style_id_++;
|
||||
}
|
||||
|
||||
const border &workbook::get_border(std::size_t style_id) const
|
||||
{
|
||||
return d_->borders_[d_->style_border_[style_id]];
|
||||
}
|
||||
|
||||
std::size_t workbook::set_border(const border &border_, std::size_t style_id)
|
||||
{
|
||||
auto hash = border_.hash();
|
||||
|
||||
if(d_->borders_.find(hash) == d_->borders_.end())
|
||||
{
|
||||
d_->borders_[hash] = border_;
|
||||
}
|
||||
|
||||
d_->style_border_[d_->next_style_id_] = hash;
|
||||
|
||||
d_->style_alignment_[d_->next_style_id_] = d_->style_alignment_[style_id];
|
||||
d_->style_font_[d_->next_style_id_] = d_->style_font_[style_id];
|
||||
d_->style_fill_[d_->next_style_id_] = d_->style_fill_[style_id];
|
||||
d_->style_number_format_[d_->next_style_id_] = d_->style_number_format_[style_id];
|
||||
d_->style_protection_[d_->next_style_id_] = d_->style_protection_[style_id];
|
||||
d_->style_pivot_button_[d_->next_style_id_] = d_->style_pivot_button_[style_id];
|
||||
d_->style_quote_prefix_[d_->next_style_id_] = d_->style_quote_prefix_[style_id];
|
||||
|
||||
return d_->next_style_id_++;
|
||||
}
|
||||
|
||||
const alignment &workbook::get_alignment(std::size_t style_id) const
|
||||
{
|
||||
return d_->alignments_[d_->style_alignment_[style_id]];
|
||||
}
|
||||
|
||||
std::size_t workbook::set_alignment(const alignment &alignment_, std::size_t style_id)
|
||||
{
|
||||
auto hash = alignment_.hash();
|
||||
|
||||
if(d_->alignments_.find(hash) == d_->alignments_.end())
|
||||
{
|
||||
d_->alignments_[hash] = alignment_;
|
||||
}
|
||||
|
||||
d_->style_alignment_[d_->next_style_id_] = hash;
|
||||
|
||||
d_->style_border_[d_->next_style_id_] = d_->style_border_[style_id];
|
||||
d_->style_font_[d_->next_style_id_] = d_->style_font_[style_id];
|
||||
d_->style_fill_[d_->next_style_id_] = d_->style_fill_[style_id];
|
||||
d_->style_number_format_[d_->next_style_id_] = d_->style_number_format_[style_id];
|
||||
d_->style_protection_[d_->next_style_id_] = d_->style_protection_[style_id];
|
||||
d_->style_pivot_button_[d_->next_style_id_] = d_->style_pivot_button_[style_id];
|
||||
d_->style_quote_prefix_[d_->next_style_id_] = d_->style_quote_prefix_[style_id];
|
||||
|
||||
return d_->next_style_id_++;
|
||||
}
|
||||
|
||||
const protection &workbook::get_protection(std::size_t style_id) const
|
||||
{
|
||||
return d_->protections_[d_->style_protection_[style_id]];
|
||||
}
|
||||
|
||||
std::size_t workbook::set_protection(const protection &protection_, std::size_t style_id)
|
||||
{
|
||||
auto hash = protection_.hash();
|
||||
|
||||
if(d_->protections_.find(hash) == d_->protections_.end())
|
||||
{
|
||||
d_->protections_[hash] = protection_;
|
||||
}
|
||||
|
||||
d_->style_protection_[d_->next_style_id_] = hash;
|
||||
|
||||
d_->style_alignment_[d_->next_style_id_] = d_->style_alignment_[style_id];
|
||||
d_->style_border_[d_->next_style_id_] = d_->style_border_[style_id];
|
||||
d_->style_font_[d_->next_style_id_] = d_->style_font_[style_id];
|
||||
d_->style_fill_[d_->next_style_id_] = d_->style_fill_[style_id];
|
||||
d_->style_number_format_[d_->next_style_id_] = d_->style_number_format_[style_id];
|
||||
d_->style_pivot_button_[d_->next_style_id_] = d_->style_pivot_button_[style_id];
|
||||
d_->style_quote_prefix_[d_->next_style_id_] = d_->style_quote_prefix_[style_id];
|
||||
|
||||
return d_->next_style_id_++;
|
||||
}
|
||||
|
||||
bool workbook::get_pivot_button(std::size_t style_id) const
|
||||
{
|
||||
return d_->style_pivot_button_[style_id];
|
||||
}
|
||||
|
||||
bool workbook::get_quote_prefix(std::size_t style_id) const
|
||||
{
|
||||
return d_->style_quote_prefix_[style_id];
|
||||
}
|
||||
|
||||
std::size_t workbook::set_number_format(const xlnt::number_format &format, std::size_t style_id)
|
||||
{
|
||||
auto hash = format.hash();
|
||||
|
||||
if(d_->number_formats_.find(hash) == d_->number_formats_.end())
|
||||
{
|
||||
d_->number_formats_[hash] = format;
|
||||
}
|
||||
|
||||
d_->style_number_format_[d_->next_style_id_] = hash;
|
||||
|
||||
d_->style_alignment_[d_->next_style_id_] = d_->style_alignment_[style_id];
|
||||
d_->style_border_[d_->next_style_id_] = d_->style_border_[style_id];
|
||||
d_->style_font_[d_->next_style_id_] = d_->style_font_[style_id];
|
||||
d_->style_fill_[d_->next_style_id_] = d_->style_fill_[style_id];
|
||||
d_->style_protection_[d_->next_style_id_] = d_->style_protection_[style_id];
|
||||
d_->style_pivot_button_[d_->next_style_id_] = d_->style_pivot_button_[style_id];
|
||||
d_->style_quote_prefix_[d_->next_style_id_] = d_->style_quote_prefix_[style_id];
|
||||
|
||||
return d_->next_style_id_++;
|
||||
}
|
||||
|
||||
} // namespace xlnt
|
||||
|
|
|
@ -7,6 +7,15 @@ xlnt::workbook load_workbook(const std::vector<std::uint8_t> &bytes)
|
|||
{
|
||||
xlnt::workbook wb;
|
||||
wb.load(bytes);
|
||||
|
||||
return wb;
|
||||
}
|
||||
|
||||
xlnt::workbook load_workbook(const std::string &filename)
|
||||
{
|
||||
xlnt::workbook wb;
|
||||
wb.load(filename);
|
||||
|
||||
return wb;
|
||||
}
|
||||
|
||||
|
|
|
@ -105,17 +105,6 @@ std::string write_worksheet(worksheet ws, const std::vector<std::string> &string
|
|||
|
||||
if(!style_id_by_hash.empty())
|
||||
{
|
||||
for(auto row : ws.rows())
|
||||
{
|
||||
for(auto cell : row)
|
||||
{
|
||||
if(cell.has_style())
|
||||
{
|
||||
styled_columns.push_back(cell_reference::column_index_from_string(cell.get_column()));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
auto cols_node = root_node.append_child("cols");
|
||||
std::sort(styled_columns.begin(), styled_columns.end());
|
||||
|
||||
|
@ -268,10 +257,8 @@ std::string write_worksheet(worksheet ws, const std::vector<std::string> &string
|
|||
}
|
||||
}
|
||||
|
||||
if(cell.has_style())
|
||||
{
|
||||
cell_node.append_attribute("s").set_value(1);
|
||||
}
|
||||
auto style_id = cell.get_style_id();
|
||||
cell_node.append_attribute("s").set_value((unsigned int)style_id);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -4,8 +4,21 @@
|
|||
#include <iostream>
|
||||
#include <cxxtest/TestSuite.h>
|
||||
|
||||
#include <xlnt/xlnt.hpp>
|
||||
#include <xlnt/reader/reader.hpp>
|
||||
#include <xlnt/cell/cell.hpp>
|
||||
#include <xlnt/cell/cell_reference.hpp>
|
||||
#include <xlnt/cell/comment.hpp>
|
||||
#include <xlnt/common/datetime.hpp>
|
||||
#include <xlnt/common/exceptions.hpp>
|
||||
#include <xlnt/reader/workbook_reader.hpp>
|
||||
#include <xlnt/styles/alignment.hpp>
|
||||
#include <xlnt/styles/borders.hpp>
|
||||
#include <xlnt/styles/font.hpp>
|
||||
#include <xlnt/styles/fill.hpp>
|
||||
#include <xlnt/styles/number_format.hpp>
|
||||
#include <xlnt/styles/protection.hpp>
|
||||
#include <xlnt/worksheet/range.hpp>
|
||||
#include <xlnt/worksheet/worksheet.hpp>
|
||||
#include <xlnt/workbook/workbook.hpp>
|
||||
|
||||
class test_cell : public CxxTest::TestSuite
|
||||
{
|
||||
|
@ -18,6 +31,23 @@ public:
|
|||
wb_guess_types.set_guess_types(true);
|
||||
}
|
||||
|
||||
void test_debug()
|
||||
{
|
||||
xlnt::workbook wb = xlnt::load_workbook("/Users/thomas/Development/xlnt/samples/sample1.xlsx");
|
||||
for(auto ws : wb)
|
||||
{
|
||||
for(auto row : ws.rows())
|
||||
{
|
||||
for(auto cell : row)
|
||||
{
|
||||
std::cout << cell << ", ";
|
||||
}
|
||||
|
||||
std::cout << std::endl;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void test_infer_numeric()
|
||||
{
|
||||
auto ws = wb_guess_types.create_sheet();
|
||||
|
@ -171,7 +201,7 @@ public:
|
|||
TS_ASSERT(cell.get_data_type() == xlnt::cell::type::numeric);
|
||||
TS_ASSERT(cell.get_value<long double>() == 40372.27616898148L);
|
||||
TS_ASSERT(cell.is_date());
|
||||
TS_ASSERT(cell.get_number_format() == "yyyy-mm-dd h:mm:ss");
|
||||
TS_ASSERT(cell.get_number_format().get_format_string() == "yyyy-mm-dd h:mm:ss");
|
||||
}
|
||||
|
||||
void test_insert_date()
|
||||
|
@ -183,7 +213,7 @@ public:
|
|||
TS_ASSERT(cell.get_data_type() == xlnt::cell::type::numeric);
|
||||
TS_ASSERT(cell.get_value<long double>() == 40372.L);
|
||||
TS_ASSERT(cell.is_date());
|
||||
TS_ASSERT(cell.get_number_format() == "yyyy-mm-dd");
|
||||
TS_ASSERT(cell.get_number_format().get_format_string() == "yyyy-mm-dd");
|
||||
}
|
||||
|
||||
void test_insert_time()
|
||||
|
@ -195,7 +225,7 @@ public:
|
|||
TS_ASSERT(cell.get_data_type() == xlnt::cell::type::numeric);
|
||||
TS_ASSERT(cell.get_value<long double>() == 0.04375L);
|
||||
TS_ASSERT(cell.is_date());
|
||||
TS_ASSERT(cell.get_number_format() == "h:mm:ss");
|
||||
TS_ASSERT(cell.get_number_format().get_format_string() == "h:mm:ss");
|
||||
}
|
||||
|
||||
void test_cell_formatted_as_date1()
|
||||
|
@ -279,7 +309,7 @@ public:
|
|||
TS_ASSERT(cell.get_value<long double>() == 1.125);
|
||||
TS_ASSERT(cell.get_data_type() == xlnt::cell::type::numeric);
|
||||
TS_ASSERT(!cell.is_date());
|
||||
TS_ASSERT(cell.get_number_format() == "[hh]:mm:ss");
|
||||
TS_ASSERT(cell.get_number_format().get_format_string() == "[hh]:mm:ss");
|
||||
}
|
||||
|
||||
void test_repr()
|
||||
|
@ -406,8 +436,8 @@ public:
|
|||
ws.get_parent().add_number_format("dd--hh--mm");
|
||||
|
||||
xlnt::cell cell(ws, "A1");
|
||||
cell.set_number_format("dd--hh--mm");
|
||||
TS_ASSERT(cell.get_number_format() == "dd--hh--mm");
|
||||
cell.set_number_format(xlnt::number_format("dd--hh--mm"));
|
||||
TS_ASSERT(cell.get_number_format().get_format_string() == "dd--hh--mm");
|
||||
}
|
||||
|
||||
void _test_alignment()
|
||||
|
@ -439,7 +469,7 @@ public:
|
|||
auto ws = wb.create_sheet();
|
||||
|
||||
xlnt::cell cell(ws, "A1");
|
||||
cell.get_style().set_pivot_button(true);
|
||||
cell.set_pivot_button(true);
|
||||
TS_ASSERT(cell.pivot_button());
|
||||
}
|
||||
|
||||
|
@ -448,7 +478,7 @@ public:
|
|||
auto ws = wb.create_sheet();
|
||||
|
||||
xlnt::cell cell(ws, "A1");
|
||||
cell.get_style().set_quote_prefix(true);
|
||||
cell.set_quote_prefix(true);
|
||||
TS_ASSERT(cell.quote_prefix());
|
||||
}
|
||||
};
|
||||
|
|
|
@ -93,7 +93,7 @@ public:
|
|||
{
|
||||
auto wb = workbook_with_styles();
|
||||
auto ws = wb["Sheet1"];
|
||||
auto code = ws.get_cell("A1").get_style().get_number_format().get_format_code();
|
||||
auto code = ws.get_cell("A1").get_number_format().get_format_code();
|
||||
auto expected = xlnt::number_format::format::general;
|
||||
TS_ASSERT_EQUALS(code, expected);
|
||||
}
|
||||
|
@ -102,7 +102,7 @@ public:
|
|||
{
|
||||
auto wb = workbook_with_styles();
|
||||
auto ws = wb["Sheet1"];
|
||||
auto code = ws.get_cell("A2").get_style().get_number_format().get_format_code();
|
||||
auto code = ws.get_cell("A2").get_number_format().get_format_code();
|
||||
auto expected = xlnt::number_format::format::date_xlsx14;
|
||||
TS_ASSERT_EQUALS(code, expected);
|
||||
}
|
||||
|
@ -111,7 +111,7 @@ public:
|
|||
{
|
||||
auto wb = workbook_with_styles();
|
||||
auto ws = wb["Sheet1"];
|
||||
auto code = ws.get_cell("A3").get_style().get_number_format().get_format_code();
|
||||
auto code = ws.get_cell("A3").get_number_format().get_format_code();
|
||||
auto expected = xlnt::number_format::format::number_00;
|
||||
TS_ASSERT_EQUALS(code, expected);
|
||||
}
|
||||
|
@ -120,7 +120,7 @@ public:
|
|||
{
|
||||
auto wb = workbook_with_styles();
|
||||
auto ws = wb["Sheet1"];
|
||||
auto code = ws.get_cell("A4").get_style().get_number_format().get_format_code();
|
||||
auto code = ws.get_cell("A4").get_number_format().get_format_code();
|
||||
auto expected = xlnt::number_format::format::date_time3;
|
||||
TS_ASSERT_EQUALS(code, expected);
|
||||
}
|
||||
|
@ -129,7 +129,7 @@ public:
|
|||
{
|
||||
auto wb = workbook_with_styles();
|
||||
auto ws = wb["Sheet1"];
|
||||
auto code = ws.get_cell("A5").get_style().get_number_format().get_format_code();
|
||||
auto code = ws.get_cell("A5").get_number_format().get_format_code();
|
||||
auto expected = xlnt::number_format::format::percentage_00;
|
||||
TS_ASSERT_EQUALS(code, expected);
|
||||
}
|
||||
|
@ -162,14 +162,14 @@ public:
|
|||
{
|
||||
auto wb = date_std_1900();
|
||||
auto ws = wb["Sheet1"];
|
||||
TS_ASSERT_EQUALS(ws.get_cell("A1").get_style().get_number_format().get_format_code(), xlnt::number_format::format::date_xlsx14);
|
||||
TS_ASSERT_EQUALS(ws.get_cell("A1").get_number_format().get_format_code(), xlnt::number_format::format::date_xlsx14);
|
||||
}
|
||||
|
||||
void test_read_date_style_mac()
|
||||
{
|
||||
auto wb = date_mac_1904();
|
||||
auto ws = wb["Sheet1"];
|
||||
TS_ASSERT_EQUALS(ws.get_cell("A1").get_style().get_number_format().get_format_code(), xlnt::number_format::format::date_xlsx14);
|
||||
TS_ASSERT_EQUALS(ws.get_cell("A1").get_number_format().get_format_code(), xlnt::number_format::format::date_xlsx14);
|
||||
}
|
||||
|
||||
void test_read_compare_mac_win_dates()
|
||||
|
|
|
@ -16,7 +16,7 @@ public:
|
|||
xlnt::workbook wbk;
|
||||
wbk.get_active_sheet().get_cell("A2").set_value("xlnt");
|
||||
wbk.get_active_sheet().get_cell("B5").set_value(88);
|
||||
wbk.get_active_sheet().get_cell("B5").get_style().set_number_format(xlnt::number_format(xlnt::number_format::format::percentage_00));
|
||||
wbk.get_active_sheet().get_cell("B5").set_number_format(xlnt::number_format(xlnt::number_format::format::percentage_00));
|
||||
wbk.save(temp_file.GetFilename());
|
||||
|
||||
if(PathHelper::FileExists(temp_file.GetFilename()))
|
||||
|
@ -97,17 +97,6 @@ public:
|
|||
TS_ASSERT(Helper::EqualsFileContent(PathHelper::GetDataDirectory() + "/writer/expected/sheet1_formula.xml", content));
|
||||
}
|
||||
|
||||
void test_write_style()
|
||||
{
|
||||
xlnt::workbook wb_guess_types;
|
||||
wb_guess_types.set_guess_types(true);
|
||||
auto ws = wb_guess_types.create_sheet();
|
||||
ws.get_cell("F1").set_value("13%");
|
||||
auto style_id_by_hash = xlnt::style_writer(wb_guess_types).get_style_by_hash();
|
||||
auto content = xlnt::write_worksheet(ws, {}, style_id_by_hash);
|
||||
TS_ASSERT(Helper::EqualsFileContent(PathHelper::GetDataDirectory() + "/writer/expected/sheet1_style.xml", content));
|
||||
}
|
||||
|
||||
void test_write_height()
|
||||
{
|
||||
auto ws = wb_.create_sheet();
|
||||
|
|
Loading…
Reference in New Issue
Block a user