clean up styles

This commit is contained in:
Thomas Fussell 2015-10-20 13:53:47 -04:00
parent c068255de4
commit cbab7a36cb
17 changed files with 217 additions and 399 deletions

View File

@ -56,12 +56,7 @@ public:
bool operator==(const alignment &other) const bool operator==(const alignment &other) const
{ {
return horizontal_ == other.horizontal_ return hash() == other.hash();
&& vertical_ == other.vertical_
&& text_rotation_ == other.text_rotation_
&& wrap_text_ == other.wrap_text_
&& shrink_to_fit_ == other.shrink_to_fit_
&& indent_ == other.indent_;
} }
std::size_t hash() const { return 0; } std::size_t hash() const { return 0; }

View File

@ -100,10 +100,7 @@ public:
bool operator==(const border &other) const bool operator==(const border &other) const
{ {
return start.value == other.start.value return hash() == other.hash();
&& outline == other.outline
&& diagonal_up == other.diagonal_up
&& diagonal_down == other.diagonal_down;
} }
std::size_t hash() const { return 0; } std::size_t hash() const { return 0; }

View File

@ -62,7 +62,7 @@ public:
virtual bool operator==(const fill &other) const virtual bool operator==(const fill &other) const
{ {
return type_ == other.type_; return hash() == other.hash();
} }
virtual std::size_t hash() const { return 0; } virtual std::size_t hash() const { return 0; }

View File

@ -47,15 +47,7 @@ public:
bool operator==(const font &other) const bool operator==(const font &other) const
{ {
return name_ == other.name_ return hash() == other.hash();
&& size_ == other.size_
&& bold_ == other.bold_
&& italic_ == other.italic_
&& superscript_ == other.superscript_
&& subscript_ == other.subscript_
&& underline_ == other.underline_
&& strikethrough_ == other.strikethrough_
&& color_ == other.color_;
} }
int get_size() const { return size_; } int get_size() const { return size_; }

View File

@ -88,6 +88,12 @@ public:
static bool is_builtin(const std::string &format); static bool is_builtin(const std::string &format);
static const number_format &default_number_format()
{
static number_format default_;
return default_;
}
number_format(); number_format();
number_format(format code); number_format(format code);
number_format(const std::string &code); number_format(const std::string &code);
@ -103,6 +109,11 @@ public:
std::size_t hash() const; std::size_t hash() const;
bool operator==(const number_format &other) const
{
return hash() == other.hash();
}
private: private:
format format_code_; format format_code_;
int format_index_; int format_index_;

View File

@ -47,7 +47,7 @@ public:
bool operator==(const protection &other) const bool operator==(const protection &other) const
{ {
return locked_ == other.locked_ && hidden_ == other.hidden_; return hash() == other.hash();
} }
std::size_t hash() const { return 0; } std::size_t hash() const { return 0; }

View File

