mirror of
https://github.com/tfussell/xlnt.git
synced 2024-03-22 13:11:17 +08:00
fix some xlsx consumption and production
This commit is contained in:
parent
cf019f6af6
commit
4d20ccaa67
|
@ -52,7 +52,7 @@ public:
|
|||
|
||||
optional<int> rotation() const;
|
||||
|
||||
alignment &rotation(bool text_rotation);
|
||||
alignment &rotation(int text_rotation);
|
||||
|
||||
optional<horizontal_alignment> horizontal() const;
|
||||
|
||||
|
|
|
@ -54,6 +54,10 @@ public:
|
|||
|
||||
bool bold() const;
|
||||
|
||||
font &superscript(bool superscript);
|
||||
|
||||
bool superscript() const;
|
||||
|
||||
font &italic(bool italic);
|
||||
|
||||
bool italic() const;
|
||||
|
|
|
@ -673,9 +673,11 @@ void xlsx_consumer::read_pivot_table()
|
|||
|
||||
void xlsx_consumer::read_shared_string_table()
|
||||
{
|
||||
static const auto xmlns = constants::get_namespace("shared-strings");
|
||||
static const auto xmlns = constants::get_namespace("worksheet");
|
||||
|
||||
parser().next_expect(xml::parser::event_type::start_element, xmlns, "sst");
|
||||
parser().content(xml::content::complex);
|
||||
|
||||
std::size_t unique_count = 0;
|
||||
|
||||
if (parser().attribute_present("uniqueCount"))
|
||||
|
@ -690,12 +692,14 @@ void xlsx_consumer::read_shared_string_table()
|
|||
if (parser().peek() == xml::parser::event_type::end_element) break;
|
||||
|
||||
parser().next_expect(xml::parser::event_type::start_element, xmlns, "si");
|
||||
parser().content(xml::content::complex);
|
||||
parser().next_expect(xml::parser::event_type::start_element);
|
||||
|
||||
text t;
|
||||
|
||||
if (parser().name() == "t")
|
||||
{
|
||||
parser().next_expect(xml::parser::event_type::characters);
|
||||
t.set_plain_string(parser().value());
|
||||
}
|
||||
else if (parser().name() == "r") // possible multiple text entities.
|
||||
|
@ -705,8 +709,8 @@ void xlsx_consumer::read_shared_string_table()
|
|||
if (parser().peek() == xml::parser::event_type::end_element) break;
|
||||
|
||||
parser().next_expect(xml::parser::event_type::start_element, xmlns, "t");
|
||||
|
||||
text_run run;
|
||||
parser().next_expect(xml::parser::event_type::characters);
|
||||
text_run run;
|
||||
run.set_string(parser().value());
|
||||
|
||||
if (parser().peek() == xml::parser::event_type::start_element)
|
||||
|
@ -740,7 +744,7 @@ void xlsx_consumer::read_shared_string_table()
|
|||
run.set_scheme(parser().attribute("val"));
|
||||
}
|
||||
|
||||
parser().next_expect(xml::parser::event_type::end_element, parser().qname());
|
||||
parser().next_expect(xml::parser::event_type::end_element);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -748,6 +752,8 @@ void xlsx_consumer::read_shared_string_table()
|
|||
}
|
||||
}
|
||||
|
||||
parser().next_expect(xml::parser::event_type::end_element);
|
||||
parser().next_expect(xml::parser::event_type::end_element);
|
||||
strings.push_back(t);
|
||||
}
|
||||
|
||||
|
@ -1022,6 +1028,10 @@ void xlsx_consumer::read_stylesheet()
|
|||
new_font.bold(true);
|
||||
}
|
||||
}
|
||||
else if (parser().name() == "vertAlign")
|
||||
{
|
||||
new_font.superscript(parser().attribute("val") == "superscript");
|
||||
}
|
||||
else if (parser().name() == "strike")
|
||||
{
|
||||
if (parser().attribute_present("val"))
|
||||
|
@ -1127,6 +1137,7 @@ void xlsx_consumer::read_stylesheet()
|
|||
if (parser().peek() == xml::parser::event_type::end_element) break;
|
||||
|
||||
parser().next_expect(xml::parser::event_type::start_element, xmlns, "xf");
|
||||
parser().content(xml::content::complex);
|
||||
|
||||
auto &record = *(!in_style_records
|
||||
? format_records.emplace(format_records.end())
|
||||
|
@ -1179,8 +1190,25 @@ void xlsx_consumer::read_stylesheet()
|
|||
|
||||
if (parser().qname() == xml::qname(xmlns, "alignment"))
|
||||
{
|
||||
record.alignment.first.wrap(is_true(parser().attribute("wrapText")));
|
||||
record.alignment.first.shrink(is_true(parser().attribute("shrinkToFit")));
|
||||
if (parser().attribute_present("wrapText"))
|
||||
{
|
||||
record.alignment.first.wrap(is_true(parser().attribute("wrapText")));
|
||||
}
|
||||
|
||||
if (parser().attribute_present("shrinkToFit"))
|
||||
{
|
||||
record.alignment.first.shrink(is_true(parser().attribute("shrinkToFit")));
|
||||
}
|
||||
|
||||
if (parser().attribute_present("indent"))
|
||||
{
|
||||
record.alignment.first.indent(parser().attribute<int>("indent"));
|
||||
}
|
||||
|
||||
if (parser().attribute_present("textRotation"))
|
||||
{
|
||||
record.alignment.first.rotation(parser().attribute<int>("textRotation"));
|
||||
}
|
||||
|
||||
if (parser().attribute_present("vertical"))
|
||||
{
|
||||
|
@ -1462,6 +1490,7 @@ void xlsx_consumer::read_worksheet(const std::string &rel_id)
|
|||
if (parser().peek() == xml::parser::event_type::end_element) break;
|
||||
|
||||
parser().next_expect(xml::parser::event_type::start_element, xmlns, "row");
|
||||
parser().content(xml::content::complex);
|
||||
|
||||
auto row_index = static_cast<row_t>(std::stoull(parser().attribute("r")));
|
||||
|
||||
|
@ -1470,6 +1499,16 @@ void xlsx_consumer::read_worksheet(const std::string &rel_id)
|
|||
ws.get_row_properties(row_index).height = std::stold(parser().attribute("ht"));
|
||||
}
|
||||
|
||||
if (parser().attribute_present("customHeight"))
|
||||
{
|
||||
ws.get_row_properties(row_index).height = std::stold(parser().attribute("customHeight"));
|
||||
}
|
||||
|
||||
if (parser().attribute_present(xml::qname(xmlns_x14ac, "dyDescent")))
|
||||
{
|
||||
parser().attribute(xml::qname(xmlns_x14ac, "dyDescent"));
|
||||
}
|
||||
|
||||
std::string span_string = parser().attribute("spans");
|
||||
auto colon_index = span_string.find(':');
|
||||
|
||||
|
@ -1492,6 +1531,7 @@ void xlsx_consumer::read_worksheet(const std::string &rel_id)
|
|||
if (parser().peek() == xml::parser::event_type::end_element) break;
|
||||
|
||||
parser().next_expect(xml::parser::event_type::start_element, xmlns, "c");
|
||||
parser().content(xml::content::complex);
|
||||
auto cell = ws.get_cell(cell_reference(parser().attribute("r")));
|
||||
|
||||
auto has_type = parser().attribute_present("t");
|
||||
|
@ -1516,22 +1556,26 @@ void xlsx_consumer::read_worksheet(const std::string &rel_id)
|
|||
if (parser().qname() == xml::qname(xmlns, "v"))
|
||||
{
|
||||
has_value = true;
|
||||
parser().next_expect(xml::parser::event_type::characters);
|
||||
value_string = parser().value();
|
||||
}
|
||||
else if (parser().qname() == xml::qname(xmlns, "f"))
|
||||
{
|
||||
has_formula = true;
|
||||
has_shared_formula = parser().attribute_present("t") && parser().attribute("t") == "shared";
|
||||
has_shared_formula = parser().attribute_present("t")
|
||||
&& parser().attribute("t") == "shared";
|
||||
parser().next_expect(xml::parser::event_type::characters);
|
||||
formula_value_string = parser().value();
|
||||
}
|
||||
else if (parser().qname() == xml::qname(xmlns, "is"))
|
||||
{
|
||||
parser().next_expect(xml::parser::event_type::start_element, xmlns, "t");
|
||||
parser().next_expect(xml::parser::event_type::characters);
|
||||
value_string = parser().value();
|
||||
parser().next_expect(xml::parser::event_type::end_element, xmlns, "t");
|
||||
}
|
||||
|
||||
parser().next_expect(xml::parser::event_type::end_element, parser().qname());
|
||||
parser().next_expect(xml::parser::event_type::end_element);
|
||||
}
|
||||
|
||||
if (has_formula && !has_shared_formula && !ws.get_workbook().get_data_only())
|
||||
|
@ -1572,6 +1616,8 @@ void xlsx_consumer::read_worksheet(const std::string &rel_id)
|
|||
|
||||
parser().next_expect(xml::parser::event_type::end_element, xmlns, "c");
|
||||
}
|
||||
|
||||
parser().next_expect(xml::parser::event_type::end_element, xmlns, "row");
|
||||
}
|
||||
|
||||
parser().next_expect(xml::parser::event_type::end_element, xmlns, "sheetData");
|
||||
|
@ -1602,6 +1648,11 @@ void xlsx_consumer::read_worksheet(const std::string &rel_id)
|
|||
ws.get_column_properties(min).custom = custom;
|
||||
}
|
||||
|
||||
if (parser().attribute_present("bestFit"))
|
||||
{
|
||||
parser().attribute("bestFit");
|
||||
}
|
||||
|
||||
parser().next_expect(xml::parser::event_type::end_element, xmlns, "col");
|
||||
}
|
||||
|
||||
|
|
|
@ -758,9 +758,19 @@ void xlsx_producer::write_styles(const relationship &rel)
|
|||
serializer().start_element(xmlns, "fonts");
|
||||
serializer().attribute("count", fonts.size());
|
||||
|
||||
auto num_known_fonts = std::count_if(fonts.begin(), fonts.end(), [](const xlnt::font &f)
|
||||
{
|
||||
static const auto known_fonts = std::vector<xlnt::font>
|
||||
{
|
||||
xlnt::font().color(xlnt::theme_color(1)).scheme("minor").family(2)
|
||||
};
|
||||
|
||||
return std::find(known_fonts.begin(), known_fonts.end(), f) != known_fonts.end();
|
||||
});
|
||||
|
||||
if (source_.x15_enabled())
|
||||
{
|
||||
serializer().attribute(xmlns_x14ac, "knownFonts", fonts.size());
|
||||
serializer().attribute(xmlns_x14ac, "knownFonts", num_known_fonts);
|
||||
}
|
||||
|
||||
for (const auto ¤t_font : fonts)
|
||||
|
@ -999,7 +1009,7 @@ void xlsx_producer::write_styles(const relationship &rel)
|
|||
{
|
||||
const auto current_alignment = current_style.alignment();
|
||||
|
||||
serializer().start_element("alignment");
|
||||
serializer().start_element(xmlns, "alignment");
|
||||
|
||||
if (current_alignment.vertical())
|
||||
{
|
||||
|
@ -1031,17 +1041,17 @@ void xlsx_producer::write_styles(const relationship &rel)
|
|||
serializer().attribute("shrinkToFit", write_bool(*current_alignment.shrink()));
|
||||
}
|
||||
|
||||
serializer().end_element("alignment");
|
||||
serializer().end_element(xmlns, "alignment");
|
||||
}
|
||||
|
||||
if (current_style.protection_applied())
|
||||
{
|
||||
const auto current_protection = current_style.protection();
|
||||
|
||||
serializer().start_element("protection");
|
||||
serializer().start_element(xmlns, "protection");
|
||||
serializer().attribute("locked", write_bool(current_protection.locked()));
|
||||
serializer().attribute("hidden", write_bool(current_protection.hidden()));
|
||||
serializer().end_element("protection");
|
||||
serializer().end_element(xmlns, "protection");
|
||||
}
|
||||
|
||||
serializer().end_element(xmlns, "xf");
|
||||
|
@ -1072,11 +1082,18 @@ void xlsx_producer::write_styles(const relationship &rel)
|
|||
if (current_format.alignment_applied()) serializer().attribute("applyAlignment", write_bool(true));
|
||||
if (current_format.protection_applied()) serializer().attribute("applyProtection", write_bool(true));
|
||||
|
||||
if (current_format.has_style())
|
||||
{
|
||||
serializer().attribute("xfId", std::distance(stylesheet.styles.begin(),
|
||||
std::find_if(stylesheet.styles.begin(), stylesheet.styles.end(),
|
||||
[&](const xlnt::style &s) { return s.name() == current_format.style().name(); })));
|
||||
}
|
||||
|
||||
if (current_format.alignment_applied())
|
||||
{
|
||||
const auto current_alignment = current_format.alignment();
|
||||
|
||||
serializer().start_element("alignment");
|
||||
serializer().start_element(xmlns, "alignment");
|
||||
|
||||
if (current_alignment.vertical())
|
||||
{
|
||||
|
@ -1108,24 +1125,17 @@ void xlsx_producer::write_styles(const relationship &rel)
|
|||
serializer().attribute("shrinkToFit", write_bool(*current_alignment.shrink()));
|
||||
}
|
||||
|
||||
serializer().end_element("alignment");
|
||||
serializer().end_element(xmlns, "alignment");
|
||||
}
|
||||
|
||||
if (current_format.protection_applied())
|
||||
{
|
||||
const auto current_protection = current_format.protection();
|
||||
|
||||
serializer().start_element("protection");
|
||||
serializer().start_element(xmlns, "protection");
|
||||
serializer().attribute("locked", write_bool(current_protection.locked()));
|
||||
serializer().attribute("hidden", write_bool(current_protection.hidden()));
|
||||
serializer().end_element("protection");
|
||||
}
|
||||
|
||||
if (current_format.has_style())
|
||||
{
|
||||
serializer().attribute("xfId", std::distance(stylesheet.styles.begin(),
|
||||
std::find_if(stylesheet.styles.begin(), stylesheet.styles.end(),
|
||||
[&](const xlnt::style &s) { return s.name() == current_format.style().name(); })));
|
||||
serializer().end_element(xmlns, "protection");
|
||||
}
|
||||
|
||||
serializer().end_element(xmlns, "xf");
|
||||
|
@ -1845,13 +1855,13 @@ void xlsx_producer::write_worksheet(const relationship &rel)
|
|||
|
||||
const auto &props = ws.get_column_properties(column);
|
||||
|
||||
serializer().end_element(xmlns, "col");
|
||||
serializer().start_element(xmlns, "col");
|
||||
serializer().attribute("min", column.index);
|
||||
serializer().attribute("max", column.index);
|
||||
serializer().attribute("width", props.width);
|
||||
serializer().attribute("style", props.style);
|
||||
serializer().attribute("customWidth", write_bool(props.custom));
|
||||
serializer().end_element(xmlns, "cols");
|
||||
serializer().end_element(xmlns, "col");
|
||||
}
|
||||
|
||||
serializer().end_element(xmlns, "cols");
|
||||
|
|
|
@ -81,9 +81,9 @@ optional<int> alignment::indent() const
|
|||
return indent_;
|
||||
}
|
||||
|
||||
alignment &alignment::rotation(bool value)
|
||||
alignment &alignment::rotation(int value)
|
||||
{
|
||||
text_rotation_ = 0;
|
||||
text_rotation_ = value;
|
||||
return *this;
|
||||
}
|
||||
|
||||
|
|
|
@ -50,6 +50,17 @@ bool font::bold() const
|
|||
return bold_;
|
||||
}
|
||||
|
||||
font &font::superscript(bool superscript)
|
||||
{
|
||||
superscript_ = superscript;
|
||||
return *this;
|
||||
}
|
||||
|
||||
bool font::superscript() const
|
||||
{
|
||||
return superscript_;
|
||||
}
|
||||
|
||||
font &font::italic(bool italic)
|
||||
{
|
||||
italic_ = italic;
|
||||
|
|
|
@ -93,7 +93,6 @@ public:
|
|||
|
||||
void test_round_trip_empty_excel_rw()
|
||||
{
|
||||
TS_SKIP("");
|
||||
auto path = path_helper::get_data_directory("9_default-excel.xlsx");
|
||||
TS_ASSERT(round_trip_matches_rw(path));
|
||||
}
|
||||
|
@ -107,13 +106,12 @@ public:
|
|||
|
||||
void test_round_trip_all_styles_rw()
|
||||
{
|
||||
TS_SKIP("");
|
||||
auto path = path_helper::get_data_directory("13_all_styles.xlsx");
|
||||
xlnt::workbook original_workbook;
|
||||
original_workbook.load(path);
|
||||
|
||||
std::vector<std::uint8_t> buffer;
|
||||
original_workbook.save(buffer);
|
||||
// TS_ASSERT(round_trip_matches_rw(path));
|
||||
//TS_ASSERT(round_trip_matches_rw(path));
|
||||
}
|
||||
};
|
||||
|
|
Loading…
Reference in New Issue
Block a user