wire up text and text run serialization

This commit is contained in:
Thomas Fussell 2016-05-14 15:19:08 -04:00
parent 74cc503215
commit 3d4941e61d
13 changed files with 163 additions and 45 deletions

View File

@ -38,9 +38,11 @@ public:
void clear();
void set_plain_string(const std::string &s);
std::string get_plain_string() const;
std::vector<text_run> get_runs();
std::vector<text_run> get_runs() const;
void add_run(const text_run &t);
void set_run(const std::vector<text_run> &parts);
bool operator==(const text &rhs) const;
private:
std::vector<text_run> runs_;

View File

@ -33,12 +33,26 @@ class XLNT_CLASS text_run
public:
text_run();
text_run(const std::string &string);
bool has_formatting() const;
std::string get_string() const;
void set_string(const std::string &string);
std::size_t get_size() const;
std::string get_color() const;
std::string get_font() const;
std::size_t get_family() const;
std::string get_scheme() const;
private:
std::string string_;
bool has_formatting_ = false;
std::size_t size_;
std::string color_;
std::string font_;
std::size_t family_;
std::string scheme_;
};
} // namespace xlnt

View File

@ -23,13 +23,13 @@
// @author: see AUTHORS file
#pragma once
#include <string>
#include <vector>
#include <xlnt/xlnt_config.hpp>
namespace xlnt {
class text;
class xml_document;
/// <summary>
@ -38,8 +38,8 @@ class xml_document;
class XLNT_CLASS shared_strings_serializer
{
public:
static bool read_shared_strings(const xml_document &xml, std::vector<std::string> &strings);
static xml_document write_shared_strings(const std::vector<std::string> &strings);
static bool read_shared_strings(const xml_document &xml, std::vector<text> &strings);
static xml_document write_shared_strings(const std::vector<text> &strings);
};
} // namespace xlnt

View File

@ -54,6 +54,7 @@ class range;
class range_reference;
class relationship;
class style;
class text;
class theme;
class worksheet;
class worksheet_iterator;
@ -202,9 +203,9 @@ public:
const std::vector<relationship> &get_root_relationships() const;
void add_shared_string(const std::string &shared, bool allow_duplicates=false);
std::vector<std::string> &get_shared_strings();
const std::vector<std::string> &get_shared_strings() const;
void add_shared_string(const text &shared, bool allow_duplicates=false);
std::vector<text> &get_shared_strings();
const std::vector<text> &get_shared_strings() const;
void set_thumbnail(const std::vector<std::uint8_t> &thumbnail);
const std::vector<std::uint8_t> &get_thumbnail() const;

View File

