mirror of
https://github.com/tfussell/xlnt.git
synced 2024-03-22 13:11:17 +08:00
refactor styles... again
This commit is contained in:
parent
4e9c48eba9
commit
85e1b4a333
|
@ -38,7 +38,6 @@ enum class calendar;
|
|||
class alignment;
|
||||
class border;
|
||||
class cell_reference;
|
||||
class cell_style;
|
||||
class comment;
|
||||
class fill;
|
||||
class font;
|
||||
|
@ -46,6 +45,7 @@ class format;
|
|||
class number_format;
|
||||
class protection;
|
||||
class relationship;
|
||||
class style;
|
||||
class workbook;
|
||||
class worksheet;
|
||||
|
||||
|
@ -205,6 +205,26 @@ public:
|
|||
const format &get_format() const;
|
||||
|
||||
void set_format(const format &new_format);
|
||||
|
||||
void clear_format();
|
||||
|
||||
// style
|
||||
|
||||
/// <summary>
|
||||
/// Return true if this cell has had a format applied to it.
|
||||
/// </summary>
|
||||
bool has_style() const;
|
||||
|
||||
/// <summary>
|
||||
/// Return a reference to the format applied to this cell.
|
||||
/// </summary>
|
||||
const style &get_style() const;
|
||||
|
||||
void set_style(const style &new_style);
|
||||
|
||||
void set_style(const std::string &style_name);
|
||||
|
||||
void clear_style();
|
||||
|
||||
/// <summary>
|
||||
/// Return the number format of this cell.
|
||||
|
|
|
@ -30,6 +30,7 @@
|
|||
|
||||
#include <xlnt/xlnt_config.hpp>
|
||||
#include <xlnt/packaging/zip_file.hpp>
|
||||
#include <detail/stylesheet.hpp>
|
||||
|
||||
namespace xlnt {
|
||||
|
||||
|
@ -93,6 +94,8 @@ public:
|
|||
/// binary data to stream.
|
||||
/// </summary>
|
||||
bool save_stream_workbook(std::ostream &stream, bool as_template = false);
|
||||
|
||||
xlnt::detail::stylesheet &get_stylesheet();
|
||||
|
||||
private:
|
||||
/// <summary>
|
||||
|
|
|
@ -28,8 +28,6 @@
|
|||
#include <vector>
|
||||
|
||||
#include <xlnt/xlnt_config.hpp>
|
||||
#include <xlnt/styles/style.hpp>
|
||||
#include <xlnt/workbook/workbook.hpp>
|
||||
|
||||
namespace xlnt {
|
||||
|
||||
|
@ -40,7 +38,7 @@ class conditional_format;
|
|||
class fill;
|
||||
class font;
|
||||
class format;
|
||||
class formattable;
|
||||
class base_format;
|
||||
class style;
|
||||
class number_format;
|
||||
class protection;
|
||||
|
@ -49,8 +47,10 @@ class style;
|
|||
class xml_document;
|
||||
class xml_node;
|
||||
|
||||
namespace detail { struct stylesheet; }
|
||||
|
||||
/// <summary>
|
||||
/// Reads and writes xl/styles.xml from/to an associated workbook.
|
||||
/// Reads and writes xl/styles.xml from/to an associated stylesheet.
|
||||
/// </summary>
|
||||
class XLNT_CLASS style_serializer
|
||||
{
|
||||
|
@ -58,11 +58,7 @@ public:
|
|||
/// <summary>
|
||||
/// Construct a style_serializer which can write styles.xml based on wb or populate wb
|
||||
/// with styles from an existing styles.xml.
|
||||
style_serializer(workbook &wb);
|
||||
|
||||
//
|
||||
// Primary methods
|
||||
//
|
||||
style_serializer(detail::stylesheet &s);
|
||||
|
||||
/// <summary>
|
||||
/// Load all styles from xml_document into workbook given in constructor.
|
||||
|
@ -73,204 +69,13 @@ public:
|
|||
/// Populate parameter xml with an XML tree representing the styles contained in the workbook
|
||||
/// given in the constructor.
|
||||
/// </summary>
|
||||
xml_document write_stylesheet();
|
||||
bool write_stylesheet(xml_document &xml);
|
||||
|
||||
// TODO: These need to be public for unit tests. Could also make test class a friend?
|
||||
// private:
|
||||
|
||||
//
|
||||
// Static element readers (i.e. readers that don't use internal state)
|
||||
//
|
||||
|
||||
/// <summary>
|
||||
/// Read and return an alignment from alignment_node.
|
||||
/// </summary>
|
||||
static alignment read_alignment(const xml_node &alignment_node);
|
||||
|
||||
/// <summary>
|
||||
/// Read and return a border side from side_node.
|
||||
/// </summary>
|
||||
static side read_side(const xml_node &side_node);
|
||||
|
||||
/// <summary>
|
||||
/// Read and return a border from border_node.
|
||||
/// </summary>
|
||||
static border read_border(const xml_node &border_node);
|
||||
|
||||
/// <summary>
|
||||
/// Read and return a fill from fill_node.
|
||||
/// </summary>
|
||||
static fill read_fill(const xml_node &fill_node);
|
||||
|
||||
/// <summary>
|
||||
/// Read and return a font from font_node.
|
||||
/// </summary>
|
||||
static font read_font(const xml_node &font_node);
|
||||
|
||||
/// <summary>
|
||||
/// Read and return a number format from number_format_node.
|
||||
/// </summary>
|
||||
static number_format read_number_format(const xml_node &number_format_node);
|
||||
|
||||
/// <summary>
|
||||
/// Read and return a protection from protection_node.
|
||||
/// </summary>
|
||||
static protection read_protection(const xml_node &protection_node);
|
||||
|
||||
/// <summary>
|
||||
/// Read and return all indexed colors from indexed_colors_node.
|
||||
/// </summary>
|
||||
static std::vector<color> read_indexed_colors(const xml_node &indexed_colors_node);
|
||||
|
||||
/// <summary>
|
||||
/// Read and return a color from color_node.
|
||||
/// </summary>
|
||||
static color read_color(const xml_node &color_node);
|
||||
|
||||
/// <summary>
|
||||
/// Read and return a conditional format, dxf, from conditional_format_node.
|
||||
/// </summary>
|
||||
static conditional_format read_conditional_format(const xml_node &conditional_formats_node);
|
||||
|
||||
/// <summary>
|
||||
/// Read a single format from the given node. In styles.xml, this is an "xf" element.
|
||||
/// A format has an optional border id, fill id, font id, and number format id where
|
||||
/// each id is an index in the corresponding list of borders, etc. A style also has
|
||||
/// optional alignment and protection children. A style also defines whether each of
|
||||
/// these is "applied". For example, a style with a defined font id, font=# but with
|
||||
/// "applyFont=0" will not use the font in formatting.
|
||||
/// </summary>
|
||||
format read_format(const xml_node &format_node);
|
||||
|
||||
/// <summary>
|
||||
/// Read a single named style from the given named_style_node. In styles.xml, this is a
|
||||
/// (confusingly named) "cellStyle" element. This node defines the name, whether it is
|
||||
/// built-in and an xfId which is the index of an element in cellStyleXfs. style_format_node
|
||||
/// should be the XML node of the element at the index of xfId.
|
||||
/// </summary>
|
||||
style read_style(const xml_node &style_node, const xml_node &style_format_node);
|
||||
|
||||
//
|
||||
// Non-static element readers (i.e. readers that modify internal state)
|
||||
//
|
||||
|
||||
bool read_number_formats(const xml_node &number_formats_node);
|
||||
|
||||
/// <summary>
|
||||
/// Read all borders from borders_node and add them to workbook.
|
||||
/// Return true on success.
|
||||
/// </summary>
|
||||
bool read_borders(const xml_node &borders_node);
|
||||
|
||||
/// <summary>
|
||||
/// Read all fills from fills_node and add them to workbook.
|
||||
/// Return true on success.
|
||||
/// </summary>
|
||||
bool read_fills(const xml_node &fills_node);
|
||||
|
||||
/// <summary>
|
||||
/// Read all fonts from fonts_node and add them to workbook.
|
||||
/// Return true on success.
|
||||
/// </summary>
|
||||
bool read_fonts(const xml_node &fonts_node);
|
||||
|
||||
/// <summary>
|
||||
/// Read all colors from colors_node and add them to workbook.
|
||||
/// Return true on success.
|
||||
/// </summary>
|
||||
bool read_colors(const xml_node &colors_node);
|
||||
|
||||
/// <summary>
|
||||
/// Read all cell styles from cell_styles_node and add them to workbook.
|
||||
/// Return true on success.
|
||||
/// </summary>
|
||||
bool read_formats(const xml_node &formats_node);
|
||||
|
||||
/// <summary>
|
||||
/// Read all named styles from named_style_node and cell_styles_node and add them to workbook.
|
||||
/// Return true on success.
|
||||
/// </summary>
|
||||
bool read_styles(const xml_node &styles_node, const xml_node &style_formats_node);
|
||||
|
||||
/// <summary>
|
||||
/// Read all borders from number_formats_node and add them to workbook.
|
||||
/// Return true on success.
|
||||
/// </summary>
|
||||
bool read_stylesheet(const xml_node &number_formats_node);
|
||||
|
||||
//
|
||||
// Non-static element writers (i.e. writers that modify internal workbook)
|
||||
//
|
||||
|
||||
/// <summary>
|
||||
/// Build an xml tree representing all borders in workbook into borders_node.
|
||||
/// Returns true on success.
|
||||
/// </summary>
|
||||
bool write_borders(xml_node &borders_node) const;
|
||||
|
||||
/// <summary>
|
||||
/// Build an xml tree representing all conditional formats in workbook into conditional_formats_node.
|
||||
/// Returns true on success.
|
||||
/// </summary>
|
||||
bool write_conditional_formats(xml_node &conditional_formats_node) const;
|
||||
|
||||
/// <summary>
|
||||
/// Build an xml tree representing all fills in workbook into fills_node.
|
||||
/// Returns true on success.
|
||||
/// </summary>
|
||||
bool write_fills(xml_node &fills_node) const;
|
||||
|
||||
/// <summary>
|
||||
/// Build an xml tree representing all fonts in workbook into fonts_node.
|
||||
/// Returns true on success.
|
||||
/// </summary>
|
||||
bool write_fonts(xml_node &fonts_node) const;
|
||||
|
||||
/// <summary>
|
||||
/// Build an xml tree representing all number formats in workbook into number_formats_node.
|
||||
/// Returns true on success.
|
||||
/// </summary>
|
||||
bool write_number_formats(xml_node &number_formats_node) const;
|
||||
|
||||
bool write_formattable(const formattable &xf, xml_node xf_node) const;
|
||||
|
||||
/// <summary>
|
||||
/// Build an xml tree representing the given style into style_node.
|
||||
/// Returns true on success.
|
||||
/// </summary>
|
||||
bool write_formats(xml_node &styles_node) const;
|
||||
|
||||
bool write_styles(xml_node &cell_styles_node, xml_node &cell_style_formats_node) const;
|
||||
|
||||
bool write_colors(xml_node &colors_node) const;
|
||||
|
||||
bool write_ext_list(xml_node &ext_list_node) const;
|
||||
|
||||
const std::vector<border> &get_borders() const;
|
||||
|
||||
const std::vector<fill> &get_fills() const;
|
||||
|
||||
const std::vector<font> &get_fonts() const;
|
||||
|
||||
const std::vector<number_format> &get_number_formats() const;
|
||||
|
||||
const std::vector<color> &get_colors() const;
|
||||
|
||||
private:
|
||||
void initialize_vectors();
|
||||
|
||||
/// <summary>
|
||||
/// Set in the constructor, this workbook is used as the source or target for all writing or reading, respectively.
|
||||
/// Set in the constructor, this stylesheet is used as the source or target for all writing or reading, respectively.
|
||||
/// </summary>
|
||||
workbook &workbook_;
|
||||
|
||||
std::vector<color> colors_;
|
||||
std::vector<border> borders_;
|
||||
std::vector<fill> fills_;
|
||||
std::vector<font> fonts_;
|
||||
std::vector<number_format> number_formats_;
|
||||
std::vector<format> formats_;
|
||||
std::vector<style> styles_;
|
||||
detail::stylesheet &stylesheet_;
|
||||
};
|
||||
|
||||
} // namespace xlnt
|
||||
|
|
|
@ -36,6 +36,8 @@ class workbook;
|
|||
class worksheet;
|
||||
class xml_document;
|
||||
|
||||
namespace detail { struct stylesheet; }
|
||||
|
||||
/// <summary>
|
||||
/// Manages converting a worksheet to and from XML.
|
||||
/// </summary>
|
||||
|
@ -44,7 +46,7 @@ class XLNT_CLASS worksheet_serializer
|
|||
public:
|
||||
worksheet_serializer(worksheet sheet);
|
||||
|
||||
bool read_worksheet(const xml_document &xml);
|
||||
bool read_worksheet(const xml_document &xml, detail::stylesheet &stylesheet);
|
||||
xml_document write_worksheet() const;
|
||||
|
||||
private:
|
||||
|
|
|
@ -38,12 +38,12 @@ class cell;
|
|||
/// <summary>
|
||||
/// Describes the formatting of a particular cell.
|
||||
/// </summary>
|
||||
class XLNT_CLASS formattable : public hashable
|
||||
class XLNT_CLASS base_format : public hashable
|
||||
{
|
||||
public:
|
||||
formattable();
|
||||
formattable(const formattable &other);
|
||||
formattable &operator=(const formattable &other);
|
||||
base_format();
|
||||
base_format(const base_format &other);
|
||||
base_format &operator=(const base_format &other);
|
||||
|
||||
void reset();
|
||||
|
|
@ -71,6 +71,8 @@ public:
|
|||
lightvertical,
|
||||
mediumgray,
|
||||
};
|
||||
|
||||
fill();
|
||||
|
||||
type get_type() const;
|
||||
|
||||
|
@ -122,21 +124,21 @@ protected:
|
|||
std::string to_hash_string() const override;
|
||||
|
||||
private:
|
||||
type type_ = type::pattern;
|
||||
pattern_type pattern_type_ = pattern_type::none;
|
||||
type type_;
|
||||
pattern_type pattern_type_;
|
||||
gradient_type gradient_type_;
|
||||
|
||||
double rotation_ = 0;
|
||||
double rotation_;
|
||||
|
||||
std::experimental::optional<color> foreground_color_ = color::black();
|
||||
std::experimental::optional<color> background_color_ = color::white();
|
||||
std::experimental::optional<color> start_color_ = color::white();
|
||||
std::experimental::optional<color> end_color_ = color::black();
|
||||
std::experimental::optional<color> foreground_color_;
|
||||
std::experimental::optional<color> background_color_;
|
||||
std::experimental::optional<color> start_color_;
|
||||
std::experimental::optional<color> end_color_;
|
||||
|
||||
double gradient_path_left_ = 0;
|
||||
double gradient_path_right_ = 0;
|
||||
double gradient_path_top_ = 0;
|
||||
double gradient_path_bottom_ = 0;
|
||||
double gradient_path_left_;
|
||||
double gradient_path_right_;
|
||||
double gradient_path_top_;
|
||||
double gradient_path_bottom_;
|
||||
};
|
||||
|
||||
} // namespace xlnt
|
||||
|
|
|
@ -47,6 +47,8 @@ public:
|
|||
single,
|
||||
single_accounting
|
||||
};
|
||||
|
||||
font();
|
||||
|
||||
void set_bold(bool bold);
|
||||
|
||||
|
|
|
@ -23,7 +23,7 @@
|
|||
// @author: see AUTHORS file
|
||||
#pragma once
|
||||
|
||||
#include <xlnt/styles/formattable.hpp>
|
||||
#include <xlnt/styles/base_format.hpp>
|
||||
|
||||
namespace xlnt {
|
||||
|
||||
|
@ -33,28 +33,15 @@ namespace detail { struct workbook_impl; }
|
|||
/// <summary>
|
||||
/// Describes the formatting of a particular cell.
|
||||
/// </summary>
|
||||
class XLNT_CLASS format : public formattable
|
||||
class XLNT_CLASS format : public base_format
|
||||
{
|
||||
public:
|
||||
format();
|
||||
format(const format &other);
|
||||
format &operator=(const format &other);
|
||||
|
||||
// Named Style
|
||||
bool has_style() const;
|
||||
std::string get_style_name() const;
|
||||
style &get_style();
|
||||
const style &get_style() const;
|
||||
void set_style(const std::string &name);
|
||||
void set_style(const style &new_style);
|
||||
void remove_style();
|
||||
|
||||
protected:
|
||||
std::string to_hash_string() const override;
|
||||
|
||||
private:
|
||||
detail::workbook_impl *parent_;
|
||||
std::string named_style_name_;
|
||||
};
|
||||
|
||||
} // namespace xlnt
|
||||
|
|
|
@ -26,7 +26,7 @@
|
|||
#include <cstdint>
|
||||
#include <string>
|
||||
|
||||
#include <xlnt/styles/formattable.hpp>
|
||||
#include <xlnt/styles/base_format.hpp>
|
||||
|
||||
namespace xlnt {
|
||||
|
||||
|
@ -36,7 +36,7 @@ class workbook;
|
|||
/// Describes a style which has a name and can be applied to multiple individual
|
||||
/// formats. In Excel this is a "Cell Style".
|
||||
/// </summary>
|
||||
class XLNT_CLASS style : public formattable
|
||||
class XLNT_CLASS style : public base_format
|
||||
{
|
||||
public:
|
||||
style();
|
||||
|
|
|
@ -23,6 +23,7 @@
|
|||
// @author: see AUTHORS file
|
||||
#pragma once
|
||||
|
||||
#include <functional>
|
||||
#include <memory>
|
||||
#include <string>
|
||||
#include <unordered_map>
|
||||
|
@ -32,11 +33,14 @@
|
|||
#include <xlnt/xlnt_config.hpp>
|
||||
#include <xlnt/packaging/relationship.hpp>
|
||||
|
||||
namespace CxxTest { class TestSuite; }
|
||||
|
||||
namespace xlnt {
|
||||
|
||||
class alignment;
|
||||
class app_properties;
|
||||
class border;
|
||||
class cell;
|
||||
class cell_style;
|
||||
class color;
|
||||
class const_worksheet_iterator;
|
||||
|
@ -193,10 +197,12 @@ public:
|
|||
const std::vector<format> &get_formats() const;
|
||||
|
||||
// Named Styles
|
||||
bool has_style(const std::string &name);
|
||||
bool has_style(const std::string &name) const;
|
||||
style &get_style(const std::string &name);
|
||||
const style &get_style(const std::string &name) const;
|
||||
std::size_t get_style_id(const std::string &name) const;
|
||||
style &create_style(const std::string &name);
|
||||
std::size_t add_style(const style &new_style);
|
||||
void clear_styles();
|
||||
const std::vector<style> &get_styles() const;
|
||||
|
||||
|
@ -214,10 +220,11 @@ public:
|
|||
const std::vector<std::uint8_t> &get_thumbnail() const;
|
||||
|
||||
private:
|
||||
friend class excel_serializer;
|
||||
friend class worksheet;
|
||||
friend class style_serializer;
|
||||
|
||||
std::string next_relationship_id() const;
|
||||
void apply_to_cells(std::function<void(cell)> f);
|
||||
|
||||
std::unique_ptr<detail::workbook_impl> d_;
|
||||
};
|
||||
|
|
|
@ -237,6 +237,8 @@ private:
|
|||
friend class cell;
|
||||
friend class range_iterator;
|
||||
friend class const_range_iterator;
|
||||
|
||||
std::size_t next_custom_number_format_id();
|
||||
|
||||
worksheet(detail::worksheet_impl *d);
|
||||
detail::worksheet_impl *d_;
|
||||
|
|
|
@ -31,8 +31,9 @@
|
|||
#include <xlnt/packaging/document_properties.hpp>
|
||||
#include <xlnt/packaging/relationship.hpp>
|
||||
#include <xlnt/serialization/encoding.hpp>
|
||||
#include <xlnt/styles/format.hpp>
|
||||
#include <xlnt/styles/color.hpp>
|
||||
#include <xlnt/styles/format.hpp>
|
||||
#include <xlnt/styles/style.hpp>
|
||||
#include <xlnt/utils/date.hpp>
|
||||
#include <xlnt/utils/datetime.hpp>
|
||||
#include <xlnt/utils/time.hpp>
|
||||
|
@ -906,10 +907,24 @@ void cell::set_font(const font &font_)
|
|||
|
||||
void cell::set_number_format(const number_format &number_format_)
|
||||
{
|
||||
format new_format;
|
||||
|
||||
if (d_->has_format_)
|
||||
{
|
||||
new_format = get_workbook().get_format(d_->format_id_);
|
||||
}
|
||||
|
||||
auto number_format_with_id = number_format_;
|
||||
|
||||
if (!number_format_with_id.has_id())
|
||||
{
|
||||
number_format_with_id.set_id(get_worksheet().next_custom_number_format_id());
|
||||
}
|
||||
|
||||
new_format.set_number_format(number_format_with_id);
|
||||
|
||||
d_->has_format_ = true;
|
||||
auto format_copy = get_workbook().get_format(d_->format_id_);
|
||||
format_copy.set_number_format(number_format_);
|
||||
d_->format_id_ = get_workbook().add_format(format_copy);
|
||||
d_->format_id_ = get_workbook().add_format(new_format);
|
||||
}
|
||||
|
||||
void cell::set_alignment(const xlnt::alignment &alignment_)
|
||||
|
@ -1030,4 +1045,42 @@ void cell::guess_type_and_set_value(const std::string &value)
|
|||
}
|
||||
}
|
||||
|
||||
void cell::clear_format()
|
||||
{
|
||||
d_->format_id_ = 0;
|
||||
d_->has_format_ = false;
|
||||
}
|
||||
|
||||
void cell::clear_style()
|
||||
{
|
||||
d_->style_id_ = 0;
|
||||
d_->has_style_ = false;
|
||||
}
|
||||
|
||||
void cell::set_style(const style &new_style)
|
||||
{
|
||||
d_->has_style_ = true;
|
||||
|
||||
if (get_workbook().has_style(new_style.get_name()))
|
||||
{
|
||||
d_->style_id_ = get_workbook().get_style_id(new_style.get_name());
|
||||
}
|
||||
else
|
||||
{
|
||||
d_->style_id_ = get_workbook().add_style(new_style);
|
||||
}
|
||||
}
|
||||
|
||||
void cell::set_style(const std::string &style_name)
|
||||
{
|
||||
d_->has_style_ = true;
|
||||
|
||||
if (!get_workbook().has_style(style_name))
|
||||
{
|
||||
throw std::runtime_error("style " + style_name + " doesn't exist in workbook");
|
||||
}
|
||||
|
||||
d_->style_id_ = get_workbook().get_style_id(style_name);
|
||||
}
|
||||
|
||||
} // namespace xlnt
|
||||
|
|
|
@ -72,6 +72,9 @@ struct cell_impl
|
|||
|
||||
bool has_format_;
|
||||
std::size_t format_id_;
|
||||
|
||||
bool has_style_;
|
||||
std::size_t style_id_;
|
||||
|
||||
std::unique_ptr<comment_impl> comment_;
|
||||
};
|
||||
|
|
172
source/detail/stylesheet.hpp
Normal file
172
source/detail/stylesheet.hpp
Normal file
|
@ -0,0 +1,172 @@
|
|||
// Copyright (c) 2014-2016 Thomas Fussell
|
||||
// Copyright (c) 2010-2015 openpyxl
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
// of this software and associated documentation files (the "Software"), to deal
|
||||
// in the Software without restriction, including without limitation the rights
|
||||
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
// copies of the Software, and to permit persons to whom the Software is
|
||||
// furnished to do so, subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included in
|
||||
// all copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, WRISING FROM,
|
||||
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
// THE SOFTWARE
|
||||
//
|
||||
// @license: http://www.opensource.org/licenses/mit-license.php
|
||||
// @author: see AUTHORS file
|
||||
#pragma once
|
||||
|
||||
#include <string>
|
||||
#include <unordered_map>
|
||||
#include <vector>
|
||||
|
||||
#include <xlnt/styles/border.hpp>
|
||||
#include <xlnt/styles/fill.hpp>
|
||||
#include <xlnt/styles/font.hpp>
|
||||
#include <xlnt/styles/format.hpp>
|
||||
#include <xlnt/styles/number_format.hpp>
|
||||
#include <xlnt/styles/style.hpp>
|
||||
|
||||
namespace {
|
||||
|
||||
template<typename T>
|
||||
std::size_t search_vector(const std::vector<T> &items, const T &to_find)
|
||||
{
|
||||
auto match = std::find(items.begin(), items.end(), to_find);
|
||||
|
||||
if (match == items.end())
|
||||
{
|
||||
throw std::out_of_range("xlnt::stylesheet index lookup");
|
||||
}
|
||||
|
||||
return std::distance(items.begin(), match);
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
namespace xlnt {
|
||||
namespace detail {
|
||||
|
||||
struct stylesheet
|
||||
{
|
||||
~stylesheet() {}
|
||||
|
||||
std::size_t index(const format &f) { return search_vector(formats, f); }
|
||||
|
||||
std::size_t index(const std::string &style_name)
|
||||
{
|
||||
auto match = std::find_if(styles.begin(), styles.end(),
|
||||
[&](const style &s) { return s.get_name() == style_name; });
|
||||
|
||||
if (match == styles.end())
|
||||
{
|
||||
throw std::out_of_range("xlnt::stylesheet style index lookup");
|
||||
}
|
||||
|
||||
return std::distance(styles.begin(), match);
|
||||
}
|
||||
|
||||
std::size_t index(const border &b) { return search_vector(borders, b); }
|
||||
std::size_t index(const fill &f) { return search_vector(fills, f); }
|
||||
std::size_t index(const font &f) { return search_vector(fonts, f); }
|
||||
std::size_t index(const number_format &f) { return search_vector(number_formats, f); }
|
||||
|
||||
std::size_t add_format(const format &f)
|
||||
{
|
||||
auto match = std::find(formats.begin(), formats.end(), f);
|
||||
|
||||
if (match != formats.end())
|
||||
{
|
||||
return std::distance(formats.begin(), match);
|
||||
}
|
||||
|
||||
auto number_format_match = std::find_if(number_formats.begin(), number_formats.end(), [&](const number_format &nf) { return nf.get_format_string() == f.get_number_format().get_format_string(); });
|
||||
|
||||
if (number_format_match == number_formats.end() && f.get_number_format().get_id() >= 164)
|
||||
{
|
||||
number_formats.push_back(f.get_number_format());
|
||||
}
|
||||
|
||||
formats.push_back(f);
|
||||
format_styles.push_back("");
|
||||
|
||||
try
|
||||
{
|
||||
search_vector(borders, f.get_border());
|
||||
}
|
||||
catch(std::out_of_range)
|
||||
{
|
||||
borders.push_back(f.get_border());
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
search_vector(fills, f.get_fill());
|
||||
}
|
||||
catch(std::out_of_range)
|
||||
{
|
||||
fills.push_back(f.get_fill());
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
search_vector(fonts, f.get_font());
|
||||
}
|
||||
catch(std::out_of_range)
|
||||
{
|
||||
fonts.push_back(f.get_font());
|
||||
}
|
||||
|
||||
if (f.get_number_format().get_id() >= 164)
|
||||
{
|
||||
try
|
||||
{
|
||||
search_vector(number_formats, f.get_number_format());
|
||||
}
|
||||
catch(std::out_of_range)
|
||||
{
|
||||
number_formats.push_back(f.get_number_format());
|
||||
}
|
||||
}
|
||||
|
||||
return formats.size() - 1;
|
||||
}
|
||||
|
||||
std::size_t add_style(const style &s)
|
||||
{
|
||||
auto match = std::find(styles.begin(), styles.end(), s);
|
||||
|
||||
if (match != styles.end())
|
||||
{
|
||||
return std::distance(styles.begin(), match);
|
||||
}
|
||||
|
||||
styles.push_back(s);
|
||||
return styles.size() - 1;
|
||||
}
|
||||
|
||||
std::vector<format> formats;
|
||||
std::vector<std::string> format_styles;
|
||||
std::vector<style> styles;
|
||||
|
||||
std::vector<border> borders;
|
||||
std::vector<fill> fills;
|
||||
std::vector<font> fonts;
|
||||
std::vector<number_format> number_formats;
|
||||
|
||||
std::vector<color> colors;
|
||||
|
||||
std::unordered_map<std::size_t, std::string> style_name_map;
|
||||
|
||||
std::size_t next_custom_format_id = 164;
|
||||
};
|
||||
|
||||
} // namespace detail
|
||||
} // namespace xlnt
|
|
@ -25,7 +25,9 @@
|
|||
#include <iterator>
|
||||
#include <vector>
|
||||
|
||||
#include <detail/stylesheet.hpp>
|
||||
#include <detail/worksheet_impl.hpp>
|
||||
#include <xlnt/serialization/encoding.hpp>
|
||||
#include <xlnt/packaging/app_properties.hpp>
|
||||
#include <xlnt/packaging/document_properties.hpp>
|
||||
#include <xlnt/packaging/manifest.hpp>
|
||||
|
@ -54,8 +56,7 @@ struct workbook_impl
|
|||
guess_types_(other.guess_types_),
|
||||
data_only_(other.data_only_),
|
||||
read_only_(other.read_only_),
|
||||
formats_(other.formats_),
|
||||
styles_(other.styles_),
|
||||
stylesheet_(other.stylesheet_),
|
||||
manifest_(other.manifest_)
|
||||
{
|
||||
}
|
||||
|
@ -95,9 +96,7 @@ struct workbook_impl
|
|||
bool data_only_;
|
||||
bool read_only_;
|
||||
|
||||
std::vector<format> formats_;
|
||||
std::vector<style> styles_;
|
||||
std::size_t next_custom_format_id_;
|
||||
stylesheet stylesheet_;
|
||||
|
||||
manifest manifest_;
|
||||
theme theme_;
|
||||
|
|
|
@ -47,6 +47,8 @@
|
|||
#include <xlnt/worksheet/worksheet.hpp>
|
||||
|
||||
#include <detail/constants.hpp>
|
||||
#include <detail/stylesheet.hpp>
|
||||
#include <detail/workbook_impl.hpp>
|
||||
|
||||
namespace {
|
||||
|
||||
|
@ -144,10 +146,11 @@ bool load_workbook(xlnt::zip_file &archive, bool guess_types, bool data_only, xl
|
|||
}
|
||||
}
|
||||
|
||||
xlnt::style_serializer style_reader_(wb);
|
||||
xlnt::detail::stylesheet stylesheet;
|
||||
xlnt::style_serializer style_serializer(stylesheet);
|
||||
xlnt::xml_document style_xml;
|
||||
style_xml.from_string(archive.read(xlnt::constants::ArcStyles()));
|
||||
style_reader_.read_stylesheet(style_xml);
|
||||
style_serializer.read_stylesheet(style_xml);
|
||||
|
||||
auto sheets_node = root_node.get_child("sheets");
|
||||
|
||||
|
@ -169,7 +172,7 @@ bool load_workbook(xlnt::zip_file &archive, bool guess_types, bool data_only, xl
|
|||
xlnt::worksheet_serializer worksheet_serializer(ws);
|
||||
xlnt::xml_document worksheet_xml;
|
||||
worksheet_xml.from_string(archive.read(ws_filename));
|
||||
worksheet_serializer.read_worksheet(worksheet_xml);
|
||||
worksheet_serializer.read_worksheet(worksheet_xml, stylesheet);
|
||||
}
|
||||
|
||||
if (archive.has_file("docProps/thumbnail.jpeg"))
|
||||
|
@ -264,8 +267,10 @@ void excel_serializer::write_data(bool /*as_template*/)
|
|||
|
||||
archive_.writestr(constants::ArcWorkbook(), xml_serializer::serialize(workbook_serializer_.write_workbook()));
|
||||
|
||||
style_serializer style_serializer_(workbook_);
|
||||
archive_.writestr(constants::ArcStyles(), style_serializer_.write_stylesheet().to_string());
|
||||
style_serializer style_serializer(workbook_.d_->stylesheet_);
|
||||
xlnt::xml_document style_xml;
|
||||
style_serializer.write_stylesheet(style_xml);
|
||||
archive_.writestr(constants::ArcStyles(), style_xml.to_string());
|
||||
|
||||
manifest_serializer manifest_serializer_(workbook_.get_manifest());
|
||||
archive_.writestr(constants::ArcContentTypes(), manifest_serializer_.write_manifest().to_string());
|
||||
|
@ -329,4 +334,9 @@ bool excel_serializer::save_virtual_workbook(std::vector<std::uint8_t> &bytes, b
|
|||
return true;
|
||||
}
|
||||
|
||||
detail::stylesheet &excel_serializer::get_stylesheet()
|
||||
{
|
||||
return workbook_.d_->stylesheet_;
|
||||
}
|
||||
|
||||
} // namespace xlnt
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -4,6 +4,8 @@
|
|||
#include <cxxtest/TestSuite.h>
|
||||
|
||||
#include <xlnt/serialization/style_serializer.hpp>
|
||||
#include <detail/stylesheet.hpp>
|
||||
#include <detail/workbook_impl.hpp>
|
||||
|
||||
class test_style_writer : public CxxTest::TestSuite
|
||||
{
|
||||
|
@ -12,15 +14,17 @@ public:
|
|||
{
|
||||
xlnt::workbook wb;
|
||||
wb.get_active_sheet().get_cell("A1").set_number_format(xlnt::number_format("YYYY"));
|
||||
xlnt::style_serializer writer(wb);
|
||||
xlnt::excel_serializer excel_serializer(wb);
|
||||
xlnt::style_serializer style_serializer(excel_serializer.get_stylesheet());
|
||||
xlnt::xml_document observed;
|
||||
auto num_fmts_node = observed.add_child("numFmts");
|
||||
writer.write_number_formats(num_fmts_node);
|
||||
style_serializer.write_stylesheet(observed);
|
||||
xlnt::xml_document expected_doc;
|
||||
std::string expected =
|
||||
" <numFmts count=\"1\">"
|
||||
" <numFmt formatCode=\"YYYY\" numFmtId=\"164\"></numFmt>"
|
||||
" </numFmts>";
|
||||
auto diff = Helper::compare_xml(expected, observed);
|
||||
expected_doc.from_string(expected);
|
||||
auto diff = Helper::compare_xml(expected_doc.get_child("numFmts"), observed.get_child("styleSheet").get_child("numFmts"));
|
||||
TS_ASSERT(diff);
|
||||
}
|
||||
/*
|
||||
|
|
|
@ -40,6 +40,7 @@
|
|||
#include <xlnt/worksheet/row_properties.hpp>
|
||||
|
||||
#include <detail/constants.hpp>
|
||||
#include <detail/stylesheet.hpp>
|
||||
|
||||
namespace {
|
||||
|
||||
|
@ -56,7 +57,7 @@ worksheet_serializer::worksheet_serializer(worksheet sheet) : sheet_(sheet)
|
|||
{
|
||||
}
|
||||
|
||||
bool worksheet_serializer::read_worksheet(const xml_document &xml)
|
||||
bool worksheet_serializer::read_worksheet(const xml_document &xml, detail::stylesheet &stylesheet)
|
||||
{
|
||||
auto &root_node = xml.get_child("worksheet");
|
||||
|
||||
|
@ -198,7 +199,7 @@ bool worksheet_serializer::read_worksheet(const xml_document &xml)
|
|||
|
||||
if (has_format)
|
||||
{
|
||||
cell.set_format(sheet_.get_workbook().get_format(format_id));
|
||||
cell.set_format(stylesheet.formats.at(format_id));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -21,11 +21,11 @@
|
|||
//
|
||||
// @license: http://www.opensource.org/licenses/mit-license.php
|
||||
// @author: see AUTHORS file
|
||||
#include <xlnt/styles/formattable.hpp>
|
||||
#include <xlnt/styles/base_format.hpp>
|
||||
|
||||
namespace xlnt {
|
||||
|
||||
formattable::formattable()
|
||||
base_format::base_format()
|
||||
: apply_alignment_(false),
|
||||
apply_border_(false),
|
||||
apply_fill_(false),
|
||||
|
@ -35,7 +35,7 @@ formattable::formattable()
|
|||
{
|
||||
}
|
||||
|
||||
formattable::formattable(const formattable &other)
|
||||
base_format::base_format(const base_format &other)
|
||||
: alignment_(other.alignment_),
|
||||
border_(other.border_),
|
||||
fill_(other.fill_),
|
||||
|
@ -51,7 +51,7 @@ formattable::formattable(const formattable &other)
|
|||
{
|
||||
}
|
||||
|
||||
formattable &formattable::operator=(const xlnt::formattable &other)
|
||||
base_format &base_format::operator=(const xlnt::base_format &other)
|
||||
{
|
||||
alignment_ = other.alignment_;
|
||||
border_ = other.border_;
|
||||
|
@ -70,105 +70,105 @@ formattable &formattable::operator=(const xlnt::formattable &other)
|
|||
return *this;
|
||||
}
|
||||
|
||||
alignment &formattable::get_alignment()
|
||||
alignment &base_format::get_alignment()
|
||||
{
|
||||
return alignment_;
|
||||
}
|
||||
|
||||
const alignment &formattable::get_alignment() const
|
||||
const alignment &base_format::get_alignment() const
|
||||
{
|
||||
return alignment_;
|
||||
}
|
||||
|
||||
void formattable::set_alignment(const xlnt::alignment &new_alignment)
|
||||
void base_format::set_alignment(const xlnt::alignment &new_alignment)
|
||||
{
|
||||
alignment_ = new_alignment;
|
||||
alignment_applied(true);
|
||||
}
|
||||
|
||||
number_format &formattable::get_number_format()
|
||||
number_format &base_format::get_number_format()
|
||||
{
|
||||
return number_format_;
|
||||
}
|
||||
|
||||
const number_format &formattable::get_number_format() const
|
||||
const number_format &base_format::get_number_format() const
|
||||
{
|
||||
return number_format_;
|
||||
}
|
||||
|
||||
void formattable::set_number_format(const xlnt::number_format &new_number_format)
|
||||
void base_format::set_number_format(const xlnt::number_format &new_number_format)
|
||||
{
|
||||
number_format_ = new_number_format;
|
||||
number_format_applied(true);
|
||||
}
|
||||
|
||||
border &formattable::get_border()
|
||||
border &base_format::get_border()
|
||||
{
|
||||
return border_;
|
||||
}
|
||||
|
||||
const border &formattable::get_border() const
|
||||
const border &base_format::get_border() const
|
||||
{
|
||||
return border_;
|
||||
}
|
||||
|
||||
void formattable::set_border(const xlnt::border &new_border)
|
||||
void base_format::set_border(const xlnt::border &new_border)
|
||||
{
|
||||
border_ = new_border;
|
||||
border_applied(true);
|
||||
}
|
||||
|
||||
fill &formattable::get_fill()
|
||||
fill &base_format::get_fill()
|
||||
{
|
||||
return fill_;
|
||||
}
|
||||
|
||||
const fill &formattable::get_fill() const
|
||||
const fill &base_format::get_fill() const
|
||||
{
|
||||
return fill_;
|
||||
}
|
||||
|
||||
void formattable::set_fill(const xlnt::fill &new_fill)
|
||||
void base_format::set_fill(const xlnt::fill &new_fill)
|
||||
{
|
||||
fill_ = new_fill;
|
||||
fill_applied(true);
|
||||
}
|
||||
|
||||
font &formattable::get_font()
|
||||
font &base_format::get_font()
|
||||
{
|
||||
return font_;
|
||||
}
|
||||
|
||||
const font &formattable::get_font() const
|
||||
const font &base_format::get_font() const
|
||||
{
|
||||
return font_;
|
||||
}
|
||||
|
||||
void formattable::set_font(const xlnt::font &new_font)
|
||||
void base_format::set_font(const xlnt::font &new_font)
|
||||
{
|
||||
font_ = new_font;
|
||||
font_applied(true);
|
||||
}
|
||||
|
||||
protection &formattable::get_protection()
|
||||
protection &base_format::get_protection()
|
||||
{
|
||||
return protection_;
|
||||
}
|
||||
|
||||
const protection &formattable::get_protection() const
|
||||
const protection &base_format::get_protection() const
|
||||
{
|
||||
return protection_;
|
||||
}
|
||||
|
||||
void formattable::set_protection(const xlnt::protection &new_protection)
|
||||
void base_format::set_protection(const xlnt::protection &new_protection)
|
||||
{
|
||||
protection_ = new_protection;
|
||||
protection_applied(true);
|
||||
}
|
||||
|
||||
std::string formattable::to_hash_string() const
|
||||
std::string base_format::to_hash_string() const
|
||||
{
|
||||
std::string hash_string("formattable:");
|
||||
std::string hash_string("base_format:");
|
||||
|
||||
hash_string.append(std::to_string(alignment_applied()));
|
||||
hash_string.append(alignment_applied() ? std::to_string(alignment_.hash()) : ":");
|
||||
|
@ -191,62 +191,62 @@ std::string formattable::to_hash_string() const
|
|||
return hash_string;
|
||||
}
|
||||
|
||||
void formattable::alignment_applied(bool applied)
|
||||
void base_format::alignment_applied(bool applied)
|
||||
{
|
||||
apply_alignment_ = applied;
|
||||
}
|
||||
|
||||
void formattable::border_applied(bool applied)
|
||||
void base_format::border_applied(bool applied)
|
||||
{
|
||||
apply_border_ = applied;
|
||||
}
|
||||
|
||||
void formattable::fill_applied(bool applied)
|
||||
void base_format::fill_applied(bool applied)
|
||||
{
|
||||
apply_fill_ = applied;
|
||||
}
|
||||
|
||||
void formattable::font_applied(bool applied)
|
||||
void base_format::font_applied(bool applied)
|
||||
{
|
||||
apply_font_ = applied;
|
||||
}
|
||||
|
||||
void formattable::number_format_applied(bool applied)
|
||||
void base_format::number_format_applied(bool applied)
|
||||
{
|
||||
apply_number_format_ = applied;
|
||||
}
|
||||
|
||||
void formattable::protection_applied(bool applied)
|
||||
void base_format::protection_applied(bool applied)
|
||||
{
|
||||
apply_protection_ = applied;
|
||||
}
|
||||
|
||||
bool formattable::alignment_applied() const
|
||||
bool base_format::alignment_applied() const
|
||||
{
|
||||
return apply_alignment_;
|
||||
}
|
||||
|
||||
bool formattable::border_applied() const
|
||||
bool base_format::border_applied() const
|
||||
{
|
||||
return apply_border_;
|
||||
}
|
||||
|
||||
bool formattable::fill_applied() const
|
||||
bool base_format::fill_applied() const
|
||||
{
|
||||
return apply_fill_;
|
||||
}
|
||||
|
||||
bool formattable::font_applied() const
|
||||
bool base_format::font_applied() const
|
||||
{
|
||||
return apply_font_;
|
||||
}
|
||||
|
||||
bool formattable::number_format_applied() const
|
||||
bool base_format::number_format_applied() const
|
||||
{
|
||||
return apply_number_format_;
|
||||
}
|
||||
|
||||
bool formattable::protection_applied() const
|
||||
bool base_format::protection_applied() const
|
||||
{
|
||||
return apply_protection_;
|
||||
}
|
||||
|
|
|
@ -26,6 +26,18 @@
|
|||
|
||||
namespace xlnt {
|
||||
|
||||
fill::fill()
|
||||
: type_(type::pattern),
|
||||
pattern_type_(pattern_type::none),
|
||||
gradient_type_(gradient_type::linear),
|
||||
rotation_(0),
|
||||
gradient_path_left_(0),
|
||||
gradient_path_right_(0),
|
||||
gradient_path_top_(0),
|
||||
gradient_path_bottom_(0)
|
||||
{
|
||||
}
|
||||
|
||||
fill::type fill::get_type() const
|
||||
{
|
||||
return type_;
|
||||
|
|
|
@ -26,6 +26,24 @@
|
|||
|
||||
namespace xlnt {
|
||||
|
||||
|
||||
font::font()
|
||||
: name_("Calibri"),
|
||||
size_(12),
|
||||
bold_(false),
|
||||
italic_(false),
|
||||
superscript_(false),
|
||||
subscript_(false),
|
||||
underline_(underline_style::none),
|
||||
strikethrough_(false),
|
||||
color_(xlnt::color::type::theme, 1),
|
||||
has_family_(true),
|
||||
family_(2),
|
||||
has_scheme_(true),
|
||||
scheme_("minor")
|
||||
{
|
||||
}
|
||||
|
||||
void font::set_bold(bool bold)
|
||||
{
|
||||
bold_ = bold;
|
||||
|
|
|
@ -31,60 +31,27 @@
|
|||
|
||||
namespace xlnt {
|
||||
|
||||
format::format()
|
||||
: formattable(),
|
||||
parent_(nullptr),
|
||||
named_style_name_("Normal")
|
||||
format::format() : base_format()
|
||||
{
|
||||
}
|
||||
|
||||
format::format(const format &other)
|
||||
: formattable(other),
|
||||
parent_(other.parent_),
|
||||
named_style_name_(other.named_style_name_)
|
||||
format::format(const format &other) : base_format(other)
|
||||
{
|
||||
}
|
||||
|
||||
format &format::operator=(const format &other)
|
||||
{
|
||||
formattable::operator=(other);
|
||||
|
||||
parent_ = other.parent_;
|
||||
named_style_name_ = other.named_style_name_;
|
||||
base_format::operator=(other);
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
std::string format::to_hash_string() const
|
||||
{
|
||||
auto hash_string = formattable::to_hash_string();
|
||||
auto hash_string = base_format::to_hash_string();
|
||||
hash_string.append(":format:");
|
||||
|
||||
if (!named_style_name_.empty())
|
||||
{
|
||||
hash_string.append(named_style_name_);
|
||||
}
|
||||
else
|
||||
{
|
||||
hash_string.append(":");
|
||||
}
|
||||
|
||||
return hash_string;
|
||||
}
|
||||
|
||||
void format::set_style(const std::string &style_name)
|
||||
{
|
||||
named_style_name_ = style_name;
|
||||
}
|
||||
|
||||
bool format::has_style() const
|
||||
{
|
||||
return !named_style_name_.empty();
|
||||
}
|
||||
|
||||
std::string format::get_style_name() const
|
||||
{
|
||||
return named_style_name_;
|
||||
}
|
||||
|
||||
} // namespace xlnt
|
||||
|
|
|
@ -70,7 +70,7 @@ const std::unordered_map<std::size_t, std::string> &builtin_formats()
|
|||
{ 42, "_(\"$\"* #,##0_);_(\"$\"* \\(#,##0\\);_(\"$\"* \"-\"_);_(@_)" },
|
||||
{ 43, "_(* #,##0.00_);_(* \\(#,##0.00\\);_(* \"-\"??_);_(@_)" },
|
||||
|
||||
{ 44, "_(\"$\"* #,##0.00_)_(\"$\"* \\(#,##0.00\\)_(\"$\"* \"-\"??_)_(@_)" },
|
||||
{ 44, "_-\"$\"* #,##0.00_-;\\-\"$\"* #,##0.00_-;_-\"$\"* \"-\"??_-;_-@_-" },
|
||||
{ 45, "mm:ss" },
|
||||
{ 46, "[h]:mm:ss" },
|
||||
{ 47, "mmss.0" },
|
||||
|
|
|
@ -27,14 +27,14 @@
|
|||
namespace xlnt {
|
||||
|
||||
style::style()
|
||||
: formattable(),
|
||||
: base_format(),
|
||||
hidden_(false),
|
||||
builtin_id_(0)
|
||||
{
|
||||
}
|
||||
|
||||
style::style(const style &other)
|
||||
: formattable(other),
|
||||
: base_format(other),
|
||||
name_(other.name_),
|
||||
hidden_(other.hidden_),
|
||||
builtin_id_(other.builtin_id_)
|
||||
|
@ -43,7 +43,7 @@ style::style(const style &other)
|
|||
|
||||
style &style::operator=(const style &other)
|
||||
{
|
||||
formattable::operator=(other);
|
||||
base_format::operator=(other);
|
||||
|
||||
name_ = other.name_;
|
||||
hidden_ = other.hidden_;
|
||||
|
@ -84,7 +84,7 @@ void style::set_name(const std::string &name)
|
|||
|
||||
std::string style::to_hash_string() const
|
||||
{
|
||||
return formattable::to_hash_string() + name_;
|
||||
return base_format::to_hash_string() + name_;
|
||||
}
|
||||
|
||||
} // namespace xlnt
|
||||
|
|
|
@ -15,9 +15,12 @@ public:
|
|||
void test_ctor()
|
||||
{
|
||||
xlnt::workbook wb;
|
||||
xlnt::style_serializer style_serializer(wb);
|
||||
xlnt::excel_serializer excel_serializer(wb);
|
||||
xlnt::style_serializer style_serializer(excel_serializer.get_stylesheet());
|
||||
xlnt::zip_file archive;
|
||||
auto stylesheet_xml = style_serializer.write_stylesheet().to_string();
|
||||
xlnt::xml_document stylesheet_doc;
|
||||
style_serializer.write_stylesheet(stylesheet_doc);
|
||||
auto stylesheet_xml = stylesheet_doc.to_string();
|
||||
|
||||
const std::string expected =
|
||||
"<styleSheet xmlns=\"http://schemas.openxmlformats.org/spreadsheetml/2006/main\" xmlns:mc=\"http://schemas.openxmlformats.org/markup-compatibility/2006\" xmlns:x14ac=\"http://schemas.microsoft.com/office/spreadsheetml/2009/9/ac\" mc:Ignorable=\"x14ac\">"
|
||||
|
@ -72,9 +75,10 @@ public:
|
|||
auto xml = PathHelper::read_file(PathHelper::GetDataDirectory("/reader/styles/simple-styles.xml"));
|
||||
doc.from_string(xml);
|
||||
xlnt::workbook wb;
|
||||
xlnt::style_serializer s(wb);
|
||||
xlnt::excel_serializer e(wb);
|
||||
xlnt::style_serializer s(e.get_stylesheet());
|
||||
TS_ASSERT(s.read_stylesheet(doc));
|
||||
TS_ASSERT_EQUALS(s.get_number_formats().size(), 1);
|
||||
TS_ASSERT_EQUALS(e.get_stylesheet().number_formats.size(), 1);
|
||||
}
|
||||
|
||||
void test_from_complex()
|
||||
|
@ -83,12 +87,13 @@ public:
|
|||
auto xml = PathHelper::read_file(PathHelper::GetDataDirectory("/reader/styles/complex-styles.xml"));
|
||||
doc.from_string(xml);
|
||||
xlnt::workbook wb;
|
||||
xlnt::style_serializer s(wb);
|
||||
xlnt::excel_serializer e(wb);
|
||||
xlnt::style_serializer s(e.get_stylesheet());
|
||||
TS_ASSERT(s.read_stylesheet(doc));
|
||||
TS_ASSERT_EQUALS(s.get_borders().size(), 7);
|
||||
TS_ASSERT_EQUALS(s.get_fills().size(), 6);
|
||||
TS_ASSERT_EQUALS(s.get_fonts().size(), 8);
|
||||
TS_ASSERT_EQUALS(s.get_number_formats().size(), 1);
|
||||
TS_ASSERT_EQUALS(e.get_stylesheet().borders.size(), 7);
|
||||
TS_ASSERT_EQUALS(e.get_stylesheet().fills.size(), 6);
|
||||
TS_ASSERT_EQUALS(e.get_stylesheet().fonts.size(), 8);
|
||||
TS_ASSERT_EQUALS(e.get_stylesheet().number_formats.size(), 0);
|
||||
}
|
||||
|
||||
/*
|
||||
|
|
|
@ -24,6 +24,7 @@
|
|||
#include <algorithm>
|
||||
#include <array>
|
||||
#include <fstream>
|
||||
#include <functional>
|
||||
#include <set>
|
||||
#include <sstream>
|
||||
|
||||
|
@ -60,7 +61,10 @@ namespace xlnt {
|
|||
namespace detail {
|
||||
|
||||
workbook_impl::workbook_impl()
|
||||
: active_sheet_index_(0), guess_types_(false), data_only_(false), read_only_(false), next_custom_format_id_(164)
|
||||
: active_sheet_index_(0),
|
||||
guess_types_(false),
|
||||
data_only_(false),
|
||||
read_only_(false)
|
||||
{
|
||||
}
|
||||
|
||||
|
@ -86,6 +90,7 @@ workbook::workbook() : d_(new detail::workbook_impl())
|
|||
|
||||
add_format(format());
|
||||
create_style("Normal");
|
||||
d_->stylesheet_.format_styles.front() = "Normal";
|
||||
}
|
||||
|
||||
workbook::workbook(encoding e) : workbook()
|
||||
|
@ -555,11 +560,6 @@ workbook::~workbook()
|
|||
{
|
||||
}
|
||||
|
||||
const std::vector<style> &workbook::get_styles() const
|
||||
{
|
||||
return d_->styles_;
|
||||
}
|
||||
|
||||
bool workbook::get_data_only() const
|
||||
{
|
||||
return d_->data_only_;
|
||||
|
@ -609,65 +609,63 @@ std::vector<named_range> workbook::get_named_ranges() const
|
|||
return named_ranges;
|
||||
}
|
||||
|
||||
std::size_t workbook::add_format(const format &style)
|
||||
std::size_t workbook::add_format(const format &to_add)
|
||||
{
|
||||
auto format_copy = style;
|
||||
|
||||
//TODO this is ugly
|
||||
if (!style.get_number_format().has_id())
|
||||
{
|
||||
bool match = false;
|
||||
|
||||
for (std::size_t i = 0; i < d_->formats_.size(); i++)
|
||||
{
|
||||
const auto ¤t_number_format = d_->formats_.at(i).get_number_format();
|
||||
|
||||
if (current_number_format.get_format_string() == format_copy.get_number_format().get_format_string())
|
||||
{
|
||||
format_copy.set_number_format(current_number_format);
|
||||
match = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (!match)
|
||||
{
|
||||
format_copy.get_number_format().set_id(d_->next_custom_format_id_++);
|
||||
}
|
||||
}
|
||||
|
||||
// TODO hashmap?
|
||||
for (std::size_t i = 0; i < d_->formats_.size(); i++)
|
||||
{
|
||||
if (d_->formats_[i] == format_copy)
|
||||
{
|
||||
return i;
|
||||
}
|
||||
}
|
||||
|
||||
d_->formats_.push_back(format_copy);
|
||||
|
||||
return d_->formats_.size() - 1;
|
||||
return d_->stylesheet_.add_format(to_add);
|
||||
}
|
||||
|
||||
std::size_t workbook::add_style(const style &to_add)
|
||||
{
|
||||
return d_->stylesheet_.add_style(to_add);
|
||||
}
|
||||
|
||||
bool workbook::has_style(const std::string &name) const
|
||||
{
|
||||
return std::find_if(d_->stylesheet_.styles.begin(), d_->stylesheet_.styles.end(),
|
||||
[&](const style &s) { return s.get_name() == name; }) != d_->stylesheet_.styles.end();
|
||||
}
|
||||
|
||||
std::size_t workbook::get_style_id(const std::string &name) const
|
||||
{
|
||||
return std::distance(d_->stylesheet_.styles.begin(),
|
||||
std::find_if(d_->stylesheet_.styles.begin(), d_->stylesheet_.styles.end(),
|
||||
[&](const style &s) { return s.get_name() == name; }));
|
||||
}
|
||||
|
||||
void workbook::clear_styles()
|
||||
{
|
||||
d_->styles_.clear();
|
||||
d_->stylesheet_.styles.clear();
|
||||
apply_to_cells([](cell c) { c.clear_style(); });
|
||||
}
|
||||
|
||||
void workbook::clear_formats()
|
||||
{
|
||||
d_->formats_.clear();
|
||||
d_->stylesheet_.formats.clear();
|
||||
apply_to_cells([](cell c) { c.clear_format(); });
|
||||
}
|
||||
|
||||
void workbook::apply_to_cells(std::function<void(cell)> f)
|
||||
{
|
||||
for (auto ws : *this)
|
||||
{
|
||||
for (auto r : ws.iter_cells(true))
|
||||
{
|
||||
for (auto c : r)
|
||||
{
|
||||
f.operator()(c);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
format &workbook::get_format(std::size_t format_index)
|
||||
{
|
||||
return d_->formats_.at(format_index);
|
||||
return d_->stylesheet_.formats.at(format_index);
|
||||
}
|
||||
|
||||
const format &workbook::get_format(std::size_t format_index) const
|
||||
{
|
||||
return d_->formats_.at(format_index);
|
||||
return d_->stylesheet_.formats.at(format_index);
|
||||
}
|
||||
|
||||
manifest &workbook::get_manifest()
|
||||
|
@ -749,30 +747,30 @@ style &workbook::create_style(const std::string &name)
|
|||
style style;
|
||||
style.set_name(name);
|
||||
|
||||
d_->styles_.push_back(style);
|
||||
d_->stylesheet_.styles.push_back(style);
|
||||
|
||||
return d_->styles_.back();
|
||||
return d_->stylesheet_.styles.back();
|
||||
}
|
||||
|
||||
std::vector<format> &workbook::get_formats()
|
||||
{
|
||||
return d_->formats_;
|
||||
return d_->stylesheet_.formats;
|
||||
}
|
||||
|
||||
const std::vector<format> &workbook::get_formats() const
|
||||
{
|
||||
return d_->formats_;
|
||||
return d_->stylesheet_.formats;
|
||||
}
|
||||
|
||||
style &workbook::get_style(const std::string &name)
|
||||
{
|
||||
return *std::find_if(d_->styles_.begin(), d_->styles_.end(),
|
||||
return *std::find_if(d_->stylesheet_.styles.begin(), d_->stylesheet_.styles.end(),
|
||||
[&name](const style &s) { return s.get_name() == name; });
|
||||
}
|
||||
|
||||
const style &workbook::get_style(const std::string &name) const
|
||||
{
|
||||
return *std::find_if(d_->styles_.begin(), d_->styles_.end(),
|
||||
return *std::find_if(d_->stylesheet_.styles.begin(), d_->stylesheet_.styles.end(),
|
||||
[&name](const style &s) { return s.get_name() == name; });
|
||||
}
|
||||
|
||||
|
|
|
@ -43,6 +43,7 @@
|
|||
|
||||
#include <detail/cell_impl.hpp>
|
||||
#include <detail/constants.hpp>
|
||||
#include <detail/workbook_impl.hpp>
|
||||
#include <detail/worksheet_impl.hpp>
|
||||
|
||||
namespace xlnt {
|
||||
|
@ -995,4 +996,9 @@ sheet_view worksheet::get_sheet_view() const
|
|||
return d_->view_;
|
||||
}
|
||||
|
||||
std::size_t worksheet::next_custom_number_format_id()
|
||||
{
|
||||
return get_workbook().d_->stylesheet_.next_custom_format_id++;
|
||||
}
|
||||
|
||||
} // namespace xlnt
|
||||
|
|
Loading…
Reference in New Issue
Block a user