continue fixing up border and fill round tripping

This commit is contained in:
Thomas Fussell 2016-09-10 10:05:06 -04:00
parent ba2186ff7b
commit cb5a9d8802
9 changed files with 186 additions and 18 deletions

View File

@ -46,15 +46,15 @@ public:
bool alignment_applied() const;
// Border
class border &border();
const class border &border() const;
void border(const xlnt::border &new_border, bool applied);
virtual class border &border();
virtual const class border &border() const;
virtual void border(const xlnt::border &new_border, bool applied);
bool border_applied() const;
// Fill
class fill &fill();
const class fill &fill() const;
void fill(const xlnt::fill &new_fill, bool applied);
virtual class fill &fill();
virtual const class fill &fill() const;
virtual void fill(const xlnt::fill &new_fill, bool applied);
bool fill_applied() const;
// Font

View File

@ -54,6 +54,14 @@ public:
void style(const std::string &name);
void style(const xlnt::style &new_style);
const class style &style() const;
class border &border() override;
const class border &border() const override;
void border(const xlnt::border &new_border, bool applied) override;
class fill &fill() override;
const class fill &fill() const override;
void fill(const xlnt::fill &new_fill, bool applied) override;
class font &font() override;
const class font &font() const override;

View File

@ -9,7 +9,7 @@ template<typename T>
class XLNT_CLASS optional
{
public:
optional() : has_value_(false)
optional() : has_value_(false), value_(T())
{
}

View File

@ -139,6 +139,44 @@ struct stylesheet
return id;
}
std::size_t add_border(const border &new_border)
{
std::size_t index = 0;
for (const border &f : borders)
{
if (f == new_border)
{
return index;
}
++index;
}
borders.push_back(new_border);
return index;
}
std::size_t add_fill(const fill &new_fill)
{
std::size_t index = 0;
for (const fill &f : fills)
{
if (f == new_fill)
{
return index;
}
++index;
}
fills.push_back(new_fill);
return index;
}
std::size_t add_font(const font &new_font)
{
std::size_t index = 0;
@ -157,6 +195,24 @@ struct stylesheet
return index;
}
void clear()
{
format_impls.clear();
formats.clear();
style_impls.clear();
styles.clear();
alignments.clear();
borders.clear();
fills.clear();
fonts.clear();
number_formats.clear();
protections.clear();
colors.clear();
}
std::list<format_impl> format_impls;
std::vector<format> formats;

View File