@ -335,18 +335,6 @@ XLNT_FUNCTION void cell::set_value(long double d)
d_->type_ = type::numeric;
}
template <>
XLNT_FUNCTION void cell::set_value(text t)
{
d_->value_text_ = t;
d_->type_ = type::string;
if (!t.get_plain_string().empty())
{
get_workbook().add_shared_string(t.get_plain_string());
}
}
template <>
XLNT_FUNCTION void cell::set_value(std::string s)
{
@ -363,9 +351,13 @@ XLNT_FUNCTION void cell::set_value(std::string s)
}
else
{
text t;
t.set_plain_string(s);
set_value(t);
d_->type_ = type::string;
d_->value_text_.set_plain_string(s);
if (s.size() > 0)
{
get_workbook().add_shared_string(d_->value_text_);
}
}
if (get_workbook().get_guess_types())
@ -374,6 +366,21 @@ XLNT_FUNCTION void cell::set_value(std::string s)
}
}
template <>
XLNT_FUNCTION void cell::set_value(text t)
{
if (t.get_runs().size() == 1 && !t.get_runs().front().has_formatting())
{
set_value(t.get_plain_string());
}
else
{
d_->type_ = type::string;
d_->value_text_ = t;
get_workbook().add_shared_string(t);
}
}
template <>
XLNT_FUNCTION void cell::set_value(char const *c)
{
@ -927,6 +934,12 @@ XLNT_FUNCTION std::string cell::get_value() const
return d_->value_text_.get_plain_string();
}
template <>
XLNT_FUNCTION text cell::get_value() const
{
return d_->value_text_;
}
bool cell::has_value() const
{
return d_->type_ != cell::type::null;

View File

@ -49,7 +49,8 @@ std::string text::get_plain_string() const
return plain_string;
}
std::vector<text_run> text::get_runs()
std::vector<text_run> text::get_runs() const
{
return runs_;
}
@ -59,4 +60,26 @@ void text::add_run(const text_run &t)
runs_.push_back(t);
}
bool text::operator==(const text &rhs) const
{
if (runs_.size() != rhs.runs_.size()) return false;
for (std::size_t i = 0; i < runs_.size(); i++)
{
if (runs_[i].get_string() != rhs.runs_[i].get_string()) return false;
if (runs_[i].has_formatting() != rhs.runs_[i].has_formatting()) return false;
if (runs_[i].has_formatting())
{
if (runs_[i].get_color() != rhs.runs_[i].get_color()) return false;
if (runs_[i].get_family() != rhs.runs_[i].get_family()) return false;
if (runs_[i].get_font() != rhs.runs_[i].get_font()) return false;
if (runs_[i].get_scheme() != rhs.runs_[i].get_scheme()) return false;
if (runs_[i].get_size() != rhs.runs_[i].get_size()) return false;
}
}
return true;
}
} // namespace xlnt

View File

@ -43,4 +43,34 @@ void text_run::set_string(const std::string &string)
string_ = string;
}
bool text_run::has_formatting() const
{
return has_formatting_;
}
std::size_t text_run::get_size() const
{
return size_;
}
std::string text_run::get_color() const
{
return color_;
}
std::string text_run::get_font() const
{
return font_;
}
std::size_t text_run::get_family() const
{
return family_;
}
std::string text_run::get_scheme() const
{
return scheme_;
}
} // namespace xlnt

View File

@ -75,7 +75,7 @@ struct workbook_impl
std::vector<worksheet_impl> worksheets_;
std::vector<relationship> relationships_;
std::vector<relationship> root_relationships_;
std::vector<std::string> shared_strings_;
std::vector<text> shared_strings_;
document_properties properties_;
app_properties app_properties_;

View File

