clang-format all files, update .clang-format, fix minor compilation errors

This commit is contained in:
Thomas Fussell 2015-11-01 09:43:01 -05:00
parent 3a50c2bb9d
commit 7f840bb904
98 changed files with 3722 additions and 3215 deletions

View File

@ -1,51 +1,45 @@
---
Language: Cpp
AccessModifierOffset: -4
ConstructorInitializerIndentWidth: 4
AlignEscapedNewlinesLeft: false
AlignTrailingComments: false
AllowAllParametersOfDeclarationOnNextLine: true
AllowShortIfStatementsOnASingleLine: false
BasedOnStyle: LLVM
AllowShortBlocksOnASingleLine: false
AllowShortFunctionsOnASingleLine: None
AllowShortIfStatementsOnASingleLine: true
AllowShortLoopsOnASingleLine: false
AllowShortFunctionsOnASingleLine: true
AlwaysBreakTemplateDeclarations: false
AlwaysBreakBeforeMultilineStrings: false
BreakBeforeBinaryOperators: false
BreakBeforeTernaryOperators: true
BreakConstructorInitializersBeforeComma: false
BinPackParameters: true
ColumnLimit: 0
AlwaysBreakBeforeMultilineStrings: true
AlwaysBreakTemplateDeclarations: true
BraceWrapping:
AfterClass: true
AfterControlStatement: true
AfterEnum: true
AfterFunction: true
AfterNamespace: false
AfterObjCDeclaration: true
AfterStruct: true
AfterUnion: true
BeforeCatch: true
BeforeElse: true
BreakBeforeBraces: Custom
ColumnLimit: 120
ConstructorInitializerAllOnOneLineOrOnePerLine: true
DerivePointerBinding: false
ExperimentalAutoDetectBinPacking: false
Cpp11BracedListStyle: false
DerivePointerAlignment: false
DisableFormat: false
IndentCaseLabels: false
MaxEmptyLinesToKeep: 1
IndentWidth: 4
KeepEmptyLinesAtTheStartOfBlocks: false
Language: Cpp
NamespaceIndentation: None
ObjCSpaceAfterProperty: false
ObjCSpaceBeforeProtocolList: true
PenaltyBreakBeforeFirstCallParameter: 19
PenaltyBreakComment: 300
PenaltyBreakString: 1000
PenaltyBreakFirstLessLess: 120
PenaltyExcessCharacter: 1000000
PenaltyReturnTypeOnItsOwnLine: 60
PointerBindsToType: false
SpacesBeforeTrailingComments: 1
Cpp11BracedListStyle: true
Standard: Cpp11
IndentWidth: 4
TabWidth: 8
UseTab: Never
BreakBeforeBraces: Allman
IndentFunctionDeclarationAfterType: false
SpacesInParentheses: false
SpacesInAngles: false
MaxEmptyLinesToKeep: 1
PointerAlignment: Right
SpaceAfterCStyleCast: false
SpaceBeforeParens: ControlStatements
SpaceInEmptyParentheses: false
SpacesBeforeTrailingComments: 1
SpacesInAngles: false
SpacesInCStyleCastParentheses: false
SpacesInContainerLiterals: true
SpaceBeforeAssignmentOperators: true
ContinuationIndentWidth: 4
CommentPragmas: '^ IWYU pragma:'
SpaceBeforeParens: Never
...
SpacesInParentheses: false
SpacesInSquareBrackets: false
Standard: Cpp11
UseTab: Never
...

View File

@ -30,7 +30,7 @@
#include <xlnt/common/types.hpp>
namespace xlnt {
enum class calendar;
class alignment;
@ -50,9 +50,9 @@ struct time;
struct timedelta;
namespace detail {
struct cell_impl;
} // namespace detail
/// <summary>
@ -66,7 +66,7 @@ struct cell_impl;
/// </remarks>
class cell
{
public:
public:
/// <summary>
/// Enumerates the possible types a cell can be determined by it's current value.
/// </summary>
@ -79,77 +79,77 @@ public:
error,
boolean
};
/// <summary>
/// Return a map of error strings such as #DIV/0! and their associated indices.
/// </summary>
static const std::unordered_map<std::string, int> error_codes();
//TODO: Should it be possible to construct and use a cell without a parent worksheet?
// TODO: Should it be possible to construct and use a cell without a parent worksheet?
//(cont'd) If so, it would need to be responsible for allocating and deleting its PIMPL.
/// <summary>
/// Construct a null cell without a parent.
/// Most methods will throw an exception if this cell is not further initialized.
/// </summary>
cell();
/// <summary>
/// Construct a cell in worksheet, sheet, at the given reference location (e.g. A1).
/// </summary>
cell(worksheet sheet, const cell_reference &reference);
/// <summary>
/// This constructor, provided for convenience, is equivalent to calling:
/// cell c(sheet, reference);
/// c.set_value(initial_value);
/// </summary>
template<typename T>
template <typename T>
cell(worksheet sheet, const cell_reference &reference, const T &initial_value);
// value
/// <summary>
/// Return true if value has been set and has not been cleared using cell::clear_value().
/// </summary>
bool has_value() const;
template<typename T>
template <typename T>
T get_value() const;
void clear_value();
template<typename T>
template <typename T>
void set_value(T value);
type get_data_type() const;
void set_data_type(type t);
// properties
/// <summary>
/// There's no reason to keep a cell which has no value and is not a placeholder.
/// Return true if this cell has no value, style, isn't merged, etc.
/// </summary>
bool garbage_collectible() const;
/// <summary>
/// Return true iff this cell's number format matches a date format.
/// </summary>
bool is_date() const;
// position
cell_reference get_reference() const;
std::string get_column() const;
column_t get_column_index() const;
row_t get_row() const;
std::pair<int, int> get_anchor() const;
// hyperlink
relationship get_hyperlink() const;
void set_hyperlink(const std::string &value);
bool has_hyperlink() const;
// style
bool has_style() const;
std::size_t get_style_id() const;
@ -170,13 +170,13 @@ public:
bool pivot_button() const;
void set_quote_prefix(bool b);
bool quote_prefix() const;
// comment
comment get_comment();
void set_comment(const comment &comment);
void clear_comment();
bool has_comment() const;
// formula
std::string get_formula() const;
void set_formula(const std::string &formula);
@ -184,47 +184,47 @@ public:
bool has_formula() const;
// printing
/// <summary>
/// Returns a string describing this cell like <Cell Sheet.A1>.
/// </summary>
std::string to_repr() const;
/// <summary>
/// Returns a string representing the value of this cell. If the data type is not a string,
/// it will be converted according to the number format.
/// </summary>
std::string to_string() const;
// merging
bool is_merged() const;
void set_merged(bool merged);
std::string get_error() const;
void set_error(const std::string &error);
cell offset(row_t row, column_t column);
worksheet get_parent();
const worksheet get_parent() const;
calendar get_base_date() const;
// operators
cell &operator=(const cell &rhs);
bool operator==(const cell &comparand) const;
bool operator==(std::nullptr_t) const;
// friend operators, so we can put cell on either side of comparisons with other types
friend bool operator==(std::nullptr_t, const cell &cell);
friend bool operator<(cell left, cell right);
private:
private:
friend class worksheet;
friend struct detail::cell_impl;
friend class style;
cell(detail::cell_impl *d);
detail::cell_impl *d_;
};
@ -237,5 +237,5 @@ inline std::ostream &operator<<(std::ostream &stream, const xlnt::cell &cell)
{
return stream << cell.to_string();
}
} // namespace xlnt

View File

@ -29,23 +29,23 @@
#include "../common/types.hpp"
namespace xlnt {
class cell_reference;
class range_reference;
struct cell_reference_hash
{
std::size_t operator()(const cell_reference &k) const;
};
class cell_reference
{
public:
public:
/// <summary>
/// Convert a coordinate to an absolute coordinate string (B12 -> $B$12)
/// </summary>
static cell_reference make_absolute(const cell_reference &relative_reference);
/// <summary>
/// Convert a column letter into a column number (e.g. B -> 2)
/// </summary>
@ -54,7 +54,7 @@ public:
/// restrict our column names to 1 - 3 characters, each in the range A - Z.
/// </remarks>
static column_t column_index_from_string(const std::string &column_string);
/// <summary>
/// Convert a column number into a column letter (3 -> 'C')
/// </summary>
@ -64,13 +64,13 @@ public:
/// ordinals by adding 64.
/// </remarks>
static std::string column_string_from_index(column_t column_index);
/// <summary>
/// Split a coordinate string like "A1" into an equivalent pair like {"A", 1}.
/// </summary>
static std::pair<std::string, row_t> split_reference(const std::string &reference_string,
bool &absolute_column, bool &absolute_row);
static std::pair<std::string, row_t> split_reference(const std::string &reference_string, bool &absolute_column,
bool &absolute_row);
// constructors
/// <summary>
/// Default constructor makes a reference to the top-left-most cell, "A1".
@ -80,21 +80,45 @@ public:
cell_reference(const std::string &reference_string);
cell_reference(const std::string &column, row_t row, bool absolute = false);
cell_reference(column_t column, row_t row, bool absolute = false);
// absoluateness
bool is_absolute() const { return absolute_; }
void set_absolute(bool absolute) { absolute_ = absolute; }
bool is_absolute() const
{
return absolute_;
}
void set_absolute(bool absolute)
{
absolute_ = absolute;
}
// getters/setters
std::string get_column() const { return column_string_from_index(column_); }
void set_column(const std::string &column_string) { column_ = column_index_from_string(column_string); }
column_t get_column_index() const { return column_; }
void set_column_index(column_t column) { column_ = column; }
row_t get_row() const { return row_ ; }
void set_row(row_t row) { row_ = row; }
std::string get_column() const
{
return column_string_from_index(column_);
}
void set_column(const std::string &column_string)
{
column_ = column_index_from_string(column_string);
}
column_t get_column_index() const
{
return column_;
}
void set_column_index(column_t column)
{
column_ = column;
}
row_t get_row() const
{
return row_;
}
void set_row(row_t row)
{
row_ = row;
}
/// <summary>
/// Return a cell_reference offset from this cell_reference by
/// the number of columns and rows specified by the parameters.
@ -102,54 +126,69 @@ public:
/// in a reference above or left of this cell_reference, respectively.
/// </summary>
cell_reference make_offset(int column_offset, int row_offset) const;
/// <summary>
/// Return a string like "A1" for cell_reference(1, 1).
/// </summary>
std::string to_string() const;
/// <summary>
/// Return a range_reference containing only this cell_reference.
/// </summary>
range_reference to_range() const;
// operators
/// <summary>
/// I've always wanted to overload the comma operator.
/// cell_reference("A", 1), cell_reference("B", 1) will return
/// range_reference(cell_reference("A", 1), cell_reference("B", 1))
/// </summary>
range_reference operator,(const cell_reference &other) const;
range_reference operator, (const cell_reference &other) const;
bool operator==(const cell_reference &comparand) const;
bool operator==(const std::string &reference_string) const { return *this == cell_reference(reference_string); }
bool operator==(const char *reference_string) const { return *this == std::string(reference_string); }
bool operator!=(const cell_reference &comparand) const { return !(*this == comparand); }
bool operator!=(const std::string &reference_string) const { return *this != cell_reference(reference_string); }
bool operator!=(const char *reference_string) const { return *this != std::string(reference_string); }
bool operator==(const std::string &reference_string) const
{
return *this == cell_reference(reference_string);
}
bool operator==(const char *reference_string) const
{
return *this == std::string(reference_string);
}
bool operator!=(const cell_reference &comparand) const
{
return !(*this == comparand);
}
bool operator!=(const std::string &reference_string) const
{
return *this != cell_reference(reference_string);
}
bool operator!=(const char *reference_string) const
{
return *this != std::string(reference_string);
}
bool operator<(const cell_reference &other);
bool operator>(const cell_reference &other);
bool operator<=(const cell_reference &other);
bool operator>=(const cell_reference &other);
private:
private:
/// <summary>
/// Index of the column. Important: this is one-indexed to conform
/// with Excel. Column "A", the first column, would have an index of 1.
/// </summary>
column_t column_;
/// <summary>
/// Index of the column. Important: this is one-indexed to conform
/// with Excel. Column "A", the first column, would have an index of 1.
/// </summary>
row_t row_;
/// <summary>
/// True if the reference is absolute. This looks like "$A$1" in Excel.
/// </summary>
bool absolute_;
};
} // namespace xlnt

View File

@ -3,11 +3,11 @@
#include <string>
namespace xlnt {
class cell;
namespace detail {
struct comment_impl;
} // namespace detail
@ -17,17 +17,17 @@ struct comment_impl;
/// </summary>
class comment
{
public:
public:
/// <summary>
/// The default constructor makes an invalid comment without a parent cell.
/// </summary>
comment();
comment(cell parent, const std::string &text, const std::string &auth);
~comment();
std::string get_text() const;
std::string get_author() const;
/// <summary>
/// True if the comments point to the same sell.
/// Note that a cell can only have one comment and a comment
@ -35,7 +35,7 @@ public:
/// </summary>
bool operator==(const comment &other) const;
private:
private:
friend class cell;
comment(detail::comment_impl *d);
detail::comment_impl *d_;

View File

@ -47,15 +47,14 @@ struct date
/// Return the current date according to the system time.
/// </summary>
static date today();
/// <summary>
/// Return a date by adding days_since_base_year to base_date.
/// This includes leap years.
/// </summary>
static date from_number(int days_since_base_year, calendar base_date);
date(int year_, int month_, int day_)
: year(year_), month(month_), day(day_)
date(int year_, int month_, int day_) : year(year_), month(month_), day(day_)
{
}
@ -63,7 +62,7 @@ struct date
/// Return the number of days between this date and base_date.
/// </summary>
int to_number(calendar base_date) const;
/// <summary>
/// Return true if this date is equal to comparand.
/// </summary>
@ -85,7 +84,7 @@ struct time
/// Return the current time according to the system time.
/// </summary>
static time now();
/// <summary>
/// Return a time from a number representing a fraction of a day.
/// The integer part of number will be ignored.
@ -114,13 +113,16 @@ struct datetime
/// Return the current date and time according to the system time.
/// </summary>
static datetime now();
/// <summary>
/// Return the current date and time according to the system time.
/// This is equivalent to datetime::now().
/// </summary>
static datetime today() { return now(); }
static datetime today()
{
return now();
}
/// <summary>
/// Return a datetime from number by converting the integer part into
/// a date and the fractional part into a time according to date::from_number
@ -129,7 +131,13 @@ struct datetime
static datetime from_number(long double number, calendar base_date);
datetime(int year_, int month_, int day_, int hour_ = 0, int minute_ = 0, int second_ = 0, int microsecond_ = 0)
: year(year_), month(month_), day(day_), hour(hour_), minute(minute_), second(second_), microsecond(microsecond_)
: year(year_),
month(month_),
day(day_),
hour(hour_),
minute(minute_),
second(second_),
microsecond(microsecond_)
{
}
@ -145,7 +153,7 @@ struct datetime
int second;
int microsecond;
};
/// <summary>
/// Represents a span of time between two datetimes. This is
/// not fully supported yet.
@ -153,18 +161,14 @@ struct datetime
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_),
minutes(minutes_),
seconds(seconds_),
microseconds(microseconds_)
: days(days_), hours(hours_), minutes(minutes_), seconds(seconds_), microseconds(microseconds_)
{
}
double to_number() const;
int days;
int hours;
int minutes;

View File