@ -213,8 +213,8 @@ std::string to_string(xlnt::border_side side)
{
case xlnt::border_side::bottom: return "bottom";
case xlnt::border_side::top: return "top";
case xlnt::border_side::start: return "start";
case xlnt::border_side::end: return "end";
case xlnt::border_side::start: return "left";
case xlnt::border_side::end: return "right";
case xlnt::border_side::horizontal: return "horizontal";
case xlnt::border_side::vertical: return "vertical";
default:
@ -669,6 +669,15 @@ void xlsx_consumer::populate_workbook()
case relationship::type::worksheet:
read_worksheet(document.root(), rel.get_id());
break;
case relationship::type::shared_string_table:
read_shared_string_table(document);
break;
case relationship::type::styles:
read_stylesheet(document);
break;
case relationship::type::theme:
read_theme(document);
break;
default:
break;
}
@ -1046,7 +1055,9 @@ void xlsx_consumer::read_stylesheet(const pugi::xml_node root)
for (auto xf_node : cell_style_xfs_node.children("xf"))
{
auto cell_style_node = *(cell_style_iter++);
auto &style = destination_.create_style(cell_style_node.attribute("Name").value());
auto &style = destination_.create_style(cell_style_node.attribute("name").value());
style.builtin_id(string_to_size_t(cell_style_node.attribute("builtinId").value()));
// Alignment
auto alignment_node = xf_node.child("alignment");
@ -1076,7 +1087,23 @@ void xlsx_consumer::read_stylesheet(const pugi::xml_node root)
// Number Format
auto number_format_applied = is_true(xf_node.attribute("applyNumberFormat").value());
auto number_format_id = xf_node.attribute("numFmtId") ? string_to_size_t(xf_node.attribute("numFmtId").value()) : 0;
auto number_format = stylesheet.number_formats.at(number_format_id);
auto number_format = number_format::general();
bool is_custom_number_format = false;
for (const auto &nf : stylesheet.number_formats)
{
if (nf.get_id() == number_format_id)
{
number_format = nf;
is_custom_number_format = true;
break;
}
}
if (number_format_id < 164 && !is_custom_number_format)
{
number_format = number_format::from_builtin_id(number_format_id);
}
style.number_format(number_format, number_format_applied);
// Protection
@ -1119,7 +1146,23 @@ void xlsx_consumer::read_stylesheet(const pugi::xml_node root)
// Number Format
auto number_format_applied = is_true(xf_node.attribute("applyNumberFormat").value());
auto number_format_id = xf_node.attribute("numFmtId") ? string_to_size_t(xf_node.attribute("numFmtId").value()) : 0;
auto number_format = stylesheet.number_formats.at(number_format_id);
auto number_format = number_format::general();
bool is_custom_number_format = false;
for (const auto &nf : stylesheet.number_formats)
{
if (nf.get_id() == number_format_id)
{
number_format = nf;
is_custom_number_format = true;
break;
}
}
if (number_format_id < 164 && !is_custom_number_format)
{
number_format = number_format::from_builtin_id(number_format_id);
}
format.number_format(number_format, number_format_applied);
// Protection

View File

@ -1070,12 +1070,27 @@ void xlsx_producer::write_styles(const relationship &rel, pugi::xml_node root)
xf_node.append_attribute("numFmtId").set_value(std::to_string(current_format.number_format().get_id()).c_str());
auto font_id = std::distance(stylesheet.fonts.begin(), std::find(stylesheet.fonts.begin(), stylesheet.fonts.end(), current_format.font()));
auto font_iter = std::find(stylesheet.fonts.begin(), stylesheet.fonts.end(), current_format.font());
if (font_iter == stylesheet.fonts.end())
{
throw xlnt::exception("font not found");
}
auto font_id = std::distance(stylesheet.fonts.begin(), font_iter);
xf_node.append_attribute("fontId").set_value(std::to_string(font_id).c_str());
auto fill_iter = std::find(stylesheet.fills.begin(), stylesheet.fills.end(), current_format.fill());
if (fill_iter == stylesheet.fills.end())
{
throw xlnt::exception("fill not found");
}
auto fill_id = std::distance(stylesheet.fills.begin(), std::find(stylesheet.fills.begin(), stylesheet.fills.end(), current_format.fill()));
xf_node.append_attribute("fillId").set_value(std::to_string(fill_id).c_str());
auto border_iter = std::find(stylesheet.borders.begin(), stylesheet.borders.end(), current_format.border());
if (border_iter == stylesheet.borders.end())
{
throw xlnt::exception("border not found");
}
auto border_id = std::distance(stylesheet.borders.begin(), std::find(stylesheet.borders.begin(), stylesheet.borders.end(), current_format.border()));
xf_node.append_attribute("borderId").set_value(std::to_string(border_id).c_str());

View File

@ -72,6 +72,38 @@ const style &format::style() const
return d_->parent->get_style(*d_->style);
}
xlnt::border &format::border()
{
return base_format::border();
}
const xlnt::border &format::border() const
{
return base_format::border();
}
void format::border(const xlnt::border &new_border, bool applied)
{
border_id(d_->parent->add_border(new_border));
base_format::border(new_border, applied);
}
xlnt::fill &format::fill()
{
return base_format::fill();
}
const xlnt::fill &format::fill() const
{
return base_format::fill();
}
void format::fill(const xlnt::fill &new_fill, bool applied)
{
fill_id(d_->parent->add_fill(new_fill));
base_format::fill(new_fill, applied);
}
xlnt::font &format::font()
{
return base_format::font();
@ -88,7 +120,6 @@ void format::font(const xlnt::font &new_font, bool applied)
base_format::font(new_font, applied);
}
xlnt::number_format &format::number_format()
{
return base_format::number_format();
@ -112,6 +143,18 @@ void format::number_format(const xlnt::number_format &new_number_format, bool ap
base_format::number_format(copy, applied);
}
format &format::border_id(std::size_t id)
{
d_->border_id = id;
return *this;
}
format &format::fill_id(std::size_t id)
{
d_->fill_id = id;
return *this;
}
format &format::font_id(std::size_t id)
{
d_->font_id = id;

View File

@ -20,6 +20,7 @@ public:
{
std::vector<std::uint8_t> buffer;
original.save(buffer);
original.save("a.xlsx");
xlnt::zip_file original_archive;
original_archive.load(buffer);
@ -29,6 +30,7 @@ public:
buffer.clear();
resulting_workbook.save(buffer);
resulting_workbook.save("b.xlsx");
xlnt::zip_file resulting_archive;
resulting_archive.load(buffer);
@ -57,26 +59,26 @@ public:
return xml_helper::xlsx_archives_match(original_archive, resulting_archive);
}
void test_round_trip_minimal_wr()
void test_round_trip_minimal_wrw()
{
xlnt::workbook wb = xlnt::workbook::minimal();
TS_ASSERT(round_trip_matches_wrw(wb));
}
void test_round_trip_empty_excel_wr()
void test_round_trip_empty_excel_wrw()
{
xlnt::workbook wb = xlnt::workbook::empty_excel();
TS_ASSERT(round_trip_matches_wrw(wb));
}
void _test_round_trip_empty_libre_office_wr()
void _test_round_trip_empty_libre_office_wrw()
{
TS_SKIP("");
xlnt::workbook wb = xlnt::workbook::empty_libre_office();
TS_ASSERT(round_trip_matches_wrw(wb));
}
void _test_round_trip_empty_pages_wr()
void _test_round_trip_empty_pages_wrw()
{
TS_SKIP("");
xlnt::workbook wb = xlnt::workbook::empty_numbers();

View File

@ -766,6 +766,7 @@ worksheet workbook::operator[](std::size_t index)
void workbook::clear()
{
*d_ = detail::workbook_impl();
d_->stylesheet_.clear();
}
bool workbook::operator==(const workbook &rhs) const