@ -23,55 +23,68 @@
// @author: see AUTHORS file // @author: see AUTHORS file
#pragma once #pragma once
#include "alignment.hpp"
#include "borders.hpp"
#include "fill.hpp"
#include "font.hpp"
#include "number_format.hpp"
#include "protection.hpp"
namespace xlnt { namespace xlnt {
namespace detail {
struct cell_impl; class workbook;
} // namespace detail
class alignment;
class border;
class font;
class fill;
class number_format;
class protection;
class cell;
class style class style
{ {
public: public:
const style default_style();
style(); style();
style(const style &rhs);
style &operator=(const style &rhs);
style copy() const;
std::size_t hash() const; std::size_t hash() const;
const font &get_font() const; const alignment get_alignment() const;
const fill &get_fill() const; const border get_border() const;
const border &get_border() const; const fill get_fill() const;
const alignment &get_alignment() const; const font get_font() const;
const number_format &get_number_format() const; const number_format get_number_format() const;
const protection &get_protection() const; const protection get_protection() const;
bool pivot_button() const; bool pivot_button() const;
bool quote_prefix() const; bool quote_prefix() const;
std::size_t get_fill_index() const { return fill_index_; }
std::size_t get_font_index() const { return font_index_; }
std::size_t get_border_index() const { return border_index_; }
std::size_t get_number_format_index() const { return number_format_index_; }
bool operator==(const style &other) const
{
return hash() == other.hash();
}
private: private:
cell get_parent(); friend class workbook;
const cell get_parent() const;
detail::cell_impl *parent_; std::size_t style_index_;
std::size_t font_id_;
std::size_t fill_id_; std::size_t alignment_index_;
std::size_t border_id_; alignment alignment_;
std::size_t alignment_id_;
std::size_t number_format_id_; std::size_t border_index_;
std::size_t protection_id_; border border_;
std::size_t style_id_;
std::size_t fill_index_;
fill fill_;
std::size_t font_index_;
font font_;
std::size_t number_format_index_;
number_format number_format_;
std::size_t protection_index_;
protection protection_;
bool pivot_button_;
bool quote_prefix_;
}; };
} // namespace xlnt } // namespace xlnt

View File

@ -208,7 +208,7 @@ public:
void add_color(color c); void add_color(color c);
void add_number_format(const std::string &format); void add_number_format(const std::string &format);
std::vector<std::array<int, 4>> get_styles() const; std::vector<style> get_styles() const;
std::vector<alignment> get_alignments() const; std::vector<alignment> get_alignments() const;
std::vector<border> get_borders() const; std::vector<border> get_borders() const;

View File

@ -1034,9 +1034,20 @@ std::size_t cell::get_xf_index() const
} }
const number_format &cell::get_number_format() const const number_format &cell::get_number_format() const
{
if(d_->has_style_)
{ {
return get_parent().get_parent().get_number_format(d_->style_id_); return get_parent().get_parent().get_number_format(d_->style_id_);
} }
else if(get_parent().get_parent().get_number_formats().empty())
{
return number_format::default_number_format();
}
else
{
return get_parent().get_parent().get_number_formats().front();
}
}
const font &cell::get_font() const const font &cell::get_font() const
{ {
@ -1187,6 +1198,7 @@ timedelta cell::get_value() const
void cell::set_number_format(const number_format &number_format_) void cell::set_number_format(const number_format &number_format_)
{ {
d_->has_style_ = true;
d_->style_id_ = get_parent().get_parent().set_number_format(number_format_, d_->style_id_); d_->style_id_ = get_parent().get_parent().set_number_format(number_format_, d_->style_id_);
} }

View File

@ -23,7 +23,8 @@ cell_impl::cell_impl(worksheet_impl *parent, column_t column, row_t row)
has_hyperlink_(false), has_hyperlink_(false),
is_merged_(false), is_merged_(false),
xf_index_(0), xf_index_(0),
style_id_(1), has_style_(false),
style_id_(0),
comment_(nullptr) comment_(nullptr)
{ {
} }

View File

@ -196,6 +196,8 @@ struct cell_impl
bool is_merged_; bool is_merged_;
std::size_t xf_index_; std::size_t xf_index_;
bool has_style_;
std::size_t style_id_; std::size_t style_id_;
std::unique_ptr<comment_impl> comment_; std::unique_ptr<comment_impl> comment_;

View File

@ -18,21 +18,13 @@ struct workbook_impl
properties_(other.properties_), properties_(other.properties_),
guess_types_(other.guess_types_), guess_types_(other.guess_types_),
data_only_(other.data_only_), data_only_(other.data_only_),
next_style_id_(other.next_style_id_), styles_(other.styles_),
alignments_(other.alignments_), alignments_(other.alignments_),
borders_(other.borders_), borders_(other.borders_),
fills_(other.fills_), fills_(other.fills_),
fonts_(other.fonts_), fonts_(other.fonts_),
number_formats_(other.number_formats_), number_formats_(other.number_formats_),
protections_(other.protections_), 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_)
{ {
} }
@ -48,21 +40,13 @@ struct workbook_impl
properties_ = other.properties_; properties_ = other.properties_;
guess_types_ = other.guess_types_; guess_types_ = other.guess_types_;
data_only_ = other.data_only_; data_only_ = other.data_only_;
next_style_id_ = other.next_style_id_; styles_ = other.styles_;
alignments_ = other.alignments_; alignments_ = other.alignments_;
borders_ = other.borders_; borders_ = other.borders_;
fills_ = other.fills_; fills_ = other.fills_;
fonts_ = other.fonts_; fonts_ = other.fonts_;
number_formats_ = other.number_formats_; number_formats_ = other.number_formats_;
protections_ = other.protections_; 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; return *this;
} }
@ -71,25 +55,21 @@ struct workbook_impl
std::vector<worksheet_impl> worksheets_; std::vector<worksheet_impl> worksheets_;
std::vector<relationship> relationships_; std::vector<relationship> relationships_;
std::vector<drawing> drawings_; std::vector<drawing> drawings_;
document_properties properties_; document_properties properties_;
bool guess_types_; bool guess_types_;
bool data_only_; bool data_only_;
std::size_t next_style_id_; std::vector<style> styles_;
std::unordered_map<std::size_t, alignment> alignments_;
std::unordered_map<std::size_t, border> borders_; std::vector<alignment> alignments_;
std::unordered_map<std::size_t, fill> fills_; std::vector<border> borders_;
std::unordered_map<std::size_t, font> fonts_; std::vector<fill> fills_;
std::unordered_map<std::size_t, number_format> number_formats_; std::vector<font> fonts_;
std::unordered_map<std::size_t, protection> protections_; std::vector<number_format> number_formats_;
std::unordered_map<std::size_t, std::size_t> style_alignment_; std::vector<protection> protections_;
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 } // namespace detail

