mirror of
https://github.com/tfussell/xlnt.git
synced 2024-03-22 13:11:17 +08:00
wire up text and text run serialization
This commit is contained in:
parent
74cc503215
commit
3d4941e61d
|
@ -38,9 +38,11 @@ public:
|
||||||
void clear();
|
void clear();
|
||||||
void set_plain_string(const std::string &s);
|
void set_plain_string(const std::string &s);
|
||||||
std::string get_plain_string() const;
|
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 add_run(const text_run &t);
|
||||||
void set_run(const std::vector<text_run> &parts);
|
void set_run(const std::vector<text_run> &parts);
|
||||||
|
|
||||||
|
bool operator==(const text &rhs) const;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
std::vector<text_run> runs_;
|
std::vector<text_run> runs_;
|
||||||
|
|
|
@ -33,12 +33,26 @@ class XLNT_CLASS text_run
|
||||||
public:
|
public:
|
||||||
text_run();
|
text_run();
|
||||||
text_run(const std::string &string);
|
text_run(const std::string &string);
|
||||||
|
|
||||||
|
bool has_formatting() const;
|
||||||
|
|
||||||
std::string get_string() const;
|
std::string get_string() const;
|
||||||
void set_string(const std::string &string);
|
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:
|
private:
|
||||||
std::string string_;
|
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
|
} // namespace xlnt
|
||||||
|
|
|
@ -23,13 +23,13 @@
|
||||||
// @author: see AUTHORS file
|
// @author: see AUTHORS file
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include <string>
|
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
#include <xlnt/xlnt_config.hpp>
|
#include <xlnt/xlnt_config.hpp>
|
||||||
|
|
||||||
namespace xlnt {
|
namespace xlnt {
|
||||||
|
|
||||||
|
class text;
|
||||||
class xml_document;
|
class xml_document;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
@ -38,8 +38,8 @@ class xml_document;
|
||||||
class XLNT_CLASS shared_strings_serializer
|
class XLNT_CLASS shared_strings_serializer
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
static bool read_shared_strings(const xml_document &xml, 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<std::string> &strings);
|
static xml_document write_shared_strings(const std::vector<text> &strings);
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace xlnt
|
} // namespace xlnt
|
||||||
|
|
|
@ -54,6 +54,7 @@ class range;
|
||||||
class range_reference;
|
class range_reference;
|
||||||
class relationship;
|
class relationship;
|
||||||
class style;
|
class style;
|
||||||
|
class text;
|
||||||
class theme;
|
class theme;
|
||||||
class worksheet;
|
class worksheet;
|
||||||
class worksheet_iterator;
|
class worksheet_iterator;
|
||||||
|
@ -202,9 +203,9 @@ public:
|
||||||
|
|
||||||
const std::vector<relationship> &get_root_relationships() const;
|
const std::vector<relationship> &get_root_relationships() const;
|
||||||
|
|
||||||
void add_shared_string(const std::string &shared, bool allow_duplicates=false);
|
void add_shared_string(const text &shared, bool allow_duplicates=false);
|
||||||
std::vector<std::string> &get_shared_strings();
|
std::vector<text> &get_shared_strings();
|
||||||
const std::vector<std::string> &get_shared_strings() const;
|
const std::vector<text> &get_shared_strings() const;
|
||||||
|
|
||||||
void set_thumbnail(const std::vector<std::uint8_t> &thumbnail);
|
void set_thumbnail(const std::vector<std::uint8_t> &thumbnail);
|
||||||
const std::vector<std::uint8_t> &get_thumbnail() const;
|
const std::vector<std::uint8_t> &get_thumbnail() const;
|
||||||
|
|
|
@ -335,18 +335,6 @@ XLNT_FUNCTION void cell::set_value(long double d)
|
||||||
d_->type_ = type::numeric;
|
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 <>
|
template <>
|
||||||
XLNT_FUNCTION void cell::set_value(std::string s)
|
XLNT_FUNCTION void cell::set_value(std::string s)
|
||||||
{
|
{
|
||||||
|
@ -363,9 +351,13 @@ XLNT_FUNCTION void cell::set_value(std::string s)
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
text t;
|
d_->type_ = type::string;
|
||||||
t.set_plain_string(s);
|
d_->value_text_.set_plain_string(s);
|
||||||
set_value(t);
|
|
||||||
|
if (s.size() > 0)
|
||||||
|
{
|
||||||
|
get_workbook().add_shared_string(d_->value_text_);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (get_workbook().get_guess_types())
|
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 <>
|
template <>
|
||||||
XLNT_FUNCTION void cell::set_value(char const *c)
|
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();
|
return d_->value_text_.get_plain_string();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
template <>
|
||||||
|
XLNT_FUNCTION text cell::get_value() const
|
||||||
|
{
|
||||||
|
return d_->value_text_;
|
||||||
|
}
|
||||||
|
|
||||||
bool cell::has_value() const
|
bool cell::has_value() const
|
||||||
{
|
{
|
||||||
return d_->type_ != cell::type::null;
|
return d_->type_ != cell::type::null;
|
||||||
|
|
|
@ -49,7 +49,8 @@ std::string text::get_plain_string() const
|
||||||
|
|
||||||
return plain_string;
|
return plain_string;
|
||||||
}
|
}
|
||||||
std::vector<text_run> text::get_runs()
|
|
||||||
|
std::vector<text_run> text::get_runs() const
|
||||||
{
|
{
|
||||||
return runs_;
|
return runs_;
|
||||||
}
|
}
|
||||||
|
@ -59,4 +60,26 @@ void text::add_run(const text_run &t)
|
||||||
runs_.push_back(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
|
} // namespace xlnt
|
||||||
|
|
|
@ -43,4 +43,34 @@ void text_run::set_string(const std::string &string)
|
||||||
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
|
} // namespace xlnt
|
||||||
|
|
|
@ -75,7 +75,7 @@ struct workbook_impl
|
||||||
std::vector<worksheet_impl> worksheets_;
|
std::vector<worksheet_impl> worksheets_;
|
||||||
std::vector<relationship> relationships_;
|
std::vector<relationship> relationships_;
|
||||||
std::vector<relationship> root_relationships_;
|
std::vector<relationship> root_relationships_;
|
||||||
std::vector<std::string> shared_strings_;
|
std::vector<text> shared_strings_;
|
||||||
|
|
||||||
document_properties properties_;
|
document_properties properties_;
|
||||||
app_properties app_properties_;
|
app_properties app_properties_;
|
||||||
|
|
|
@ -24,6 +24,7 @@
|
||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
#include <iterator>
|
#include <iterator>
|
||||||
|
|
||||||
|
#include <xlnt/cell/text.hpp>
|
||||||
#include <xlnt/serialization/excel_serializer.hpp>
|
#include <xlnt/serialization/excel_serializer.hpp>
|
||||||
#include <xlnt/serialization/manifest_serializer.hpp>
|
#include <xlnt/serialization/manifest_serializer.hpp>
|
||||||
#include <xlnt/serialization/relationship_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()))
|
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;
|
xlnt::xml_document shared_strings_xml;
|
||||||
shared_strings_xml.from_string(archive.read(xlnt::constants::ArcSharedString()));
|
shared_strings_xml.from_string(archive.read(xlnt::constants::ArcSharedString()));
|
||||||
xlnt::shared_strings_serializer::read_shared_strings(shared_strings_xml, shared_strings);
|
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);
|
wb.add_shared_string(shared_string, true);
|
||||||
}
|
}
|
||||||
|
|
|
@ -21,13 +21,15 @@
|
||||||
//
|
//
|
||||||
// @license: http://www.opensource.org/licenses/mit-license.php
|
// @license: http://www.opensource.org/licenses/mit-license.php
|
||||||
// @author: see AUTHORS file
|
// @author: see AUTHORS file
|
||||||
|
|
||||||
#include <xlnt/serialization/shared_strings_serializer.hpp>
|
#include <xlnt/serialization/shared_strings_serializer.hpp>
|
||||||
|
#include <xlnt/cell/text.hpp>
|
||||||
#include <xlnt/serialization/xml_document.hpp>
|
#include <xlnt/serialization/xml_document.hpp>
|
||||||
#include <xlnt/serialization/xml_node.hpp>
|
#include <xlnt/serialization/xml_node.hpp>
|
||||||
|
|
||||||
namespace xlnt {
|
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;
|
xml_document xml;
|
||||||
|
|
||||||
|
@ -39,13 +41,38 @@ xml_document shared_strings_serializer::write_shared_strings(const std::vector<s
|
||||||
|
|
||||||
for (const auto &string : strings)
|
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;
|
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();
|
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"));
|
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;
|
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;
|
text t;
|
||||||
for (const auto& r_node : si_node.get_children())
|
|
||||||
|
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);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -73,7 +73,7 @@ public:
|
||||||
ws.get_cell("A3").set_value("nice");
|
ws.get_cell("A3").set_value("nice");
|
||||||
|
|
||||||
auto content = xlnt::shared_strings_serializer::write_shared_strings(wb.get_shared_strings());
|
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));
|
TS_ASSERT(Helper::compare_xml(PathHelper::GetDataDirectory() + "/writer/expected/sharedStrings.xml", content));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -220,7 +220,7 @@ public:
|
||||||
|
|
||||||
xlnt::worksheet_serializer serializer(ws);
|
xlnt::worksheet_serializer serializer(ws);
|
||||||
auto observed = serializer.write_worksheet();
|
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));
|
TS_ASSERT(Helper::compare_xml(PathHelper::GetDataDirectory() + "/writer/expected/sheet1_freeze_panes_horiz.xml", observed));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -28,6 +28,7 @@
|
||||||
#include <xlnt/serialization/worksheet_serializer.hpp>
|
#include <xlnt/serialization/worksheet_serializer.hpp>
|
||||||
#include <xlnt/cell/cell.hpp>
|
#include <xlnt/cell/cell.hpp>
|
||||||
#include <xlnt/cell/cell_reference.hpp>
|
#include <xlnt/cell/cell_reference.hpp>
|
||||||
|
#include <xlnt/cell/text.hpp>
|
||||||
#include <xlnt/serialization/xml_document.hpp>
|
#include <xlnt/serialization/xml_document.hpp>
|
||||||
#include <xlnt/serialization/xml_node.hpp>
|
#include <xlnt/serialization/xml_node.hpp>
|
||||||
#include <xlnt/workbook/workbook.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++)
|
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);
|
match_index = static_cast<int>(i);
|
||||||
break;
|
break;
|
||||||
|
|
|
@ -685,17 +685,17 @@ const std::vector<relationship> &workbook::get_root_relationships() const
|
||||||
return d_->root_relationships_;
|
return d_->root_relationships_;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::vector<std::string> &workbook::get_shared_strings()
|
std::vector<text> &workbook::get_shared_strings()
|
||||||
{
|
{
|
||||||
return d_->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_;
|
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)
|
if (!allow_duplicates)
|
||||||
{
|
{
|
||||||
|
|
Loading…
Reference in New Issue
Block a user