xlnt/source/writer/style_writer.cpp

482 lines
19 KiB
C++
Raw Normal View History

#include <sstream>
#include <pugixml.hpp>
2015-10-19 03:30:46 +08:00
#include <xlnt/styles/alignment.hpp>
2015-10-21 11:30:10 +08:00
#include <xlnt/styles/border.hpp>
2015-10-19 03:30:46 +08:00
#include <xlnt/styles/fill.hpp>
#include <xlnt/styles/font.hpp>
#include <xlnt/styles/number_format.hpp>
#include <xlnt/styles/protection.hpp>
2014-08-14 06:56:34 +08:00
#include <xlnt/writer/style_writer.hpp>
#include <xlnt/workbook/workbook.hpp>
#include <xlnt/worksheet/worksheet.hpp>
#include <xlnt/worksheet/range.hpp>
#include <xlnt/cell/cell.hpp>
2014-06-05 06:42:17 +08:00
namespace xlnt {
style_writer::style_writer(xlnt::workbook &wb) : wb_(wb)
{
}
std::string style_writer::write_table() const
{
pugi::xml_document doc;
auto style_sheet_node = doc.append_child("styleSheet");
style_sheet_node.append_attribute("xmlns").set_value("http://schemas.openxmlformats.org/spreadsheetml/2006/main");
style_sheet_node.append_attribute("xmlns:mc").set_value("http://schemas.openxmlformats.org/markup-compatibility/2006");
style_sheet_node.append_attribute("mc:Ignorable").set_value("x14ac");
style_sheet_node.append_attribute("xmlns:x14ac").set_value("http://schemas.microsoft.com/office/spreadsheetml/2009/9/ac");
2015-10-19 03:30:46 +08:00
auto num_fmts_node = style_sheet_node.append_child("numFmts");
2015-10-19 12:03:52 +08:00
auto num_fmts = wb_.get_number_formats();
2015-10-19 03:30:46 +08:00
num_fmts_node.append_attribute("count").set_value(static_cast<int>(num_fmts.size()));
2015-10-19 12:03:52 +08:00
2015-10-19 03:30:46 +08:00
for(auto &num_fmt : num_fmts)
2014-08-02 04:46:54 +08:00
{
2015-10-19 03:30:46 +08:00
auto num_fmt_node = num_fmts_node.append_child("numFmt");
2015-10-24 02:42:36 +08:00
num_fmt_node.append_attribute("numFmtId").set_value(num_fmt.get_id());
2015-10-19 12:03:52 +08:00
num_fmt_node.append_attribute("formatCode").set_value(num_fmt.get_format_string().c_str());
2014-08-14 06:56:34 +08:00
}
auto fonts_node = style_sheet_node.append_child("fonts");
2015-10-19 12:03:52 +08:00
auto fonts = wb_.get_fonts();
2015-10-21 11:30:10 +08:00
if(fonts.empty())
{
fonts.push_back(font());
}
2015-10-19 03:30:46 +08:00
fonts_node.append_attribute("count").set_value(static_cast<int>(fonts.size()));
fonts_node.append_attribute("x14ac:knownFonts").set_value(1);
2015-10-19 03:30:46 +08:00
for(auto &f : fonts)
{
auto font_node = fonts_node.append_child("font");
2015-10-24 02:42:36 +08:00
2015-10-19 03:30:46 +08:00
auto size_node = font_node.append_child("sz");
2015-10-19 12:03:52 +08:00
size_node.append_attribute("val").set_value(f.get_size());
2015-10-24 02:42:36 +08:00
2015-10-19 03:30:46 +08:00
auto color_node = font_node.append_child("color");
2015-10-24 02:42:36 +08:00
if(f.get_color().get_type() == color::type::indexed)
{
color_node.append_attribute("indexed").set_value(static_cast<unsigned int>(f.get_color().get_index()));
}
else if(f.get_color().get_type() == color::type::theme)
{
color_node.append_attribute("theme").set_value(static_cast<unsigned int>(f.get_color().get_theme()));
}
2015-10-19 03:30:46 +08:00
auto name_node = font_node.append_child("name");
2015-10-19 12:03:52 +08:00
name_node.append_attribute("val").set_value(f.get_name().c_str());
2015-10-24 02:42:36 +08:00
if(f.has_family())
{
auto family_node = font_node.append_child("family");
family_node.append_attribute("val").set_value(2);
}
if(f.has_scheme())
{
auto scheme_node = font_node.append_child("scheme");
scheme_node.append_attribute("val").set_value("minor");
}
2015-10-19 03:30:46 +08:00
2015-10-19 12:03:52 +08:00
if(f.is_bold())
2015-10-19 03:30:46 +08:00
{
auto bold_node = font_node.append_child("b");
bold_node.append_attribute("val").set_value(1);
}
}
auto fills_node = style_sheet_node.append_child("fills");
2015-10-24 02:42:36 +08:00
const auto &fills = wb_.get_fills();
fills_node.append_attribute("count").set_value(static_cast<unsigned int>(fills.size()));
for(auto &fill_ : fills)
{
auto fill_node = fills_node.append_child("fill");
if(fill_.get_type() == fill::type::pattern)
{
auto pattern_fill_node = fill_node.append_child("patternFill");
auto type_string = fill_.get_pattern_type_string();
pattern_fill_node.append_attribute("patternType").set_value(type_string.c_str());
if(fill_.has_foreground_color())
{
auto fg_color_node = pattern_fill_node.append_child("fgColor");
switch(fill_.get_foreground_color().get_type())
{
case color::type::auto_: fg_color_node.append_attribute("auto").set_value(fill_.get_foreground_color().get_auto()); break;
case color::type::theme: fg_color_node.append_attribute("theme").set_value(fill_.get_foreground_color().get_theme()); break;
case color::type::indexed: fg_color_node.append_attribute("indexed").set_value(fill_.get_foreground_color().get_index()); break;
default: throw std::runtime_error("bad type");
}
}
if(fill_.has_background_color())
{
auto bg_color_node = pattern_fill_node.append_child("bgColor");
switch(fill_.get_background_color().get_type())
{
case color::type::auto_: bg_color_node.append_attribute("auto").set_value(fill_.get_background_color().get_auto()); break;
case color::type::theme: bg_color_node.append_attribute("theme").set_value(fill_.get_background_color().get_theme()); break;
case color::type::indexed: bg_color_node.append_attribute("indexed").set_value(fill_.get_background_color().get_index()); break;
default: throw std::runtime_error("bad type");
}
}
}
}
auto borders_node = style_sheet_node.append_child("borders");
2015-10-24 02:42:36 +08:00
const auto &borders = wb_.get_borders();
borders_node.append_attribute("count").set_value(static_cast<unsigned int>(borders.size()));
for(const auto &border_ : borders)
{
auto border_node = borders_node.append_child("border");
if(border_.left_assigned)
{
auto left_node = border_node.append_child("left");
if(border_.left.is_style_assigned())
{
auto style_attribute = left_node.append_attribute("style");
switch(border_.left.get_style())
{
case border_style::none: style_attribute.set_value("none"); break;
case border_style::thin: style_attribute.set_value("thin"); break;
default: throw std::runtime_error("invalid style");
}
}
if(border_.left.is_color_assigned())
{
auto color_node = left_node.append_child("color");
if(border_.left.get_color_type() == side::color_type::indexed)
{
color_node.append_attribute("indexed").set_value((int)border_.left.get_color());
}
else if(border_.diagonal.get_color_type() == side::color_type::theme)
{
color_node.append_attribute("indexed").set_value((int)border_.left.get_color());
}
else
{
throw std::runtime_error("invalid color type");
}
}
}
if(border_.right_assigned)
{
auto right_node = border_node.append_child("right");
if(border_.right.is_style_assigned())
{
auto style_attribute = right_node.append_attribute("style");
switch(border_.right.get_style())
{
case border_style::none: style_attribute.set_value("none"); break;
case border_style::thin: style_attribute.set_value("thin"); break;
default: throw std::runtime_error("invalid style");
}
}
if(border_.right.is_color_assigned())
{
auto color_node = right_node.append_child("color");
if(border_.right.get_color_type() == side::color_type::indexed)
{
color_node.append_attribute("indexed").set_value((int)border_.right.get_color());
}
else if(border_.diagonal.get_color_type() == side::color_type::theme)
{
color_node.append_attribute("indexed").set_value((int)border_.right.get_color());
}
else
{
throw std::runtime_error("invalid color type");
}
}
}
if(border_.top_assigned)
{
auto top_node = border_node.append_child("top");
if(border_.top.is_style_assigned())
{
auto style_attribute = top_node.append_attribute("style");
switch(border_.top.get_style())
{
case border_style::none: style_attribute.set_value("none"); break;
case border_style::thin: style_attribute.set_value("thin"); break;
default: throw std::runtime_error("invalid style");
}
}
if(border_.top.is_color_assigned())
{
auto color_node = top_node.append_child("color");
if(border_.top.get_color_type() == side::color_type::indexed)
{
color_node.append_attribute("indexed").set_value((int)border_.top.get_color());
}
else if(border_.diagonal.get_color_type() == side::color_type::theme)
{
color_node.append_attribute("indexed").set_value((int)border_.top.get_color());
}
else
{
throw std::runtime_error("invalid color type");
}
}
}
if(border_.bottom_assigned)
{
auto bottom_node = border_node.append_child("bottom");
if(border_.bottom.is_style_assigned())
{
auto style_attribute = bottom_node.append_attribute("style");
switch(border_.bottom.get_style())
{
case border_style::none: style_attribute.set_value("none"); break;
case border_style::thin: style_attribute.set_value("thin"); break;
default: throw std::runtime_error("invalid style");
}
}
if(border_.bottom.is_color_assigned())
{
auto color_node = bottom_node.append_child("color");
if(border_.bottom.get_color_type() == side::color_type::indexed)
{
color_node.append_attribute("indexed").set_value((int)border_.bottom.get_color());
}
else if(border_.diagonal.get_color_type() == side::color_type::theme)
{
color_node.append_attribute("indexed").set_value((int)border_.bottom.get_color());
}
else
{
throw std::runtime_error("invalid color type");
}
}
}
if(border_.diagonal_assigned)
{
auto diagonal_node = border_node.append_child("diagonal");
if(border_.diagonal.is_style_assigned())
{
auto style_attribute = diagonal_node.append_attribute("style");
switch(border_.diagonal.get_style())
{
case border_style::none: style_attribute.set_value("none"); break;
case border_style::thin: style_attribute.set_value("thin"); break;
default: throw std::runtime_error("invalid style");
}
}
if(border_.diagonal.is_color_assigned())
{
auto color_node = diagonal_node.append_child("color");
if(border_.diagonal.get_color_type() == side::color_type::indexed)
{
color_node.append_attribute("indexed").set_value((int)border_.diagonal.get_color());
}
else if(border_.diagonal.get_color_type() == side::color_type::theme)
{
color_node.append_attribute("indexed").set_value((int)border_.diagonal.get_color());
}
else
{
throw std::runtime_error("invalid color type");
}
}
}
}
auto cell_style_xfs_node = style_sheet_node.append_child("cellStyleXfs");
cell_style_xfs_node.append_attribute("count").set_value(1);
2015-10-24 02:42:36 +08:00
auto style_xf_node = cell_style_xfs_node.append_child("xf");
style_xf_node.append_attribute("numFmtId").set_value(0);
style_xf_node.append_attribute("fontId").set_value(0);
style_xf_node.append_attribute("fillId").set_value(0);
style_xf_node.append_attribute("borderId").set_value(0);
2015-10-19 12:03:52 +08:00
auto cell_xfs_node = style_sheet_node.append_child("cellXfs");
2015-10-19 12:03:52 +08:00
const auto &styles = wb_.get_styles();
cell_xfs_node.append_attribute("count").set_value(static_cast<int>(styles.size()));
for(auto &style : styles)
{
2015-10-24 02:42:36 +08:00
auto xf_node = cell_xfs_node.append_child("xf");
xf_node.append_attribute("numFmtId").set_value(style.get_number_format().get_id());
xf_node.append_attribute("fontId").set_value((int)style.get_font_id());
if(style.fill_apply_)
2015-10-21 11:30:10 +08:00
{
2015-10-24 02:42:36 +08:00
xf_node.append_attribute("fillId").set_value((int)style.get_fill_id());
2015-10-21 11:30:10 +08:00
}
2015-10-24 02:42:36 +08:00
if(style.border_apply_)
{
xf_node.append_attribute("borderId").set_value((int)style.get_border_id());
}
xf_node.append_attribute("applyNumberFormat").set_value(style.number_format_apply_ ? 1 : 0);
xf_node.append_attribute("applyFont").set_value(style.font_apply_ ? 1 : 0);
xf_node.append_attribute("applyFill").set_value(style.fill_apply_ ? 1 : 0);
xf_node.append_attribute("applyBorder").set_value(style.border_apply_ ? 1 : 0);
xf_node.append_attribute("applyAlignment").set_value(style.alignment_apply_ ? 1 : 0);
xf_node.append_attribute("applyProtection").set_value(style.protection_apply_ ? 1 : 0);
if(style.alignment_apply_)
2015-10-21 11:30:10 +08:00
{
2015-10-24 02:42:36 +08:00
auto alignment_node = xf_node.append_child("alignment");
if(style.alignment_.has_vertical())
{
switch(style.alignment_.get_vertical())
{
case alignment::vertical_alignment::bottom:
alignment_node.append_attribute("vertical").set_value("bottom");
break;
case alignment::vertical_alignment::center:
alignment_node.append_attribute("vertical").set_value("center");
break;
case alignment::vertical_alignment::justify:
alignment_node.append_attribute("vertical").set_value("justify");
break;
case alignment::vertical_alignment::top:
alignment_node.append_attribute("vertical").set_value("top");
break;
default:
throw std::runtime_error("invalid alignment");
}
}
if(style.alignment_.has_horizontal())
{
switch(style.alignment_.get_horizontal())
{
case alignment::horizontal_alignment::center:
alignment_node.append_attribute("horizontal").set_value("center");
break;
case alignment::horizontal_alignment::center_continuous:
alignment_node.append_attribute("horizontal").set_value("center_continuous");
break;
case alignment::horizontal_alignment::general:
alignment_node.append_attribute("horizontal").set_value("general");
break;
case alignment::horizontal_alignment::justify:
alignment_node.append_attribute("horizontal").set_value("justify");
break;
case alignment::horizontal_alignment::left:
alignment_node.append_attribute("horizontal").set_value("left");
break;
case alignment::horizontal_alignment::right:
alignment_node.append_attribute("horizontal").set_value("right");
break;
default:
throw std::runtime_error("invalid alignment");
}
}
if(style.alignment_.get_wrap_text())
{
alignment_node.append_attribute("wrapText").set_value(1);
}
2015-10-21 11:30:10 +08:00
}
2015-10-19 12:03:52 +08:00
}
auto cell_styles_node = style_sheet_node.append_child("cellStyles");
cell_styles_node.append_attribute("count").set_value(1);
auto cell_style_node = cell_styles_node.append_child("cellStyle");
cell_style_node.append_attribute("name").set_value("Normal");
cell_style_node.append_attribute("xfId").set_value(0);
cell_style_node.append_attribute("builtinId").set_value(0);
style_sheet_node.append_child("dxfs").append_attribute("count").set_value(0);
auto table_styles_node = style_sheet_node.append_child("tableStyles");
table_styles_node.append_attribute("count").set_value(0);
table_styles_node.append_attribute("defaultTableStyle").set_value("TableStyleMedium2");
table_styles_node.append_attribute("defaultPivotStyle").set_value("PivotStyleMedium9");
2015-10-24 02:42:36 +08:00
auto colors_node = style_sheet_node.append_child("colors");
auto indexed_colors_node = colors_node.append_child("indexedColors");
const std::vector<std::string> colors =
{
"ff000000",
"ffffffff",
"ffff0000",
"ff00ff00",
"ff0000ff",
"ffffff00",
"ffff00ff",
"ff00ffff",
"ff000000",
"ffaaaaaa",
"ffbdc0bf",
"ffdbdbdb"
};
for(auto &color : colors)
{
indexed_colors_node.append_child("rgbColor").append_attribute("rgb").set_value(color.c_str());
}
auto ext_list_node = style_sheet_node.append_child("extLst");
auto ext_node = ext_list_node.append_child("ext");
ext_node.append_attribute("uri").set_value("{EB79DEF2-80B8-43e5-95BD-54CBDDF9020C}");
ext_node.append_attribute("xmlns:x14").set_value("http://schemas.microsoft.com/office/spreadsheetml/2009/9/main");
ext_node.append_child("x14:slicerStyles").append_attribute("defaultSlicerStyle").set_value("SlicerStyleLight1");
std::stringstream ss;
doc.save(ss);
return ss.str();
}
2015-10-17 06:35:11 +08:00
std::string style_writer::write_number_formats()
{
pugi::xml_document doc;
auto root = doc.append_child("styleSheet");
root.append_attribute("xmlns").set_value("http://schemas.openxmlformats.org/spreadsheetml/2006/main");
auto num_fmts_node = root.append_child("numFmts");
num_fmts_node.append_attribute("count").set_value(1);
auto num_fmt_node = num_fmts_node.append_child("numFmt");
num_fmt_node.append_attribute("formatCode").set_value("YYYY");
num_fmt_node.append_attribute("numFmtId").set_value(164);
std::stringstream ss;
doc.save(ss);
return ss.str();
}
2014-06-05 06:42:17 +08:00
} // namespace xlnt