View File

@ -178,6 +178,10 @@ void read_worksheet_common(xlnt::worksheet ws, const pugi::xml_node &root_node,
} }
} }
} }
else
{
ws.get_cell(address).set_number_format(xlnt::number_format(xlnt::number_format::format::general));
}
} }
} }
} }

View File

@ -22,17 +22,9 @@ style::style()
{ {
} }
style::style(const style &other)
{
}
const cell style::get_parent() const
{
return cell(parent_);
}
std::size_t style::hash() const std::size_t style::hash() const
{ {
/*
std::size_t seed = 100; std::size_t seed = 100;
std::hash<std::string> string_hash; std::hash<std::string> string_hash;
auto font_ = get_font(); auto font_ = get_font();
@ -45,48 +37,51 @@ std::size_t style::hash() const
bools = bools << 1 & font_.superscript_; bools = bools << 1 & font_.superscript_;
bools = bools << 1 & font_.subscript_; bools = bools << 1 & font_.subscript_;
hash_combine(seed, bools); hash_combine(seed, bools);
*/
std::size_t seed = 100;
hash_combine(seed, number_format_.hash());
return seed; return seed;
} }
const number_format &style::get_number_format() const const number_format style::get_number_format() const
{ {
return get_parent().get_number_format(); return number_format_;
} }
const border &style::get_border() const const border style::get_border() const
{ {
return get_parent().get_border(); return border_;
} }
const alignment &style::get_alignment() const const alignment style::get_alignment() const
{ {
return get_parent().get_alignment(); return alignment_;
} }
const fill &style::get_fill() const const fill style::get_fill() const
{ {
return get_parent().get_fill(); return fill_;
} }
const font &style::get_font() const const font style::get_font() const
{ {
return get_parent().get_font(); return font_;
} }
const protection &style::get_protection() const const protection style::get_protection() const
{ {
return get_parent().get_protection(); return protection_;
} }
bool style::pivot_button() const bool style::pivot_button() const
{ {
return get_parent().pivot_button(); return pivot_button_;
} }
bool style::quote_prefix() const bool style::quote_prefix() const
{ {
return get_parent().quote_prefix(); return quote_prefix_;
} }
} // namespace xlnt } // namespace xlnt

View File

