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
|
||||
/// the given string as its textual content.
|
||||
/// </summary>
|
||||
void plain_text(const std::string &s);
|
||||
void plain_text(const std::string &s, bool preserve_space);
|
||||
|
||||
/// <summary>
|
||||
/// 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;
|
||||
optional<font> second;
|
||||
bool preserve_space;
|
||||
|
||||
bool operator==(const rich_text_run &other) const;
|
||||
|
||||
|
|
|
@ -390,6 +390,16 @@ public:
|
|||
/// </summary>
|
||||
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
|
||||
|
||||
/// <summary>
|
||||
|
|
|
@ -468,7 +468,7 @@ void cell::error(const std::string &error)
|
|||
throw invalid_data_type();
|
||||
}
|
||||
|
||||
d_->value_text_.plain_text(error);
|
||||
d_->value_text_.plain_text(error, false);
|
||||
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)
|
||||
: text_(), author_(author)
|
||||
{
|
||||
text_.plain_text(text);
|
||||
text_.plain_text(text, false);
|
||||
}
|
||||
|
||||
rich_text comment::text() const
|
||||
|
|
|
@ -48,10 +48,10 @@ void rich_text::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();
|
||||
add_run(rich_text_run{s, {}});
|
||||
add_run(rich_text_run{s, {}, preserve_space});
|
||||
}
|
||||
|
||||
std::string rich_text::plain_text() const
|
||||
|
|
|
@ -121,6 +121,8 @@ struct workbook_impl
|
|||
|
||||
optional<file_version_t> file_version_;
|
||||
optional<calculation_properties> calculation_properties_;
|
||||
optional<std::string> abs_path_;
|
||||
optional<std::size_t> arch_id_flags_;
|
||||
};
|
||||
|
||||
} // namespace detail
|
||||
|
|
|
@ -1504,6 +1504,31 @@ void xlsx_consumer::read_office_document(const std::string &content_type) // CT_
|
|||
{
|
||||
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
|
||||
{
|
||||
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
|
||||
{
|
||||
skip_remaining_content(current_workbook_element);
|
||||
}
|
||||
else if (current_workbook_element == qn("mc", "AlternateContent"))
|
||||
while (in_element(qn("workbook", "extLst")))
|
||||
{
|
||||
skip_remaining_content(current_workbook_element);
|
||||
auto extension_element = expect_start_element(xml::content::complex);
|
||||
|
||||
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
|
||||
{
|
||||
|
@ -2735,12 +2777,15 @@ rich_text xlsx_consumer::read_rich_text(const xml::qname &parent)
|
|||
while (in_element(parent))
|
||||
{
|
||||
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();
|
||||
auto text = read_text();
|
||||
|
||||
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"))
|
||||
{
|
||||
|
|
|
@ -462,11 +462,22 @@ void xlsx_producer::write_workbook(const relationship &rel)
|
|||
static const auto &xmlns = constants::ns("workbook");
|
||||
static const auto &xmlns_r = constants::ns("r");
|
||||
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_namespace(xmlns, "");
|
||||
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())
|
||||
{
|
||||
write_start_element(xmlns, "fileVersion");
|
||||
|
@ -493,6 +504,20 @@ void xlsx_producer::write_workbook(const relationship &rel)
|
|||
|
||||
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())
|
||||
{
|
||||
write_start_element(xmlns, "bookViews");
|
||||
|
@ -634,6 +659,19 @@ void xlsx_producer::write_workbook(const relationship &rel)
|
|||
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");
|
||||
|
||||
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*/)
|
||||
{
|
||||
static const auto &xmlns = constants::ns("spreadsheetml");
|
||||
static const auto &xmlns_xml = constants::ns("xml");
|
||||
|
||||
write_start_element(xmlns, "sst");
|
||||
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, "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_end_element(xmlns, "t");
|
||||
write_end_element(xmlns, "si");
|
||||
|
@ -941,6 +984,12 @@ void xlsx_producer::write_font(const font &f)
|
|||
write_end_element(xmlns, "i");
|
||||
}
|
||||
|
||||
if (f.strikethrough())
|
||||
{
|
||||
write_start_element(xmlns, "strike");
|
||||
write_end_element(xmlns, "strike");
|
||||
}
|
||||
|
||||
if (f.underlined())
|
||||
{
|
||||
write_start_element(xmlns, "u");
|
||||
|
@ -951,12 +1000,6 @@ void xlsx_producer::write_font(const font &f)
|
|||
write_end_element(xmlns, "u");
|
||||
}
|
||||
|
||||
if (f.strikethrough())
|
||||
{
|
||||
write_start_element(xmlns, "strike");
|
||||
write_end_element(xmlns, "strike");
|
||||
}
|
||||
|
||||
if (f.superscript())
|
||||
{
|
||||
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());
|
||||
}
|
||||
|
||||
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()
|
||||
&& 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()));
|
||||
}
|
||||
|
||||
if (current_format_impl.alignment_id.is_set()
|
||||
&& current_format_impl.alignment_applied.is_set())
|
||||
if (current_format_impl.alignment_applied.is_set())
|
||||
{
|
||||
write_attribute("applyAlignment",
|
||||
write_bool(current_format_impl.alignment_applied.get()));
|
||||
}
|
||||
|
||||
if (current_format_impl.protection_id.is_set()
|
||||
&& current_format_impl.protection_applied.is_set())
|
||||
if (current_format_impl.protection_applied.is_set())
|
||||
{
|
||||
write_attribute("applyProtection",
|
||||
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));
|
||||
}
|
||||
|
||||
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())
|
||||
{
|
||||
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");
|
||||
}
|
||||
|
||||
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()
|
||||
{
|
||||
auto impl = new detail::workbook_impl();
|
||||
|
|
Binary file not shown.
Loading…
Reference in New Issue
Block a user