@ -24,6 +24,7 @@
#include <algorithm>
#include <iterator>
#include <xlnt/cell/text.hpp>
#include <xlnt/serialization/excel_serializer.hpp>
#include <xlnt/serialization/manifest_serializer.hpp>
#include <xlnt/serialization/relationship_serializer.hpp>
@ -125,12 +126,12 @@ bool load_workbook(xlnt::zip_file &archive, bool guess_types, bool data_only, xl
if(archive.has_file(xlnt::constants::ArcSharedString()))
{
std::vector<std::string> shared_strings;
std::vector<xlnt::text> shared_strings;
xlnt::xml_document shared_strings_xml;
shared_strings_xml.from_string(archive.read(xlnt::constants::ArcSharedString()));
xlnt::shared_strings_serializer::read_shared_strings(shared_strings_xml, shared_strings);
for (auto shared_string : shared_strings)
for (auto &shared_string : shared_strings)
{
wb.add_shared_string(shared_string, true);
}

View File

@ -21,13 +21,15 @@
//
// @license: http://www.opensource.org/licenses/mit-license.php
// @author: see AUTHORS file
#include <xlnt/serialization/shared_strings_serializer.hpp>
#include <xlnt/cell/text.hpp>
#include <xlnt/serialization/xml_document.hpp>
#include <xlnt/serialization/xml_node.hpp>
namespace xlnt {
xml_document shared_strings_serializer::write_shared_strings(const std::vector<std::string> &strings)
xml_document shared_strings_serializer::write_shared_strings(const std::vector<text> &strings)
{
xml_document xml;
@ -39,13 +41,38 @@ xml_document shared_strings_serializer::write_shared_strings(const std::vector<s
for (const auto &string : strings)
{
root_node.add_child("si").add_child("t").set_text(string);
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());
}
else
{
for (const auto &run : string.get_runs())
{
auto string_item_node = root_node.add_child("si");
auto rich_text_run_node = string_item_node.add_child("r");
auto text_node = rich_text_run_node.add_child("t");
text_node.set_text(run.get_string());
if (run.has_formatting())
{
auto run_properties_node = rich_text_run_node.add_child("rPr");
run_properties_node.add_child("sz").add_attribute("val", std::to_string(run.get_size()));
run_properties_node.add_child("color").add_attribute("rgb", run.get_color());
run_properties_node.add_child("rFont").add_attribute("val", run.get_font());
run_properties_node.add_child("family").add_attribute("val", std::to_string(run.get_family()));
run_properties_node.add_child("scheme").add_attribute("val", run.get_scheme());
}
}
}
}
return xml;
}
bool shared_strings_serializer::read_shared_strings(const xml_document &xml, std::vector<std::string> &strings)
bool shared_strings_serializer::read_shared_strings(const xml_document &xml, std::vector<text> &strings)
{
strings.clear();
@ -57,28 +84,34 @@ bool shared_strings_serializer::read_shared_strings(const xml_document &xml, std
unique_count = std::stoull(root_node.get_attribute("uniqueCount"));
}
for (const auto &si_node : root_node.get_children())
for (const auto &string_item_node : root_node.get_children())
{
if (si_node.get_name() != "si")
if (string_item_node.get_name() != "si")
{
continue;
}
if (si_node.has_child("t"))
if (string_item_node.has_child("t"))
{
strings.push_back(si_node.get_child("t").get_text());
text t;
t.set_plain_string(string_item_node.get_child("t").get_text());
strings.push_back(t);
}
else if (si_node.has_child("r")) // possible multiple text entities.
else if (string_item_node.has_child("r")) // possible multiple text entities.
{
std::string text;
for (const auto& r_node : si_node.get_children())
text t;
for (const auto& rich_text_run_node : string_item_node.get_children())
{
if (r_node.get_name() == "r" && r_node.has_child("t"))
if (rich_text_run_node.get_name() == "r" && rich_text_run_node.has_child("t"))
{
text += r_node.get_child("t").get_text();
text_run run;
run.set_string(rich_text_run_node.get_child("t").get_text());
t.add_run(run);
}
}
strings.push_back(std::move(text));
strings.push_back(t);
}
}

View File

@ -73,7 +73,7 @@ public:
ws.get_cell("A3").set_value("nice");
auto content = xlnt::shared_strings_serializer::write_shared_strings(wb.get_shared_strings());
TS_ASSERT(Helper::compare_xml(PathHelper::GetDataDirectory() + "/writer/expected/sharedStrings.xml", content));
}
@ -220,7 +220,7 @@ public:
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));
}

View File

@ -28,6 +28,7 @@
#include <xlnt/serialization/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>
@ -438,7 +439,7 @@ xml_document worksheet_serializer::write_worksheet() const
for (std::size_t i = 0; i < shared_strings.size(); i++)
{
if (shared_strings[i] == cell.get_value<std::string>())
if (shared_strings[i] == cell.get_value<text>())
{
match_index = static_cast<int>(i);
break;

View File

@ -685,17 +685,17 @@ const std::vector<relationship> &workbook::get_root_relationships() const
return d_->root_relationships_;
}
std::vector<std::string> &workbook::get_shared_strings()
std::vector<text> &workbook::get_shared_strings()
{
return d_->shared_strings_;
}
const std::vector<std::string> &workbook::get_shared_strings() const
const std::vector<text> &workbook::get_shared_strings() const
{
return d_->shared_strings_;
}
void workbook::add_shared_string(const std::string &shared, bool allow_duplicates)
void workbook::add_shared_string(const text &shared, bool allow_duplicates)
{
if (!allow_duplicates)
{