@ -106,11 +106,11 @@ std::string style_writer::write_table() const
for(auto &style : styles) for(auto &style : styles)
{ {
xf_node = cell_xfs_node.append_child("xf"); xf_node = cell_xfs_node.append_child("xf");
xf_node.append_attribute("numFmtId").set_value(static_cast<int>(style[3])); xf_node.append_attribute("numFmtId").set_value((int)style.get_number_format_index());
xf_node.append_attribute("applyNumberFormat").set_value(1); xf_node.append_attribute("applyNumberFormat").set_value(1);
xf_node.append_attribute("fontId").set_value(static_cast<int>(style[2])); xf_node.append_attribute("fontId").set_value((int)style.get_font_index());
xf_node.append_attribute("fillId").set_value(static_cast<int>(style[1])); xf_node.append_attribute("fillId").set_value((int)style.get_fill_index());
xf_node.append_attribute("borderId").set_value(static_cast<int>(style[0])); xf_node.append_attribute("borderId").set_value((int)style.get_border_index());
auto alignment_node = xf_node.append_child("alignment"); auto alignment_node = xf_node.append_child("alignment");
alignment_node.append_attribute("vertical").set_value("top"); alignment_node.append_attribute("vertical").set_value("top");

View File

@ -69,7 +69,7 @@ void hash_combine(std::size_t& seed, const T& v)
namespace xlnt { namespace xlnt {
namespace detail { namespace detail {
workbook_impl::workbook_impl() : active_sheet_index_(0), guess_types_(false), data_only_(false), next_style_id_(2) workbook_impl::workbook_impl() : active_sheet_index_(0), guess_types_(false), data_only_(false)
{ {
} }
@ -81,22 +81,6 @@ workbook::workbook() : d_(new detail::workbook_impl())
create_relationship("rId2", "sharedStrings.xml", relationship::type::shared_strings); create_relationship("rId2", "sharedStrings.xml", relationship::type::shared_strings);
create_relationship("rId3", "styles.xml", relationship::type::styles); create_relationship("rId3", "styles.xml", relationship::type::styles);
create_relationship("rId4", "theme/theme1.xml", relationship::type::theme); create_relationship("rId4", "theme/theme1.xml", relationship::type::theme);
d_->alignments_[alignment().hash()] = alignment();
d_->borders_[border().hash()] = border();
d_->fills_[fill().hash()] = fill();
d_->fonts_[font().hash()] = font();
d_->number_formats_[number_format().hash()] = number_format();
d_->protections_[protection().hash()] = protection();
d_->style_alignment_[1] = alignment().hash();
d_->style_border_[1] = border().hash();
d_->style_font_[1] = font().hash();
d_->style_fill_[1] = fill().hash();
d_->style_number_format_[1] = number_format().hash();
d_->style_protection_[1] = protection().hash();
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) workbook::iterator::iterator(workbook &wb, std::size_t index) : wb_(wb), index_(index)
@ -753,313 +737,168 @@ std::size_t workbook::add_style(xlnt::style style_)
const number_format &workbook::get_number_format(std::size_t style_id) const const number_format &workbook::get_number_format(std::size_t style_id) const
{ {
return d_->number_formats_[d_->style_number_format_[style_id]]; return d_->number_formats_[d_->styles_[style_id].number_format_index_];
} }
const font &workbook::get_font(std::size_t style_id) const const font &workbook::get_font(std::size_t style_id) const
{ {
return d_->fonts_[d_->style_font_[style_id]]; return d_->fonts_[d_->styles_[style_id].font_index_];
} }
std::size_t workbook::set_font(const font &font_, std::size_t style_id) std::size_t workbook::set_font(const font &font_, std::size_t style_id)
{ {
auto hash = font_.hash(); auto match = std::find(d_->fonts_.begin(), d_->fonts_.end(), font_);
auto font_index = 0;
if(d_->number_formats_.find(hash) == d_->number_formats_.end()) if(match == d_->fonts_.end())
{ {
d_->fonts_[hash] = font_; d_->fonts_.push_back(font_);
font_index = d_->fonts_.size() - 1;
}
else
{
font_index = match - d_->fonts_.begin();
} }
d_->style_font_[d_->next_style_id_] = hash; auto existing_style = d_->styles_[style_id];
d_->style_alignment_[d_->next_style_id_] = d_->style_alignment_[style_id]; if(font_index == existing_style.font_index_)
d_->style_border_[d_->next_style_id_] = d_->style_border_[style_id]; {
d_->style_fill_[d_->next_style_id_] = d_->style_fill_[style_id]; // no change
d_->style_number_format_[d_->next_style_id_] = d_->style_number_format_[style_id]; return 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_++; auto new_style = existing_style;
new_style.font_index_ = font_index;
auto style_match = std::find(d_->styles_.begin(), d_->styles_.end(), new_style);
if(style_match != d_->styles_.end())
{
return style_match - d_->styles_.begin();
}
d_->styles_.push_back(new_style);
return d_->styles_.size() - 1;
} }
const fill &workbook::get_fill(std::size_t style_id) const const fill &workbook::get_fill(std::size_t style_id) const
{ {
return d_->fills_[d_->style_fill_[style_id]]; return d_->fills_[d_->styles_[style_id].fill_index_];
} }
std::size_t workbook::set_fill(const fill &fill_, std::size_t style_id) std::size_t workbook::set_fill(const fill &fill_, std::size_t style_id)
{ {
auto hash = fill_.hash(); return style_id;
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 const border &workbook::get_border(std::size_t style_id) const
{ {
return d_->borders_[d_->style_border_[style_id]]; return d_->borders_[d_->styles_[style_id].border_index_];
} }
std::size_t workbook::set_border(const border &border_, std::size_t style_id) std::size_t workbook::set_border(const border &border_, std::size_t style_id)
{ {
auto hash = border_.hash(); return style_id;
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 const alignment &workbook::get_alignment(std::size_t style_id) const
{ {
return d_->alignments_[d_->style_alignment_[style_id]]; return d_->alignments_[d_->styles_[style_id].alignment_index_];
} }
std::size_t workbook::set_alignment(const alignment &alignment_, std::size_t style_id) std::size_t workbook::set_alignment(const alignment &alignment_, std::size_t style_id)
{ {
auto hash = alignment_.hash(); return style_id;
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 const protection &workbook::get_protection(std::size_t style_id) const
{ {
return d_->protections_[d_->style_protection_[style_id]]; return d_->protections_[d_->styles_[style_id].number_format_index_];
} }
std::size_t workbook::set_protection(const protection &protection_, std::size_t style_id) std::size_t workbook::set_protection(const protection &protection_, std::size_t style_id)
{ {
auto hash = protection_.hash(); return style_id;
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 bool workbook::get_pivot_button(std::size_t style_id) const
{ {
return d_->style_pivot_button_[style_id]; return d_->styles_[style_id].pivot_button_;
} }
bool workbook::get_quote_prefix(std::size_t style_id) const bool workbook::get_quote_prefix(std::size_t style_id) const
{ {
return d_->style_quote_prefix_[style_id]; return d_->styles_[style_id].quote_prefix_;
} }
std::size_t workbook::set_number_format(const xlnt::number_format &format, std::size_t style_id) std::size_t workbook::set_number_format(const xlnt::number_format &format, std::size_t style_id)
{ {
auto hash = format.hash(); auto match = std::find(d_->number_formats_.begin(), d_->number_formats_.end(), format);
auto format_index = 0;
if(d_->number_formats_.find(hash) == d_->number_formats_.end()) if(match == d_->number_formats_.end())
{ {
d_->number_formats_[hash] = format; d_->number_formats_.push_back(format);
format_index = d_->number_formats_.size() - 1;
}
else
{
format_index = match - d_->number_formats_.begin();
} }
d_->style_number_format_[d_->next_style_id_] = hash; if(d_->styles_.empty())
{
d_->style_alignment_[d_->next_style_id_] = d_->style_alignment_[style_id]; style new_style;
d_->style_border_[d_->next_style_id_] = d_->style_border_[style_id]; new_style.style_index_ = 0;
d_->style_font_[d_->next_style_id_] = d_->style_font_[style_id]; new_style.alignment_index_ = 0;
d_->style_fill_[d_->next_style_id_] = d_->style_fill_[style_id]; new_style.border_index_ = 0;
d_->style_protection_[d_->next_style_id_] = d_->style_protection_[style_id]; new_style.fill_index_ = 0;
d_->style_pivot_button_[d_->next_style_id_] = d_->style_pivot_button_[style_id]; new_style.font_index_ = 0;
d_->style_quote_prefix_[d_->next_style_id_] = d_->style_quote_prefix_[style_id]; new_style.number_format_index_ = format_index;
new_style.protection_index_ = 0;
return d_->next_style_id_++; d_->styles_.push_back(new_style);
return 0;
} }
std::vector<alignment> workbook::get_alignments() const auto existing_style = d_->styles_[style_id];
{
std::vector<alignment> alignments;
for(auto &pair : d_->alignments_) if(format_index == existing_style.number_format_index_)
{ {
alignments.push_back(pair.second); // no change
return style_id;
} }
return alignments; auto new_style = existing_style;
new_style.number_format_index_ = format_index;
new_style.number_format_ = format;
auto style_match = std::find(d_->styles_.begin(), d_->styles_.end(), new_style);
if(style_match != d_->styles_.end())
{
return style_match - d_->styles_.begin();
} }
std::vector<border> workbook::get_borders() const d_->styles_.push_back(new_style);
{
std::vector<border> borders;
for(auto &pair : d_->borders_) return d_->styles_.size() - 1;
{
borders.push_back(pair.second);
} }
return borders; std::vector<style> workbook::get_styles() const
}
std::vector<fill> workbook::get_fills() const
{ {
std::vector<fill> fills; return d_->styles_;
for(auto &pair : d_->fills_)
{
fills.push_back(pair.second);
}
return fills;
}
std::vector<font> workbook::get_fonts() const
{
std::vector<font> fonts;
for(auto &pair : d_->fonts_)
{
fonts.push_back(pair.second);
}
return fonts;
} }
std::vector<number_format> workbook::get_number_formats() const std::vector<number_format> workbook::get_number_formats() const
{ {
std::vector<number_format> number_formats; return d_->number_formats_;
for(auto &pair : d_->number_formats_)
{
number_formats.push_back(pair.second);
} }
return number_formats; std::vector<font> workbook::get_fonts() const
}
std::vector<protection> workbook::get_protections() const
{ {
std::vector<protection> protections; return d_->fonts_;
for(auto &pair : d_->protections_)
{
protections.push_back(pair.second);
}
return protections;
}
std::vector<std::array<int, 4>> workbook::get_styles() const
{
auto borders = get_borders();
auto fills = get_fills();
auto fonts = get_fonts();
auto number_formats = get_number_formats();
std::unordered_map<std::size_t, std::array<int, 4>> styles;
for(std::size_t i = 1; i < d_->next_style_id_; i++)
{
std::array<std::size_t, 4> style_hashes = {d_->style_border_[i], d_->style_fill_[i], d_->style_font_[i], d_->style_number_format_[i]};
std::array<int, 4> style = {-1, -1, -1, -1};
for(std::size_t i = 0; i < borders.size(); i++)
{
if(borders[i].hash() == style_hashes[0])
{
style[0] = i;
break;
}
}
for(std::size_t i = 0; i < fills.size(); i++)
{
if(fills[i].hash() == style_hashes[1])
{
style[1] = i;
break;
}
}
for(std::size_t i = 0; i < fonts.size(); i++)
{
if(fonts[i].hash() == style_hashes[2])
{
style[2] = i;
break;
}
}
for(std::size_t i = 0; i < number_formats.size(); i++)
{
if(number_formats[i].hash() == style_hashes[3])
{
style[3] = i;
break;
}
}
std::size_t seed = style[0];
hash_combine(seed, style[1]);
hash_combine(seed, style[2]);
hash_combine(seed, style[3]);
styles[seed] = style;
}
std::vector<std::array<int, 4>> styles_vector;
for(auto &pair : styles)
{
styles_vector.push_back(pair.second);
}
return styles_vector;
} }
} // namespace xlnt } // namespace xlnt

View File

@ -126,11 +126,6 @@ std::string write_worksheet(worksheet ws, const std::vector<std::string> &string
std::unordered_map<std::string, std::string> hyperlink_references; std::unordered_map<std::string, std::string> hyperlink_references;
auto sheet_data_node = root_node.append_child("sheetData"); auto sheet_data_node = root_node.append_child("sheetData");
const auto &styles = ws.get_parent().get_styles();
auto borders = ws.get_parent().get_borders();
auto fills = ws.get_parent().get_fills();
auto fonts = ws.get_parent().get_fonts();
auto number_formats = ws.get_parent().get_number_formats();
for(auto row : ws.rows()) for(auto row : ws.rows())
{ {
@ -270,25 +265,7 @@ std::string write_worksheet(worksheet ws, const std::vector<std::string> &string
} }
auto style_id = cell.get_style_id(); auto style_id = cell.get_style_id();
auto border = ws.get_parent().get_border(style_id); cell_node.append_attribute("s").set_value((int)style_id);
auto font = ws.get_parent().get_font(style_id);
auto fill = ws.get_parent().get_fill(style_id);
auto num_format = ws.get_parent().get_number_format(style_id);
int style_index = 0;
for(auto &style : styles)
{
if(borders[style.at(0)].hash() == border.hash()
&& fonts[style.at(1)].hash() == font.hash()
&& fills[style.at(2)].hash() == fill.hash()
&& number_formats[style.at(3)].hash() == num_format.hash())
{
cell_node.append_attribute("s").set_value(style_index);
break;
}
style_index++;
}
} }
} }
} }