@ -34,7 +34,7 @@ namespace xlnt {
/// </summary>
class cell_coordinates_exception : public std::runtime_error
{
public:
public:
cell_coordinates_exception(row_t row, column_t column);
cell_coordinates_exception(const std::string &coord_string);
};
@ -45,7 +45,7 @@ public:
/// </summary>
class illegal_character_error : public std::runtime_error
{
public:
public:
illegal_character_error(char c);
};
@ -54,7 +54,7 @@ public:
/// </summary>
class column_string_index_exception : public std::runtime_error
{
public:
public:
column_string_index_exception();
};
@ -63,7 +63,7 @@ public:
/// </summary>
class data_type_exception : public std::runtime_error
{
public:
public:
data_type_exception();
};
@ -72,7 +72,7 @@ public:
/// </summary>
class named_range_exception : public std::runtime_error
{
public:
public:
named_range_exception();
};
@ -81,7 +81,7 @@ public:
/// </summary>
class sheet_title_exception : public std::runtime_error
{
public:
public:
sheet_title_exception(const std::string &title);
};
@ -90,7 +90,7 @@ public:
/// </summary>
class invalid_file_exception : public std::runtime_error
{
public:
public:
invalid_file_exception(const std::string &filename);
};
@ -99,7 +99,7 @@ public:
/// </summary>
class read_only_workbook_exception : public std::runtime_error
{
public:
public:
read_only_workbook_exception();
};
@ -108,7 +108,7 @@ public:
/// </summary>
class missing_number_format : public std::runtime_error
{
public:
public:
missing_number_format();
};
@ -117,13 +117,13 @@ public:
/// </summary>
class attribute_error : public std::runtime_error
{
public:
public:
attribute_error();
};
class value_error : public std::runtime_error
{
public:
public:
value_error() : std::runtime_error("")
{
}

View File

@ -3,13 +3,13 @@
#include <functional>
namespace xlnt {
//TODO: Can this be in source->detail, or must it be in a header?
// TODO: Can this be in source->detail, or must it be in a header?
template <class T>
inline void hash_combine(std::size_t& seed, const T& v)
inline void hash_combine(std::size_t &seed, const T &v)
{
std::hash<T> hasher;
seed ^= hasher(v) + 0x9e3779b9 + (seed<<6) + (seed>>2);
seed ^= hasher(v) + 0x9e3779b9 + (seed << 6) + (seed >> 2);
}
} // namespace xlnt

View File

@ -26,7 +26,7 @@
#include <string>
namespace xlnt {
/// <summary>
/// Specifies whether the target of a relationship is inside or outside the Package.
/// </summary>
@ -43,11 +43,12 @@ enum class target_mode
};
/// <summary>
/// Represents an association between a source Package or part, and a target object which can be a part or external resource.
/// Represents an association between a source Package or part, and a target object which can be a part or external
/// resource.
/// </summary>
class relationship
{
public:
public:
enum class type
{
invalid,
@ -63,113 +64,142 @@ public:
office_document,
custom_xml
};
static type type_from_string(const std::string &type_string)
{
if(type_string == "http://schemas.openxmlformats.org/officeDocument/2006/relationships/extended-properties")
if (type_string == "http://schemas.openxmlformats.org/officeDocument/2006/relationships/extended-properties")
{
return type::extended_properties;
}
else if(type_string == "http://schemas.openxmlformats.org/package/2006/relationships/metadata/core-properties")
else if (type_string == "http://schemas.openxmlformats.org/package/2006/relationships/metadata/core-properties")
{
return type::core_properties;
}
else if(type_string == "http://schemas.openxmlformats.org/officeDocument/2006/relationships/officeDocument")
else if (type_string == "http://schemas.openxmlformats.org/officeDocument/2006/relationships/officeDocument")
{
return type::office_document;
}
else if(type_string == "http://schemas.openxmlformats.org/officeDocument/2006/relationships/worksheet")
else if (type_string == "http://schemas.openxmlformats.org/officeDocument/2006/relationships/worksheet")
{
return type::worksheet;
}
else if(type_string == "http://schemas.openxmlformats.org/officeDocument/2006/relationships/sharedStrings")
else if (type_string == "http://schemas.openxmlformats.org/officeDocument/2006/relationships/sharedStrings")
{
return type::shared_strings;
}
else if(type_string == "http://schemas.openxmlformats.org/officeDocument/2006/relationships/styles")
else if (type_string == "http://schemas.openxmlformats.org/officeDocument/2006/relationships/styles")
{
return type::styles;
}
else if(type_string == "http://schemas.openxmlformats.org/officeDocument/2006/relationships/theme")
else if (type_string == "http://schemas.openxmlformats.org/officeDocument/2006/relationships/theme")
{
return type::theme;
}
else if(type_string == "http://schemas.openxmlformats.org/officeDocument/2006/relationships/hyperlink")
else if (type_string == "http://schemas.openxmlformats.org/officeDocument/2006/relationships/hyperlink")
{
return type::hyperlink;
}
else if(type_string == "http://schemas.openxmlformats.org/officeDocument/2006/relationships/chartsheet")
else if (type_string == "http://schemas.openxmlformats.org/officeDocument/2006/relationships/chartsheet")
{
return type::chartsheet;
}
else if(type_string == "http://schemas.openxmlformats.org/officeDocument/2006/relationships/customXml")
else if (type_string == "http://schemas.openxmlformats.org/officeDocument/2006/relationships/customXml")
{
return type::custom_xml;
}
return type::invalid;
}
static std::string type_to_string(type t)
{
switch(t)
switch (t)
{
case type::extended_properties: return "http://schemas.openxmlformats.org/officeDocument/2006/relationships/extended-properties";
case type::core_properties: return "http://schemas.openxmlformats.org/package/2006/relationships/metadata/core-properties";
case type::office_document: return "http://schemas.openxmlformats.org/officeDocument/2006/relationships/officeDocument";
case type::worksheet: return "http://schemas.openxmlformats.org/officeDocument/2006/relationships/worksheet";
case type::shared_strings: return "http://schemas.openxmlformats.org/officeDocument/2006/relationships/sharedStrings";
case type::styles: return "http://schemas.openxmlformats.org/officeDocument/2006/relationships/styles";
case type::theme: return "http://schemas.openxmlformats.org/officeDocument/2006/relationships/theme";
case type::hyperlink: return "http://schemas.openxmlformats.org/officeDocument/2006/relationships/hyperlink";
case type::chartsheet: return "http://schemas.openxmlformats.org/officeDocument/2006/relationships/chartsheet";
case type::custom_xml: return "http://schemas.openxmlformats.org/officeDocument/2006/relationships/customXml";
default: return "??";
case type::extended_properties:
return "http://schemas.openxmlformats.org/officeDocument/2006/relationships/extended-properties";
case type::core_properties:
return "http://schemas.openxmlformats.org/package/2006/relationships/metadata/core-properties";
case type::office_document:
return "http://schemas.openxmlformats.org/officeDocument/2006/relationships/officeDocument";
case type::worksheet:
return "http://schemas.openxmlformats.org/officeDocument/2006/relationships/worksheet";
case type::shared_strings:
return "http://schemas.openxmlformats.org/officeDocument/2006/relationships/sharedStrings";
case type::styles:
return "http://schemas.openxmlformats.org/officeDocument/2006/relationships/styles";
case type::theme:
return "http://schemas.openxmlformats.org/officeDocument/2006/relationships/theme";
case type::hyperlink:
return "http://schemas.openxmlformats.org/officeDocument/2006/relationships/hyperlink";
case type::chartsheet:
return "http://schemas.openxmlformats.org/officeDocument/2006/relationships/chartsheet";
case type::custom_xml:
return "http://schemas.openxmlformats.org/officeDocument/2006/relationships/customXml";
default:
return "??";
}
}
relationship();
relationship(const std::string &t, const std::string &r_id = "", const std::string &target_uri = "") : relationship(type_from_string(t), r_id, target_uri) {}
relationship(const std::string &t, const std::string &r_id = "", const std::string &target_uri = "")
: relationship(type_from_string(t), r_id, target_uri)
{
}
relationship(type t, const std::string &r_id = "", const std::string &target_uri = "");
/// <summary>
/// gets a string that identifies the relationship.
/// </summary>
std::string get_id() const { return id_; }
std::string get_id() const
{
return id_;
}
/// <summary>
/// gets the URI of the package or part that owns the relationship.
/// </summary>
std::string get_source_uri() const { return source_uri_; }
std::string get_source_uri() const
{
return source_uri_;
}
/// <summary>
/// gets a value that indicates whether the target of the relationship is or External to the Package.
/// </summary>
target_mode get_target_mode() const { return target_mode_; }
target_mode get_target_mode() const
{
return target_mode_;
}
/// <summary>
/// gets the URI of the target resource of the relationship.
/// </summary>
std::string get_target_uri() const { return target_uri_; }
type get_type() const { return type_; }
std::string get_type_string() const { return type_to_string(type_); }
std::string get_target_uri() const
{
return target_uri_;
}
type get_type() const
{
return type_;
}
std::string get_type_string() const
{
return type_to_string(type_);
}
friend bool operator==(const relationship &left, const relationship &right)
{
return left.type_ == right.type_
&& left.id_ == right.id_
&& left.source_uri_ == right.source_uri_
&& left.target_uri_ == right.target_uri_
&& left.target_mode_ == right.target_mode_;
return left.type_ == right.type_ && left.id_ == right.id_ && left.source_uri_ == right.source_uri_ &&
left.target_uri_ == right.target_uri_ && left.target_mode_ == right.target_mode_;
}
private:
private:
type type_;
std::string id_;
std::string source_uri_;
std::string target_uri_;
target_mode target_mode_;
};
} // namespace xlnt

View File

@ -24,9 +24,9 @@ struct zip_info
int minutes;
int seconds;
};
zip_info();
date_time_t date_time;
std::string filename;
std::string comment;
@ -46,70 +46,73 @@ struct zip_info
class zip_file
{
public:
public:
zip_file();
zip_file(const std::string &filename);
zip_file(const std::vector<unsigned char> &bytes);
zip_file(std::istream &stream);
~zip_file();
// to/from file
void load(const std::string &filename);
void save(const std::string &filename);
// to/from byte vector
void load(const std::vector<unsigned char> &bytes);
void save(std::vector<unsigned char> &bytes);
// to/from iostream
void load(std::istream &stream);
void save(std::ostream &stream);
void reset();
bool has_file(const std::string &name);
bool has_file(const zip_info &name);
zip_info getinfo(const std::string &name);
std::vector<zip_info> infolist();
std::vector<std::string> namelist();
std::ostream &open(const std::string &name);
std::ostream &open(const zip_info &name);
void extract(const std::string &name);
void extract(const std::string &name, const std::string &path);
void extract(const zip_info &name);
void extract(const zip_info &name, const std::string &path);
void extractall();
void extractall(const std::string &path);
void extractall(const std::string &path, const std::vector<std::string> &members);
void extractall(const std::string &path, const std::vector<zip_info> &members);
void printdir();
void printdir(std::ostream &stream);
std::string read(const std::string &name);
std::string read(const zip_info &name);
std::pair<bool, std::string> testzip();
void write(const std::string &filename);
void write(const std::string &filename, const std::string &arcname);
void writestr(const std::string &arcname, const std::string &bytes);
void writestr(const zip_info &arcname, const std::string &bytes);
std::string get_filename() const { return filename_; }
std::string get_filename() const
{
return filename_;
}
std::string comment;
private:
private:
void start_read();
void start_write();
void append_comment();
void remove_comment();

View File

@ -35,8 +35,8 @@ namespace xlnt {
enum class limit_style
{
openpyxl, /// limit style using in openpyxl
excel, /// limits according to Excel
maximum /// limits based on system
excel, /// limits according to Excel
maximum /// limits based on system
};
/// <summary>
@ -44,5 +44,4 @@ enum class limit_style
/// See limit_style for more information.
/// </summary>
const limit_style LimitStyle = limit_style::openpyxl;
}

View File

@ -27,13 +27,13 @@ namespace xlnt {
class worksheet;
struct drawing_struct;
class drawing
{
public:
public:
drawing();
private:
private:
friend class worksheet;
drawing(drawing_struct *root);
drawing_struct *root_;

View File

@ -1,7 +1,7 @@
namespace xlnt {
class tokenizer {
class tokenizer
{
};
} // namespace xlnt

View File

@ -9,22 +9,22 @@ class tokenizer;
class translator
{
translator(const std::string &formula, const cell_reference &ref);
std::vector<std::string> get_tokens();
static std::string translate_row(const std::string &row_str, int row_delta);
static std::string translate_col(const std::string &col_str, col_delta);
std::pair<std::string, std::string> strip_ws_name(const std::string &range_str);
void translate_range(const range_reference &range_ref);
void translate_formula(const cell_reference &dest);
private:
private:
const std::string ROW_RANGE_RE;
const std::string COL_RANGE_RE;
const std::string CELL_REF_RE;
std::string formula_;
cell_reference reference_;
tokenizer tokenizer_;

View File

@ -31,18 +31,18 @@
namespace xlnt {
class xml_document;
class comment_serializer
{
comment_serializer(worksheet sheet);
void read_comments(const xml_document &xml);
void read_comments_vml(const xml_document &xml);
xml_document write_comments() const;
xml_document write_comments_vml() const;
private:
private:
worksheet sheet_;
};

View File

@ -31,7 +31,7 @@
#include <xlnt/common/zip_file.hpp>
namespace xlnt {
class workbook;
/// <summary>
@ -40,48 +40,47 @@ class workbook;
/// </summary>
class excel_serializer
{
public:
public:
/// <summary>
///
/// </summary>
static const std::string central_directory_signature();
/// <summary>
///
/// </summary>
static std::string repair_central_directory(const std::string &original);
/// <summary>
/// Construct an excel_serializer which operates on wb.
/// </summary>
excel_serializer(workbook &wb);
/// <summary>
/// Create a ZIP file in memory, load archive from filename, then populate workbook
/// with data from archive.
/// </summary>
bool load_workbook(const std::string &filename, bool guess_types = false, bool data_only = false);
/// <summary>
/// Create a ZIP file in memory, load archive from stream, then populate workbook
/// with data from archive.
/// </summary>
bool load_stream_workbook(std::istream &stream, bool guess_types = false, bool data_only = false);
/// <summary>
/// Create a ZIP file in memory, load archive from bytes, then populate workbook
/// with data from archive.
/// </summary>
bool load_virtual_workbook(const std::vector<std::uint8_t> &bytes, bool guess_types = false, bool data_only = false);
bool load_virtual_workbook(const std::vector<std::uint8_t> &bytes, bool guess_types = false,
bool data_only = false);
/// <summary>
/// Create a ZIP file in memory, save workbook to this archive, then save archive
/// to filename.
/// </summary>
bool save_workbook(const std::string &filename, bool as_template = false);
/// <summary>
/// Create a ZIP file in memory, save workbook to this archive, then assign ZIP file
/// binary data to bytes.
@ -93,75 +92,75 @@ public:
/// binary data to stream.
/// </summary>
bool save_stream_workbook(std::ostream &stream, bool as_template = false);
private:
private:
/// <summary>
/// Reads all files in archive and populates workbook with associated data
/// using other appropriate serializers such as workbook_serializer.
/// </summary>
void read_data(bool guess_types, bool data_only);
/// <summary>
/// Read xl/sharedStrings.xml from internal archive and add shared strings to workbook.
/// </summary>
void read_shared_strings();
/// <summary>
///
/// </summary>
void read_images();
/// <summary>
///
/// </summary>
void read_charts();
/// <summary>
///
/// </summary>
void read_chartsheets();
/// <summary>
///
/// </summary>
void read_worksheets();
/// <summary>
///
/// </summary>
void read_external_links();
/// <summary>
/// Write all files needed to create a valid XLSX file which represents all
/// data contained in workbook.
/// </summary>
void write_data(bool as_template);
/// <summary>
/// Write xl/sharedStrings.xml to internal archive based on shared strings in workbook.
/// </summary>
void write_shared_strings();
/// <summary>
///
/// </summary>
void write_images();
/// <summary>
///
/// </summary>
void write_charts();
/// <summary>
///
/// </summary>
void write_chartsheets();
/// <summary>
///
/// </summary>
void write_worksheets();
/// <summary>
///
/// </summary>

View File

@ -3,22 +3,22 @@
#include <string>
namespace xlnt {
class manifest;
class xml_document;
class manifest_serializer
{
public:
public:
manifest_serializer(manifest &m);
void read_manifest(const xml_document &xml);
xml_document write_manifest() const;
std::string determine_document_type() const;
private:
private:
manifest &manifest_;
};
}; // namespace xlnt

View File

@ -4,15 +4,16 @@
#include <vector>
namespace xlnt {
class relationship;
class zip_file;
class relationship_serializer
{
public:
public:
static std::vector<relationship> read_relationships(zip_file &archive, const std::string &target);
static bool write_relationships(const std::vector<relationship> &relationships, const std::string &target, zip_file &archive);
static bool write_relationships(const std::vector<relationship> &relationships, const std::string &target,
zip_file &archive);
};
} // namespace xlnt

View File

@ -27,12 +27,12 @@
#include <vector>
namespace xlnt {
class xml_document;
class shared_strings_serializer
{
public:
public:
static bool read_shared_strings(const xml_document &xml, std::vector<std::string> &strings);
static xml_document write_shared_strings(const std::vector<std::string> &strings);
};

View File

@ -44,180 +44,180 @@ class side;
class style;
class xml_document;
class xml_node;
/// <summary>
/// Reads and writes xl/styles.xml from/to an associated workbook.
/// </summary>
class style_serializer
{
public:
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
//
/// <summary>
/// Load all styles from xml_document into workbook given in constructor.
/// </summary>
bool read_stylesheet(const xml_document &xml);
/// <summary>
/// Populate parameter xml with an XML tree representing the styles contained in the workbook
/// given in the constructor.
/// </summary>
xml_document write_stylesheet() const;
//TODO: These need to be public for unit tests. Could also make test class a friend?
//private:
// 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 and return a pair containing a name and corresponding style from named_style_node.
/// </summary>
static std::pair<std::string, style> read_named_style(const xml_node &named_style_node);
//
// Static element writers (i.e. writers that don't use internal state)
//
/// <summary>
/// Build and return an xml tree representing alignment_.
/// </summary>
static xml_node write_alignment(const alignment &alignment_);
/// <summary>
/// Build and return an xml tree representing border_.
/// </summary>
static xml_node write_border(const border &border_);
/// <summary>
/// Build and return an xml tree representing conditional_format_.
/// </summary>
static xml_node write_conditional_format(const conditional_format &conditional_format_);
/// <summary>
/// Build and return an xml tree representing fill_.
/// </summary>
static xml_node write_fill(const fill &fill_);
/// <summary>
/// Build and return an xml tree representing font_.
/// </summary>
static xml_node write_font(const font &font_);
/// <summary>
/// Build and return two xml trees, first=cell style and second=named style, representing named_style_.
/// </summary>
static std::pair<xml_node, xml_node> write_named_style(const named_style &named_style_);
/// <summary>
/// Build an xml tree representing all named styles in workbook into named_styles_node and cell_styles_node.
/// Returns true on success.
/// </summary>
static std::pair<xml_node, xml_node> write_named_styles();
/// <summary>
/// Build and return an xml tree representing number_format_.
/// </summary>
static xml_node write_number_format(const number_format &number_format_);
//
// Non-static element readers (i.e. readers that modify internal state)
//
/// <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 named styles from named_style_node and cell_styles_node and add them to workbook.
/// Return true on success.
/// </summary>
bool read_named_styles(const xml_node &named_styles_node);
/// <summary>
/// Read all borders from number_formats_node and add them to workbook.
/// Return true on success.
/// </summary>
bool read_number_formats(const xml_node &number_formats_node);
/// <summary>
/// Read a single style from the given node. In styles.xml, this is an "xf" element.
/// A style has an optional border id, fill id, font id, and number format id where
@ -227,48 +227,48 @@ public:
/// "applyFont=0" will not use the font in formatting.
/// </summary>
style read_style(const xml_node &style_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 fonts_node) const;
/// <summary>
/// Build an xml tree representing the given style into style_node.
/// Returns true on success.
/// </summary>
bool write_style(const style &style_, xml_node &style_node) const;
private:
private:
/// <summary>
/// Set in the constructor, this workbook is used as the source or target for all writing or reading, respectively.
/// </summary>

View File

@ -26,17 +26,17 @@
#include <string>
namespace xlnt {
class theme;
class xml_document;
class theme_serializer
{
public:
public:
bool read_theme(const xml_document &xml, theme &t);
xml_document write_theme(const theme &t) const;
private:
private:
};
} // namespace xlnt

View File

@ -36,28 +36,28 @@ class workbook;
class zip_file;
class xml_document;
class xml_node;
class workbook_serializer
{
public:
public:
using string_pair = std::pair<std::string, std::string>;
workbook_serializer(workbook &wb);
void read_workbook(const xml_document &xml);
void read_properties_app(const xml_document &xml);
void read_properties_core(const xml_document &xml);
xml_document write_workbook() const;
xml_document write_properties_app() const;
xml_document write_properties_core() const;
std::vector<string_pair> read_sheets();
std::vector<string_pair> detect_worksheets();
xml_node write_named_ranges() const;
private:
private:
workbook &workbook_;
};

View File

@ -29,7 +29,7 @@
#include <xlnt/worksheet/worksheet.hpp>
namespace xlnt {
class relationship;
class workbook;
class worksheet;
@ -37,13 +37,13 @@ class xml_document;
class worksheet_serializer
{
public:
public:
worksheet_serializer(worksheet sheet);
bool read_worksheet(const xml_document &xml);
xml_document write_worksheet() const;
private:
private:
worksheet sheet_;
};

View File

@ -8,39 +8,39 @@ namespace xlnt {
namespace detail {
struct xml_document_impl;
} // namespace detail
class xml_node;
class xml_serializer;
class xml_document
{
public:
public:
using string_pair = std::pair<std::string, std::string>;
xml_document();
xml_document(const xml_document &other);
xml_document(xml_document &&other);
~xml_document();
xml_document &operator=(const xml_document &other);
xml_document &operator=(xml_document &&other);
void set_encoding(const std::string &encoding);
void add_namespace(const std::string &id, const std::string &uri);
xml_node add_child(const xml_node &child);
xml_node add_child(const std::string &child_name);
xml_node get_root();
const xml_node get_root() const;
xml_node get_child(const std::string &child_name);
const xml_node get_child(const std::string &child_name) const;
std::string to_string() const;
xml_document &from_string(const std::string &xml_string);
private:
private:
friend class xml_serializer;
std::unique_ptr<detail::xml_document_impl> d_;
};

View File

@ -8,42 +8,42 @@ namespace xlnt {
namespace detail {
struct xml_node_impl;
} // namespace detail
class xml_document;
class xml_node
{
public:
public:
using string_pair = std::pair<std::string, std::string>;
xml_node();
xml_node(const xml_node &other);
~xml_node();
xml_node &operator=(const xml_node &other);
std::string get_name() const;
void set_name(const std::string &name);
bool has_text() const;
std::string get_text() const;
void set_text(const std::string &text);
const std::vector<xml_node> get_children() const;
bool has_child(const std::string &child_name) const;
xml_node get_child(const std::string &child_name);
const xml_node get_child(const std::string &child_name) const;
xml_node add_child(const xml_node &child);
xml_node add_child(const std::string &child_name);
const std::vector<string_pair> get_attributes() const;
bool has_attribute(const std::string &attribute_name) const;
std::string get_attribute(const std::string &attribute_name) const;
void add_attribute(const std::string &name, const std::string &value);
std::string to_string() const;
private:
private:
friend class xml_document;
friend class xml_serializer;
xml_node(const detail::xml_node_impl &d);

View File

@ -9,7 +9,7 @@ class xml_node;
class xml_serializer
{
public:
public:
static std::string serialize(const xml_document &xml);
static xml_document deserialize(const std::string &xml_string);

View File

@ -32,7 +32,7 @@ namespace xlnt {
/// </summary>
class alignment
{
public:
public:
enum class horizontal_alignment
{
none,
@ -43,7 +43,7 @@ public:
center_continuous,
justify
};
enum class vertical_alignment
{
none,
@ -52,52 +52,52 @@ public:
center,
justify
};
bool get_wrap_text() const
{
return wrap_text_;
}
void set_wrap_text(bool wrap_text)
{
wrap_text_ = wrap_text;
}
bool has_horizontal() const
{
return horizontal_ != horizontal_alignment::none;
}
horizontal_alignment get_horizontal() const
{
return horizontal_;
}
void set_horizontal(horizontal_alignment horizontal)
{
horizontal_ = horizontal;
}
bool has_vertical() const
{
return vertical_ != vertical_alignment::none;
}
vertical_alignment get_vertical() const
{
return vertical_;
}
void set_vertical(vertical_alignment vertical)
{
vertical_ = vertical;
}
bool operator==(const alignment &other) const
{
return hash() == other.hash();
}
std::size_t hash() const
{
std::size_t seed = 0;
@ -109,8 +109,8 @@ public:
hash_combine(seed, indent_);
return seed;
}
private:
private:
horizontal_alignment horizontal_ = horizontal_alignment::none;
vertical_alignment vertical_ = vertical_alignment::none;
int text_rotation_ = 0;

View File

@ -30,7 +30,7 @@
#include "../common/hash_combine.hpp"
namespace xlnt {
enum class diagonal_direction
{
none,
@ -38,12 +38,12 @@ enum class diagonal_direction
down,
both
};
class border
{
public:
public:
static border default_border();
bool start_assigned = false;
side start;
bool end_assigned = false;
@ -66,36 +66,36 @@ public:
bool outline = false;
bool diagonal_up = false;
bool diagonal_down = false;
diagonal_direction diagonal_direction_ = diagonal_direction::none;
bool operator==(const border &other) const
{
return hash() == other.hash();
}
std::size_t hash() const
{
std::size_t seed = 0;
hash_combine(seed, start_assigned);
if(start_assigned) hash_combine(seed, start.hash());
if (start_assigned) hash_combine(seed, start.hash());
hash_combine(seed, end_assigned);
if(end_assigned) hash_combine(seed, end.hash());
if (end_assigned) hash_combine(seed, end.hash());
hash_combine(seed, left_assigned);
if(left_assigned) hash_combine(seed, left.hash());
if (left_assigned) hash_combine(seed, left.hash());
hash_combine(seed, right_assigned);
if(right_assigned) hash_combine(seed, right.hash());
if (right_assigned) hash_combine(seed, right.hash());
hash_combine(seed, top_assigned);
if(top_assigned) hash_combine(seed, top.hash());
if (top_assigned) hash_combine(seed, top.hash());
hash_combine(seed, bottom_assigned);
if(bottom_assigned) hash_combine(seed, bottom.hash());
if (bottom_assigned) hash_combine(seed, bottom.hash());
hash_combine(seed, diagonal_assigned);
if(diagonal_assigned) hash_combine(seed, diagonal.hash());
if (diagonal_assigned) hash_combine(seed, diagonal.hash());
hash_combine(seed, vertical_assigned);
if(vertical_assigned) hash_combine(seed, vertical.hash());
if (vertical_assigned) hash_combine(seed, vertical.hash());
hash_combine(seed, horizontal_assigned);
if(horizontal_assigned) hash_combine(seed, horizontal.hash());
if (horizontal_assigned) hash_combine(seed, horizontal.hash());
return seed;
}

View File

@ -31,7 +31,7 @@ namespace xlnt {
class color
{
public:
public:
enum class type
{
indexed,
@ -39,7 +39,7 @@ public:
auto_,
rgb
};
static const color black;
static const color white;
static const color red;
@ -50,85 +50,87 @@ public:
static const color darkgreen;
static const color yellow;
static const color darkyellow;
color() {}
color()
{
}
color(type t, std::size_t v) : type_(t), index_(v)
{
}
color(type t, const std::string &v) : type_(t), rgb_string_(v)
{
}
void set_auto(int auto_index)
{
type_ = type::auto_;
index_ = auto_index;
}
void set_index(int index)
{
type_ = type::indexed;
index_ = index;
}
void set_theme(int theme)
{
type_ = type::theme;
index_ = theme;
}
type get_type() const
{
return type_;
}
int get_auto() const
{
if(type_ != type::auto_)
if (type_ != type::auto_)
{
throw std::runtime_error("not auto color");
}
return index_;
}
int get_index() const
{
if(type_ != type::indexed)
if (type_ != type::indexed)
{
throw std::runtime_error("not indexed color");
}
return index_;
}
int get_theme() const
{
if(type_ != type::theme)
if (type_ != type::theme)
{
throw std::runtime_error("not theme color");
}
return index_;
}
std::string get_rgb_string() const
{
if(type_ != type::rgb)
if (type_ != type::rgb)
{
throw std::runtime_error("not rgb color");
}
return rgb_string_;
}
std::size_t hash() const
{
auto seed = static_cast<std::size_t>(type_);
if(type_ != type::rgb)
if (type_ != type::rgb)
{
hash_combine(seed, index_);
}
@ -136,16 +138,16 @@ public:
{
hash_combine(seed, rgb_string_);
}
return seed;
}
bool operator==(const color &other) const
{
return hash() == other.hash();
}
private:
private:
type type_ = type::indexed;
int index_ = 0;
std::string rgb_string_;

View File

@ -30,7 +30,7 @@ namespace xlnt {
class fill
{
public:
public:
enum class type
{
none,
@ -38,13 +38,13 @@ public:
gradient,
pattern
};
enum class gradient_type
{
linear,
path
};
enum class pattern_type
{
none,
@ -67,147 +67,176 @@ public:
lightvertical,
mediumgray,
};
type get_type() const { return type_; }
void set_type(type t) { type_ = t; }
type get_type() const
{
return type_;
}
void set_type(type t)
{
type_ = t;
}
std::string get_pattern_type_string() const
{
if(type_ != type::pattern)
if (type_ != type::pattern)
{
throw std::runtime_error("not pattern fill");
}
switch(pattern_type_)
switch (pattern_type_)
{
case pattern_type::none: return "none";
case pattern_type::solid: return "solid";
case pattern_type::darkdown: return "darkdown";
case pattern_type::darkgray: return "darkgray";
case pattern_type::darkgrid: return "darkgrid";
case pattern_type::darkhorizontal: return "darkhorizontal";
case pattern_type::darktrellis: return "darktrellis";
case pattern_type::darkup: return "darkup";
case pattern_type::darkvertical: return "darkvertical";
case pattern_type::gray0625: return "gray0625";
case pattern_type::gray125: return "gray125";
case pattern_type::lightdown: return "lightdown";
case pattern_type::lightgray: return "lightgray";
case pattern_type::lightgrid: return "lightgrid";
case pattern_type::lighthorizontal: return "lighthorizontal";
case pattern_type::lighttrellis: return "lighttrellis";
case pattern_type::lightup: return "lightup";
case pattern_type::lightvertical: return "lightvertical";
case pattern_type::mediumgray: return "mediumgray";
default: throw std::runtime_error("invalid type");
case pattern_type::none:
return "none";
case pattern_type::solid:
return "solid";
case pattern_type::darkdown:
return "darkdown";
case pattern_type::darkgray:
return "darkgray";
case pattern_type::darkgrid:
return "darkgrid";
case pattern_type::darkhorizontal:
return "darkhorizontal";
case pattern_type::darktrellis:
return "darktrellis";
case pattern_type::darkup:
return "darkup";
case pattern_type::darkvertical:
return "darkvertical";
case pattern_type::gray0625:
return "gray0625";
case pattern_type::gray125:
return "gray125";
case pattern_type::lightdown:
return "lightdown";
case pattern_type::lightgray:
return "lightgray";
case pattern_type::lightgrid:
return "lightgrid";
case pattern_type::lighthorizontal:
return "lighthorizontal";
case pattern_type::lighttrellis:
return "lighttrellis";
case pattern_type::lightup:
return "lightup";
case pattern_type::lightvertical:
return "lightvertical";
case pattern_type::mediumgray:
return "mediumgray";
default:
throw std::runtime_error("invalid type");
}
}
std::string get_gradient_type_string() const
{
if(type_ != type::gradient)
if (type_ != type::gradient)
{
throw std::runtime_error("not gradient fill");
}
switch(gradient_type_)
switch (gradient_type_)
{
case gradient_type::linear: return "linear";
case gradient_type::path: return "path";
default: throw std::runtime_error("invalid type");
case gradient_type::linear:
return "linear";
case gradient_type::path:
return "path";
default:
throw std::runtime_error("invalid type");
}
}
pattern_type get_pattern_type() const
{
return pattern_type_;
}
void set_pattern_type(pattern_type t)
{
type_ = type::pattern;
pattern_type_ = t;
}
void set_gradient_type(gradient_type t)
{
type_ = type::gradient;
gradient_type_ = t;
}
void set_start_color(const color &c)
{
start_color_ = c;
start_color_assigned_ = true;
}
void set_end_color(const color &c)
{
end_color_ = c;
end_color_assigned_ = true;
}
void set_foreground_color(const color &c)
{
foreground_color_ = c;
foreground_color_assigned_ = true;
}
void set_background_color(const color &c)
{
background_color_ = c;
background_color_assigned_ = true;
}
color get_foreground_color() const
{
return foreground_color_;
}
color get_background_color() const
{
return background_color_;
}
bool has_foreground_color() const
{
return foreground_color_assigned_;
}
bool has_background_color() const
{
return background_color_assigned_;
}
bool operator==(const fill &other) const
{
return hash() == other.hash();
}
void set_rotation(double rotation)
{
rotation_ = rotation;
}
double get_rotation() const
{
return rotation_;
}
std::size_t hash() const
{
auto seed = static_cast<std::size_t>(type_);
if(type_ == type::pattern)
if (type_ == type::pattern)
{
hash_combine(seed, static_cast<std::size_t>(pattern_type_));
hash_combine(seed, foreground_color_assigned_);
if(foreground_color_assigned_)
if (foreground_color_assigned_)
{
hash_combine(seed, static_cast<std::size_t>(foreground_color_.get_type()));
switch(foreground_color_.get_type())
switch (foreground_color_.get_type())
{
case color::type::auto_:
hash_combine(seed, static_cast<std::size_t>(foreground_color_.get_auto()));
@ -222,59 +251,71 @@ public:
break;
}
}
hash_combine(seed, background_color_assigned_);
if(background_color_assigned_)
if (background_color_assigned_)
{
hash_combine(seed, static_cast<std::size_t>(background_color_.get_type()));
switch(foreground_color_.get_type())
switch (foreground_color_.get_type())
{
case color::type::auto_:
hash_combine(seed, static_cast<std::size_t>(background_color_.get_auto()));
break;
case color::type::indexed:
hash_combine(seed, static_cast<std::size_t>(background_color_.get_index()));
break;
case color::type::theme:
hash_combine(seed, static_cast<std::size_t>(background_color_.get_theme()));
break;
case color::type::rgb:
break;
case color::type::auto_:
hash_combine(seed, static_cast<std::size_t>(background_color_.get_auto()));
break;
case color::type::indexed:
hash_combine(seed, static_cast<std::size_t>(background_color_.get_index()));
break;
case color::type::theme:
hash_combine(seed, static_cast<std::size_t>(background_color_.get_theme()));
break;
case color::type::rgb:
break;
}
}
}
else if(type_ == type::gradient)
else if (type_ == type::gradient)
{
hash_combine(seed, static_cast<std::size_t>(gradient_type_));
if(gradient_type_ == gradient_type::path)
if (gradient_type_ == gradient_type::path)
{
hash_combine(seed, gradient_path_left_);
hash_combine(seed, gradient_path_right_);
hash_combine(seed, gradient_path_top_);
hash_combine(seed, gradient_path_bottom_);
}
else if(gradient_type_ == gradient_type::linear)
else if (gradient_type_ == gradient_type::linear)
{
hash_combine(seed, rotation_);
}
}
else if(type_ == type::solid)
else if (type_ == type::solid)
{
// hash_combine(seed, static_cast<std::size_t>());
// hash_combine(seed, static_cast<std::size_t>());
}
return seed;
}
double get_gradient_left() const { return gradient_path_left_; }
double get_gradient_right() const { return gradient_path_right_; }
double get_gradient_top() const { return gradient_path_top_; }
double get_gradient_bottom() const { return gradient_path_bottom_; }
private:
double get_gradient_left() const
{
return gradient_path_left_;
}
double get_gradient_right() const
{
return gradient_path_right_;
}
double get_gradient_top() const
{
return gradient_path_top_;
}
double get_gradient_bottom() const
{
return gradient_path_bottom_;
}
private:
type type_ = type::none;
pattern_type pattern_type_;
gradient_type gradient_type_;

View File

@ -29,12 +29,12 @@
#include <xlnt/styles/color.hpp>
namespace xlnt {
class style;
class font
{
public:
public:
enum class underline_style
{
none,
@ -43,37 +43,99 @@ public:
single,
single_accounting
};
void set_bold(bool bold) { bold_ = bold; }
bool is_bold() const { return bold_; }
void set_italic(bool italic) { italic_ = italic; }
bool is_italic() const { return italic_; }
void set_strikethrough(bool strikethrough) { strikethrough_ = strikethrough; }
bool is_strikethrough() const { return strikethrough_; }
void set_underline(underline_style new_underline) { underline_ = new_underline; }
bool is_underline() const { return underline_ != underline_style::none; }
underline_style get_underline() const { return underline_; }
void set_size(int size) { size_ = size; }
int get_size() const { return size_; }
void set_name(const std::string &name) { name_ = name; }
std::string get_name() const { return name_; }
void set_color(color c) { color_ = c; }
void set_family(int family) { has_family_ = true; family_ = family; }
void set_scheme(const std::string &scheme) { has_scheme_ = true; scheme_ = scheme; }
color get_color() const { return color_; }
bool has_family() const { return has_family_; }
int get_family() const { return family_; }
bool has_scheme() const { return has_scheme_; }
void set_bold(bool bold)
{
bold_ = bold;
}
bool is_bold() const
{
return bold_;
}
void set_italic(bool italic)
{
italic_ = italic;
}
bool is_italic() const
{
return italic_;
}
void set_strikethrough(bool strikethrough)
{
strikethrough_ = strikethrough;
}
bool is_strikethrough() const
{
return strikethrough_;
}
void set_underline(underline_style new_underline)
{
underline_ = new_underline;
}
bool is_underline() const
{
return underline_ != underline_style::none;
}
underline_style get_underline() const
{
return underline_;
}
void set_size(int size)
{
size_ = size;
}
int get_size() const
{
return size_;
}
void set_name(const std::string &name)
{
name_ = name;
}
std::string get_name() const
{
return name_;
}
void set_color(color c)
{
color_ = c;
}
void set_family(int family)
{
has_family_ = true;
family_ = family;
}
void set_scheme(const std::string &scheme)
{
has_scheme_ = true;
scheme_ = scheme;
}
color get_color() const
{
return color_;
}
bool has_family() const
{
return has_family_;
}
int get_family() const
{
return family_;
}
bool has_scheme() const
{
return has_scheme_;
}
std::size_t hash() const
{
std::size_t seed = bold_;
@ -85,39 +147,44 @@ public:
hash_combine(seed, size_);
hash_combine(seed, static_cast<std::size_t>(underline_));
hash_combine(seed, static_cast<std::size_t>(color_.get_type()));
switch(color_.get_type())
switch (color_.get_type())
{
case color::type::indexed: hash_combine(seed, color_.get_index()); break;
case color::type::theme: hash_combine(seed, color_.get_theme()); break;
default: break;
case color::type::indexed:
hash_combine(seed, color_.get_index());
break;
case color::type::theme:
hash_combine(seed, color_.get_theme());
break;
default:
break;
}
hash_combine(seed, family_);
hash_combine(seed, scheme_);
return seed;
}
bool operator==(const font &other) const
{
return hash() == other.hash();
}
private:
private:
friend class style;
std::string name_ = "Calibri";
int size_ = 11;
bool bold_ = false;
bool italic_ = false;
bool superscript_ = false;
bool subscript_ = false;
underline_style underline_ = underline_style::none;
bool strikethrough_ = false;
color color_;
bool has_family_ = false;
int family_;
bool has_scheme_ = false;
std::string scheme_;
std::string name_ = "Calibri";
int size_ = 11;
bool bold_ = false;
bool italic_ = false;
bool superscript_ = false;
bool subscript_ = false;
underline_style underline_ = underline_style::none;
bool strikethrough_ = false;
color color_;
bool has_family_ = false;
int family_;
bool has_scheme_ = false;
std::string scheme_;
};
} // namespace xlnt

View File

@ -29,17 +29,17 @@ namespace xlnt {
class named_style
{
public:
public:
named_style();
std::size_t hash() const;
bool operator==(const named_style &other) const
{
return style_.hash() == other.style_.hash();
}
private:
private:
std::string name_;
style style_;
};

View File

@ -31,7 +31,7 @@ namespace xlnt {
class number_format
{
public:
public:
static const number_format general();
static const number_format text();
static const number_format number();
@ -68,25 +68,31 @@ public:
static const number_format currency_eur_simple();
static number_format from_builtin_id(int builtin_id);
number_format();
number_format(int builtin_id);
number_format(const std::string &code, int custom_id = -1);
void set_format_string(const std::string &format_code, int id = -1);
std::string get_format_string() const;
void set_id(int id) { id_ = id; }
int get_id() const { return id_; }
void set_id(int id)
{
id_ = id;
}
int get_id() const
{
return id_;
}
std::size_t hash() const;
bool operator==(const number_format &other) const
{
return hash() == other.hash();
}
private:
private:
int id_;
std::string format_string_;
};

View File

@ -31,41 +31,41 @@ namespace xlnt {
class protection
{
public:
public:
enum class type
{
inherit,
protected_,
unprotected
};
protection();
protection(type locked);
void set_locked(type locked_type)
{
locked_ = locked_type;
}
void set_hidden(type hidden_type)
{
hidden_ = hidden_type;
}
bool operator==(const protection &other) const
{
return hash() == other.hash();
}
std::size_t hash() const
{
std::size_t seed = static_cast<std::size_t>(locked_);
hash_combine(seed, static_cast<std::size_t>(hidden_));
return seed;
}
private:
private:
type locked_;
type hidden_;
};

View File

@ -49,72 +49,72 @@ enum class border_style
class side
{
public:
public:
side();
std::size_t hash() const
{
std::size_t seed = 0;
hash_combine(seed, style_assigned_);
if(style_assigned_)
if (style_assigned_)
{
hash_combine(seed, static_cast<std::size_t>(style_));
}
hash_combine(seed, color_assigned_);
if(color_assigned_)
if (color_assigned_)
{
hash_combine(seed, color_.hash());
}
return seed;
}
border_style get_style() const
{
return style_;
}
color get_color() const
{
return color_;
}
bool is_style_assigned() const
{
return style_assigned_;
}
bool is_color_assigned() const
{
return color_assigned_;
}
bool operator==(const side &other) const
{
return other.style_ == style_ && color_ == other.color_;
}
void set_border_style(border_style bs)
{
style_assigned_ = true;
style_ = bs;
}
void set_color(color new_color)
{
color_assigned_ = true;
color_ = new_color;
}
private:
private:
bool style_assigned_ = false;
border_style style_ = border_style::none;
bool color_assigned_ = false;
color color_ = color::black;
};
} // namespace xlnt

View File

@ -36,13 +36,13 @@ class workbook;
class style
{
public:
public:
style();
style(const style &other);
style &operator=(const style &other);
std::size_t hash() const;
const alignment get_alignment() const;
const border get_border() const;
const fill get_fill() const;
@ -51,54 +51,87 @@ public:
const protection get_protection() const;
bool pivot_button() const;
bool quote_prefix() const;
std::size_t get_id() const { return id_; }
std::size_t get_fill_id() const { return fill_id_; }
std::size_t get_font_id() const { return font_id_; }
std::size_t get_border_id() const { return border_id_; }
std::size_t get_number_format_id() const { return number_format_id_; }
void apply_alignment(bool apply) { alignment_apply_ = apply; }
void apply_border(bool apply) { border_apply_ = apply; }
void apply_fill(bool apply) { fill_apply_ = apply; }
void apply_font(bool apply) { font_apply_ = apply; }
void apply_number_format(bool apply) { number_format_apply_ = apply; }
void apply_protection(bool apply) { protection_apply_ = apply; }
std::size_t get_id() const
{
return id_;
}
std::size_t get_fill_id() const
{
return fill_id_;
}
std::size_t get_font_id() const
{
return font_id_;
}
std::size_t get_border_id() const
{
return border_id_;
}
std::size_t get_number_format_id() const
{
return number_format_id_;
}
void apply_alignment(bool apply)
{
alignment_apply_ = apply;
}
void apply_border(bool apply)
{
border_apply_ = apply;
}
void apply_fill(bool apply)
{
fill_apply_ = apply;
}
void apply_font(bool apply)
{
font_apply_ = apply;
}
void apply_number_format(bool apply)
{
number_format_apply_ = apply;
}
void apply_protection(bool apply)
{
protection_apply_ = apply;
}
bool operator==(const style &other) const
{
return hash() == other.hash();
}
private:
private:
friend class style_serializer;
friend class workbook;
std::size_t id_;
bool alignment_apply_;
alignment alignment_;
bool border_apply_;
std::size_t border_id_;
border border_;
bool fill_apply_;
std::size_t fill_id_;
fill fill_;
bool font_apply_;
std::size_t font_id_;
font font_;
bool number_format_apply_;
std::size_t number_format_id_;
number_format number_format_;
bool protection_apply_;
protection protection_;
bool pivot_button_;
bool quote_prefix_;
};

View File

@ -34,9 +34,9 @@ namespace xlnt {
/// </summary>
class document_properties
{
public:
public:
document_properties();
std::string creator;
std::string last_modified_by;
datetime created;

View File

@ -26,20 +26,20 @@
#include <string>
namespace xlnt {
/// <summary>
/// Security information about the document.
/// </summary>
class document_security
{
public:
public:
document_security();
bool lock_revision;
bool lock_structure;
bool lock_windows;
std::string revision_password;
std::string workbook_password;
};
} // namespace xlnt

View File

@ -2,8 +2,7 @@
namespace xlnt {
class external_book {
class external_book
{
};
}

View File

@ -4,57 +4,75 @@
#include <vector>
namespace xlnt {
class default_type
{
public:
public:
default_type();
default_type(const std::string &extension, const std::string &content_type);
default_type(const default_type &other);
default_type &operator=(const default_type &other);
std::string get_extension() const { return extension_; }
std::string get_content_type() const { return content_type_; }
private:
std::string get_extension() const
{
return extension_;
}
std::string get_content_type() const
{
return content_type_;
}
private:
std::string extension_;
std::string content_type_;
};
class override_type
{
public:
public:
override_type();
override_type(const std::string &extension, const std::string &content_type);
override_type(const override_type &other);
override_type &operator=(const override_type &other);
std::string get_part_name() const { return part_name_; }
std::string get_content_type() const { return content_type_; }
private:
std::string get_part_name() const
{
return part_name_;
}
std::string get_content_type() const
{
return content_type_;
}
private:
std::string part_name_;
std::string content_type_;
};
class manifest
{
public:
public:
void add_default_type(const std::string &extension, const std::string &content_type);
void add_override_type(const std::string &part_name, const std::string &content_type);
const std::vector<default_type> &get_default_types() const { return default_types_; }
const std::vector<override_type> &get_override_types() const { return override_types_; }
const std::vector<default_type> &get_default_types() const
{
return default_types_;
}
const std::vector<override_type> &get_override_types() const
{
return override_types_;
}
bool has_default_type(const std::string &extension) const;
bool has_override_type(const std::string &part_name) const;
std::string get_default_type(const std::string &extension) const;
std::string get_override_type(const std::string &part_name) const;
private:
private:
std::vector<default_type> default_types_;
std::vector<override_type> override_types_;
};
} // namespace xlnt

View File

@ -7,26 +7,31 @@ namespace xlnt {
class range_reference;
class worksheet;
std::vector<std::pair<std::string, std::string>> split_named_range(const std::string &named_range_string);
class named_range
{
public:
public:
using target = std::pair<worksheet, range_reference>;
named_range();
named_range(const named_range &other);
named_range(const std::string &name, const std::vector<target> &targets);
std::string get_name() const { return name_; }
const std::vector<target> &get_targets() const { return targets_; }
std::string get_name() const
{
return name_;
}
const std::vector<target> &get_targets() const
{
return targets_;
}
named_range &operator=(const named_range &other);
private:
private:
std::string name_;
std::vector<target> targets_;
};
}

View File

@ -4,7 +4,6 @@ namespace xlnt {
class theme
{
};
} // namespace xlnt

View File

@ -52,11 +52,11 @@ class style;
class theme;
class worksheet;
class zip_file;
enum class encoding;
namespace detail {
struct workbook_impl;
namespace detail {
struct workbook_impl;
} // namespace detail
/// <summary>
@ -64,51 +64,57 @@ namespace detail {
/// </summary>
class workbook
{
public:
public:
class iterator
{
public:
public:
iterator(workbook &wb, std::size_t index);
iterator(const iterator &);
iterator &operator=(const iterator &);
worksheet operator*();
bool operator==(const iterator &comparand) const;
bool operator!=(const iterator &comparand) const { return !(*this == comparand); }
bool operator!=(const iterator &comparand) const
{
return !(*this == comparand);
}
iterator operator++(int);
iterator &operator++();
private:
private:
workbook &wb_;
std::size_t index_;
};
class const_iterator
{
public:
public:
const_iterator(const workbook &wb, std::size_t index);
const_iterator(const const_iterator &);
const_iterator &operator=(const const_iterator &);
const worksheet operator*();
bool operator==(const const_iterator &comparand) const;
bool operator!=(const const_iterator &comparand) const { return !(*this == comparand); }
bool operator!=(const const_iterator &comparand) const
{
return !(*this == comparand);
}
const_iterator operator++(int);
const_iterator &operator++();
private:
private:
const workbook &wb_;
std::size_t index_;
};
static std::size_t index_from_ws_filename(const std::string &filename);
//constructors
// constructors
workbook();
workbook(encoding e);
workbook &operator=(workbook other);
workbook(workbook &&other);
workbook(const workbook &other);
friend void swap(workbook &left, workbook &right);
worksheet get_active_sheet();
@ -118,80 +124,86 @@ public:
bool get_data_only() const;
void set_data_only(bool data_only);
//create
// create
worksheet create_sheet();
worksheet create_sheet(std::size_t index);
worksheet create_sheet(const std::string &title);
worksheet create_sheet(std::size_t index, const std::string &title);
worksheet create_sheet(const std::string &title, const relationship &rel);
//add
worksheet create_sheet(const std::string &title, const relationship &rel);
// add
void add_sheet(worksheet worksheet);
void add_sheet(worksheet worksheet, std::size_t index);
//remove
// remove
void remove_sheet(worksheet worksheet);
void clear();
//container operations
// container operations
worksheet get_sheet_by_name(const std::string &sheet_name);
const worksheet get_sheet_by_name(const std::string &sheet_name) const;
worksheet get_sheet_by_index(std::size_t index);
const worksheet get_sheet_by_index(std::size_t index) const;
bool contains(const std::string &key) const;
int get_index(worksheet worksheet);
worksheet operator[](const std::string &name);
worksheet operator[](std::size_t index);
iterator begin();
iterator end();
const_iterator begin() const { return cbegin(); }
const_iterator end() const { return cend(); }
const_iterator begin() const
{
return cbegin();
}
const_iterator end() const
{
return cend();
}
const_iterator cbegin() const;
const_iterator cend() const;
std::vector<std::string> get_sheet_names() const;
document_properties &get_properties();
const document_properties &get_properties() const;
//named ranges
// named ranges
std::vector<named_range> get_named_ranges() const;
void create_named_range(const std::string &name, worksheet worksheet, const range_reference &reference);
bool has_named_range(const std::string &name) const;
range get_named_range(const std::string &name);
void remove_named_range(const std::string &name);
//serialization
// serialization
bool save(std::vector<unsigned char> &data);
bool save(const std::string &filename);
bool load(const std::vector<unsigned char> &data);
bool load(const std::string &filename);
bool load(std::istream &stream);
bool load(zip_file &archive);
bool operator==(const workbook &rhs) const;
bool operator!=(const workbook &rhs) const
{
return !(*this == rhs);
}
bool operator==(std::nullptr_t) const;
bool operator!=(std::nullptr_t) const
{
return !(*this == std::nullptr_t{});
}
void create_relationship(const std::string &id, const std::string &target, relationship::type type);
relationship get_relationship(const std::string &id) const;
void create_relationship(const std::string &id, const std::string &target, relationship::type type);
relationship get_relationship(const std::string &id) const;
const std::vector<relationship> &get_relationships() const;
void add_alignment(const alignment &a);
void add_border(const border &b);
void add_fill(const fill &f);
@ -199,18 +211,18 @@ public:
void add_color(const color &c);
void add_number_format(const number_format &format);
void add_protection(const protection &p);
std::vector<style> get_styles() const;
std::vector<color> get_colors() const;
std::vector<border> get_borders() const;
std::vector<fill> get_fills() const;
std::vector<font> get_fonts() const;
std::vector<number_format> get_number_formats() const;
std::size_t add_indexed_color(const std::string &rgb);
std::size_t add_indexed_color(const std::string &rgb);
std::string get_indexed_color(std::size_t color_index) 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;
@ -225,27 +237,27 @@ public:
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() const;
const theme &get_loaded_theme() const;
const style &get_style(std::size_t style_id) const;
std::size_t add_style(const style &style_);
manifest &get_manifest();
const manifest &get_manifest() const;
const std::vector<relationship> &get_root_relationships() const;
void add_shared_string(const std::string &shared);
std::vector<std::string> &get_shared_strings();
const std::vector<std::string> &get_shared_strings() const;
private:
private:
friend class worksheet;
std::shared_ptr<detail::workbook_impl> d_;
};
} // namespace xlnt

View File

@ -14,42 +14,36 @@ class range_reference;
class cell_vector
{
public:
template<bool is_const = true>
public:
template <bool is_const = true>
class common_iterator : public std::iterator<std::bidirectional_iterator_tag, cell>
{
public:
public:
common_iterator(worksheet ws, const cell_reference &start_cell, major_order order = major_order::row)
: ws_(ws),
current_cell_(start_cell),
range_(start_cell.to_range()),
order_(order)
: ws_(ws), current_cell_(start_cell), range_(start_cell.to_range()), order_(order)
{
}
common_iterator(const common_iterator<false> &other)
{
*this = other;
}
cell operator*();
bool operator== (const common_iterator& other) const
bool operator==(const common_iterator &other) const
{
return ws_ == other.ws_
&& current_cell_ == other.current_cell_
&& order_ == other.order_;
return ws_ == other.ws_ && current_cell_ == other.current_cell_ && order_ == other.order_;
}
bool operator!=(const common_iterator& other) const
bool operator!=(const common_iterator &other) const
{
return !(*this == other);
}
common_iterator &operator--()
{
if(order_ == major_order::row)
if (order_ == major_order::row)
{
current_cell_.set_column_index(current_cell_.get_column_index() - 1);
}
@ -57,20 +51,20 @@ public:
{
current_cell_.set_row(current_cell_.get_row() - 1);
}
return *this;
}
common_iterator operator--(int)
{
iterator old = *this;
--*this;
return old;
}
common_iterator &operator++()
{
if(order_ == major_order::row)
if (order_ == major_order::row)
{
current_cell_.set_column_index(current_cell_.get_column_index() + 1);
}
@ -78,61 +72,70 @@ public:
{
current_cell_.set_row(current_cell_.get_row() + 1);
}
return *this;
}
common_iterator operator++(int)
{
iterator old = *this;
++*this;
return old;
}
friend class common_iterator<true>;
private:
private:
worksheet ws_;
cell_reference current_cell_;
range_reference range_;
major_order order_;
};
using iterator = common_iterator<false>;
using const_iterator = common_iterator<true>;
cell_vector(worksheet ws, const range_reference &ref, major_order order = major_order::row);
std::size_t num_cells() const;
cell front();
const cell front() const;
cell back();
const cell back() const;
cell operator[](std::size_t column_index);
const cell operator[](std::size_t column_index) const;
cell get_cell(std::size_t column_index);
const cell get_cell(std::size_t column_index) const;
std::size_t length() const { return num_cells(); }
std::size_t length() const
{
return num_cells();
}
iterator begin();
iterator end();
const_iterator begin() const { return cbegin(); }
const_iterator end() const { return cend(); }
const_iterator begin() const
{
return cbegin();
}
const_iterator end() const
{
return cend();
}
const_iterator cbegin() const;
const_iterator cend() const;
private:
private:
worksheet ws_;
range_reference ref_;
major_order order_;

View File

@ -28,13 +28,9 @@ namespace xlnt {
class column_properties
{
public:
void set_height(int height) { this->height = height; }
int row_index;
int height;
bool visible;
int outline_level;
bool collapsed;
int style_index;
double width;
std::size_t style;
bool custom;
};
} // namespace xlnt

View File

@ -27,24 +27,71 @@ namespace xlnt {
class page_margins
{
public:
margins() : default_(true), top_(0), left_(0), bottom_(0), right_(0), header_(0), footer_(0) {}
bool is_default() const { return default_; }
double get_top() const { return top_; }
void set_top(double top) { default_ = false; top_ = top; }
double get_left() const { return left_; }
void set_left(double left) { default_ = false; left_ = left; }
double get_bottom() const { return bottom_; }
void set_bottom(double bottom) { default_ = false; bottom_ = bottom; }
double get_right() const { return right_; }
void set_right(double right) { default_ = false; right_ = right; }
double get_header() const { return header_; }
void set_header(double header) { default_ = false; header_ = header; }
double get_footer() const { return footer_; }
void set_footer(double footer) { default_ = false; footer_ = footer; }
private:
public:
page_margins() : default_(true), top_(0), left_(0), bottom_(0), right_(0), header_(0), footer_(0)
{
}
bool is_default() const
{
return default_;
}
double get_top() const
{
return top_;
}
void set_top(double top)
{
default_ = false;
top_ = top;
}
double get_left() const
{
return left_;
}
void set_left(double left)
{
default_ = false;
left_ = left;
}
double get_bottom() const
{
return bottom_;
}
void set_bottom(double bottom)
{
default_ = false;
bottom_ = bottom;
}
double get_right() const
{
return right_;
}
void set_right(double right)
{
default_ = false;
right_ = right;
}
double get_header() const
{
return header_;
}
void set_header(double header)
{
default_ = false;
header_ = header;
}
double get_footer() const
{
return footer_;
}
void set_footer(double footer)
{
default_ = false;
footer_ = footer;
}
private:
bool default_;
double top_;
double left_;
@ -53,5 +100,5 @@ private:
double header_;
double footer_;
};
} // namespace xlnt

View File

@ -33,14 +33,14 @@ struct page_setup
row = 1,
column = 2
};
enum class sheet_state
{
visible,
hidden,
very_hidden
};
enum class paper_size
{
letter = 1,
@ -55,39 +55,123 @@ struct page_setup
a4_small = 10,
a5 = 11
};
enum class orientation
{
portrait,
landscape
};
public:
page_setup() : default_(true), break_(page_break::none), sheet_state_(sheet_state::visible), paper_size_(paper_size::letter),
orientation_(orientation::portrait), fit_to_page_(false), fit_to_height_(false), fit_to_width_(false), horizontal_centered_(false), vertical_centered_(false), scale_(1) {}
bool is_default() const { return default_; }
page_break get_break() const { return break_; }
void set_break(page_break b) { default_ = false; break_ = b; }
sheet_state get_sheet_state() const { return sheet_state_; }
void set_sheet_state(sheet_state sheet_state) { sheet_state_ = sheet_state; }
paper_size get_paper_size() const { return paper_size_; }
void set_paper_size(paper_size paper_size) { default_ = false; paper_size_ = paper_size; }
orientation get_orientation() const { return orientation_; }
void set_orientation(orientation orientation) { default_ = false; orientation_ = orientation; }
bool fit_to_page() const { return fit_to_page_; }
void set_fit_to_page(bool fit_to_page) { default_ = false; fit_to_page_ = fit_to_page; }
bool fit_to_height() const { return fit_to_height_; }
void set_fit_to_height(bool fit_to_height) { default_ = false; fit_to_height_ = fit_to_height; }
bool fit_to_width() const { return fit_to_width_; }
void set_fit_to_width(bool fit_to_width) { default_ = false; fit_to_width_ = fit_to_width; }
void set_horizontal_centered(bool horizontal_centered) { default_ = false; horizontal_centered_ = horizontal_centered; }
bool get_horizontal_centered() const { return horizontal_centered_; }
void set_vertical_centered(bool vertical_centered) { default_ = false; vertical_centered_ = vertical_centered; }
bool get_vertical_centered() const { return vertical_centered_; }
void set_scale(double scale) { default_ = false; scale_ = scale; }
double get_scale() const { return scale_; }
private:
public:
page_setup()
: default_(true),
break_(page_break::none),
sheet_state_(sheet_state::visible),
paper_size_(paper_size::letter),
orientation_(orientation::portrait),
fit_to_page_(false),
fit_to_height_(false),
fit_to_width_(false),
horizontal_centered_(false),
vertical_centered_(false),
scale_(1)
{
}
bool is_default() const
{
return default_;
}
page_break get_break() const
{
return break_;
}
void set_break(page_break b)
{
default_ = false;
break_ = b;
}
sheet_state get_sheet_state() const
{
return sheet_state_;
}
void set_sheet_state(sheet_state sheet_state)
{
sheet_state_ = sheet_state;
}
paper_size get_paper_size() const
{
return paper_size_;
}
void set_paper_size(paper_size paper_size)
{
default_ = false;
paper_size_ = paper_size;
}
orientation get_orientation() const
{
return orientation_;
}
void set_orientation(orientation orientation)
{
default_ = false;
orientation_ = orientation;
}
bool fit_to_page() const
{
return fit_to_page_;
}
void set_fit_to_page(bool fit_to_page)
{
default_ = false;
fit_to_page_ = fit_to_page;
}
bool fit_to_height() const
{
return fit_to_height_;
}
void set_fit_to_height(bool fit_to_height)
{
default_ = false;
fit_to_height_ = fit_to_height;
}
bool fit_to_width() const
{
return fit_to_width_;
}
void set_fit_to_width(bool fit_to_width)
{
default_ = false;
fit_to_width_ = fit_to_width;
}
void set_horizontal_centered(bool horizontal_centered)
{
default_ = false;
horizontal_centered_ = horizontal_centered;
}
bool get_horizontal_centered() const
{
return horizontal_centered_;
}
void set_vertical_centered(bool vertical_centered)
{
default_ = false;
vertical_centered_ = vertical_centered;
}
bool get_vertical_centered() const
{
return vertical_centered_;
}
void set_scale(double scale)
{
default_ = false;
scale_ = scale;
}
double get_scale() const
{
return scale_;
}
private:
bool default_;
page_break break_;
sheet_state sheet_state_;
@ -100,5 +184,5 @@ private:
bool vertical_centered_;
double scale_;
};
} // namespace xlnt

View File

@ -36,41 +36,36 @@ namespace xlnt {
class range
{
public:
template<bool is_const = true>
public:
template <bool is_const = true>
class common_iterator : public std::iterator<std::bidirectional_iterator_tag, cell>
{
public:
public:
common_iterator(worksheet ws, const range_reference &start_cell, major_order order = major_order::row)
: ws_(ws),
current_cell_(start_cell.get_top_left()),
range_(start_cell),
order_(order)
: ws_(ws), current_cell_(start_cell.get_top_left()), range_(start_cell), order_(order)
{
}
common_iterator(const common_iterator<false> &other)
{
*this = other;
}
cell_vector operator*();
bool operator== (const common_iterator& other) const
bool operator==(const common_iterator &other) const
{
return ws_ == other.ws_
&& current_cell_ == other.current_cell_
&& order_ == other.order_;
return ws_ == other.ws_ && current_cell_ == other.current_cell_ && order_ == other.order_;
}
bool operator!=(const common_iterator& other) const
bool operator!=(const common_iterator &other) const
{
return !(*this == other);
}
common_iterator &operator--()
{
if(order_ == major_order::row)
if (order_ == major_order::row)
{
current_cell_.set_row(current_cell_.get_row() - 1);
}
@ -78,20 +73,20 @@ public:
{
current_cell_.set_column_index(current_cell_.get_column_index() - 1);
}
return *this;
}
common_iterator operator--(int)
{
iterator old = *this;
--*this;
return old;
}
common_iterator &operator++()
{
if(order_ == major_order::row)
if (order_ == major_order::row)
{
current_cell_.set_row(current_cell_.get_row() + 1);
}
@ -99,29 +94,29 @@ public:
{
current_cell_.set_column_index(current_cell_.get_column_index() + 1);
}
return *this;
}
common_iterator operator++(int)
{
iterator old = *this;
++*this;
return old;
}
friend class common_iterator<true>;
private:
private:
worksheet ws_;
cell_reference current_cell_;
range_reference range_;
major_order order_;
};
using iterator = common_iterator<false>;
using const_iterator = common_iterator<true>;
range(worksheet ws, const range_reference &reference, major_order order = major_order::row);
~range();
@ -132,7 +127,10 @@ public:
bool operator==(const range &comparand) const;
bool operator!=(const range &comparand) const { return !(*this == comparand); }
bool operator!=(const range &comparand) const
{
return !(*this == comparand);
}
cell_vector get_vector(std::size_t vector_index);
@ -145,19 +143,25 @@ public:
range_reference get_reference() const;
std::size_t length() const;
bool contains(const cell_reference &ref);
iterator begin();
iterator end();
const_iterator begin() const { return cbegin(); }
const_iterator end() const { return cend(); }
const_iterator begin() const
{
return cbegin();
}
const_iterator end() const
{
return cend();
}
const_iterator cbegin() const;
const_iterator cend() const;
private:
private:
worksheet ws_;
range_reference ref_;
major_order order_;

View File

@ -28,7 +28,7 @@ namespace xlnt {
class range_reference
{
public:
public:
/// <summary>
/// Convert a coordinate to an absolute coordinate string (B12 -> $B$12)
/// </summary>
@ -44,27 +44,51 @@ public:
bool is_single_cell() const;
column_t get_width() const;
row_t get_height() const;
cell_reference get_top_left() const { return top_left_; }
cell_reference get_bottom_right() const { return bottom_right_; }
cell_reference &get_top_left() { return top_left_; }
cell_reference &get_bottom_right() { return bottom_right_; }
cell_reference get_top_left() const
{
return top_left_;
}
cell_reference get_bottom_right() const
{
return bottom_right_;
}
cell_reference &get_top_left()
{
return top_left_;
}
cell_reference &get_bottom_right()
{
return bottom_right_;
}
range_reference make_offset(int column_offset, int row_offset) const;
std::string to_string() const;
bool operator==(const range_reference &comparand) const;
bool operator==(const std::string &reference_string) const { return *this == range_reference(reference_string); }
bool operator==(const char *reference_string) const { return *this == std::string(reference_string); }
bool operator==(const std::string &reference_string) const
{
return *this == range_reference(reference_string);
}
bool operator==(const char *reference_string) const
{
return *this == std::string(reference_string);
}
bool operator!=(const range_reference &comparand) const;
bool operator!=(const std::string &reference_string) const { return *this != range_reference(reference_string); }
bool operator!=(const char *reference_string) const { return *this != std::string(reference_string); }
bool operator!=(const std::string &reference_string) const
{
return *this != range_reference(reference_string);
}
bool operator!=(const char *reference_string) const
{
return *this != std::string(reference_string);
}
private:
private:
cell_reference top_left_;
cell_reference bottom_right_;
};
inline bool operator==(const std::string &reference_string, const range_reference &ref)
{
return ref == reference_string;

View File

@ -28,13 +28,11 @@ namespace xlnt {
class row_properties
{
public:
void set_height(int height) { this->height = height; }
int row_index;
int height;
double height;
bool visible;
int outline_level;
bool collapsed;
int style_index;
};
} // namespace xlnt

View File

@ -24,10 +24,8 @@
namespace xlnt {
class selection {
};
class selection
{
};
} // namespace xlnt

View File

@ -6,14 +6,17 @@ namespace xlnt {
class sheet_protection
{
public:
public:
static std::string hash_password(const std::string &password);
void set_password(const std::string &password);
std::string get_hashed_password() const { return hashed_password_; }
private:
std::string get_hashed_password() const
{
return hashed_password_;
}
private:
std::string hashed_password_;
};
} // namespace xlnt

View File

@ -23,7 +23,7 @@
#pragma once
namespace xlnt {
class sheet_view
{
};

View File

@ -34,50 +34,53 @@
#include "../common/relationship.hpp"
namespace xlnt {
class cell;
class cell_reference;
class column_properties;
class comment;
class range;
class range_reference;
class relationship;
class row_properties;
class workbook;
struct date;
namespace detail {
struct worksheet_impl;
namespace detail {
struct worksheet_impl;
} // namespace detail
class row_properties
{
public:
double height;
bool visible;
int outline_level;
bool collapsed;
int style_index;
};
class column_properties
{
public:
double width;
std::size_t style;
bool custom;
};
class header
{
public:
public:
header();
void set_text(const std::string &text) { default_ = false; text_ = text; }
void set_font_name(const std::string &font_name) { default_ = false; font_name_ = font_name; }
void set_font_size(std::size_t font_size) { default_ = false; font_size_ = font_size; }
void set_font_color(const std::string &font_color) { default_ = false; font_color_ = font_color; }
bool is_default() const { return default_; }
private:
void set_text(const std::string &text)
{
default_ = false;
text_ = text;
}
void set_font_name(const std::string &font_name)
{
default_ = false;
font_name_ = font_name;
}
void set_font_size(std::size_t font_size)
{
default_ = false;
font_size_ = font_size;
}
void set_font_color(const std::string &font_color)
{
default_ = false;
font_color_ = font_color;
}
bool is_default() const
{
return default_;
}
private:
bool default_;
std::string text_;
std::string font_name_;
@ -87,63 +90,156 @@ private:
class footer
{
public:
public:
footer();
void set_text(const std::string &text) { default_ = false; text_ = text; }
void set_font_name(const std::string &font_name) { default_ = false; font_name_ = font_name; }
void set_font_size(std::size_t font_size) { default_ = false; font_size_ = font_size; }
void set_font_color(const std::string &font_color) { default_ = false; font_color_ = font_color; }
bool is_default() const { return default_; }
private:
void set_text(const std::string &text)
{
default_ = false;
text_ = text;
}
void set_font_name(const std::string &font_name)
{
default_ = false;
font_name_ = font_name;
}
void set_font_size(std::size_t font_size)
{
default_ = false;
font_size_ = font_size;
}
void set_font_color(const std::string &font_color)
{
default_ = false;
font_color_ = font_color;
}
bool is_default() const
{
return default_;
}
private:
bool default_;
std::string text_;
std::string font_name_;
std::size_t font_size_;
std::string font_color_;
};
class header_footer
{
public:
public:
header_footer();
header &get_left_header() { return left_header_; }
header &get_center_header() { return center_header_; }
header &get_right_header() { return right_header_; }
footer &get_left_footer() { return left_footer_; }
footer &get_center_footer() { return center_footer_; }
footer &get_right_footer() { return right_footer_; }
bool is_default_header() const { return left_header_.is_default() && center_header_.is_default() && right_header_.is_default(); }
bool is_default_footer() const { return left_footer_.is_default() && center_footer_.is_default() && right_footer_.is_default(); }
bool is_default() const { return is_default_header() && is_default_footer(); }
private:
header &get_left_header()
{
return left_header_;
}
header &get_center_header()
{
return center_header_;
}
header &get_right_header()
{
return right_header_;
}
footer &get_left_footer()
{
return left_footer_;
}
footer &get_center_footer()
{
return center_footer_;
}
footer &get_right_footer()
{
return right_footer_;
}
bool is_default_header() const
{
return left_header_.is_default() && center_header_.is_default() && right_header_.is_default();
}
bool is_default_footer() const
{
return left_footer_.is_default() && center_footer_.is_default() && right_footer_.is_default();
}
bool is_default() const
{
return is_default_header() && is_default_footer();
}
private:
header left_header_, right_header_, center_header_;
footer left_footer_, right_footer_, center_footer_;
};
struct margins
{
public:
margins() : default_(true), top_(0), left_(0), bottom_(0), right_(0), header_(0), footer_(0) {}
bool is_default() const { return default_; }
double get_top() const { return top_; }
void set_top(double top) { default_ = false; top_ = top; }
double get_left() const { return left_; }
void set_left(double left) { default_ = false; left_ = left; }
double get_bottom() const { return bottom_; }
void set_bottom(double bottom) { default_ = false; bottom_ = bottom; }
double get_right() const { return right_; }
void set_right(double right) { default_ = false; right_ = right; }
double get_header() const { return header_; }
void set_header(double header) { default_ = false; header_ = header; }
double get_footer() const { return footer_; }
void set_footer(double footer) { default_ = false; footer_ = footer; }
private:
public:
margins() : default_(true), top_(0), left_(0), bottom_(0), right_(0), header_(0), footer_(0)
{
}
bool is_default() const
{
return default_;
}
double get_top() const
{
return top_;
}
void set_top(double top)
{
default_ = false;
top_ = top;
}
double get_left() const
{
return left_;
}
void set_left(double left)
{
default_ = false;
left_ = left;
}
double get_bottom() const
{
return bottom_;
}
void set_bottom(double bottom)
{
default_ = false;
bottom_ = bottom;
}
double get_right() const
{
return right_;
}
void set_right(double right)
{
default_ = false;
right_ = right;
}
double get_header() const
{
return header_;
}
void set_header(double header)
{
default_ = false;
header_ = header;
}
double get_footer() const
{
return footer_;
}
void set_footer(double footer)
{
default_ = false;
footer_ = footer;
}
private:
bool default_;
double top_;
double left_;
@ -155,7 +251,7 @@ private:
class worksheet
{
public:
public:
worksheet();
worksheet(const worksheet &rhs);
worksheet(workbook &parent_workbook, const std::string &title = std::string());
@ -163,19 +259,19 @@ public:
std::string to_string() const;
workbook &get_parent() const;
void garbage_collect();
// title
std::string get_title() const;
void set_title(const std::string &title);
std::string make_unique_sheet_name(const std::string &value);
// freeze panes
cell_reference get_frozen_panes() const;
void freeze_panes(cell top_left_cell);
void freeze_panes(const std::string &top_left_coordinate);
void unfreeze_panes();
bool has_frozen_panes() const;
// container
cell get_cell(const cell_reference &reference);
const cell get_cell(const cell_reference &reference) const;
@ -189,13 +285,13 @@ public:
range rows(const std::string &range_string, int row_offset, int column_offset) const;
range columns() const;
std::list<cell> get_cell_collection();
// properties
column_properties &get_column_properties(column_t column);
const column_properties &get_column_properties(column_t column) const;
bool has_column_properties(column_t column) const;
void add_column_properties(column_t column, const column_properties &props);
row_properties &get_row_properties(row_t row);
const row_properties &get_row_properties(row_t row) const;
bool has_row_properties(row_t row) const;
@ -212,7 +308,7 @@ public:
bool has_named_range(const std::string &name);
range get_named_range(const std::string &name);
void remove_named_range(const std::string &name);
// extents
row_t get_lowest_row() const;
row_t get_highest_row() const;
@ -220,21 +316,21 @@ public:
column_t get_lowest_column() const;
column_t get_highest_column() const;
range_reference calculate_dimension() const;
// relationships
relationship create_relationship(relationship::type type, const std::string &target_uri);
const std::vector<relationship> &get_relationships() const;
// charts
//void add_chart(chart chart);
// void add_chart(chart chart);
// cell merge
void merge_cells(const range_reference &reference);
void merge_cells(column_t start_column, row_t start_row, column_t end_column, row_t end_row);
void unmerge_cells(const range_reference &reference);
void unmerge_cells(column_t start_column, row_t start_row, column_t end_column, row_t end_row);
std::vector<range_reference> get_merged_ranges() const;
// append
void append();
void append(const std::vector<std::string> &cells);
@ -243,9 +339,9 @@ public:
void append(const std::vector<cell> &cells);
void append(const std::unordered_map<std::string, std::string> &cells);
void append(const std::unordered_map<int, std::string> &cells);
void append(const std::vector<int>::const_iterator begin, const std::vector<int>::const_iterator end);
// operators
bool operator==(const worksheet &other) const;
bool operator!=(const worksheet &other) const;
@ -260,41 +356,41 @@ public:
const range operator[](const std::string &range_string) const;
range operator()(const cell_reference &top_left, const cell_reference &bottom_right);
const range operator()(const cell_reference &top_left, const cell_reference &bottom_right) const;
// page
page_setup &get_page_setup();
const page_setup &get_page_setup() const;
margins &get_page_margins();
const margins &get_page_margins() const;
// auto filter
range_reference get_auto_filter() const;
void auto_filter(const xlnt::range &range);
void auto_filter(const range_reference &reference);
void unset_auto_filter();
bool has_auto_filter() const;
// comments
void increment_comments();
void decrement_comments();
std::size_t get_comment_count() const;
void reserve(std::size_t n);
header_footer &get_header_footer();
const header_footer &get_header_footer() const;
void set_parent(workbook &wb);
std::vector<std::string> get_formula_attributes() const;
void set_sheet_state(page_setup::sheet_state state);
private:
private:
friend class workbook;
friend class cell;
worksheet(detail::worksheet_impl *d);
detail::worksheet_impl *d_;
};
} // namespace xlnt

View File

@ -25,7 +25,8 @@
namespace xlnt {
class worksheet_properties {
class worksheet_properties
{
};
} // namespace xlnt

View File

@ -33,6 +33,8 @@ const std::string author_email = "thomas.fussell@gmail.com";
const std::string url = "https://github.com/tfussell/xlnt";
const std::string download_url = "https://github.com/tfussell/xlnt/archive/master.zip";
#include "config.hpp"
#include "cell/cell.hpp"
#include "cell/cell_reference.hpp"
#include "cell/comment.hpp"
@ -40,11 +42,36 @@ const std::string download_url = "https://github.com/tfussell/xlnt/archive/maste
#include "common/encoding.hpp"
#include "common/exceptions.hpp"
#include "common/relationship.hpp"
#include "common/string_table.hpp"
#include "common/types.hpp"
#include "common/zip_file.hpp"
#include "styles/alignment.hpp"
#include "styles/border.hpp"
#include "styles/color.hpp"
#include "styles/fill.hpp"
#include "styles/font.hpp"
#include "styles/named_style.hpp"
#include "styles/number_format.hpp"
#include "styles/protection.hpp"
#include "styles/side.hpp"
#include "styles/style.hpp"
#include "workbook/document_properties.hpp"
#include "workbook/document_security.hpp"
#include "workbook/external_book.hpp"
#include "workbook/manifest.hpp"
#include "workbook/named_range.hpp"
#include "workbook/theme.hpp"
#include "workbook/workbook.hpp"
#include "worksheet/cell_vector.hpp"
#include "worksheet/column_properties.hpp"
#include "worksheet/major_order.hpp"
#include "worksheet/page_margins.hpp"
#include "worksheet/page_setup.hpp"
#include "worksheet/pane.hpp"
#include "worksheet/range.hpp"
#include "worksheet/range_reference.hpp"
#include "worksheet/row_properties.hpp"
#include "worksheet/selection.hpp"
#include "worksheet/sheet_protection.hpp"
#include "worksheet/sheet_view.hpp"
#include "worksheet/worksheet_properties.hpp"
#include "worksheet/worksheet.hpp"

File diff suppressed because it is too large Load Diff

View File

@ -7,19 +7,19 @@
#include "detail/constants.hpp"
namespace xlnt {
std::size_t cell_reference_hash::operator()(const cell_reference &k) const
{
return k.get_row() * constants::MaxColumn + k.get_column_index();
}
cell_reference cell_reference::make_absolute(const cell_reference &relative_reference)
{
cell_reference copy = relative_reference;
copy.absolute_ = true;
return copy;
}
cell_reference::cell_reference() : cell_reference(1, 1, false)
{
}
@ -33,43 +33,38 @@ cell_reference::cell_reference(const std::string &string)
cell_reference::cell_reference(const char *reference_string) : cell_reference(std::string(reference_string))
{
}
cell_reference::cell_reference(const std::string &column, row_t row, bool absolute)
: column_(column_index_from_string(column)),
row_(row),
absolute_(absolute)
: column_(column_index_from_string(column)), row_(row), absolute_(absolute)
{
if(row == 0 || row_ >= constants::MaxRow || column_ == 0 || column_ >= constants::MaxColumn)
if (row == 0 || row_ >= constants::MaxRow || column_ == 0 || column_ >= constants::MaxColumn)
{
throw cell_coordinates_exception(column_, row_);
}
}
cell_reference::cell_reference(column_t column_index, row_t row, bool absolute)
: column_(column_index),
row_(row),
absolute_(absolute)
: column_(column_index), row_(row), absolute_(absolute)
{
if(row_ == 0 || row_ >= constants::MaxRow || column_ == 0 || column_ >= constants::MaxColumn)
if (row_ == 0 || row_ >= constants::MaxRow || column_ == 0 || column_ >= constants::MaxColumn)
{
throw cell_coordinates_exception(column_, row_);
}
}
range_reference cell_reference::operator,(const xlnt::cell_reference &other) const
range_reference cell_reference::operator, (const xlnt::cell_reference &other) const
{
return range_reference(*this, other);
}
std::string cell_reference::to_string() const
{
if(absolute_)
if (absolute_)
{
return std::string("$") + column_string_from_index(column_) + "$" + std::to_string(row_);
}
return column_string_from_index(column_) + std::to_string(row_);
}
@ -78,23 +73,24 @@ range_reference cell_reference::to_range() const
return range_reference(column_, row_, column_, row_);
}
std::pair<std::string, row_t> cell_reference::split_reference(const std::string &reference_string, bool &absolute_column, bool &absolute_row)
std::pair<std::string, row_t> cell_reference::split_reference(const std::string &reference_string,
bool &absolute_column, bool &absolute_row)
{
absolute_column = false;
absolute_row = false;
// Convert a coordinate string like 'B12' to a tuple ('B', 12)
bool column_part = true;
std::string column_string;
for(auto character : reference_string)
for (auto character : reference_string)
{
char upper = std::toupper(character, std::locale::classic());
if(std::isalpha(character, std::locale::classic()))
if (std::isalpha(character, std::locale::classic()))
{
if(column_part)
if (column_part)
{
column_string.append(1, upper);
}
@ -103,11 +99,11 @@ std::pair<std::string, row_t> cell_reference::split_reference(const std::string
throw cell_coordinates_exception(reference_string);
}
}
else if(character == '$')
else if (character == '$')
{
if(column_part)
if (column_part)
{
if(column_string.empty())
if (column_string.empty())
{
column_string.append(1, upper);
}
@ -119,73 +115,72 @@ std::pair<std::string, row_t> cell_reference::split_reference(const std::string
}
else
{
if(column_part)
if (column_part)
{
column_part = false;
}
else if(!std::isdigit(character, std::locale::classic()))
else if (!std::isdigit(character, std::locale::classic()))
{
throw cell_coordinates_exception(reference_string);
}
}
}
std::string row_string = reference_string.substr(column_string.length());
if(row_string.length() == 0)
if (row_string.length() == 0)
{
throw cell_coordinates_exception(reference_string);
}
if(column_string[0] == '$')
if (column_string[0] == '$')
{
absolute_row = true;
column_string = column_string.substr(1);
}
if(row_string[0] == '$')
if (row_string[0] == '$')
{
absolute_column = true;
row_string = row_string.substr(1);
}
return {column_string, std::stoi(row_string)};
return { column_string, std::stoi(row_string) };
}
cell_reference cell_reference::make_offset(int column_offset, int row_offset) const
{
return cell_reference(static_cast<column_t>(static_cast<int>(column_) + column_offset),
static_cast<row_t>(static_cast<int>(row_) + row_offset));
static_cast<row_t>(static_cast<int>(row_) + row_offset));
}
bool cell_reference::operator==(const cell_reference &comparand) const
{
return comparand.column_ == column_
&& comparand.row_ == row_
&& absolute_ == comparand.absolute_;
return comparand.column_ == column_ && comparand.row_ == row_ && absolute_ == comparand.absolute_;
}
column_t cell_reference::column_index_from_string(const std::string &column_string)
{
if(column_string.length() > 3 || column_string.empty())
if (column_string.length() > 3 || column_string.empty())
{
throw column_string_index_exception();
}
column_t column_index = 0;
int place = 1;
for(int i = static_cast<int>(column_string.length()) - 1; i >= 0; i--)
for (int i = static_cast<int>(column_string.length()) - 1; i >= 0; i--)
{
if(!std::isalpha(column_string[static_cast<std::size_t>(i)], std::locale::classic()))
if (!std::isalpha(column_string[static_cast<std::size_t>(i)], std::locale::classic()))
{
throw column_string_index_exception();
}
column_index += static_cast<column_t>((std::toupper(column_string[static_cast<std::size_t>(i)], std::locale::classic()) - 'A' + 1) * place);
column_index += static_cast<column_t>(
(std::toupper(column_string[static_cast<std::size_t>(i)], std::locale::classic()) - 'A' + 1) * place);
place *= 26;
}
return column_index;
}
@ -197,36 +192,36 @@ std::string cell_reference::column_string_from_index(column_t column_index)
{
// these indicies corrospond to A->ZZZ and include all allowed
// columns
if(column_index < 1 || column_index > constants::MaxColumn)
if (column_index < 1 || column_index > constants::MaxColumn)
{
// auto msg = "Column index out of bounds: " + std::to_string(column_index);
// auto msg = "Column index out of bounds: " + std::to_string(column_index);
throw column_string_index_exception();
}
int temp = static_cast<int>(column_index);
std::string column_letter = "";
while(temp > 0)
while (temp > 0)
{
int quotient = temp / 26, remainder = temp % 26;
// check for exact division and borrow if needed
if(remainder == 0)
if (remainder == 0)
{
quotient -= 1;
remainder = 26;
}
column_letter = std::string(1, char(remainder + 64)) + column_letter;
temp = quotient;
}
return column_letter;
}
bool cell_reference::operator<(const cell_reference &other)
{
if(row_ != other.row_)
if (row_ != other.row_)
{
return row_ < other.row_;
}
@ -236,32 +231,32 @@ bool cell_reference::operator<(const cell_reference &other)
bool cell_reference::operator>(const cell_reference &other)
{
if(row_ != other.row_)
if (row_ != other.row_)
{
return row_ > other.row_;
}
return column_ > other.column_;
}
bool cell_reference::operator<=(const cell_reference &other)
{
if(row_ != other.row_)
if (row_ != other.row_)
{
return row_ < other.row_;
}
return column_ <= other.column_;
}
bool cell_reference::operator>=(const cell_reference &other)
{
if(row_ != other.row_)
if (row_ != other.row_)
{
return row_ > other.row_;
}
return column_ >= other.column_;
}
} // namespace xlnt

View File

@ -8,7 +8,7 @@ namespace xlnt {
comment::comment(detail::comment_impl *d) : d_(d)
{
}
comment::comment(cell parent, const std::string &text, const std::string &author) : d_(nullptr)
{
d_ = parent.get_comment().d_;

View File

@ -7,53 +7,53 @@ namespace xlnt {
time time::from_number(long double raw_time)
{
time result;
time result;
double integer_part;
double fractional_part = std::modf((double)raw_time, &integer_part);
fractional_part *= 24;
result.hour = (int)fractional_part;
fractional_part = 60 * (fractional_part - result.hour);
result.minute = (int)fractional_part;
fractional_part = 60 * (fractional_part - result.minute);
result.second = (int)fractional_part;
fractional_part = 1000000 * (fractional_part - result.second);
result.microsecond = (int)fractional_part;
if (result.microsecond == 999999 && fractional_part - result.microsecond > 0.5)
fractional_part = 60 * (fractional_part - result.hour);
result.minute = (int)fractional_part;
fractional_part = 60 * (fractional_part - result.minute);
result.second = (int)fractional_part;
fractional_part = 1000000 * (fractional_part - result.second);
result.microsecond = (int)fractional_part;
if (result.microsecond == 999999 && fractional_part - result.microsecond > 0.5)
{
result.microsecond = 0;
result.second += 1;
if (result.second == 60)
result.microsecond = 0;
result.second += 1;
if (result.second == 60)
{
result.second = 0;
result.minute += 1;
if (result.minute == 60)
result.second = 0;
result.minute += 1;
if (result.minute == 60)
{
result.minute = 0;
result.hour += 1;
result.minute = 0;
result.hour += 1;
}
}
}
return result;
return result;
}
date date::from_number(int days_since_base_year, calendar base_date)
{
date result(0, 0, 0);
if(base_date == calendar::mac_1904)
if (base_date == calendar::mac_1904)
{
days_since_base_year += 1462;
}
if(days_since_base_year == 60)
if (days_since_base_year == 60)
{
result.day = 29;
result.month = 2;
result.year = 1900;
}
else if(days_since_base_year < 60)
else if (days_since_base_year < 60)
{
days_since_base_year++;
}
@ -76,33 +76,25 @@ datetime datetime::from_number(long double raw_time, calendar base_date)
{
auto date_part = date::from_number((int)raw_time, base_date);
auto time_part = time::from_number(raw_time);
return datetime(date_part.year, date_part.month, date_part.day, time_part.hour, time_part.minute, time_part.second, time_part.microsecond);
return datetime(date_part.year, date_part.month, date_part.day, time_part.hour, time_part.minute, time_part.second,
time_part.microsecond);
}
bool date::operator==(const date &comparand) const
{
return year == comparand.year
&& month == comparand.month
&& day == comparand.day;
return year == comparand.year && month == comparand.month && day == comparand.day;
}
bool time::operator==(const time &comparand) const
{
return hour == comparand.hour
&& minute == comparand.minute
&& second == comparand.second
&& microsecond == comparand.microsecond;
return hour == comparand.hour && minute == comparand.minute && second == comparand.second &&
microsecond == comparand.microsecond;
}
bool datetime::operator==(const datetime &comparand) const
{
return year == comparand.year
&& month == comparand.month
&& day == comparand.day
&& hour == comparand.hour
&& minute == comparand.minute
&& second == comparand.second
&& microsecond == comparand.microsecond;
return year == comparand.year && month == comparand.month && day == comparand.day && hour == comparand.hour &&
minute == comparand.minute && second == comparand.second && microsecond == comparand.microsecond;
}
time::time(const std::string &time_string) : hour(0), minute(0), second(0), microsecond(0)
@ -114,10 +106,10 @@ time::time(const std::string &time_string) : hour(0), minute(0), second(0), micr
colon_index = remaining.find(':');
minute = std::stoi(remaining.substr(0, colon_index));
colon_index = remaining.find(':');
if(colon_index != std::string::npos)
if (colon_index != std::string::npos)
{
remaining = remaining.substr(colon_index + 1);
second = std::stoi(remaining);
remaining = remaining.substr(colon_index + 1);
second = std::stoi(remaining);
}
}
@ -134,22 +126,21 @@ long double time::to_number() const
int date::to_number(calendar base_date) const
{
if(day == 29 && month == 2 && year == 1900)
if (day == 29 && month == 2 && year == 1900)
{
return 60;
}
int days_since_1900 = int((1461 * (year + 4800 + int((month - 14) / 12))) / 4)
+ int((367 * (month - 2 - 12 * ((month - 14) / 12))) / 12)
- int((3 * (int((year + 4900 + int((month - 14) / 12)) / 100))) / 4)
+ day - 2415019 - 32075;
int days_since_1900 = int((1461 * (year + 4800 + int((month - 14) / 12))) / 4) +
int((367 * (month - 2 - 12 * ((month - 14) / 12))) / 12) -
int((3 * (int((year + 4900 + int((month - 14) / 12)) / 100))) / 4) + day - 2415019 - 32075;
if(days_since_1900 <= 60)
if (days_since_1900 <= 60)
{
days_since_1900--;
}
if(base_date == calendar::mac_1904)
if (base_date == calendar::mac_1904)
{
return days_since_1900 - 1462;
}
@ -159,13 +150,13 @@ int date::to_number(calendar base_date) const
long double datetime::to_number(calendar base_date) const
{
return date(year, month, day).to_number(base_date)
+ time(hour, minute, second, microsecond).to_number();
return date(year, month, day).to_number(base_date) + time(hour, minute, second, microsecond).to_number();
}
std::string datetime::to_string(xlnt::calendar /*base_date*/) const
{
return std::to_string(year) + "/" + std::to_string(month) + "/" + std::to_string(day) + " " +std::to_string(hour) + ":" + std::to_string(minute) + ":" + std::to_string(second) + ":" + std::to_string(microsecond);
return std::to_string(year) + "/" + std::to_string(month) + "/" + std::to_string(day) + " " + std::to_string(hour) +
":" + std::to_string(minute) + ":" + std::to_string(second) + ":" + std::to_string(microsecond);
}
date date::today()
@ -181,7 +172,7 @@ datetime datetime::now()
std::tm now = *std::localtime(&raw_time);
return datetime(1900 + now.tm_year, now.tm_mon + 1, now.tm_mday, now.tm_hour, now.tm_min, now.tm_sec);
}
double timedelta::to_number() const
{
return days + hours / 24.0;

View File

@ -5,55 +5,44 @@ namespace xlnt {
sheet_title_exception::sheet_title_exception(const std::string &title)
: std::runtime_error(std::string("bad worksheet title: ") + title)
{
}
column_string_index_exception::column_string_index_exception()
: std::runtime_error("")
column_string_index_exception::column_string_index_exception() : std::runtime_error("")
{
}
data_type_exception::data_type_exception()
: std::runtime_error("")
data_type_exception::data_type_exception() : std::runtime_error("")
{
}
attribute_error::attribute_error()
: std::runtime_error("")
attribute_error::attribute_error() : std::runtime_error("")
{
}
named_range_exception::named_range_exception()
: std::runtime_error("named range not found or not owned by this worksheet")
{
}
invalid_file_exception::invalid_file_exception(const std::string &filename)
: std::runtime_error(std::string("couldn't open file: (") + filename + ")")
{
}
cell_coordinates_exception::cell_coordinates_exception(row_t row, column_t column)
: std::runtime_error(std::string("bad cell coordinates: (") + std::to_string(row) + "," + std::to_string(column) + ")")
: std::runtime_error(std::string("bad cell coordinates: (") + std::to_string(row) + "," + std::to_string(column) +
")")
{
}
cell_coordinates_exception::cell_coordinates_exception(const std::string &coord_string)
: std::runtime_error(std::string("bad cell coordinates: (") + coord_string + ")")
{
}
illegal_character_error::illegal_character_error(char c)
: std::runtime_error(std::string("illegal character: (") + std::to_string(static_cast<unsigned char>(c)) + ")")
{
}
} // namespace xlnt

View File

@ -2,15 +2,17 @@
namespace xlnt {
relationship::relationship(type t, const std::string &r_id, const std::string &target_uri) : type_(t), id_(r_id), source_uri_(""), target_uri_(target_uri), target_mode_(target_mode::internal)
relationship::relationship(type t, const std::string &r_id, const std::string &target_uri)
: type_(t), id_(r_id), source_uri_(""), target_uri_(target_uri), target_mode_(target_mode::internal)
{
if(t == type::hyperlink)
if (t == type::hyperlink)
{
target_mode_ = target_mode::external;
}
}
relationship::relationship() : type_(type::invalid), id_(""), source_uri_(""), target_uri_(""), target_mode_(target_mode::internal)
relationship::relationship()
: type_(type::invalid), id_(""), source_uri_(""), target_uri_(""), target_mode_(target_mode::internal)
{
}

View File

@ -25,7 +25,7 @@ std::string get_working_directory()
return "";
#endif
}
#ifdef _WIN32
char directory_separator = '\\';
char alt_directory_separator = '/';
@ -33,33 +33,33 @@ char alt_directory_separator = '/';
char directory_separator = '/';
char alt_directory_separator = '\\';
#endif
std::string join_path(const std::vector<std::string> &parts)
{
std::string joined;
std::size_t i = 0;
for(auto part : parts)
for (auto part : parts)
{
joined.append(part);
if(i++ != parts.size() - 1)
if (i++ != parts.size() - 1)
{
joined.append(1, '/');
}
}
return joined;
}
std::vector<std::string> split_path(const std::string &path, char delim = directory_separator)
{
std::vector<std::string> split;
std::string::size_type previous_index = 0;
auto separator_index = path.find(delim);
while(separator_index != std::string::npos)
while (separator_index != std::string::npos)
{
auto part = path.substr(previous_index, separator_index - previous_index);
if(part != "..")
if (part != "..")
{
split.push_back(part);
}
@ -70,79 +70,65 @@ std::vector<std::string> split_path(const std::string &path, char delim = direct
previous_index = separator_index + 1;
separator_index = path.find(delim, previous_index);
}
split.push_back(path.substr(previous_index));
if(split.size() == 1 && delim == directory_separator)
if (split.size() == 1 && delim == directory_separator)
{
auto alternative = split_path(path, alt_directory_separator);
if(alternative.size() > 1)
if (alternative.size() > 1)
{
return alternative;
}
}
return split;
}
uint32_t crc32buf(const char *buf, std::size_t len)
{
uint32_t oldcrc32 = 0xFFFFFFFF;
uint32_t crc_32_tab[] = { /* CRC polynomial 0xedb88320 */
0x00000000, 0x77073096, 0xee0e612c, 0x990951ba, 0x076dc419, 0x706af48f,
0xe963a535, 0x9e6495a3, 0x0edb8832, 0x79dcb8a4, 0xe0d5e91e, 0x97d2d988,
0x09b64c2b, 0x7eb17cbd, 0xe7b82d07, 0x90bf1d91, 0x1db71064, 0x6ab020f2,
0xf3b97148, 0x84be41de, 0x1adad47d, 0x6ddde4eb, 0xf4d4b551, 0x83d385c7,
0x136c9856, 0x646ba8c0, 0xfd62f97a, 0x8a65c9ec, 0x14015c4f, 0x63066cd9,
0xfa0f3d63, 0x8d080df5, 0x3b6e20c8, 0x4c69105e, 0xd56041e4, 0xa2677172,
0x3c03e4d1, 0x4b04d447, 0xd20d85fd, 0xa50ab56b, 0x35b5a8fa, 0x42b2986c,
0xdbbbc9d6, 0xacbcf940, 0x32d86ce3, 0x45df5c75, 0xdcd60dcf, 0xabd13d59,
0x26d930ac, 0x51de003a, 0xc8d75180, 0xbfd06116, 0x21b4f4b5, 0x56b3c423,
0xcfba9599, 0xb8bda50f, 0x2802b89e, 0x5f058808, 0xc60cd9b2, 0xb10be924,
0x2f6f7c87, 0x58684c11, 0xc1611dab, 0xb6662d3d, 0x76dc4190, 0x01db7106,
0x98d220bc, 0xefd5102a, 0x71b18589, 0x06b6b51f, 0x9fbfe4a5, 0xe8b8d433,
0x7807c9a2, 0x0f00f934, 0x9609a88e, 0xe10e9818, 0x7f6a0dbb, 0x086d3d2d,
0x91646c97, 0xe6635c01, 0x6b6b51f4, 0x1c6c6162, 0x856530d8, 0xf262004e,
0x6c0695ed, 0x1b01a57b, 0x8208f4c1, 0xf50fc457, 0x65b0d9c6, 0x12b7e950,
0x8bbeb8ea, 0xfcb9887c, 0x62dd1ddf, 0x15da2d49, 0x8cd37cf3, 0xfbd44c65,
0x4db26158, 0x3ab551ce, 0xa3bc0074, 0xd4bb30e2, 0x4adfa541, 0x3dd895d7,
0xa4d1c46d, 0xd3d6f4fb, 0x4369e96a, 0x346ed9fc, 0xad678846, 0xda60b8d0,
0x44042d73, 0x33031de5, 0xaa0a4c5f, 0xdd0d7cc9, 0x5005713c, 0x270241aa,
0xbe0b1010, 0xc90c2086, 0x5768b525, 0x206f85b3, 0xb966d409, 0xce61e49f,
0x5edef90e, 0x29d9c998, 0xb0d09822, 0xc7d7a8b4, 0x59b33d17, 0x2eb40d81,
0xb7bd5c3b, 0xc0ba6cad, 0xedb88320, 0x9abfb3b6, 0x03b6e20c, 0x74b1d29a,
0xead54739, 0x9dd277af, 0x04db2615, 0x73dc1683, 0xe3630b12, 0x94643b84,
0x0d6d6a3e, 0x7a6a5aa8, 0xe40ecf0b, 0x9309ff9d, 0x0a00ae27, 0x7d079eb1,
0xf00f9344, 0x8708a3d2, 0x1e01f268, 0x6906c2fe, 0xf762575d, 0x806567cb,
0x196c3671, 0x6e6b06e7, 0xfed41b76, 0x89d32be0, 0x10da7a5a, 0x67dd4acc,
0xf9b9df6f, 0x8ebeeff9, 0x17b7be43, 0x60b08ed5, 0xd6d6a3e8, 0xa1d1937e,
0x38d8c2c4, 0x4fdff252, 0xd1bb67f1, 0xa6bc5767, 0x3fb506dd, 0x48b2364b,
0xd80d2bda, 0xaf0a1b4c, 0x36034af6, 0x41047a60, 0xdf60efc3, 0xa867df55,
0x316e8eef, 0x4669be79, 0xcb61b38c, 0xbc66831a, 0x256fd2a0, 0x5268e236,
0xcc0c7795, 0xbb0b4703, 0x220216b9, 0x5505262f, 0xc5ba3bbe, 0xb2bd0b28,
0x2bb45a92, 0x5cb36a04, 0xc2d7ffa7, 0xb5d0cf31, 0x2cd99e8b, 0x5bdeae1d,
0x9b64c2b0, 0xec63f226, 0x756aa39c, 0x026d930a, 0x9c0906a9, 0xeb0e363f,
0x72076785, 0x05005713, 0x95bf4a82, 0xe2b87a14, 0x7bb12bae, 0x0cb61b38,
0x92d28e9b, 0xe5d5be0d, 0x7cdcefb7, 0x0bdbdf21, 0x86d3d2d4, 0xf1d4e242,
0x68ddb3f8, 0x1fda836e, 0x81be16cd, 0xf6b9265b, 0x6fb077e1, 0x18b74777,
0x88085ae6, 0xff0f6a70, 0x66063bca, 0x11010b5c, 0x8f659eff, 0xf862ae69,
0x616bffd3, 0x166ccf45, 0xa00ae278, 0xd70dd2ee, 0x4e048354, 0x3903b3c2,
0xa7672661, 0xd06016f7, 0x4969474d, 0x3e6e77db, 0xaed16a4a, 0xd9d65adc,
0x40df0b66, 0x37d83bf0, 0xa9bcae53, 0xdebb9ec5, 0x47b2cf7f, 0x30b5ffe9,
0xbdbdf21c, 0xcabac28a, 0x53b39330, 0x24b4a3a6, 0xbad03605, 0xcdd70693,
0x54de5729, 0x23d967bf, 0xb3667a2e, 0xc4614ab8, 0x5d681b02, 0x2a6f2b94,
uint32_t crc_32_tab[] = {
/* CRC polynomial 0xedb88320 */
0x00000000, 0x77073096, 0xee0e612c, 0x990951ba, 0x076dc419, 0x706af48f, 0xe963a535, 0x9e6495a3, 0x0edb8832,
0x79dcb8a4, 0xe0d5e91e, 0x97d2d988, 0x09b64c2b, 0x7eb17cbd, 0xe7b82d07, 0x90bf1d91, 0x1db71064, 0x6ab020f2,
0xf3b97148, 0x84be41de, 0x1adad47d, 0x6ddde4eb, 0xf4d4b551, 0x83d385c7, 0x136c9856, 0x646ba8c0, 0xfd62f97a,
0x8a65c9ec, 0x14015c4f, 0x63066cd9, 0xfa0f3d63, 0x8d080df5, 0x3b6e20c8, 0x4c69105e, 0xd56041e4, 0xa2677172,
0x3c03e4d1, 0x4b04d447, 0xd20d85fd, 0xa50ab56b, 0x35b5a8fa, 0x42b2986c, 0xdbbbc9d6, 0xacbcf940, 0x32d86ce3,
0x45df5c75, 0xdcd60dcf, 0xabd13d59, 0x26d930ac, 0x51de003a, 0xc8d75180, 0xbfd06116, 0x21b4f4b5, 0x56b3c423,
0xcfba9599, 0xb8bda50f, 0x2802b89e, 0x5f058808, 0xc60cd9b2, 0xb10be924, 0x2f6f7c87, 0x58684c11, 0xc1611dab,
0xb6662d3d, 0x76dc4190, 0x01db7106, 0x98d220bc, 0xefd5102a, 0x71b18589, 0x06b6b51f, 0x9fbfe4a5, 0xe8b8d433,
0x7807c9a2, 0x0f00f934, 0x9609a88e, 0xe10e9818, 0x7f6a0dbb, 0x086d3d2d, 0x91646c97, 0xe6635c01, 0x6b6b51f4,
0x1c6c6162, 0x856530d8, 0xf262004e, 0x6c0695ed, 0x1b01a57b, 0x8208f4c1, 0xf50fc457, 0x65b0d9c6, 0x12b7e950,
0x8bbeb8ea, 0xfcb9887c, 0x62dd1ddf, 0x15da2d49, 0x8cd37cf3, 0xfbd44c65, 0x4db26158, 0x3ab551ce, 0xa3bc0074,
0xd4bb30e2, 0x4adfa541, 0x3dd895d7, 0xa4d1c46d, 0xd3d6f4fb, 0x4369e96a, 0x346ed9fc, 0xad678846, 0xda60b8d0,
0x44042d73, 0x33031de5, 0xaa0a4c5f, 0xdd0d7cc9, 0x5005713c, 0x270241aa, 0xbe0b1010, 0xc90c2086, 0x5768b525,
0x206f85b3, 0xb966d409, 0xce61e49f, 0x5edef90e, 0x29d9c998, 0xb0d09822, 0xc7d7a8b4, 0x59b33d17, 0x2eb40d81,
0xb7bd5c3b, 0xc0ba6cad, 0xedb88320, 0x9abfb3b6, 0x03b6e20c, 0x74b1d29a, 0xead54739, 0x9dd277af, 0x04db2615,
0x73dc1683, 0xe3630b12, 0x94643b84, 0x0d6d6a3e, 0x7a6a5aa8, 0xe40ecf0b, 0x9309ff9d, 0x0a00ae27, 0x7d079eb1,
0xf00f9344, 0x8708a3d2, 0x1e01f268, 0x6906c2fe, 0xf762575d, 0x806567cb, 0x196c3671, 0x6e6b06e7, 0xfed41b76,
0x89d32be0, 0x10da7a5a, 0x67dd4acc, 0xf9b9df6f, 0x8ebeeff9, 0x17b7be43, 0x60b08ed5, 0xd6d6a3e8, 0xa1d1937e,
0x38d8c2c4, 0x4fdff252, 0xd1bb67f1, 0xa6bc5767, 0x3fb506dd, 0x48b2364b, 0xd80d2bda, 0xaf0a1b4c, 0x36034af6,
0x41047a60, 0xdf60efc3, 0xa867df55, 0x316e8eef, 0x4669be79, 0xcb61b38c, 0xbc66831a, 0x256fd2a0, 0x5268e236,
0xcc0c7795, 0xbb0b4703, 0x220216b9, 0x5505262f, 0xc5ba3bbe, 0xb2bd0b28, 0x2bb45a92, 0x5cb36a04, 0xc2d7ffa7,
0xb5d0cf31, 0x2cd99e8b, 0x5bdeae1d, 0x9b64c2b0, 0xec63f226, 0x756aa39c, 0x026d930a, 0x9c0906a9, 0xeb0e363f,
0x72076785, 0x05005713, 0x95bf4a82, 0xe2b87a14, 0x7bb12bae, 0x0cb61b38, 0x92d28e9b, 0xe5d5be0d, 0x7cdcefb7,
0x0bdbdf21, 0x86d3d2d4, 0xf1d4e242, 0x68ddb3f8, 0x1fda836e, 0x81be16cd, 0xf6b9265b, 0x6fb077e1, 0x18b74777,
0x88085ae6, 0xff0f6a70, 0x66063bca, 0x11010b5c, 0x8f659eff, 0xf862ae69, 0x616bffd3, 0x166ccf45, 0xa00ae278,
0xd70dd2ee, 0x4e048354, 0x3903b3c2, 0xa7672661, 0xd06016f7, 0x4969474d, 0x3e6e77db, 0xaed16a4a, 0xd9d65adc,
0x40df0b66, 0x37d83bf0, 0xa9bcae53, 0xdebb9ec5, 0x47b2cf7f, 0x30b5ffe9, 0xbdbdf21c, 0xcabac28a, 0x53b39330,
0x24b4a3a6, 0xbad03605, 0xcdd70693, 0x54de5729, 0x23d967bf, 0xb3667a2e, 0xc4614ab8, 0x5d681b02, 0x2a6f2b94,
0xb40bbe37, 0xc30c8ea1, 0x5a05df1b, 0x2d02ef8d
};
#define UPDC32(octet,crc) (crc_32_tab[((crc)\
^ static_cast<uint8_t>(octet)) & 0xff] ^ ((crc) >> 8))
for ( ; len; --len, ++buf)
#define UPDC32(octet, crc) (crc_32_tab[((crc) ^ static_cast<uint8_t>(octet)) & 0xff] ^ ((crc) >> 8))
for (; len; --len, ++buf)
{
oldcrc32 = UPDC32(*buf, oldcrc32);
}
return ~oldcrc32;
}
@ -162,14 +148,14 @@ tm safe_localtime(const time_t &t)
std::size_t write_callback(void *opaque, mz_uint64 file_ofs, const void *pBuf, std::size_t n)
{
auto buffer = static_cast<std::vector<char> *>(opaque);
if(file_ofs + n > buffer->size())
if (file_ofs + n > buffer->size())
{
auto new_size = static_cast<std::vector<char>::size_type>(file_ofs + n);
buffer->resize(new_size);
}
for(std::size_t i = 0; i < n; i++)
for (std::size_t i = 0; i < n; i++)
{
(*buffer)[static_cast<std::size_t>(file_ofs + i)] = (static_cast<const char *>(pBuf))[i];
}
@ -259,49 +245,49 @@ void zip_file::save(const std::string &filename)
void zip_file::save(std::ostream &stream)
{
if(archive_->m_zip_mode == MZ_ZIP_MODE_WRITING)
if (archive_->m_zip_mode == MZ_ZIP_MODE_WRITING)
{
mz_zip_writer_finalize_archive(archive_.get());
}
if(archive_->m_zip_mode == MZ_ZIP_MODE_WRITING_HAS_BEEN_FINALIZED)
if (archive_->m_zip_mode == MZ_ZIP_MODE_WRITING_HAS_BEEN_FINALIZED)
{
mz_zip_writer_end(archive_.get());
}
if(archive_->m_zip_mode == MZ_ZIP_MODE_INVALID)
if (archive_->m_zip_mode == MZ_ZIP_MODE_INVALID)
{
start_read();
}
append_comment();
stream.write(buffer_.data(), static_cast<long>(buffer_.size()));
}
void zip_file::save(std::vector<unsigned char> &bytes)
{
if(archive_->m_zip_mode == MZ_ZIP_MODE_WRITING)
if (archive_->m_zip_mode == MZ_ZIP_MODE_WRITING)
{
mz_zip_writer_finalize_archive(archive_.get());
}
if(archive_->m_zip_mode == MZ_ZIP_MODE_WRITING_HAS_BEEN_FINALIZED)
if (archive_->m_zip_mode == MZ_ZIP_MODE_WRITING_HAS_BEEN_FINALIZED)
{
mz_zip_writer_end(archive_.get());
}
if(archive_->m_zip_mode == MZ_ZIP_MODE_INVALID)
if (archive_->m_zip_mode == MZ_ZIP_MODE_INVALID)
{
start_read();
}
append_comment();
bytes.assign(buffer_.begin(), buffer_.end());
}
void zip_file::append_comment()
{
if(!comment.empty())
if (!comment.empty())
{
auto comment_length = std::min(static_cast<uint16_t>(comment.length()), std::numeric_limits<uint16_t>::max());
buffer_[buffer_.size() - 2] = static_cast<char>(comment_length);
@ -312,32 +298,30 @@ void zip_file::append_comment()
void zip_file::remove_comment()
{
if(buffer_.empty()) return;
if (buffer_.empty()) return;
std::size_t position = buffer_.size() - 1;
for(; position >= 3; position--)
for (; position >= 3; position--)
{
if(buffer_[position - 3] == 'P'
&& buffer_[position - 2] == 'K'
&& buffer_[position - 1] == '\x05'
&& buffer_[position] == '\x06')
if (buffer_[position - 3] == 'P' && buffer_[position - 2] == 'K' && buffer_[position - 1] == '\x05' &&
buffer_[position] == '\x06')
{
position = position + 17;
break;
}
}
if(position == 3)
if (position == 3)
{
throw std::runtime_error("didn't find end of central directory signature");
}
uint16_t length = static_cast<uint16_t>(buffer_[position + 1]);
length = static_cast<uint16_t>(length << 8) + static_cast<uint16_t>(buffer_[position]);
position += 2;
if(length != 0)
if (length != 0)
{
comment = std::string(buffer_.data() + position, buffer_.data() + position + length);
buffer_.resize(buffer_.size() - length);
@ -348,7 +332,7 @@ void zip_file::remove_comment()
void zip_file::reset()
{
switch(archive_->m_zip_mode)
switch (archive_->m_zip_mode)
{
case MZ_ZIP_MODE_READING:
mz_zip_reader_end(archive_.get());
@ -363,15 +347,15 @@ void zip_file::reset()
case MZ_ZIP_MODE_INVALID:
break;
}
if(archive_->m_zip_mode != MZ_ZIP_MODE_INVALID)
if (archive_->m_zip_mode != MZ_ZIP_MODE_INVALID)
{
throw std::runtime_error("");
}
buffer_.clear();
comment.clear();
start_write();
mz_zip_writer_finalize_archive(archive_.get());
mz_zip_writer_end(archive_.get());
@ -379,14 +363,14 @@ void zip_file::reset()
zip_info zip_file::getinfo(const std::string &name)
{
if(archive_->m_zip_mode != MZ_ZIP_MODE_READING)
if (archive_->m_zip_mode != MZ_ZIP_MODE_READING)
{
start_read();
}
int index = mz_zip_reader_locate_file(archive_.get(), name.c_str(), nullptr, 0);
if(index == -1)
if (index == -1)
{
throw std::runtime_error("not found");
}
@ -396,7 +380,7 @@ zip_info zip_file::getinfo(const std::string &name)
zip_info zip_file::getinfo(int index)
{
if(archive_->m_zip_mode != MZ_ZIP_MODE_READING)
if (archive_->m_zip_mode != MZ_ZIP_MODE_READING)
{
start_read();
}
@ -426,25 +410,25 @@ zip_info zip_file::getinfo(int index)
result.create_version = stat.m_version_made_by;
result.volume = stat.m_file_index;
result.create_system = stat.m_method;
return result;
}
void zip_file::start_read()
{
if(archive_->m_zip_mode == MZ_ZIP_MODE_READING) return;
if(archive_->m_zip_mode == MZ_ZIP_MODE_WRITING)
if (archive_->m_zip_mode == MZ_ZIP_MODE_READING) return;
if (archive_->m_zip_mode == MZ_ZIP_MODE_WRITING)
{
mz_zip_writer_finalize_archive(archive_.get());
}
if(archive_->m_zip_mode == MZ_ZIP_MODE_WRITING_HAS_BEEN_FINALIZED)
if (archive_->m_zip_mode == MZ_ZIP_MODE_WRITING_HAS_BEEN_FINALIZED)
{
mz_zip_writer_end(archive_.get());
}
if(!mz_zip_reader_init_mem(archive_.get(), buffer_.data(), buffer_.size(), 0))
if (!mz_zip_reader_init_mem(archive_.get(), buffer_.data(), buffer_.size(), 0))
{
throw std::runtime_error("bad zip");
}
@ -452,55 +436,55 @@ void zip_file::start_read()
void zip_file::start_write()
{
if(archive_->m_zip_mode == MZ_ZIP_MODE_WRITING) return;
switch(archive_->m_zip_mode)
if (archive_->m_zip_mode == MZ_ZIP_MODE_WRITING) return;
switch (archive_->m_zip_mode)
{
case MZ_ZIP_MODE_READING:
case MZ_ZIP_MODE_READING:
{
mz_zip_archive archive_copy;
std::memset(&archive_copy, 0, sizeof(mz_zip_archive));
std::vector<char> buffer_copy(buffer_.begin(), buffer_.end());
if (!mz_zip_reader_init_mem(&archive_copy, buffer_copy.data(), buffer_copy.size(), 0))
{
mz_zip_archive archive_copy;
std::memset(&archive_copy, 0, sizeof(mz_zip_archive));
std::vector<char> buffer_copy(buffer_.begin(), buffer_.end());
if(!mz_zip_reader_init_mem(&archive_copy, buffer_copy.data(), buffer_copy.size(), 0))
{
throw std::runtime_error("bad zip");
}
mz_zip_reader_end(archive_.get());
archive_->m_pWrite = &write_callback;
archive_->m_pIO_opaque = &buffer_;
buffer_ = std::vector<char>();
if(!mz_zip_writer_init(archive_.get(), 0))
{
throw std::runtime_error("bad zip");
}
for(unsigned int i = 0; i < static_cast<unsigned int>(archive_copy.m_total_files); i++)
{
if(!mz_zip_writer_add_from_zip_reader(archive_.get(), &archive_copy, i))
{
throw std::runtime_error("fail");
}
}
mz_zip_reader_end(&archive_copy);
return;
throw std::runtime_error("bad zip");
}
case MZ_ZIP_MODE_WRITING_HAS_BEEN_FINALIZED:
mz_zip_writer_end(archive_.get());
break;
case MZ_ZIP_MODE_INVALID:
case MZ_ZIP_MODE_WRITING:
break;
mz_zip_reader_end(archive_.get());
archive_->m_pWrite = &write_callback;
archive_->m_pIO_opaque = &buffer_;
buffer_ = std::vector<char>();
if (!mz_zip_writer_init(archive_.get(), 0))
{
throw std::runtime_error("bad zip");
}
for (unsigned int i = 0; i < static_cast<unsigned int>(archive_copy.m_total_files); i++)
{
if (!mz_zip_writer_add_from_zip_reader(archive_.get(), &archive_copy, i))
{
throw std::runtime_error("fail");
}
}
mz_zip_reader_end(&archive_copy);
return;
}
case MZ_ZIP_MODE_WRITING_HAS_BEEN_FINALIZED:
mz_zip_writer_end(archive_.get());
break;
case MZ_ZIP_MODE_INVALID:
case MZ_ZIP_MODE_WRITING:
break;
}
archive_->m_pWrite = &write_callback;
archive_->m_pIO_opaque = &buffer_;
if(!mz_zip_writer_init(archive_.get(), 0))
if (!mz_zip_writer_init(archive_.get(), 0))
{
throw std::runtime_error("bad zip");
}
@ -509,7 +493,7 @@ void zip_file::start_write()
void zip_file::write(const std::string &filename)
{
auto split = split_path(filename);
if(split.size() > 1)
if (split.size() > 1)
{
split.erase(split.begin());
}
@ -529,12 +513,12 @@ void zip_file::write(const std::string &filename, const std::string &arcname)
void zip_file::writestr(const std::string &arcname, const std::string &bytes)
{
if(archive_->m_zip_mode != MZ_ZIP_MODE_WRITING)
if (archive_->m_zip_mode != MZ_ZIP_MODE_WRITING)
{
start_write();
}
if(!mz_zip_writer_add_mem(archive_.get(), arcname.c_str(), bytes.data(), bytes.size(), MZ_BEST_COMPRESSION))
if (!mz_zip_writer_add_mem(archive_.get(), arcname.c_str(), bytes.data(), bytes.size(), MZ_BEST_COMPRESSION))
{
throw std::runtime_error("write error");
}
@ -542,19 +526,21 @@ void zip_file::writestr(const std::string &arcname, const std::string &bytes)
void zip_file::writestr(const zip_info &info, const std::string &bytes)
{
if(info.filename.empty() || info.date_time.year < 1980)
if (info.filename.empty() || info.date_time.year < 1980)
{
throw std::runtime_error("must specify a filename and valid date (year >= 1980");
}
if(archive_->m_zip_mode != MZ_ZIP_MODE_WRITING)
if (archive_->m_zip_mode != MZ_ZIP_MODE_WRITING)
{
start_write();
}
auto crc = crc32buf(bytes.c_str(), bytes.size());
if(!mz_zip_writer_add_mem_ex(archive_.get(), info.filename.c_str(), bytes.data(), bytes.size(), info.comment.c_str(), static_cast<mz_uint16>(info.comment.size()), MZ_BEST_COMPRESSION, 0, crc))
if (!mz_zip_writer_add_mem_ex(archive_.get(), info.filename.c_str(), bytes.data(), bytes.size(),
info.comment.c_str(), static_cast<mz_uint16>(info.comment.size()),
MZ_BEST_COMPRESSION, 0, crc))
{
throw std::runtime_error("write error");
}
@ -563,10 +549,11 @@ void zip_file::writestr(const zip_info &info, const std::string &bytes)
std::string zip_file::read(const zip_info &info)
{
std::size_t size;
char *data = static_cast<char *>(mz_zip_reader_extract_file_to_heap(archive_.get(), info.filename.c_str(), &size, 0));
if(data == nullptr)
char *data =
static_cast<char *>(mz_zip_reader_extract_file_to_heap(archive_.get(), info.filename.c_str(), &size, 0));
if (data == nullptr)
{
throw std::runtime_error("file couldn't be read");
throw std::runtime_error("file couldn't be read");
}
std::string extracted(data, data + size);
mz_free(data);
@ -580,7 +567,7 @@ std::string zip_file::read(const std::string &name)
bool zip_file::has_file(const std::string &name)
{
if(archive_->m_zip_mode != MZ_ZIP_MODE_READING)
if (archive_->m_zip_mode != MZ_ZIP_MODE_READING)
{
start_read();
}
@ -597,14 +584,14 @@ bool zip_file::has_file(const zip_info &name)
std::vector<zip_info> zip_file::infolist()
{
if(archive_->m_zip_mode != MZ_ZIP_MODE_READING)
if (archive_->m_zip_mode != MZ_ZIP_MODE_READING)
{
start_read();
}
std::vector<zip_info> info;
for(std::size_t i = 0; i < mz_zip_reader_get_num_files(archive_.get()); i++)
for (std::size_t i = 0; i < mz_zip_reader_get_num_files(archive_.get()); i++)
{
info.push_back(getinfo(static_cast<int>(i)));
}
@ -616,7 +603,7 @@ std::vector<std::string> zip_file::namelist()
{
std::vector<std::string> names;
for(auto &info : infolist())
for (auto &info : infolist())
{
names.push_back(info.filename);
}
@ -644,7 +631,7 @@ void zip_file::extract(const std::string &member)
void zip_file::extract(const std::string &member, const std::string &path)
{
std::fstream stream(join_path({path, member}), std::ios::binary | std::ios::out);
std::fstream stream(join_path({ path, member }), std::ios::binary | std::ios::out);
stream << open(member).rdbuf();
}
@ -655,7 +642,7 @@ void zip_file::extract(const zip_info &member)
void zip_file::extract(const zip_info &member, const std::string &path)
{
std::fstream stream(join_path({path, member.filename}), std::ios::binary | std::ios::out);
std::fstream stream(join_path({ path, member.filename }), std::ios::binary | std::ios::out);
stream << open(member).rdbuf();
}
@ -666,7 +653,7 @@ void zip_file::extractall(const std::string &path)
void zip_file::extractall(const std::string &path, const std::vector<std::string> &members)
{
for(auto &member : members)
for (auto &member : members)
{
extract(member, path);
}
@ -674,7 +661,7 @@ void zip_file::extractall(const std::string &path, const std::vector<std::string
void zip_file::extractall(const std::string &path, const std::vector<zip_info> &members)
{
for(auto &member : members)
for (auto &member : members)
{
extract(member, path);
}
@ -687,19 +674,27 @@ void zip_file::printdir()
void zip_file::printdir(std::ostream &stream)
{
stream << " Length " << " " << " " << "Date" << " " << " " << "Time " << " " << "Name" << std::endl;
stream << " Length "
<< " "
<< " "
<< "Date"
<< " "
<< " "
<< "Time "
<< " "
<< "Name" << std::endl;
stream << "--------- ---------- ----- ----" << std::endl;
std::size_t sum_length = 0;
std::size_t file_count = 0;
for(auto &member : infolist())
for (auto &member : infolist())
{
sum_length += member.file_size;
file_count++;
std::string length_string = std::to_string(member.file_size);
while(length_string.length() < 9)
while (length_string.length() < 9)
{
length_string = " " + length_string;
}
@ -723,7 +718,7 @@ void zip_file::printdir(std::ostream &stream)
stream << "--------- -------" << std::endl;
std::string length_string = std::to_string(sum_length);
while(length_string.length() < 9)
while (length_string.length() < 9)
{
length_string = " " + length_string;
}
@ -733,23 +728,23 @@ void zip_file::printdir(std::ostream &stream)
std::pair<bool, std::string> zip_file::testzip()
{
if(archive_->m_zip_mode == MZ_ZIP_MODE_INVALID)
if (archive_->m_zip_mode == MZ_ZIP_MODE_INVALID)
{
throw std::runtime_error("not open");
}
for(auto &file : infolist())
for (auto &file : infolist())
{
auto content = read(file);
auto crc = crc32buf(content.c_str(), content.size());
if(crc != file.crc)
if (crc != file.crc)
{
return {false, file.filename};
return { false, file.filename };
}
}
return {true, ""};
return { true, "" };
}
} // namespace xlnt

View File

@ -5,15 +5,15 @@
namespace xlnt {
namespace detail {
cell_impl::cell_impl() : cell_impl(1, 1)
{
}
cell_impl::cell_impl(column_t column, row_t row) : cell_impl(nullptr, column, row)
{
}
cell_impl::cell_impl(worksheet_impl *parent, column_t column, row_t row)
: type_(cell::type::null),
parent_(parent),
@ -27,12 +27,12 @@ cell_impl::cell_impl(worksheet_impl *parent, column_t column, row_t row)
comment_(nullptr)
{
}
cell_impl::cell_impl(const cell_impl &rhs)
{
*this = rhs;
}
cell_impl &cell_impl::operator=(const cell_impl &rhs)
{
parent_ = rhs.parent_;
@ -47,12 +47,12 @@ cell_impl &cell_impl::operator=(const cell_impl &rhs)
type_ = rhs.type_;
style_id_ = rhs.style_id_;
has_style_ = rhs.has_style_;
if(rhs.comment_ != nullptr)
if (rhs.comment_ != nullptr)
{
comment_.reset(new comment_impl(*rhs.comment_));
}
return *this;
}

View File

@ -21,22 +21,22 @@ std::string check_string(std::string s)
{
return s;
}
// check encoding?
if (s.size() > 32767)
{
s = s.substr(0, 32767); // max string length in Excel
}
for (char c : s)
{
if (c>= 0 && (c <= 8 || c == 11 || c == 12 || (c >= 14 && c <= 31)))
if (c >= 0 && (c <= 8 || c == 11 || c == 12 || (c >= 14 && c <= 31)))
{
throw xlnt::illegal_character_error(c);
}
}
return s;
}
@ -45,8 +45,8 @@ std::pair<bool, long double> cast_numeric(const std::string &s)
const char *str = s.c_str();
char *str_end = nullptr;
auto result = std::strtold(str, &str_end);
if (str_end != str + s.size()) return{ false, 0 };
return{ true, result };
if (str_end != str + s.size()) return { false, 0 };
return { true, result };
}
std::pair<bool, long double> cast_percentage(const std::string &s)
@ -54,20 +54,20 @@ std::pair<bool, long double> cast_percentage(const std::string &s)
if (s.back() == '%')
{
auto number = cast_numeric(s.substr(0, s.size() - 1));
if (number.first)
{
return{ true, number.second / 100 };
return { true, number.second / 100 };
}
}
return { false, 0 };
}
std::pair<bool, xlnt::time> cast_time(const std::string &s)
{
xlnt::time result;
try
{
auto last_colon = s.find_last_of(':');
@ -75,9 +75,9 @@ std::pair<bool, xlnt::time> cast_time(const std::string &s)
double seconds = std::stod(s.substr(last_colon + 1));
result.second = static_cast<int>(seconds);
result.microsecond = static_cast<int>((seconds - static_cast<double>(result.second)) * 1e6);
auto first_colon = s.find_first_of(':');
if (first_colon == last_colon)
{
auto decimal_pos = s.find('.');
@ -100,9 +100,9 @@ std::pair<bool, xlnt::time> cast_time(const std::string &s)
}
catch (std::invalid_argument)
{
return{ false, result };
return { false, result };
}
return { true, result };
}
@ -115,7 +115,7 @@ class style;
namespace detail {
struct worksheet_impl;
struct cell_impl
{
cell_impl();
@ -123,31 +123,31 @@ struct cell_impl
cell_impl(worksheet_impl *parent, column_t column, row_t row);
cell_impl(const cell_impl &rhs);
cell_impl &operator=(const cell_impl &rhs);
cell self()
{
return xlnt::cell(this);
}
void set_string(const std::string &s, bool guess_types)
{
value_string_ = check_string(s);
type_ = cell::type::string;
if (value_string_.size() > 1 && value_string_.front() == '=')
{
formula_ = value_string_;
type_ = cell::type::formula;
value_string_.clear();
}
else if(cell::error_codes().find(s) != cell::error_codes().end())
else if (cell::error_codes().find(s) != cell::error_codes().end())
{
type_ = cell::type::error;
}
else if(guess_types)
else if (guess_types)
{
auto percentage = cast_percentage(s);
if (percentage.first)
{
value_numeric_ = percentage.second;
@ -157,7 +157,7 @@ struct cell_impl
else
{
auto time = cast_time(s);
if (time.first)
{
type_ = cell::type::numeric;
@ -167,7 +167,7 @@ struct cell_impl
else
{
auto numeric = cast_numeric(s);
if (numeric.first)
{
value_numeric_ = numeric.second;
@ -179,27 +179,27 @@ struct cell_impl
}
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 has_style_;
std::size_t style_id_;
std::unique_ptr<comment_impl> comment_;
};
} // namespace detail
} // namespace xlnt

View File

@ -6,7 +6,7 @@ namespace detail {
comment_impl::comment_impl()
{
}
comment_impl::comment_impl(const comment_impl &rhs)
{
*this = rhs;
@ -16,9 +16,9 @@ comment_impl &comment_impl::operator=(const xlnt::detail::comment_impl &rhs)
{
text_ = rhs.text_;
author_ = rhs.author_;
return *this;
}
} // namespace detail
} // namespace xlnt

View File

@ -13,7 +13,7 @@ struct comment_impl
comment_impl(cell_impl *parent, const std::string &text, const std::string &author);
comment_impl(const comment_impl &rhs);
comment_impl &operator=(const comment_impl &rhs);
std::string text_;
std::string author_;
};

View File

@ -9,7 +9,8 @@ namespace xlnt {
const row_t constants::MinRow = 1;
const row_t constants::MaxRow = LimitStyle == limit_style::excel ? (1u << 20) : UINT32_MAX;
const column_t constants::MinColumn = 1;
const column_t constants::MaxColumn = LimitStyle == limit_style::excel ? (1u << 14) : LimitStyle == limit_style::openpyxl ? 18278 : UINT32_MAX;
const column_t constants::MaxColumn =
LimitStyle == limit_style::excel ? (1u << 14) : LimitStyle == limit_style::openpyxl ? 18278 : UINT32_MAX;
// constants
const std::string constants::PackageProps = "docProps";
@ -30,20 +31,18 @@ const std::string constants::ArcStyles = PackageXl + "/styles.xml";
const std::string constants::ArcTheme = PackageTheme + "/theme1.xml";
const std::string constants::ArcSharedString = PackageXl + "/sharedStrings.xml";
const std::unordered_map<std::string, std::string> constants::Namespaces =
{
{"spreadsheetml", "http://schemas.openxmlformats.org/spreadsheetml/2006/main"},
{"content-types", "http://schemas.openxmlformats.org/package/2006/content-types"},
{"relationships", "http://schemas.openxmlformats.org/package/2006/relationships"},
{"drawingml", "http://schemas.openxmlformats.org/drawingml/2006/main"},
{"r", "http://schemas.openxmlformats.org/officeDocument/2006/relationships"},
{"cp", "http://schemas.openxmlformats.org/package/2006/metadata/core-properties"},
{"dc", "http://purl.org/dc/elements/1.1/"},
{"dcterms", "http://purl.org/dc/terms/"},
{"dcmitype", "http://purl.org/dc/dcmitype/"},
{"xsi", "http://www.w3.org/2001/XMLSchema-instance"},
{"vt", "http://schemas.openxmlformats.org/officeDocument/2006/docPropsVTypes"},
{"xml", "http://www.w3.org/XML/1998/namespace"}
const std::unordered_map<std::string, std::string> constants::Namespaces = {
{ "spreadsheetml", "http://schemas.openxmlformats.org/spreadsheetml/2006/main" },
{ "content-types", "http://schemas.openxmlformats.org/package/2006/content-types" },
{ "relationships", "http://schemas.openxmlformats.org/package/2006/relationships" },
{ "drawingml", "http://schemas.openxmlformats.org/drawingml/2006/main" },
{ "r", "http://schemas.openxmlformats.org/officeDocument/2006/relationships" },
{ "cp", "http://schemas.openxmlformats.org/package/2006/metadata/core-properties" },
{ "dc", "http://purl.org/dc/elements/1.1/" },
{ "dcterms", "http://purl.org/dc/terms/" },
{ "dcmitype", "http://purl.org/dc/dcmitype/" },
{ "xsi", "http://www.w3.org/2001/XMLSchema-instance" },
{ "vt", "http://schemas.openxmlformats.org/officeDocument/2006/docPropsVTypes" },
{ "xml", "http://www.w3.org/XML/1998/namespace" }
};
}

View File

@ -35,5 +35,5 @@ struct constants
static const std::unordered_map<std::string, std::string> Namespaces;
};
} // namespace xlnt

View File

@ -0,0 +1,31 @@
#pragma once
#ifdef _MSC_VER
#pragma push_macro("NOMINMAX")
#pragma push_macro("UNICODE")
#pragma push_macro("STRICT")
#ifndef NOMINMAX
#define NOMINMAX
#endif
#ifndef UNICODE
#define UNICODE
#endif
#ifndef STRICT
#define STRICT
#endif
#ifndef WIN32_LEAN_AND_MEAN
#define WIN32_LEAN_AND_MEAN
#endif
#include <Windows.h>
#pragma pop_macro("STRICT")
#pragma pop_macro("UNICODE")
#pragma pop_macro("NOMINMAX")
#endif // _MSC_VER

View File

@ -9,27 +9,27 @@ namespace detail {
struct workbook_impl
{
workbook_impl();
workbook_impl(const workbook_impl &other)
workbook_impl(const workbook_impl &other)
: active_sheet_index_(other.active_sheet_index_),
worksheets_(other.worksheets_),
relationships_(other.relationships_),
root_relationships_(other.root_relationships_),
drawings_(other.drawings_),
shared_strings_(other.shared_strings_),
properties_(other.properties_),
guess_types_(other.guess_types_),
data_only_(other.data_only_),
styles_(other.styles_),
colors_(other.colors_),
borders_(other.borders_),
fills_(other.fills_),
fonts_(other.fonts_),
number_formats_(other.number_formats_),
manifest_(other.manifest_)
worksheets_(other.worksheets_),
relationships_(other.relationships_),
root_relationships_(other.root_relationships_),
drawings_(other.drawings_),
shared_strings_(other.shared_strings_),
properties_(other.properties_),
guess_types_(other.guess_types_),
data_only_(other.data_only_),
styles_(other.styles_),
colors_(other.colors_),
borders_(other.borders_),
fills_(other.fills_),
fonts_(other.fonts_),
number_formats_(other.number_formats_),
manifest_(other.manifest_)
{
}
workbook_impl &operator=(const workbook_impl &other)
{
active_sheet_index_ = other.active_sheet_index_;
@ -38,7 +38,8 @@ struct workbook_impl
relationships_.clear();
std::copy(other.relationships_.begin(), other.relationships_.end(), std::back_inserter(relationships_));
root_relationships_.clear();
std::copy(other.root_relationships_.begin(), other.root_relationships_.end(), std::back_inserter(root_relationships_));
std::copy(other.root_relationships_.begin(), other.root_relationships_.end(),
std::back_inserter(root_relationships_));
drawings_.clear();
std::copy(other.drawings_.begin(), other.drawings_.end(), back_inserter(drawings_));
shared_strings_.clear();
@ -53,7 +54,7 @@ struct workbook_impl
number_formats_ = other.number_formats_;
colors_ = other.colors_;
manifest_ = other.manifest_;
return *this;
}
@ -63,24 +64,24 @@ struct workbook_impl
std::vector<relationship> root_relationships_;
std::vector<drawing> drawings_;
std::vector<std::string> shared_strings_;
document_properties properties_;
bool guess_types_;
bool data_only_;
std::vector<style> styles_;
std::size_t next_custom_format_id_;
std::vector<color> colors_;
std::vector<border> borders_;
std::vector<fill> fills_;
std::vector<font> fonts_;
std::vector<number_format> number_formats_;
manifest manifest_;
theme theme_;
};

View File

@ -2,6 +2,9 @@
#include <unordered_map>
#include <vector>
#include <xlnt/worksheet/column_properties.hpp>
#include <xlnt/worksheet/row_properties.hpp>
#include "cell_impl.hpp"
namespace xlnt {
@ -13,7 +16,7 @@ namespace detail {
struct worksheet_impl
{
worksheet_impl(workbook *parent_workbook, const std::string &title)
: parent_(parent_workbook), title_(title), freeze_panes_("A1"), comment_count_(0)
: parent_(parent_workbook), title_(title), freeze_panes_("A1"), comment_count_(0)
{
page_margins_.set_left(0.75);
page_margins_.set_right(0.75);
@ -22,12 +25,12 @@ struct worksheet_impl
page_margins_.set_header(0.5);
page_margins_.set_footer(0.5);
}
worksheet_impl(const worksheet_impl &other)
{
*this = other;
}
void operator=(const worksheet_impl &other)
{
parent_ = other.parent_;
@ -36,9 +39,9 @@ struct worksheet_impl
title_ = other.title_;
freeze_panes_ = other.freeze_panes_;
cell_map_ = other.cell_map_;
for(auto &row : cell_map_)
for (auto &row : cell_map_)
{
for(auto &cell : row.second)
for (auto &cell : row.second)
{
cell.second.parent_ = this;
}
@ -52,7 +55,7 @@ struct worksheet_impl
comment_count_ = other.comment_count_;
header_footer_ = other.header_footer_;
}
workbook *parent_;
std::unordered_map<column_t, column_properties> column_properties_;
std::unordered_map<row_t, row_properties> row_properties_;

View File

@ -12,6 +12,6 @@ struct xml_document_impl
std::string encoding;
pugi::xml_document doc;
};
} // namespace detail
} // namespace xlnt

View File

@ -7,10 +7,14 @@ namespace detail {
struct xml_node_impl
{
xml_node_impl() {}
explicit xml_node_impl(pugi::xml_node n) : node(n) {}
xml_node_impl()
{
}
explicit xml_node_impl(pugi::xml_node n) : node(n)
{
}
pugi::xml_node node;
};
} // namespace detail
} // namespace xlnt

View File

@ -6,13 +6,11 @@ struct drawing_struct
{
drawing_struct()
{
}
};
drawing::drawing() : root_(nullptr)
{
}
} // namespace xlnt

View File

@ -1,5 +1,5 @@
#include <xlnt/s11n/comment_serializer.hpp>
namespace {
} // namespace xlnt

View File

@ -21,21 +21,21 @@
#include <detail/constants.hpp>
namespace {
std::string::size_type find_string_in_string(const std::string &string, const std::string &substring)
{
std::string::size_type possible_match_index = string.find(substring.at(0));
while(possible_match_index != std::string::npos)
while (possible_match_index != std::string::npos)
{
if(string.substr(possible_match_index, substring.size()) == substring)
if (string.substr(possible_match_index, substring.size()) == substring)
{
return possible_match_index;
}
possible_match_index = string.find(substring.at(0), possible_match_index + 1);
}
return possible_match_index;
}
@ -43,58 +43,63 @@ bool load_workbook(xlnt::zip_file &archive, bool guess_types, bool data_only, xl
{
wb.set_guess_types(guess_types);
wb.set_data_only(data_only);
xlnt::manifest_serializer ms(wb.get_manifest());
ms.read_manifest(xlnt::xml_serializer::deserialize(archive.read(xlnt::constants::ArcContentTypes)));
if(ms.determine_document_type() != "excel")
if (ms.determine_document_type() != "excel")
{
throw xlnt::invalid_file_exception("");
}
wb.clear();
auto workbook_relationships = xlnt::relationship_serializer::read_relationships(archive, xlnt::constants::ArcWorkbook);
for(const auto &relationship : workbook_relationships)
auto workbook_relationships =
xlnt::relationship_serializer::read_relationships(archive, xlnt::constants::ArcWorkbook);
for (const auto &relationship : workbook_relationships)
{
wb.create_relationship(relationship.get_id(), relationship.get_target_uri(), relationship.get_type());
}
auto xml = xlnt::xml_serializer::deserialize(archive.read(xlnt::constants::ArcWorkbook));
auto root_node = xml.get_child("workbook");
auto workbook_pr_node = root_node.get_child("workbookPr");
wb.get_properties().excel_base_date = (workbook_pr_node.has_attribute("date1904") && workbook_pr_node.get_attribute("date1904") != "0") ? xlnt::calendar::mac_1904 : xlnt::calendar::windows_1900;
wb.get_properties().excel_base_date =
(workbook_pr_node.has_attribute("date1904") && workbook_pr_node.get_attribute("date1904") != "0")
? xlnt::calendar::mac_1904
: xlnt::calendar::windows_1900;
xlnt::shared_strings_serializer shared_strings_serializer_;
std::vector<std::string> shared_strings;
shared_strings_serializer_.read_shared_strings(xlnt::xml_serializer::deserialize(archive.read(xlnt::constants::ArcSharedString)), shared_strings);
for(auto shared_string : shared_strings)
shared_strings_serializer_.read_shared_strings(
xlnt::xml_serializer::deserialize(archive.read(xlnt::constants::ArcSharedString)), shared_strings);
for (auto shared_string : shared_strings)
{
wb.add_shared_string(shared_string);
}
xlnt::style_serializer style_reader_(wb);
style_reader_.read_stylesheet(xlnt::xml_serializer::deserialize(archive.read(xlnt::constants::ArcStyles)));
auto sheets_node = root_node.get_child("sheets");
for(auto sheet_node : sheets_node.get_children())
for (auto sheet_node : sheets_node.get_children())
{
auto rel = wb.get_relationship(sheet_node.get_attribute("r:id"));
auto ws = wb.create_sheet(sheet_node.get_attribute("name"), rel);
auto ws_filename = "xl/" + rel.get_target_uri();
xlnt::worksheet_serializer worksheet_serializer(ws);
worksheet_serializer.read_worksheet(xlnt::xml_serializer::deserialize(archive.read(ws_filename)));
}
return true;
}
} // namespace
namespace xlnt {
@ -107,19 +112,18 @@ const std::string excel_serializer::central_directory_signature()
std::string excel_serializer::repair_central_directory(const std::string &original)
{
auto pos = find_string_in_string(original, central_directory_signature());
if(pos != std::string::npos)
if (pos != std::string::npos)
{
return original.substr(0, pos + 22);
}
return original;
}
bool excel_serializer::load_stream_workbook(std::istream &stream, bool guess_types, bool data_only)
{
std::vector<std::uint8_t> bytes((std::istream_iterator<char>(stream)),
std::istream_iterator<char>());
std::vector<std::uint8_t> bytes((std::istream_iterator<char>(stream)), std::istream_iterator<char>());
return load_virtual_workbook(bytes, guess_types, data_only);
}
@ -130,21 +134,21 @@ bool excel_serializer::load_workbook(const std::string &filename, bool guess_typ
{
archive_.load(filename);
}
catch(std::runtime_error)
catch (std::runtime_error)
{
throw invalid_file_exception(filename);
}
return ::load_workbook(archive_, guess_types, data_only, workbook_);
}
bool excel_serializer::load_virtual_workbook(const std::vector<std::uint8_t> &bytes, bool guess_types, bool data_only)
{
archive_.load(bytes);
return ::load_workbook(archive_, guess_types, data_only, workbook_);
}
excel_serializer::excel_serializer(workbook &wb) : workbook_(wb)
{
}
@ -152,42 +156,44 @@ excel_serializer::excel_serializer(workbook &wb) : workbook_(wb)
void excel_serializer::write_data(bool /*as_template*/)
{
relationship_serializer relationship_serializer_;
relationship_serializer_.write_relationships(workbook_.get_root_relationships(), "", archive_);
relationship_serializer_.write_relationships(workbook_.get_relationships(), constants::ArcWorkbook, archive_);
xml_document properties_app_xml;
workbook_serializer workbook_serializer_(workbook_);
archive_.writestr(constants::ArcApp, xml_serializer::serialize(workbook_serializer_.write_properties_app()));
archive_.writestr(constants::ArcCore, xml_serializer::serialize(workbook_serializer_.write_properties_core()));
theme_serializer theme_serializer_;
archive_.writestr(constants::ArcTheme, theme_serializer_.write_theme(workbook_.get_loaded_theme()).to_string());
xlnt::shared_strings_serializer shared_strings_serializer_;
archive_.writestr(constants::ArcSharedString, xml_serializer::serialize(shared_strings_serializer_.write_shared_strings(workbook_.get_shared_strings())));
archive_.writestr(
constants::ArcSharedString,
xml_serializer::serialize(shared_strings_serializer_.write_shared_strings(workbook_.get_shared_strings())));
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());
manifest_serializer manifest_serializer_(workbook_.get_manifest());
archive_.writestr(constants::ArcContentTypes, manifest_serializer_.write_manifest().to_string());
write_worksheets();
}
void excel_serializer::write_worksheets()
{
std::size_t index = 0;
for(auto ws : workbook_)
for (auto ws : workbook_)
{
for(auto relationship : workbook_.get_relationships())
for (auto relationship : workbook_.get_relationships())
{
if(relationship.get_type() == relationship::type::worksheet &&
workbook::index_from_ws_filename(relationship.get_target_uri()) == index)
if (relationship.get_type() == relationship::type::worksheet &&
workbook::index_from_ws_filename(relationship.get_target_uri()) == index)
{
worksheet_serializer serializer_(ws);
std::string ws_filename = "xl/" + relationship.get_target_uri();
@ -195,21 +201,20 @@ void excel_serializer::write_worksheets()
break;
}
}
index++;
}
}
void excel_serializer::write_external_links()
{
}
bool excel_serializer::save_stream_workbook(std::ostream &stream, bool as_template)
{
write_data(as_template);
archive_.save(stream);
return true;
}
@ -225,8 +230,8 @@ bool excel_serializer::save_virtual_workbook(std::vector<std::uint8_t> &bytes, b
{
write_data(as_template);
archive_.save(bytes);
return true;
}
} // namespace xlnt

View File

@ -9,72 +9,71 @@ namespace xlnt {
manifest_serializer::manifest_serializer(manifest &m) : manifest_(m)
{
}
void manifest_serializer::read_manifest(const xml_document &xml)
{
const auto root_node = xml.get_child("Types");
for(const auto child : root_node.get_children())
for (const auto child : root_node.get_children())
{
if(child.get_name() == "Default")
if (child.get_name() == "Default")
{
manifest_.add_default_type(child.get_attribute("Extension"), child.get_attribute("ContentType"));
}
else if(child.get_name() == "Override")
else if (child.get_name() == "Override")
{
manifest_.add_override_type(child.get_attribute("PartName"), child.get_attribute("ContentType"));
}
}
}
xml_document manifest_serializer::write_manifest() const
{
xml_document xml;
auto root_node = xml.add_child("Types");
xml.add_namespace("", constants::Namespaces.at("content-types"));
for(const auto default_type : manifest_.get_default_types())
for (const auto default_type : manifest_.get_default_types())
{
auto type_node = root_node.add_child("Default");
type_node.add_attribute("Extension", default_type.get_extension());
type_node.add_attribute("ContentType", default_type.get_content_type());
}
for(const auto override_type : manifest_.get_override_types())
for (const auto override_type : manifest_.get_override_types())
{
auto type_node = root_node.add_child("Override");
type_node.add_attribute("PartName", override_type.get_part_name());
type_node.add_attribute("ContentType", override_type.get_content_type());
}
return xml;
}
std::string manifest_serializer::determine_document_type() const
{
if(!manifest_.has_override_type(constants::ArcWorkbook))
if (!manifest_.has_override_type(constants::ArcWorkbook))
{
return "unsupported";
}
std::string type = manifest_.get_override_type(constants::ArcWorkbook);
if(type == "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet.main+xml")
if (type == "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet.main+xml")
{
return "excel";
}
else if(type == "application/vnd.openxmlformats-officedocument.presentationml.presentation.main+xml")
else if (type == "application/vnd.openxmlformats-officedocument.presentationml.presentation.main+xml")
{
return "powerpoint";
}
else if(type == "application/vnd.openxmlformats-officedocument.wordprocessingml.document.main+xml")
else if (type == "application/vnd.openxmlformats-officedocument.wordprocessingml.document.main+xml")
{
return "word";
}
return "unsupported";
}

View File

@ -12,76 +12,75 @@ namespace {
std::string make_rels_name(const std::string &target)
{
const char sep = '/';
if(target.empty() || target.back() == sep)
if (target.empty() || target.back() == sep)
{
return target + "_rels/.rels";
}
auto sep_pos = target.find_last_of(sep);
auto first_part = target.substr(0, sep_pos + 1);
auto last_part = target.substr(sep_pos + 1);
return first_part + "_rels/" + last_part + ".rels";
}
}
namespace xlnt {
std::vector<relationship> relationship_serializer::read_relationships(zip_file &archive, const std::string &target)
{
xml_document xml;
xml.from_string(archive.read(make_rels_name(target)));
auto root_node = xml.get_child("Relationships");
std::vector<relationship> relationships;
for(auto relationship_node : root_node.get_children())
for (auto relationship_node : root_node.get_children())
{
if(relationship_node.get_name() != "Relationship")
if (relationship_node.get_name() != "Relationship")
{
continue;
}
std::string id = relationship_node.get_attribute("Id");
std::string type = relationship_node.get_attribute("Type");
std::string target = relationship_node.get_attribute("Target");
relationships.push_back(xlnt::relationship(type, id, target));
}
return relationships;
}
bool relationship_serializer::write_relationships(const std::vector<relationship> &relationships, const std::string &target, zip_file &archive)
bool relationship_serializer::write_relationships(const std::vector<relationship> &relationships,
const std::string &target, zip_file &archive)
{
xml_document xml;
auto root_node = xml.add_child("Relationships");
xml.add_namespace("", constants::Namespaces.at("relationships"));
for(const auto &relationship : relationships)
for (const auto &relationship : relationships)
{
auto target = relationship.get_target_uri();
auto relationship_node = root_node.add_child("Relationship");
relationship_node.add_attribute("Id", relationship.get_id());
relationship_node.add_attribute("Target", target);
relationship_node.add_attribute("Type", relationship.get_type_string());
if(relationship.get_target_mode() == target_mode::external)
if (relationship.get_target_mode() == target_mode::external)
{
relationship_node.add_attribute("TargetMode", "External");
}
}
archive.writestr(make_rels_name(target), xml.to_string());
return true;
}
}

View File

@ -3,55 +3,55 @@
#include <xlnt/s11n/xml_node.hpp>
namespace xlnt {
xml_document shared_strings_serializer::write_shared_strings(const std::vector<std::string> &strings)
{
xml_document xml;
auto root_node = xml.add_child("sst");
xml.add_namespace("", "http://schemas.openxmlformats.org/spreadsheetml/2006/main");
root_node.add_attribute("uniqueCount", std::to_string(strings.size()));
for(const auto &string : strings)
for (const auto &string : strings)
{
root_node.add_child("si").add_child("t").set_text(string);
}
return xml;
}
bool shared_strings_serializer::read_shared_strings(const xml_document &xml, std::vector<std::string> &strings)
{
strings.clear();
auto root_node = xml.get_child("sst");
auto unique_count = std::stoull(root_node.get_attribute("uniqueCount"));
for(const auto &si_node : root_node.get_children())
for (const auto &si_node : root_node.get_children())
{
if(si_node.get_name() != "si")
if (si_node.get_name() != "si")
{
continue;
}
if(si_node.has_child("t"))
if (si_node.has_child("t"))
{
strings.push_back(si_node.get_child("t").get_text());
}
else if(si_node.has_child("r"))
else if (si_node.has_child("r"))
{
strings.push_back(si_node.get_child("r").get_child("t").get_text());
}
}
if(unique_count != strings.size())
if (unique_count != strings.size())
{
throw std::runtime_error("counts don't match");
}
return true;
}

File diff suppressed because it is too large Load Diff

View File

@ -5,58 +5,51 @@
#include <detail/constants.hpp>
namespace xlnt {
//I have no idea what this stuff is. I hope it was worth it.
// I have no idea what this stuff is. I hope it was worth it.
xml_document theme_serializer::write_theme(const theme &) const
{
xml_document xml;
auto theme_node = xml.add_child("a:theme");
xml.add_namespace("a", constants::Namespaces.at("drawingml"));
theme_node.add_attribute("name", "Office Theme");
auto theme_elements_node = theme_node.add_child("a:themeElements");
auto clr_scheme_node = theme_elements_node.add_child("a:clrScheme");
clr_scheme_node.add_attribute("name", "Office");
struct scheme_element
{
std::string name;
std::string sub_element_name;
std::string val;
};
std::vector<scheme_element> scheme_elements =
{
{"a:dk1", "a:sysClr", "windowText"},
{"a:lt1", "a:sysClr", "window"},
{"a:dk2", "a:srgbClr", "1F497D"},
{"a:lt2", "a:srgbClr", "EEECE1"},
{"a:accent1", "a:srgbClr", "4F81BD"},
{"a:accent2", "a:srgbClr", "C0504D"},
{"a:accent3", "a:srgbClr", "9BBB59"},
{"a:accent4", "a:srgbClr", "8064A2"},
{"a:accent5", "a:srgbClr", "4BACC6"},
{"a:accent6", "a:srgbClr", "F79646"},
{"a:hlink", "a:srgbClr", "0000FF"},
{"a:folHlink", "a:srgbClr", "800080"},
std::vector<scheme_element> scheme_elements = {
{ "a:dk1", "a:sysClr", "windowText" }, { "a:lt1", "a:sysClr", "window" },
{ "a:dk2", "a:srgbClr", "1F497D" }, { "a:lt2", "a:srgbClr", "EEECE1" },
{ "a:accent1", "a:srgbClr", "4F81BD" }, { "a:accent2", "a:srgbClr", "C0504D" },
{ "a:accent3", "a:srgbClr", "9BBB59" }, { "a:accent4", "a:srgbClr", "8064A2" },
{ "a:accent5", "a:srgbClr", "4BACC6" }, { "a:accent6", "a:srgbClr", "F79646" },
{ "a:hlink", "a:srgbClr", "0000FF" }, { "a:folHlink", "a:srgbClr", "800080" },
};
for(auto element : scheme_elements)
for (auto element : scheme_elements)
{
auto element_node = clr_scheme_node.add_child(element.name);
element_node.add_child(element.sub_element_name).add_attribute("val", element.val);
if(element.name == "a:dk1")
if (element.name == "a:dk1")
{
element_node.get_child(element.sub_element_name).add_attribute("lastClr", "000000");
}
else if(element.name == "a:lt1")
else if (element.name == "a:lt1")
{
element_node.get_child(element.sub_element_name).add_attribute("lastClr", "FFFFFF");
}
}
struct font_scheme
{
bool typeface;
@ -64,56 +57,58 @@ xml_document theme_serializer::write_theme(const theme &) const
std::string major;
std::string minor;
};
std::vector<font_scheme> font_schemes =
{
{true, "a:latin", "Cambria", "Calibri"},
{true, "a:ea", "", ""},
{true, "a:cs", "", ""},
{false, "Jpan", "\xef\xbc\xad\xef\xbc\xb3 \xef\xbc\xb0\xe3\x82\xb4\xe3\x82\xb7\xe3\x83\x83\xe3\x82\xaf", "\xef\xbc\xad\xef\xbc\xb3 \xef\xbc\xb0\xe3\x82\xb4\xe3\x82\xb7\xe3\x83\x83\xe3\x82\xaf"},
{false, "Hang", "\xeb\xa7\x91\xec\x9d\x80 \xea\xb3\xa0\xeb\x94\x95", "\xeb\xa7\x91\xec\x9d\x80 \xea\xb3\xa0\xeb\x94\x95"},
{false, "Hans", "\xe5\xae\x8b\xe4\xbd\x93", "\xe5\xae\x8b\xe4\xbd\x93"},
{false, "Hant", "\xe6\x96\xb0\xe7\xb4\xb0\xe6\x98\x8e\xe9\xab\x94", "\xe6\x96\xb0\xe7\xb4\xb0\xe6\x98\x8e\xe9\xab\x94"},
{false, "Arab", "Times New Roman", "Arial"},
{false, "Hebr", "Times New Roman", "Arial"},
{false, "Thai", "Tahoma", "Tahoma"},
{false, "Ethi", "Nyala", "Nyala"},
{false, "Beng", "Vrinda", "Vrinda"},
{false, "Gujr", "Shruti", "Shruti"},
{false, "Khmr", "MoolBoran", "DaunPenh"},
{false, "Knda", "Tunga", "Tunga"},
{false, "Guru", "Raavi", "Raavi"},
{false, "Cans", "Euphemia", "Euphemia"},
{false, "Cher", "Plantagenet Cherokee", "Plantagenet Cherokee"},
{false, "Yiii", "Microsoft Yi Baiti", "Microsoft Yi Baiti"},
{false, "Tibt", "Microsoft Himalaya", "Microsoft Himalaya"},
{false, "Thaa", "MV Boli", "MV Boli"},
{false, "Deva", "Mangal", "Mangal"},
{false, "Telu", "Gautami", "Gautami"},
{false, "Taml", "Latha", "Latha"},
{false, "Syrc", "Estrangelo Edessa", "Estrangelo Edessa"},
{false, "Orya", "Kalinga", "Kalinga"},
{false, "Mlym", "Kartika", "Kartika"},
{false, "Laoo", "DokChampa", "DokChampa"},
{false, "Sinh", "Iskoola Pota", "Iskoola Pota"},
{false, "Mong", "Mongolian Baiti", "Mongolian Baiti"},
{false, "Viet", "Times New Roman", "Arial"},
{false, "Uigh", "Microsoft Uighur", "Microsoft Uighur"}
std::vector<font_scheme> font_schemes = {
{ true, "a:latin", "Cambria", "Calibri" },
{ true, "a:ea", "", "" },
{ true, "a:cs", "", "" },
{ false, "Jpan", "\xef\xbc\xad\xef\xbc\xb3 \xef\xbc\xb0\xe3\x82\xb4\xe3\x82\xb7\xe3\x83\x83\xe3\x82\xaf",
"\xef\xbc\xad\xef\xbc\xb3 \xef\xbc\xb0\xe3\x82\xb4\xe3\x82\xb7\xe3\x83\x83\xe3\x82\xaf" },
{ false, "Hang", "\xeb\xa7\x91\xec\x9d\x80 \xea\xb3\xa0\xeb\x94\x95",
"\xeb\xa7\x91\xec\x9d\x80 \xea\xb3\xa0\xeb\x94\x95" },
{ false, "Hans", "\xe5\xae\x8b\xe4\xbd\x93", "\xe5\xae\x8b\xe4\xbd\x93" },
{ false, "Hant", "\xe6\x96\xb0\xe7\xb4\xb0\xe6\x98\x8e\xe9\xab\x94",
"\xe6\x96\xb0\xe7\xb4\xb0\xe6\x98\x8e\xe9\xab\x94" },
{ false, "Arab", "Times New Roman", "Arial" },
{ false, "Hebr", "Times New Roman", "Arial" },
{ false, "Thai", "Tahoma", "Tahoma" },
{ false, "Ethi", "Nyala", "Nyala" },
{ false, "Beng", "Vrinda", "Vrinda" },
{ false, "Gujr", "Shruti", "Shruti" },
{ false, "Khmr", "MoolBoran", "DaunPenh" },
{ false, "Knda", "Tunga", "Tunga" },
{ false, "Guru", "Raavi", "Raavi" },
{ false, "Cans", "Euphemia", "Euphemia" },
{ false, "Cher", "Plantagenet Cherokee", "Plantagenet Cherokee" },
{ false, "Yiii", "Microsoft Yi Baiti", "Microsoft Yi Baiti" },
{ false, "Tibt", "Microsoft Himalaya", "Microsoft Himalaya" },
{ false, "Thaa", "MV Boli", "MV Boli" },
{ false, "Deva", "Mangal", "Mangal" },
{ false, "Telu", "Gautami", "Gautami" },
{ false, "Taml", "Latha", "Latha" },
{ false, "Syrc", "Estrangelo Edessa", "Estrangelo Edessa" },
{ false, "Orya", "Kalinga", "Kalinga" },
{ false, "Mlym", "Kartika", "Kartika" },
{ false, "Laoo", "DokChampa", "DokChampa" },
{ false, "Sinh", "Iskoola Pota", "Iskoola Pota" },
{ false, "Mong", "Mongolian Baiti", "Mongolian Baiti" },
{ false, "Viet", "Times New Roman", "Arial" },
{ false, "Uigh", "Microsoft Uighur", "Microsoft Uighur" }
};
auto font_scheme_node = theme_elements_node.add_child("a:fontScheme");
font_scheme_node.add_attribute("name", "Office");
auto major_fonts_node = font_scheme_node.add_child("a:majorFont");
auto minor_fonts_node = font_scheme_node.add_child("a:minorFont");
for(auto scheme : font_schemes)
for (auto scheme : font_schemes)
{
if(scheme.typeface)
if (scheme.typeface)
{
auto major_font_node = major_fonts_node.add_child(scheme.script);
major_font_node.add_attribute("typeface", scheme.major);
auto minor_font_node = minor_fonts_node.add_child(scheme.script);
minor_font_node.add_attribute("typeface", scheme.minor);
}
@ -122,22 +117,22 @@ xml_document theme_serializer::write_theme(const theme &) const
auto major_font_node = major_fonts_node.add_child("a:font");
major_font_node.add_attribute("script", scheme.script);
major_font_node.add_attribute("typeface", scheme.major);
auto minor_font_node = minor_fonts_node.add_child("a:font");
minor_font_node.add_attribute("script", scheme.script);
minor_font_node.add_attribute("typeface", scheme.minor);
}
}
auto format_scheme_node = theme_elements_node.add_child("a:fmtScheme");
format_scheme_node.add_attribute("name", "Office");
auto fill_style_list_node = format_scheme_node.add_child("a:fillStyleLst");
fill_style_list_node.add_child("a:solidFill").add_child("a:schemeClr").add_attribute("val", "phClr");
auto grad_fill_node = fill_style_list_node.add_child("a:gradFill");
grad_fill_node.add_attribute("rotWithShape", "1");
auto grad_fill_list = grad_fill_node.add_child("a:gsLst");
auto gs_node = grad_fill_list.add_child("a:gs");
gs_node.add_attribute("pos", "0");
@ -145,28 +140,28 @@ xml_document theme_serializer::write_theme(const theme &) const
scheme_color_node.add_attribute("val", "phClr");
scheme_color_node.add_child("a:tint").add_attribute("val", "50000");
scheme_color_node.add_child("a:satMod").add_attribute("val", "300000");
gs_node = grad_fill_list.add_child("a:gs");
gs_node.add_attribute("pos", "35000");
scheme_color_node = gs_node.add_child("a:schemeClr");
scheme_color_node.add_attribute("val", "phClr");
scheme_color_node.add_child("a:tint").add_attribute("val", "37000");
scheme_color_node.add_child("a:satMod").add_attribute("val", "300000");
gs_node = grad_fill_list.add_child("a:gs");
gs_node.add_attribute("pos", "100000");
scheme_color_node = gs_node.add_child("a:schemeClr");
scheme_color_node.add_attribute("val", "phClr");
scheme_color_node.add_child("a:tint").add_attribute("val", "15000");
scheme_color_node.add_child("a:satMod").add_attribute("val", "350000");
auto lin_node = grad_fill_node.add_child("a:lin");
lin_node.add_attribute("ang", "16200000");
lin_node.add_attribute("scaled", "1");
grad_fill_node = fill_style_list_node.add_child("a:gradFill");
grad_fill_node.add_attribute("rotWithShape", "1");
grad_fill_list = grad_fill_node.add_child("a:gsLst");
gs_node = grad_fill_list.add_child("a:gs");
gs_node.add_attribute("pos", "0");
@ -174,62 +169,62 @@ xml_document theme_serializer::write_theme(const theme &) const
scheme_color_node.add_attribute("val", "phClr");
scheme_color_node.add_child("a:shade").add_attribute("val", "51000");
scheme_color_node.add_child("a:satMod").add_attribute("val", "130000");
gs_node = grad_fill_list.add_child("a:gs");
gs_node.add_attribute("pos", "80000");
scheme_color_node = gs_node.add_child("a:schemeClr");
scheme_color_node.add_attribute("val", "phClr");
scheme_color_node.add_child("a:shade").add_attribute("val", "93000");
scheme_color_node.add_child("a:satMod").add_attribute("val", "130000");
gs_node = grad_fill_list.add_child("a:gs");
gs_node.add_attribute("pos", "100000");
scheme_color_node = gs_node.add_child("a:schemeClr");
scheme_color_node.add_attribute("val", "phClr");
scheme_color_node.add_child("a:shade").add_attribute("val", "94000");
scheme_color_node.add_child("a:satMod").add_attribute("val", "135000");
lin_node = grad_fill_node.add_child("a:lin");
lin_node.add_attribute("ang", "16200000");
lin_node.add_attribute("scaled", "0");
auto line_style_list_node = format_scheme_node.add_child("a:lnStyleLst");
auto ln_node = line_style_list_node.add_child("a:ln");
ln_node.add_attribute("w", "9525");
ln_node.add_attribute("cap", "flat");
ln_node.add_attribute("cmpd", "sng");
ln_node.add_attribute("algn", "ctr");
auto solid_fill_node = ln_node.add_child("a:solidFill");
scheme_color_node = solid_fill_node.add_child("a:schemeClr");
scheme_color_node.add_attribute("val", "phClr");
scheme_color_node.add_child("a:shade").add_attribute("val", "95000");
scheme_color_node.add_child("a:satMod").add_attribute("val", "105000");
ln_node.add_child("a:prstDash").add_attribute("val", "solid");
ln_node = line_style_list_node.add_child("a:ln");
ln_node.add_attribute("w", "25400");
ln_node.add_attribute("cap", "flat");
ln_node.add_attribute("cmpd", "sng");
ln_node.add_attribute("algn", "ctr");
solid_fill_node = ln_node.add_child("a:solidFill");
scheme_color_node = solid_fill_node.add_child("a:schemeClr");
scheme_color_node.add_attribute("val", "phClr");
ln_node.add_child("a:prstDash").add_attribute("val", "solid");
ln_node = line_style_list_node.add_child("a:ln");
ln_node.add_attribute("w", "38100");
ln_node.add_attribute("cap", "flat");
ln_node.add_attribute("cmpd", "sng");
ln_node.add_attribute("algn", "ctr");
solid_fill_node = ln_node.add_child("a:solidFill");
scheme_color_node = solid_fill_node.add_child("a:schemeClr");
scheme_color_node.add_attribute("val", "phClr");
ln_node.add_child("a:prstDash").add_attribute("val", "solid");
auto effect_style_list_node = format_scheme_node.add_child("a:effectStyleLst");
auto effect_style_node = effect_style_list_node.add_child("a:effectStyle");
auto effect_list_node = effect_style_node.add_child("a:effectLst");
@ -241,7 +236,7 @@ xml_document theme_serializer::write_theme(const theme &) const
auto srgb_clr_node = outer_shadow_node.add_child("a:srgbClr");
srgb_clr_node.add_attribute("val", "000000");
srgb_clr_node.add_child("a:alpha").add_attribute("val", "38000");
effect_style_node = effect_style_list_node.add_child("a:effectStyle");
effect_list_node = effect_style_node.add_child("a:effectLst");
outer_shadow_node = effect_list_node.add_child("a:outerShdw");
@ -252,7 +247,7 @@ xml_document theme_serializer::write_theme(const theme &) const
srgb_clr_node = outer_shadow_node.add_child("a:srgbClr");
srgb_clr_node.add_attribute("val", "000000");
srgb_clr_node.add_child("a:alpha").add_attribute("val", "35000");
effect_style_node = effect_style_list_node.add_child("a:effectStyle");
effect_list_node = effect_style_node.add_child("a:effectLst");
outer_shadow_node = effect_list_node.add_child("a:outerShdw");
@ -277,18 +272,18 @@ xml_document theme_serializer::write_theme(const theme &) const
rot_node.add_attribute("lat", "0");
rot_node.add_attribute("lon", "0");
rot_node.add_attribute("rev", "1200000");
auto bevel_node = effect_style_node.add_child("a:sp3d").add_child("a:bevelT");
bevel_node.add_attribute("w", "63500");
bevel_node.add_attribute("h", "25400");
auto bg_fill_style_list_node = format_scheme_node.add_child("a:bgFillStyleLst");
bg_fill_style_list_node.add_child("a:solidFill").add_child("a:schemeClr").add_attribute("val", "phClr");
grad_fill_node = bg_fill_style_list_node.add_child("a:gradFill");
grad_fill_node.add_attribute("rotWithShape", "1");
grad_fill_list = grad_fill_node.add_child("a:gsLst");
gs_node = grad_fill_list.add_child("a:gs");
gs_node.add_attribute("pos", "0");
@ -296,7 +291,7 @@ xml_document theme_serializer::write_theme(const theme &) const
scheme_color_node.add_attribute("val", "phClr");
scheme_color_node.add_child("a:tint").add_attribute("val", "40000");
scheme_color_node.add_child("a:satMod").add_attribute("val", "350000");
gs_node = grad_fill_list.add_child("a:gs");
gs_node.add_attribute("pos", "40000");
scheme_color_node = gs_node.add_child("a:schemeClr");
@ -304,14 +299,14 @@ xml_document theme_serializer::write_theme(const theme &) const
scheme_color_node.add_child("a:tint").add_attribute("val", "45000");
scheme_color_node.add_child("a:shade").add_attribute("val", "99000");
scheme_color_node.add_child("a:satMod").add_attribute("val", "350000");
gs_node = grad_fill_list.add_child("a:gs");
gs_node.add_attribute("pos", "100000");
scheme_color_node = gs_node.add_child("a:schemeClr");
scheme_color_node.add_attribute("val", "phClr");
scheme_color_node.add_child("a:shade").add_attribute("val", "20000");
scheme_color_node.add_child("a:satMod").add_attribute("val", "255000");
auto path_node = grad_fill_node.add_child("a:path");
path_node.add_attribute("path", "circle");
auto fill_to_rect_node = path_node.add_child("a:fillToRect");
@ -319,10 +314,10 @@ xml_document theme_serializer::write_theme(const theme &) const
fill_to_rect_node.add_attribute("t", "-80000");
fill_to_rect_node.add_attribute("r", "50000");
fill_to_rect_node.add_attribute("b", "180000");
grad_fill_node = bg_fill_style_list_node.add_child("a:gradFill");
grad_fill_node.add_attribute("rotWithShape", "1");
grad_fill_list = grad_fill_node.add_child("a:gsLst");
gs_node = grad_fill_list.add_child("a:gs");
gs_node.add_attribute("pos", "0");
@ -330,14 +325,14 @@ xml_document theme_serializer::write_theme(const theme &) const
scheme_color_node.add_attribute("val", "phClr");
scheme_color_node.add_child("a:tint").add_attribute("val", "80000");
scheme_color_node.add_child("a:satMod").add_attribute("val", "300000");
gs_node = grad_fill_list.add_child("a:gs");
gs_node.add_attribute("pos", "100000");
scheme_color_node = gs_node.add_child("a:schemeClr");
scheme_color_node.add_attribute("val", "phClr");
scheme_color_node.add_child("a:shade").add_attribute("val", "30000");
scheme_color_node.add_child("a:satMod").add_attribute("val", "200000");
path_node = grad_fill_node.add_child("a:path");
path_node.add_attribute("path", "circle");
fill_to_rect_node = path_node.add_child("a:fillToRect");
@ -345,11 +340,11 @@ xml_document theme_serializer::write_theme(const theme &) const
fill_to_rect_node.add_attribute("t", "50000");
fill_to_rect_node.add_attribute("r", "50000");
fill_to_rect_node.add_attribute("b", "50000");
theme_node.add_child("a:objectDefaults");
theme_node.add_child("a:extraClrSchemeLst");
return xml;
}
} // namespace xlnt

View File

@ -16,7 +16,7 @@
#include "detail/constants.hpp"
namespace {
xlnt::datetime w3cdtf_to_datetime(const std::string &string)
{
xlnt::datetime result(1900, 1, 1);
@ -33,20 +33,22 @@ xlnt::datetime w3cdtf_to_datetime(const std::string &string)
result.second = std::stoi(string.substr(separator_index + 1, string.find('Z', separator_index + 1)));
return result;
}
std::string fill(const std::string &string, std::size_t length = 2)
{
if(string.size() >= length)
if (string.size() >= length)
{
return string;
}
return std::string(length - string.size(), '0') + string;
}
std::string datetime_to_w3cdtf(const xlnt::datetime &dt)
{
return std::to_string(dt.year) + "-" + fill(std::to_string(dt.month)) + "-" + fill(std::to_string(dt.day)) + "T" + fill(std::to_string(dt.hour)) + ":" + fill(std::to_string(dt.minute)) + ":" + fill(std::to_string(dt.second)) + "Z";
return std::to_string(dt.year) + "-" + fill(std::to_string(dt.month)) + "-" + fill(std::to_string(dt.day)) + "T" +
fill(std::to_string(dt.hour)) + ":" + fill(std::to_string(dt.minute)) + ":" +
fill(std::to_string(dt.second)) + "Z";
}
} // namespace
@ -56,16 +58,16 @@ namespace xlnt {
workbook_serializer::workbook_serializer(workbook &wb) : workbook_(wb)
{
}
std::vector<workbook_serializer::string_pair> workbook_serializer::read_sheets()
{
/*
std::string ns;
for(auto child : doc.children())
{
std::string name = child.name();
if(name.find(':') != std::string::npos)
{
auto colon_index = name.find(':');
@ -73,9 +75,9 @@ std::vector<workbook_serializer::string_pair> workbook_serializer::read_sheets()
break;
}
}
auto with_ns = [&](const std::string &base) { return ns.empty() ? base : ns + ":" + base; };
auto root_node = doc.get_child(with_ns("workbook"));
auto sheets_node = root_node.get_child(with_ns("sheets"));
*/
@ -83,7 +85,7 @@ std::vector<workbook_serializer::string_pair> workbook_serializer::read_sheets()
/*
// store temp because pugixml iteration uses the internal char array multiple times
auto sheet_element_name = with_ns("sheet");
for(auto sheet_node : sheets_node.children(sheet_element_name))
{
std::string id = sheet_node.attribute("r:id").as_string();
@ -98,23 +100,23 @@ void workbook_serializer::read_properties_core(const xml_document &xml)
{
auto &props = workbook_.get_properties();
auto root_node = xml.get_child("dc:coreProperties");
props.excel_base_date = calendar::windows_1900;
if(root_node.has_child("dc:creator"))
if (root_node.has_child("dc:creator"))
{
props.creator = root_node.get_child("dc:creator").get_text();
}
if(root_node.has_child("cp:lastModifiedBy"))
if (root_node.has_child("cp:lastModifiedBy"))
{
props.last_modified_by = root_node.get_child("cp:lastModifiedBy").get_text();
}
if(root_node.has_child("dcterms:created"))
if (root_node.has_child("dcterms:created"))
{
std::string created_string = root_node.get_child("dcterms:created").get_text();
props.created = w3cdtf_to_datetime(created_string);
}
if(root_node.has_child("dcterms:modified"))
if (root_node.has_child("dcterms:modified"))
{
std::string modified_string = root_node.get_child("dcterms:modified").get_text();
props.modified = w3cdtf_to_datetime(modified_string);
@ -129,49 +131,51 @@ void workbook_serializer::read_properties_core(const xml_document &xml)
/// </summary>
std::vector<workbook_serializer::string_pair> workbook_serializer::detect_worksheets()
{
static const std::string ValidWorksheet = "application/vnd.openxmlformats-officedocument.spreadsheetml.worksheet+xml";
static const std::string ValidWorksheet =
"application/vnd.openxmlformats-officedocument.spreadsheetml.worksheet+xml";
std::vector<std::string> valid_sheets;
for(const auto &content_type : workbook_.get_manifest().get_override_types())
for (const auto &content_type : workbook_.get_manifest().get_override_types())
{
if(content_type.get_content_type() == ValidWorksheet)
if (content_type.get_content_type() == ValidWorksheet)
{
valid_sheets.push_back(content_type.get_part_name());
}
}
auto &workbook_relationships = workbook_.get_relationships();
std::vector<std::pair<std::string, std::string>> result;
for(const auto &ws : read_sheets())
for (const auto &ws : read_sheets())
{
auto rel = *std::find_if(workbook_relationships.begin(), workbook_relationships.end(), [&](const relationship &r) { return r.get_id() == ws.first; });
auto rel = *std::find_if(workbook_relationships.begin(), workbook_relationships.end(),
[&](const relationship &r) { return r.get_id() == ws.first; });
auto target = rel.get_target_uri();
if(std::find(valid_sheets.begin(), valid_sheets.end(), "/" + target) != valid_sheets.end())
if (std::find(valid_sheets.begin(), valid_sheets.end(), "/" + target) != valid_sheets.end())
{
result.push_back({target, ws.second});
result.push_back({ target, ws.second });
}
}
return result;
}
xml_document workbook_serializer::write_properties_core() const
{
auto &props = workbook_.get_properties();
xml_document xml;
auto root_node = xml.add_child("cp:coreProperties");
xml.add_namespace("cp", "http://schemas.openxmlformats.org/package/2006/metadata/core-properties");
xml.add_namespace("dc", "http://purl.org/dc/elements/1.1/");
xml.add_namespace("dcmitype", "http://purl.org/dc/dcmitype/");
xml.add_namespace("dcterms", "http://purl.org/dc/terms/");
xml.add_namespace("xsi", "http://www.w3.org/2001/XMLSchema-instance");
root_node.add_child("dc:creator").set_text(props.creator);
root_node.add_child("cp:lastModifiedBy").set_text(props.last_modified_by);
root_node.add_child("dcterms:created").set_text(datetime_to_w3cdtf(props.created));
@ -183,19 +187,19 @@ xml_document workbook_serializer::write_properties_core() const
root_node.add_child("dc:subject");
root_node.add_child("cp:keywords");
root_node.add_child("cp:category");
return xml;
}
xml_document workbook_serializer::write_properties_app() const
{
xml_document xml;
auto root_node = xml.add_child("Properties");
xml.add_namespace("", "http://schemas.openxmlformats.org/officeDocument/2006/extended-properties");
xml.add_namespace("vt", "http://schemas.openxmlformats.org/officeDocument/2006/docPropsVTypes");
root_node.add_child("Application").set_text("Microsoft Excel");
root_node.add_child("DocSecurity").set_text("0");
root_node.add_child("ScaleCrop").set_text("false");
@ -204,20 +208,22 @@ xml_document workbook_serializer::write_properties_app() const
root_node.add_child("SharedDoc").set_text("false");
root_node.add_child("HyperlinksChanged").set_text("false");
root_node.add_child("AppVersion").set_text("12.0000");
auto heading_pairs_node = root_node.add_child("HeadingPairs");
auto heading_pairs_vector_node = heading_pairs_node.add_child("vt:vector");
heading_pairs_vector_node.add_attribute("baseType", "variant");
heading_pairs_vector_node.add_attribute("size", "2");
heading_pairs_vector_node.add_child("vt:variant").add_child("vt:lpstr").set_text("Worksheets");
heading_pairs_vector_node.add_child("vt:variant").add_child("vt:i4").set_text(std::to_string(workbook_.get_sheet_names().size()));
heading_pairs_vector_node.add_child("vt:variant")
.add_child("vt:i4")
.set_text(std::to_string(workbook_.get_sheet_names().size()));
auto titles_of_parts_node = root_node.add_child("TitlesOfParts");
auto titles_of_parts_vector_node = titles_of_parts_node.add_child("vt:vector");
titles_of_parts_vector_node.add_attribute("baseType", "lpstr");
titles_of_parts_vector_node.add_attribute("size", std::to_string(workbook_.get_sheet_names().size()));
for(auto ws : workbook_)
for (auto ws : workbook_)
{
titles_of_parts_vector_node.add_child("vt:lpstr").set_text(ws.get_title());
}
@ -228,38 +234,39 @@ xml_document workbook_serializer::write_properties_app() const
xml_document workbook_serializer::write_workbook() const
{
std::size_t num_visible = 0;
for(auto ws : workbook_)
for (auto ws : workbook_)
{
if(ws.get_page_setup().get_sheet_state() == xlnt::page_setup::sheet_state::visible)
if (ws.get_page_setup().get_sheet_state() == xlnt::page_setup::sheet_state::visible)
{
num_visible++;
}
}
if(num_visible == 0)
if (num_visible == 0)
{
throw xlnt::value_error();
}
xml_document xml;
auto root_node = xml.add_child("workbook");
xml.add_namespace("", "http://schemas.openxmlformats.org/spreadsheetml/2006/main");
xml.add_namespace("r", "http://schemas.openxmlformats.org/officeDocument/2006/relationships");
auto file_version_node = root_node.add_child("fileVersion");
file_version_node.add_attribute("appName", "xl");
file_version_node.add_attribute("lastEdited", "4");
file_version_node.add_attribute("lowestEdited", "4");
file_version_node.add_attribute("rupBuild", "4505");
auto workbook_pr_node = root_node.add_child("workbookPr");
workbook_pr_node.add_attribute("codeName", "ThisWorkbook");
workbook_pr_node.add_attribute("defaultThemeVersion", "124226");
workbook_pr_node.add_attribute("date1904", workbook_.get_properties().excel_base_date == calendar::mac_1904 ? "1" : "0");
workbook_pr_node.add_attribute("date1904",
workbook_.get_properties().excel_base_date == calendar::mac_1904 ? "1" : "0");
auto book_views_node = root_node.add_child("bookViews");
auto workbook_view_node = book_views_node.add_child("workbookView");
workbook_view_node.add_attribute("activeTab", "0");
@ -271,57 +278,59 @@ xml_document workbook_serializer::write_workbook() const
workbook_view_node.add_attribute("showVerticalScroll", "1");
workbook_view_node.add_attribute("tabRatio", "600");
workbook_view_node.add_attribute("visibility", "visible");
auto sheets_node = root_node.add_child("sheets");
auto defined_names_node = root_node.add_child("definedNames");
for(const auto &relationship : workbook_.get_relationships())
for (const auto &relationship : workbook_.get_relationships())
{
if(relationship.get_type() == relationship::type::worksheet)
if (relationship.get_type() == relationship::type::worksheet)
{
//TODO: this is ugly
// TODO: this is ugly
std::string sheet_index_string = relationship.get_target_uri();
sheet_index_string = sheet_index_string.substr(0, sheet_index_string.find('.'));
sheet_index_string = sheet_index_string.substr(sheet_index_string.find_last_of('/'));
auto iter = sheet_index_string.end();
iter--;
while (isdigit(*iter)) iter--;
while (isdigit(*iter))
iter--;
auto first_digit = iter - sheet_index_string.begin();
sheet_index_string = sheet_index_string.substr(static_cast<std::string::size_type>(first_digit + 1));
std::size_t sheet_index = static_cast<std::size_t>(std::stoll(sheet_index_string) - 1);
auto ws = workbook_.get_sheet_by_index(sheet_index);
auto sheet_node = sheets_node.add_child("sheet");
sheet_node.add_attribute("name", ws.get_title());
sheet_node.add_attribute("sheetId", std::to_string(sheet_index + 1));
sheet_node.add_attribute("r:id", relationship.get_id());
if(ws.has_auto_filter())
if (ws.has_auto_filter())
{
auto defined_name_node = defined_names_node.add_child("definedName");
defined_name_node.add_attribute("name", "_xlnm._FilterDatabase");
defined_name_node.add_attribute("hidden", "1");
defined_name_node.add_attribute("localSheetId", "0");
std::string name = "'" + ws.get_title() + "'!" + range_reference::make_absolute(ws.get_auto_filter()).to_string();
std::string name =
"'" + ws.get_title() + "'!" + range_reference::make_absolute(ws.get_auto_filter()).to_string();
defined_name_node.set_text(name);
}
}
}
auto calc_pr_node = root_node.add_child("calcPr");
calc_pr_node.add_attribute("calcId", "124519");
calc_pr_node.add_attribute("calcMode", "auto");
calc_pr_node.add_attribute("fullCalcOnLoad", "1");
return xml;
}
xml_node workbook_serializer::write_named_ranges() const
{
xlnt::xml_node named_ranges_node;
for(auto &named_range : workbook_.get_named_ranges())
for (auto &named_range : workbook_.get_named_ranges())
{
named_ranges_node.add_child(named_range.get_name());
}

View File

@ -7,10 +7,12 @@
#include <xlnt/s11n/xml_document.hpp>
#include <xlnt/s11n/xml_node.hpp>
#include <xlnt/workbook/workbook.hpp>
#include <xlnt/worksheet/column_properties.hpp>
#include <xlnt/worksheet/range.hpp>
#include <xlnt/worksheet/range_reference.hpp>
#include <xlnt/worksheet/row_properties.hpp>
#include "detail/constants.hpp"
#include <detail/constants.hpp>
namespace {
@ -18,7 +20,7 @@ bool is_integral(long double d)
{
return d == static_cast<long long int>(d);
}
} // namepsace
namespace xlnt {
@ -26,61 +28,61 @@ namespace xlnt {
worksheet_serializer::worksheet_serializer(worksheet sheet) : sheet_(sheet)
{
}
bool worksheet_serializer::read_worksheet(const xml_document &xml)
{
auto &root_node = xml.get_child("worksheet");
auto &dimension_node = root_node.get_child("dimension");
std::string dimension = dimension_node.get_attribute("ref");
auto full_range = xlnt::range_reference(dimension);
auto sheet_data_node = root_node.get_child("sheetData");
if(root_node.has_child("mergeCells"))
if (root_node.has_child("mergeCells"))
{
auto merge_cells_node = root_node.get_child("mergeCells");
auto count = std::stoull(merge_cells_node.get_attribute("count"));
for(auto merge_cell_node : merge_cells_node.get_children())
for (auto merge_cell_node : merge_cells_node.get_children())
{
if(merge_cell_node.get_name() != "mergeCell")
if (merge_cell_node.get_name() != "mergeCell")
{
continue;
}
sheet_.merge_cells(merge_cell_node.get_attribute("ref"));
count--;
}
if(count != 0)
if (count != 0)
{
throw std::runtime_error("mismatch between count and actual number of merged cells");
}
}
auto &shared_strings = sheet_.get_parent().get_shared_strings();
for(auto row_node : sheet_data_node.get_children())
for (auto row_node : sheet_data_node.get_children())
{
if(row_node.get_name() != "row")
if (row_node.get_name() != "row")
{
continue;
}
auto row_index = static_cast<row_t>(std::stoull(row_node.get_attribute("r")));
if(row_node.has_attribute("ht"))
if (row_node.has_attribute("ht"))
{
sheet_.get_row_properties(row_index).height = std::stold(row_node.get_attribute("ht"));
}
std::string span_string = row_node.get_attribute("spans");
auto colon_index = span_string.find(':');
column_t min_column = 0;
column_t max_column = 0;
if(colon_index != std::string::npos)
if (colon_index != std::string::npos)
{
min_column = static_cast<column_t>(std::stoll(span_string.substr(0, colon_index)));
max_column = static_cast<column_t>(std::stoll(span_string.substr(colon_index + 1)));
@ -90,73 +92,74 @@ bool worksheet_serializer::read_worksheet(const xml_document &xml)
min_column = static_cast<column_t>(full_range.get_top_left().get_column_index());
max_column = static_cast<column_t>(full_range.get_bottom_right().get_column_index());
}
for(column_t i = min_column; i <= max_column; i++)
for (column_t i = min_column; i <= max_column; i++)
{
std::string address = xlnt::cell_reference::column_string_from_index(i) + std::to_string(row_index);
xml_node cell_node;
bool cell_found = false;
for(auto &check_cell_node : row_node.get_children())
for (auto &check_cell_node : row_node.get_children())
{
if(check_cell_node.get_name() != "c")
if (check_cell_node.get_name() != "c")
{
continue;
}
if(check_cell_node.has_attribute("r") && check_cell_node.get_attribute("r") == address)
if (check_cell_node.has_attribute("r") && check_cell_node.get_attribute("r") == address)
{
cell_node = check_cell_node;
cell_found = true;
break;
}
}
if(cell_found)
if (cell_found)
{
bool has_value = cell_node.has_child("v");
std::string value_string = has_value ? cell_node.get_child("v").get_text() : "";
bool has_type = cell_node.has_attribute("t");
std::string type = has_type ? cell_node.get_attribute("t") : "";
bool has_style = cell_node.has_attribute("s");
int style_id = has_style ? std::stoull(cell_node.get_attribute("s")) : 0;
bool has_formula = cell_node.has_child("f");
bool has_shared_formula = has_formula && cell_node.get_child("f").has_attribute("t") && cell_node.get_child("f").get_attribute("t") == "shared";
bool has_shared_formula = has_formula && cell_node.get_child("f").has_attribute("t") &&
cell_node.get_child("f").get_attribute("t") == "shared";
auto cell = sheet_.get_cell(address);
if(has_formula && !has_shared_formula && !sheet_.get_parent().get_data_only())
if (has_formula && !has_shared_formula && !sheet_.get_parent().get_data_only())
{
std::string formula = cell_node.get_child("f").get_text();
cell.set_formula(formula);
}
if(has_type && type == "inlineStr") // inline string
if (has_type && type == "inlineStr") // inline string
{
std::string inline_string = cell_node.get_child("is").get_child("t").get_text();
cell.set_value(inline_string);
}
else if(has_type && type == "s" && !has_formula) // shared string
else if (has_type && type == "s" && !has_formula) // shared string
{
auto shared_string_index = std::stoull(value_string);
auto shared_string = shared_strings.at(shared_string_index);
cell.set_value(shared_string);
}
else if(has_type && type == "b") // boolean
else if (has_type && type == "b") // boolean
{
cell.set_value(value_string != "0");
}
else if(has_type && type == "str")
else if (has_type && type == "str")
{
cell.set_value(value_string);
}
else if(has_value && !value_string.empty())
else if (has_value && !value_string.empty())
{
if(!value_string.empty() && value_string[0] == '#')
if (!value_string.empty() && value_string[0] == '#')
{
cell.set_error(value_string);
}
@ -165,103 +168,103 @@ bool worksheet_serializer::read_worksheet(const xml_document &xml)
cell.set_value(std::stold(value_string));
}
}
if(has_style)
if (has_style)
{
cell.set_style_id(style_id);
}
}
}
}
auto &cols_node = root_node.get_child("cols");
for(auto col_node : cols_node.get_children())
for (auto col_node : cols_node.get_children())
{
if(col_node.get_name() != "col")
if (col_node.get_name() != "col")
{
continue;
}
auto min = static_cast<column_t>(std::stoull(col_node.get_attribute("min")));
auto max = static_cast<column_t>(std::stoull(col_node.get_attribute("max")));
auto width = std::stold(col_node.get_attribute("width"));
auto column_style = std::stoull(col_node.get_attribute("style"));
bool custom = col_node.get_attribute("customWidth") == "1";
for(auto column = min; column <= max; column++)
for (auto column = min; column <= max; column++)
{
if(!sheet_.has_column_properties(column))
if (!sheet_.has_column_properties(column))
{
sheet_.add_column_properties(column, column_properties());
}
sheet_.get_column_properties(min).width = width;
sheet_.get_column_properties(min).style = column_style;
sheet_.get_column_properties(min).custom = custom;
}
}
if(root_node.has_child("autoFilter"))
if (root_node.has_child("autoFilter"))
{
auto &auto_filter_node = root_node.get_child("autoFilter");
xlnt::range_reference ref(auto_filter_node.get_attribute("ref"));
sheet_.auto_filter(ref);
}
return true;
}
xml_document worksheet_serializer::write_worksheet() const
{
sheet_.get_cell("A1");
xml_document xml;
auto root_node = xml.add_child("worksheet");
xml.add_namespace("", constants::Namespaces.at("spreadsheetml"));
xml.add_namespace("r", constants::Namespaces.at("r"));
auto sheet_pr_node = root_node.add_child("sheetPr");
if(!sheet_.get_page_setup().is_default())
if (!sheet_.get_page_setup().is_default())
{
auto page_set_up_pr_node = sheet_pr_node.add_child("pageSetUpPr");
page_set_up_pr_node.add_attribute("fitToPage", sheet_.get_page_setup().fit_to_page() ? "1" : "0");
}
auto outline_pr_node = sheet_pr_node.add_child("outlinePr");
outline_pr_node.add_attribute("summaryBelow", "1");
outline_pr_node.add_attribute("summaryRight", "1");
auto dimension_node = root_node.add_child("dimension");
dimension_node.add_attribute("ref", sheet_.calculate_dimension().to_string());
auto sheet_views_node = root_node.add_child("sheetViews");
auto sheet_view_node = sheet_views_node.add_child("sheetView");
sheet_view_node.add_attribute("workbookViewId", "0");
std::string active_pane = "bottomRight";
if(sheet_.has_frozen_panes())
if (sheet_.has_frozen_panes())
{
auto pane_node = sheet_view_node.add_child("pane");
if(sheet_.get_frozen_panes().get_column_index() > 1)
if (sheet_.get_frozen_panes().get_column_index() > 1)
{
pane_node.add_attribute("xSplit", std::to_string(sheet_.get_frozen_panes().get_column_index() - 1));
active_pane = "topRight";
}
if(sheet_.get_frozen_panes().get_row() > 1)
if (sheet_.get_frozen_panes().get_row() > 1)
{
pane_node.add_attribute("ySplit", std::to_string(sheet_.get_frozen_panes().get_row() - 1));
active_pane = "bottomLeft";
}
if(sheet_.get_frozen_panes().get_row() > 1 && sheet_.get_frozen_panes().get_column_index() > 1)
if (sheet_.get_frozen_panes().get_row() > 1 && sheet_.get_frozen_panes().get_column_index() > 1)
{
auto top_right_node = sheet_view_node.add_child("selection");
top_right_node.add_attribute("pane", "topRight");
@ -269,59 +272,59 @@ xml_document worksheet_serializer::write_worksheet() const
bottom_left_node.add_attribute("pane", "bottomLeft");
active_pane = "bottomRight";
}
pane_node.add_attribute("topLeftCell", sheet_.get_frozen_panes().to_string());
pane_node.add_attribute("activePane", active_pane);
pane_node.add_attribute("state", "frozen");
}
auto selection_node = sheet_view_node.add_child("selection");
if(sheet_.has_frozen_panes())
if (sheet_.has_frozen_panes())
{
if(sheet_.get_frozen_panes().get_row() > 1 && sheet_.get_frozen_panes().get_column_index() > 1)
if (sheet_.get_frozen_panes().get_row() > 1 && sheet_.get_frozen_panes().get_column_index() > 1)
{
selection_node.add_attribute("pane", "bottomRight");
}
else if(sheet_.get_frozen_panes().get_row() > 1)
else if (sheet_.get_frozen_panes().get_row() > 1)
{
selection_node.add_attribute("pane", "bottomLeft");
}
else if(sheet_.get_frozen_panes().get_column_index() > 1)
else if (sheet_.get_frozen_panes().get_column_index() > 1)
{
selection_node.add_attribute("pane", "topRight");
}
}
std::string active_cell = "A1";
selection_node.add_attribute("activeCell", active_cell);
selection_node.add_attribute("sqref", active_cell);
auto sheet_format_pr_node = root_node.add_child("sheetFormatPr");
sheet_format_pr_node.add_attribute("baseColWidth", "10");
sheet_format_pr_node.add_attribute("defaultRowHeight", "15");
bool has_column_properties = false;
for(auto column = sheet_.get_lowest_column(); column <= sheet_.get_highest_column(); column++)
for (auto column = sheet_.get_lowest_column(); column <= sheet_.get_highest_column(); column++)
{
if(sheet_.has_column_properties(column))
if (sheet_.has_column_properties(column))
{
has_column_properties = true;
break;
}
}
if(has_column_properties)
if (has_column_properties)
{
auto cols_node = root_node.add_child("cols");
for(auto column = sheet_.get_lowest_column(); column <= sheet_.get_highest_column(); column++)
for (auto column = sheet_.get_lowest_column(); column <= sheet_.get_highest_column(); column++)
{
const auto &props = sheet_.get_column_properties(column);
auto col_node = cols_node.add_child("col");
col_node.add_attribute("min", std::to_string(column));
col_node.add_attribute("max", std::to_string(column));
col_node.add_attribute("width", std::to_string(props.width));
@ -329,45 +332,45 @@ xml_document worksheet_serializer::write_worksheet() const
col_node.add_attribute("customWidth", props.custom ? "1" : "0");
}
}
std::unordered_map<std::string, std::string> hyperlink_references;
auto sheet_data_node = root_node.add_child("sheetData");
const auto &shared_strings = sheet_.get_parent().get_shared_strings();
for(auto row : sheet_.rows())
for (auto row : sheet_.rows())
{
row_t min = static_cast<row_t>(row.num_cells());
row_t max = 0;
bool any_non_null = false;
for(auto cell : row)
for (auto cell : row)
{
min = std::min(min, cell_reference::column_index_from_string(cell.get_column()));
max = std::max(max, cell_reference::column_index_from_string(cell.get_column()));
if(!cell.garbage_collectible())
if (!cell.garbage_collectible())
{
any_non_null = true;
}
}
if(!any_non_null)
if (!any_non_null)
{
continue;
}
auto row_node = sheet_data_node.add_child("row");
row_node.add_attribute("r", std::to_string(row.front().get_row()));
row_node.add_attribute("spans", (std::to_string(min) + ":" + std::to_string(max)));
if(sheet_.has_row_properties(row.front().get_row()))
if (sheet_.has_row_properties(row.front().get_row()))
{
row_node.add_attribute("customHeight", "1");
auto height = sheet_.get_row_properties(row.front().get_row()).height;
if(height == std::floor(height))
if (height == std::floor(height))
{
row_node.add_attribute("ht", std::to_string(static_cast<long long int>(height)) + ".0");
}
@ -376,46 +379,46 @@ xml_document worksheet_serializer::write_worksheet() const
row_node.add_attribute("ht", std::to_string(height));
}
}
//row_node.add_attribute("x14ac:dyDescent", 0.25);
for(auto cell : row)
// row_node.add_attribute("x14ac:dyDescent", 0.25);
for (auto cell : row)
{
if(!cell.garbage_collectible())
if (!cell.garbage_collectible())
{
if(cell.has_hyperlink())
if (cell.has_hyperlink())
{
hyperlink_references[cell.get_hyperlink().get_id()] = cell.get_reference().to_string();
}
auto cell_node = row_node.add_child("c");
cell_node.add_attribute("r", cell.get_reference().to_string());
if(cell.get_data_type() == cell::type::string)
if (cell.get_data_type() == cell::type::string)
{
if(cell.has_formula())
if (cell.has_formula())
{
cell_node.add_attribute("t", "str");
cell_node.add_child("f").set_text(cell.get_formula());
cell_node.add_child("v").set_text(cell.to_string());
continue;
}
int match_index = -1;
for(std::size_t i = 0; i < shared_strings.size(); i++)
for (std::size_t i = 0; i < shared_strings.size(); i++)
{
if(shared_strings[i] == cell.get_value<std::string>())
if (shared_strings[i] == cell.get_value<std::string>())
{
match_index = static_cast<int>(i);
break;
}
}
if(match_index == -1)
if (match_index == -1)
{
if(cell.get_value<std::string>().empty())
if (cell.get_value<std::string>().empty())
{
cell_node.add_attribute("t", "s");
}
@ -435,27 +438,27 @@ xml_document worksheet_serializer::write_worksheet() const
}
else
{
if(cell.get_data_type() != cell::type::null)
if (cell.get_data_type() != cell::type::null)
{
if(cell.get_data_type() == cell::type::boolean)
if (cell.get_data_type() == cell::type::boolean)
{
cell_node.add_attribute("t", "b");
auto value_node = cell_node.add_child("v");
value_node.set_text(cell.get_value<bool>() ? "1" : "0");
}
else if(cell.get_data_type() == cell::type::numeric)
else if (cell.get_data_type() == cell::type::numeric)
{
if(cell.has_formula())
if (cell.has_formula())
{
cell_node.add_child("f").set_text(cell.get_formula());
cell_node.add_child("v").set_text(cell.to_string());
continue;
}
cell_node.add_attribute("t", "n");
auto value_node = cell_node.add_child("v");
if(is_integral(cell.get_value<long double>()))
if (is_integral(cell.get_value<long double>()))
{
value_node.set_text(std::to_string(cell.get_value<long long>()));
}
@ -469,45 +472,45 @@ xml_document worksheet_serializer::write_worksheet() const
}
}
}
else if(cell.has_formula())
else if (cell.has_formula())
{
cell_node.add_child("f").set_text(cell.get_formula());
cell_node.add_child("v");
continue;
}
}
if(cell.has_style())
if (cell.has_style())
{
cell_node.add_attribute("s", std::to_string(cell.get_style_id()));
}
}
}
}
if(sheet_.has_auto_filter())
if (sheet_.has_auto_filter())
{
auto auto_filter_node = root_node.add_child("autoFilter");
auto_filter_node.add_attribute("ref", sheet_.get_auto_filter().to_string());
}
if(!sheet_.get_merged_ranges().empty())
if (!sheet_.get_merged_ranges().empty())
{
auto merge_cells_node = root_node.add_child("mergeCells");
merge_cells_node.add_attribute("count", std::to_string(sheet_.get_merged_ranges().size()));
for(auto merged_range : sheet_.get_merged_ranges())
for (auto merged_range : sheet_.get_merged_ranges())
{
auto merge_cell_node = merge_cells_node.add_child("mergeCell");
merge_cell_node.add_attribute("ref", merged_range.to_string());
}
}
if(!sheet_.get_relationships().empty())
if (!sheet_.get_relationships().empty())
{
auto hyperlinks_node = root_node.add_child("hyperlinks");
for(const auto &relationship : sheet_.get_relationships())
for (const auto &relationship : sheet_.get_relationships())
{
auto hyperlink_node = hyperlinks_node.add_child("hyperlink");
hyperlink_node.add_attribute("display", relationship.get_target_uri());
@ -515,45 +518,54 @@ xml_document worksheet_serializer::write_worksheet() const
hyperlink_node.add_attribute("r:id", relationship.get_id());
}
}
if(!sheet_.get_page_setup().is_default())
if (!sheet_.get_page_setup().is_default())
{
auto print_options_node = root_node.add_child("printOptions");
print_options_node.add_attribute("horizontalCentered", sheet_.get_page_setup().get_horizontal_centered() ? "1" : "0");
print_options_node.add_attribute("verticalCentered", sheet_.get_page_setup().get_vertical_centered() ? "1" : "0");
print_options_node.add_attribute("horizontalCentered",
sheet_.get_page_setup().get_horizontal_centered() ? "1" : "0");
print_options_node.add_attribute("verticalCentered",
sheet_.get_page_setup().get_vertical_centered() ? "1" : "0");
}
auto page_margins_node = root_node.add_child("pageMargins");
page_margins_node.add_attribute("left", std::to_string(sheet_.get_page_margins().get_left()));
page_margins_node.add_attribute("right", std::to_string(sheet_.get_page_margins().get_right()));
page_margins_node.add_attribute("top", std::to_string(sheet_.get_page_margins().get_top()));
page_margins_node.add_attribute("bottom", std::to_string(sheet_.get_page_margins().get_bottom()));
page_margins_node.add_attribute("header", std::to_string(sheet_.get_page_margins().get_header()));
page_margins_node.add_attribute("footer", std::to_string(sheet_.get_page_margins().get_footer()));
if(!sheet_.get_page_setup().is_default())
if (!sheet_.get_page_setup().is_default())
{
auto page_setup_node = root_node.add_child("pageSetup");
std::string orientation_string = sheet_.get_page_setup().get_orientation() == page_setup::orientation::landscape ? "landscape" : "portrait";
std::string orientation_string =
sheet_.get_page_setup().get_orientation() == page_setup::orientation::landscape ? "landscape" : "portrait";
page_setup_node.add_attribute("orientation", orientation_string);
page_setup_node.add_attribute("paperSize", std::to_string(static_cast<int>(sheet_.get_page_setup().get_paper_size())));
page_setup_node.add_attribute("paperSize",
std::to_string(static_cast<int>(sheet_.get_page_setup().get_paper_size())));
page_setup_node.add_attribute("fitToHeight", sheet_.get_page_setup().fit_to_height() ? "1" : "0");
page_setup_node.add_attribute("fitToWidth", sheet_.get_page_setup().fit_to_width() ? "1" : "0");
}
if(!sheet_.get_header_footer().is_default())
if (!sheet_.get_header_footer().is_default())
{
auto header_footer_node = root_node.add_child("headerFooter");
auto odd_header_node = header_footer_node.add_child("oddHeader");
std::string header_text = "&L&\"Calibri,Regular\"&K000000Left Header Text&C&\"Arial,Regular\"&6&K445566Center Header Text&R&\"Arial,Bold\"&8&K112233Right Header Text";
std::string header_text =
"&L&\"Calibri,Regular\"&K000000Left Header Text&C&\"Arial,Regular\"&6&K445566Center Header "
"Text&R&\"Arial,Bold\"&8&K112233Right Header Text";
odd_header_node.set_text(header_text);
auto odd_footer_node = header_footer_node.add_child("oddFooter");
std::string footer_text = "&L&\"Times New Roman,Regular\"&10&K445566Left Footer Text_x000D_And &D and &T&C&\"Times New Roman,Bold\"&12&K778899Center Footer Text &Z&F on &A&R&\"Times New Roman,Italic\"&14&KAABBCCRight Footer Text &P of &N";
std::string footer_text =
"&L&\"Times New Roman,Regular\"&10&K445566Left Footer Text_x000D_And &D and &T&C&\"Times New "
"Roman,Bold\"&12&K778899Center Footer Text &Z&F on &A&R&\"Times New Roman,Italic\"&14&KAABBCCRight Footer "
"Text &P of &N";
odd_footer_node.set_text(footer_text);
}
return xml;
}

View File

@ -6,7 +6,7 @@
#include <detail/xml_node_impl.hpp>
namespace xlnt {
xml_document::xml_document() : d_(new detail::xml_document_impl())
{
}
@ -61,7 +61,7 @@ xml_document &xml_document::from_string(const std::string &xml_string)
{
auto doc = xml_serializer::deserialize(xml_string);
std::swap(doc.d_, d_);
return *this;
}

View File

@ -13,7 +13,7 @@ xml_node::xml_node(const detail::xml_node_impl &d) : xml_node()
{
d_->node = d.node;
}
xml_node::~xml_node()
{
}
@ -22,11 +22,11 @@ xml_node::xml_node(const xml_node &other) : xml_node()
{
d_->node = other.d_->node;
}
xml_node &xml_node::operator=(const xlnt::xml_node &other)
{
d_->node = other.d_->node;
return *this;
}
@ -58,29 +58,29 @@ void xml_node::set_text(const std::string &text)
const std::vector<xml_node> xml_node::get_children() const
{
std::vector<xml_node> children;
for(auto child : d_->node.children())
for (auto child : d_->node.children())
{
children.push_back(xml_node(detail::xml_node_impl(child)));
}
return children;
}
xml_node xml_node::add_child(const xml_node &child)
{
auto child_node = xml_node(detail::xml_node_impl(d_->node.append_child(child.get_name().c_str())));
for(auto attr : child.get_attributes())
for (auto attr : child.get_attributes())
{
child_node.add_attribute(attr.first, attr.second);
}
for(auto child_child : child.get_children())
for (auto child_child : child.get_children())
{
child_node.add_child(child_child);
}
return child_node;
}
@ -92,12 +92,12 @@ xml_node xml_node::add_child(const std::string &child_name)
const std::vector<xml_node::string_pair> xml_node::get_attributes() const
{
std::vector<string_pair> attributes;
for(auto attr : d_->node.attributes())
for (auto attr : d_->node.attributes())
{
attributes.push_back(std::make_pair<std::string, std::string>(attr.name(), attr.value()));
}
return attributes;
}
@ -130,7 +130,7 @@ const xml_node xml_node::get_child(const std::string &child_name) const
{
return xml_node(detail::xml_node_impl(d_->node.child(child_name.c_str())));
}
std::string xml_node::to_string() const
{
return xml_serializer::serialize_node(*this);

View File

@ -14,15 +14,15 @@ std::string xml_serializer::serialize(const xml_document &xml)
{
std::ostringstream ss;
xml.d_->doc.save(ss, " ", pugi::format_default, pugi::encoding_utf8);
return ss.str();
}
xml_document xml_serializer::deserialize(const std::string &xml_string)
{
xml_document doc;
doc.d_->doc.load(xml_string.c_str());
return doc;
}
@ -30,11 +30,11 @@ std::string xml_serializer::serialize_node(const xml_node &xml)
{
pugi::xml_document doc;
doc.append_copy(xml.d_->node);
std::ostringstream ss;
doc.save(ss);
return ss.str();
}
} // namespace xlnt

View File

@ -5,7 +5,6 @@ namespace xlnt {
side::side()
{
}
} // namespace xlnt

View File

@ -8,49 +8,48 @@ namespace {
const std::unordered_map<int, std::string> &builtin_formats()
{
static const std::unordered_map<int, std::string> formats =
{
{0, "General"},
{1, "0"},
{2, "0.00"},
{3, "#,##0"},
{4, "#,##0.00"},
{5, "\"$\"#,##0_);(\"$\"#,##0)"},
{6, "\"$\"#,##0_);[Red](\"$\"#,##0)"},
{7, "\"$\"#,##0.00_);(\"$\"#,##0.00)"},
{8, "\"$\"#,##0.00_);[Red](\"$\"#,##0.00)"},
{9, "0%"},
{10, "0.00%"},
{11, "0.00E+00"},
{12, "# ?/?"},
{13, "# \?\?/??"}, //escape trigraph
{14, "mm-dd-yy"},
{15, "d-mmm-yy"},
{16, "d-mmm"},
{17, "mmm-yy"},
{18, "h:mm AM/PM"},
{19, "h:mm:ss AM/PM"},
{20, "h:mm"},
{21, "h:mm:ss"},
{22, "m/d/yy h:mm"},
{37, "#,##0_);(#,##0)"},
{38, "#,##0_);[Red](#,##0)"},
{39, "#,##0.00_);(#,##0.00)"},
{40, "#,##0.00_);[Red](#,##0.00)"},
{41, "_(* #,##0_);_(* \\(#,##0\\);_(* \"-\"_);_(@_)"},
{42, "_(\"$\"* #,##0_);_(\"$\"* \\(#,##0\\);_(\"$\"* \"-\"_);_(@_)"},
{43, "_(* #,##0.00_);_(* \\(#,##0.00\\);_(* \"-\"??_);_(@_)"},
{44, "_(\"$\"* #,##0.00_)_(\"$\"* \\(#,##0.00\\)_(\"$\"* \"-\"??_)_(@_)"},
{45, "mm:ss"},
{46, "[h]:mm:ss"},
{47, "mmss.0"},
{48, "##0.0E+0"},
{49, "@"}
//EXCEL differs from the standard in the following:
static const std::unordered_map<int, std::string> formats = {
{ 0, "General" },
{ 1, "0" },
{ 2, "0.00" },
{ 3, "#,##0" },
{ 4, "#,##0.00" },
{ 5, "\"$\"#,##0_);(\"$\"#,##0)" },
{ 6, "\"$\"#,##0_);[Red](\"$\"#,##0)" },
{ 7, "\"$\"#,##0.00_);(\"$\"#,##0.00)" },
{ 8, "\"$\"#,##0.00_);[Red](\"$\"#,##0.00)" },
{ 9, "0%" },
{ 10, "0.00%" },
{ 11, "0.00E+00" },
{ 12, "# ?/?" },
{ 13, "# \?\?/??" }, // escape trigraph
{ 14, "mm-dd-yy" },
{ 15, "d-mmm-yy" },
{ 16, "d-mmm" },
{ 17, "mmm-yy" },
{ 18, "h:mm AM/PM" },
{ 19, "h:mm:ss AM/PM" },
{ 20, "h:mm" },
{ 21, "h:mm:ss" },
{ 22, "m/d/yy h:mm" },
{ 37, "#,##0_);(#,##0)" },
{ 38, "#,##0_);[Red](#,##0)" },
{ 39, "#,##0.00_);(#,##0.00)" },
{ 40, "#,##0.00_);[Red](#,##0.00)" },
{ 41, "_(* #,##0_);_(* \\(#,##0\\);_(* \"-\"_);_(@_)" },
{ 42, "_(\"$\"* #,##0_);_(\"$\"* \\(#,##0\\);_(\"$\"* \"-\"_);_(@_)" },
{ 43, "_(* #,##0.00_);_(* \\(#,##0.00\\);_(* \"-\"??_);_(@_)" },
{ 44, "_(\"$\"* #,##0.00_)_(\"$\"* \\(#,##0.00\\)_(\"$\"* \"-\"??_)_(@_)" },
{ 45, "mm:ss" },
{ 46, "[h]:mm:ss" },
{ 47, "mmss.0" },
{ 48, "##0.0E+0" },
{ 49, "@" }
// EXCEL differs from the standard in the following:
//{14, "m/d/yyyy"},
//{22, "m/d/yyyy h:mm"},
//{37, "#,##0_);(#,##0)"},
@ -60,10 +59,10 @@ const std::unordered_map<int, std::string> &builtin_formats()
//{47, "mm:ss.0"},
//{55, "yyyy/mm/dd"}
};
return formats;
}
} // namespace
namespace xlnt {
@ -73,199 +72,199 @@ const number_format number_format::general()
static const number_format format(builtin_formats().at(0), 0);
return format;
}
const number_format number_format::text()
{
static const number_format format(builtin_formats().at(49), 49);
return format;
}
const number_format number_format::number()
{
static const number_format format(builtin_formats().at(1), 1);
return format;
}
const number_format number_format::number_00()
{
static const number_format format(builtin_formats().at(2), 2);
return format;
}
const number_format number_format::number_comma_separated1()
{
static const number_format format(builtin_formats().at(4), 4);
return format;
}
const number_format number_format::number_comma_separated2()
{
static const number_format format("#,##0.00_-");
return format;
}
const number_format number_format::percentage()
{
static const number_format format(builtin_formats().at(9), 9);
return format;
}
const number_format number_format::percentage_00()
{
static const number_format format(builtin_formats().at(10), 10);
return format;
}
const number_format number_format::date_yyyymmdd2()
{
static const number_format format("yyyy-mm-dd");
return format;
}
const number_format number_format::date_yyyymmdd()
{
static const number_format format("yy-mm-dd");
return format;
}
const number_format number_format::date_ddmmyyyy()
{
static const number_format format("dd/mm/yy");
return format;
}
const number_format number_format::date_dmyslash()
{
static const number_format format("d/m/y");
return format;
}
const number_format number_format::date_dmyminus()
{
static const number_format format("d-m-y");
return format;
}
const number_format number_format::date_dmminus()
{
static const number_format format("d-m");
return format;
}
const number_format number_format::date_myminus()
{
static const number_format format("m-y");
return format;
}
const number_format number_format::date_xlsx14()
{
static const number_format format(builtin_formats().at(14), 14);
return format;
}
const number_format number_format::date_xlsx15()
{
static const number_format format(builtin_formats().at(15), 15);
return format;
}
const number_format number_format::date_xlsx16()
{
static const number_format format(builtin_formats().at(16), 16);
return format;
}
const number_format number_format::date_xlsx17()
{
static const number_format format(builtin_formats().at(17), 17);
return format;
}
const number_format number_format::date_xlsx22()
{
static const number_format format(builtin_formats().at(22), 22);
return format;
}
const number_format number_format::date_datetime()
{
static const number_format format("yyyy-mm-dd h:mm:ss");
return format;
}
const number_format number_format::date_time1()
{
static const number_format format(builtin_formats().at(18), 18);
return format;
}
const number_format number_format::date_time2()
{
static const number_format format(builtin_formats().at(19), 19);
return format;
}
const number_format number_format::date_time3()
{
static const number_format format(builtin_formats().at(20), 20);
return format;
}
const number_format number_format::date_time4()
{
static const number_format format(builtin_formats().at(21), 21);
return format;
}
const number_format number_format::date_time5()
{
static const number_format format(builtin_formats().at(45), 45);
return format;
}
const number_format number_format::date_time6()
{
static const number_format format(builtin_formats().at(21), 21);
return format;
}
const number_format number_format::date_time7()
{
static const number_format format("i:s.S");
return format;
}
const number_format number_format::date_time8()
{
static const number_format format("h:mm:ss@");
return format;
}
const number_format number_format::date_timedelta()
{
static const number_format format("[hh]:mm:ss");
return format;
}
const number_format number_format::date_yyyymmddslash()
{
static const number_format format("yy/mm/dd@");
return format;
}
const number_format number_format::currency_usd_simple()
{
static const number_format format("\"$\"#,##0.00_-");
return format;
}
const number_format number_format::currency_usd()
{
static const number_format format("$#,##0_-");
return format;
}
const number_format number_format::currency_eur_simple()
{
static const number_format format("[$EUR ]#,##0.00_-");
@ -287,11 +286,11 @@ number_format::number_format(const std::string &format_string, int id)
number_format number_format::from_builtin_id(int builtin_id)
{
if(builtin_formats().find(builtin_id) == builtin_formats().end())
if (builtin_formats().find(builtin_id) == builtin_formats().end())
{
throw std::runtime_error("unknown id: " + std::to_string(builtin_id));
}
auto format_string = builtin_formats().at(builtin_id);
return number_format(format_string, builtin_id);
}
@ -305,20 +304,20 @@ std::size_t number_format::hash() const
{
std::size_t seed = static_cast<std::size_t>(id_);
hash_combine(seed, format_string_);
return seed;
}
void number_format::set_format_string(const std::string &format_string, int id)
{
format_string_ = format_string;
id_ = id;
if(id_ == -1)
if (id_ == -1)
{
for(const auto &pair : builtin_formats())
for (const auto &pair : builtin_formats())
{
if(pair.second == format_string)
if (pair.second == format_string)
{
id_ = pair.first;
break;

View File

@ -4,12 +4,10 @@ namespace xlnt {
protection::protection() : protection(type::unprotected)
{
}
protection::protection(type t) : locked_(t), hidden_(type::unprotected)
{
}
} // namespace xlnt

View File

@ -7,12 +7,11 @@
namespace {
template <class T>
void hash_combine(std::size_t& seed, const T& v)
void hash_combine(std::size_t &seed, const T &v)
{
std::hash<T> hasher;
seed ^= hasher(v) + 0x9e3779b9 + (seed<<6) + (seed>>2);
seed ^= hasher(v) + 0x9e3779b9 + (seed << 6) + (seed >> 2);
}
}
namespace xlnt {
@ -20,43 +19,43 @@ namespace xlnt {
const color color::black = color(color::type::indexed, 0);
const color color::white = color(color::type::indexed, 0);
style::style() :
id_(0),
alignment_apply_(false),
border_apply_(false),
border_id_(0),
fill_apply_(false),
fill_id_(0),
font_apply_(false),
font_id_(0),
number_format_apply_(false),
number_format_id_(0),
protection_apply_(false),
pivot_button_(false),
quote_prefix_(false)
style::style()
: id_(0),
alignment_apply_(false),
border_apply_(false),
border_id_(0),
fill_apply_(false),
fill_id_(0),
font_apply_(false),
font_id_(0),
number_format_apply_(false),
number_format_id_(0),
protection_apply_(false),
pivot_button_(false),
quote_prefix_(false)
{
}
style::style(const style &other) :
id_(other.id_),
alignment_apply_(other.alignment_apply_),
alignment_(other.alignment_),
border_apply_(other.border_apply_),
border_id_(other.border_id_),
border_(other.border_),
fill_apply_(other.fill_apply_),
fill_id_(other.fill_id_),
fill_(other.fill_),
font_apply_(other.font_apply_),
font_id_(other.font_id_),
font_(other.font_),
number_format_apply_(other.number_format_apply_),
number_format_id_(other.number_format_id_),
number_format_(other.number_format_),
protection_apply_(other.protection_apply_),
protection_(other.protection_),
pivot_button_(other.pivot_button_),
quote_prefix_(other.quote_prefix_)
style::style(const style &other)
: id_(other.id_),
alignment_apply_(other.alignment_apply_),
alignment_(other.alignment_),
border_apply_(other.border_apply_),
border_id_(other.border_id_),
border_(other.border_),
fill_apply_(other.fill_apply_),
fill_id_(other.fill_id_),
fill_(other.fill_),
font_apply_(other.font_apply_),
font_id_(other.font_id_),
font_(other.font_),
number_format_apply_(other.number_format_apply_),
number_format_id_(other.number_format_id_),
number_format_(other.number_format_),
protection_apply_(other.protection_apply_),
protection_(other.protection_),
pivot_button_(other.pivot_button_),
quote_prefix_(other.quote_prefix_)
{
}
@ -81,32 +80,32 @@ style &style::operator=(const style &other)
protection_apply_ = other.protection_apply_;
pivot_button_ = other.pivot_button_;
quote_prefix_ = other.quote_prefix_;
return *this;
}
std::size_t style::hash() const
{
std::size_t seed = 0;
hash_combine(seed, alignment_apply_);
hash_combine(seed, alignment_apply_ ? alignment_.hash() : 0);
hash_combine(seed, border_apply_);
hash_combine(seed, border_apply_ ? border_id_ : 0);
hash_combine(seed, font_apply_);
hash_combine(seed, font_apply_ ? font_id_ : 0);
hash_combine(seed, fill_apply_);
hash_combine(seed, fill_apply_ ? fill_id_ : 0);
hash_combine(seed, number_format_apply_);
hash_combine(seed, number_format_apply_ ? number_format_id_ : 0);
hash_combine(seed, protection_apply_);
hash_combine(seed, protection_apply_ ? get_protection().hash() : 0);
return seed;
}
@ -124,7 +123,7 @@ const alignment style::get_alignment() const
{
return alignment_;
}
const fill style::get_fill() const
{
return fill_;

View File

@ -2,12 +2,9 @@
namespace xlnt {
document_properties::document_properties()
: created(1900, 1, 1),
modified(1900, 1, 1),
excel_base_date(calendar::windows_1900)
document_properties::document_properties()
: created(1900, 1, 1), modified(1900, 1, 1), excel_base_date(calendar::windows_1900)
{
}
} // namespace xlnt

View File

@ -4,23 +4,23 @@ namespace {
bool match_path(const std::string &path, const std::string &comparand)
{
if(path == comparand)
if (path == comparand)
{
return true;
}
if(path[0] != '/' && path[0] != '.' && comparand[0] == '/')
if (path[0] != '/' && path[0] != '.' && comparand[0] == '/')
{
return match_path("/" + path, comparand);
}
else if(comparand[0] != '/' && comparand[0] != '.' && path[0] == '/')
else if (comparand[0] != '/' && comparand[0] != '.' && path[0] == '/')
{
return match_path(path, "/" + comparand);
}
return false;
}
} // namespace
namespace xlnt {
@ -29,15 +29,12 @@ default_type::default_type()
{
}
default_type::default_type(const std::string &extension, const std::string &content_type) :
extension_(extension),
content_type_(content_type)
default_type::default_type(const std::string &extension, const std::string &content_type)
: extension_(extension), content_type_(content_type)
{
}
default_type::default_type(const default_type &other) :
extension_(other.extension_),
content_type_(other.content_type_)
default_type::default_type(const default_type &other) : extension_(other.extension_), content_type_(other.content_type_)
{
}
@ -45,7 +42,7 @@ default_type &default_type::operator=(const default_type &other)
{
extension_ = other.extension_;
content_type_ = other.content_type_;
return *this;
}
@ -53,15 +50,13 @@ override_type::override_type()
{
}
override_type::override_type(const std::string &part_name, const std::string &content_type) :
part_name_(part_name),
content_type_(content_type)
override_type::override_type(const std::string &part_name, const std::string &content_type)
: part_name_(part_name), content_type_(content_type)
{
}
override_type::override_type(const override_type &other) :
part_name_(other.part_name_),
content_type_(other.content_type_)
override_type::override_type(const override_type &other)
: part_name_(other.part_name_), content_type_(other.content_type_)
{
}
@ -69,20 +64,21 @@ override_type &override_type::operator=(const override_type &other)
{
part_name_ = other.part_name_;
content_type_ = other.content_type_;
return *this;
}
bool manifest::has_default_type(const std::string &extension) const
{
return std::find_if(default_types_.begin(), default_types_.end(),
[&](const default_type &d) { return d.get_extension() == extension; }) != default_types_.end();
[&](const default_type &d) { return d.get_extension() == extension; }) != default_types_.end();
}
bool manifest::has_override_type(const std::string &part_name) const
{
return std::find_if(override_types_.begin(), override_types_.end(),
[&](const override_type &d) { return match_path(d.get_part_name(), part_name); }) != override_types_.end();
return std::find_if(override_types_.begin(), override_types_.end(), [&](const override_type &d) {
return match_path(d.get_part_name(), part_name);
}) != override_types_.end();
}
void manifest::add_default_type(const std::string &extension, const std::string &content_type)
@ -98,26 +94,26 @@ void manifest::add_override_type(const std::string &part_name, const std::string
std::string manifest::get_default_type(const std::string &extension) const
{
auto match = std::find_if(default_types_.begin(), default_types_.end(),
[&](const default_type &d) { return d.get_extension() == extension; });
if(match == default_types_.end())
[&](const default_type &d) { return d.get_extension() == extension; });
if (match == default_types_.end())
{
throw std::runtime_error("no default type found for extension: " + extension);
}
return match->get_content_type();
}
std::string manifest::get_override_type(const std::string &part_name) const
{
auto match = std::find_if(override_types_.begin(), override_types_.end(),
[&](const override_type &d) { return match_path(d.get_part_name(), part_name); });
if(match == override_types_.end())
[&](const override_type &d) { return match_path(d.get_part_name(), part_name); });
if (match == override_types_.end())
{
throw std::runtime_error("no default type found for part name: " + part_name);
}
return match->get_content_type();
}

View File

@ -17,18 +17,18 @@ std::vector<std::string> split_string(const std::string &string, char delim)
std::vector<std::string> split;
std::string::size_type previous_index = 0;
auto separator_index = string.find(delim);
while(separator_index != std::string::npos)
while (separator_index != std::string::npos)
{
auto part = string.substr(previous_index, separator_index - previous_index);
split.push_back(part);
previous_index = separator_index + 1;
separator_index = string.find(delim, previous_index);
}
split.push_back(string.substr(previous_index));
return split;
}
@ -39,29 +39,29 @@ namespace xlnt {
std::vector<std::pair<std::string, std::string>> split_named_range(const std::string &named_range_string)
{
std::vector<std::pair<std::string, std::string>> final;
for(auto part : split_string(named_range_string, ','))
for (auto part : split_string(named_range_string, ','))
{
auto split = split_string(part, '!');
if(split[0].front() == '\'' && split[0].back() == '\'')
if (split[0].front() == '\'' && split[0].back() == '\'')
{
split[0] = split[0].substr(1, split[0].length() - 2);
}
// Try to parse it. Use empty string if it's not a valid range.
try
{
xlnt::range_reference ref(split[1]);
}
catch(xlnt::cell_coordinates_exception)
catch (xlnt::cell_coordinates_exception)
{
split[1] = "";
}
final.push_back({split[0], split[1]});
final.push_back({ split[0], split[1] });
}
return final;
}
@ -75,8 +75,7 @@ named_range::named_range(const named_range &other)
}
named_range::named_range(const std::string &name, const std::vector<named_range::target> &targets)
: name_(name),
targets_(targets)
: name_(name), targets_(targets)
{
}
@ -84,8 +83,8 @@ named_range &named_range::operator=(const named_range &other)
{
name_ = other.name_;
targets_ = other.targets_;
return *this;
}
} // namespace xlnt

View File

@ -4,10 +4,6 @@
#include <set>
#include <sstream>
#ifdef _WIN32
#include <Windows.h>
#endif
#include <xlnt/common/exceptions.hpp>
#include <xlnt/common/relationship.hpp>
#include <xlnt/common/zip_file.hpp>
@ -28,20 +24,21 @@
#include <xlnt/worksheet/range.hpp>
#include <xlnt/worksheet/worksheet.hpp>
#include "detail/cell_impl.hpp"
#include "detail/include_pugixml.hpp"
#include "detail/workbook_impl.hpp"
#include "detail/worksheet_impl.hpp"
#include <detail/cell_impl.hpp>
#include <detail/include_windows.hpp>
#include <detail/workbook_impl.hpp>
#include <detail/worksheet_impl.hpp>
namespace xlnt {
namespace detail {
workbook_impl::workbook_impl() : active_sheet_index_(0), guess_types_(false), data_only_(false), next_custom_format_id_(164)
workbook_impl::workbook_impl()
: active_sheet_index_(0), guess_types_(false), data_only_(false), next_custom_format_id_(164)
{
}
} // namespace detail
workbook::workbook() : d_(new detail::workbook_impl())
{
create_sheet("Sheet");
@ -52,45 +49,41 @@ workbook::workbook() : d_(new detail::workbook_impl())
workbook::iterator::iterator(workbook &wb, std::size_t index) : wb_(wb), index_(index)
{
}
workbook::iterator::iterator(const iterator &rhs) : wb_(rhs.wb_), index_(rhs.index_)
{
}
worksheet workbook::iterator::operator*()
{
return wb_[index_];
}
workbook::iterator &workbook::iterator::operator++()
{
index_++;
return *this;
}
workbook::iterator workbook::iterator::operator++(int)
{
iterator old(wb_, index_);
++*this;
return old;
}
bool workbook::iterator::operator==(const iterator &comparand) const
{
return index_ == comparand.index_ && wb_ == comparand.wb_;
}
workbook::const_iterator::const_iterator(const workbook &wb, std::size_t index) : wb_(wb), index_(index)
{
}
workbook::const_iterator::const_iterator(const const_iterator &rhs) : wb_(rhs.wb_), index_(rhs.index_)
{
}
const worksheet workbook::const_iterator::operator*()
@ -110,17 +103,17 @@ workbook::const_iterator workbook::const_iterator::operator++(int)
++*this;
return old;
}
bool workbook::const_iterator::operator==(const const_iterator &comparand) const
{
return index_ == comparand.index_ && wb_ == comparand.wb_;
}
worksheet workbook::get_sheet_by_name(const std::string &name)
{
for(auto &impl : d_->worksheets_)
for (auto &impl : d_->worksheets_)
{
if(impl.title_ == name)
if (impl.title_ == name)
{
return worksheet(&impl);
}
@ -133,7 +126,7 @@ worksheet workbook::get_sheet_by_index(std::size_t index)
{
return worksheet(&d_->worksheets_[index]);
}
const worksheet workbook::get_sheet_by_index(std::size_t index) const
{
return worksheet(&d_->worksheets_.at(index));
@ -146,9 +139,9 @@ worksheet workbook::get_active_sheet()
bool workbook::has_named_range(const std::string &name) const
{
for(auto worksheet : *this)
for (auto worksheet : *this)
{
if(worksheet.has_named_range(name))
if (worksheet.has_named_range(name))
{
return true;
}
@ -157,31 +150,33 @@ bool workbook::has_named_range(const std::string &name) const
}
worksheet workbook::create_sheet()
{
{
std::string title = "Sheet1";
int index = 1;
while(get_sheet_by_name(title) != nullptr)
while (get_sheet_by_name(title) != nullptr)
{
title = "Sheet" + std::to_string(++index);
}
d_->worksheets_.push_back(detail::worksheet_impl(this, title));
create_relationship("rId" + std::to_string(d_->relationships_.size() + 1), "xl/worksheets/sheet" + std::to_string(d_->worksheets_.size()) + ".xml", relationship::type::worksheet);
return worksheet(&d_->worksheets_.back());
create_relationship("rId" + std::to_string(d_->relationships_.size() + 1),
"xl/worksheets/sheet" + std::to_string(d_->worksheets_.size()) + ".xml",
relationship::type::worksheet);
return worksheet(&d_->worksheets_.back());
}
void workbook::add_sheet(xlnt::worksheet worksheet)
{
for(auto ws : *this)
for (auto ws : *this)
{
if(worksheet == ws)
if (worksheet == ws)
{
throw std::runtime_error("worksheet already in workbook");
}
}
d_->worksheets_.emplace_back(*worksheet.d_);
}
@ -194,9 +189,9 @@ void workbook::add_sheet(xlnt::worksheet worksheet, std::size_t index)
int workbook::get_index(xlnt::worksheet worksheet)
{
int i = 0;
for(auto ws : *this)
for (auto ws : *this)
{
if(worksheet == ws)
if (worksheet == ws)
{
return i;
}
@ -208,7 +203,7 @@ int workbook::get_index(xlnt::worksheet worksheet)
void workbook::create_named_range(const std::string &name, worksheet range_owner, const range_reference &reference)
{
auto match = get_sheet_by_name(range_owner.get_title());
if(match != nullptr)
if (match != nullptr)
{
match.create_named_range(name, reference);
return;
@ -218,28 +213,28 @@ void workbook::create_named_range(const std::string &name, worksheet range_owner
void workbook::remove_named_range(const std::string &name)
{
for(auto ws : *this)
for (auto ws : *this)
{
if(ws.has_named_range(name))
if (ws.has_named_range(name))
{
ws.remove_named_range(name);
return;
}
}
throw std::runtime_error("named range not found");
}
range workbook::get_named_range(const std::string &name)
{
for(auto ws : *this)
for (auto ws : *this)
{
if(ws.has_named_range(name))
if (ws.has_named_range(name))
{
return ws.get_named_range(name);
}
}
throw std::runtime_error("named range not found");
}
@ -247,15 +242,15 @@ bool workbook::load(std::istream &stream)
{
excel_serializer serializer_(*this);
serializer_.load_stream_workbook(stream);
return true;
}
bool workbook::load(const std::vector<unsigned char> &data)
{
excel_serializer serializer_(*this);
serializer_.load_virtual_workbook(data);
return true;
}
@ -284,9 +279,9 @@ void workbook::create_relationship(const std::string &id, const std::string &tar
relationship workbook::get_relationship(const std::string &id) const
{
for(auto &rel : d_->relationships_)
for (auto &rel : d_->relationships_)
{
if(rel.get_id() == id)
if (rel.get_id() == id)
{
return rel;
}
@ -294,24 +289,26 @@ relationship workbook::get_relationship(const std::string &id) const
throw std::runtime_error("");
}
void workbook::remove_sheet(worksheet ws)
{
auto match_iter = std::find_if(d_->worksheets_.begin(), d_->worksheets_.end(), [=](detail::worksheet_impl &comp) { return worksheet(&comp) == ws; });
auto match_iter = std::find_if(d_->worksheets_.begin(), d_->worksheets_.end(),
[=](detail::worksheet_impl &comp) { return worksheet(&comp) == ws; });
if(match_iter == d_->worksheets_.end())
if (match_iter == d_->worksheets_.end())
{
throw std::runtime_error("worksheet not owned by this workbook");
}
auto sheet_filename = "xl/worksheets/sheet" + std::to_string(d_->worksheets_.size()) + ".xml";
auto rel_iter = std::find_if(d_->relationships_.begin(), d_->relationships_.end(), [=](relationship &r) { return r.get_target_uri() == sheet_filename; });
if(rel_iter == d_->relationships_.end())
auto rel_iter = std::find_if(d_->relationships_.begin(), d_->relationships_.end(),
[=](relationship &r) { return r.get_target_uri() == sheet_filename; });
if (rel_iter == d_->relationships_.end())
{
throw std::runtime_error("no matching rel found");
}
d_->relationships_.erase(rel_iter);
d_->worksheets_.erase(match_iter);
}
@ -319,17 +316,17 @@ void workbook::remove_sheet(worksheet ws)
worksheet workbook::create_sheet(std::size_t index)
{
create_sheet();
if (index != d_->worksheets_.size() - 1)
{
std::swap(d_->worksheets_.back(), d_->worksheets_[index]);
d_->worksheets_.pop_back();
}
if (index != d_->worksheets_.size() - 1)
{
std::swap(d_->worksheets_.back(), d_->worksheets_[index]);
d_->worksheets_.pop_back();
}
return worksheet(&d_->worksheets_[index]);
}
//TODO: There should be a better way to do this...
// TODO: There should be a better way to do this...
std::size_t workbook::index_from_ws_filename(const std::string &ws_filename)
{
std::string sheet_index_string(ws_filename);
@ -337,61 +334,67 @@ std::size_t workbook::index_from_ws_filename(const std::string &ws_filename)
sheet_index_string = sheet_index_string.substr(sheet_index_string.find_last_of('/'));
auto iter = sheet_index_string.end();
iter--;
while (isdigit(*iter)) iter--;
while (isdigit(*iter))
iter--;
auto first_digit = static_cast<std::size_t>(iter - sheet_index_string.begin());
sheet_index_string = sheet_index_string.substr(first_digit + 1);
auto sheet_index = static_cast<std::size_t>(std::stoll(sheet_index_string) - 1);
return sheet_index;
}
worksheet workbook::create_sheet(const std::string &title, const relationship &rel)
{
d_->worksheets_.push_back(detail::worksheet_impl(this, title));
d_->worksheets_.push_back(detail::worksheet_impl(this, title));
auto index = index_from_ws_filename(rel.get_target_uri());
if (index != d_->worksheets_.size() - 1)
{
std::swap(d_->worksheets_.back(), d_->worksheets_[index]);
d_->worksheets_.pop_back();
}
auto index = index_from_ws_filename(rel.get_target_uri());
if (index != d_->worksheets_.size() - 1)
{
std::swap(d_->worksheets_.back(), d_->worksheets_[index]);
d_->worksheets_.pop_back();
}
return worksheet(&d_->worksheets_[index]);
return worksheet(&d_->worksheets_[index]);
}
worksheet workbook::create_sheet(std::size_t index, const std::string &title)
{
auto ws = create_sheet(index);
ws.set_title(title);
return ws;
}
worksheet workbook::create_sheet(const std::string &title)
{
if(title.length() > 31)
if (title.length() > 31)
{
throw sheet_title_exception(title);
}
if(std::find_if(title.begin(), title.end(),
[](char c) { return c == '*' || c == ':' || c == '/' || c == '\\' || c == '?' || c == '[' || c == ']'; }) != title.end())
if (std::find_if(title.begin(), title.end(), [](char c) {
return c == '*' || c == ':' || c == '/' || c == '\\' || c == '?' || c == '[' || c == ']';
}) != title.end())
{
throw sheet_title_exception(title);
}
std::string unique_title = title;
if(std::find_if(d_->worksheets_.begin(), d_->worksheets_.end(), [&](detail::worksheet_impl &ws) { return worksheet(&ws).get_title() == unique_title; }) != d_->worksheets_.end())
if (std::find_if(d_->worksheets_.begin(), d_->worksheets_.end(), [&](detail::worksheet_impl &ws) {
return worksheet(&ws).get_title() == unique_title;
}) != d_->worksheets_.end())
{
std::size_t suffix = 1;
while(std::find_if(d_->worksheets_.begin(), d_->worksheets_.end(), [&](detail::worksheet_impl &ws) { return worksheet(&ws).get_title() == unique_title; }) != d_->worksheets_.end())
while (std::find_if(d_->worksheets_.begin(), d_->worksheets_.end(), [&](detail::worksheet_impl &ws) {
return worksheet(&ws).get_title() == unique_title;
}) != d_->worksheets_.end())
{
unique_title = title + std::to_string(suffix);
suffix++;
}
}
auto ws = create_sheet();
ws.set_title(unique_title);
@ -421,12 +424,12 @@ workbook::const_iterator workbook::cend() const
std::vector<std::string> workbook::get_sheet_names() const
{
std::vector<std::string> names;
for(auto ws : *this)
for (auto ws : *this)
{
names.push_back(ws.get_title());
}
return names;
}
@ -461,7 +464,7 @@ bool workbook::save(const std::string &filename)
{
excel_serializer serializer(*this);
serializer.save_workbook(filename);
return true;
}
@ -477,25 +480,7 @@ bool workbook::operator==(const workbook &rhs) const
const std::vector<relationship> &xlnt::workbook::get_relationships() const
{
return d_->relationships_;
}
std::vector<content_type> xlnt::workbook::get_content_types() const
{
std::vector<content_type> content_types;
content_types.push_back({ true, "xml", "", "application/xml" });
content_types.push_back({ true, "rels", "", "application/vnd.openxmlformats-package.relationships+xml" });
content_types.push_back({ false, "", "/xl/workbook.xml", "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet.main+xml" });
for(std::size_t i = 0; i < get_sheet_names().size(); i++)
{
content_types.push_back({false, "", "/xl/worksheets/sheet" + std::to_string(i + 1) + ".xml", "application/vnd.openxmlformats-officedocument.spreadsheetml.worksheet+xml"});
}
content_types.push_back({false, "", "/xl/theme/theme1.xml", "application/vnd.openxmlformats-officedocument.theme+xml"});
content_types.push_back({false, "", "/xl/styles.xml", "application/vnd.openxmlformats-officedocument.spreadsheetml.styles+xml"});
content_types.push_back({false, "", "/xl/sharedStrings.xml", "application/vnd.openxmlformats-officedocument.spreadsheetml.sharedStrings+xml"});
content_types.push_back({false, "", "/docProps/core.xml", "application/vnd.openxmlformats-package.core-properties+xml"});
content_types.push_back({false, "", "/docProps/app.xml", "application/vnd.openxmlformats-officedocument.extended-properties+xml"});
return content_types;
return d_->relationships_;
}
document_properties &workbook::get_properties()
@ -512,18 +497,18 @@ void swap(workbook &left, workbook &right)
{
using std::swap;
swap(left.d_, right.d_);
for(auto ws : left)
for (auto ws : left)
{
ws.set_parent(left);
}
for(auto ws : right)
for (auto ws : right)
{
ws.set_parent(right);
}
}
workbook &workbook::operator=(workbook other)
{
swap(*this, other);
@ -534,12 +519,12 @@ workbook::workbook(workbook &&other) : workbook()
{
swap(*this, other);
}
workbook::workbook(const workbook &other) : workbook()
{
*d_.get() = *other.d_.get();
for(auto ws : *this)
for (auto ws : *this)
{
ws.set_parent(*this);
}
@ -574,10 +559,9 @@ void workbook::add_number_format(const number_format &number_format_)
{
d_->number_formats_.push_back(number_format_);
}
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() const
@ -593,15 +577,15 @@ const theme &workbook::get_loaded_theme() const
std::vector<named_range> workbook::get_named_ranges() const
{
std::vector<named_range> named_ranges;
for(auto ws : *this)
for (auto ws : *this)
{
for(auto &ws_named_range : ws.d_->named_ranges_)
for (auto &ws_named_range : ws.d_->named_ranges_)
{
named_ranges.push_back(ws_named_range.second);
}
}
return named_ranges;
}
@ -609,25 +593,25 @@ std::size_t workbook::add_style(const xlnt::style &style_)
{
d_->styles_.push_back(style_);
d_->styles_.back().id_ = d_->styles_.size() - 1;
return d_->styles_.back().id_;
}
const number_format &workbook::get_number_format(std::size_t style_id) const
{
auto number_format_id = d_->styles_[style_id].number_format_id_;
for(const auto &number_format_ : d_->number_formats_)
for (const auto &number_format_ : d_->number_formats_)
{
if(static_cast<std::size_t>(number_format_.get_id()) == number_format_id)
if (static_cast<std::size_t>(number_format_.get_id()) == number_format_id)
{
return number_format_;
}
}
auto nf = number_format::from_builtin_id(static_cast<int>(number_format_id));
d_->number_formats_.push_back(nf);
return d_->number_formats_.back();
}
@ -640,8 +624,8 @@ std::size_t workbook::set_font(const font &font_, std::size_t style_id)
{
auto match = std::find(d_->fonts_.begin(), d_->fonts_.end(), font_);
std::size_t font_index = 0;
if(match == d_->fonts_.end())
if (match == d_->fonts_.end())
{
d_->fonts_.push_back(font_);
font_index = d_->fonts_.size() - 1;
@ -650,27 +634,27 @@ std::size_t workbook::set_font(const font &font_, std::size_t style_id)
{
font_index = match - d_->fonts_.begin();
}
auto existing_style = d_->styles_[style_id];
if(font_index == existing_style.font_id_)
if (font_index == existing_style.font_id_)
{
// no change
return style_id;
}
auto new_style = existing_style;
new_style.font_id_ = font_index;
auto style_match = std::find(d_->styles_.begin(), d_->styles_.end(), new_style);
if(style_match != d_->styles_.end())
if (style_match != d_->styles_.end())
{
return style_match - d_->styles_.begin();
}
d_->styles_.push_back(new_style);
return d_->styles_.size() - 1;
}
@ -679,7 +663,7 @@ const fill &workbook::get_fill(std::size_t fill_id) const
return d_->fills_[fill_id];
}
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)
{
return style_id;
}
@ -689,7 +673,7 @@ const border &workbook::get_border(std::size_t border_id) const
return d_->borders_[border_id];
}
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)
{
return style_id;
}
@ -699,7 +683,7 @@ const alignment &workbook::get_alignment(std::size_t style_id) const
return d_->styles_[style_id].alignment_;
}
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)
{
return style_id;
}
@ -709,7 +693,7 @@ const protection &workbook::get_protection(std::size_t style_id) const
return d_->styles_[style_id].protection_;
}
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)
{
return style_id;
}
@ -728,85 +712,85 @@ std::size_t workbook::set_number_format(const xlnt::number_format &format, std::
{
auto match = std::find(d_->number_formats_.begin(), d_->number_formats_.end(), format);
std::size_t format_id = 0;
if(match == d_->number_formats_.end())
if (match == d_->number_formats_.end())
{
d_->number_formats_.push_back(format);
if(format.get_id() == -1)
if (format.get_id() == -1)
{
d_->number_formats_.back().set_id(d_->next_custom_format_id_++);
}
format_id = d_->number_formats_.back().get_id();
}
else
{
format_id = match->get_id();
}
if(d_->styles_.empty())
if (d_->styles_.empty())
{
style new_style;
new_style.id_ = 0;
new_style.border_id_ = 0;
new_style.fill_id_ = 0;
new_style.font_id_ = 0;
new_style.number_format_id_ = format_id;
new_style.number_format_apply_ = true;
if(d_->borders_.empty())
if (d_->borders_.empty())
{
d_->borders_.push_back(new_style.get_border());
}
if(d_->fills_.empty())
if (d_->fills_.empty())
{
d_->fills_.push_back(new_style.get_fill());
}
if(d_->fonts_.empty())
if (d_->fonts_.empty())
{
d_->fonts_.push_back(new_style.get_font());
}
d_->styles_.push_back(new_style);
return 0;
}
// If the style is unchanged, just return it.
auto existing_style = d_->styles_[style_id];
existing_style.number_format_apply_ = true;
if(format_id == existing_style.number_format_id_)
if (format_id == existing_style.number_format_id_)
{
// no change
return style_id;
}
// Make a new style with this format.
auto new_style = existing_style;
new_style.number_format_id_ = format_id;
new_style.number_format_ = format;
// Check if the new style is already applied to a different cell. If so, reuse it.
auto style_match = std::find(d_->styles_.begin(), d_->styles_.end(), new_style);
if(style_match != d_->styles_.end())
if (style_match != d_->styles_.end())
{
return style_match->get_id();
}
// No match found, so add it.
new_style.id_ = d_->styles_.size();
d_->styles_.push_back(new_style);
return new_style.id_;
}
std::vector<style> workbook::get_styles() const
{
return d_->styles_;
@ -831,7 +815,7 @@ std::vector<fill> workbook::get_fills() const
{
return d_->fills_;
}
void workbook::add_color(const color &rgb)
{
d_->colors_.push_back(rgb);
@ -851,7 +835,7 @@ manifest &workbook::get_manifest()
{
return d_->manifest_;
}
const manifest &workbook::get_manifest() const
{
return d_->manifest_;
@ -859,13 +843,15 @@ const manifest &workbook::get_manifest() const
const std::vector<relationship> &workbook::get_root_relationships() const
{
if(d_->root_relationships_.empty())
if (d_->root_relationships_.empty())
{
d_->root_relationships_.push_back(relationship(relationship::type::core_properties, "rId1", "docProps/core.xml"));
d_->root_relationships_.push_back(relationship(relationship::type::extended_properties, "rId2", "docProps/app.xml"));
d_->root_relationships_.push_back(
relationship(relationship::type::core_properties, "rId1", "docProps/core.xml"));
d_->root_relationships_.push_back(
relationship(relationship::type::extended_properties, "rId2", "docProps/app.xml"));
d_->root_relationships_.push_back(relationship(relationship::type::office_document, "rId3", "xl/workbook.xml"));
}
return d_->root_relationships_;
}

View File

@ -5,24 +5,24 @@
namespace xlnt {
template<>
template <>
cell cell_vector::iterator::operator*()
{
return ws_[current_cell_];
}
cell_vector::iterator cell_vector::begin()
{
return iterator(ws_, ref_.get_top_left(), order_);
return iterator(ws_, ref_.get_top_left(), order_);
}
cell_vector::iterator cell_vector::end()
{
if(order_ == major_order::row)
if (order_ == major_order::row)
{
auto past_end = ref_.get_bottom_right();
past_end.set_column_index(past_end.get_column_index() + 1);
return iterator(ws_, past_end, order_);
past_end.set_column_index(past_end.get_column_index() + 1);
return iterator(ws_, past_end, order_);
}
auto past_end = ref_.get_bottom_right();
@ -32,16 +32,16 @@ cell_vector::iterator cell_vector::end()
cell_vector::const_iterator cell_vector::cbegin() const
{
return const_iterator(ws_, ref_.get_top_left(), order_);
return const_iterator(ws_, ref_.get_top_left(), order_);
}
cell_vector::const_iterator cell_vector::cend() const
{
if(order_ == major_order::row)
if (order_ == major_order::row)
{
auto past_end = ref_.get_bottom_right();
past_end.set_column_index(past_end.get_column_index() + 1);
return const_iterator(ws_, past_end, order_);
past_end.set_column_index(past_end.get_column_index() + 1);
return const_iterator(ws_, past_end, order_);
}
auto past_end = ref_.get_bottom_right();
@ -56,7 +56,7 @@ cell cell_vector::operator[](std::size_t cell_index)
std::size_t cell_vector::num_cells() const
{
if(order_ == major_order::row)
if (order_ == major_order::row)
{
return ref_.get_width() + 1;
}
@ -65,15 +65,13 @@ std::size_t cell_vector::num_cells() const
}
cell_vector::cell_vector(worksheet ws, const range_reference &reference, major_order order)
: ws_(ws),
ref_(reference),
order_(order)
: ws_(ws), ref_(reference), order_(order)
{
}
cell cell_vector::front()
{
if(order_ == major_order::row)
if (order_ == major_order::row)
{
return get_cell(ref_.get_top_left().get_column_index());
}
@ -83,7 +81,7 @@ cell cell_vector::front()
cell cell_vector::back()
{
if(order_ == major_order::row)
if (order_ == major_order::row)
{
return get_cell(ref_.get_bottom_right().get_column_index());
}
@ -93,20 +91,17 @@ cell cell_vector::back()
cell cell_vector::get_cell(std::size_t index)
{
if(order_ == major_order::row)
if (order_ == major_order::row)
{
return ws_.get_cell(ref_.get_top_left().make_offset((int)index, 0));
}
return ws_.get_cell(ref_.get_top_left().make_offset(0, (int)index));
}
}
range::range(worksheet ws, const range_reference &reference, major_order order)
: ws_(ws),
ref_(reference),
order_(order)
: ws_(ws), ref_(reference), order_(order)
{
}
range::~range()
@ -125,44 +120,46 @@ range_reference range::get_reference() const
std::size_t range::length() const
{
if(order_ == major_order::row)
if (order_ == major_order::row)
{
return ref_.get_bottom_right().get_row() - ref_.get_top_left().get_row() + 1;
}
return ref_.get_bottom_right().get_column_index() - ref_.get_top_left().get_column_index() + 1;
}
bool range::operator==(const range &comparand) const
{
return ref_ == comparand.ref_
&& ws_ == comparand.ws_
&& order_ == comparand.order_;
return ref_ == comparand.ref_ && ws_ == comparand.ws_ && order_ == comparand.order_;
}
cell_vector range::get_vector(std::size_t vector_index)
{
if(order_ == major_order::row)
if (order_ == major_order::row)
{
range_reference reference(ref_.get_top_left().get_column_index(),
range_reference reference(
ref_.get_top_left().get_column_index(),
static_cast<row_t>(static_cast<std::size_t>(ref_.get_top_left().get_row()) + vector_index),
ref_.get_bottom_right().get_column_index(),
static_cast<row_t>(static_cast<std::size_t>(ref_.get_top_left().get_row()) + vector_index));
return cell_vector(ws_, reference, order_);
}
range_reference reference(static_cast<column_t>(static_cast<std::size_t>(ref_.get_top_left().get_column_index()) + vector_index),
ref_.get_top_left().get_row(),
static_cast<column_t>(static_cast<std::size_t>(ref_.get_top_left().get_column_index()) + vector_index),
ref_.get_bottom_right().get_row());
range_reference reference(
static_cast<column_t>(static_cast<std::size_t>(ref_.get_top_left().get_column_index()) + vector_index),
ref_.get_top_left().get_row(),
static_cast<column_t>(static_cast<std::size_t>(ref_.get_top_left().get_column_index()) + vector_index),
ref_.get_bottom_right().get_row());
return cell_vector(ws_, reference, order_);
}
bool range::contains(const cell_reference &ref)
{
return ref_.get_top_left().get_column_index() <= ref.get_column_index() && ref_.get_bottom_right().get_column_index() >= ref.get_column_index() && ref_.get_top_left().get_row() <= ref.get_row() && ref_.get_bottom_right().get_row() >= ref.get_row();
return ref_.get_top_left().get_column_index() <= ref.get_column_index() &&
ref_.get_bottom_right().get_column_index() >= ref.get_column_index() &&
ref_.get_top_left().get_row() <= ref.get_row() && ref_.get_bottom_right().get_row() >= ref.get_row();
}
cell range::get_cell(const cell_reference &ref)
@ -172,28 +169,26 @@ cell range::get_cell(const cell_reference &ref)
range::iterator range::begin()
{
if(order_ == major_order::row)
if (order_ == major_order::row)
{
cell_reference top_right(ref_.get_bottom_right().get_column_index(),
ref_.get_top_left().get_row());
range_reference row_range(ref_.get_top_left(), top_right);
return iterator(ws_, row_range, order_);
cell_reference top_right(ref_.get_bottom_right().get_column_index(), ref_.get_top_left().get_row());
range_reference row_range(ref_.get_top_left(), top_right);
return iterator(ws_, row_range, order_);
}
cell_reference bottom_left(ref_.get_top_left().get_column_index(),
ref_.get_bottom_right().get_row());
cell_reference bottom_left(ref_.get_top_left().get_column_index(), ref_.get_bottom_right().get_row());
range_reference row_range(ref_.get_top_left(), bottom_left);
return iterator(ws_, row_range, order_);
}
range::iterator range::end()
{
if(order_ == major_order::row)
if (order_ == major_order::row)
{
auto past_end_row_index = ref_.get_bottom_right().get_row() + 1;
cell_reference bottom_left(ref_.get_top_left().get_column_index(), past_end_row_index);
cell_reference bottom_right(ref_.get_bottom_right().get_column_index(), past_end_row_index);
return iterator(ws_, range_reference(bottom_left, bottom_right), order_);
cell_reference bottom_left(ref_.get_top_left().get_column_index(), past_end_row_index);
cell_reference bottom_right(ref_.get_bottom_right().get_column_index(), past_end_row_index);
return iterator(ws_, range_reference(bottom_left, bottom_right), order_);
}
auto past_end_column_index = ref_.get_bottom_right().get_column_index() + 1;
@ -204,28 +199,26 @@ range::iterator range::end()
range::const_iterator range::cbegin() const
{
if(order_ == major_order::row)
if (order_ == major_order::row)
{
cell_reference top_right(ref_.get_bottom_right().get_column_index(),
ref_.get_top_left().get_row());
range_reference row_range(ref_.get_top_left(), top_right);
return const_iterator(ws_, row_range, order_);
cell_reference top_right(ref_.get_bottom_right().get_column_index(), ref_.get_top_left().get_row());
range_reference row_range(ref_.get_top_left(), top_right);
return const_iterator(ws_, row_range, order_);
}
cell_reference bottom_left(ref_.get_top_left().get_column_index(),
ref_.get_bottom_right().get_row());
cell_reference bottom_left(ref_.get_top_left().get_column_index(), ref_.get_bottom_right().get_row());
range_reference row_range(ref_.get_top_left(), bottom_left);
return const_iterator(ws_, row_range, order_);
}
range::const_iterator range::cend() const
{
if(order_ == major_order::row)
if (order_ == major_order::row)
{
auto past_end_row_index = ref_.get_bottom_right().get_row() + 1;
cell_reference bottom_left(ref_.get_top_left().get_column_index(), past_end_row_index);
cell_reference bottom_right(ref_.get_bottom_right().get_column_index(), past_end_row_index);
return const_iterator(ws_, range_reference(bottom_left, bottom_right), order_);
cell_reference bottom_left(ref_.get_top_left().get_column_index(), past_end_row_index);
cell_reference bottom_right(ref_.get_bottom_right().get_column_index(), past_end_row_index);
return const_iterator(ws_, range_reference(bottom_left, bottom_right), order_);
}
auto past_end_column_index = ref_.get_bottom_right().get_column_index() + 1;
@ -234,22 +227,18 @@ range::const_iterator range::cend() const
return const_iterator(ws_, range_reference(top_right, bottom_right), order_);
}
template<>
template <>
cell_vector range::iterator::operator*()
{
if(order_ == major_order::row)
if (order_ == major_order::row)
{
range_reference reference(range_.get_top_left().get_column_index(),
current_cell_.get_row(),
range_.get_bottom_right().get_column_index(),
current_cell_.get_row());
return cell_vector(ws_, reference, order_);
range_reference reference(range_.get_top_left().get_column_index(), current_cell_.get_row(),
range_.get_bottom_right().get_column_index(), current_cell_.get_row());
return cell_vector(ws_, reference, order_);
}
range_reference reference(current_cell_.get_column_index(),
range_.get_top_left().get_row(),
current_cell_.get_column_index(),
range_.get_bottom_right().get_row());
range_reference reference(current_cell_.get_column_index(), range_.get_top_left().get_row(),
current_cell_.get_column_index(), range_.get_bottom_right().get_row());
return cell_vector(ws_, reference, order_);
}

View File

@ -20,13 +20,11 @@ range_reference::range_reference(const char *range_string) : range_reference(std
{
}
range_reference::range_reference(const std::string &range_string)
: top_left_("A1"),
bottom_right_("A1")
range_reference::range_reference(const std::string &range_string) : top_left_("A1"), bottom_right_("A1")
{
auto colon_index = range_string.find(':');
if(colon_index != std::string::npos)
if (colon_index != std::string::npos)
{
top_left_ = cell_reference(range_string.substr(0, colon_index));
bottom_right_ = cell_reference(range_string.substr(colon_index + 1));
@ -39,22 +37,20 @@ range_reference::range_reference(const std::string &range_string)
}
range_reference::range_reference(const cell_reference &top_left, const cell_reference &bottom_right)
: top_left_(top_left),
bottom_right_(bottom_right)
: top_left_(top_left), bottom_right_(bottom_right)
{
}
range_reference::range_reference(column_t column_index_start, row_t row_index_start, column_t column_index_end, row_t row_index_end)
: top_left_(column_index_start, row_index_start),
bottom_right_(column_index_end, row_index_end)
range_reference::range_reference(column_t column_index_start, row_t row_index_start, column_t column_index_end,
row_t row_index_end)
: top_left_(column_index_start, row_index_start), bottom_right_(column_index_end, row_index_end)
{
}
range_reference range_reference::make_offset(int column_offset, int row_offset) const
{
return range_reference(top_left_.make_offset(column_offset, row_offset), bottom_right_.make_offset(column_offset, row_offset));
return range_reference(top_left_.make_offset(column_offset, row_offset),
bottom_right_.make_offset(column_offset, row_offset));
}
row_t range_reference::get_height() const
@ -79,14 +75,11 @@ std::string range_reference::to_string() const
bool range_reference::operator==(const range_reference &comparand) const
{
return comparand.top_left_ == top_left_
&& comparand.bottom_right_ == bottom_right_;
return comparand.top_left_ == top_left_ && comparand.bottom_right_ == bottom_right_;
}
bool range_reference::operator!=(const range_reference &comparand) const
{
return comparand.top_left_ != top_left_
|| comparand.bottom_right_ != bottom_right_;
return comparand.top_left_ != top_left_ || comparand.bottom_right_ != bottom_right_;
}
}

View File

@ -11,7 +11,7 @@ void sheet_protection::set_password(const std::string &password)
hashed_password_ = hash_password(password);
}
template< typename T >
template <typename T>
std::string int_to_hex(T i)
{
std::stringstream stream;
@ -23,8 +23,8 @@ std::string sheet_protection::hash_password(const std::string &plaintext_passwor
{
int password = 0x0000;
int i = 1;
for(auto character : plaintext_password)
for (auto character : plaintext_password)
{
int value = character << i;
int rotated_bits = value >> 15;
@ -32,13 +32,13 @@ std::string sheet_protection::hash_password(const std::string &plaintext_passwor
password ^= (value | rotated_bits);
i++;
}
password ^= plaintext_password.size();
password ^= 0xCE4B;
std::string hashed = int_to_hex(password);
std::transform(hashed.begin(), hashed.end(), hashed.begin(), [](char c){ return std::toupper(c, std::locale::classic()); });
std::transform(hashed.begin(), hashed.end(), hashed.begin(),
[](char c) { return std::toupper(c, std::locale::classic()); });
return hashed;
}
}

View File

@ -16,20 +16,18 @@ namespace xlnt {
worksheet::worksheet() : d_(nullptr)
{
}
worksheet::worksheet(detail::worksheet_impl *d) : d_(d)
{
}
worksheet::worksheet(const worksheet &rhs) : d_(rhs.d_)
{
}
worksheet::worksheet(workbook &parent, const std::string &title) : d_(title == "" ? parent.create_sheet().d_ : parent.create_sheet(title).d_)
worksheet::worksheet(workbook &parent, const std::string &title)
: d_(title == "" ? parent.create_sheet().d_ : parent.create_sheet(title).d_)
{
}
@ -43,7 +41,7 @@ std::string worksheet::unique_sheet_name(const std::string &value) const
auto names = get_parent().get_sheet_names();
auto match = std::find(names.begin(), names.end(), value);
std::size_t append = 0;
while(match != names.end())
while (match != names.end())
{
append++;
match = std::find(names.begin(), names.end(), value + std::to_string(append));
@ -54,13 +52,13 @@ std::string worksheet::unique_sheet_name(const std::string &value) const
void worksheet::create_named_range(const std::string &name, const range_reference &reference)
{
std::vector<named_range::target> targets;
targets.push_back({*this, reference});
targets.push_back({ *this, reference });
d_->named_ranges_[name] = named_range(name, targets);
}
range worksheet::operator()(const xlnt::cell_reference &top_left, const xlnt::cell_reference &bottom_right)
{
return get_range({top_left, bottom_right});
return get_range({ top_left, bottom_right });
}
cell worksheet::operator[](const cell_reference &ref)
@ -132,15 +130,15 @@ void worksheet::garbage_collect()
{
auto cell_map_iter = d_->cell_map_.begin();
while(cell_map_iter != d_->cell_map_.end())
while (cell_map_iter != d_->cell_map_.end())
{
auto cell_iter = cell_map_iter->second.begin();
while(cell_iter != cell_map_iter->second.end())
while (cell_iter != cell_map_iter->second.end())
{
cell current_cell(&cell_iter->second);
if(current_cell.garbage_collectible())
if (current_cell.garbage_collectible())
{
cell_iter = cell_map_iter->second.erase(cell_iter);
continue;
@ -149,7 +147,7 @@ void worksheet::garbage_collect()
cell_iter++;
}
if(cell_map_iter->second.empty())
if (cell_map_iter->second.empty())
{
cell_map_iter = d_->cell_map_.erase(cell_map_iter);
continue;
@ -162,9 +160,9 @@ void worksheet::garbage_collect()
std::list<cell> worksheet::get_cell_collection()
{
std::list<cell> cells;
for(auto &c : d_->cell_map_)
for (auto &c : d_->cell_map_)
{
for(auto &d : c.second)
for (auto &d : c.second)
{
cells.push_back(cell(&d.second));
}
@ -174,7 +172,7 @@ std::list<cell> worksheet::get_cell_collection()
std::string worksheet::get_title() const
{
if(d_ == nullptr)
if (d_ == nullptr)
{
throw std::runtime_error("null worksheet");
}
@ -208,18 +206,18 @@ void worksheet::unfreeze_panes()
cell worksheet::get_cell(const cell_reference &reference)
{
if(d_->cell_map_.find(reference.get_row()) == d_->cell_map_.end())
if (d_->cell_map_.find(reference.get_row()) == d_->cell_map_.end())
{
d_->cell_map_[reference.get_row()] = std::unordered_map<column_t, detail::cell_impl>();
}
auto &row = d_->cell_map_[reference.get_row()];
if(row.find(reference.get_column_index()) == row.end())
if (row.find(reference.get_column_index()) == row.end())
{
row[reference.get_column_index()] = detail::cell_impl(d_, reference.get_column_index(), reference.get_row());
}
return cell(&row[reference.get_column_index()]);
}
@ -235,75 +233,75 @@ bool worksheet::has_row_properties(row_t row) const
range worksheet::get_named_range(const std::string &name)
{
if(!has_named_range(name))
if (!has_named_range(name))
{
throw named_range_exception();
}
return get_range(d_->named_ranges_[name].get_targets()[0].second);
}
column_t worksheet::get_lowest_column() const
{
if(d_->cell_map_.empty())
if (d_->cell_map_.empty())
{
return 1;
}
column_t lowest = std::numeric_limits<column_t>::max();
for(auto &row : d_->cell_map_)
for (auto &row : d_->cell_map_)
{
for(auto &c : row.second)
for (auto &c : row.second)
{
lowest = std::min(lowest, (column_t)c.first);
}
}
return lowest;
}
row_t worksheet::get_lowest_row() const
{
if(d_->cell_map_.empty())
if (d_->cell_map_.empty())
{
return 1;
}
row_t lowest = std::numeric_limits<row_t>::max();
for(auto &row : d_->cell_map_)
for (auto &row : d_->cell_map_)
{
lowest = std::min(lowest, (row_t)row.first);
}
return lowest;
}
row_t worksheet::get_highest_row() const
{
row_t highest = 1;
for(auto &row : d_->cell_map_)
for (auto &row : d_->cell_map_)
{
highest = std::max(highest, (row_t)row.first);
}
return highest;
}
column_t worksheet::get_highest_column() const
{
column_t highest = 1;
for(auto &row : d_->cell_map_)
for (auto &row : d_->cell_map_)
{
for(auto &c : row.second)
for (auto &c : row.second)
{
highest = std::max(highest, (column_t)c.first);
}
}
return highest;
}
@ -311,10 +309,10 @@ range_reference worksheet::calculate_dimension() const
{
auto lowest_column = get_lowest_column();
auto lowest_row = get_lowest_row();
auto highest_column = get_highest_column();
auto highest_row = get_highest_row();
return range_reference(lowest_column, lowest_row, highest_column, highest_row);
}
@ -357,15 +355,15 @@ void worksheet::merge_cells(const range_reference &reference)
d_->merged_cells_.push_back(reference);
bool first = true;
for(auto row : get_range(reference))
for (auto row : get_range(reference))
{
for(auto cell : row)
for (auto cell : row)
{
cell.set_merged(true);
if(!first)
if (!first)
{
if(cell.get_data_type() == cell::type::string)
if (cell.get_data_type() == cell::type::string)
{
cell.set_value("");
}
@ -388,23 +386,23 @@ void worksheet::merge_cells(column_t start_column, row_t start_row, column_t end
void worksheet::unmerge_cells(const range_reference &reference)
{
auto match = std::find(d_->merged_cells_.begin(), d_->merged_cells_.end(), reference);
if(match == d_->merged_cells_.end())
if (match == d_->merged_cells_.end())
{
throw std::runtime_error("cells not merged");
}
d_->merged_cells_.erase(match);
for(auto row : get_range(reference))
for (auto row : get_range(reference))
{
for(auto cell : row)
for (auto cell : row)
{
cell.set_merged(false);
}
}
}
void worksheet::unmerge_cells(column_t start_column, row_t start_row, column_t end_column, row_t end_row)
{
unmerge_cells(xlnt::range_reference(start_column, start_row, end_column, end_row));
@ -418,31 +416,31 @@ void worksheet::append()
void worksheet::append(const std::vector<std::string> &cells)
{
xlnt::cell_reference next(1, get_next_row());
for(auto cell : cells)
for (auto cell : cells)
{
get_cell(next).set_value(cell);
next.set_column_index(next.get_column_index() + 1);
}
}
row_t worksheet::get_next_row() const
{
auto row = get_highest_row() + 1;
if(row == 2 && d_->cell_map_.size() == 0)
if (row == 2 && d_->cell_map_.size() == 0)
{
row = 1;
}
return row;
}
void worksheet::append(const std::vector<int> &cells)
{
xlnt::cell_reference next(1, get_next_row());
for(auto cell : cells)
for (auto cell : cells)
{
get_cell(next).set_value(cell);
next.set_column_index(next.get_column_index() + 1);
@ -452,8 +450,8 @@ void worksheet::append(const std::vector<int> &cells)
void worksheet::append(const std::vector<date> &cells)
{
xlnt::cell_reference next(1, get_next_row());
for(auto cell : cells)
for (auto cell : cells)
{
get_cell(next).set_value(cell);
next.set_column_index(next.get_column_index() + 1);
@ -463,19 +461,19 @@ void worksheet::append(const std::vector<date> &cells)
void worksheet::append(const std::vector<cell> &cells)
{
xlnt::cell_reference next(1, get_next_row());
for(auto cell : cells)
for (auto cell : cells)
{
get_cell(next).set_value(cell);
next.set_column_index(next.get_column_index() + 1);
}
}
void worksheet::append(const std::unordered_map<std::string, std::string> &cells)
{
auto row = get_next_row();
for(auto cell : cells)
for (auto cell : cells)
{
get_cell(cell_reference(cell.first, row)).set_value(cell.second);
}
@ -484,18 +482,18 @@ void worksheet::append(const std::unordered_map<std::string, std::string> &cells
void worksheet::append(const std::unordered_map<int, std::string> &cells)
{
auto row = get_next_row();
for(auto cell : cells)
for (auto cell : cells)
{
get_cell(cell_reference(static_cast<column_t>(cell.first), row)).set_value(cell.second);
}
}
void worksheet::append(const std::vector<int>::const_iterator begin, const std::vector<int>::const_iterator end)
{
xlnt::cell_reference next(1, get_next_row());
for(auto i = begin; i != end; i++)
for (auto i = begin; i != end; i++)
{
get_cell(next).set_value(*i);
next.set_column_index(next.get_column_index() + 1);
@ -543,7 +541,6 @@ bool worksheet::operator!=(std::nullptr_t) const
return d_ != nullptr;
}
void worksheet::operator=(const worksheet &other)
{
d_ = other.d_;
@ -561,7 +558,7 @@ range worksheet::operator[](const range_reference &ref)
range worksheet::operator[](const std::string &name)
{
if(has_named_range(name))
if (has_named_range(name))
{
return get_named_range(name);
}
@ -575,7 +572,7 @@ bool worksheet::has_named_range(const std::string &name)
void worksheet::remove_named_range(const std::string &name)
{
if(!has_named_range(name))
if (!has_named_range(name))
{
throw std::runtime_error("worksheet doesn't have named range");
}
@ -587,7 +584,7 @@ void worksheet::reserve(std::size_t n)
{
d_->cell_map_.reserve(n);
}
void worksheet::increment_comments()
{
d_->comment_count_++;
@ -615,17 +612,14 @@ const header_footer &worksheet::get_header_footer() const
header_footer::header_footer()
{
}
header::header() : default_(true), font_size_(12)
{
}
footer::footer() : default_(true), font_size_(12)
{
}
void worksheet::set_parent(xlnt::workbook &wb)
@ -644,7 +638,7 @@ cell_reference worksheet::get_point_pos(int left, int top) const
static const double DefaultRowHeight = 15.0;
auto points_to_pixels = [](double value, double dpi) { return (int)std::ceil(value * dpi / 72); };
auto default_height = points_to_pixels(DefaultRowHeight, 96.0);
auto default_width = points_to_pixels(DefaultColumnWidth, 96.0);
@ -654,15 +648,15 @@ cell_reference worksheet::get_point_pos(int left, int top) const
int left_pos = 0;
int top_pos = 0;
while(left_pos <= left)
while (left_pos <= left)
{
current_column++;
if(has_column_properties(current_column))
if (has_column_properties(current_column))
{
auto cdw = get_column_properties(current_column).width;
if(cdw >= 0)
if (cdw >= 0)
{
left_pos += points_to_pixels(cdw, 96.0);
continue;
@ -672,15 +666,15 @@ cell_reference worksheet::get_point_pos(int left, int top) const
left_pos += default_width;
}
while(top_pos <= top)
while (top_pos <= top)
{
current_row++;
if(has_row_properties(current_row))
if (has_row_properties(current_row))
{
auto cdh = get_row_properties(current_row).height;
if(cdh >= 0)
if (cdh >= 0)
{
top_pos += points_to_pixels(cdh, 96.0);
continue;
@ -690,14 +684,14 @@ cell_reference worksheet::get_point_pos(int left, int top) const
top_pos += default_height;
}
return {current_column - 1, current_row - 1};
return { current_column - 1, current_row - 1 };
}
cell_reference worksheet::get_point_pos(const std::pair<int, int> &point) const
{
return get_point_pos(point.first, point.second);
}
void worksheet::set_sheet_state(page_setup::sheet_state state)
{
get_page_setup().set_sheet_state(state);