mirror of
https://github.com/tfussell/xlnt.git
synced 2024-03-22 13:11:17 +08:00
clang-format all files, update .clang-format, fix minor compilation errors
This commit is contained in:
parent
3a50c2bb9d
commit
7f840bb904
|
@ -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
|
||||
|
||||
...
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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_;
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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("")
|
||||
{
|
||||
}
|
||||
|
|
|
@ -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
|
|
@ -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
|
||||
|
|
|
@ -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();
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
||||
}
|
||||
|
|
|
@ -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_;
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
namespace xlnt {
|
||||
|
||||
class tokenizer {
|
||||
|
||||
class tokenizer
|
||||
{
|
||||
};
|
||||
|
||||
|
||||
} // namespace xlnt
|
||||
|
|
|
@ -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_;
|
||||
|
|
|
@ -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_;
|
||||
};
|
||||
|
||||
|
|
|
@ -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>
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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);
|
||||
};
|
||||
|
|
|
@ -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>
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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_;
|
||||
};
|
||||
|
||||
|
|
|
@ -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_;
|
||||
};
|
||||
|
||||
|
|
|
@ -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_;
|
||||
};
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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_;
|
||||
|
|
|
@ -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_;
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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_;
|
||||
};
|
||||
|
|
|
@ -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_;
|
||||
};
|
||||
|
|
|
@ -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_;
|
||||
};
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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_;
|
||||
};
|
||||
|
|
|
@ -34,9 +34,9 @@ namespace xlnt {
|
|||
/// </summary>
|
||||
class document_properties
|
||||
{
|
||||
public:
|
||||
public:
|
||||
document_properties();
|
||||
|
||||
|
||||
std::string creator;
|
||||
std::string last_modified_by;
|
||||
datetime created;
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -2,8 +2,7 @@
|
|||
|
||||
namespace xlnt {
|
||||
|
||||
class external_book {
|
||||
|
||||
class external_book
|
||||
{
|
||||
};
|
||||
|
||||
}
|
||||
|
|
|
@ -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
|
|
@ -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_;
|
||||
};
|
||||
|
||||
}
|
||||
|
|
|
@ -4,7 +4,6 @@ namespace xlnt {
|
|||
|
||||
class theme
|
||||
{
|
||||
|
||||
};
|
||||
|
||||
|
||||
} // namespace xlnt
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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_;
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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_;
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -24,10 +24,8 @@
|
|||
|
||||
namespace xlnt {
|
||||
|
||||
class selection {
|
||||
|
||||
};
|
||||
|
||||
class selection
|
||||
{
|
||||
};
|
||||
|
||||
} // namespace xlnt
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -23,7 +23,7 @@
|
|||
#pragma once
|
||||
|
||||
namespace xlnt {
|
||||
|
||||
|
||||
class sheet_view
|
||||
{
|
||||
};
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -25,7 +25,8 @@
|
|||
|
||||
namespace xlnt {
|
||||
|
||||
class worksheet_properties {
|
||||
class worksheet_properties
|
||||
{
|
||||
};
|
||||
|
||||
} // namespace xlnt
|
||||
|
|
|
@ -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
|
@ -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
|
||||
|
|
|
@ -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_;
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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)
|
||||
{
|
||||
}
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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_;
|
||||
};
|
||||
|
|
|
@ -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" }
|
||||
};
|
||||
|
||||
}
|
||||
|
|
|
@ -35,5 +35,5 @@ struct constants
|
|||
|
||||
static const std::unordered_map<std::string, std::string> Namespaces;
|
||||
};
|
||||
|
||||
|
||||
} // namespace xlnt
|
||||
|
|
31
source/detail/include_windows.hpp
Normal file
31
source/detail/include_windows.hpp
Normal 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
|
|
@ -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_;
|
||||
};
|
||||
|
||||
|
|
|
@ -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_;
|
||||
|
|
|
@ -12,6 +12,6 @@ struct xml_document_impl
|
|||
std::string encoding;
|
||||
pugi::xml_document doc;
|
||||
};
|
||||
|
||||
|
||||
} // namespace detail
|
||||
} // namespace xlnt
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -6,13 +6,11 @@ struct drawing_struct
|
|||
{
|
||||
drawing_struct()
|
||||
{
|
||||
|
||||
}
|
||||
};
|
||||
|
||||
drawing::drawing() : root_(nullptr)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
} // namespace xlnt
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
#include <xlnt/s11n/comment_serializer.hpp>
|
||||
|
||||
namespace {
|
||||
|
||||
|
||||
} // namespace xlnt
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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";
|
||||
}
|
||||
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -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
|
@ -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
|
||||
|
|
|
@ -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());
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -5,7 +5,6 @@ namespace xlnt {
|
|||
|
||||
side::side()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
|
||||
} // namespace xlnt
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -4,12 +4,10 @@ namespace xlnt {
|
|||
|
||||
protection::protection() : protection(type::unprotected)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
protection::protection(type t) : locked_(t), hidden_(type::unprotected)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
} // namespace xlnt
|
||||
|
|
|
@ -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_;
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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();
|
||||
}
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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_;
|
||||
}
|
||||
|
||||
|
|
|
@ -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_);
|
||||
}
|
||||
|
||||
|
|
|
@ -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_;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
|
|
Loading…
Reference in New Issue
Block a user