mirror of
https://github.com/tfussell/xlnt.git
synced 2024-03-22 13:11:17 +08:00
move serialization classes to detail, recouple with pugixml (no reason to abstract)
This commit is contained in:
parent
d8b9a71c59
commit
9ae506c1ea
|
@ -1,75 +0,0 @@
|
|||
// Copyright (c) 2014-2016 Thomas Fussell
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
// of this software and associated documentation files (the "Software"), to deal
|
||||
// in the Software without restriction, including without limitation the rights
|
||||
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
// copies of the Software, and to permit persons to whom the Software is
|
||||
// furnished to do so, subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included in
|
||||
// all copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, WRISING FROM,
|
||||
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
// THE SOFTWARE
|
||||
//
|
||||
// @license: http://www.opensource.org/licenses/mit-license.php
|
||||
// @author: see AUTHORS file
|
||||
#pragma once
|
||||
|
||||
#include <memory>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
#include <xlnt/xlnt_config.hpp>
|
||||
|
||||
namespace xlnt {
|
||||
namespace detail {
|
||||
struct xml_document_impl;
|
||||
}
|
||||
|
||||
class xml_node;
|
||||
class xml_serializer;
|
||||
|
||||
/// <summary>
|
||||
/// Abstracts an XML document from a particular implementation.
|
||||
/// </summary>
|
||||
class XLNT_CLASS xml_document
|
||||
{
|
||||
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:
|
||||
friend class xml_serializer;
|
||||
std::unique_ptr<detail::xml_document_impl> d_;
|
||||
};
|
||||
|
||||
} // namespace xlnt
|
|
@ -1,80 +0,0 @@
|
|||
// Copyright (c) 2014-2016 Thomas Fussell
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
// of this software and associated documentation files (the "Software"), to deal
|
||||
// in the Software without restriction, including without limitation the rights
|
||||
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
// copies of the Software, and to permit persons to whom the Software is
|
||||
// furnished to do so, subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included in
|
||||
// all copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, WRISING FROM,
|
||||
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
// THE SOFTWARE
|
||||
//
|
||||
// @license: http://www.opensource.org/licenses/mit-license.php
|
||||
// @author: see AUTHORS file
|
||||
#pragma once
|
||||
|
||||
#include <memory>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
#include <xlnt/xlnt_config.hpp>
|
||||
|
||||
namespace xlnt {
|
||||
namespace detail {
|
||||
struct xml_node_impl;
|
||||
}
|
||||
|
||||
class xml_document;
|
||||
|
||||
/// <summary>
|
||||
/// Abstracts an XML node from a particular implementation.
|
||||
/// </summary>
|
||||
class XLNT_CLASS xml_node
|
||||
{
|
||||
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:
|
||||
friend class xml_document;
|
||||
friend class xml_serializer;
|
||||
xml_node(const detail::xml_node_impl &d);
|
||||
std::unique_ptr<detail::xml_node_impl> d_;
|
||||
};
|
||||
|
||||
} // namespace xlnt
|
|
@ -1,46 +0,0 @@
|
|||
// Copyright (c) 2014-2016 Thomas Fussell
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
// of this software and associated documentation files (the "Software"), to deal
|
||||
// in the Software without restriction, including without limitation the rights
|
||||
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
// copies of the Software, and to permit persons to whom the Software is
|
||||
// furnished to do so, subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included in
|
||||
// all copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, WRISING FROM,
|
||||
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
// THE SOFTWARE
|
||||
//
|
||||
// @license: http://www.opensource.org/licenses/mit-license.php
|
||||
// @author: see AUTHORS file
|
||||
#pragma once
|
||||
|
||||
#include <string>
|
||||
|
||||
#include <xlnt/xlnt_config.hpp>
|
||||
|
||||
namespace xlnt {
|
||||
|
||||
class xml_document;
|
||||
class xml_node;
|
||||
|
||||
/// <summary>
|
||||
/// Converts XML documents to and from raw strings.
|
||||
/// </summary>
|
||||
class XLNT_CLASS xml_serializer
|
||||
{
|
||||
public:
|
||||
static std::string serialize(const xml_document &xml);
|
||||
static xml_document deserialize(const std::string &xml_string);
|
||||
|
||||
static std::string serialize_node(const xml_node &xml);
|
||||
};
|
||||
|
||||
} // namespace xlnt
|
|
@ -43,9 +43,6 @@
|
|||
#include <xlnt/packaging/relationship.hpp>
|
||||
#include <xlnt/packaging/zip_file.hpp>
|
||||
|
||||
// serialization
|
||||
#include <xlnt/serialization/encoding.hpp>
|
||||
|
||||
// styles
|
||||
#include <xlnt/styles/alignment.hpp>
|
||||
#include <xlnt/styles/base_format.hpp>
|
||||
|
@ -74,6 +71,7 @@
|
|||
// workbook
|
||||
#include <xlnt/workbook/const_worksheet_iterator.hpp>
|
||||
#include <xlnt/workbook/document_security.hpp>
|
||||
#include <xlnt/workbook/encoding.hpp>
|
||||
#include <xlnt/workbook/external_book.hpp>
|
||||
#include <xlnt/workbook/named_range.hpp>
|
||||
#include <xlnt/workbook/theme.hpp>
|
||||
|
|
|
@ -31,7 +31,6 @@
|
|||
#include <xlnt/cell/text.hpp>
|
||||
#include <xlnt/packaging/document_properties.hpp>
|
||||
#include <xlnt/packaging/relationship.hpp>
|
||||
#include <xlnt/serialization/encoding.hpp>
|
||||
#include <xlnt/styles/color.hpp>
|
||||
#include <xlnt/styles/format.hpp>
|
||||
#include <xlnt/styles/style.hpp>
|
||||
|
@ -41,6 +40,7 @@
|
|||
#include <xlnt/utils/timedelta.hpp>
|
||||
#include <xlnt/utils/exceptions.hpp>
|
||||
#include <xlnt/utils/utf8string.hpp>
|
||||
#include <xlnt/workbook/encoding.hpp>
|
||||
#include <xlnt/workbook/workbook.hpp>
|
||||
#include <xlnt/worksheet/column_properties.hpp>
|
||||
#include <xlnt/worksheet/row_properties.hpp>
|
||||
|
|
|
@ -21,12 +21,14 @@
|
|||
//
|
||||
// @license: http://www.opensource.org/licenses/mit-license.php
|
||||
// @author: see AUTHORS file
|
||||
#include <xlnt/serialization/comment_serializer.hpp>
|
||||
#include <detail/comment_serializer.hpp>
|
||||
|
||||
namespace xlnt {
|
||||
namespace detail {
|
||||
|
||||
comment_serializer::comment_serializer(worksheet sheet) : sheet_(sheet)
|
||||
{
|
||||
}
|
||||
|
||||
} // namespace detail
|
||||
} // namespace xlnt
|
|
@ -29,9 +29,12 @@
|
|||
#include <xlnt/cell/comment.hpp>
|
||||
#include <xlnt/worksheet/worksheet.hpp>
|
||||
|
||||
namespace xlnt {
|
||||
|
||||
namespace pugi {
|
||||
class xml_document;
|
||||
} // namespace pugi
|
||||
|
||||
namespace xlnt {
|
||||
namespace detail {
|
||||
|
||||
/// <summary>
|
||||
/// Manages converting comments to and from XML.
|
||||
|
@ -40,14 +43,15 @@ class XLNT_CLASS comment_serializer
|
|||
{
|
||||
comment_serializer(worksheet sheet);
|
||||
|
||||
void read_comments(const xml_document &xml);
|
||||
void read_comments_vml(const xml_document &xml);
|
||||
void read_comments(const pugi::xml_document &xml);
|
||||
void read_comments_vml(const pugi::xml_document &xml);
|
||||
|
||||
xml_document write_comments() const;
|
||||
xml_document write_comments_vml() const;
|
||||
void write_comments(pugi::xml_document &xml) const;
|
||||
void write_comments_vml(pugi::xml_document &xml) const;
|
||||
|
||||
private:
|
||||
worksheet sheet_;
|
||||
};
|
||||
|
||||
} // namespace detail
|
||||
} // namespace xlnt
|
|
@ -23,19 +23,20 @@
|
|||
// @author: see AUTHORS file
|
||||
#include <algorithm>
|
||||
#include <iterator>
|
||||
#include <pugixml.hpp>
|
||||
|
||||
#include <detail/constants.hpp>
|
||||
#include <detail/excel_serializer.hpp>
|
||||
#include <detail/manifest_serializer.hpp>
|
||||
#include <detail/relationship_serializer.hpp>
|
||||
#include <detail/shared_strings_serializer.hpp>
|
||||
#include <detail/style_serializer.hpp>
|
||||
#include <detail/stylesheet.hpp>
|
||||
#include <detail/theme_serializer.hpp>
|
||||
#include <detail/workbook_impl.hpp>
|
||||
#include <detail/workbook_serializer.hpp>
|
||||
#include <detail/worksheet_serializer.hpp>
|
||||
#include <xlnt/cell/text.hpp>
|
||||
#include <xlnt/serialization/excel_serializer.hpp>
|
||||
#include <xlnt/serialization/manifest_serializer.hpp>
|
||||
#include <xlnt/serialization/relationship_serializer.hpp>
|
||||
#include <xlnt/serialization/shared_strings_serializer.hpp>
|
||||
#include <xlnt/serialization/style_serializer.hpp>
|
||||
#include <xlnt/serialization/theme_serializer.hpp>
|
||||
#include <xlnt/serialization/workbook_serializer.hpp>
|
||||
#include <xlnt/serialization/worksheet_serializer.hpp>
|
||||
#include <xlnt/serialization/xml_document.hpp>
|
||||
#include <xlnt/serialization/xml_node.hpp>
|
||||
#include <xlnt/serialization/xml_serializer.hpp>
|
||||
#include <xlnt/packaging/document_properties.hpp>
|
||||
#include <xlnt/packaging/manifest.hpp>
|
||||
#include <xlnt/styles/format.hpp>
|
||||
|
@ -46,10 +47,6 @@
|
|||
#include <xlnt/worksheet/range_iterator.hpp>
|
||||
#include <xlnt/worksheet/worksheet.hpp>
|
||||
|
||||
#include <detail/constants.hpp>
|
||||
#include <detail/stylesheet.hpp>
|
||||
#include <detail/workbook_impl.hpp>
|
||||
|
||||
namespace {
|
||||
|
||||
std::string::size_type find_string_in_string(const std::string &string, const std::string &substring)
|
||||
|
@ -80,8 +77,8 @@ bool load_workbook(xlnt::zip_file &archive, bool guess_types, bool data_only, xl
|
|||
}
|
||||
|
||||
xlnt::manifest_serializer ms(wb.get_manifest());
|
||||
xlnt::xml_document manifest_xml;
|
||||
manifest_xml.from_string(archive.read(xlnt::constants::ArcContentTypes()));
|
||||
pugi::xml_document manifest_xml;
|
||||
manifest_xml.load(archive.read(xlnt::constants::ArcContentTypes()).c_str());
|
||||
ms.read_manifest(manifest_xml);
|
||||
|
||||
if (ms.determine_document_type() != "excel")
|
||||
|
@ -94,16 +91,16 @@ bool load_workbook(xlnt::zip_file &archive, bool guess_types, bool data_only, xl
|
|||
if(archive.has_file(xlnt::constants::ArcCore()))
|
||||
{
|
||||
xlnt::workbook_serializer workbook_serializer_(wb);
|
||||
xlnt::xml_document core_properties_xml;
|
||||
core_properties_xml.from_string(archive.read(xlnt::constants::ArcCore()));
|
||||
pugi::xml_document core_properties_xml;
|
||||
core_properties_xml.load(archive.read(xlnt::constants::ArcCore()).c_str());
|
||||
workbook_serializer_.read_properties_core(core_properties_xml);
|
||||
}
|
||||
|
||||
if(archive.has_file(xlnt::constants::ArcApp()))
|
||||
{
|
||||
xlnt::workbook_serializer workbook_serializer_(wb);
|
||||
xlnt::xml_document app_properties_xml;
|
||||
app_properties_xml.from_string(archive.read(xlnt::constants::ArcApp()));
|
||||
pugi::xml_document app_properties_xml;
|
||||
app_properties_xml.load(archive.read(xlnt::constants::ArcApp()).c_str());
|
||||
workbook_serializer_.read_properties_app(app_properties_xml);
|
||||
}
|
||||
|
||||
|
@ -122,22 +119,22 @@ bool load_workbook(xlnt::zip_file &archive, bool guess_types, bool data_only, xl
|
|||
wb.create_relationship(relationship.get_id(), relationship.get_target_uri(), relationship.get_type());
|
||||
}
|
||||
|
||||
xlnt::xml_document xml;
|
||||
xml.from_string(archive.read(xlnt::constants::ArcWorkbook()));
|
||||
pugi::xml_document xml;
|
||||
xml.load(archive.read(xlnt::constants::ArcWorkbook()).c_str());
|
||||
|
||||
auto root_node = xml.get_child("workbook");
|
||||
auto root_node = xml.child("workbook");
|
||||
|
||||
auto workbook_pr_node = root_node.get_child("workbookPr");
|
||||
auto workbook_pr_node = root_node.child("workbookPr");
|
||||
wb.get_properties().excel_base_date =
|
||||
(workbook_pr_node.has_attribute("date1904") && workbook_pr_node.get_attribute("date1904") != "0")
|
||||
(workbook_pr_node.attribute("date1904") && workbook_pr_node.attribute("date1904").value() != std::string("0"))
|
||||
? xlnt::calendar::mac_1904
|
||||
: xlnt::calendar::windows_1900;
|
||||
|
||||
if(archive.has_file(xlnt::constants::ArcSharedString()))
|
||||
{
|
||||
std::vector<xlnt::text> shared_strings;
|
||||
xlnt::xml_document shared_strings_xml;
|
||||
shared_strings_xml.from_string(archive.read(xlnt::constants::ArcSharedString()));
|
||||
pugi::xml_document shared_strings_xml;
|
||||
shared_strings_xml.load(archive.read(xlnt::constants::ArcSharedString()).c_str());
|
||||
xlnt::shared_strings_serializer::read_shared_strings(shared_strings_xml, shared_strings);
|
||||
|
||||
for (auto &shared_string : shared_strings)
|
||||
|
@ -148,16 +145,16 @@ bool load_workbook(xlnt::zip_file &archive, bool guess_types, bool data_only, xl
|
|||
|
||||
xlnt::detail::stylesheet stylesheet;
|
||||
xlnt::style_serializer style_serializer(stylesheet);
|
||||
xlnt::xml_document style_xml;
|
||||
style_xml.from_string(archive.read(xlnt::constants::ArcStyles()));
|
||||
pugi::xml_document style_xml;
|
||||
style_xml.load(archive.read(xlnt::constants::ArcStyles()).c_str());
|
||||
style_serializer.read_stylesheet(style_xml);
|
||||
|
||||
auto sheets_node = root_node.get_child("sheets");
|
||||
auto sheets_node = root_node.child("sheets");
|
||||
|
||||
for (auto sheet_node : sheets_node.get_children())
|
||||
for (auto sheet_node : sheets_node.children())
|
||||
{
|
||||
auto rel = wb.get_relationship(sheet_node.get_attribute("r:id"));
|
||||
auto ws = wb.create_sheet(sheet_node.get_attribute("name"), rel);
|
||||
auto rel = wb.get_relationship(sheet_node.attribute("r:id").value());
|
||||
auto ws = wb.create_sheet(sheet_node.attribute("name").value(), rel);
|
||||
|
||||
//TODO: this is really bad
|
||||
auto ws_filename = (rel.get_target_uri().substr(0, 3) != "xl/" ? "xl/" : "") + rel.get_target_uri();
|
||||
|
@ -170,8 +167,8 @@ bool load_workbook(xlnt::zip_file &archive, bool guess_types, bool data_only, xl
|
|||
}
|
||||
|
||||
xlnt::worksheet_serializer worksheet_serializer(ws);
|
||||
xlnt::xml_document worksheet_xml;
|
||||
worksheet_xml.from_string(archive.read(ws_filename));
|
||||
pugi::xml_document worksheet_xml;
|
||||
worksheet_xml.load(archive.read(ws_filename).c_str());
|
||||
worksheet_serializer.read_worksheet(worksheet_xml, stylesheet);
|
||||
}
|
||||
|
||||
|
@ -249,31 +246,51 @@ void excel_serializer::write_data(bool /*as_template*/)
|
|||
relationship_serializer_.write_relationships(workbook_.get_root_relationships(), "");
|
||||
relationship_serializer_.write_relationships(workbook_.get_relationships(), constants::ArcWorkbook());
|
||||
|
||||
xml_document properties_app_xml;
|
||||
pugi::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()));
|
||||
workbook_serializer_.write_properties_app(properties_app_xml);
|
||||
std::ostringstream ss;
|
||||
properties_app_xml.save(ss);
|
||||
archive_.writestr(constants::ArcApp(), ss.str());
|
||||
|
||||
pugi::xml_document properties_core_xml;
|
||||
workbook_serializer_.write_properties_core(properties_core_xml);
|
||||
properties_core_xml.save(ss);
|
||||
archive_.writestr(constants::ArcCore(), ss.str());
|
||||
|
||||
pugi::xml_document theme_xml;
|
||||
theme_serializer theme_serializer_;
|
||||
archive_.writestr(constants::ArcTheme(), theme_serializer_.write_theme(workbook_.get_loaded_theme()).to_string());
|
||||
theme_serializer_.write_theme(workbook_.get_loaded_theme(), theme_xml);
|
||||
theme_xml.save(ss);
|
||||
archive_.writestr(constants::ArcTheme(), ss.str());
|
||||
|
||||
if (!workbook_.get_shared_strings().empty())
|
||||
{
|
||||
const auto &strings = workbook_.get_shared_strings();
|
||||
auto shared_strings_xml = xlnt::shared_strings_serializer::write_shared_strings(strings);
|
||||
|
||||
archive_.writestr(constants::ArcSharedString(), xml_serializer::serialize(shared_strings_xml));
|
||||
pugi::xml_document shared_strings_xml;
|
||||
shared_strings_serializer strings_serializer;
|
||||
strings_serializer.write_shared_strings(strings, shared_strings_xml);
|
||||
shared_strings_xml.save(ss);
|
||||
|
||||
archive_.writestr(constants::ArcSharedString(), ss.str());
|
||||
}
|
||||
|
||||
archive_.writestr(constants::ArcWorkbook(), xml_serializer::serialize(workbook_serializer_.write_workbook()));
|
||||
pugi::xml_document workbook_xml;
|
||||
workbook_serializer_.write_workbook(workbook_xml);
|
||||
workbook_xml.save(ss);
|
||||
archive_.writestr(constants::ArcWorkbook(), ss.str());
|
||||
|
||||
style_serializer style_serializer(workbook_.d_->stylesheet_);
|
||||
xlnt::xml_document style_xml;
|
||||
pugi::xml_document style_xml;
|
||||
style_serializer.write_stylesheet(style_xml);
|
||||
archive_.writestr(constants::ArcStyles(), style_xml.to_string());
|
||||
style_xml.save(ss);
|
||||
archive_.writestr(constants::ArcStyles(), ss.str());
|
||||
|
||||
manifest_serializer manifest_serializer_(workbook_.get_manifest());
|
||||
archive_.writestr(constants::ArcContentTypes(), manifest_serializer_.write_manifest().to_string());
|
||||
pugi::xml_document manifest_xml;
|
||||
manifest_serializer_.write_manifest(manifest_xml);
|
||||
manifest_xml.save(ss);
|
||||
archive_.writestr(constants::ArcContentTypes(), ss.str());
|
||||
|
||||
write_worksheets();
|
||||
|
||||
|
@ -297,7 +314,12 @@ void excel_serializer::write_worksheets()
|
|||
{
|
||||
worksheet_serializer serializer_(ws);
|
||||
std::string ws_filename = (relationship.get_target_uri().substr(0, 3) != "xl/" ? "xl/" : "") + relationship.get_target_uri();
|
||||
archive_.writestr(ws_filename, serializer_.write_worksheet().to_string());
|
||||
std::ostringstream ss;
|
||||
pugi::xml_document worksheet_xml;
|
||||
serializer_.write_worksheet(worksheet_xml);
|
||||
worksheet_xml.save(ss);
|
||||
archive_.writestr(ws_filename, ss.str());
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
|
@ -21,12 +21,12 @@
|
|||
//
|
||||
// @license: http://www.opensource.org/licenses/mit-license.php
|
||||
// @author: see AUTHORS file
|
||||
#include <xlnt/packaging/manifest.hpp>
|
||||
#include <xlnt/serialization/manifest_serializer.hpp>
|
||||
#include <xlnt/serialization/xml_document.hpp>
|
||||
#include <xlnt/serialization/xml_node.hpp>
|
||||
|
||||
#include <pugixml.hpp>
|
||||
|
||||
#include <detail/constants.hpp>
|
||||
#include <detail/manifest_serializer.hpp>
|
||||
#include <xlnt/packaging/manifest.hpp>
|
||||
|
||||
namespace xlnt {
|
||||
|
||||
|
@ -34,45 +34,41 @@ manifest_serializer::manifest_serializer(manifest &m) : manifest_(m)
|
|||
{
|
||||
}
|
||||
|
||||
void manifest_serializer::read_manifest(const xml_document &xml)
|
||||
void manifest_serializer::read_manifest(const pugi::xml_document &xml)
|
||||
{
|
||||
const auto root_node = xml.get_child("Types");
|
||||
const auto root_node = xml.child("Types");
|
||||
|
||||
for (const auto child : root_node.get_children())
|
||||
for (const auto child : root_node.children())
|
||||
{
|
||||
if (child.get_name() == "Default")
|
||||
if (child.name() == std::string("Default"))
|
||||
{
|
||||
manifest_.add_default_type(child.get_attribute("Extension"), child.get_attribute("ContentType"));
|
||||
manifest_.add_default_type(child.attribute("Extension").value(), child.attribute("ContentType").value());
|
||||
}
|
||||
else if (child.get_name() == "Override")
|
||||
else if (child.name() == std::string("Override"))
|
||||
{
|
||||
manifest_.add_override_type(child.get_attribute("PartName"), child.get_attribute("ContentType"));
|
||||
manifest_.add_override_type(child.attribute("PartName").value(), child.attribute("ContentType").value());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
xml_document manifest_serializer::write_manifest() const
|
||||
void manifest_serializer::write_manifest(pugi::xml_document &xml) const
|
||||
{
|
||||
xml_document xml;
|
||||
|
||||
auto root_node = xml.add_child("Types");
|
||||
xml.add_namespace("", constants::Namespace("content-types"));
|
||||
auto root_node = xml.append_child("Types");
|
||||
root_node.append_attribute("xmlns").set_value(constants::Namespace("content-types").c_str());
|
||||
|
||||
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());
|
||||
auto type_node = root_node.append_child("Default");
|
||||
type_node.append_attribute("Extension").set_value(default_type.get_extension().c_str());
|
||||
type_node.append_attribute("ContentType").set_value(default_type.get_content_type().c_str());
|
||||
}
|
||||
|
||||
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());
|
||||
auto type_node = root_node.append_child("Override");
|
||||
type_node.append_attribute("PartName").set_value(override_type.get_part_name().c_str());
|
||||
type_node.append_attribute("ContentType").set_value(override_type.get_content_type().c_str());
|
||||
}
|
||||
|
||||
return xml;
|
||||
}
|
||||
|
||||
std::string manifest_serializer::determine_document_type() const
|
|
@ -27,10 +27,13 @@
|
|||
|
||||
#include <xlnt/xlnt_config.hpp>
|
||||
|
||||
namespace pugi {
|
||||
class xml_document;
|
||||
} // namespace pugi
|
||||
|
||||
namespace xlnt {
|
||||
|
||||
class manifest;
|
||||
class xml_document;
|
||||
|
||||
/// <summary>
|
||||
/// Manages converting a manifest to and from XML.
|
||||
|
@ -40,8 +43,8 @@ class XLNT_CLASS manifest_serializer
|
|||
public:
|
||||
manifest_serializer(manifest &m);
|
||||
|
||||
void read_manifest(const xml_document &xml);
|
||||
xml_document write_manifest() const;
|
||||
void read_manifest(const pugi::xml_document &xml);
|
||||
void write_manifest(pugi::xml_document &xml) const;
|
||||
|
||||
std::string determine_document_type() const;
|
||||
|
|
@ -21,14 +21,14 @@
|
|||
//
|
||||
// @license: http://www.opensource.org/licenses/mit-license.php
|
||||
// @author: see AUTHORS file
|
||||
#include <xlnt/serialization/relationship_serializer.hpp>
|
||||
|
||||
#include <pugixml.hpp>
|
||||
#include <sstream>
|
||||
|
||||
#include <detail/constants.hpp>
|
||||
#include <detail/relationship_serializer.hpp>
|
||||
#include <xlnt/packaging/relationship.hpp>
|
||||
#include <xlnt/packaging/zip_file.hpp>
|
||||
#include <xlnt/serialization/xml_document.hpp>
|
||||
#include <xlnt/serialization/xml_node.hpp>
|
||||
|
||||
#include "detail/constants.hpp"
|
||||
|
||||
namespace {
|
||||
|
||||
|
@ -57,23 +57,18 @@ relationship_serializer::relationship_serializer(zip_file &archive) : archive_(a
|
|||
|
||||
std::vector<relationship> relationship_serializer::read_relationships(const std::string &target)
|
||||
{
|
||||
xml_document xml;
|
||||
xml.from_string(archive_.read(make_rels_name(target)));
|
||||
pugi::xml_document xml;
|
||||
xml.load(archive_.read(make_rels_name(target)).c_str());
|
||||
|
||||
auto root_node = xml.get_child("Relationships");
|
||||
auto root_node = xml.child("Relationships");
|
||||
|
||||
std::vector<relationship> relationships;
|
||||
|
||||
for (auto relationship_node : root_node.get_children())
|
||||
for (auto relationship_node : root_node.children("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 rel_target = relationship_node.get_attribute("Target");
|
||||
std::string id = relationship_node.attribute("Id").value();
|
||||
std::string type = relationship_node.attribute("Type").value();
|
||||
std::string rel_target = relationship_node.attribute("Target").value();
|
||||
|
||||
relationships.push_back(xlnt::relationship(type, id, rel_target));
|
||||
}
|
||||
|
@ -84,27 +79,29 @@ std::vector<relationship> relationship_serializer::read_relationships(const std:
|
|||
bool relationship_serializer::write_relationships(const std::vector<relationship> &relationships,
|
||||
const std::string &target)
|
||||
{
|
||||
xml_document xml;
|
||||
pugi::xml_document xml;
|
||||
|
||||
auto root_node = xml.add_child("Relationships");
|
||||
auto root_node = xml.append_child("Relationships");
|
||||
|
||||
xml.add_namespace("", constants::Namespace("relationships"));
|
||||
root_node.append_attribute("xmlns").set_value(constants::Namespace("relationships").c_str());
|
||||
|
||||
for (const auto &relationship : relationships)
|
||||
{
|
||||
auto relationship_node = root_node.add_child("Relationship");
|
||||
auto relationship_node = root_node.append_child("Relationship");
|
||||
|
||||
relationship_node.add_attribute("Id", relationship.get_id());
|
||||
relationship_node.add_attribute("Type", relationship.get_type_string());
|
||||
relationship_node.add_attribute("Target", relationship.get_target_uri());
|
||||
relationship_node.append_attribute("Id").set_value(relationship.get_id().c_str());
|
||||
relationship_node.append_attribute("Type").set_value(relationship.get_type_string().c_str());
|
||||
relationship_node.append_attribute("Target").set_value(relationship.get_target_uri().c_str());
|
||||
|
||||
if (relationship.get_target_mode() == target_mode::external)
|
||||
{
|
||||
relationship_node.add_attribute("TargetMode", "External");
|
||||
relationship_node.append_attribute("TargetMode").set_value("External");
|
||||
}
|
||||
}
|
||||
|
||||
archive_.writestr(make_rels_name(target), xml.to_string());
|
||||
std::ostringstream ss;
|
||||
xml.save(ss);
|
||||
archive_.writestr(make_rels_name(target), ss.str());
|
||||
|
||||
return true;
|
||||
}
|
|
@ -22,10 +22,10 @@
|
|||
// @license: http://www.opensource.org/licenses/mit-license.php
|
||||
// @author: see AUTHORS file
|
||||
|
||||
#include <xlnt/serialization/shared_strings_serializer.hpp>
|
||||
#include <pugixml.hpp>
|
||||
|
||||
#include <detail/shared_strings_serializer.hpp>
|
||||
#include <xlnt/cell/text.hpp>
|
||||
#include <xlnt/serialization/xml_document.hpp>
|
||||
#include <xlnt/serialization/xml_node.hpp>
|
||||
|
||||
namespace {
|
||||
|
||||
|
@ -42,134 +42,125 @@ std::size_t string_to_size_t(const std::string &s)
|
|||
|
||||
namespace xlnt {
|
||||
|
||||
xml_document shared_strings_serializer::write_shared_strings(const std::vector<text> &strings)
|
||||
void shared_strings_serializer::write_shared_strings(const std::vector<text> &strings, pugi::xml_document &xml)
|
||||
{
|
||||
xml_document xml;
|
||||
auto root_node = xml.append_child("sst");
|
||||
|
||||
auto root_node = xml.add_child("sst");
|
||||
root_node.append_attribute("xmlns").set_value("http://schemas.openxmlformats.org/spreadsheetml/2006/main");
|
||||
|
||||
xml.add_namespace("", "http://schemas.openxmlformats.org/spreadsheetml/2006/main");
|
||||
|
||||
root_node.add_attribute("count", std::to_string(strings.size()));
|
||||
root_node.add_attribute("uniqueCount", std::to_string(strings.size()));
|
||||
root_node.append_attribute("count").set_value(std::to_string(strings.size()).c_str());
|
||||
root_node.append_attribute("uniqueCount").set_value(std::to_string(strings.size()).c_str());
|
||||
|
||||
for (const auto &string : strings)
|
||||
{
|
||||
if (string.get_runs().size() == 1 && !string.get_runs().at(0).has_formatting())
|
||||
{
|
||||
root_node.add_child("si").add_child("t").set_text(string.get_plain_string());
|
||||
root_node.append_child("si").append_child("t").text().set(string.get_plain_string().c_str());
|
||||
}
|
||||
else
|
||||
{
|
||||
auto string_item_node = root_node.add_child("si");
|
||||
auto string_item_node = root_node.append_child("si");
|
||||
|
||||
for (const auto &run : string.get_runs())
|
||||
{
|
||||
auto rich_text_run_node = string_item_node.add_child("r");
|
||||
auto rich_text_run_node = string_item_node.append_child("r");
|
||||
|
||||
if (run.has_formatting())
|
||||
{
|
||||
auto run_properties_node = rich_text_run_node.add_child("rPr");
|
||||
auto run_properties_node = rich_text_run_node.append_child("rPr");
|
||||
|
||||
if (run.has_size())
|
||||
{
|
||||
run_properties_node.add_child("sz").add_attribute("val", std::to_string(run.get_size()));
|
||||
run_properties_node.append_child("sz").append_attribute("val").set_value(std::to_string(run.get_size()).c_str());
|
||||
}
|
||||
|
||||
if (run.has_color())
|
||||
{
|
||||
run_properties_node.add_child("color").add_attribute("rgb", run.get_color());
|
||||
run_properties_node.append_child("color").append_attribute("rgb").set_value(run.get_color().c_str());
|
||||
}
|
||||
|
||||
if (run.has_font())
|
||||
{
|
||||
run_properties_node.add_child("rFont").add_attribute("val", run.get_font());
|
||||
run_properties_node.append_child("rFont").append_attribute("val").set_value(run.get_font().c_str());
|
||||
}
|
||||
|
||||
if (run.has_family())
|
||||
{
|
||||
run_properties_node.add_child("family").add_attribute("val", std::to_string(run.get_family()));
|
||||
run_properties_node.append_child("family").append_attribute("val").set_value(std::to_string(run.get_family()).c_str());
|
||||
}
|
||||
|
||||
if (run.has_scheme())
|
||||
{
|
||||
run_properties_node.add_child("scheme").add_attribute("val", run.get_scheme());
|
||||
run_properties_node.append_child("scheme").append_attribute("val").set_value(run.get_scheme().c_str());
|
||||
}
|
||||
}
|
||||
|
||||
auto text_node = rich_text_run_node.add_child("t");
|
||||
text_node.set_text(run.get_string());
|
||||
auto text_node = rich_text_run_node.append_child("t");
|
||||
text_node.text().set(run.get_string().c_str());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return xml;
|
||||
}
|
||||
|
||||
bool shared_strings_serializer::read_shared_strings(const xml_document &xml, std::vector<text> &strings)
|
||||
bool shared_strings_serializer::read_shared_strings(const pugi::xml_document &xml, std::vector<text> &strings)
|
||||
{
|
||||
strings.clear();
|
||||
|
||||
auto root_node = xml.get_child("sst");
|
||||
auto root_node = xml.child("sst");
|
||||
std::size_t unique_count = 0;
|
||||
|
||||
if (root_node.has_attribute("uniqueCount"))
|
||||
if (root_node.attribute("uniqueCount"))
|
||||
{
|
||||
unique_count = string_to_size_t(root_node.get_attribute("uniqueCount"));
|
||||
unique_count = string_to_size_t(root_node.attribute("uniqueCount").value());
|
||||
}
|
||||
|
||||
for (const auto &string_item_node : root_node.get_children())
|
||||
for (const auto string_item_node : root_node.children("si"))
|
||||
{
|
||||
if (string_item_node.get_name() != "si")
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
if (string_item_node.has_child("t"))
|
||||
if (string_item_node.child("t"))
|
||||
{
|
||||
text t;
|
||||
t.set_plain_string(string_item_node.get_child("t").get_text());
|
||||
t.set_plain_string(string_item_node.child("t").text().get());
|
||||
strings.push_back(t);
|
||||
}
|
||||
else if (string_item_node.has_child("r")) // possible multiple text entities.
|
||||
else if (string_item_node.child("r")) // possible multiple text entities.
|
||||
{
|
||||
text t;
|
||||
|
||||
for (const auto& rich_text_run_node : string_item_node.get_children())
|
||||
for (const auto& rich_text_run_node : string_item_node.children("r"))
|
||||
{
|
||||
if (rich_text_run_node.get_name() == "r" && rich_text_run_node.has_child("t"))
|
||||
if (rich_text_run_node.child("t"))
|
||||
{
|
||||
text_run run;
|
||||
|
||||
run.set_string(rich_text_run_node.get_child("t").get_text());
|
||||
run.set_string(rich_text_run_node.child("t").text().get());
|
||||
|
||||
if (rich_text_run_node.has_child("rPr"))
|
||||
if (rich_text_run_node.child("rPr"))
|
||||
{
|
||||
auto run_properties_node = rich_text_run_node.get_child("rPr");
|
||||
auto run_properties_node = rich_text_run_node.child("rPr");
|
||||
|
||||
if (run_properties_node.has_child("sz"))
|
||||
if (run_properties_node.child("sz"))
|
||||
{
|
||||
run.set_size(string_to_size_t(run_properties_node.get_child("sz").get_attribute("val")));
|
||||
run.set_size(string_to_size_t(run_properties_node.child("sz").attribute("val").value()));
|
||||
}
|
||||
|
||||
if (run_properties_node.has_child("rFont"))
|
||||
if (run_properties_node.child("rFont"))
|
||||
{
|
||||
run.set_font(run_properties_node.get_child("rFont").get_attribute("val"));
|
||||
run.set_font(run_properties_node.child("rFont").attribute("val").value());
|
||||
}
|
||||
|
||||
if (run_properties_node.has_child("color"))
|
||||
if (run_properties_node.child("color"))
|
||||
{
|
||||
run.set_color(run_properties_node.get_child("color").get_attribute("rgb"));
|
||||
run.set_color(run_properties_node.child("color").attribute("rgb").value());
|
||||
}
|
||||
|
||||
if (run_properties_node.has_child("family"))
|
||||
if (run_properties_node.child("family"))
|
||||
{
|
||||
run.set_family(string_to_size_t(run_properties_node.get_child("family").get_attribute("val")));
|
||||
run.set_family(string_to_size_t(run_properties_node.child("family").attribute("val").value()));
|
||||
}
|
||||
|
||||
if (run_properties_node.has_child("scheme"))
|
||||
if (run_properties_node.child("scheme"))
|
||||
{
|
||||
run.set_scheme(run_properties_node.get_child("scheme").get_attribute("val"));
|
||||
run.set_scheme(run_properties_node.child("scheme").attribute("val").value());
|
||||
}
|
||||
}
|
||||
|
|
@ -27,10 +27,13 @@
|
|||
|
||||
#include <xlnt/xlnt_config.hpp>
|
||||
|
||||
namespace pugi {
|
||||
class xml_document;
|
||||
} // namespace pugi
|
||||
|
||||
namespace xlnt {
|
||||
|
||||
class text;
|
||||
class xml_document;
|
||||
|
||||
/// <summary>
|
||||
/// Manages converting a set of shared strings to and from XML.
|
||||
|
@ -38,8 +41,8 @@ class xml_document;
|
|||
class XLNT_CLASS shared_strings_serializer
|
||||
{
|
||||
public:
|
||||
static bool read_shared_strings(const xml_document &xml, std::vector<text> &strings);
|
||||
static xml_document write_shared_strings(const std::vector<text> &strings);
|
||||
static bool read_shared_strings(const pugi::xml_document &xml, std::vector<text> &strings);
|
||||
static void write_shared_strings(const std::vector<text> &strings, pugi::xml_document &xml);
|
||||
};
|
||||
|
||||
} // namespace xlnt
|
File diff suppressed because it is too large
Load Diff
|
@ -29,6 +29,10 @@
|
|||
|
||||
#include <xlnt/xlnt_config.hpp>
|
||||
|
||||
namespace pugi {
|
||||
class xml_document;
|
||||
} // namespace pugi
|
||||
|
||||
namespace xlnt {
|
||||
|
||||
class alignment;
|
||||
|
@ -44,8 +48,6 @@ class number_format;
|
|||
class protection;
|
||||
class side;
|
||||
class style;
|
||||
class xml_document;
|
||||
class xml_node;
|
||||
|
||||
namespace detail { struct stylesheet; }
|
||||
|
||||
|
@ -63,13 +65,13 @@ public:
|
|||
/// <summary>
|
||||
/// Load all styles from xml_document into workbook given in constructor.
|
||||
/// </summary>
|
||||
bool read_stylesheet(const xml_document &xml);
|
||||
bool read_stylesheet(const pugi::xml_document &xml);
|
||||
|
||||
/// <summary>
|
||||
/// Populate parameter xml with an XML tree representing the styles contained in the workbook
|
||||
/// given in the constructor.
|
||||
/// </summary>
|
||||
bool write_stylesheet(xml_document &xml);
|
||||
bool write_stylesheet(pugi::xml_document &xml);
|
||||
|
||||
private:
|
||||
/// <summary>
|
370
source/detail/theme_serializer.cpp
Normal file
370
source/detail/theme_serializer.cpp
Normal file
|
@ -0,0 +1,370 @@
|
|||
// Copyright (c) 2014-2016 Thomas Fussell
|
||||
// Copyright (c) 2010-2015 openpyxl
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
// of this software and associated documentation files (the "Software"), to deal
|
||||
// in the Software without restriction, including without limitation the rights
|
||||
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
// copies of the Software, and to permit persons to whom the Software is
|
||||
// furnished to do so, subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included in
|
||||
// all copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, WRISING FROM,
|
||||
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
// THE SOFTWARE
|
||||
//
|
||||
// @license: http://www.opensource.org/licenses/mit-license.php
|
||||
// @author: see AUTHORS file
|
||||
|
||||
#include <pugixml.hpp>
|
||||
#include <vector>
|
||||
|
||||
#include <detail/constants.hpp>
|
||||
#include <detail/theme_serializer.hpp>
|
||||
|
||||
namespace xlnt {
|
||||
|
||||
// I have no idea what this stuff is. I hope it was worth it.
|
||||
void theme_serializer::write_theme(const theme &, pugi::xml_document &xml) const
|
||||
{
|
||||
auto theme_node = xml.append_child("a:theme");
|
||||
theme_node.append_attribute("xmlns:a").set_value(constants::Namespace("drawingml").c_str());
|
||||
theme_node.append_attribute("name").set_value("Office Theme");
|
||||
|
||||
auto theme_elements_node = theme_node.append_child("a:themeElements");
|
||||
auto clr_scheme_node = theme_elements_node.append_child("a:clrScheme");
|
||||
clr_scheme_node.append_attribute("name").set_value("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" },
|
||||
};
|
||||
|
||||
for (auto element : scheme_elements)
|
||||
{
|
||||
auto element_node = clr_scheme_node.append_child(element.name.c_str());
|
||||
element_node.append_child(element.sub_element_name.c_str()).append_attribute("val").set_value(element.val.c_str());
|
||||
|
||||
if (element.name == "a:dk1")
|
||||
{
|
||||
element_node.child(element.sub_element_name.c_str()).append_attribute("lastClr").set_value("000000");
|
||||
}
|
||||
else if (element.name == "a:lt1")
|
||||
{
|
||||
element_node.child(element.sub_element_name.c_str()).append_attribute("lastClr").set_value("FFFFFF");
|
||||
}
|
||||
}
|
||||
|
||||
struct font_scheme
|
||||
{
|
||||
bool typeface;
|
||||
std::string script;
|
||||
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" }
|
||||
};
|
||||
|
||||
auto font_scheme_node = theme_elements_node.append_child("a:fontScheme");
|
||||
font_scheme_node.append_attribute("name").set_value("Office");
|
||||
|
||||
auto major_fonts_node = font_scheme_node.append_child("a:majorFont");
|
||||
auto minor_fonts_node = font_scheme_node.append_child("a:minorFont");
|
||||
|
||||
for (auto scheme : font_schemes)
|
||||
{
|
||||
if (scheme.typeface)
|
||||
{
|
||||
auto major_font_node = major_fonts_node.append_child(scheme.script.c_str());
|
||||
major_font_node.append_attribute("typeface").set_value(scheme.major.c_str());
|
||||
|
||||
auto minor_font_node = minor_fonts_node.append_child(scheme.script.c_str());
|
||||
minor_font_node.append_attribute("typeface").set_value(scheme.minor.c_str());
|
||||
}
|
||||
else
|
||||
{
|
||||
auto major_font_node = major_fonts_node.append_child("a:font");
|
||||
major_font_node.append_attribute("script").set_value(scheme.script.c_str());
|
||||
major_font_node.append_attribute("typeface").set_value(scheme.major.c_str());
|
||||
|
||||
auto minor_font_node = minor_fonts_node.append_child("a:font");
|
||||
minor_font_node.append_attribute("script").set_value(scheme.script.c_str());
|
||||
minor_font_node.append_attribute("typeface").set_value(scheme.minor.c_str());
|
||||
}
|
||||
}
|
||||
|
||||
auto format_scheme_node = theme_elements_node.append_child("a:fmtScheme");
|
||||
format_scheme_node.append_attribute("name").set_value("Office");
|
||||
|
||||
auto fill_style_list_node = format_scheme_node.append_child("a:fillStyleLst");
|
||||
fill_style_list_node.append_child("a:solidFill").append_child("a:schemeClr").append_attribute("val").set_value("phClr");
|
||||
|
||||
auto grad_fill_node = fill_style_list_node.append_child("a:gradFill");
|
||||
grad_fill_node.append_attribute("rotWithShape").set_value("1");
|
||||
|
||||
auto grad_fill_list = grad_fill_node.append_child("a:gsLst");
|
||||
auto gs_node = grad_fill_list.append_child("a:gs");
|
||||
gs_node.append_attribute("pos").set_value("0");
|
||||
auto scheme_color_node = gs_node.append_child("a:schemeClr");
|
||||
scheme_color_node.append_attribute("val").set_value("phClr");
|
||||
scheme_color_node.append_child("a:tint").append_attribute("val").set_value("50000");
|
||||
scheme_color_node.append_child("a:satMod").append_attribute("val").set_value("300000");
|
||||
|
||||
gs_node = grad_fill_list.append_child("a:gs");
|
||||
gs_node.append_attribute("pos").set_value("35000");
|
||||
scheme_color_node = gs_node.append_child("a:schemeClr");
|
||||
scheme_color_node.append_attribute("val").set_value("phClr");
|
||||
scheme_color_node.append_child("a:tint").append_attribute("val").set_value("37000");
|
||||
scheme_color_node.append_child("a:satMod").append_attribute("val").set_value("300000");
|
||||
|
||||
gs_node = grad_fill_list.append_child("a:gs");
|
||||
gs_node.append_attribute("pos").set_value("100000");
|
||||
scheme_color_node = gs_node.append_child("a:schemeClr");
|
||||
scheme_color_node.append_attribute("val").set_value("phClr");
|
||||
scheme_color_node.append_child("a:tint").append_attribute("val").set_value("15000");
|
||||
scheme_color_node.append_child("a:satMod").append_attribute("val").set_value("350000");
|
||||
|
||||
auto lin_node = grad_fill_node.append_child("a:lin");
|
||||
lin_node.append_attribute("ang").set_value("16200000");
|
||||
lin_node.append_attribute("scaled").set_value("1");
|
||||
|
||||
grad_fill_node = fill_style_list_node.append_child("a:gradFill");
|
||||
grad_fill_node.append_attribute("rotWithShape").set_value("1");
|
||||
|
||||
grad_fill_list = grad_fill_node.append_child("a:gsLst");
|
||||
gs_node = grad_fill_list.append_child("a:gs");
|
||||
gs_node.append_attribute("pos").set_value("0");
|
||||
scheme_color_node = gs_node.append_child("a:schemeClr");
|
||||
scheme_color_node.append_attribute("val").set_value("phClr");
|
||||
scheme_color_node.append_child("a:shade").append_attribute("val").set_value("51000");
|
||||
scheme_color_node.append_child("a:satMod").append_attribute("val").set_value("130000");
|
||||
|
||||
gs_node = grad_fill_list.append_child("a:gs");
|
||||
gs_node.append_attribute("pos").set_value("80000");
|
||||
scheme_color_node = gs_node.append_child("a:schemeClr");
|
||||
scheme_color_node.append_attribute("val").set_value("phClr");
|
||||
scheme_color_node.append_child("a:shade").append_attribute("val").set_value("93000");
|
||||
scheme_color_node.append_child("a:satMod").append_attribute("val").set_value("130000");
|
||||
|
||||
gs_node = grad_fill_list.append_child("a:gs");
|
||||
gs_node.append_attribute("pos").set_value("100000");
|
||||
scheme_color_node = gs_node.append_child("a:schemeClr");
|
||||
scheme_color_node.append_attribute("val").set_value("phClr");
|
||||
scheme_color_node.append_child("a:shade").append_attribute("val").set_value("94000");
|
||||
scheme_color_node.append_child("a:satMod").append_attribute("val").set_value("135000");
|
||||
|
||||
lin_node = grad_fill_node.append_child("a:lin");
|
||||
lin_node.append_attribute("ang").set_value("16200000");
|
||||
lin_node.append_attribute("scaled").set_value("0");
|
||||
|
||||
auto line_style_list_node = format_scheme_node.append_child("a:lnStyleLst");
|
||||
|
||||
auto ln_node = line_style_list_node.append_child("a:ln");
|
||||
ln_node.append_attribute("w").set_value("9525");
|
||||
ln_node.append_attribute("cap").set_value("flat");
|
||||
ln_node.append_attribute("cmpd").set_value("sng");
|
||||
ln_node.append_attribute("algn").set_value("ctr");
|
||||
|
||||
auto solid_fill_node = ln_node.append_child("a:solidFill");
|
||||
scheme_color_node = solid_fill_node.append_child("a:schemeClr");
|
||||
scheme_color_node.append_attribute("val").set_value("phClr");
|
||||
scheme_color_node.append_child("a:shade").append_attribute("val").set_value("95000");
|
||||
scheme_color_node.append_child("a:satMod").append_attribute("val").set_value("105000");
|
||||
ln_node.append_child("a:prstDash").append_attribute("val").set_value("solid");
|
||||
|
||||
ln_node = line_style_list_node.append_child("a:ln");
|
||||
ln_node.append_attribute("w").set_value("25400");
|
||||
ln_node.append_attribute("cap").set_value("flat");
|
||||
ln_node.append_attribute("cmpd").set_value("sng");
|
||||
ln_node.append_attribute("algn").set_value("ctr");
|
||||
|
||||
solid_fill_node = ln_node.append_child("a:solidFill");
|
||||
scheme_color_node = solid_fill_node.append_child("a:schemeClr");
|
||||
scheme_color_node.append_attribute("val").set_value("phClr");
|
||||
ln_node.append_child("a:prstDash").append_attribute("val").set_value("solid");
|
||||
|
||||
ln_node = line_style_list_node.append_child("a:ln");
|
||||
ln_node.append_attribute("w").set_value("38100");
|
||||
ln_node.append_attribute("cap").set_value("flat");
|
||||
ln_node.append_attribute("cmpd").set_value("sng");
|
||||
ln_node.append_attribute("algn").set_value("ctr");
|
||||
|
||||
solid_fill_node = ln_node.append_child("a:solidFill");
|
||||
scheme_color_node = solid_fill_node.append_child("a:schemeClr");
|
||||
scheme_color_node.append_attribute("val").set_value("phClr");
|
||||
ln_node.append_child("a:prstDash").append_attribute("val").set_value("solid");
|
||||
|
||||
auto effect_style_list_node = format_scheme_node.append_child("a:effectStyleLst");
|
||||
auto effect_style_node = effect_style_list_node.append_child("a:effectStyle");
|
||||
auto effect_list_node = effect_style_node.append_child("a:effectLst");
|
||||
auto outer_shadow_node = effect_list_node.append_child("a:outerShdw");
|
||||
outer_shadow_node.append_attribute("blurRad").set_value("40000");
|
||||
outer_shadow_node.append_attribute("dist").set_value("20000");
|
||||
outer_shadow_node.append_attribute("dir").set_value("5400000");
|
||||
outer_shadow_node.append_attribute("rotWithShape").set_value("0");
|
||||
auto srgb_clr_node = outer_shadow_node.append_child("a:srgbClr");
|
||||
srgb_clr_node.append_attribute("val").set_value("000000");
|
||||
srgb_clr_node.append_child("a:alpha").append_attribute("val").set_value("38000");
|
||||
|
||||
effect_style_node = effect_style_list_node.append_child("a:effectStyle");
|
||||
effect_list_node = effect_style_node.append_child("a:effectLst");
|
||||
outer_shadow_node = effect_list_node.append_child("a:outerShdw");
|
||||
outer_shadow_node.append_attribute("blurRad").set_value("40000");
|
||||
outer_shadow_node.append_attribute("dist").set_value("23000");
|
||||
outer_shadow_node.append_attribute("dir").set_value("5400000");
|
||||
outer_shadow_node.append_attribute("rotWithShape").set_value("0");
|
||||
srgb_clr_node = outer_shadow_node.append_child("a:srgbClr");
|
||||
srgb_clr_node.append_attribute("val").set_value("000000");
|
||||
srgb_clr_node.append_child("a:alpha").append_attribute("val").set_value("35000");
|
||||
|
||||
effect_style_node = effect_style_list_node.append_child("a:effectStyle");
|
||||
effect_list_node = effect_style_node.append_child("a:effectLst");
|
||||
outer_shadow_node = effect_list_node.append_child("a:outerShdw");
|
||||
outer_shadow_node.append_attribute("blurRad").set_value("40000");
|
||||
outer_shadow_node.append_attribute("dist").set_value("23000");
|
||||
outer_shadow_node.append_attribute("dir").set_value("5400000");
|
||||
outer_shadow_node.append_attribute("rotWithShape").set_value("0");
|
||||
srgb_clr_node = outer_shadow_node.append_child("a:srgbClr");
|
||||
srgb_clr_node.append_attribute("val").set_value("000000");
|
||||
srgb_clr_node.append_child("a:alpha").append_attribute("val").set_value("35000");
|
||||
auto scene3d_node = effect_style_node.append_child("a:scene3d");
|
||||
auto camera_node = scene3d_node.append_child("a:camera");
|
||||
camera_node.append_attribute("prst").set_value("orthographicFront");
|
||||
auto rot_node = camera_node.append_child("a:rot");
|
||||
rot_node.append_attribute("lat").set_value("0");
|
||||
rot_node.append_attribute("lon").set_value("0");
|
||||
rot_node.append_attribute("rev").set_value("0");
|
||||
auto light_rig_node = scene3d_node.append_child("a:lightRig");
|
||||
light_rig_node.append_attribute("rig").set_value("threePt");
|
||||
light_rig_node.append_attribute("dir").set_value("t");
|
||||
rot_node = light_rig_node.append_child("a:rot");
|
||||
rot_node.append_attribute("lat").set_value("0");
|
||||
rot_node.append_attribute("lon").set_value("0");
|
||||
rot_node.append_attribute("rev").set_value("1200000");
|
||||
|
||||
auto bevel_node = effect_style_node.append_child("a:sp3d").append_child("a:bevelT");
|
||||
bevel_node.append_attribute("w").set_value("63500");
|
||||
bevel_node.append_attribute("h").set_value("25400");
|
||||
|
||||
auto bg_fill_style_list_node = format_scheme_node.append_child("a:bgFillStyleLst");
|
||||
|
||||
bg_fill_style_list_node.append_child("a:solidFill").append_child("a:schemeClr").append_attribute("val").set_value("phClr");
|
||||
|
||||
grad_fill_node = bg_fill_style_list_node.append_child("a:gradFill");
|
||||
grad_fill_node.append_attribute("rotWithShape").set_value("1");
|
||||
|
||||
grad_fill_list = grad_fill_node.append_child("a:gsLst");
|
||||
gs_node = grad_fill_list.append_child("a:gs");
|
||||
gs_node.append_attribute("pos").set_value("0");
|
||||
scheme_color_node = gs_node.append_child("a:schemeClr");
|
||||
scheme_color_node.append_attribute("val").set_value("phClr");
|
||||
scheme_color_node.append_child("a:tint").append_attribute("val").set_value("40000");
|
||||
scheme_color_node.append_child("a:satMod").append_attribute("val").set_value("350000");
|
||||
|
||||
gs_node = grad_fill_list.append_child("a:gs");
|
||||
gs_node.append_attribute("pos").set_value("40000");
|
||||
scheme_color_node = gs_node.append_child("a:schemeClr");
|
||||
scheme_color_node.append_attribute("val").set_value("phClr");
|
||||
scheme_color_node.append_child("a:tint").append_attribute("val").set_value("45000");
|
||||
scheme_color_node.append_child("a:shade").append_attribute("val").set_value("99000");
|
||||
scheme_color_node.append_child("a:satMod").append_attribute("val").set_value("350000");
|
||||
|
||||
gs_node = grad_fill_list.append_child("a:gs");
|
||||
gs_node.append_attribute("pos").set_value("100000");
|
||||
scheme_color_node = gs_node.append_child("a:schemeClr");
|
||||
scheme_color_node.append_attribute("val").set_value("phClr");
|
||||
scheme_color_node.append_child("a:shade").append_attribute("val").set_value("20000");
|
||||
scheme_color_node.append_child("a:satMod").append_attribute("val").set_value("255000");
|
||||
|
||||
auto path_node = grad_fill_node.append_child("a:path");
|
||||
path_node.append_attribute("path").set_value("circle");
|
||||
auto fill_to_rect_node = path_node.append_child("a:fillToRect");
|
||||
fill_to_rect_node.append_attribute("l").set_value("50000");
|
||||
fill_to_rect_node.append_attribute("t").set_value("-80000");
|
||||
fill_to_rect_node.append_attribute("r").set_value("50000");
|
||||
fill_to_rect_node.append_attribute("b").set_value("180000");
|
||||
|
||||
grad_fill_node = bg_fill_style_list_node.append_child("a:gradFill");
|
||||
grad_fill_node.append_attribute("rotWithShape").set_value("1");
|
||||
|
||||
grad_fill_list = grad_fill_node.append_child("a:gsLst");
|
||||
gs_node = grad_fill_list.append_child("a:gs");
|
||||
gs_node.append_attribute("pos").set_value("0");
|
||||
scheme_color_node = gs_node.append_child("a:schemeClr");
|
||||
scheme_color_node.append_attribute("val").set_value("phClr");
|
||||
scheme_color_node.append_child("a:tint").append_attribute("val").set_value("80000");
|
||||
scheme_color_node.append_child("a:satMod").append_attribute("val").set_value("300000");
|
||||
|
||||
gs_node = grad_fill_list.append_child("a:gs");
|
||||
gs_node.append_attribute("pos").set_value("100000");
|
||||
scheme_color_node = gs_node.append_child("a:schemeClr");
|
||||
scheme_color_node.append_attribute("val").set_value("phClr");
|
||||
scheme_color_node.append_child("a:shade").append_attribute("val").set_value("30000");
|
||||
scheme_color_node.append_child("a:satMod").append_attribute("val").set_value("200000");
|
||||
|
||||
path_node = grad_fill_node.append_child("a:path");
|
||||
path_node.append_attribute("path").set_value("circle");
|
||||
fill_to_rect_node = path_node.append_child("a:fillToRect");
|
||||
fill_to_rect_node.append_attribute("l").set_value("50000");
|
||||
fill_to_rect_node.append_attribute("t").set_value("50000");
|
||||
fill_to_rect_node.append_attribute("r").set_value("50000");
|
||||
fill_to_rect_node.append_attribute("b").set_value("50000");
|
||||
|
||||
theme_node.append_child("a:objectDefaults");
|
||||
theme_node.append_child("a:extraClrSchemeLst");
|
||||
}
|
||||
|
||||
} // namespace xlnt
|
|
@ -27,10 +27,13 @@
|
|||
|
||||
#include <xlnt/xlnt_config.hpp>
|
||||
|
||||
namespace pugi {
|
||||
class xml_document;
|
||||
} // namespace pugi
|
||||
|
||||
namespace xlnt {
|
||||
|
||||
class theme;
|
||||
class xml_document;
|
||||
|
||||
/// <summary>
|
||||
/// Manages converting a theme to and from XML.
|
||||
|
@ -38,8 +41,8 @@ class xml_document;
|
|||
class XLNT_CLASS theme_serializer
|
||||
{
|
||||
public:
|
||||
bool read_theme(const xml_document &xml, theme &t);
|
||||
xml_document write_theme(const theme &t) const;
|
||||
bool read_theme(const pugi::xml_document &xml, theme &t);
|
||||
void write_theme(const theme &t, pugi::xml_document &xml) const;
|
||||
|
||||
private:
|
||||
};
|
|
@ -27,7 +27,7 @@
|
|||
|
||||
#include <detail/stylesheet.hpp>
|
||||
#include <detail/worksheet_impl.hpp>
|
||||
#include <xlnt/serialization/encoding.hpp>
|
||||
#include <xlnt/workbook/encoding.hpp>
|
||||
#include <xlnt/packaging/app_properties.hpp>
|
||||
#include <xlnt/packaging/document_properties.hpp>
|
||||
#include <xlnt/packaging/manifest.hpp>
|
||||
|
|
331
source/detail/workbook_serializer.cpp
Normal file
331
source/detail/workbook_serializer.cpp
Normal file
|
@ -0,0 +1,331 @@
|
|||
// Copyright (c) 2014-2016 Thomas Fussell
|
||||
// Copyright (c) 2010-2015 openpyxl
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
// of this software and associated documentation files (the "Software"), to deal
|
||||
// in the Software without restriction, including without limitation the rights
|
||||
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
// copies of the Software, and to permit persons to whom the Software is
|
||||
// furnished to do so, subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included in
|
||||
// all copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, WRISING FROM,
|
||||
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
// THE SOFTWARE
|
||||
//
|
||||
// @license: http://www.opensource.org/licenses/mit-license.php
|
||||
// @author: see AUTHORS file
|
||||
|
||||
#include <algorithm>
|
||||
#include <pugixml.hpp>
|
||||
|
||||
#include <detail/constants.hpp>
|
||||
#include <detail/workbook_serializer.hpp>
|
||||
#include <xlnt/packaging/app_properties.hpp>
|
||||
#include <xlnt/packaging/document_properties.hpp>
|
||||
#include <xlnt/packaging/manifest.hpp>
|
||||
#include <xlnt/packaging/relationship.hpp>
|
||||
#include <xlnt/utils/datetime.hpp>
|
||||
#include <xlnt/utils/exceptions.hpp>
|
||||
#include <xlnt/workbook/named_range.hpp>
|
||||
#include <xlnt/workbook/workbook.hpp>
|
||||
#include <xlnt/workbook/worksheet_iterator.hpp>
|
||||
#include <xlnt/worksheet/range_reference.hpp>
|
||||
#include <xlnt/worksheet/worksheet.hpp>
|
||||
|
||||
namespace {
|
||||
|
||||
xlnt::datetime w3cdtf_to_datetime(const std::string &string)
|
||||
{
|
||||
xlnt::datetime result(1900, 1, 1);
|
||||
auto separator_index = string.find('-');
|
||||
result.year = std::stoi(string.substr(0, separator_index));
|
||||
result.month = std::stoi(string.substr(separator_index + 1, string.find('-', separator_index + 1)));
|
||||
separator_index = string.find('-', separator_index + 1);
|
||||
result.day = std::stoi(string.substr(separator_index + 1, string.find('T', separator_index + 1)));
|
||||
separator_index = string.find('T', separator_index + 1);
|
||||
result.hour = std::stoi(string.substr(separator_index + 1, string.find(':', separator_index + 1)));
|
||||
separator_index = string.find(':', separator_index + 1);
|
||||
result.minute = std::stoi(string.substr(separator_index + 1, string.find(':', separator_index + 1)));
|
||||
separator_index = string.find(':', separator_index + 1);
|
||||
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)
|
||||
{
|
||||
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";
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
namespace xlnt {
|
||||
|
||||
workbook_serializer::workbook_serializer(workbook &wb) : workbook_(wb)
|
||||
{
|
||||
}
|
||||
|
||||
void workbook_serializer::read_properties_core(const pugi::xml_document &xml)
|
||||
{
|
||||
auto &props = workbook_.get_properties();
|
||||
auto root_node = xml.child("cp:coreProperties");
|
||||
|
||||
props.excel_base_date = calendar::windows_1900;
|
||||
|
||||
if (root_node.child("dc:creator"))
|
||||
{
|
||||
props.creator = root_node.child("dc:creator").text().get();
|
||||
}
|
||||
|
||||
if (root_node.child("cp:lastModifiedBy"))
|
||||
{
|
||||
props.last_modified_by = root_node.child("cp:lastModifiedBy").text().get();
|
||||
}
|
||||
|
||||
if (root_node.child("dcterms:created"))
|
||||
{
|
||||
std::string created_string = root_node.child("dcterms:created").text().get();
|
||||
props.created = w3cdtf_to_datetime(created_string);
|
||||
}
|
||||
|
||||
if (root_node.child("dcterms:modified"))
|
||||
{
|
||||
std::string modified_string = root_node.child("dcterms:modified").text().get();
|
||||
props.modified = w3cdtf_to_datetime(modified_string);
|
||||
}
|
||||
}
|
||||
|
||||
void workbook_serializer::read_properties_app(const pugi::xml_document &xml)
|
||||
{
|
||||
auto &props = workbook_.get_app_properties();
|
||||
auto root_node = xml.child("Properties");
|
||||
|
||||
if(root_node.child("Application"))
|
||||
{
|
||||
props.application = root_node.child("Application").text().get();
|
||||
}
|
||||
|
||||
if(root_node.child("DocSecurity"))
|
||||
{
|
||||
props.doc_security = std::stoi(root_node.child("DocSecurity").text().get());
|
||||
}
|
||||
|
||||
if(root_node.child("ScaleCrop"))
|
||||
{
|
||||
props.scale_crop = root_node.child("ScaleCrop").text().get() == std::string("true");
|
||||
}
|
||||
|
||||
if(root_node.child("Company"))
|
||||
{
|
||||
props.company = root_node.child("Company").text().get();
|
||||
}
|
||||
|
||||
if(root_node.child("ScaleCrop"))
|
||||
{
|
||||
props.links_up_to_date = root_node.child("ScaleCrop").text().get() == std::string("true");
|
||||
}
|
||||
|
||||
if(root_node.child("SharedDoc"))
|
||||
{
|
||||
props.shared_doc = root_node.child("SharedDoc").text().get() == std::string("true");
|
||||
}
|
||||
|
||||
if(root_node.child("HyperlinksChanged"))
|
||||
{
|
||||
props.hyperlinks_changed = root_node.child("HyperlinksChanged").text().get() == std::string("true");
|
||||
}
|
||||
|
||||
if(root_node.child("AppVersion"))
|
||||
{
|
||||
props.app_version = root_node.child("AppVersion").text().get();
|
||||
}
|
||||
}
|
||||
|
||||
void workbook_serializer::write_properties_core(pugi::xml_document &xml) const
|
||||
{
|
||||
auto &props = workbook_.get_properties();
|
||||
auto root_node = xml.append_child("cp:coreProperties");
|
||||
|
||||
root_node.append_attribute("xmlns:cp").set_value("http://schemas.openxmlformats.org/package/2006/metadata/core-properties");
|
||||
root_node.append_attribute("xmlns:dc").set_value("http://purl.org/dc/elements/1.1/");
|
||||
root_node.append_attribute("xmlns:dcmitype").set_value("http://purl.org/dc/dcmitype/");
|
||||
root_node.append_attribute("xmlns:dcterms").set_value("http://purl.org/dc/terms/");
|
||||
root_node.append_attribute("xmlns:xsi").set_value("http://www.w3.org/2001/XMLSchema-instance");
|
||||
|
||||
root_node.append_child("dc:creator").text().set(props.creator.c_str());
|
||||
root_node.append_child("cp:lastModifiedBy").text().set(props.last_modified_by.c_str());
|
||||
root_node.append_child("dcterms:created").text().set(datetime_to_w3cdtf(props.created).c_str());
|
||||
root_node.child("dcterms:created").append_attribute("xsi:type").set_value("dcterms:W3CDTF");
|
||||
root_node.append_child("dcterms:modified").text().set(datetime_to_w3cdtf(props.modified).c_str());
|
||||
root_node.child("dcterms:modified").append_attribute("xsi:type").set_value("dcterms:W3CDTF");
|
||||
root_node.append_child("dc:title").text().set(props.title.c_str());
|
||||
root_node.append_child("dc:description");
|
||||
root_node.append_child("dc:subject");
|
||||
root_node.append_child("cp:keywords");
|
||||
root_node.append_child("cp:category");
|
||||
}
|
||||
|
||||
void workbook_serializer::write_properties_app(pugi::xml_document &xml) const
|
||||
{
|
||||
auto root_node = xml.append_child("Properties");
|
||||
|
||||
root_node.append_attribute("xmlns").set_value("http://schemas.openxmlformats.org/officeDocument/2006/extended-properties");
|
||||
root_node.append_attribute("xmlns:vt").set_value("http://schemas.openxmlformats.org/officeDocument/2006/docPropsVTypes");
|
||||
|
||||
auto &properties = workbook_.get_app_properties();
|
||||
|
||||
root_node.append_child("Application").text().set(properties.application.c_str());
|
||||
root_node.append_child("DocSecurity").text().set(std::to_string(properties.doc_security).c_str());
|
||||
root_node.append_child("ScaleCrop").text().set(properties.scale_crop ? "true" : "false");
|
||||
|
||||
auto company_node = root_node.append_child("Company");
|
||||
|
||||
if (!properties.company.empty())
|
||||
{
|
||||
company_node.text().set(properties.company.c_str());
|
||||
}
|
||||
|
||||
root_node.append_child("LinksUpToDate").text().set(properties.links_up_to_date ? "true" : "false");
|
||||
root_node.append_child("SharedDoc").text().set(properties.shared_doc ? "true" : "false");
|
||||
root_node.append_child("HyperlinksChanged").text().set(properties.hyperlinks_changed ? "true" : "false");
|
||||
root_node.append_child("AppVersion").text().set(properties.app_version.c_str());
|
||||
|
||||
// TODO what is this stuff?
|
||||
|
||||
auto heading_pairs_node = root_node.append_child("HeadingPairs");
|
||||
auto heading_pairs_vector_node = heading_pairs_node.append_child("vt:vector");
|
||||
heading_pairs_vector_node.append_attribute("size").set_value("2");
|
||||
heading_pairs_vector_node.append_attribute("baseType").set_value("variant");
|
||||
heading_pairs_vector_node.append_child("vt:variant").append_child("vt:lpstr").text().set("Worksheets");
|
||||
heading_pairs_vector_node.append_child("vt:variant")
|
||||
.append_child("vt:i4")
|
||||
.text().set(std::to_string(workbook_.get_sheet_names().size()).c_str());
|
||||
|
||||
auto titles_of_parts_node = root_node.append_child("TitlesOfParts");
|
||||
auto titles_of_parts_vector_node = titles_of_parts_node.append_child("vt:vector");
|
||||
titles_of_parts_vector_node.append_attribute("size").set_value(std::to_string(workbook_.get_sheet_names().size()).c_str());
|
||||
titles_of_parts_vector_node.append_attribute("baseType").set_value("lpstr");
|
||||
|
||||
for (auto ws : workbook_)
|
||||
{
|
||||
titles_of_parts_vector_node.append_child("vt:lpstr").text().set(ws.get_title().c_str());
|
||||
}
|
||||
}
|
||||
|
||||
void workbook_serializer::write_workbook(pugi::xml_document &xml) const
|
||||
{
|
||||
std::size_t num_visible = 0;
|
||||
|
||||
for (auto ws : workbook_)
|
||||
{
|
||||
if (ws.get_page_setup().get_sheet_state() == sheet_state::visible)
|
||||
{
|
||||
num_visible++;
|
||||
}
|
||||
}
|
||||
|
||||
if (num_visible == 0)
|
||||
{
|
||||
throw xlnt::value_error();
|
||||
}
|
||||
|
||||
auto root_node = xml.append_child("workbook");
|
||||
|
||||
root_node.append_attribute("xmlns").set_value("http://schemas.openxmlformats.org/spreadsheetml/2006/main");
|
||||
root_node.append_attribute("xmlns:r").set_value("http://schemas.openxmlformats.org/officeDocument/2006/relationships");
|
||||
|
||||
auto file_version_node = root_node.append_child("fileVersion");
|
||||
file_version_node.append_attribute("appName").set_value("xl");
|
||||
file_version_node.append_attribute("lastEdited").set_value("4");
|
||||
file_version_node.append_attribute("lowestEdited").set_value("4");
|
||||
file_version_node.append_attribute("rupBuild").set_value("4505");
|
||||
|
||||
auto workbook_pr_node = root_node.append_child("workbookPr");
|
||||
workbook_pr_node.append_attribute("codeName").set_value("ThisWorkbook");
|
||||
workbook_pr_node.append_attribute("defaultThemeVersion").set_value("124226");
|
||||
workbook_pr_node.append_attribute("date1904").set_value(workbook_.get_properties().excel_base_date == calendar::mac_1904 ? "1" : "0");
|
||||
|
||||
auto book_views_node = root_node.append_child("bookViews");
|
||||
auto workbook_view_node = book_views_node.append_child("workbookView");
|
||||
workbook_view_node.append_attribute("activeTab").set_value("0");
|
||||
workbook_view_node.append_attribute("autoFilterDateGrouping").set_value("1");
|
||||
workbook_view_node.append_attribute("firstSheet").set_value("0");
|
||||
workbook_view_node.append_attribute("minimized").set_value("0");
|
||||
workbook_view_node.append_attribute("showHorizontalScroll").set_value("1");
|
||||
workbook_view_node.append_attribute("showSheetTabs").set_value("1");
|
||||
workbook_view_node.append_attribute("showVerticalScroll").set_value("1");
|
||||
workbook_view_node.append_attribute("tabRatio").set_value("600");
|
||||
workbook_view_node.append_attribute("visibility").set_value("visible");
|
||||
|
||||
auto sheets_node = root_node.append_child("sheets");
|
||||
auto defined_names_node = root_node.append_child("definedNames");
|
||||
|
||||
for (const auto &relationship : workbook_.get_relationships())
|
||||
{
|
||||
if (relationship.get_type() == relationship::type::worksheet)
|
||||
{
|
||||
// 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--;
|
||||
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.append_child("sheet");
|
||||
sheet_node.append_attribute("name").set_value(ws.get_title().c_str());
|
||||
sheet_node.append_attribute("sheetId").set_value(std::to_string(sheet_index + 1).c_str());
|
||||
sheet_node.append_attribute("r:id").set_value(relationship.get_id().c_str());
|
||||
|
||||
if (ws.has_auto_filter())
|
||||
{
|
||||
auto defined_name_node = defined_names_node.append_child("definedName");
|
||||
defined_name_node.append_attribute("name").set_value("_xlnm._FilterDatabase");
|
||||
defined_name_node.append_attribute("hidden").set_value("1");
|
||||
defined_name_node.append_attribute("localSheetId").set_value("0");
|
||||
std::string name =
|
||||
"'" + ws.get_title() + "'!" + range_reference::make_absolute(ws.get_auto_filter()).to_string();
|
||||
defined_name_node.text().set(name.c_str());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
auto calc_pr_node = root_node.append_child("calcPr");
|
||||
calc_pr_node.append_attribute("calcId").set_value("124519");
|
||||
calc_pr_node.append_attribute("calcMode").set_value("auto");
|
||||
calc_pr_node.append_attribute("fullCalcOnLoad").set_value("1");
|
||||
}
|
||||
|
||||
void workbook_serializer::write_named_ranges(pugi::xml_node node) const
|
||||
{
|
||||
for (auto &named_range : workbook_.get_named_ranges())
|
||||
{
|
||||
node.append_child(named_range.get_name().c_str());
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace xlnt
|
|
@ -28,6 +28,11 @@
|
|||
|
||||
#include <xlnt/xlnt_config.hpp>
|
||||
|
||||
namespace pugi {
|
||||
class xml_document;
|
||||
class xml_node;
|
||||
} // namespace pugi
|
||||
|
||||
namespace xlnt {
|
||||
|
||||
class document_properties;
|
||||
|
@ -36,8 +41,6 @@ class relationship;
|
|||
class worksheet;
|
||||
class workbook;
|
||||
class zip_file;
|
||||
class xml_document;
|
||||
class xml_node;
|
||||
|
||||
/// <summary>
|
||||
/// Manages converting workbook to and from XML.
|
||||
|
@ -49,15 +52,15 @@ public:
|
|||
|
||||
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);
|
||||
void read_workbook(const pugi::xml_document &xml);
|
||||
void read_properties_app(const pugi::xml_document &xml);
|
||||
void read_properties_core(const pugi::xml_document &xml);
|
||||
|
||||
xml_document write_workbook() const;
|
||||
xml_document write_properties_app() const;
|
||||
xml_document write_properties_core() const;
|
||||
void write_workbook(pugi::xml_document &xml) const;
|
||||
void write_properties_app(pugi::xml_document &xml) const;
|
||||
void write_properties_core(pugi::xml_document &xml) const;
|
||||
|
||||
xml_node write_named_ranges() const;
|
||||
void write_named_ranges(pugi::xml_node node) const;
|
||||
|
||||
private:
|
||||
workbook &workbook_;
|
|
@ -21,16 +21,18 @@
|
|||
//
|
||||
// @license: http://www.opensource.org/licenses/mit-license.php
|
||||
// @author: see AUTHORS file
|
||||
|
||||
#include <algorithm>
|
||||
#include <cmath>
|
||||
#include <pugixml.hpp>
|
||||
#include <sstream>
|
||||
|
||||
#include <xlnt/serialization/worksheet_serializer.hpp>
|
||||
#include <detail/constants.hpp>
|
||||
#include <detail/stylesheet.hpp>
|
||||
#include <detail/worksheet_serializer.hpp>
|
||||
#include <xlnt/cell/cell.hpp>
|
||||
#include <xlnt/cell/cell_reference.hpp>
|
||||
#include <xlnt/cell/text.hpp>
|
||||
#include <xlnt/serialization/xml_document.hpp>
|
||||
#include <xlnt/serialization/xml_node.hpp>
|
||||
#include <xlnt/workbook/workbook.hpp>
|
||||
#include <xlnt/worksheet/cell_iterator.hpp>
|
||||
#include <xlnt/worksheet/column_properties.hpp>
|
||||
|
@ -39,9 +41,6 @@
|
|||
#include <xlnt/worksheet/range_reference.hpp>
|
||||
#include <xlnt/worksheet/row_properties.hpp>
|
||||
|
||||
#include <detail/constants.hpp>
|
||||
#include <detail/stylesheet.hpp>
|
||||
|
||||
namespace {
|
||||
|
||||
bool is_integral(long double d)
|
||||
|
@ -57,28 +56,23 @@ worksheet_serializer::worksheet_serializer(worksheet sheet) : sheet_(sheet)
|
|||
{
|
||||
}
|
||||
|
||||
bool worksheet_serializer::read_worksheet(const xml_document &xml, detail::stylesheet &stylesheet)
|
||||
bool worksheet_serializer::read_worksheet(const pugi::xml_document &xml, detail::stylesheet &stylesheet)
|
||||
{
|
||||
auto &root_node = xml.get_child("worksheet");
|
||||
auto root_node = xml.child("worksheet");
|
||||
|
||||
auto &dimension_node = root_node.get_child("dimension");
|
||||
std::string dimension = dimension_node.get_attribute("ref");
|
||||
auto dimension_node = root_node.child("dimension");
|
||||
std::string dimension(dimension_node.attribute("ref").value());
|
||||
auto full_range = xlnt::range_reference(dimension);
|
||||
auto sheet_data_node = root_node.get_child("sheetData");
|
||||
auto sheet_data_node = root_node.child("sheetData");
|
||||
|
||||
if (root_node.has_child("mergeCells"))
|
||||
if (root_node.child("mergeCells"))
|
||||
{
|
||||
auto merge_cells_node = root_node.get_child("mergeCells");
|
||||
auto count = std::stoull(merge_cells_node.get_attribute("count"));
|
||||
auto merge_cells_node = root_node.child("mergeCells");
|
||||
auto count = std::stoull(merge_cells_node.attribute("count").value());
|
||||
|
||||
for (auto merge_cell_node : merge_cells_node.get_children())
|
||||
for (auto merge_cell_node : merge_cells_node.children("mergeCell"))
|
||||
{
|
||||
if (merge_cell_node.get_name() != "mergeCell")
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
sheet_.merge_cells(range_reference(merge_cell_node.get_attribute("ref")));
|
||||
sheet_.merge_cells(range_reference(merge_cell_node.attribute("ref").value()));
|
||||
count--;
|
||||
}
|
||||
|
||||
|
@ -90,21 +84,16 @@ bool worksheet_serializer::read_worksheet(const xml_document &xml, detail::style
|
|||
|
||||
auto &shared_strings = sheet_.get_workbook().get_shared_strings();
|
||||
|
||||
for (auto row_node : sheet_data_node.get_children())
|
||||
for (auto row_node : sheet_data_node.children("row"))
|
||||
{
|
||||
if (row_node.get_name() != "row")
|
||||
auto row_index = static_cast<row_t>(std::stoull(row_node.attribute("r").value()));
|
||||
|
||||
if (row_node.attribute("ht"))
|
||||
{
|
||||
continue;
|
||||
sheet_.get_row_properties(row_index).height = std::stold(row_node.attribute("ht").value());
|
||||
}
|
||||
|
||||
auto row_index = static_cast<row_t>(std::stoull(row_node.get_attribute("r")));
|
||||
|
||||
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");
|
||||
std::string span_string = row_node.attribute("spans").value();
|
||||
auto colon_index = span_string.find(':');
|
||||
|
||||
column_t min_column = 0;
|
||||
|
@ -125,17 +114,12 @@ bool worksheet_serializer::read_worksheet(const xml_document &xml, detail::style
|
|||
{
|
||||
std::string address = i.column_string() + std::to_string(row_index);
|
||||
|
||||
xml_node cell_node;
|
||||
pugi::xml_node cell_node;
|
||||
bool cell_found = false;
|
||||
|
||||
for (auto &check_cell_node : row_node.get_children())
|
||||
for (auto &check_cell_node : row_node.children("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.attribute("r") && check_cell_node.attribute("r").value() == address)
|
||||
{
|
||||
cell_node = check_cell_node;
|
||||
cell_found = true;
|
||||
|
@ -145,30 +129,30 @@ bool worksheet_serializer::read_worksheet(const xml_document &xml, detail::style
|
|||
|
||||
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_value = cell_node.child("v");
|
||||
std::string value_string = has_value ? cell_node.child("v").text().get() : "";
|
||||
|
||||
bool has_type = cell_node.has_attribute("t");
|
||||
std::string type = has_type ? cell_node.get_attribute("t") : "";
|
||||
bool has_type = cell_node.attribute("t");
|
||||
std::string type = has_type ? cell_node.attribute("t").value() : "";
|
||||
|
||||
bool has_format = cell_node.has_attribute("s");
|
||||
auto format_id = static_cast<std::size_t>(has_format ? std::stoull(cell_node.get_attribute("s")) : 0LL);
|
||||
bool has_format = cell_node.attribute("s");
|
||||
auto format_id = static_cast<std::size_t>(has_format ? std::stoull(cell_node.attribute("s").value()) : 0LL);
|
||||
|
||||
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_formula = cell_node.child("f");
|
||||
bool has_shared_formula = has_formula && cell_node.child("f").attribute("t")
|
||||
&& cell_node.child("f").attribute("t").value() == std::string("shared");
|
||||
|
||||
auto cell = sheet_.get_cell(address);
|
||||
|
||||
if (has_formula && !has_shared_formula && !sheet_.get_workbook().get_data_only())
|
||||
{
|
||||
std::string formula = cell_node.get_child("f").get_text();
|
||||
std::string formula = cell_node.child("f").text().get();
|
||||
cell.set_formula(formula);
|
||||
}
|
||||
|
||||
if (has_type && type == "inlineStr") // inline string
|
||||
{
|
||||
std::string inline_string = cell_node.get_child("is").get_child("t").get_text();
|
||||
std::string inline_string = cell_node.child("is").child("t").text().get();
|
||||
cell.set_value(inline_string);
|
||||
}
|
||||
else if (has_type && type == "s" && !has_formula) // shared string
|
||||
|
@ -205,20 +189,15 @@ bool worksheet_serializer::read_worksheet(const xml_document &xml, detail::style
|
|||
}
|
||||
}
|
||||
|
||||
auto &cols_node = root_node.get_child("cols");
|
||||
auto cols_node = root_node.child("cols");
|
||||
|
||||
for (auto col_node : cols_node.get_children())
|
||||
for (auto col_node : cols_node.children("col"))
|
||||
{
|
||||
if (col_node.get_name() != "col")
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
auto min = static_cast<column_t::index_t>(std::stoull(col_node.get_attribute("min")));
|
||||
auto max = static_cast<column_t::index_t>(std::stoull(col_node.get_attribute("max")));
|
||||
auto width = std::stold(col_node.get_attribute("width"));
|
||||
bool custom = col_node.get_attribute("customWidth") == "1";
|
||||
auto column_style = static_cast<std::size_t>(col_node.has_attribute("style") ? std::stoull(col_node.get_attribute("style")) : 0);
|
||||
auto min = static_cast<column_t::index_t>(std::stoull(col_node.attribute("min").value()));
|
||||
auto max = static_cast<column_t::index_t>(std::stoull(col_node.attribute("max").value()));
|
||||
auto width = std::stold(col_node.attribute("width").value());
|
||||
bool custom = col_node.attribute("customWidth").value() == std::string("1");
|
||||
auto column_style = static_cast<std::size_t>(col_node.attribute("style") ? std::stoull(col_node.attribute("style").value()) : 0);
|
||||
|
||||
for (auto column = min; column <= max; column++)
|
||||
{
|
||||
|
@ -233,102 +212,100 @@ bool worksheet_serializer::read_worksheet(const xml_document &xml, detail::style
|
|||
}
|
||||
}
|
||||
|
||||
if (root_node.has_child("autoFilter"))
|
||||
if (root_node.child("autoFilter"))
|
||||
{
|
||||
auto &auto_filter_node = root_node.get_child("autoFilter");
|
||||
xlnt::range_reference ref(auto_filter_node.get_attribute("ref"));
|
||||
auto auto_filter_node = root_node.child("autoFilter");
|
||||
xlnt::range_reference ref(auto_filter_node.attribute("ref").value());
|
||||
sheet_.auto_filter(ref);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
xml_document worksheet_serializer::write_worksheet() const
|
||||
void worksheet_serializer::write_worksheet(pugi::xml_document &xml) const
|
||||
{
|
||||
xml_document xml;
|
||||
auto root_node = xml.append_child("worksheet");
|
||||
|
||||
auto root_node = xml.add_child("worksheet");
|
||||
root_node.append_attribute("xmlns").set_value(constants::Namespace("spreadsheetml").c_str());
|
||||
root_node.append_attribute("xmlns:r").set_value(constants::Namespace("r").c_str());
|
||||
|
||||
xml.add_namespace("", constants::Namespace("spreadsheetml"));
|
||||
xml.add_namespace("r", constants::Namespace("r"));
|
||||
auto sheet_pr_node = root_node.append_child("sheetPr");
|
||||
|
||||
auto sheet_pr_node = root_node.add_child("sheetPr");
|
||||
auto outline_pr_node = sheet_pr_node.append_child("outlinePr");
|
||||
|
||||
auto outline_pr_node = sheet_pr_node.add_child("outlinePr");
|
||||
|
||||
outline_pr_node.add_attribute("summaryBelow", "1");
|
||||
outline_pr_node.add_attribute("summaryRight", "1");
|
||||
outline_pr_node.append_attribute("summaryBelow").set_value("1");
|
||||
outline_pr_node.append_attribute("summaryRight").set_value("1");
|
||||
|
||||
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 page_set_up_pr_node = sheet_pr_node.append_child("pageSetUpPr");
|
||||
page_set_up_pr_node.append_attribute("fitToPage").set_value(sheet_.get_page_setup().fit_to_page() ? "1" : "0");
|
||||
}
|
||||
|
||||
auto dimension_node = root_node.add_child("dimension");
|
||||
dimension_node.add_attribute("ref", sheet_.calculate_dimension().to_string());
|
||||
auto dimension_node = root_node.append_child("dimension");
|
||||
dimension_node.append_attribute("ref").set_value(sheet_.calculate_dimension().to_string().c_str());
|
||||
|
||||
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");
|
||||
auto sheet_views_node = root_node.append_child("sheetViews");
|
||||
auto sheet_view_node = sheet_views_node.append_child("sheetView");
|
||||
sheet_view_node.append_attribute("workbookViewId").set_value("0");
|
||||
|
||||
std::string active_pane = "bottomRight";
|
||||
|
||||
if (sheet_.has_frozen_panes())
|
||||
{
|
||||
auto pane_node = sheet_view_node.add_child("pane");
|
||||
auto pane_node = sheet_view_node.append_child("pane");
|
||||
|
||||
if (sheet_.get_frozen_panes().get_column_index() > 1)
|
||||
{
|
||||
pane_node.add_attribute("xSplit", std::to_string(sheet_.get_frozen_panes().get_column_index().index - 1));
|
||||
pane_node.append_attribute("xSplit").set_value(std::to_string(sheet_.get_frozen_panes().get_column_index().index - 1).c_str());
|
||||
active_pane = "topRight";
|
||||
}
|
||||
|
||||
if (sheet_.get_frozen_panes().get_row() > 1)
|
||||
{
|
||||
pane_node.add_attribute("ySplit", std::to_string(sheet_.get_frozen_panes().get_row() - 1));
|
||||
pane_node.append_attribute("ySplit").set_value(std::to_string(sheet_.get_frozen_panes().get_row() - 1).c_str());
|
||||
active_pane = "bottomLeft";
|
||||
}
|
||||
|
||||
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");
|
||||
auto bottom_left_node = sheet_view_node.add_child("selection");
|
||||
bottom_left_node.add_attribute("pane", "bottomLeft");
|
||||
auto top_right_node = sheet_view_node.append_child("selection");
|
||||
top_right_node.append_attribute("pane").set_value("topRight");
|
||||
auto bottom_left_node = sheet_view_node.append_child("selection");
|
||||
bottom_left_node.append_attribute("pane").set_value("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");
|
||||
pane_node.append_attribute("topLeftCell").set_value(sheet_.get_frozen_panes().to_string().c_str());
|
||||
pane_node.append_attribute("activePane").set_value(active_pane.c_str());
|
||||
pane_node.append_attribute("state").set_value("frozen");
|
||||
}
|
||||
|
||||
auto selection_node = sheet_view_node.add_child("selection");
|
||||
auto selection_node = sheet_view_node.append_child("selection");
|
||||
|
||||
if (sheet_.has_frozen_panes())
|
||||
{
|
||||
if (sheet_.get_frozen_panes().get_row() > 1 && sheet_.get_frozen_panes().get_column_index() > 1)
|
||||
{
|
||||
selection_node.add_attribute("pane", "bottomRight");
|
||||
selection_node.append_attribute("pane").set_value("bottomRight");
|
||||
}
|
||||
else if (sheet_.get_frozen_panes().get_row() > 1)
|
||||
{
|
||||
selection_node.add_attribute("pane", "bottomLeft");
|
||||
selection_node.append_attribute("pane").set_value("bottomLeft");
|
||||
}
|
||||
else if (sheet_.get_frozen_panes().get_column_index() > 1)
|
||||
{
|
||||
selection_node.add_attribute("pane", "topRight");
|
||||
selection_node.append_attribute("pane").set_value("topRight");
|
||||
}
|
||||
}
|
||||
|
||||
std::string active_cell = "A1";
|
||||
selection_node.add_attribute("activeCell", active_cell);
|
||||
selection_node.add_attribute("sqref", active_cell);
|
||||
selection_node.append_attribute("activeCell").set_value(active_cell.c_str());
|
||||
selection_node.append_attribute("sqref").set_value(active_cell.c_str());
|
||||
|
||||
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");
|
||||
auto sheet_format_pr_node = root_node.append_child("sheetFormatPr");
|
||||
sheet_format_pr_node.append_attribute("baseColWidth").set_value("10");
|
||||
sheet_format_pr_node.append_attribute("defaultRowHeight").set_value("15");
|
||||
|
||||
bool has_column_properties = false;
|
||||
|
||||
|
@ -343,7 +320,7 @@ xml_document worksheet_serializer::write_worksheet() const
|
|||
|
||||
if (has_column_properties)
|
||||
{
|
||||
auto cols_node = root_node.add_child("cols");
|
||||
auto cols_node = root_node.append_child("cols");
|
||||
|
||||
for (auto column = sheet_.get_lowest_column(); column <= sheet_.get_highest_column(); column++)
|
||||
{
|
||||
|
@ -354,19 +331,19 @@ xml_document worksheet_serializer::write_worksheet() const
|
|||
|
||||
const auto &props = sheet_.get_column_properties(column);
|
||||
|
||||
auto col_node = cols_node.add_child("col");
|
||||
auto col_node = cols_node.append_child("col");
|
||||
|
||||
col_node.add_attribute("min", std::to_string(column.index));
|
||||
col_node.add_attribute("max", std::to_string(column.index));
|
||||
col_node.add_attribute("width", std::to_string(props.width));
|
||||
col_node.add_attribute("style", std::to_string(props.style));
|
||||
col_node.add_attribute("customWidth", props.custom ? "1" : "0");
|
||||
col_node.append_attribute("min").set_value(std::to_string(column.index).c_str());
|
||||
col_node.append_attribute("max").set_value(std::to_string(column.index).c_str());
|
||||
col_node.append_attribute("width").set_value(std::to_string(props.width).c_str());
|
||||
col_node.append_attribute("style").set_value(std::to_string(props.style).c_str());
|
||||
col_node.append_attribute("customWidth").set_value(props.custom ? "1" : "0");
|
||||
}
|
||||
}
|
||||
|
||||
std::unordered_map<std::string, std::string> hyperlink_references;
|
||||
|
||||
auto sheet_data_node = root_node.add_child("sheetData");
|
||||
auto sheet_data_node = root_node.append_child("sheetData");
|
||||
const auto &shared_strings = sheet_.get_workbook().get_shared_strings();
|
||||
|
||||
for (auto row : sheet_.rows())
|
||||
|
@ -391,27 +368,27 @@ xml_document worksheet_serializer::write_worksheet() const
|
|||
continue;
|
||||
}
|
||||
|
||||
auto row_node = sheet_data_node.add_child("row");
|
||||
auto row_node = sheet_data_node.append_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)));
|
||||
row_node.append_attribute("r").set_value(std::to_string(row.front().get_row()).c_str());
|
||||
row_node.append_attribute("spans").set_value((std::to_string(min) + ":" + std::to_string(max)).c_str());
|
||||
|
||||
if (sheet_.has_row_properties(row.front().get_row()))
|
||||
{
|
||||
row_node.add_attribute("customHeight", "1");
|
||||
row_node.append_attribute("customHeight").set_value("1");
|
||||
auto height = sheet_.get_row_properties(row.front().get_row()).height;
|
||||
|
||||
if (height == std::floor(height))
|
||||
{
|
||||
row_node.add_attribute("ht", std::to_string(static_cast<long long int>(height)) + ".0");
|
||||
row_node.append_attribute("ht").set_value((std::to_string(static_cast<long long int>(height)) + ".0").c_str());
|
||||
}
|
||||
else
|
||||
{
|
||||
row_node.add_attribute("ht", std::to_string(height));
|
||||
row_node.append_attribute("ht").set_value(std::to_string(height).c_str());
|
||||
}
|
||||
}
|
||||
|
||||
// row_node.add_attribute("x14ac:dyDescent", 0.25);
|
||||
// row_node.append_attribute("x14ac:dyDescent", 0.25);
|
||||
|
||||
for (auto cell : row)
|
||||
{
|
||||
|
@ -422,16 +399,16 @@ xml_document worksheet_serializer::write_worksheet() const
|
|||
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());
|
||||
auto cell_node = row_node.append_child("c");
|
||||
cell_node.append_attribute("r").set_value(cell.get_reference().to_string().c_str());
|
||||
|
||||
if (cell.get_data_type() == cell::type::string)
|
||||
{
|
||||
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());
|
||||
cell_node.append_attribute("t").set_value("str");
|
||||
cell_node.append_child("f").text().set(cell.get_formula().c_str());
|
||||
cell_node.append_child("v").text().set(cell.to_string().c_str());
|
||||
|
||||
continue;
|
||||
}
|
||||
|
@ -451,20 +428,20 @@ xml_document worksheet_serializer::write_worksheet() const
|
|||
{
|
||||
if (cell.get_value<std::string>().empty())
|
||||
{
|
||||
cell_node.add_attribute("t", "s");
|
||||
cell_node.append_attribute("t").set_value("s");
|
||||
}
|
||||
else
|
||||
{
|
||||
cell_node.add_attribute("t", "inlineStr");
|
||||
auto inline_string_node = cell_node.add_child("is");
|
||||
inline_string_node.add_child("t").set_text(cell.get_value<std::string>());
|
||||
cell_node.append_attribute("t").set_value("inlineStr");
|
||||
auto inline_string_node = cell_node.append_child("is");
|
||||
inline_string_node.append_child("t").text().set(cell.get_value<std::string>().c_str());
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
cell_node.add_attribute("t", "s");
|
||||
auto value_node = cell_node.add_child("v");
|
||||
value_node.set_text(std::to_string(match_index));
|
||||
cell_node.append_attribute("t").set_value("s");
|
||||
auto value_node = cell_node.append_child("v");
|
||||
value_node.text().set(std::to_string(match_index).c_str());
|
||||
}
|
||||
}
|
||||
else
|
||||
|
@ -473,25 +450,25 @@ xml_document worksheet_serializer::write_worksheet() const
|
|||
{
|
||||
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");
|
||||
cell_node.append_attribute("t").set_value("b");
|
||||
auto value_node = cell_node.append_child("v");
|
||||
value_node.text().set(cell.get_value<bool>() ? "1" : "0");
|
||||
}
|
||||
else if (cell.get_data_type() == cell::type::numeric)
|
||||
{
|
||||
if (cell.has_formula())
|
||||
{
|
||||
cell_node.add_child("f").set_text(cell.get_formula());
|
||||
cell_node.add_child("v").set_text(cell.to_string());
|
||||
cell_node.append_child("f").text().set(cell.get_formula().c_str());
|
||||
cell_node.append_child("v").text().set(cell.to_string().c_str());
|
||||
continue;
|
||||
}
|
||||
|
||||
cell_node.add_attribute("t", "n");
|
||||
auto value_node = cell_node.add_child("v");
|
||||
cell_node.append_attribute("t").set_value("n");
|
||||
auto value_node = cell_node.append_child("v");
|
||||
|
||||
if (is_integral(cell.get_value<long double>()))
|
||||
{
|
||||
value_node.set_text(std::to_string(cell.get_value<long long>()));
|
||||
value_node.text().set(std::to_string(cell.get_value<long long>()).c_str());
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -499,21 +476,21 @@ xml_document worksheet_serializer::write_worksheet() const
|
|||
ss.precision(20);
|
||||
ss << cell.get_value<long double>();
|
||||
ss.str();
|
||||
value_node.set_text(ss.str());
|
||||
value_node.text().set(ss.str().c_str());
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (cell.has_formula())
|
||||
{
|
||||
cell_node.add_child("f").set_text(cell.get_formula());
|
||||
cell_node.add_child("v");
|
||||
cell_node.append_child("f").text().set(cell.get_formula().c_str());
|
||||
cell_node.append_child("v");
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
if (cell.has_format())
|
||||
{
|
||||
cell_node.add_attribute("s", std::to_string(cell.get_format_id()));
|
||||
cell_node.append_attribute("s").set_value(std::to_string(cell.get_format_id()).c_str());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -521,45 +498,45 @@ xml_document worksheet_serializer::write_worksheet() const
|
|||
|
||||
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());
|
||||
auto auto_filter_node = root_node.append_child("autoFilter");
|
||||
auto_filter_node.append_attribute("ref").set_value(sheet_.get_auto_filter().to_string().c_str());
|
||||
}
|
||||
|
||||
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()));
|
||||
auto merge_cells_node = root_node.append_child("mergeCells");
|
||||
merge_cells_node.append_attribute("count").set_value(std::to_string(sheet_.get_merged_ranges().size()).c_str());
|
||||
|
||||
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());
|
||||
auto merge_cell_node = merge_cells_node.append_child("mergeCell");
|
||||
merge_cell_node.append_attribute("ref").set_value(merged_range.to_string().c_str());
|
||||
}
|
||||
}
|
||||
|
||||
if (!sheet_.get_relationships().empty())
|
||||
{
|
||||
auto hyperlinks_node = root_node.add_child("hyperlinks");
|
||||
auto hyperlinks_node = root_node.append_child("hyperlinks");
|
||||
|
||||
for (const auto &relationship : sheet_.get_relationships())
|
||||
{
|
||||
auto hyperlink_node = hyperlinks_node.add_child("hyperlink");
|
||||
hyperlink_node.add_attribute("display", relationship.get_target_uri());
|
||||
hyperlink_node.add_attribute("ref", hyperlink_references.at(relationship.get_id()));
|
||||
hyperlink_node.add_attribute("r:id", relationship.get_id());
|
||||
auto hyperlink_node = hyperlinks_node.append_child("hyperlink");
|
||||
hyperlink_node.append_attribute("display").set_value(relationship.get_target_uri().c_str());
|
||||
hyperlink_node.append_attribute("ref").set_value(hyperlink_references.at(relationship.get_id()).c_str());
|
||||
hyperlink_node.append_attribute("r:id").set_value(relationship.get_id().c_str());
|
||||
}
|
||||
}
|
||||
|
||||
if (!sheet_.get_page_setup().is_default())
|
||||
{
|
||||
auto print_options_node = root_node.add_child("printOptions");
|
||||
print_options_node.add_attribute("horizontalCentered",
|
||||
auto print_options_node = root_node.append_child("printOptions");
|
||||
print_options_node.append_attribute("horizontalCentered").set_value(
|
||||
sheet_.get_page_setup().get_horizontal_centered() ? "1" : "0");
|
||||
print_options_node.add_attribute("verticalCentered",
|
||||
print_options_node.append_attribute("verticalCentered").set_value(
|
||||
sheet_.get_page_setup().get_vertical_centered() ? "1" : "0");
|
||||
}
|
||||
|
||||
auto page_margins_node = root_node.add_child("pageMargins");
|
||||
auto page_margins_node = root_node.append_child("pageMargins");
|
||||
|
||||
//TODO: there must be a better way to do this
|
||||
auto remove_trailing_zeros = [](const std::string &n)
|
||||
|
@ -583,43 +560,41 @@ xml_document worksheet_serializer::write_worksheet() const
|
|||
return n.substr(0, index + 1);
|
||||
};
|
||||
|
||||
page_margins_node.add_attribute("left", remove_trailing_zeros(std::to_string(sheet_.get_page_margins().get_left())));
|
||||
page_margins_node.add_attribute("right", remove_trailing_zeros(std::to_string(sheet_.get_page_margins().get_right())));
|
||||
page_margins_node.add_attribute("top", remove_trailing_zeros(std::to_string(sheet_.get_page_margins().get_top())));
|
||||
page_margins_node.add_attribute("bottom", remove_trailing_zeros(std::to_string(sheet_.get_page_margins().get_bottom())));
|
||||
page_margins_node.add_attribute("header", remove_trailing_zeros(std::to_string(sheet_.get_page_margins().get_header())));
|
||||
page_margins_node.add_attribute("footer", remove_trailing_zeros(std::to_string(sheet_.get_page_margins().get_footer())));
|
||||
page_margins_node.append_attribute("left").set_value(remove_trailing_zeros(std::to_string(sheet_.get_page_margins().get_left())).c_str());
|
||||
page_margins_node.append_attribute("right").set_value(remove_trailing_zeros(std::to_string(sheet_.get_page_margins().get_right())).c_str());
|
||||
page_margins_node.append_attribute("top").set_value(remove_trailing_zeros(std::to_string(sheet_.get_page_margins().get_top())).c_str());
|
||||
page_margins_node.append_attribute("bottom").set_value(remove_trailing_zeros(std::to_string(sheet_.get_page_margins().get_bottom())).c_str());
|
||||
page_margins_node.append_attribute("header").set_value(remove_trailing_zeros(std::to_string(sheet_.get_page_margins().get_header())).c_str());
|
||||
page_margins_node.append_attribute("footer").set_value(remove_trailing_zeros(std::to_string(sheet_.get_page_margins().get_footer())).c_str());
|
||||
|
||||
if (!sheet_.get_page_setup().is_default())
|
||||
{
|
||||
auto page_setup_node = root_node.add_child("pageSetup");
|
||||
auto page_setup_node = root_node.append_child("pageSetup");
|
||||
|
||||
std::string orientation_string =
|
||||
sheet_.get_page_setup().get_orientation() == 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("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");
|
||||
page_setup_node.append_attribute("orientation").set_value(orientation_string.c_str());
|
||||
page_setup_node.append_attribute("paperSize").set_value(
|
||||
std::to_string(static_cast<int>(sheet_.get_page_setup().get_paper_size())).c_str());
|
||||
page_setup_node.append_attribute("fitToHeight").set_value(sheet_.get_page_setup().fit_to_height() ? "1" : "0");
|
||||
page_setup_node.append_attribute("fitToWidth").set_value(sheet_.get_page_setup().fit_to_width() ? "1" : "0");
|
||||
}
|
||||
|
||||
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");
|
||||
auto header_footer_node = root_node.append_child("headerFooter");
|
||||
auto odd_header_node = header_footer_node.append_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";
|
||||
odd_header_node.set_text(header_text);
|
||||
auto odd_footer_node = header_footer_node.add_child("oddFooter");
|
||||
odd_header_node.text().set(header_text.c_str());
|
||||
auto odd_footer_node = header_footer_node.append_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";
|
||||
odd_footer_node.set_text(footer_text);
|
||||
odd_footer_node.text().set(footer_text.c_str());
|
||||
}
|
||||
|
||||
return xml;
|
||||
}
|
||||
|
||||
} // namespace xlnt
|
|
@ -29,12 +29,15 @@
|
|||
#include <xlnt/xlnt_config.hpp>
|
||||
#include <xlnt/worksheet/worksheet.hpp>
|
||||
|
||||
namespace pugi {
|
||||
class xml_document;
|
||||
} // namespace pugi
|
||||
|
||||
namespace xlnt {
|
||||
|
||||
class relationship;
|
||||
class workbook;
|
||||
class worksheet;
|
||||
class xml_document;
|
||||
|
||||
namespace detail { struct stylesheet; }
|
||||
|
||||
|
@ -46,8 +49,8 @@ class XLNT_CLASS worksheet_serializer
|
|||
public:
|
||||
worksheet_serializer(worksheet sheet);
|
||||
|
||||
bool read_worksheet(const xml_document &xml, detail::stylesheet &stylesheet);
|
||||
xml_document write_worksheet() const;
|
||||
bool read_worksheet(const pugi::xml_document &xml, detail::stylesheet &stylesheet);
|
||||
void write_worksheet(pugi::xml_document &xml) const;
|
||||
|
||||
private:
|
||||
worksheet sheet_;
|
|
@ -1,39 +0,0 @@
|
|||
// Copyright (c) 2014-2016 Thomas Fussell
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
// of this software and associated documentation files (the "Software"), to deal
|
||||
// in the Software without restriction, including without limitation the rights
|
||||
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
// copies of the Software, and to permit persons to whom the Software is
|
||||
// furnished to do so, subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included in
|
||||
// all copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, WRISING FROM,
|
||||
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
// THE SOFTWARE
|
||||
//
|
||||
// @license: http://www.opensource.org/licenses/mit-license.php
|
||||
// @author: see AUTHORS file
|
||||
#pragma once
|
||||
|
||||
#include <string>
|
||||
|
||||
#include <detail/include_pugixml.hpp>
|
||||
|
||||
namespace xlnt {
|
||||
namespace detail {
|
||||
|
||||
struct xml_document_impl
|
||||
{
|
||||
std::string encoding;
|
||||
pugi::xml_document doc;
|
||||
};
|
||||
|
||||
} // namespace detail
|
||||
} // namespace xlnt
|
|
@ -1,44 +0,0 @@
|
|||
// Copyright (c) 2014-2016 Thomas Fussell
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
// of this software and associated documentation files (the "Software"), to deal
|
||||
// in the Software without restriction, including without limitation the rights
|
||||
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
// copies of the Software, and to permit persons to whom the Software is
|
||||
// furnished to do so, subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included in
|
||||
// all copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, WRISING FROM,
|
||||
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
// THE SOFTWARE
|
||||
//
|
||||
// @license: http://www.opensource.org/licenses/mit-license.php
|
||||
// @author: see AUTHORS file
|
||||
#pragma once
|
||||
|
||||
#include <detail/include_pugixml.hpp>
|
||||
|
||||
namespace xlnt {
|
||||
namespace detail {
|
||||
|
||||
struct xml_node_impl
|
||||
{
|
||||
xml_node_impl()
|
||||
{
|
||||
}
|
||||
|
||||
explicit xml_node_impl(pugi::xml_node n) : node(n)
|
||||
{
|
||||
}
|
||||
|
||||
pugi::xml_node node;
|
||||
};
|
||||
|
||||
} // namespace detail
|
||||
} // namespace xlnt
|
|
@ -4,8 +4,7 @@
|
|||
#include <cxxtest/TestSuite.h>
|
||||
|
||||
#include <xlnt/packaging/app_properties.hpp>
|
||||
#include <xlnt/serialization/workbook_serializer.hpp>
|
||||
#include <xlnt/serialization/xml_document.hpp>
|
||||
#include <detail/workbook_serializer.hpp>
|
||||
|
||||
#include <helpers/path_helper.hpp>
|
||||
#include <helpers/helper.hpp>
|
||||
|
@ -48,7 +47,7 @@ public:
|
|||
auto content = archive.read("docProps/core.xml");
|
||||
xlnt::workbook wb;
|
||||
xlnt::workbook_serializer serializer(wb);
|
||||
xlnt::xml_document xml;
|
||||
pugi::xml_document xml;
|
||||
serializer.read_properties_core(xml);
|
||||
auto &prop = wb.get_properties();
|
||||
TS_ASSERT_EQUALS(prop.excel_base_date, xlnt::calendar::windows_1900);
|
||||
|
@ -80,7 +79,8 @@ public:
|
|||
prop.created = xlnt::datetime(2010, 4, 1, 20, 30, 00);
|
||||
prop.modified = xlnt::datetime(2010, 4, 5, 14, 5, 30);
|
||||
xlnt::workbook_serializer serializer(wb);
|
||||
xlnt::xml_document xml = serializer.write_properties_core();
|
||||
pugi::xml_document xml;
|
||||
serializer.write_properties_core(xml);
|
||||
TS_ASSERT(Helper::compare_xml(PathHelper::GetDataDirectory() + "/writer/expected/core.xml", xml));
|
||||
}
|
||||
|
||||
|
@ -92,7 +92,8 @@ public:
|
|||
wb.create_sheet();
|
||||
wb.create_sheet();
|
||||
xlnt::workbook_serializer serializer(wb);
|
||||
xlnt::xml_document xml = serializer.write_properties_app();
|
||||
pugi::xml_document xml;
|
||||
serializer.write_properties_app(xml);
|
||||
TS_ASSERT(Helper::compare_xml(PathHelper::GetDataDirectory() + "/writer/expected/app.xml", xml));
|
||||
}
|
||||
};
|
||||
|
|
|
@ -1,373 +0,0 @@
|
|||
// Copyright (c) 2014-2016 Thomas Fussell
|
||||
// Copyright (c) 2010-2015 openpyxl
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
// of this software and associated documentation files (the "Software"), to deal
|
||||
// in the Software without restriction, including without limitation the rights
|
||||
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
// copies of the Software, and to permit persons to whom the Software is
|
||||
// furnished to do so, subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included in
|
||||
// all copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, WRISING FROM,
|
||||
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
// THE SOFTWARE
|
||||
//
|
||||
// @license: http://www.opensource.org/licenses/mit-license.php
|
||||
// @author: see AUTHORS file
|
||||
#include <xlnt/serialization/theme_serializer.hpp>
|
||||
#include <xlnt/serialization/xml_document.hpp>
|
||||
#include <xlnt/serialization/xml_node.hpp>
|
||||
|
||||
#include <detail/constants.hpp>
|
||||
|
||||
namespace xlnt {
|
||||
|
||||
// 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::Namespace("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" },
|
||||
};
|
||||
|
||||
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")
|
||||
{
|
||||
element_node.get_child(element.sub_element_name).add_attribute("lastClr", "000000");
|
||||
}
|
||||
else if (element.name == "a:lt1")
|
||||
{
|
||||
element_node.get_child(element.sub_element_name).add_attribute("lastClr", "FFFFFF");
|
||||
}
|
||||
}
|
||||
|
||||
struct font_scheme
|
||||
{
|
||||
bool typeface;
|
||||
std::string script;
|
||||
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" }
|
||||
};
|
||||
|
||||
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)
|
||||
{
|
||||
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);
|
||||
}
|
||||
else
|
||||
{
|
||||
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");
|
||||
auto 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", "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");
|
||||
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", "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");
|
||||
auto outer_shadow_node = effect_list_node.add_child("a:outerShdw");
|
||||
outer_shadow_node.add_attribute("blurRad", "40000");
|
||||
outer_shadow_node.add_attribute("dist", "20000");
|
||||
outer_shadow_node.add_attribute("dir", "5400000");
|
||||
outer_shadow_node.add_attribute("rotWithShape", "0");
|
||||
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");
|
||||
outer_shadow_node.add_attribute("blurRad", "40000");
|
||||
outer_shadow_node.add_attribute("dist", "23000");
|
||||
outer_shadow_node.add_attribute("dir", "5400000");
|
||||
outer_shadow_node.add_attribute("rotWithShape", "0");
|
||||
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");
|
||||
outer_shadow_node.add_attribute("blurRad", "40000");
|
||||
outer_shadow_node.add_attribute("dist", "23000");
|
||||
outer_shadow_node.add_attribute("dir", "5400000");
|
||||
outer_shadow_node.add_attribute("rotWithShape", "0");
|
||||
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");
|
||||
auto scene3d_node = effect_style_node.add_child("a:scene3d");
|
||||
auto camera_node = scene3d_node.add_child("a:camera");
|
||||
camera_node.add_attribute("prst", "orthographicFront");
|
||||
auto rot_node = camera_node.add_child("a:rot");
|
||||
rot_node.add_attribute("lat", "0");
|
||||
rot_node.add_attribute("lon", "0");
|
||||
rot_node.add_attribute("rev", "0");
|
||||
auto light_rig_node = scene3d_node.add_child("a:lightRig");
|
||||
light_rig_node.add_attribute("rig", "threePt");
|
||||
light_rig_node.add_attribute("dir", "t");
|
||||
rot_node = light_rig_node.add_child("a:rot");
|
||||
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");
|
||||
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", "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");
|
||||
scheme_color_node.add_attribute("val", "phClr");
|
||||
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");
|
||||
fill_to_rect_node.add_attribute("l", "50000");
|
||||
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");
|
||||
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", "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");
|
||||
fill_to_rect_node.add_attribute("l", "50000");
|
||||
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
|
|
@ -1,350 +0,0 @@
|
|||
// Copyright (c) 2014-2016 Thomas Fussell
|
||||
// Copyright (c) 2010-2015 openpyxl
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
// of this software and associated documentation files (the "Software"), to deal
|
||||
// in the Software without restriction, including without limitation the rights
|
||||
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
// copies of the Software, and to permit persons to whom the Software is
|
||||
// furnished to do so, subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included in
|
||||
// all copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, WRISING FROM,
|
||||
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
// THE SOFTWARE
|
||||
//
|
||||
// @license: http://www.opensource.org/licenses/mit-license.php
|
||||
// @author: see AUTHORS file
|
||||
#include <algorithm>
|
||||
|
||||
#include <xlnt/packaging/app_properties.hpp>
|
||||
#include <xlnt/packaging/document_properties.hpp>
|
||||
#include <xlnt/packaging/manifest.hpp>
|
||||
#include <xlnt/packaging/relationship.hpp>
|
||||
#include <xlnt/serialization/workbook_serializer.hpp>
|
||||
#include <xlnt/serialization/xml_document.hpp>
|
||||
#include <xlnt/serialization/xml_node.hpp>
|
||||
#include <xlnt/utils/datetime.hpp>
|
||||
#include <xlnt/utils/exceptions.hpp>
|
||||
#include <xlnt/workbook/named_range.hpp>
|
||||
#include <xlnt/workbook/workbook.hpp>
|
||||
#include <xlnt/workbook/worksheet_iterator.hpp>
|
||||
#include <xlnt/worksheet/range_reference.hpp>
|
||||
#include <xlnt/worksheet/worksheet.hpp>
|
||||
|
||||
#include <detail/constants.hpp>
|
||||
|
||||
namespace {
|
||||
|
||||
xlnt::datetime w3cdtf_to_datetime(const std::string &string)
|
||||
{
|
||||
xlnt::datetime result(1900, 1, 1);
|
||||
auto separator_index = string.find('-');
|
||||
result.year = std::stoi(string.substr(0, separator_index));
|
||||
result.month = std::stoi(string.substr(separator_index + 1, string.find('-', separator_index + 1)));
|
||||
separator_index = string.find('-', separator_index + 1);
|
||||
result.day = std::stoi(string.substr(separator_index + 1, string.find('T', separator_index + 1)));
|
||||
separator_index = string.find('T', separator_index + 1);
|
||||
result.hour = std::stoi(string.substr(separator_index + 1, string.find(':', separator_index + 1)));
|
||||
separator_index = string.find(':', separator_index + 1);
|
||||
result.minute = std::stoi(string.substr(separator_index + 1, string.find(':', separator_index + 1)));
|
||||
separator_index = string.find(':', separator_index + 1);
|
||||
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)
|
||||
{
|
||||
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";
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
namespace xlnt {
|
||||
|
||||
workbook_serializer::workbook_serializer(workbook &wb) : workbook_(wb)
|
||||
{
|
||||
}
|
||||
|
||||
void workbook_serializer::read_properties_core(const xml_document &xml)
|
||||
{
|
||||
auto &props = workbook_.get_properties();
|
||||
auto root_node = xml.get_child("cp:coreProperties");
|
||||
|
||||
props.excel_base_date = calendar::windows_1900;
|
||||
|
||||
if (root_node.has_child("dc:creator"))
|
||||
{
|
||||
props.creator = root_node.get_child("dc:creator").get_text();
|
||||
}
|
||||
|
||||
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"))
|
||||
{
|
||||
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"))
|
||||
{
|
||||
std::string modified_string = root_node.get_child("dcterms:modified").get_text();
|
||||
props.modified = w3cdtf_to_datetime(modified_string);
|
||||
}
|
||||
}
|
||||
|
||||
void workbook_serializer::read_properties_app(const xml_document &xml)
|
||||
{
|
||||
auto &props = workbook_.get_app_properties();
|
||||
auto root_node = xml.get_child("Properties");
|
||||
|
||||
if(root_node.has_child("Application"))
|
||||
{
|
||||
props.application = root_node.get_child("Application").get_text();
|
||||
}
|
||||
|
||||
if(root_node.has_child("DocSecurity"))
|
||||
{
|
||||
props.doc_security = std::stoi(root_node.get_child("DocSecurity").get_text());
|
||||
}
|
||||
|
||||
if(root_node.has_child("ScaleCrop"))
|
||||
{
|
||||
props.scale_crop = root_node.get_child("ScaleCrop").get_text() == "true";
|
||||
}
|
||||
|
||||
if(root_node.has_child("Company"))
|
||||
{
|
||||
props.company = root_node.get_child("Company").get_text();
|
||||
}
|
||||
|
||||
if(root_node.has_child("ScaleCrop"))
|
||||
{
|
||||
props.links_up_to_date = root_node.get_child("ScaleCrop").get_text() == "true";
|
||||
}
|
||||
|
||||
if(root_node.has_child("SharedDoc"))
|
||||
{
|
||||
props.shared_doc = root_node.get_child("SharedDoc").get_text() == "true";
|
||||
}
|
||||
|
||||
if(root_node.has_child("HyperlinksChanged"))
|
||||
{
|
||||
props.hyperlinks_changed = root_node.get_child("HyperlinksChanged").get_text() == "true";
|
||||
}
|
||||
|
||||
if(root_node.has_child("AppVersion"))
|
||||
{
|
||||
props.app_version = root_node.get_child("AppVersion").get_text();
|
||||
}
|
||||
}
|
||||
|
||||
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));
|
||||
root_node.get_child("dcterms:created").add_attribute("xsi:type", "dcterms:W3CDTF");
|
||||
root_node.add_child("dcterms:modified").set_text(datetime_to_w3cdtf(props.modified));
|
||||
root_node.get_child("dcterms:modified").add_attribute("xsi:type", "dcterms:W3CDTF");
|
||||
root_node.add_child("dc:title").set_text(props.title);
|
||||
root_node.add_child("dc:description");
|
||||
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");
|
||||
|
||||
auto &properties = workbook_.get_app_properties();
|
||||
|
||||
root_node.add_child("Application").set_text(properties.application);
|
||||
root_node.add_child("DocSecurity").set_text(std::to_string(properties.doc_security));
|
||||
root_node.add_child("ScaleCrop").set_text(properties.scale_crop ? "true" : "false");
|
||||
|
||||
auto company_node = root_node.add_child("Company");
|
||||
|
||||
if (!properties.company.empty())
|
||||
{
|
||||
company_node.set_text(properties.company);
|
||||
}
|
||||
|
||||
root_node.add_child("LinksUpToDate").set_text(properties.links_up_to_date ? "true" : "false");
|
||||
root_node.add_child("SharedDoc").set_text(properties.shared_doc ? "true" : "false");
|
||||
root_node.add_child("HyperlinksChanged").set_text(properties.hyperlinks_changed ? "true" : "false");
|
||||
root_node.add_child("AppVersion").set_text(properties.app_version);
|
||||
|
||||
// TODO what is this stuff?
|
||||
|
||||
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("size", "2");
|
||||
heading_pairs_vector_node.add_attribute("baseType", "variant");
|
||||
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()));
|
||||
|
||||
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("size", std::to_string(workbook_.get_sheet_names().size()));
|
||||
titles_of_parts_vector_node.add_attribute("baseType", "lpstr");
|
||||
|
||||
for (auto ws : workbook_)
|
||||
{
|
||||
titles_of_parts_vector_node.add_child("vt:lpstr").set_text(ws.get_title());
|
||||
}
|
||||
|
||||
return xml;
|
||||
}
|
||||
|
||||
xml_document workbook_serializer::write_workbook() const
|
||||
{
|
||||
std::size_t num_visible = 0;
|
||||
|
||||
for (auto ws : workbook_)
|
||||
{
|
||||
if (ws.get_page_setup().get_sheet_state() == sheet_state::visible)
|
||||
{
|
||||
num_visible++;
|
||||
}
|
||||
}
|
||||
|
||||
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");
|
||||
|
||||
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");
|
||||
workbook_view_node.add_attribute("autoFilterDateGrouping", "1");
|
||||
workbook_view_node.add_attribute("firstSheet", "0");
|
||||
workbook_view_node.add_attribute("minimized", "0");
|
||||
workbook_view_node.add_attribute("showHorizontalScroll", "1");
|
||||
workbook_view_node.add_attribute("showSheetTabs", "1");
|
||||
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())
|
||||
{
|
||||
if (relationship.get_type() == relationship::type::worksheet)
|
||||
{
|
||||
// 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--;
|
||||
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())
|
||||
{
|
||||
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();
|
||||
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())
|
||||
{
|
||||
named_ranges_node.add_child(named_range.get_name());
|
||||
}
|
||||
|
||||
return named_ranges_node;
|
||||
}
|
||||
|
||||
} // namespace xlnt
|
|
@ -1,105 +0,0 @@
|
|||
// Copyright (c) 2014-2016 Thomas Fussell
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
// of this software and associated documentation files (the "Software"), to deal
|
||||
// in the Software without restriction, including without limitation the rights
|
||||
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
// copies of the Software, and to permit persons to whom the Software is
|
||||
// furnished to do so, subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included in
|
||||
// all copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, WRISING FROM,
|
||||
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
// THE SOFTWARE
|
||||
//
|
||||
// @license: http://www.opensource.org/licenses/mit-license.php
|
||||
// @author: see AUTHORS file
|
||||
#include <xlnt/serialization/xml_document.hpp>
|
||||
#include <xlnt/serialization/xml_node.hpp>
|
||||
#include <xlnt/serialization/xml_serializer.hpp>
|
||||
|
||||
#include <detail/include_pugixml.hpp>
|
||||
#include <detail/xml_document_impl.hpp>
|
||||
#include <detail/xml_node_impl.hpp>
|
||||
|
||||
namespace xlnt {
|
||||
|
||||
xml_document::xml_document() : d_(new detail::xml_document_impl())
|
||||
{
|
||||
}
|
||||
|
||||
xml_document::xml_document(const xml_document &other) : xml_document()
|
||||
{
|
||||
d_->doc.append_copy(other.d_->doc.root());
|
||||
}
|
||||
|
||||
xml_document::xml_document(xml_document &&other)
|
||||
{
|
||||
std::swap(d_, other.d_);
|
||||
}
|
||||
|
||||
xml_document::~xml_document()
|
||||
{
|
||||
}
|
||||
|
||||
void xml_document::set_encoding(const std::string &encoding)
|
||||
{
|
||||
d_->encoding = encoding;
|
||||
}
|
||||
|
||||
void xml_document::add_namespace(const std::string &id, const std::string &uri)
|
||||
{
|
||||
d_->doc.first_child().append_attribute((id.empty() ? "xmlns" : "xmlns:" + id).c_str()).set_value(uri.c_str());
|
||||
}
|
||||
|
||||
xml_node xml_document::add_child(const xml_node &child)
|
||||
{
|
||||
auto child_node = d_->doc.root().append_copy(child.d_->node);
|
||||
return xml_node(detail::xml_node_impl(child_node));
|
||||
}
|
||||
|
||||
xml_node xml_document::add_child(const std::string &child_name)
|
||||
{
|
||||
auto child = d_->doc.root().append_child(child_name.c_str());
|
||||
return xml_node(detail::xml_node_impl(child));
|
||||
}
|
||||
|
||||
xml_node xml_document::get_root()
|
||||
{
|
||||
return xml_node(detail::xml_node_impl(d_->doc.root()));
|
||||
}
|
||||
|
||||
const xml_node xml_document::get_root() const
|
||||
{
|
||||
return xml_node(detail::xml_node_impl(d_->doc.root()));
|
||||
}
|
||||
|
||||
std::string xml_document::to_string() const
|
||||
{
|
||||
return xml_serializer::serialize(*this);
|
||||
}
|
||||
|
||||
xml_document &xml_document::from_string(const std::string &xml_string)
|
||||
{
|
||||
d_->doc.load(xml_string.c_str());
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
xml_node xml_document::get_child(const std::string &child_name)
|
||||
{
|
||||
return xml_node(detail::xml_node_impl(d_->doc.child(child_name.c_str())));
|
||||
}
|
||||
|
||||
const xml_node xml_document::get_child(const std::string &child_name) const
|
||||
{
|
||||
return xml_node(detail::xml_node_impl(d_->doc.child(child_name.c_str())));
|
||||
}
|
||||
|
||||
} // namespace xlnt
|
|
@ -1,161 +0,0 @@
|
|||
// Copyright (c) 2014-2016 Thomas Fussell
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
// of this software and associated documentation files (the "Software"), to deal
|
||||
// in the Software without restriction, including without limitation the rights
|
||||
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
// copies of the Software, and to permit persons to whom the Software is
|
||||
// furnished to do so, subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included in
|
||||
// all copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, WRISING FROM,
|
||||
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
// THE SOFTWARE
|
||||
//
|
||||
// @license: http://www.opensource.org/licenses/mit-license.php
|
||||
// @author: see AUTHORS file
|
||||
#include <xlnt/serialization/xml_node.hpp>
|
||||
#include <xlnt/serialization/xml_serializer.hpp>
|
||||
|
||||
#include <detail/xml_node_impl.hpp>
|
||||
|
||||
namespace xlnt {
|
||||
|
||||
xml_node::xml_node() : d_(new detail::xml_node_impl)
|
||||
{
|
||||
}
|
||||
|
||||
xml_node::xml_node(const detail::xml_node_impl &d) : xml_node()
|
||||
{
|
||||
d_->node = d.node;
|
||||
}
|
||||
|
||||
xml_node::~xml_node()
|
||||
{
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
std::string xml_node::get_name() const
|
||||
{
|
||||
return d_->node.name();
|
||||
}
|
||||
|
||||
void xml_node::set_name(const std::string &name)
|
||||
{
|
||||
d_->node.set_name(name.c_str());
|
||||
}
|
||||
|
||||
bool xml_node::has_text() const
|
||||
{
|
||||
return d_->node.text() != nullptr;
|
||||
}
|
||||
|
||||
std::string xml_node::get_text() const
|
||||
{
|
||||
return d_->node.text().as_string();
|
||||
}
|
||||
|
||||
void xml_node::set_text(const std::string &text)
|
||||
{
|
||||
d_->node.text().set(text.c_str());
|
||||
}
|
||||
|
||||
const std::vector<xml_node> xml_node::get_children() const
|
||||
{
|
||||
std::vector<xml_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())
|
||||
{
|
||||
child_node.add_attribute(attr.first, attr.second);
|
||||
}
|
||||
|
||||
for (auto child_child : child.get_children())
|
||||
{
|
||||
child_node.add_child(child_child);
|
||||
}
|
||||
|
||||
return child_node;
|
||||
}
|
||||
|
||||
xml_node xml_node::add_child(const std::string &child_name)
|
||||
{
|
||||
return xml_node(detail::xml_node_impl(d_->node.append_child(child_name.c_str())));
|
||||
}
|
||||
|
||||
const std::vector<xml_node::string_pair> xml_node::get_attributes() const
|
||||
{
|
||||
std::vector<string_pair> attributes;
|
||||
|
||||
for (auto attr : d_->node.attributes())
|
||||
{
|
||||
attributes.push_back(std::make_pair<std::string, std::string>(attr.name(), attr.value()));
|
||||
}
|
||||
|
||||
return attributes;
|
||||
}
|
||||
|
||||
void xml_node::add_attribute(const std::string &name, const std::string &value)
|
||||
{
|
||||
d_->node.append_attribute(name.c_str()).set_value(value.c_str());
|
||||
}
|
||||
|
||||
bool xml_node::has_attribute(const std::string &attribute_name) const
|
||||
{
|
||||
return d_->node.attribute(attribute_name.c_str()) != nullptr;
|
||||
}
|
||||
|
||||
std::string xml_node::get_attribute(const std::string &attribute_name) const
|
||||
{
|
||||
return d_->node.attribute(attribute_name.c_str()).value();
|
||||
}
|
||||
|
||||
bool xml_node::has_child(const std::string &child_name) const
|
||||
{
|
||||
return d_->node.child(child_name.c_str()) != nullptr;
|
||||
}
|
||||
|
||||
xml_node xml_node::get_child(const std::string &child_name)
|
||||
{
|
||||
return xml_node(detail::xml_node_impl(d_->node.child(child_name.c_str())));
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
} // namespace xlnt
|
|
@ -1,62 +0,0 @@
|
|||
// Copyright (c) 2014-2016 Thomas Fussell
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
// of this software and associated documentation files (the "Software"), to deal
|
||||
// in the Software without restriction, including without limitation the rights
|
||||
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
// copies of the Software, and to permit persons to whom the Software is
|
||||
// furnished to do so, subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included in
|
||||
// all copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, WRISING FROM,
|
||||
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
// THE SOFTWARE
|
||||
//
|
||||
// @license: http://www.opensource.org/licenses/mit-license.php
|
||||
// @author: see AUTHORS file
|
||||
#include <sstream>
|
||||
|
||||
#include <xlnt/serialization/xml_serializer.hpp>
|
||||
#include <xlnt/serialization/xml_document.hpp>
|
||||
#include <xlnt/serialization/xml_node.hpp>
|
||||
|
||||
#include "detail/include_pugixml.hpp"
|
||||
#include "detail/xml_document_impl.hpp"
|
||||
#include "detail/xml_node_impl.hpp"
|
||||
|
||||
namespace xlnt {
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
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
|
|
@ -1,9 +1,11 @@
|
|||
#pragma once
|
||||
|
||||
#include <iostream>
|
||||
#include <pugixml.hpp>
|
||||
#include <cxxtest/TestSuite.h>
|
||||
|
||||
#include "pugixml.hpp"
|
||||
#include <detail/excel_serializer.hpp>
|
||||
#include <detail/style_serializer.hpp>
|
||||
#include <xlnt/xlnt.hpp>
|
||||
#include <xlnt/packaging/zip_file.hpp>
|
||||
#include <helpers/helper.hpp>
|
||||
|
@ -18,9 +20,11 @@ public:
|
|||
xlnt::excel_serializer excel_serializer(wb);
|
||||
xlnt::style_serializer style_serializer(excel_serializer.get_stylesheet());
|
||||
xlnt::zip_file archive;
|
||||
xlnt::xml_document stylesheet_doc;
|
||||
pugi::xml_document stylesheet_doc;
|
||||
style_serializer.write_stylesheet(stylesheet_doc);
|
||||
auto stylesheet_xml = stylesheet_doc.to_string();
|
||||
std::ostringstream ss;
|
||||
stylesheet_doc.save(ss);
|
||||
auto stylesheet_xml = ss.str();
|
||||
|
||||
const std::string expected =
|
||||
"<styleSheet xmlns=\"http://schemas.openxmlformats.org/spreadsheetml/2006/main\" xmlns:mc=\"http://schemas.openxmlformats.org/markup-compatibility/2006\" xmlns:x14ac=\"http://schemas.microsoft.com/office/spreadsheetml/2009/9/ac\" mc:Ignorable=\"x14ac\">"
|
||||
|
@ -71,9 +75,9 @@ public:
|
|||
|
||||
void test_from_simple()
|
||||
{
|
||||
xlnt::xml_document doc;
|
||||
pugi::xml_document doc;
|
||||
auto xml = PathHelper::read_file(PathHelper::GetDataDirectory("/reader/styles/simple-styles.xml"));
|
||||
doc.from_string(xml);
|
||||
doc.load(xml.c_str());
|
||||
xlnt::workbook wb;
|
||||
xlnt::excel_serializer e(wb);
|
||||
xlnt::style_serializer s(e.get_stylesheet());
|
||||
|
@ -83,9 +87,9 @@ public:
|
|||
|
||||
void test_from_complex()
|
||||
{
|
||||
xlnt::xml_document doc;
|
||||
pugi::xml_document doc;
|
||||
auto xml = PathHelper::read_file(PathHelper::GetDataDirectory("/reader/styles/complex-styles.xml"));
|
||||
doc.from_string(xml);
|
||||
doc.load(xml.c_str());
|
||||
xlnt::workbook wb;
|
||||
xlnt::excel_serializer e(wb);
|
||||
xlnt::style_serializer s(e.get_stylesheet());
|
||||
|
|
|
@ -2,20 +2,16 @@
|
|||
|
||||
#include <fstream>
|
||||
#include <iostream>
|
||||
|
||||
#include <cxxtest/TestSuite.h>
|
||||
|
||||
#include <xlnt/packaging/manifest.hpp>
|
||||
#include <xlnt/serialization/excel_serializer.hpp>
|
||||
#include <xlnt/serialization/manifest_serializer.hpp>
|
||||
#include <xlnt/serialization/relationship_serializer.hpp>
|
||||
#include <xlnt/serialization/workbook_serializer.hpp>
|
||||
#include <xlnt/serialization/xml_serializer.hpp>
|
||||
|
||||
#include <detail/excel_serializer.hpp>
|
||||
#include <detail/manifest_serializer.hpp>
|
||||
#include <detail/relationship_serializer.hpp>
|
||||
#include <detail/workbook_serializer.hpp>
|
||||
#include <helpers/path_helper.hpp>
|
||||
|
||||
#include <xlnt/cell/text.hpp>
|
||||
#include <xlnt/cell/text_run.hpp>
|
||||
#include <xlnt/packaging/manifest.hpp>
|
||||
|
||||
class test_read : public CxxTest::TestSuite
|
||||
{
|
|
@ -3,7 +3,7 @@
|
|||
#include <iostream>
|
||||
#include <cxxtest/TestSuite.h>
|
||||
|
||||
#include <xlnt/serialization/style_serializer.hpp>
|
||||
#include <detail/style_serializer.hpp>
|
||||
#include <detail/stylesheet.hpp>
|
||||
#include <detail/workbook_impl.hpp>
|
||||
|
||||
|
@ -16,15 +16,15 @@ public:
|
|||
wb.get_active_sheet().get_cell("A1").set_number_format(xlnt::number_format("YYYY"));
|
||||
xlnt::excel_serializer excel_serializer(wb);
|
||||
xlnt::style_serializer style_serializer(excel_serializer.get_stylesheet());
|
||||
xlnt::xml_document observed;
|
||||
pugi::xml_document observed;
|
||||
style_serializer.write_stylesheet(observed);
|
||||
xlnt::xml_document expected_doc;
|
||||
pugi::xml_document expected_doc;
|
||||
std::string expected =
|
||||
" <numFmts count=\"1\">"
|
||||
" <numFmt formatCode=\"YYYY\" numFmtId=\"164\"></numFmt>"
|
||||
" </numFmts>";
|
||||
expected_doc.from_string(expected);
|
||||
auto diff = Helper::compare_xml(expected_doc.get_child("numFmts"), observed.get_child("styleSheet").get_child("numFmts"));
|
||||
expected_doc.load(expected.c_str());
|
||||
auto diff = Helper::compare_xml(expected_doc.child("numFmts"), observed.child("styleSheet").child("numFmts"));
|
||||
TS_ASSERT(diff);
|
||||
}
|
||||
/*
|
|
@ -3,12 +3,11 @@
|
|||
#include <iostream>
|
||||
#include <cxxtest/TestSuite.h>
|
||||
|
||||
#include <xlnt/serialization/theme_serializer.hpp>
|
||||
#include <detail/theme_serializer.hpp>
|
||||
#include <helpers/path_helper.hpp>
|
||||
#include <helpers/helper.hpp>
|
||||
#include <xlnt/workbook/workbook.hpp>
|
||||
|
||||
#include "helpers/path_helper.hpp"
|
||||
#include "helpers/helper.hpp"
|
||||
|
||||
class test_theme : public CxxTest::TestSuite
|
||||
{
|
||||
public:
|
||||
|
@ -16,7 +15,8 @@ public:
|
|||
{
|
||||
xlnt::workbook wb;
|
||||
xlnt::theme_serializer serializer;
|
||||
auto xml = serializer.write_theme(wb.get_loaded_theme());
|
||||
pugi::xml_document xml;
|
||||
serializer.write_theme(wb.get_loaded_theme(), xml);
|
||||
TS_ASSERT(Helper::compare_xml(PathHelper::GetDataDirectory() + "/writer/expected/theme1.xml", xml));
|
||||
}
|
||||
};
|
||||
|
|
|
@ -3,16 +3,15 @@
|
|||
#include <iostream>
|
||||
#include <cxxtest/TestSuite.h>
|
||||
|
||||
#include <xlnt/serialization/relationship_serializer.hpp>
|
||||
#include <xlnt/serialization/shared_strings_serializer.hpp>
|
||||
#include <xlnt/serialization/workbook_serializer.hpp>
|
||||
#include <xlnt/serialization/worksheet_serializer.hpp>
|
||||
#include <detail/relationship_serializer.hpp>
|
||||
#include <detail/shared_strings_serializer.hpp>
|
||||
#include <detail/workbook_serializer.hpp>
|
||||
#include <detail/worksheet_serializer.hpp>
|
||||
#include <helpers/temporary_file.hpp>
|
||||
#include <helpers/path_helper.hpp>
|
||||
#include <helpers/helper.hpp>
|
||||
#include <xlnt/workbook/workbook.hpp>
|
||||
|
||||
#include "helpers/temporary_file.hpp"
|
||||
#include "helpers/path_helper.hpp"
|
||||
#include "helpers/helper.hpp"
|
||||
|
||||
class test_write : public CxxTest::TestSuite
|
||||
{
|
||||
public:
|
||||
|
@ -50,18 +49,20 @@ public:
|
|||
xlnt::zip_file archive;
|
||||
xlnt::relationship_serializer serializer(archive);
|
||||
serializer.write_relationships(wb.get_relationships(), "xl/workbook.xml");
|
||||
auto content = xlnt::xml_serializer::deserialize(archive.read("xl/_rels/workbook.xml.rels"));
|
||||
pugi::xml_document xml;
|
||||
xml.load(archive.read("xl/_rels/workbook.xml.rels").c_str());
|
||||
|
||||
TS_ASSERT(Helper::compare_xml(PathHelper::GetDataDirectory() + "/writer/expected/workbook.xml.rels", content));
|
||||
TS_ASSERT(Helper::compare_xml(PathHelper::GetDataDirectory() + "/writer/expected/workbook.xml.rels", xml));
|
||||
}
|
||||
|
||||
void test_write_workbook()
|
||||
{
|
||||
xlnt::workbook wb;
|
||||
xlnt::workbook_serializer serializer(wb);
|
||||
auto content = serializer.write_workbook();
|
||||
pugi::xml_document xml;
|
||||
serializer.write_workbook(xml);
|
||||
|
||||
TS_ASSERT(Helper::compare_xml(PathHelper::GetDataDirectory() + "/writer/expected/workbook.xml", content));
|
||||
TS_ASSERT(Helper::compare_xml(PathHelper::GetDataDirectory() + "/writer/expected/workbook.xml", xml));
|
||||
}
|
||||
|
||||
void test_write_string_table()
|
||||
|
@ -73,9 +74,10 @@ public:
|
|||
ws.get_cell("A2").set_value("world");
|
||||
ws.get_cell("A3").set_value("nice");
|
||||
|
||||
auto content = xlnt::shared_strings_serializer::write_shared_strings(wb.get_shared_strings());
|
||||
pugi::xml_document xml;
|
||||
xlnt::shared_strings_serializer::write_shared_strings(wb.get_shared_strings(), xml);
|
||||
|
||||
TS_ASSERT(Helper::compare_xml(PathHelper::GetDataDirectory() + "/writer/expected/sharedStrings.xml", content));
|
||||
TS_ASSERT(Helper::compare_xml(PathHelper::GetDataDirectory() + "/writer/expected/sharedStrings.xml", xml));
|
||||
}
|
||||
|
||||
void test_write_worksheet()
|
||||
|
@ -84,9 +86,10 @@ public:
|
|||
ws.get_cell("F42").set_value("hello");
|
||||
|
||||
xlnt::worksheet_serializer serializer(ws);
|
||||
auto observed = serializer.write_worksheet();
|
||||
pugi::xml_document xml;
|
||||
serializer.write_worksheet(xml);
|
||||
|
||||
TS_ASSERT(Helper::compare_xml(PathHelper::GetDataDirectory() + "/writer/expected/sheet1.xml", observed));
|
||||
TS_ASSERT(Helper::compare_xml(PathHelper::GetDataDirectory() + "/writer/expected/sheet1.xml", xml));
|
||||
}
|
||||
|
||||
void test_write_hidden_worksheet()
|
||||
|
@ -96,9 +99,10 @@ public:
|
|||
ws.get_cell("F42").set_value("hello");
|
||||
|
||||
xlnt::worksheet_serializer serializer(ws);
|
||||
auto observed = serializer.write_worksheet();
|
||||
pugi::xml_document xml;
|
||||
serializer.write_worksheet(xml);
|
||||
|
||||
TS_ASSERT(Helper::compare_xml(PathHelper::GetDataDirectory() + "/writer/expected/sheet1.xml", observed));
|
||||
TS_ASSERT(Helper::compare_xml(PathHelper::GetDataDirectory() + "/writer/expected/sheet1.xml", xml));
|
||||
}
|
||||
|
||||
void test_write_bool()
|
||||
|
@ -108,9 +112,10 @@ public:
|
|||
ws.get_cell("F43").set_value(true);
|
||||
|
||||
xlnt::worksheet_serializer serializer(ws);
|
||||
auto observed = serializer.write_worksheet();
|
||||
pugi::xml_document xml;
|
||||
serializer.write_worksheet(xml);
|
||||
|
||||
TS_ASSERT(Helper::compare_xml(PathHelper::GetDataDirectory() + "/writer/expected/sheet1_bool.xml", observed));
|
||||
TS_ASSERT(Helper::compare_xml(PathHelper::GetDataDirectory() + "/writer/expected/sheet1_bool.xml", xml));
|
||||
}
|
||||
|
||||
void test_write_formula()
|
||||
|
@ -121,9 +126,10 @@ public:
|
|||
ws.get_cell("F3").set_formula("F1+F2");
|
||||
|
||||
xlnt::worksheet_serializer serializer(ws);
|
||||
auto observed = serializer.write_worksheet();
|
||||
pugi::xml_document xml;
|
||||
serializer.write_worksheet(xml);
|
||||
|
||||
TS_ASSERT(Helper::compare_xml(PathHelper::GetDataDirectory() + "/writer/expected/sheet1_formula.xml", observed));
|
||||
TS_ASSERT(Helper::compare_xml(PathHelper::GetDataDirectory() + "/writer/expected/sheet1_formula.xml", xml));
|
||||
}
|
||||
|
||||
void test_write_height()
|
||||
|
@ -133,9 +139,10 @@ public:
|
|||
ws.get_row_properties(ws.get_cell("F1").get_row()).height = 30;
|
||||
|
||||
xlnt::worksheet_serializer serializer(ws);
|
||||
auto observed = serializer.write_worksheet();
|
||||
pugi::xml_document xml;
|
||||
serializer.write_worksheet(xml);
|
||||
|
||||
TS_ASSERT(Helper::compare_xml(PathHelper::GetDataDirectory() + "/writer/expected/sheet1_height.xml", observed));
|
||||
TS_ASSERT(Helper::compare_xml(PathHelper::GetDataDirectory() + "/writer/expected/sheet1_height.xml", xml));
|
||||
}
|
||||
|
||||
void test_write_hyperlink()
|
||||
|
@ -147,9 +154,10 @@ public:
|
|||
ws.get_cell("A1").set_hyperlink("http://test.com");
|
||||
|
||||
xlnt::worksheet_serializer serializer(ws);
|
||||
auto observed = serializer.write_worksheet();
|
||||
pugi::xml_document xml;
|
||||
serializer.write_worksheet(xml);
|
||||
|
||||
TS_ASSERT(Helper::compare_xml(PathHelper::GetDataDirectory() + "/writer/expected/sheet1_hyperlink.xml", observed));
|
||||
TS_ASSERT(Helper::compare_xml(PathHelper::GetDataDirectory() + "/writer/expected/sheet1_hyperlink.xml", xml));
|
||||
}
|
||||
|
||||
void test_write_hyperlink_rels()
|
||||
|
@ -166,9 +174,10 @@ public:
|
|||
xlnt::zip_file archive;
|
||||
xlnt::relationship_serializer serializer(archive);
|
||||
serializer.write_relationships(ws.get_relationships(), "xl/worksheets/sheet1.xml");
|
||||
auto content = xlnt::xml_serializer::deserialize(archive.read("xl/worksheets/_rels/sheet1.xml.rels"));
|
||||
pugi::xml_document xml;
|
||||
xml.load(archive.read("xl/worksheets/_rels/sheet1.xml.rels").c_str());
|
||||
|
||||
TS_ASSERT(Helper::compare_xml(PathHelper::GetDataDirectory() + "/writer/expected/sheet1_hyperlink.xml.rels", content));
|
||||
TS_ASSERT(Helper::compare_xml(PathHelper::GetDataDirectory() + "/writer/expected/sheet1_hyperlink.xml.rels", xml));
|
||||
}
|
||||
|
||||
void _test_write_hyperlink_image_rels()
|
||||
|
@ -193,14 +202,16 @@ public:
|
|||
ws.auto_filter("A1:F1");
|
||||
|
||||
xlnt::worksheet_serializer ws_serializer(ws);
|
||||
auto observed = ws_serializer.write_worksheet();
|
||||
pugi::xml_document xml;
|
||||
ws_serializer.write_worksheet(xml);
|
||||
|
||||
TS_ASSERT(Helper::compare_xml(PathHelper::GetDataDirectory() + "/writer/expected/sheet1_auto_filter.xml", observed));
|
||||
TS_ASSERT(Helper::compare_xml(PathHelper::GetDataDirectory() + "/writer/expected/sheet1_auto_filter.xml", xml));
|
||||
|
||||
xlnt::workbook_serializer wb_serializer(wb);
|
||||
auto observed2 = wb_serializer.write_workbook();
|
||||
pugi::xml_document xml2;
|
||||
wb_serializer.write_workbook(xml2);
|
||||
|
||||
TS_ASSERT(Helper::compare_xml(PathHelper::GetDataDirectory() + "/writer/expected/workbook_auto_filter.xml", observed2));
|
||||
TS_ASSERT(Helper::compare_xml(PathHelper::GetDataDirectory() + "/writer/expected/workbook_auto_filter.xml", xml2));
|
||||
}
|
||||
|
||||
void test_write_auto_filter_filter_column()
|
||||
|
@ -220,9 +231,10 @@ public:
|
|||
ws.freeze_panes("A4");
|
||||
|
||||
xlnt::worksheet_serializer serializer(ws);
|
||||
auto observed = serializer.write_worksheet();
|
||||
auto temp = observed.to_string();
|
||||
TS_ASSERT(Helper::compare_xml(PathHelper::GetDataDirectory() + "/writer/expected/sheet1_freeze_panes_horiz.xml", observed));
|
||||
pugi::xml_document xml;
|
||||
serializer.write_worksheet(xml);
|
||||
|
||||
TS_ASSERT(Helper::compare_xml(PathHelper::GetDataDirectory() + "/writer/expected/sheet1_freeze_panes_horiz.xml", xml));
|
||||
}
|
||||
|
||||
void test_freeze_panes_vert()
|
||||
|
@ -232,9 +244,10 @@ public:
|
|||
ws.freeze_panes("D1");
|
||||
|
||||
xlnt::worksheet_serializer serializer(ws);
|
||||
auto observed = serializer.write_worksheet();
|
||||
pugi::xml_document xml;
|
||||
serializer.write_worksheet(xml);
|
||||
|
||||
TS_ASSERT(Helper::compare_xml(PathHelper::GetDataDirectory() + "/writer/expected/sheet1_freeze_panes_vert.xml", observed));
|
||||
TS_ASSERT(Helper::compare_xml(PathHelper::GetDataDirectory() + "/writer/expected/sheet1_freeze_panes_vert.xml", xml));
|
||||
}
|
||||
|
||||
void test_freeze_panes_both()
|
||||
|
@ -244,9 +257,10 @@ public:
|
|||
ws.freeze_panes("D4");
|
||||
|
||||
xlnt::worksheet_serializer serializer(ws);
|
||||
auto observed = serializer.write_worksheet();
|
||||
pugi::xml_document xml;
|
||||
serializer.write_worksheet(xml);
|
||||
|
||||
TS_ASSERT(Helper::compare_xml(PathHelper::GetDataDirectory() + "/writer/expected/sheet1_freeze_panes_both.xml", observed));
|
||||
TS_ASSERT(Helper::compare_xml(PathHelper::GetDataDirectory() + "/writer/expected/sheet1_freeze_panes_both.xml", xml));
|
||||
}
|
||||
|
||||
void test_long_number()
|
||||
|
@ -255,9 +269,10 @@ public:
|
|||
ws.get_cell("A1").set_value(9781231231230LL);
|
||||
|
||||
xlnt::worksheet_serializer serializer(ws);
|
||||
auto observed = serializer.write_worksheet();
|
||||
pugi::xml_document xml;
|
||||
serializer.write_worksheet(xml);
|
||||
|
||||
TS_ASSERT(Helper::compare_xml(PathHelper::GetDataDirectory() + "/writer/expected/long_number.xml", observed));
|
||||
TS_ASSERT(Helper::compare_xml(PathHelper::GetDataDirectory() + "/writer/expected/long_number.xml", xml));
|
||||
}
|
||||
|
||||
void test_short_number()
|
||||
|
@ -266,9 +281,10 @@ public:
|
|||
ws.get_cell("A1").set_value(1234567890);
|
||||
|
||||
xlnt::worksheet_serializer serializer(ws);
|
||||
auto observed = serializer.write_worksheet();
|
||||
pugi::xml_document xml;
|
||||
serializer.write_worksheet(xml);
|
||||
|
||||
TS_ASSERT(Helper::compare_xml(PathHelper::GetDataDirectory() + "/writer/expected/short_number.xml", observed));
|
||||
TS_ASSERT(Helper::compare_xml(PathHelper::GetDataDirectory() + "/writer/expected/short_number.xml", xml));
|
||||
}
|
||||
|
||||
void _test_write_images()
|
|
@ -3,10 +3,9 @@
|
|||
#include <iostream>
|
||||
#include <cxxtest/TestSuite.h>
|
||||
|
||||
#include <xlnt/serialization/workbook_serializer.hpp>
|
||||
#include <xlnt/utils/exceptions.hpp>
|
||||
|
||||
#include <detail/workbook_serializer.hpp>
|
||||
#include <helpers/path_helper.hpp>
|
||||
#include <xlnt/utils/exceptions.hpp>
|
||||
|
||||
class test_write_workbook : public CxxTest::TestSuite
|
||||
{
|
||||
|
@ -19,9 +18,10 @@ public:
|
|||
ws.auto_filter("A1:F1");
|
||||
|
||||
xlnt::workbook_serializer serializer(wb);
|
||||
auto observed = serializer.write_workbook();
|
||||
pugi::xml_document xml;
|
||||
serializer.write_workbook(xml);
|
||||
|
||||
auto diff = Helper::compare_xml(PathHelper::read_file("workbook_auto_filter.xml"), observed);
|
||||
auto diff = Helper::compare_xml(PathHelper::read_file("workbook_auto_filter.xml"), xml);
|
||||
TS_ASSERT(!diff);
|
||||
}
|
||||
|
||||
|
@ -33,7 +33,8 @@ public:
|
|||
wb.create_sheet();
|
||||
|
||||
xlnt::workbook_serializer serializer(wb);
|
||||
auto observed = serializer.write_workbook();
|
||||
pugi::xml_document xml;
|
||||
serializer.write_workbook(xml);
|
||||
|
||||
std::string expected_string =
|
||||
"<workbook xmlns=\"http://schemas.openxmlformats.org/spreadsheetml/2006/main\" xmlns:r=\"http://schemas.openxmlformats.org/officeDocument/2006/relationships\">"
|
||||
|
@ -49,10 +50,10 @@ public:
|
|||
" <calcPr calcId=\"124519\" fullCalcOnLoad=\"1\"/>"
|
||||
"</workbook>";
|
||||
|
||||
xlnt::xml_document expected;
|
||||
expected.from_string(expected_string);
|
||||
pugi::xml_document expected;
|
||||
expected.load(expected_string.c_str());
|
||||
|
||||
auto diff = Helper::compare_xml(expected, observed);
|
||||
auto diff = Helper::compare_xml(expected, xml);
|
||||
TS_ASSERT(!diff);
|
||||
}
|
||||
|
||||
|
@ -64,7 +65,8 @@ public:
|
|||
|
||||
xlnt::workbook_serializer serializer(wb);
|
||||
|
||||
TS_ASSERT_THROWS(serializer.write_workbook(), xlnt::value_error);
|
||||
pugi::xml_document xml;
|
||||
TS_ASSERT_THROWS(serializer.write_workbook(xml), xlnt::value_error);
|
||||
}
|
||||
|
||||
void test_write_empty_workbook()
|
||||
|
@ -98,8 +100,8 @@ public:
|
|||
xlnt::zip_file archive;
|
||||
xlnt::relationship_serializer serializer(archive);
|
||||
serializer.write_relationships(wb.get_relationships(), "xl/workbook.xml");
|
||||
xlnt::xml_document observed;
|
||||
observed.from_string(archive.read("xl/_rels/workbook.xml.rels"));
|
||||
pugi::xml_document observed;
|
||||
observed.load(archive.read("xl/_rels/workbook.xml.rels").c_str());
|
||||
auto filename = "workbook.xml.rels";
|
||||
auto diff = Helper::compare_xml(PathHelper::read_file(filename), observed);
|
||||
TS_ASSERT(!diff);
|
||||
|
@ -109,9 +111,10 @@ public:
|
|||
{
|
||||
xlnt::workbook wb;
|
||||
xlnt::workbook_serializer serializer(wb);
|
||||
auto observed = serializer.write_workbook();
|
||||
pugi::xml_document xml;
|
||||
serializer.write_workbook(xml);
|
||||
auto filename = PathHelper::GetDataDirectory("/workbook.xml");
|
||||
auto diff = Helper::compare_xml(PathHelper::read_file(filename), observed);
|
||||
auto diff = Helper::compare_xml(PathHelper::read_file(filename), xml);
|
||||
TS_ASSERT(!diff);
|
||||
}
|
||||
|
||||
|
@ -121,14 +124,13 @@ public:
|
|||
auto ws = wb.create_sheet();
|
||||
wb.create_named_range("test_range", ws, "A1:B5");
|
||||
xlnt::workbook_serializer serializer(wb);
|
||||
auto observed_node = serializer.write_named_ranges();
|
||||
xlnt::xml_document observed;
|
||||
observed.add_child(observed_node);
|
||||
pugi::xml_document xml;
|
||||
serializer.write_named_ranges(xml.root());
|
||||
std::string expected =
|
||||
"<root>"
|
||||
"<s:definedName xmlns:s=\"http://schemas.openxmlformats.org/spreadsheetml/2006/main\" name=\"test_range\">'Sheet'!$A$1:$B$5</s:definedName>"
|
||||
"</root>";
|
||||
auto diff = Helper::compare_xml(expected, observed);
|
||||
auto diff = Helper::compare_xml(expected, xml);
|
||||
TS_ASSERT(!diff);
|
||||
}
|
||||
|
||||
|
@ -144,7 +146,8 @@ public:
|
|||
wb.set_code_name("MyWB");
|
||||
|
||||
xlnt::workbook_serializer serializer(wb);
|
||||
auto observed = serializer.write_workbook();
|
||||
pugi::xml_document xml;
|
||||
serializer.write_workbook(xml);
|
||||
|
||||
std::string expected =
|
||||
"<workbook xmlns=\"http://schemas.openxmlformats.org/spreadsheetml/2006/main\" xmlns:r=\"http://schemas.openxmlformats.org/officeDocument/2006/relationships\">"
|
||||
|
@ -158,7 +161,7 @@ public:
|
|||
" <definedNames/>"
|
||||
" <calcPr calcId=\"124519\" fullCalcOnLoad=\"1\"/>"
|
||||
"</workbook>";
|
||||
auto diff = Helper::compare_xml(expected, observed);
|
||||
auto diff = Helper::compare_xml(expected, xml);
|
||||
TS_ASSERT(!diff);
|
||||
}
|
||||
|
||||
|
@ -168,8 +171,8 @@ public:
|
|||
xlnt::zip_file archive;
|
||||
xlnt::relationship_serializer serializer(archive);
|
||||
serializer.write_relationships(wb.get_root_relationships(), "");
|
||||
xlnt::xml_document observed;
|
||||
observed.from_string(archive.read("_rels/.rels"));
|
||||
pugi::xml_document observed;
|
||||
observed.load(archive.read("_rels/.rels").c_str());
|
||||
|
||||
std::string expected =
|
||||
"<Relationships xmlns=\"http://schemas.openxmlformats.org/package/2006/relationships\">"
|
||||
|
@ -179,7 +182,7 @@ public:
|
|||
"</Relationships>";
|
||||
|
||||
auto diff = Helper::compare_xml(expected, observed);
|
||||
TS_ASSERT(!diff);
|
||||
TS_ASSERT(diff);
|
||||
}
|
||||
|
||||
private:
|
|
@ -33,8 +33,6 @@
|
|||
#include <xlnt/packaging/manifest.hpp>
|
||||
#include <xlnt/packaging/relationship.hpp>
|
||||
#include <xlnt/packaging/zip_file.hpp>
|
||||
#include <xlnt/serialization/encoding.hpp>
|
||||
#include <xlnt/serialization/excel_serializer.hpp>
|
||||
#include <xlnt/styles/alignment.hpp>
|
||||
#include <xlnt/styles/border.hpp>
|
||||
#include <xlnt/styles/format.hpp>
|
||||
|
@ -45,6 +43,7 @@
|
|||
#include <xlnt/styles/protection.hpp>
|
||||
#include <xlnt/utils/exceptions.hpp>
|
||||
#include <xlnt/workbook/const_worksheet_iterator.hpp>
|
||||
#include <xlnt/workbook/encoding.hpp>
|
||||
#include <xlnt/workbook/named_range.hpp>
|
||||
#include <xlnt/workbook/theme.hpp>
|
||||
#include <xlnt/workbook/workbook.hpp>
|
||||
|
@ -53,6 +52,7 @@
|
|||
#include <xlnt/worksheet/worksheet.hpp>
|
||||
|
||||
#include <detail/cell_impl.hpp>
|
||||
#include <detail/excel_serializer.hpp>
|
||||
#include <detail/include_windows.hpp>
|
||||
#include <detail/workbook_impl.hpp>
|
||||
#include <detail/worksheet_impl.hpp>
|
||||
|
|
|
@ -3,7 +3,6 @@
|
|||
#include <iostream>
|
||||
#include <cxxtest/TestSuite.h>
|
||||
|
||||
#include <xlnt/serialization/worksheet_serializer.hpp>
|
||||
#include <xlnt/worksheet/footer.hpp>
|
||||
#include <xlnt/worksheet/header.hpp>
|
||||
#include <xlnt/worksheet/header_footer.hpp>
|
||||
|
|
|
@ -1,11 +1,8 @@
|
|||
#pragma once
|
||||
|
||||
#include <pugixml.hpp>
|
||||
#include <sstream>
|
||||
|
||||
#include <xlnt/serialization/xml_document.hpp>
|
||||
#include <xlnt/serialization/xml_node.hpp>
|
||||
#include <xlnt/serialization/xml_serializer.hpp>
|
||||
|
||||
#include "path_helper.hpp"
|
||||
|
||||
class Helper
|
||||
|
@ -31,12 +28,12 @@ public:
|
|||
operator bool() const { return difference == difference_type::equivalent; }
|
||||
};
|
||||
|
||||
static comparison_result compare_xml(const xlnt::xml_document &expected, const xlnt::xml_document &observed)
|
||||
static comparison_result compare_xml(const pugi::xml_document &expected, const pugi::xml_document &observed)
|
||||
{
|
||||
return compare_xml(expected.get_root(), observed.get_root());
|
||||
return compare_xml(expected.root(), observed.root());
|
||||
}
|
||||
|
||||
static comparison_result compare_xml(const std::string &expected, const xlnt::xml_document &observed)
|
||||
|
||||
static comparison_result compare_xml(const std::string &expected, const pugi::xml_document &observed)
|
||||
{
|
||||
std::string expected_contents = expected;
|
||||
|
||||
|
@ -49,46 +46,48 @@ public:
|
|||
expected_contents = s.str();
|
||||
}
|
||||
|
||||
xlnt::xml_document expected_xml;
|
||||
expected_xml.from_string(expected_contents);
|
||||
pugi::xml_document expected_xml;
|
||||
expected_xml.load(expected_contents.c_str());
|
||||
|
||||
auto observed_string = observed.to_string();
|
||||
std::ostringstream ss;
|
||||
observed.save(ss);
|
||||
auto observed_string = ss.str();
|
||||
|
||||
return compare_xml(expected_xml.get_root(), observed.get_root());
|
||||
return compare_xml(expected_xml.root(), observed.root());
|
||||
}
|
||||
|
||||
static comparison_result compare_xml(const std::string &left_contents, const std::string &right_contents)
|
||||
{
|
||||
xlnt::xml_document left_xml;
|
||||
left_xml.from_string(left_contents);
|
||||
pugi::xml_document left_xml;
|
||||
left_xml.load(left_contents.c_str());
|
||||
|
||||
xlnt::xml_document right_xml;
|
||||
right_xml.from_string(right_contents);
|
||||
pugi::xml_document right_xml;
|
||||
right_xml.load(right_contents.c_str());
|
||||
|
||||
return compare_xml(left_xml.get_root(), right_xml.get_root());
|
||||
return compare_xml(left_xml.root(), right_xml.root());
|
||||
}
|
||||
|
||||
static comparison_result compare_xml(const xlnt::xml_node &left, const xlnt::xml_node &right)
|
||||
static comparison_result compare_xml(const pugi::xml_node &left, const pugi::xml_node &right)
|
||||
{
|
||||
std::string left_temp = left.get_name();
|
||||
std::string right_temp = right.get_name();
|
||||
std::string left_temp = left.name();
|
||||
std::string right_temp = right.name();
|
||||
|
||||
if(left_temp != right_temp)
|
||||
{
|
||||
return {difference_type::names_differ, left_temp, right_temp};
|
||||
}
|
||||
|
||||
for(auto &left_attribute : left.get_attributes())
|
||||
for(auto &left_attribute : left.attributes())
|
||||
{
|
||||
left_temp = left_attribute.second;
|
||||
|
||||
if(!right.has_attribute(left_attribute.first))
|
||||
left_temp = left_attribute.name();
|
||||
|
||||
if(!right.attribute(left_attribute.name()))
|
||||
{
|
||||
return {difference_type::missing_attribute, left_temp, "((empty))"};
|
||||
}
|
||||
|
||||
left_temp = left_attribute.second;
|
||||
right_temp = right.get_attribute(left_attribute.first);
|
||||
left_temp = left_attribute.name();
|
||||
right_temp = right.attribute(left_attribute.name()).name();
|
||||
|
||||
if(left_temp != right_temp)
|
||||
{
|
||||
|
@ -96,34 +95,34 @@ public:
|
|||
}
|
||||
}
|
||||
|
||||
if(left.has_text())
|
||||
if(left.text())
|
||||
{
|
||||
left_temp = left.get_text();
|
||||
left_temp = left.text().get();
|
||||
|
||||
if(!right.has_text())
|
||||
if(!right.text())
|
||||
{
|
||||
return {difference_type::missing_text, left_temp, "((empty))"};
|
||||
}
|
||||
|
||||
right_temp = right.get_text();
|
||||
right_temp = right.text().get();
|
||||
|
||||
if(left_temp != right_temp)
|
||||
{
|
||||
return {difference_type::text_values_differ, left_temp, right_temp};
|
||||
}
|
||||
}
|
||||
else if(right.has_text())
|
||||
else if(right.text())
|
||||
{
|
||||
right_temp = right.get_text();
|
||||
right_temp = right.text().get();
|
||||
return {difference_type::text_values_differ, "((empty))", right_temp};
|
||||
}
|
||||
|
||||
auto right_children = right.get_children();
|
||||
auto right_children = right.children();
|
||||
auto right_child_iter = right_children.begin();
|
||||
|
||||
for(auto left_child : left.get_children())
|
||||
for(auto left_child : left.children())
|
||||
{
|
||||
left_temp = left_child.get_name();
|
||||
left_temp = left_child.name();
|
||||
|
||||
if(right_child_iter == right_children.end())
|
||||
{
|
||||
|
@ -143,7 +142,7 @@ public:
|
|||
|
||||
if(right_child_iter != right_children.end())
|
||||
{
|
||||
right_temp = right_child_iter->get_name();
|
||||
right_temp = right_child_iter->name();
|
||||
return {difference_type::child_order_differs, "((end))", right_temp};
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue
Block a user