mirror of
https://github.com/tfussell/xlnt.git
synced 2024-03-22 13:11:17 +08:00
use value_traits for enum parsing/serialization and refactor xlsx_producer helper functions
This commit is contained in:
parent
afb9c75369
commit
a81a0a6dde
|
@ -146,4 +146,13 @@ public:
|
|||
no_visible_worksheets();
|
||||
};
|
||||
|
||||
/// <summary>
|
||||
/// Debug exception for a switch that fell through to the default case
|
||||
/// </summary>
|
||||
class XLNT_CLASS unhandled_switch_case : public exception
|
||||
{
|
||||
public:
|
||||
unhandled_switch_case();
|
||||
};
|
||||
|
||||
} // namespace xlnt
|
||||
|
|
155
source/detail/custom_value_traits.cpp
Normal file
155
source/detail/custom_value_traits.cpp
Normal file
|
@ -0,0 +1,155 @@
|
|||
#include <detail/custom_value_traits.hpp>
|
||||
|
||||
namespace xlnt {
|
||||
namespace detail {
|
||||
|
||||
/// <summary>
|
||||
/// Returns the string representation of the underline style.
|
||||
/// </summary>
|
||||
std::string to_string(font::underline_style underline_style)
|
||||
{
|
||||
switch (underline_style)
|
||||
{
|
||||
case font::underline_style::double_: return "double";
|
||||
case font::underline_style::double_accounting: return "doubleAccounting";
|
||||
case font::underline_style::single: return "single";
|
||||
case font::underline_style::single_accounting: return "singleAccounting";
|
||||
case font::underline_style::none: return "none";
|
||||
default: return default_case("none");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Returns the string representation of the relationship type.
|
||||
/// </summary>
|
||||
std::string to_string(relationship::type t)
|
||||
{
|
||||
switch (t)
|
||||
{
|
||||
case relationship::type::office_document:
|
||||
return "http://schemas.openxmlformats.org/officeDocument/2006/relationships/officeDocument";
|
||||
case relationship::type::thumbnail:
|
||||
return "http://schemas.openxmlformats.org/package/2006/relationships/metadata/thumbnail";
|
||||
case relationship::type::calculation_chain:
|
||||
return "http://purl.oclc.org/ooxml/officeDocument/relationships/calcChain";
|
||||
case relationship::type::extended_properties:
|
||||
return "http://schemas.openxmlformats.org/officeDocument/2006/relationships/extended-properties";
|
||||
case relationship::type::core_properties:
|
||||
return "http://schemas.openxmlformats.org/package/2006/relationships/metadata/core-properties";
|
||||
case relationship::type::worksheet:
|
||||
return "http://schemas.openxmlformats.org/officeDocument/2006/relationships/worksheet";
|
||||
case relationship::type::shared_string_table:
|
||||
return "http://schemas.openxmlformats.org/officeDocument/2006/relationships/sharedStrings";
|
||||
case relationship::type::styles:
|
||||
return "http://schemas.openxmlformats.org/officeDocument/2006/relationships/styles";
|
||||
case relationship::type::theme:
|
||||
return "http://schemas.openxmlformats.org/officeDocument/2006/relationships/theme";
|
||||
case relationship::type::hyperlink:
|
||||
return "http://schemas.openxmlformats.org/officeDocument/2006/relationships/hyperlink";
|
||||
case relationship::type::chartsheet:
|
||||
return "http://schemas.openxmlformats.org/officeDocument/2006/relationships/chartsheet";
|
||||
default:
|
||||
return default_case("?");
|
||||
}
|
||||
}
|
||||
|
||||
std::string to_string(pattern_fill_type fill_type)
|
||||
{
|
||||
switch (fill_type)
|
||||
{
|
||||
case pattern_fill_type::darkdown: return "darkdown";
|
||||
case pattern_fill_type::darkgray: return "darkgray";
|
||||
case pattern_fill_type::darkgrid: return "darkgrid";
|
||||
case pattern_fill_type::darkhorizontal: return "darkhorizontal";
|
||||
case pattern_fill_type::darktrellis: return "darkhorizontal";
|
||||
case pattern_fill_type::darkup: return "darkup";
|
||||
case pattern_fill_type::darkvertical: return "darkvertical";
|
||||
case pattern_fill_type::gray0625: return "gray0625";
|
||||
case pattern_fill_type::gray125: return "gray125";
|
||||
case pattern_fill_type::lightdown: return "lightdown";
|
||||
case pattern_fill_type::lightgray: return "lightgray";
|
||||
case pattern_fill_type::lightgrid: return "lightgrid";
|
||||
case pattern_fill_type::lighthorizontal: return "lighthorizontal";
|
||||
case pattern_fill_type::lighttrellis: return "lighttrellis";
|
||||
case pattern_fill_type::lightup: return "lightup";
|
||||
case pattern_fill_type::lightvertical: return "lightvertical";
|
||||
case pattern_fill_type::mediumgray: return "mediumgray";
|
||||
case pattern_fill_type::solid: return "solid";
|
||||
case pattern_fill_type::none: return "none";
|
||||
default: return default_case("none");
|
||||
}
|
||||
}
|
||||
|
||||
std::string to_string(gradient_fill_type fill_type)
|
||||
{
|
||||
return fill_type == gradient_fill_type::linear ? "linear" : "path";
|
||||
}
|
||||
|
||||
std::string to_string(border_style border_style)
|
||||
{
|
||||
switch (border_style)
|
||||
{
|
||||
case border_style::dashdot: return "dashdot";
|
||||
case border_style::dashdotdot: return "dashdotdot";
|
||||
case border_style::dashed: return "dashed";
|
||||
case border_style::dotted: return "dotted";
|
||||
case border_style::double_: return "double";
|
||||
case border_style::hair: return "hair";
|
||||
case border_style::medium: return "medium";
|
||||
case border_style::mediumdashdot: return "mediumdashdot";
|
||||
case border_style::mediumdashdotdot: return "mediumdashdotdot";
|
||||
case border_style::mediumdashed: return "mediumdashed";
|
||||
case border_style::slantdashdot: return "slantdashdot";
|
||||
case border_style::thick: return "thick";
|
||||
case border_style::thin: return "thin";
|
||||
case border_style::none: return "none";
|
||||
default: return default_case("none");
|
||||
}
|
||||
}
|
||||
|
||||
std::string to_string(vertical_alignment vertical_alignment)
|
||||
{
|
||||
switch (vertical_alignment)
|
||||
{
|
||||
case vertical_alignment::bottom: return "bottom";
|
||||
case vertical_alignment::center: return "center";
|
||||
case vertical_alignment::justify: return "justify";
|
||||
case vertical_alignment::top: return "top";
|
||||
case vertical_alignment::none: return "none";
|
||||
default: return default_case("none");
|
||||
}
|
||||
}
|
||||
|
||||
std::string to_string(horizontal_alignment horizontal_alignment)
|
||||
{
|
||||
switch (horizontal_alignment)
|
||||
{
|
||||
case horizontal_alignment::center: return "center";
|
||||
case horizontal_alignment::center_continuous: return "center-continous";
|
||||
case horizontal_alignment::general: return "general";
|
||||
case horizontal_alignment::justify: return "justify";
|
||||
case horizontal_alignment::left: return "left";
|
||||
case horizontal_alignment::right: return "right";
|
||||
case horizontal_alignment::none: return "none";
|
||||
default: return default_case("none");
|
||||
}
|
||||
}
|
||||
|
||||
std::string to_string(border_side side)
|
||||
{
|
||||
switch (side)
|
||||
{
|
||||
case border_side::bottom: return "bottom";
|
||||
case border_side::top: return "top";
|
||||
case border_side::start: return "left";
|
||||
case border_side::end: return "right";
|
||||
case border_side::horizontal: return "horizontal";
|
||||
case border_side::vertical: return "vertical";
|
||||
case border_side::diagonal: return "diagonal";
|
||||
default: return default_case("top");
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace detail
|
||||
} // namespace xlnt
|
373
source/detail/custom_value_traits.hpp
Normal file
373
source/detail/custom_value_traits.hpp
Normal file
|
@ -0,0 +1,373 @@
|
|||
#pragma once
|
||||
|
||||
#include <xml/parser>
|
||||
#include <xml/serializer>
|
||||
|
||||
#include <xlnt/packaging/relationship.hpp>
|
||||
#include <xlnt/styles/border.hpp>
|
||||
#include <xlnt/styles/font.hpp>
|
||||
#include <xlnt/styles/fill.hpp>
|
||||
#include <xlnt/styles/horizontal_alignment.hpp>
|
||||
#include <xlnt/styles/vertical_alignment.hpp>
|
||||
#include <xlnt/utils/exceptions.hpp>
|
||||
|
||||
namespace xlnt {
|
||||
namespace detail {
|
||||
|
||||
template<typename T>
|
||||
T default_case(T default_return_value)
|
||||
{
|
||||
#ifdef EXCEPT_ON_UNHANDLED_SWITCH_CASE
|
||||
throw unhandled_switch_case();
|
||||
#endif
|
||||
return default_return_value;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns the string representation of the underline style.
|
||||
/// </summary>
|
||||
std::string to_string(font::underline_style underline_style);
|
||||
|
||||
/// <summary>
|
||||
/// Returns the string representation of the relationship type.
|
||||
/// </summary>
|
||||
std::string to_string(relationship::type t);
|
||||
|
||||
std::string to_string(pattern_fill_type fill_type);
|
||||
|
||||
std::string to_string(gradient_fill_type fill_type);
|
||||
|
||||
std::string to_string(border_style border_style);
|
||||
|
||||
std::string to_string(vertical_alignment vertical_alignment);
|
||||
|
||||
std::string to_string(horizontal_alignment horizontal_alignment);
|
||||
|
||||
std::string to_string(border_side side);
|
||||
|
||||
} // namespace detail
|
||||
} // namespace xlnt
|
||||
|
||||
namespace xml {
|
||||
|
||||
template <>
|
||||
struct value_traits<xlnt::font::underline_style>
|
||||
{
|
||||
static xlnt::font::underline_style parse(std::string underline_string, const parser &)
|
||||
{
|
||||
using xlnt::font;
|
||||
|
||||
static auto *underline_styles = new std::vector<font::underline_style>
|
||||
{
|
||||
font::underline_style::double_,
|
||||
font::underline_style::double_accounting,
|
||||
font::underline_style::single,
|
||||
font::underline_style::single_accounting,
|
||||
font::underline_style::none
|
||||
};
|
||||
|
||||
for (auto underline_style : *underline_styles)
|
||||
{
|
||||
if (xlnt::detail::to_string(underline_style) == underline_string)
|
||||
{
|
||||
return underline_style;
|
||||
}
|
||||
}
|
||||
|
||||
return xlnt::detail::default_case(font::underline_style::none);
|
||||
}
|
||||
|
||||
static std::string serialize(xlnt::font::underline_style underline_style, const serializer &)
|
||||
{
|
||||
return xlnt::detail::to_string(underline_style);
|
||||
}
|
||||
}; // struct value_traits<xlnt::font::underline_style>
|
||||
|
||||
template <>
|
||||
struct value_traits<xlnt::relationship_type>
|
||||
{
|
||||
static xlnt::relationship_type parse(std::string relationship_type_string, const parser &)
|
||||
{
|
||||
using xlnt::relationship_type;
|
||||
|
||||
static auto *relationship_types = new std::vector<relationship_type>
|
||||
{
|
||||
relationship_type::calculation_chain,
|
||||
relationship_type::chartsheet,
|
||||
relationship_type::comments,
|
||||
relationship_type::connections,
|
||||
relationship_type::core_properties,
|
||||
relationship_type::custom_properties,
|
||||
relationship_type::custom_property,
|
||||
relationship_type::custom_xml_mappings,
|
||||
relationship_type::dialogsheet,
|
||||
relationship_type::drawings,
|
||||
relationship_type::extended_properties,
|
||||
relationship_type::external_workbook_references,
|
||||
relationship_type::hyperlink,
|
||||
relationship_type::image,
|
||||
relationship_type::metadata,
|
||||
relationship_type::office_document,
|
||||
relationship_type::pivot_table,
|
||||
relationship_type::pivot_table_cache_definition,
|
||||
relationship_type::pivot_table_cache_records,
|
||||
relationship_type::printer_settings,
|
||||
relationship_type::query_table,
|
||||
relationship_type::revision_log,
|
||||
relationship_type::shared_string_table,
|
||||
relationship_type::shared_workbook,
|
||||
relationship_type::shared_workbook_revision_headers,
|
||||
relationship_type::shared_workbook_user_data,
|
||||
relationship_type::single_cell_table_definitions,
|
||||
relationship_type::styles,
|
||||
relationship_type::table_definition,
|
||||
relationship_type::theme,
|
||||
relationship_type::thumbnail,
|
||||
relationship_type::unknown,
|
||||
relationship_type::volatile_dependencies,
|
||||
relationship_type::worksheet
|
||||
};
|
||||
|
||||
for (auto type : *relationship_types)
|
||||
{
|
||||
if (xlnt::detail::to_string(type) == relationship_type_string)
|
||||
{
|
||||
return type;
|
||||
}
|
||||
}
|
||||
|
||||
return xlnt::detail::default_case(relationship_type::unknown);
|
||||
}
|
||||
|
||||
static std::string serialize(xlnt::relationship_type type, const serializer &)
|
||||
{
|
||||
return xlnt::detail::to_string(type);
|
||||
}
|
||||
}; // struct value_traits<xlnt::relationship_type>
|
||||
|
||||
template <>
|
||||
struct value_traits<xlnt::pattern_fill_type>
|
||||
{
|
||||
static xlnt::pattern_fill_type parse(std::string fill_type_string, const parser &)
|
||||
{
|
||||
using xlnt::pattern_fill_type;
|
||||
|
||||
static auto *fill_types = new std::vector<pattern_fill_type>
|
||||
{
|
||||
pattern_fill_type::darkdown,
|
||||
pattern_fill_type::darkgray,
|
||||
pattern_fill_type::darkgrid,
|
||||
pattern_fill_type::darkhorizontal,
|
||||
pattern_fill_type::darktrellis,
|
||||
pattern_fill_type::darkup,
|
||||
pattern_fill_type::darkvertical,
|
||||
pattern_fill_type::gray0625,
|
||||
pattern_fill_type::gray125,
|
||||
pattern_fill_type::lightdown,
|
||||
pattern_fill_type::lightgray,
|
||||
pattern_fill_type::lightgrid,
|
||||
pattern_fill_type::lighthorizontal,
|
||||
pattern_fill_type::lighttrellis,
|
||||
pattern_fill_type::lightup,
|
||||
pattern_fill_type::lightvertical,
|
||||
pattern_fill_type::mediumgray,
|
||||
pattern_fill_type::none,
|
||||
pattern_fill_type::solid
|
||||
};
|
||||
|
||||
for (auto fill_type : *fill_types)
|
||||
{
|
||||
if (xlnt::detail::to_string(fill_type) == fill_type_string)
|
||||
{
|
||||
return fill_type;
|
||||
}
|
||||
}
|
||||
|
||||
return xlnt::detail::default_case(pattern_fill_type::none);
|
||||
}
|
||||
|
||||
static std::string serialize(xlnt::pattern_fill_type fill_type, const serializer &)
|
||||
{
|
||||
return xlnt::detail::to_string(fill_type);
|
||||
}
|
||||
}; // struct value_traits<xlnt::fill_type>
|
||||
|
||||
template <>
|
||||
struct value_traits<xlnt::gradient_fill_type>
|
||||
{
|
||||
static xlnt::gradient_fill_type parse(std::string fill_type_string, const parser &)
|
||||
{
|
||||
using xlnt::gradient_fill_type;
|
||||
|
||||
static auto *gradient_fill_types = new std::vector<gradient_fill_type>
|
||||
{
|
||||
gradient_fill_type::linear,
|
||||
gradient_fill_type::path
|
||||
};
|
||||
|
||||
for (auto fill_type : *gradient_fill_types)
|
||||
{
|
||||
if (xlnt::detail::to_string(fill_type) == fill_type_string)
|
||||
{
|
||||
return fill_type;
|
||||
}
|
||||
}
|
||||
|
||||
return xlnt::detail::default_case(gradient_fill_type::linear);
|
||||
}
|
||||
|
||||
static std::string serialize(xlnt::gradient_fill_type fill_type, const serializer &)
|
||||
{
|
||||
return xlnt::detail::to_string(fill_type);
|
||||
}
|
||||
}; // struct value_traits<xlnt::gradient_fill_type>
|
||||
|
||||
template <>
|
||||
struct value_traits<xlnt::border_style>
|
||||
{
|
||||
static xlnt::border_style parse(std::string style_string, const parser &)
|
||||
{
|
||||
using xlnt::border_style;
|
||||
|
||||
static auto *border_styles = new std::vector<border_style>
|
||||
{
|
||||
border_style::dashdot,
|
||||
border_style::dashdotdot,
|
||||
border_style::dashed,
|
||||
border_style::dotted,
|
||||
border_style::double_,
|
||||
border_style::hair,
|
||||
border_style::medium,
|
||||
border_style::mediumdashdot,
|
||||
border_style::mediumdashdotdot,
|
||||
border_style::mediumdashed,
|
||||
border_style::none,
|
||||
border_style::slantdashdot,
|
||||
border_style::thick,
|
||||
border_style::thin
|
||||
};
|
||||
|
||||
for (auto style : *border_styles)
|
||||
{
|
||||
if (xlnt::detail::to_string(style) == style_string)
|
||||
{
|
||||
return style;
|
||||
}
|
||||
}
|
||||
|
||||
return xlnt::detail::default_case(border_style::none);
|
||||
}
|
||||
|
||||
static std::string
|
||||
serialize (xlnt::border_style style, const serializer &)
|
||||
{
|
||||
return xlnt::detail::to_string(style);
|
||||
}
|
||||
}; // struct value_traits<xlnt::border_style>
|
||||
|
||||
template <>
|
||||
struct value_traits<xlnt::vertical_alignment>
|
||||
{
|
||||
static xlnt::vertical_alignment parse(std::string alignment_string, const parser &)
|
||||
{
|
||||
using xlnt::vertical_alignment;
|
||||
|
||||
static auto *vertical_alignments = new std::vector<vertical_alignment>
|
||||
{
|
||||
vertical_alignment::bottom,
|
||||
vertical_alignment::center,
|
||||
vertical_alignment::justify,
|
||||
vertical_alignment::none,
|
||||
vertical_alignment::top
|
||||
};
|
||||
|
||||
for (auto alignment : *vertical_alignments)
|
||||
{
|
||||
if (xlnt::detail::to_string(alignment) == alignment_string)
|
||||
{
|
||||
return alignment;
|
||||
}
|
||||
}
|
||||
|
||||
return xlnt::detail::default_case(vertical_alignment::none);
|
||||
}
|
||||
|
||||
static std::string serialize (xlnt::vertical_alignment alignment, const serializer &)
|
||||
{
|
||||
return xlnt::detail::to_string(alignment);
|
||||
}
|
||||
}; // struct value_traits<xlnt::vertical_alignment>
|
||||
|
||||
template <>
|
||||
struct value_traits<xlnt::horizontal_alignment>
|
||||
{
|
||||
static xlnt::horizontal_alignment parse(std::string alignment_string, const parser &)
|
||||
{
|
||||
using xlnt::horizontal_alignment;
|
||||
|
||||
static auto *horizontal_alignments = new std::vector<horizontal_alignment>
|
||||
{
|
||||
horizontal_alignment::center,
|
||||
horizontal_alignment::center_continuous,
|
||||
horizontal_alignment::general,
|
||||
horizontal_alignment::justify,
|
||||
horizontal_alignment::left,
|
||||
horizontal_alignment::right,
|
||||
horizontal_alignment::none
|
||||
};
|
||||
|
||||
for (auto alignment : *horizontal_alignments)
|
||||
{
|
||||
if (xlnt::detail::to_string(alignment) == alignment_string)
|
||||
{
|
||||
return alignment;
|
||||
}
|
||||
}
|
||||
|
||||
return xlnt::detail::default_case(horizontal_alignment::none);
|
||||
}
|
||||
|
||||
static std::string serialize(xlnt::horizontal_alignment alignment, const serializer &)
|
||||
{
|
||||
return xlnt::detail::to_string(alignment);
|
||||
}
|
||||
}; // struct value_traits<xlnt::horizontal_alignment>
|
||||
|
||||
template <>
|
||||
struct value_traits<xlnt::border_side>
|
||||
{
|
||||
static xlnt::border_side parse(std::string side_string, const parser &)
|
||||
{
|
||||
using xlnt::border_side;
|
||||
|
||||
static auto *border_sides = new std::vector<border_side>
|
||||
{
|
||||
border_side::top,
|
||||
border_side::bottom,
|
||||
border_side::start,
|
||||
border_side::end,
|
||||
border_side::vertical,
|
||||
border_side::horizontal,
|
||||
border_side::diagonal
|
||||
};
|
||||
|
||||
for (auto side : *border_sides)
|
||||
{
|
||||
if (xlnt::detail::to_string(side) == side_string)
|
||||
{
|
||||
return side;
|
||||
}
|
||||
}
|
||||
|
||||
return border_side::top;
|
||||
}
|
||||
|
||||
static std::string serialize (xlnt::border_side side, const serializer &)
|
||||
{
|
||||
return xlnt::detail::to_string(side);
|
||||
}
|
||||
}; // struct value_traits<xlnt::border_side>
|
||||
|
||||
}
|
||||
|
||||
|
|
@ -3,6 +3,7 @@
|
|||
#include <detail/xlsx_consumer.hpp>
|
||||
|
||||
#include <detail/constants.hpp>
|
||||
#include <detail/custom_value_traits.hpp>
|
||||
#include <detail/workbook_impl.hpp>
|
||||
#include <xlnt/cell/cell.hpp>
|
||||
#include <xlnt/utils/path.hpp>
|
||||
|
@ -57,16 +58,6 @@ struct EnumClassHash
|
|||
template<typename T>
|
||||
T from_string(const std::string &string);
|
||||
|
||||
template<>
|
||||
xlnt::font::underline_style from_string(const std::string &underline_string)
|
||||
{
|
||||
if (underline_string == "double") return xlnt::font::underline_style::double_;
|
||||
if (underline_string == "doubleAccounting") return xlnt::font::underline_style::double_accounting;
|
||||
if (underline_string == "single") return xlnt::font::underline_style::single;
|
||||
if (underline_string == "singleAccounting") return xlnt::font::underline_style::single_accounting;
|
||||
return xlnt::font::underline_style::none;
|
||||
}
|
||||
|
||||
template<>
|
||||
xlnt::pattern_fill_type from_string(const std::string &fill_type)
|
||||
{
|
||||
|
@ -250,32 +241,38 @@ xlnt::protection read_protection(xml::parser &parser)
|
|||
xlnt::alignment read_alignment(xml::parser &parser)
|
||||
{
|
||||
xlnt::alignment align;
|
||||
/*
|
||||
align.wrap(is_true(alignment_node.attribute("wrapText").value()));
|
||||
align.shrink(is_true(alignment_node.attribute("shrinkToFit").value()));
|
||||
|
||||
if (alignment_node.attribute("vertical"))
|
||||
align.wrap(is_true(parser.attribute("wrapText")));
|
||||
align.shrink(is_true(parser.attribute("shrinkToFit")));
|
||||
|
||||
if (parser.attribute_present("vertical"))
|
||||
{
|
||||
std::string vertical = alignment_node.attribute("vertical").value();
|
||||
align.vertical(from_string<xlnt::vertical_alignment>(vertical));
|
||||
align.vertical(from_string<xlnt::vertical_alignment>(
|
||||
parser.attribute("vertical")));
|
||||
}
|
||||
|
||||
if (alignment_node.attribute("horizontal"))
|
||||
if (parser.attribute_present("horizontal"))
|
||||
{
|
||||
std::string horizontal = alignment_node.attribute("horizontal").value();
|
||||
align.horizontal(from_string<xlnt::horizontal_alignment>(horizontal));
|
||||
align.horizontal(from_string<xlnt::horizontal_alignment>(
|
||||
parser.attribute("horizontal")));
|
||||
}
|
||||
*/
|
||||
|
||||
return align;
|
||||
}
|
||||
|
||||
void read_number_formats(xml::parser &parser, std::vector<xlnt::number_format> &number_formats)
|
||||
{
|
||||
number_formats.clear();
|
||||
/*
|
||||
for (auto num_fmt_node : number_formats_node.children("numFmt"))
|
||||
|
||||
while (true)
|
||||
{
|
||||
std::string format_string(num_fmt_node.attribute("formatCode").value());
|
||||
if (parser.peek() == xml::parser::event_type::end_element)
|
||||
{
|
||||
break;
|
||||
}
|
||||
|
||||
parser.next_expect(xml::parser::event_type::start_element, "numFmt");
|
||||
auto format_string = parser.attribute("formatCode");
|
||||
|
||||
if (format_string == "GENERAL")
|
||||
{
|
||||
|
@ -285,11 +282,14 @@ void read_number_formats(xml::parser &parser, std::vector<xlnt::number_format> &
|
|||
xlnt::number_format nf;
|
||||
|
||||
nf.set_format_string(format_string);
|
||||
nf.set_id(string_to_size_t(num_fmt_node.attribute("numFmtId").value()));
|
||||
nf.set_id(string_to_size_t(parser.attribute("numFmtId")));
|
||||
|
||||
number_formats.push_back(nf);
|
||||
|
||||
parser.next_expect(xml::parser::event_type::end_element, "numFmt");
|
||||
}
|
||||
*/
|
||||
|
||||
parser.next_expect(xml::parser::event_type::end_element, "numFmts");
|
||||
}
|
||||
|
||||
xlnt::color read_color(xml::parser &parser)
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
#include <cmath>
|
||||
|
||||
#include <detail/custom_value_traits.hpp>
|
||||
#include <detail/xlsx_producer.hpp>
|
||||
#include <detail/constants.hpp>
|
||||
#include <detail/workbook_impl.hpp>
|
||||
|
@ -34,227 +35,12 @@ std::string fill(const std::string &string, std::size_t length = 2)
|
|||
|
||||
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";
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns the string representation of the relationship type.
|
||||
/// </summary>
|
||||
std::string to_string(xlnt::relationship::type t)
|
||||
{
|
||||
switch (t)
|
||||
{
|
||||
case xlnt::relationship::type::office_document:
|
||||
return "http://schemas.openxmlformats.org/officeDocument/2006/relationships/officeDocument";
|
||||
case xlnt::relationship::type::thumbnail:
|
||||
return "http://schemas.openxmlformats.org/package/2006/relationships/metadata/thumbnail";
|
||||
case xlnt::relationship::type::calculation_chain:
|
||||
return "http://purl.oclc.org/ooxml/officeDocument/relationships/calcChain";
|
||||
case xlnt::relationship::type::extended_properties:
|
||||
return "http://schemas.openxmlformats.org/officeDocument/2006/relationships/extended-properties";
|
||||
case xlnt::relationship::type::core_properties:
|
||||
return "http://schemas.openxmlformats.org/package/2006/relationships/metadata/core-properties";
|
||||
case xlnt::relationship::type::worksheet:
|
||||
return "http://schemas.openxmlformats.org/officeDocument/2006/relationships/worksheet";
|
||||
case xlnt::relationship::type::shared_string_table:
|
||||
return "http://schemas.openxmlformats.org/officeDocument/2006/relationships/sharedStrings";
|
||||
case xlnt::relationship::type::styles:
|
||||
return "http://schemas.openxmlformats.org/officeDocument/2006/relationships/styles";
|
||||
case xlnt::relationship::type::theme:
|
||||
return "http://schemas.openxmlformats.org/officeDocument/2006/relationships/theme";
|
||||
case xlnt::relationship::type::hyperlink:
|
||||
return "http://schemas.openxmlformats.org/officeDocument/2006/relationships/hyperlink";
|
||||
case xlnt::relationship::type::chartsheet:
|
||||
return "http://schemas.openxmlformats.org/officeDocument/2006/relationships/chartsheet";
|
||||
default:
|
||||
return "??";
|
||||
}
|
||||
}
|
||||
|
||||
std::string to_string(xlnt::font::underline_style underline_style)
|
||||
{
|
||||
switch (underline_style)
|
||||
{
|
||||
case xlnt::font::underline_style::double_: return "double";
|
||||
case xlnt::font::underline_style::double_accounting: return "doubleAccounting";
|
||||
case xlnt::font::underline_style::single: return "single";
|
||||
case xlnt::font::underline_style::single_accounting: return "singleAccounting";
|
||||
default:
|
||||
case xlnt::font::underline_style::none: return "none";
|
||||
}
|
||||
}
|
||||
|
||||
std::string to_string(xlnt::pattern_fill_type fill_type)
|
||||
{
|
||||
switch (fill_type)
|
||||
{
|
||||
case xlnt::pattern_fill_type::darkdown: return "darkdown";
|
||||
case xlnt::pattern_fill_type::darkgray: return "darkgray";
|
||||
case xlnt::pattern_fill_type::darkgrid: return "darkgrid";
|
||||
case xlnt::pattern_fill_type::darkhorizontal: return "darkhorizontal";
|
||||
case xlnt::pattern_fill_type::darktrellis: return "darkhorizontal";
|
||||
case xlnt::pattern_fill_type::darkup: return "darkup";
|
||||
case xlnt::pattern_fill_type::darkvertical: return "darkvertical";
|
||||
case xlnt::pattern_fill_type::gray0625: return "gray0625";
|
||||
case xlnt::pattern_fill_type::gray125: return "gray125";
|
||||
case xlnt::pattern_fill_type::lightdown: return "lightdown";
|
||||
case xlnt::pattern_fill_type::lightgray: return "lightgray";
|
||||
case xlnt::pattern_fill_type::lightgrid: return "lightgrid";
|
||||
case xlnt::pattern_fill_type::lighthorizontal: return "lighthorizontal";
|
||||
case xlnt::pattern_fill_type::lighttrellis: return "lighttrellis";
|
||||
case xlnt::pattern_fill_type::lightup: return "lightup";
|
||||
case xlnt::pattern_fill_type::lightvertical: return "lightvertical";
|
||||
case xlnt::pattern_fill_type::mediumgray: return "mediumgray";
|
||||
case xlnt::pattern_fill_type::solid: return "solid";
|
||||
default:
|
||||
case xlnt::pattern_fill_type::none: return "none";
|
||||
}
|
||||
}
|
||||
|
||||
std::string to_string(xlnt::gradient_fill_type fill_type)
|
||||
{
|
||||
return fill_type == xlnt::gradient_fill_type::linear ? "linear" : "path";
|
||||
}
|
||||
|
||||
std::string to_string(xlnt::border_style border_style)
|
||||
{
|
||||
switch (border_style)
|
||||
{
|
||||
case xlnt::border_style::dashdot: return "dashdot";
|
||||
case xlnt::border_style::dashdotdot: return "dashdotdot";
|
||||
case xlnt::border_style::dashed: return "dashed";
|
||||
case xlnt::border_style::dotted: return "dotted";
|
||||
case xlnt::border_style::double_: return "double";
|
||||
case xlnt::border_style::hair: return "hair";
|
||||
case xlnt::border_style::medium: return "medium";
|
||||
case xlnt::border_style::mediumdashdot: return "mediumdashdot";
|
||||
case xlnt::border_style::mediumdashdotdot: return "mediumdashdotdot";
|
||||
case xlnt::border_style::mediumdashed: return "mediumdashed";
|
||||
case xlnt::border_style::slantdashdot: return "slantdashdot";
|
||||
case xlnt::border_style::thick: return "thick";
|
||||
case xlnt::border_style::thin: return "thin";
|
||||
default:
|
||||
case xlnt::border_style::none: return "none";
|
||||
}
|
||||
}
|
||||
|
||||
std::string to_string(xlnt::vertical_alignment vertical_alignment)
|
||||
{
|
||||
switch (vertical_alignment)
|
||||
{
|
||||
case xlnt::vertical_alignment::bottom: return "bottom";
|
||||
case xlnt::vertical_alignment::center: return "center";
|
||||
case xlnt::vertical_alignment::justify: return "justify";
|
||||
case xlnt::vertical_alignment::top: return "top";
|
||||
default:
|
||||
case xlnt::vertical_alignment::none: return "none";
|
||||
}
|
||||
}
|
||||
|
||||
std::string to_string(xlnt::horizontal_alignment horizontal_alignment)
|
||||
{
|
||||
switch (horizontal_alignment)
|
||||
{
|
||||
case xlnt::horizontal_alignment::center: return "center";
|
||||
case xlnt::horizontal_alignment::center_continuous: return "center-continous";
|
||||
case xlnt::horizontal_alignment::general: return "general";
|
||||
case xlnt::horizontal_alignment::justify: return "justify";
|
||||
case xlnt::horizontal_alignment::left: return "left";
|
||||
case xlnt::horizontal_alignment::right: return "right";
|
||||
default:
|
||||
case xlnt::horizontal_alignment::none: return "none";
|
||||
}
|
||||
}
|
||||
|
||||
std::string to_string(xlnt::border_side side)
|
||||
{
|
||||
switch (side)
|
||||
{
|
||||
case xlnt::border_side::bottom: return "bottom";
|
||||
case xlnt::border_side::top: return "top";
|
||||
case xlnt::border_side::start: return "left";
|
||||
case xlnt::border_side::end: return "right";
|
||||
case xlnt::border_side::horizontal: return "horizontal";
|
||||
case xlnt::border_side::vertical: return "vertical";
|
||||
default:
|
||||
case xlnt::border_side::diagonal: return "diagonal";
|
||||
}
|
||||
}
|
||||
|
||||
void write_relationships(const std::vector<xlnt::relationship> &relationships, xml::serializer &serializer)
|
||||
{
|
||||
const auto xmlns = xlnt::constants::get_namespace("relationships");
|
||||
|
||||
serializer.start_element(xmlns, "Relationships");
|
||||
serializer.namespace_decl(xmlns, "");
|
||||
|
||||
for (const auto &relationship : relationships)
|
||||
{
|
||||
serializer.start_element(xmlns, "Relationship");
|
||||
|
||||
serializer.attribute("Id", relationship.get_id());
|
||||
serializer.attribute("Type", to_string(relationship.get_type()));
|
||||
serializer.attribute("Target", relationship.get_target().get_path().string());
|
||||
|
||||
if (relationship.get_target_mode() == xlnt::target_mode::external)
|
||||
{
|
||||
serializer.attribute("TargetMode", "External");
|
||||
}
|
||||
|
||||
serializer.end_element(xmlns, "Relationship");
|
||||
}
|
||||
|
||||
serializer.end_element(xmlns, "Relationships");
|
||||
}
|
||||
|
||||
|
||||
bool write_color(const xlnt::color &color, xml::serializer &serializer)
|
||||
{
|
||||
switch (color.get_type())
|
||||
{
|
||||
case xlnt::color::type::theme:
|
||||
serializer.attribute("theme", std::to_string(color.get_theme().get_index()));
|
||||
break;
|
||||
|
||||
case xlnt::color::type::indexed:
|
||||
serializer.attribute("indexed", std::to_string(color.get_indexed().get_index()));
|
||||
break;
|
||||
|
||||
case xlnt::color::type::rgb:
|
||||
default:
|
||||
serializer.attribute("rgb", color.get_rgb().get_hex_string());
|
||||
break;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void write_dxfs(xml::serializer &serializer)
|
||||
{
|
||||
serializer.attribute("count", "0");
|
||||
}
|
||||
|
||||
void write_table_styles(xml::serializer &serializer)
|
||||
{
|
||||
serializer.attribute("count", "0");
|
||||
serializer.attribute("defaultTableStyle", "TableStyleMedium9");
|
||||
serializer.attribute("defaultPivotStyle", "PivotStyleMedium7");
|
||||
}
|
||||
|
||||
void write_colors(const std::vector<xlnt::color> &colors, xml::serializer &serializer)
|
||||
{
|
||||
serializer.start_element("indexedColors");
|
||||
|
||||
for (auto &c : colors)
|
||||
{
|
||||
serializer.start_element("rgbColor");
|
||||
serializer.attribute("rgb", c.get_rgb().get_hex_string());
|
||||
serializer.end_element();
|
||||
}
|
||||
|
||||
serializer.end_element();
|
||||
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
|
||||
|
@ -288,31 +74,35 @@ void xlsx_producer::write(std::vector<std::uint8_t> &destination)
|
|||
|
||||
void xlsx_producer::populate_archive()
|
||||
{
|
||||
write_manifest();
|
||||
write_content_types();
|
||||
|
||||
const auto root_rels = source_.get_manifest().get_relationships(path("/"));
|
||||
write_relationships(root_rels, path("/"));
|
||||
|
||||
for (auto &rel : source_.impl().manifest_.get_relationships(path("/")))
|
||||
for (auto &rel : root_rels)
|
||||
{
|
||||
std::ostringstream serializer_stream;
|
||||
xml::serializer serializer(serializer_stream, rel.get_target().get_path().string());
|
||||
serializer_ = &serializer;
|
||||
|
||||
bool write_document = true;
|
||||
|
||||
switch (rel.get_type())
|
||||
{
|
||||
case relationship::type::core_properties:
|
||||
write_core_properties(rel, serializer);
|
||||
write_core_properties(rel);
|
||||
break;
|
||||
|
||||
case relationship::type::extended_properties:
|
||||
write_extended_properties(rel, serializer);
|
||||
write_extended_properties(rel);
|
||||
break;
|
||||
|
||||
case relationship::type::custom_properties:
|
||||
write_custom_properties(rel, serializer);
|
||||
write_custom_properties(rel);
|
||||
break;
|
||||
|
||||
case relationship::type::office_document:
|
||||
write_workbook(rel, serializer);
|
||||
write_workbook(rel);
|
||||
break;
|
||||
|
||||
case relationship::type::thumbnail:
|
||||
|
@ -338,7 +128,7 @@ void xlsx_producer::populate_archive()
|
|||
|
||||
// Package Parts
|
||||
|
||||
void xlsx_producer::write_manifest()
|
||||
void xlsx_producer::write_content_types()
|
||||
{
|
||||
std::ostringstream content_types_stream;
|
||||
xml::serializer content_types_serializer(content_types_stream, "[Content_Types].xml");
|
||||
|
@ -367,42 +157,19 @@ void xlsx_producer::write_manifest()
|
|||
}
|
||||
|
||||
content_types_serializer.end_element(xmlns, "Types");
|
||||
|
||||
for (const auto &part : source_.get_manifest().get_parts())
|
||||
{
|
||||
auto part_rels = source_.get_manifest().get_relationships(part);
|
||||
|
||||
if (part_rels.empty()) continue;
|
||||
|
||||
path parent = part.parent();
|
||||
|
||||
if (parent.is_absolute())
|
||||
{
|
||||
parent = path(parent.string().substr(1));
|
||||
}
|
||||
|
||||
std::ostringstream rels_stream;
|
||||
path rels_path(parent.append("_rels").append(part.filename() + ".rels").string());
|
||||
xml::serializer rels_serializer(rels_stream, rels_path.string());
|
||||
|
||||
write_relationships(part_rels, rels_serializer);
|
||||
|
||||
destination_.write_string(rels_stream.str(), rels_path);
|
||||
}
|
||||
|
||||
destination_.write_string(content_types_stream.str(), path("[Content_Types].xml"));
|
||||
}
|
||||
|
||||
void xlsx_producer::write_extended_properties(const relationship &rel, xml::serializer &serializer)
|
||||
void xlsx_producer::write_extended_properties(const relationship &rel)
|
||||
{
|
||||
serializer.start_element("Properties");
|
||||
serializer().start_element("Properties");
|
||||
|
||||
serializer.namespace_decl("http://schemas.openxmlformats.org/officeDocument/2006/extended-properties", "xmlns");
|
||||
serializer.namespace_decl("http://schemas.openxmlformats.org/officeDocument/2006/docPropsVTypes", "vt");
|
||||
serializer().namespace_decl("http://schemas.openxmlformats.org/officeDocument/2006/extended-properties", "xmlns");
|
||||
serializer().namespace_decl("http://schemas.openxmlformats.org/officeDocument/2006/docPropsVTypes", "vt");
|
||||
|
||||
serializer.element("Application", source_.get_application());
|
||||
serializer.element("DocSecurity", std::to_string(source_.get_doc_security()));
|
||||
serializer.element("ScaleCrop", source_.get_scale_crop() ? "true" : "false");
|
||||
serializer().element("Application", source_.get_application());
|
||||
serializer().element("DocSecurity", std::to_string(source_.get_doc_security()));
|
||||
serializer().element("ScaleCrop", source_.get_scale_crop() ? "true" : "false");
|
||||
/*
|
||||
auto heading_pairs_node = properties_node.append_child("HeadingPairs");
|
||||
auto heading_pairs_vector_node = heading_pairs_node.append_child("vt:vector");
|
||||
|
@ -437,7 +204,7 @@ void xlsx_producer::write_extended_properties(const relationship &rel, xml::seri
|
|||
*/
|
||||
}
|
||||
|
||||
void xlsx_producer::write_core_properties(const relationship &rel, xml::serializer &serializer)
|
||||
void xlsx_producer::write_core_properties(const relationship &rel)
|
||||
{
|
||||
/*
|
||||
auto core_properties_node = root.append_child("cp:coreProperties");
|
||||
|
@ -468,14 +235,14 @@ void xlsx_producer::write_core_properties(const relationship &rel, xml::serializ
|
|||
*/
|
||||
}
|
||||
|
||||
void xlsx_producer::write_custom_properties(const relationship &rel, xml::serializer &serializer)
|
||||
void xlsx_producer::write_custom_properties(const relationship &rel)
|
||||
{
|
||||
serializer.element("Properties");
|
||||
serializer().element("Properties");
|
||||
}
|
||||
|
||||
// Write SpreadsheetML-Specific Package Parts
|
||||
|
||||
void xlsx_producer::write_workbook(const relationship &rel, xml::serializer &serializer)
|
||||
void xlsx_producer::write_workbook(const relationship &rel)
|
||||
{
|
||||
std::size_t num_visible = 0;
|
||||
bool any_defined_names = false;
|
||||
|
@ -500,15 +267,15 @@ void xlsx_producer::write_workbook(const relationship &rel, xml::serializer &ser
|
|||
|
||||
const auto xmlns = std::string("http://schemas.openxmlformats.org/spreadsheetml/2006/main");
|
||||
|
||||
serializer.start_element(xmlns, "workbook");
|
||||
serializer.namespace_decl(xmlns, "");
|
||||
serializer.namespace_decl("http://schemas.openxmlformats.org/officeDocument/2006/relationships", "r");
|
||||
serializer().start_element(xmlns, "workbook");
|
||||
serializer().namespace_decl(xmlns, "");
|
||||
serializer().namespace_decl("http://schemas.openxmlformats.org/officeDocument/2006/relationships", "r");
|
||||
|
||||
if (source_.x15_enabled())
|
||||
{
|
||||
serializer.namespace_decl("http://schemas.openxmlformats.org/markup-compatibility/2006", "mc");
|
||||
serializer.attribute("mc:Ignorable", "x15");
|
||||
serializer.namespace_decl("http://schemas.microsoft.com/office/spreadsheetml/2010/11/main", "x15");
|
||||
serializer().namespace_decl("http://schemas.openxmlformats.org/markup-compatibility/2006", "mc");
|
||||
serializer().attribute("mc:Ignorable", "x15");
|
||||
serializer().namespace_decl("http://schemas.microsoft.com/office/spreadsheetml/2010/11/main", "x15");
|
||||
}
|
||||
/*
|
||||
if (source_.has_file_version())
|
||||
|
@ -573,7 +340,7 @@ void xlsx_producer::write_workbook(const relationship &rel, xml::serializer &ser
|
|||
}
|
||||
*/
|
||||
|
||||
serializer.start_element(xmlns, "sheets");
|
||||
serializer().start_element(xmlns, "sheets");
|
||||
/*
|
||||
if (any_defined_names)
|
||||
{
|
||||
|
@ -586,16 +353,16 @@ void xlsx_producer::write_workbook(const relationship &rel, xml::serializer &ser
|
|||
auto sheet_rel_id = source_.d_->sheet_title_rel_id_map_[ws.get_title()];
|
||||
auto sheet_rel = source_.d_->manifest_.get_relationship(rel.get_source().get_path(), sheet_rel_id);
|
||||
|
||||
serializer.start_element(xmlns, "sheet");
|
||||
serializer.attribute("name", ws.get_title());
|
||||
serializer.attribute("sheetId", std::to_string(ws.get_id()));
|
||||
serializer().start_element(xmlns, "sheet");
|
||||
serializer().attribute("name", ws.get_title());
|
||||
serializer().attribute("sheetId", std::to_string(ws.get_id()));
|
||||
|
||||
if (ws.has_page_setup() && ws.get_sheet_state() == xlnt::sheet_state::hidden)
|
||||
{
|
||||
serializer.attribute("state", "hidden");
|
||||
serializer().attribute("state", "hidden");
|
||||
}
|
||||
|
||||
serializer.attribute("http://schemas.openxmlformats.org/officeDocument/2006/relationships", "id", sheet_rel_id);
|
||||
serializer().attribute("http://schemas.openxmlformats.org/officeDocument/2006/relationships", "id", sheet_rel_id);
|
||||
/*
|
||||
if (ws.has_auto_filter())
|
||||
{
|
||||
|
@ -609,7 +376,7 @@ void xlsx_producer::write_workbook(const relationship &rel, xml::serializer &ser
|
|||
}
|
||||
*/
|
||||
|
||||
serializer.end_element(xmlns, "sheet");
|
||||
serializer().end_element(xmlns, "sheet");
|
||||
}
|
||||
/*
|
||||
if (source_.has_calculation_properties())
|
||||
|
@ -650,70 +417,74 @@ void xlsx_producer::write_workbook(const relationship &rel, xml::serializer &ser
|
|||
}
|
||||
*/
|
||||
|
||||
serializer.end_element(xmlns, "sheets");
|
||||
serializer.end_element(xmlns, "workbook");
|
||||
serializer().end_element(xmlns, "sheets");
|
||||
serializer().end_element(xmlns, "workbook");
|
||||
|
||||
for (const auto &child_rel : source_.get_manifest().get_relationships(rel.get_target().get_path()))
|
||||
auto workbook_rels = source_.get_manifest().get_relationships(rel.get_target().get_path());
|
||||
write_relationships(workbook_rels, rel.get_target().get_path());
|
||||
|
||||
for (const auto &child_rel : workbook_rels)
|
||||
{
|
||||
std::ostringstream child_stream;
|
||||
xml::serializer child_serializer(child_stream, child_rel.get_target().get_path().string());
|
||||
serializer_ = &child_serializer;
|
||||
|
||||
switch (child_rel.get_type())
|
||||
{
|
||||
case relationship::type::calculation_chain:
|
||||
write_calculation_chain(child_rel, child_serializer);
|
||||
write_calculation_chain(child_rel);
|
||||
break;
|
||||
|
||||
case relationship::type::chartsheet:
|
||||
write_chartsheet(child_rel, child_serializer);
|
||||
write_chartsheet(child_rel);
|
||||
break;
|
||||
|
||||
case relationship::type::connections:
|
||||
write_connections(child_rel, child_serializer);
|
||||
write_connections(child_rel);
|
||||
break;
|
||||
|
||||
case relationship::type::custom_xml_mappings:
|
||||
write_custom_xml_mappings(child_rel, child_serializer);
|
||||
write_custom_xml_mappings(child_rel);
|
||||
break;
|
||||
|
||||
case relationship::type::dialogsheet:
|
||||
write_dialogsheet(child_rel, child_serializer);
|
||||
write_dialogsheet(child_rel);
|
||||
break;
|
||||
|
||||
case relationship::type::external_workbook_references:
|
||||
write_external_workbook_references(child_rel, child_serializer);
|
||||
write_external_workbook_references(child_rel);
|
||||
break;
|
||||
|
||||
case relationship::type::metadata:
|
||||
write_metadata(child_rel, child_serializer);
|
||||
write_metadata(child_rel);
|
||||
break;
|
||||
|
||||
case relationship::type::pivot_table:
|
||||
write_pivot_table(child_rel, child_serializer);
|
||||
write_pivot_table(child_rel);
|
||||
break;
|
||||
|
||||
case relationship::type::shared_string_table:
|
||||
write_shared_string_table(child_rel, child_serializer);
|
||||
write_shared_string_table(child_rel);
|
||||
break;
|
||||
|
||||
case relationship::type::shared_workbook_revision_headers:
|
||||
write_shared_workbook_revision_headers(child_rel, child_serializer);
|
||||
write_shared_workbook_revision_headers(child_rel);
|
||||
break;
|
||||
|
||||
case relationship::type::styles:
|
||||
write_styles(child_rel, child_serializer);
|
||||
write_styles(child_rel);
|
||||
break;
|
||||
|
||||
case relationship::type::theme:
|
||||
write_theme(child_rel, child_serializer);
|
||||
write_theme(child_rel);
|
||||
break;
|
||||
|
||||
case relationship::type::volatile_dependencies:
|
||||
write_volatile_dependencies(child_rel, child_serializer);
|
||||
write_volatile_dependencies(child_rel);
|
||||
break;
|
||||
|
||||
case relationship::type::worksheet:
|
||||
write_worksheet(child_rel, child_serializer);
|
||||
write_worksheet(child_rel);
|
||||
break;
|
||||
|
||||
default:
|
||||
|
@ -727,49 +498,49 @@ void xlsx_producer::write_workbook(const relationship &rel, xml::serializer &ser
|
|||
|
||||
// Write Workbook Relationship Target Parts
|
||||
|
||||
void xlsx_producer::write_calculation_chain(const relationship &rel, xml::serializer &serializer)
|
||||
void xlsx_producer::write_calculation_chain(const relationship &rel)
|
||||
{
|
||||
serializer.start_element("calcChain");
|
||||
serializer().start_element("calcChain");
|
||||
}
|
||||
|
||||
void xlsx_producer::write_chartsheet(const relationship &rel, xml::serializer &serializer)
|
||||
void xlsx_producer::write_chartsheet(const relationship &rel)
|
||||
{
|
||||
serializer.start_element("chartsheet");
|
||||
serializer().start_element("chartsheet");
|
||||
}
|
||||
|
||||
void xlsx_producer::write_connections(const relationship &rel, xml::serializer &serializer)
|
||||
void xlsx_producer::write_connections(const relationship &rel)
|
||||
{
|
||||
serializer.start_element("connections");
|
||||
serializer().start_element("connections");
|
||||
}
|
||||
|
||||
void xlsx_producer::write_custom_xml_mappings(const relationship &rel, xml::serializer &serializer)
|
||||
void xlsx_producer::write_custom_xml_mappings(const relationship &rel)
|
||||
{
|
||||
serializer.start_element("MapInfo");
|
||||
serializer().start_element("MapInfo");
|
||||
}
|
||||
|
||||
void xlsx_producer::write_dialogsheet(const relationship &rel, xml::serializer &serializer)
|
||||
void xlsx_producer::write_dialogsheet(const relationship &rel)
|
||||
{
|
||||
serializer.start_element("dialogsheet");
|
||||
serializer().start_element("dialogsheet");
|
||||
}
|
||||
|
||||
void xlsx_producer::write_external_workbook_references(const relationship &rel, xml::serializer &serializer)
|
||||
void xlsx_producer::write_external_workbook_references(const relationship &rel)
|
||||
{
|
||||
serializer.start_element("externalLink");
|
||||
serializer().start_element("externalLink");
|
||||
}
|
||||
|
||||
void xlsx_producer::write_metadata(const relationship &rel, xml::serializer &serializer)
|
||||
void xlsx_producer::write_metadata(const relationship &rel)
|
||||
{
|
||||
serializer.start_element("metadata");
|
||||
serializer().start_element("metadata");
|
||||
}
|
||||
|
||||
void xlsx_producer::write_pivot_table(const relationship &rel, xml::serializer &serializer)
|
||||
void xlsx_producer::write_pivot_table(const relationship &rel)
|
||||
{
|
||||
serializer.start_element("pivotTableDefinition");
|
||||
serializer().start_element("pivotTableDefinition");
|
||||
}
|
||||
|
||||
void xlsx_producer::write_shared_string_table(const relationship &rel, xml::serializer &serializer)
|
||||
void xlsx_producer::write_shared_string_table(const relationship &rel)
|
||||
{
|
||||
serializer.start_element("sst");
|
||||
serializer().start_element("sst");
|
||||
/*
|
||||
sst_node.append_attribute("xmlns").set_value("http://schemas.openxmlformats.org/spreadsheetml/2006/main");
|
||||
std::size_t string_count = 0;
|
||||
|
@ -843,24 +614,24 @@ void xlsx_producer::write_shared_string_table(const relationship &rel, xml::seri
|
|||
*/
|
||||
}
|
||||
|
||||
void xlsx_producer::write_shared_workbook_revision_headers(const relationship &rel, xml::serializer &serializer)
|
||||
void xlsx_producer::write_shared_workbook_revision_headers(const relationship &rel)
|
||||
{
|
||||
serializer.start_element("headers");
|
||||
serializer().start_element("headers");
|
||||
}
|
||||
|
||||
void xlsx_producer::write_shared_workbook(const relationship &rel, xml::serializer &serializer)
|
||||
void xlsx_producer::write_shared_workbook(const relationship &rel)
|
||||
{
|
||||
serializer.start_element("revisions");
|
||||
serializer().start_element("revisions");
|
||||
}
|
||||
|
||||
void xlsx_producer::write_shared_workbook_user_data(const relationship &rel, xml::serializer &serializer)
|
||||
void xlsx_producer::write_shared_workbook_user_data(const relationship &rel)
|
||||
{
|
||||
serializer.start_element("users");
|
||||
serializer().start_element("users");
|
||||
}
|
||||
|
||||
void xlsx_producer::write_styles(const relationship &rel, xml::serializer &serializer)
|
||||
void xlsx_producer::write_styles(const relationship &rel)
|
||||
{
|
||||
serializer.start_element("styleSheet");
|
||||
serializer().start_element("styleSheet");
|
||||
/*
|
||||
// Namespaces
|
||||
|
||||
|
@ -1309,9 +1080,9 @@ void xlsx_producer::write_styles(const relationship &rel, xml::serializer &seria
|
|||
*/
|
||||
}
|
||||
|
||||
void xlsx_producer::write_theme(const relationship &rel, xml::serializer &serializer)
|
||||
void xlsx_producer::write_theme(const relationship &rel)
|
||||
{
|
||||
serializer.start_element("a:theme");
|
||||
serializer().start_element("a:theme");
|
||||
/*
|
||||
theme_node.append_attribute("xmlns:a").set_value(constants::get_namespace("drawingml").c_str());
|
||||
theme_node.append_attribute("name").set_value("Office Theme");
|
||||
|
@ -1618,12 +1389,12 @@ void xlsx_producer::write_theme(const relationship &rel, xml::serializer &serial
|
|||
*/
|
||||
}
|
||||
|
||||
void xlsx_producer::write_volatile_dependencies(const relationship &rel, xml::serializer &serializer)
|
||||
void xlsx_producer::write_volatile_dependencies(const relationship &rel)
|
||||
{
|
||||
serializer.start_element("volTypes");
|
||||
serializer().start_element("volTypes");
|
||||
}
|
||||
|
||||
void xlsx_producer::write_worksheet(const relationship &rel, xml::serializer &serializer)
|
||||
void xlsx_producer::write_worksheet(const relationship &rel)
|
||||
{
|
||||
auto title = std::find_if(source_.d_->sheet_title_rel_id_map_.begin(),
|
||||
source_.d_->sheet_title_rel_id_map_.end(),
|
||||
|
@ -1636,15 +1407,15 @@ void xlsx_producer::write_worksheet(const relationship &rel, xml::serializer &se
|
|||
|
||||
const auto xmlns = std::string("http://schemas.openxmlformats.org/spreadsheetml/2006/main");
|
||||
|
||||
serializer.start_element(xmlns, "worksheet");
|
||||
serializer.namespace_decl(xmlns, "");
|
||||
serializer.namespace_decl("http://schemas.openxmlformats.org/officeDocument/2006/relationships", "r");
|
||||
serializer().start_element(xmlns, "worksheet");
|
||||
serializer().namespace_decl(xmlns, "");
|
||||
serializer().namespace_decl("http://schemas.openxmlformats.org/officeDocument/2006/relationships", "r");
|
||||
|
||||
if (ws.x14ac_enabled())
|
||||
{
|
||||
serializer.namespace_decl("http://schemas.openxmlformats.org/markup-compatibility/2006", "mc");
|
||||
serializer.attribute("mc:Ignorable", "x14ac");
|
||||
serializer.namespace_decl("http://schemas.microsoft.com/office/spreadsheetml/2009/9/ac", "x14ac");
|
||||
serializer().namespace_decl("http://schemas.openxmlformats.org/markup-compatibility/2006", "mc");
|
||||
serializer().attribute("mc:Ignorable", "x14ac");
|
||||
serializer().namespace_decl("http://schemas.microsoft.com/office/spreadsheetml/2009/9/ac", "x14ac");
|
||||
}
|
||||
/*
|
||||
if (ws.has_page_setup())
|
||||
|
@ -1786,7 +1557,7 @@ void xlsx_producer::write_worksheet(const relationship &rel, xml::serializer &se
|
|||
|
||||
std::unordered_map<std::string, std::string> hyperlink_references;
|
||||
|
||||
serializer.start_element(xmlns, "sheetData");
|
||||
serializer().start_element(xmlns, "sheetData");
|
||||
const auto &shared_strings = ws.get_workbook().get_shared_strings();
|
||||
/*
|
||||
for (auto row : ws.rows())
|
||||
|
@ -1934,7 +1705,7 @@ void xlsx_producer::write_worksheet(const relationship &rel, xml::serializer &se
|
|||
}
|
||||
}
|
||||
*/
|
||||
serializer.end_element();
|
||||
serializer().end_element();
|
||||
/*
|
||||
if (ws.has_auto_filter())
|
||||
{
|
||||
|
@ -2055,32 +1826,32 @@ void xlsx_producer::write_worksheet(const relationship &rel, xml::serializer &se
|
|||
}
|
||||
*/
|
||||
|
||||
serializer.end_element();
|
||||
serializer().end_element();
|
||||
}
|
||||
|
||||
// Sheet Relationship Target Parts
|
||||
|
||||
void xlsx_producer::write_comments(const relationship &rel, xml::serializer &serializer)
|
||||
void xlsx_producer::write_comments(const relationship &rel)
|
||||
{
|
||||
serializer.start_element("comments");
|
||||
serializer().start_element("comments");
|
||||
}
|
||||
|
||||
void xlsx_producer::write_drawings(const relationship &rel, xml::serializer &serializer)
|
||||
void xlsx_producer::write_drawings(const relationship &rel)
|
||||
{
|
||||
serializer.start_element("wsDr");
|
||||
serializer().start_element("wsDr");
|
||||
}
|
||||
|
||||
// Other Parts
|
||||
|
||||
void xlsx_producer::write_custom_property(xml::serializer &serializer)
|
||||
void xlsx_producer::write_custom_property()
|
||||
{
|
||||
}
|
||||
|
||||
void xlsx_producer::write_unknown_parts(xml::serializer &serializer)
|
||||
void xlsx_producer::write_unknown_parts()
|
||||
{
|
||||
}
|
||||
|
||||
void xlsx_producer::write_unknown_relationships(xml::serializer &serializer)
|
||||
void xlsx_producer::write_unknown_relationships()
|
||||
{
|
||||
}
|
||||
|
||||
|
@ -2091,6 +1862,11 @@ void xlsx_producer::write_thumbnail(const relationship &rel)
|
|||
destination_.write_string(thumbnail_string, rel.get_target().get_path());
|
||||
}
|
||||
|
||||
xml::serializer &xlsx_producer::serializer()
|
||||
{
|
||||
return *serializer_;
|
||||
}
|
||||
|
||||
std::string xlsx_producer::write_bool(bool boolean) const
|
||||
{
|
||||
if (source_.d_->short_bools_)
|
||||
|
@ -2101,5 +1877,92 @@ std::string xlsx_producer::write_bool(bool boolean) const
|
|||
return boolean ? "true" : "false";
|
||||
}
|
||||
|
||||
|
||||
void xlsx_producer::write_relationships(const std::vector<xlnt::relationship> &relationships, const path &part)
|
||||
{
|
||||
path parent = part.parent();
|
||||
|
||||
if (parent.is_absolute())
|
||||
{
|
||||
parent = path(parent.string().substr(1));
|
||||
}
|
||||
|
||||
std::ostringstream rels_stream;
|
||||
path rels_path(parent.append("_rels").append(part.filename() + ".rels").string());
|
||||
xml::serializer rels_serializer(rels_stream, rels_path.string());
|
||||
|
||||
const auto xmlns = xlnt::constants::get_namespace("relationships");
|
||||
|
||||
rels_serializer.start_element(xmlns, "Relationships");
|
||||
rels_serializer.namespace_decl(xmlns, "");
|
||||
|
||||
for (const auto &relationship : relationships)
|
||||
{
|
||||
rels_serializer.start_element(xmlns, "Relationship");
|
||||
|
||||
rels_serializer.attribute("Id", relationship.get_id());
|
||||
rels_serializer.attribute("Type", relationship.get_type());
|
||||
rels_serializer.attribute("Target", relationship.get_target().get_path().string());
|
||||
|
||||
if (relationship.get_target_mode() == xlnt::target_mode::external)
|
||||
{
|
||||
rels_serializer.attribute("TargetMode", "External");
|
||||
}
|
||||
|
||||
rels_serializer.end_element(xmlns, "Relationship");
|
||||
}
|
||||
|
||||
rels_serializer.end_element(xmlns, "Relationships");
|
||||
destination_.write_string(rels_stream.str(), rels_path);
|
||||
}
|
||||
|
||||
|
||||
bool xlsx_producer::write_color(const xlnt::color &color)
|
||||
{
|
||||
switch (color.get_type())
|
||||
{
|
||||
case xlnt::color::type::theme:
|
||||
serializer().attribute("theme", std::to_string(color.get_theme().get_index()));
|
||||
break;
|
||||
|
||||
case xlnt::color::type::indexed:
|
||||
serializer().attribute("indexed", std::to_string(color.get_indexed().get_index()));
|
||||
break;
|
||||
|
||||
case xlnt::color::type::rgb:
|
||||
default:
|
||||
serializer().attribute("rgb", color.get_rgb().get_hex_string());
|
||||
break;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void xlsx_producer::write_dxfs()
|
||||
{
|
||||
serializer().attribute("count", "0");
|
||||
}
|
||||
|
||||
void xlsx_producer::write_table_styles()
|
||||
{
|
||||
serializer().attribute("count", "0");
|
||||
serializer().attribute("defaultTableStyle", "TableStyleMedium9");
|
||||
serializer().attribute("defaultPivotStyle", "PivotStyleMedium7");
|
||||
}
|
||||
|
||||
void xlsx_producer::write_colors(const std::vector<xlnt::color> &colors)
|
||||
{
|
||||
serializer().start_element("indexedColors");
|
||||
|
||||
for (auto &c : colors)
|
||||
{
|
||||
serializer().start_element("rgbColor");
|
||||
serializer().attribute("rgb", c.get_rgb().get_hex_string());
|
||||
serializer().end_element();
|
||||
}
|
||||
|
||||
serializer().end_element();
|
||||
}
|
||||
|
||||
} // namespace detail
|
||||
} // namepsace xlnt
|
||||
|
|
|
@ -31,8 +31,13 @@
|
|||
#include <xlnt/xlnt_config.hpp>
|
||||
#include <xlnt/packaging/zip_file.hpp>
|
||||
|
||||
namespace xml {
|
||||
class serializer;
|
||||
} // namespace xml
|
||||
|
||||
namespace xlnt {
|
||||
|
||||
class color;
|
||||
class path;
|
||||
class relationship;
|
||||
class workbook;
|
||||
|
@ -62,46 +67,46 @@ private:
|
|||
|
||||
// Package Parts
|
||||
|
||||
void write_manifest();
|
||||
void write_core_properties(const relationship &rel, xml::serializer &serializer);
|
||||
void write_extended_properties(const relationship &rel, xml::serializer &serializer);
|
||||
void write_custom_properties(const relationship &rel, xml::serializer &serializer);
|
||||
void write_content_types();
|
||||
void write_core_properties(const relationship &rel);
|
||||
void write_extended_properties(const relationship &rel);
|
||||
void write_custom_properties(const relationship &rel);
|
||||
void write_thumbnail(const relationship &rel);
|
||||
|
||||
// SpreadsheetML-Specific Package Parts
|
||||
|
||||
void write_workbook(const relationship &rel, xml::serializer &serializer);
|
||||
void write_workbook(const relationship &rel);
|
||||
|
||||
// Workbook Relationship Target Parts
|
||||
|
||||
void write_calculation_chain(const relationship &rel, xml::serializer &serializer);
|
||||
void write_connections(const relationship &rel, xml::serializer &serializer);
|
||||
void write_custom_xml_mappings(const relationship &rel, xml::serializer &serializer);
|
||||
void write_external_workbook_references(const relationship &rel, xml::serializer &serializer);
|
||||
void write_metadata(const relationship &rel, xml::serializer &serializer);
|
||||
void write_pivot_table(const relationship &rel, xml::serializer &serializer);
|
||||
void write_shared_string_table(const relationship &rel, xml::serializer &serializer);
|
||||
void write_shared_workbook_revision_headers(const relationship &rel, xml::serializer &serializer);
|
||||
void write_shared_workbook(const relationship &rel, xml::serializer &serializer);
|
||||
void write_shared_workbook_user_data(const relationship &rel, xml::serializer &serializer);
|
||||
void write_styles(const relationship &rel, xml::serializer &serializer);
|
||||
void write_theme(const relationship &rel, xml::serializer &serializer);
|
||||
void write_volatile_dependencies(const relationship &rel, xml::serializer &serializer);
|
||||
void write_calculation_chain(const relationship &rel);
|
||||
void write_connections(const relationship &rel);
|
||||
void write_custom_xml_mappings(const relationship &rel);
|
||||
void write_external_workbook_references(const relationship &rel);
|
||||
void write_metadata(const relationship &rel);
|
||||
void write_pivot_table(const relationship &rel);
|
||||
void write_shared_string_table(const relationship &rel);
|
||||
void write_shared_workbook_revision_headers(const relationship &rel);
|
||||
void write_shared_workbook(const relationship &rel);
|
||||
void write_shared_workbook_user_data(const relationship &rel);
|
||||
void write_styles(const relationship &rel);
|
||||
void write_theme(const relationship &rel);
|
||||
void write_volatile_dependencies(const relationship &rel);
|
||||
|
||||
void write_chartsheet(const relationship &rel, xml::serializer &serializer);
|
||||
void write_dialogsheet(const relationship &rel, xml::serializer &serializer);
|
||||
void write_worksheet(const relationship &rel, xml::serializer &serializer);
|
||||
void write_chartsheet(const relationship &rel);
|
||||
void write_dialogsheet(const relationship &rel);
|
||||
void write_worksheet(const relationship &rel);
|
||||
|
||||
// Sheet Relationship Target Parts
|
||||
|
||||
void write_comments(const relationship &rel, xml::serializer &serializer);
|
||||
void write_drawings(const relationship &rel, xml::serializer &serializer);
|
||||
void write_comments(const relationship &rel);
|
||||
void write_drawings(const relationship &rel);
|
||||
|
||||
// Other Parts
|
||||
|
||||
void write_custom_property(xml::serializer &serializer);
|
||||
void write_unknown_parts(xml::serializer &serializer);
|
||||
void write_unknown_relationships(xml::serializer &serializer);
|
||||
void write_custom_property();
|
||||
void write_unknown_parts();
|
||||
void write_unknown_relationships();
|
||||
|
||||
// Helpers
|
||||
|
||||
|
@ -111,6 +116,18 @@ private:
|
|||
/// we're trying to match.
|
||||
/// </summary>
|
||||
std::string write_bool(bool boolean) const;
|
||||
|
||||
void write_relationships(const std::vector<xlnt::relationship> &relationships, const path &part);
|
||||
bool write_color(const xlnt::color &color);
|
||||
void write_dxfs();
|
||||
void write_table_styles();
|
||||
void write_colors(const std::vector<xlnt::color> &colors);
|
||||
|
||||
/// <summary>
|
||||
/// Dereference serializer_ pointer and return a reference to the object.
|
||||
/// This is called by internal methods so that we can use . instead of ->.
|
||||
/// </summary>
|
||||
xml::serializer &serializer();
|
||||
|
||||
/// <summary>
|
||||
/// A reference to the workbook which is the object of read/write operations.
|
||||
|
@ -122,6 +139,12 @@ private:
|
|||
/// will be written.
|
||||
/// </summary>
|
||||
zip_file destination_;
|
||||
|
||||
/// <summary>
|
||||
/// Instead of passing the current serializer into part serialization methods,
|
||||
/// store pointer in this field and access it in methods with xlsx_producer::serializer().
|
||||
/// </summary>
|
||||
xml::serializer *serializer_;
|
||||
};
|
||||
|
||||
} // namespace detail
|
||||
|
|
Loading…
Reference in New Issue
Block a user