mirror of
https://github.com/tfussell/xlnt.git
synced 2024-03-22 13:11:17 +08:00
implement abspath and archid flags, fixes some serialization problems
This commit is contained in:
parent
6eb16243ca
commit
e350a7734d
|
@ -67,7 +67,7 @@ public:
|
||||||
/// Clears any runs in this text and adds a single run with default formatting and
|
/// Clears any runs in this text and adds a single run with default formatting and
|
||||||
/// the given string as its textual content.
|
/// the given string as its textual content.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
void plain_text(const std::string &s);
|
void plain_text(const std::string &s, bool preserve_space);
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Combines the textual content of each text run in order and returns the result.
|
/// Combines the textual content of each text run in order and returns the result.
|
||||||
|
|
|
@ -38,6 +38,7 @@ struct rich_text_run
|
||||||
{
|
{
|
||||||
std::string first;
|
std::string first;
|
||||||
optional<font> second;
|
optional<font> second;
|
||||||
|
bool preserve_space;
|
||||||
|
|
||||||
bool operator==(const rich_text_run &other) const;
|
bool operator==(const rich_text_run &other) const;
|
||||||
|
|
||||||
|
|
|
@ -390,6 +390,16 @@ public:
|
||||||
/// </summary>
|
/// </summary>
|
||||||
void title(const std::string &title);
|
void title(const std::string &title);
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Sets the absolute path of this workbook to path.
|
||||||
|
/// </summary>
|
||||||
|
void abs_path(const std::string &path);
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Sets the ArchID flags of this workbook to flags.
|
||||||
|
/// </summary>
|
||||||
|
void arch_id_flags(const std::size_t flags);
|
||||||
|
|
||||||
// Named Ranges
|
// Named Ranges
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
|
|
@ -468,7 +468,7 @@ void cell::error(const std::string &error)
|
||||||
throw invalid_data_type();
|
throw invalid_data_type();
|
||||||
}
|
}
|
||||||
|
|
||||||
d_->value_text_.plain_text(error);
|
d_->value_text_.plain_text(error, false);
|
||||||
d_->type_ = type::error;
|
d_->type_ = type::error;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -38,7 +38,7 @@ comment::comment(const rich_text &text, const std::string &author)
|
||||||
comment::comment(const std::string &text, const std::string &author)
|
comment::comment(const std::string &text, const std::string &author)
|
||||||
: text_(), author_(author)
|
: text_(), author_(author)
|
||||||
{
|
{
|
||||||
text_.plain_text(text);
|
text_.plain_text(text, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
rich_text comment::text() const
|
rich_text comment::text() const
|
||||||
|
|
|
@ -48,10 +48,10 @@ void rich_text::clear()
|
||||||
runs_.clear();
|
runs_.clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
void rich_text::plain_text(const std::string &s)
|
void rich_text::plain_text(const std::string &s, bool preserve_space = false)
|
||||||
{
|
{
|
||||||
clear();
|
clear();
|
||||||
add_run(rich_text_run{s, {}});
|
add_run(rich_text_run{s, {}, preserve_space});
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string rich_text::plain_text() const
|
std::string rich_text::plain_text() const
|
||||||
|
|
|
@ -121,6 +121,8 @@ struct workbook_impl
|
||||||
|
|
||||||
optional<file_version_t> file_version_;
|
optional<file_version_t> file_version_;
|
||||||
optional<calculation_properties> calculation_properties_;
|
optional<calculation_properties> calculation_properties_;
|
||||||
|
optional<std::string> abs_path_;
|
||||||
|
optional<std::size_t> arch_id_flags_;
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace detail
|
} // namespace detail
|
||||||
|
|
|
@ -1504,6 +1504,31 @@ void xlsx_consumer::read_office_document(const std::string &content_type) // CT_
|
||||||
{
|
{
|
||||||
skip_remaining_content(current_workbook_element);
|
skip_remaining_content(current_workbook_element);
|
||||||
}
|
}
|
||||||
|
else if (current_workbook_element == qn("mc", "AlternateContent"))
|
||||||
|
{
|
||||||
|
while (in_element(qn("mc", "AlternateContent")))
|
||||||
|
{
|
||||||
|
auto alternate_content_element = expect_start_element(xml::content::complex);
|
||||||
|
|
||||||
|
if (alternate_content_element == qn("mc", "Choice")
|
||||||
|
&& parser().attribute_present("Requires")
|
||||||
|
&& parser().attribute("Requires") == "x15")
|
||||||
|
{
|
||||||
|
auto x15_element = expect_start_element(xml::content::simple);
|
||||||
|
|
||||||
|
if (x15_element == qn("x15ac", "absPath"))
|
||||||
|
{
|
||||||
|
target_.d_->abs_path_ = parser().attribute("url");
|
||||||
|
}
|
||||||
|
|
||||||
|
skip_remaining_content(x15_element);
|
||||||
|
expect_end_element(x15_element);
|
||||||
|
}
|
||||||
|
|
||||||
|
skip_remaining_content(alternate_content_element);
|
||||||
|
expect_end_element(alternate_content_element);
|
||||||
|
}
|
||||||
|
}
|
||||||
else if (current_workbook_element == qn("workbook", "workbookPr")) // CT_WorkbookPr 0-1
|
else if (current_workbook_element == qn("workbook", "workbookPr")) // CT_WorkbookPr 0-1
|
||||||
{
|
{
|
||||||
target_.base_date(parser().attribute_present("date1904") // optional, bool=false
|
target_.base_date(parser().attribute_present("date1904") // optional, bool=false
|
||||||
|
@ -1656,11 +1681,28 @@ void xlsx_consumer::read_office_document(const std::string &content_type) // CT_
|
||||||
}
|
}
|
||||||
else if (current_workbook_element == qn("workbook", "extLst")) // CT_ExtensionList 0-1
|
else if (current_workbook_element == qn("workbook", "extLst")) // CT_ExtensionList 0-1
|
||||||
{
|
{
|
||||||
skip_remaining_content(current_workbook_element);
|
while (in_element(qn("workbook", "extLst")))
|
||||||
}
|
{
|
||||||
else if (current_workbook_element == qn("mc", "AlternateContent"))
|
auto extension_element = expect_start_element(xml::content::complex);
|
||||||
{
|
|
||||||
skip_remaining_content(current_workbook_element);
|
if (extension_element == qn("workbook", "ext")
|
||||||
|
&& parser().attribute_present("uri")
|
||||||
|
&& parser().attribute("uri") == "{7523E5D3-25F3-A5E0-1632-64F254C22452}")
|
||||||
|
{
|
||||||
|
auto arch_id_extension_element = expect_start_element(xml::content::simple);
|
||||||
|
|
||||||
|
if (arch_id_extension_element == qn("mx", "ArchID"))
|
||||||
|
{
|
||||||
|
target_.d_->arch_id_flags_ = parser().attribute<std::size_t>("Flags");
|
||||||
|
}
|
||||||
|
|
||||||
|
skip_remaining_content(arch_id_extension_element);
|
||||||
|
expect_end_element(arch_id_extension_element);
|
||||||
|
}
|
||||||
|
|
||||||
|
skip_remaining_content(extension_element);
|
||||||
|
expect_end_element(extension_element);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -2735,12 +2777,15 @@ rich_text xlsx_consumer::read_rich_text(const xml::qname &parent)
|
||||||
while (in_element(parent))
|
while (in_element(parent))
|
||||||
{
|
{
|
||||||
auto text_element = expect_start_element(xml::content::mixed);
|
auto text_element = expect_start_element(xml::content::mixed);
|
||||||
|
const auto xml_space = qn("xml", "space");
|
||||||
|
const auto preserve_space = parser().attribute_present(xml_space)
|
||||||
|
? parser().attribute(xml_space) == "preserve" : false;
|
||||||
skip_attributes();
|
skip_attributes();
|
||||||
auto text = read_text();
|
auto text = read_text();
|
||||||
|
|
||||||
if (text_element == xml::qname(xmlns, "t"))
|
if (text_element == xml::qname(xmlns, "t"))
|
||||||
{
|
{
|
||||||
t.plain_text(text);
|
t.plain_text(text, preserve_space);
|
||||||
}
|
}
|
||||||
else if (text_element == xml::qname(xmlns, "r"))
|
else if (text_element == xml::qname(xmlns, "r"))
|
||||||
{
|
{
|
||||||
|
|
|
@ -462,11 +462,22 @@ void xlsx_producer::write_workbook(const relationship &rel)
|
||||||
static const auto &xmlns = constants::ns("workbook");
|
static const auto &xmlns = constants::ns("workbook");
|
||||||
static const auto &xmlns_r = constants::ns("r");
|
static const auto &xmlns_r = constants::ns("r");
|
||||||
static const auto &xmlns_s = constants::ns("spreadsheetml");
|
static const auto &xmlns_s = constants::ns("spreadsheetml");
|
||||||
|
static const auto &xmlns_mx = constants::ns("mx");
|
||||||
|
static const auto &xmlns_x15ac = constants::ns("x15ac");
|
||||||
|
static const auto &xmlns_x15 = constants::ns("x15");
|
||||||
|
static const auto &xmlns_mc = constants::ns("mc");
|
||||||
|
|
||||||
write_start_element(xmlns, "workbook");
|
write_start_element(xmlns, "workbook");
|
||||||
write_namespace(xmlns, "");
|
write_namespace(xmlns, "");
|
||||||
write_namespace(xmlns_r, "r");
|
write_namespace(xmlns_r, "r");
|
||||||
|
|
||||||
|
if (source_.d_->abs_path_.is_set())
|
||||||
|
{
|
||||||
|
write_namespace(xmlns_mc, "mc");
|
||||||
|
write_namespace(xmlns_x15, "x15");
|
||||||
|
write_attribute(xml::qname(xmlns_mc, "Ignorable"), "x15");
|
||||||
|
}
|
||||||
|
|
||||||
if (source_.has_file_version())
|
if (source_.has_file_version())
|
||||||
{
|
{
|
||||||
write_start_element(xmlns, "fileVersion");
|
write_start_element(xmlns, "fileVersion");
|
||||||
|
@ -493,6 +504,20 @@ void xlsx_producer::write_workbook(const relationship &rel)
|
||||||
|
|
||||||
write_end_element(xmlns, "workbookPr");
|
write_end_element(xmlns, "workbookPr");
|
||||||
|
|
||||||
|
if (source_.d_->abs_path_.is_set())
|
||||||
|
{
|
||||||
|
write_start_element(xmlns_mc, "AlternateContent");
|
||||||
|
write_namespace(xmlns_mc, "mc");
|
||||||
|
write_start_element(xmlns_mc, "Choice");
|
||||||
|
write_attribute("Requires", "x15");
|
||||||
|
write_start_element(xmlns_x15ac, "absPath");
|
||||||
|
write_namespace(xmlns_x15ac, "x15ac");
|
||||||
|
write_attribute("url", source_.d_->abs_path_.get());
|
||||||
|
write_end_element(xmlns_x15ac, "absPath");
|
||||||
|
write_end_element(xmlns_mc, "Choice");
|
||||||
|
write_end_element(xmlns_mc, "AlternateContent");
|
||||||
|
}
|
||||||
|
|
||||||
if (source_.has_view())
|
if (source_.has_view())
|
||||||
{
|
{
|
||||||
write_start_element(xmlns, "bookViews");
|
write_start_element(xmlns, "bookViews");
|
||||||
|
@ -634,6 +659,19 @@ void xlsx_producer::write_workbook(const relationship &rel)
|
||||||
write_end_element(xmlns, "definedNames");
|
write_end_element(xmlns, "definedNames");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (source_.d_->arch_id_flags_.is_set())
|
||||||
|
{
|
||||||
|
write_start_element(xmlns, "extLst");
|
||||||
|
write_start_element(xmlns, "ext");
|
||||||
|
write_namespace(xmlns_mx, "mx");
|
||||||
|
write_attribute("uri", "{7523E5D3-25F3-A5E0-1632-64F254C22452}");
|
||||||
|
write_start_element(xmlns_mx, "ArchID");
|
||||||
|
write_attribute("Flags", source_.d_->arch_id_flags_.get());
|
||||||
|
write_end_element(xmlns_mx, "ArchID");
|
||||||
|
write_end_element(xmlns, "ext");
|
||||||
|
write_end_element(xmlns, "extLst");
|
||||||
|
}
|
||||||
|
|
||||||
write_end_element(xmlns, "workbook");
|
write_end_element(xmlns, "workbook");
|
||||||
|
|
||||||
auto workbook_rels = source_.manifest().relationships(rel.target().path());
|
auto workbook_rels = source_.manifest().relationships(rel.target().path());
|
||||||
|
@ -785,6 +823,7 @@ void xlsx_producer::write_pivot_table(const relationship & /*rel*/)
|
||||||
void xlsx_producer::write_shared_string_table(const relationship & /*rel*/)
|
void xlsx_producer::write_shared_string_table(const relationship & /*rel*/)
|
||||||
{
|
{
|
||||||
static const auto &xmlns = constants::ns("spreadsheetml");
|
static const auto &xmlns = constants::ns("spreadsheetml");
|
||||||
|
static const auto &xmlns_xml = constants::ns("xml");
|
||||||
|
|
||||||
write_start_element(xmlns, "sst");
|
write_start_element(xmlns, "sst");
|
||||||
write_namespace(xmlns, "");
|
write_namespace(xmlns, "");
|
||||||
|
@ -832,6 +871,10 @@ void xlsx_producer::write_shared_string_table(const relationship & /*rel*/)
|
||||||
{
|
{
|
||||||
write_start_element(xmlns, "si");
|
write_start_element(xmlns, "si");
|
||||||
write_start_element(xmlns, "t");
|
write_start_element(xmlns, "t");
|
||||||
|
if (string.runs().front().preserve_space)
|
||||||
|
{
|
||||||
|
write_attribute(xml::qname(xmlns_xml, "space"), "preserve");
|
||||||
|
}
|
||||||
write_characters(string.plain_text(), has_trailing_whitespace(string.plain_text()));
|
write_characters(string.plain_text(), has_trailing_whitespace(string.plain_text()));
|
||||||
write_end_element(xmlns, "t");
|
write_end_element(xmlns, "t");
|
||||||
write_end_element(xmlns, "si");
|
write_end_element(xmlns, "si");
|
||||||
|
@ -941,22 +984,22 @@ void xlsx_producer::write_font(const font &f)
|
||||||
write_end_element(xmlns, "i");
|
write_end_element(xmlns, "i");
|
||||||
}
|
}
|
||||||
|
|
||||||
if (f.underlined())
|
|
||||||
{
|
|
||||||
write_start_element(xmlns, "u");
|
|
||||||
if (f.underline() != font::underline_style::single)
|
|
||||||
{
|
|
||||||
write_attribute("val", f.underline());
|
|
||||||
}
|
|
||||||
write_end_element(xmlns, "u");
|
|
||||||
}
|
|
||||||
|
|
||||||
if (f.strikethrough())
|
if (f.strikethrough())
|
||||||
{
|
{
|
||||||
write_start_element(xmlns, "strike");
|
write_start_element(xmlns, "strike");
|
||||||
write_end_element(xmlns, "strike");
|
write_end_element(xmlns, "strike");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (f.underlined())
|
||||||
|
{
|
||||||
|
write_start_element(xmlns, "u");
|
||||||
|
if (f.underline() != font::underline_style::single)
|
||||||
|
{
|
||||||
|
write_attribute("val", f.underline());
|
||||||
|
}
|
||||||
|
write_end_element(xmlns, "u");
|
||||||
|
}
|
||||||
|
|
||||||
if (f.superscript())
|
if (f.superscript())
|
||||||
{
|
{
|
||||||
write_start_element(xmlns, "vertAlign");
|
write_start_element(xmlns, "vertAlign");
|
||||||
|
@ -1431,6 +1474,11 @@ void xlsx_producer::write_styles(const relationship & /*rel*/)
|
||||||
write_attribute("borderId", current_format_impl.border_id.get());
|
write_attribute("borderId", current_format_impl.border_id.get());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (current_format_impl.style.is_set())
|
||||||
|
{
|
||||||
|
write_attribute("xfId", stylesheet.style_index(current_format_impl.style.get()));
|
||||||
|
}
|
||||||
|
|
||||||
if (current_format_impl.number_format_id.is_set()
|
if (current_format_impl.number_format_id.is_set()
|
||||||
&& current_format_impl.number_format_applied.is_set())
|
&& current_format_impl.number_format_applied.is_set())
|
||||||
{
|
{
|
||||||
|
@ -1459,15 +1507,13 @@ void xlsx_producer::write_styles(const relationship & /*rel*/)
|
||||||
write_bool(current_format_impl.border_applied.get()));
|
write_bool(current_format_impl.border_applied.get()));
|
||||||
}
|
}
|
||||||
|
|
||||||
if (current_format_impl.alignment_id.is_set()
|
if (current_format_impl.alignment_applied.is_set())
|
||||||
&& current_format_impl.alignment_applied.is_set())
|
|
||||||
{
|
{
|
||||||
write_attribute("applyAlignment",
|
write_attribute("applyAlignment",
|
||||||
write_bool(current_format_impl.alignment_applied.get()));
|
write_bool(current_format_impl.alignment_applied.get()));
|
||||||
}
|
}
|
||||||
|
|
||||||
if (current_format_impl.protection_id.is_set()
|
if (current_format_impl.protection_applied.is_set())
|
||||||
&& current_format_impl.protection_applied.is_set())
|
|
||||||
{
|
{
|
||||||
write_attribute("applyProtection",
|
write_attribute("applyProtection",
|
||||||
write_bool(current_format_impl.protection_applied.get()));
|
write_bool(current_format_impl.protection_applied.get()));
|
||||||
|
@ -1483,11 +1529,6 @@ void xlsx_producer::write_styles(const relationship & /*rel*/)
|
||||||
write_attribute("quotePrefix", write_bool(true));
|
write_attribute("quotePrefix", write_bool(true));
|
||||||
}
|
}
|
||||||
|
|
||||||
if (current_format_impl.style.is_set())
|
|
||||||
{
|
|
||||||
write_attribute("xfId", stylesheet.style_index(current_format_impl.style.get()));
|
|
||||||
}
|
|
||||||
|
|
||||||
if (current_format_impl.alignment_id.is_set())
|
if (current_format_impl.alignment_id.is_set())
|
||||||
{
|
{
|
||||||
const auto ¤t_alignment = stylesheet.alignments[current_format_impl.alignment_id.get()];
|
const auto ¤t_alignment = stylesheet.alignments[current_format_impl.alignment_id.get()];
|
||||||
|
|
|
@ -374,6 +374,16 @@ variant workbook::custom_property(const std::string &property_name) const
|
||||||
throw xlnt::exception("workbook doesn't have custom property");
|
throw xlnt::exception("workbook doesn't have custom property");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void workbook::abs_path(const std::string &path)
|
||||||
|
{
|
||||||
|
d_->abs_path_ = path;
|
||||||
|
}
|
||||||
|
|
||||||
|
void workbook::arch_id_flags(const std::size_t flags)
|
||||||
|
{
|
||||||
|
d_->arch_id_flags_ = flags;
|
||||||
|
}
|
||||||
|
|
||||||
workbook workbook::empty()
|
workbook workbook::empty()
|
||||||
{
|
{
|
||||||
auto impl = new detail::workbook_impl();
|
auto impl = new detail::workbook_impl();
|
||||||
|
|
Binary file not shown.
Loading…
Reference in New Issue
Block a user