begin translating xml parsing and serialization to libstudxml

This commit is contained in:
Thomas Fussell 2016-09-16 22:59:13 -04:00
parent 044424a6f0
commit 45f61ee644
11 changed files with 490 additions and 357 deletions

5
.gitmodules vendored
View File

@ -12,3 +12,8 @@
path = third-party/utfcpp path = third-party/utfcpp
url = https://github.com/nemtrif/utfcpp url = https://github.com/nemtrif/utfcpp
branch = master branch = master
[submodule "third-party/pugixml"]
path = third-party/pugixml
url = https://github.com/zeux/pugixml
branch = master

View File

@ -28,7 +28,7 @@ include_directories(include)
include_directories(include/xlnt) include_directories(include/xlnt)
include_directories(source) include_directories(source)
include_directories(third-party/miniz) include_directories(third-party/miniz)
include_directories(third-party/pugixml/src) include_directories(third-party/libstudxml)
include_directories(third-party/utfcpp/source) include_directories(third-party/utfcpp/source)
FILE(GLOB ROOT_HEADERS include/xlnt/*.hpp) FILE(GLOB ROOT_HEADERS include/xlnt/*.hpp)
@ -64,14 +64,13 @@ SET(SOURCES ${CELL_SOURCES} ${CHARTS_SOURCES} ${CHARTSHEET_SOURCES} ${DRAWING_SO
SET(MINIZ ../third-party/miniz/miniz.c ../third-party/miniz/miniz.h) SET(MINIZ ../third-party/miniz/miniz.c ../third-party/miniz/miniz.h)
SET(PUGIXML ../third-party/pugixml/src/pugixml.hpp ../third-party/pugixml/src/pugixml.cpp ../third-party/pugixml/src/pugiconfig.hpp) SET(LIBSTUDXML ../third-party/libstudxml/xml/parser.cxx)
if(SHARED) if(SHARED)
add_library(xlnt.shared SHARED ${HEADERS} ${SOURCES} ${MINIZ} ${PUGIXML}) add_library(xlnt.shared SHARED ${HEADERS} ${SOURCES} ${MINIZ} ${LIBSTUDXML})
target_compile_definitions(xlnt.shared PRIVATE XLNT_SHARED=1) target_compile_definitions(xlnt.shared PRIVATE XLNT_SHARED=1)
if(MSVC) if(MSVC)
target_compile_definitions(xlnt.shared PRIVATE XLNT_EXPORT=1) target_compile_definitions(xlnt.shared PRIVATE XLNT_EXPORT=1)
target_compile_definitions(xlnt.shared PRIVATE PUGIXML_API=__declspec\(dllexport\))
set_target_properties(xlnt.shared PROPERTIES COMPILE_FLAGS "/wd\"4251\" /wd\"4275\"") set_target_properties(xlnt.shared PROPERTIES COMPILE_FLAGS "/wd\"4251\" /wd\"4275\"")
endif() endif()
install(TARGETS xlnt.shared install(TARGETS xlnt.shared
@ -102,7 +101,7 @@ if(SHARED)
endif() endif()
if(STATIC) if(STATIC)
add_library(xlnt.static STATIC ${HEADERS} ${SOURCES} ${MINIZ} ${PUGIXML}) add_library(xlnt.static STATIC ${HEADERS} ${SOURCES} ${MINIZ} ${LIBSTUDXML})
target_compile_definitions(xlnt.static PUBLIC XLNT_STATIC=1) target_compile_definitions(xlnt.static PUBLIC XLNT_STATIC=1)
install(TARGETS xlnt.static install(TARGETS xlnt.static
LIBRARY DESTINATION ${LIB_DEST_DIR} LIBRARY DESTINATION ${LIB_DEST_DIR}
@ -130,7 +129,7 @@ source_group(utils FILES ${UTILS_HEADERS} ${UTILS_SOURCES})
source_group(workbook FILES ${WORKBOOK_HEADERS} ${WORKBOOK_SOURCES}) source_group(workbook FILES ${WORKBOOK_HEADERS} ${WORKBOOK_SOURCES})
source_group(worksheet FILES ${WORKSHEET_HEADERS} ${WORKSHEET_SOURCES}) source_group(worksheet FILES ${WORKSHEET_HEADERS} ${WORKSHEET_SOURCES})
source_group(third-party\\miniz FILES ${MINIZ}) source_group(third-party\\miniz FILES ${MINIZ})
source_group(third-party\\pugixml FILES ${PUGIXML}) source_group(third-party\\libstudxml FILES ${LIBSTUDXML})
SET(CMAKE_INSTALL_RPATH_USE_LINK_PATH TRUE) SET(CMAKE_INSTALL_RPATH_USE_LINK_PATH TRUE)

View File

@ -22,9 +22,7 @@
// @author: see AUTHORS file // @author: see AUTHORS file
#pragma once #pragma once
/// <summary> #include <xml/content>
/// Define this here so we don't have to modify pugiconfig.hpp in pugixml source tree. #include <xml/parser>
/// </summary> #include <xml/qname>
#define PUGIXML_HAS_LONG_LONG #include <xml/serializer>
#include <pugixml.hpp>

View File

@ -3,7 +3,6 @@
#include <detail/xlsx_consumer.hpp> #include <detail/xlsx_consumer.hpp>
#include <detail/constants.hpp> #include <detail/constants.hpp>
#include <detail/include_pugixml.hpp>
#include <detail/workbook_impl.hpp> #include <detail/workbook_impl.hpp>
#include <xlnt/cell/cell.hpp> #include <xlnt/cell/cell.hpp>
#include <xlnt/utils/path.hpp> #include <xlnt/utils/path.hpp>
@ -222,20 +221,36 @@ std::string to_string(xlnt::border_side side)
} }
} }
xlnt::protection read_protection(const pugi::xml_node protection_node) xlnt::protection read_protection(xml::parser &parser)
{ {
xlnt::protection prot; xlnt::protection prot;
prot.locked(is_true(protection_node.attribute("locked").value())); for (auto event : parser)
prot.hidden(is_true(protection_node.attribute("hidden").value())); {
if (event == xml::parser::event_type::start_attribute)
{
if (parser.name() == "locked")
{
prot.locked(is_true(parser.value()));
}
else if (parser.name() == "hidden")
{
prot.hidden(is_true(parser.value()));
}
}
else
{
break;
}
}
return prot; return prot;
} }
xlnt::alignment read_alignment(const pugi::xml_node alignment_node) xlnt::alignment read_alignment(xml::parser &parser)
{ {
xlnt::alignment align; xlnt::alignment align;
/*
align.wrap(is_true(alignment_node.attribute("wrapText").value())); align.wrap(is_true(alignment_node.attribute("wrapText").value()));
align.shrink(is_true(alignment_node.attribute("shrinkToFit").value())); align.shrink(is_true(alignment_node.attribute("shrinkToFit").value()));
@ -250,14 +265,14 @@ xlnt::alignment read_alignment(const pugi::xml_node alignment_node)
std::string horizontal = alignment_node.attribute("horizontal").value(); std::string horizontal = alignment_node.attribute("horizontal").value();
align.horizontal(from_string<xlnt::horizontal_alignment>(horizontal)); align.horizontal(from_string<xlnt::horizontal_alignment>(horizontal));
} }
*/
return align; return align;
} }
void read_number_formats(const pugi::xml_node number_formats_node, std::vector<xlnt::number_format> &number_formats) void read_number_formats(xml::parser &parser, std::vector<xlnt::number_format> &number_formats)
{ {
number_formats.clear(); number_formats.clear();
/*
for (auto num_fmt_node : number_formats_node.children("numFmt")) for (auto num_fmt_node : number_formats_node.children("numFmt"))
{ {
std::string format_string(num_fmt_node.attribute("formatCode").value()); std::string format_string(num_fmt_node.attribute("formatCode").value());
@ -274,12 +289,13 @@ void read_number_formats(const pugi::xml_node number_formats_node, std::vector<x
number_formats.push_back(nf); number_formats.push_back(nf);
} }
*/
} }
xlnt::color read_color(const pugi::xml_node &color_node) xlnt::color read_color(xml::parser &parser)
{ {
xlnt::color result; xlnt::color result;
/*
if (color_node.attribute("auto")) if (color_node.attribute("auto"))
{ {
return result; return result;
@ -302,14 +318,14 @@ xlnt::color read_color(const pugi::xml_node &color_node)
{ {
result.set_tint(color_node.attribute("tint").as_double()); result.set_tint(color_node.attribute("tint").as_double());
} }
*/
return result; return result;
} }
xlnt::font read_font(const pugi::xml_node font_node) xlnt::font read_font(xml::parser &parser)
{ {
xlnt::font new_font; xlnt::font new_font;
/*
new_font.size(string_to_size_t(font_node.child("sz").attribute("val").value())); new_font.size(string_to_size_t(font_node.child("sz").attribute("val").value()));
new_font.name(font_node.child("name").attribute("val").value()); new_font.name(font_node.child("name").attribute("val").value());
@ -376,42 +392,46 @@ xlnt::font read_font(const pugi::xml_node font_node)
new_font.underline(xlnt::font::underline_style::single); new_font.underline(xlnt::font::underline_style::single);
} }
} }
*/
return new_font; return new_font;
} }
void read_fonts(const pugi::xml_node &fonts_node, std::vector<xlnt::font> &fonts) void read_fonts(xml::parser &parser, std::vector<xlnt::font> &fonts)
{ {
fonts.clear(); fonts.clear();
/*
for (auto font_node : fonts_node.children()) for (auto font_node : fonts_node.children())
{ {
fonts.push_back(read_font(font_node)); fonts.push_back(read_font(font_node));
} }
*/
} }
void read_indexed_colors(const pugi::xml_node &indexed_colors_node, std::vector<xlnt::color> &colors) void read_indexed_colors(xml::parser &parser, std::vector<xlnt::color> &colors)
{ {
/*
for (auto color_node : indexed_colors_node.children()) for (auto color_node : indexed_colors_node.children())
{ {
colors.push_back(read_color(color_node)); colors.push_back(read_color(color_node));
} }
*/
} }
void read_colors(const pugi::xml_node &colors_node, std::vector<xlnt::color> &colors) void read_colors(xml::parser &parser, std::vector<xlnt::color> &colors)
{ {
colors.clear(); colors.clear();
/*
if (colors_node.child("indexedColors")) if (colors_node.child("indexedColors"))
{ {
read_indexed_colors(colors_node.child("indexedColors"), colors); read_indexed_colors(colors_node.child("indexedColors"), colors);
} }
*/
} }
xlnt::fill read_fill(const pugi::xml_node &fill_node) xlnt::fill read_fill(xml::parser &parser)
{ {
xlnt::fill new_fill; xlnt::fill new_fill;
/*
if (fill_node.child("patternFill")) if (fill_node.child("patternFill"))
{ {
auto pattern_fill_node = fill_node.child("patternFill"); auto pattern_fill_node = fill_node.child("patternFill");
@ -462,25 +482,26 @@ xlnt::fill read_fill(const pugi::xml_node &fill_node)
new_fill = gradient; new_fill = gradient;
} }
*/
return new_fill; return new_fill;
} }
void read_fills(const pugi::xml_node &fills_node, std::vector<xlnt::fill> &fills) void read_fills(xml::parser &parser, std::vector<xlnt::fill> &fills)
{ {
fills.clear(); fills.clear();
/*
for (auto fill_node : fills_node.children()) for (auto fill_node : fills_node.children())
{ {
fills.emplace_back(); fills.emplace_back();
fills.back() = read_fill(fill_node); fills.back() = read_fill(fill_node);
} }
*/
} }
xlnt::border::border_property read_side(const pugi::xml_node &side_node) xlnt::border::border_property read_side(xml::parser &parser)
{ {
xlnt::border::border_property new_side; xlnt::border::border_property new_side;
/*
if (side_node.attribute("style")) if (side_node.attribute("style"))
{ {
new_side.style(from_string<xlnt::border_style>(side_node.attribute("style").value())); new_side.style(from_string<xlnt::border_style>(side_node.attribute("style").value()));
@ -490,14 +511,14 @@ xlnt::border::border_property read_side(const pugi::xml_node &side_node)
{ {
new_side.color(read_color(side_node.child("color"))); new_side.color(read_color(side_node.child("color")));
} }
*/
return new_side; return new_side;
} }
xlnt::border read_border(const pugi::xml_node &border_node) xlnt::border read_border(xml::parser &parser)
{ {
xlnt::border new_border; xlnt::border new_border;
/*
for (const auto &side : xlnt::border::all_sides()) for (const auto &side : xlnt::border::all_sides())
{ {
auto side_name = to_string(side); auto side_name = to_string(side);
@ -507,41 +528,53 @@ xlnt::border read_border(const pugi::xml_node &border_node)
new_border.side(side, read_side(border_node.child(side_name.c_str()))); new_border.side(side, read_side(border_node.child(side_name.c_str())));
} }
} }
*/
return new_border; return new_border;
} }
void read_borders(const pugi::xml_node &borders_node, std::vector<xlnt::border> &borders) void read_borders(xml::parser &parser, std::vector<xlnt::border> &borders)
{ {
borders.clear(); borders.clear();
/*
for (auto border_node : borders_node.children()) for (auto border_node : borders_node.children())
{ {
borders.push_back(read_border(border_node)); borders.push_back(read_border(border_node));
} }
*/
} }
std::vector<xlnt::relationship> read_relationships(const xlnt::path &part, xlnt::zip_file &archive) std::vector<xlnt::relationship> read_relationships(const xlnt::path &part, xlnt::zip_file &archive)
{ {
std::vector<xlnt::relationship> relationships; std::vector<xlnt::relationship> relationships;
if (!archive.has_file(part)) return relationships; if (!archive.has_file(part)) return relationships;
pugi::xml_document document; std::istringstream rels_stream(archive.read(part));
document.load_string(archive.read(part).c_str()); xml::parser parser(rels_stream, part.string());
auto root_node = document.child("Relationships");
xlnt::uri source(part.string()); xlnt::uri source(part.string());
for (auto relationship_node : root_node.children("Relationship")) const auto xmlns = xlnt::constants::get_namespace("relationships");
{ parser.next_expect(xml::parser::event_type::start_element, xmlns, "Relationships");
std::string id(relationship_node.attribute("Id").value()); parser.content(xml::content::complex);
std::string type_string(relationship_node.attribute("Type").value());
auto type = from_string<xlnt::relationship::type>(type_string);
xlnt::uri target(relationship_node.attribute("Target").value());
relationships.push_back(xlnt::relationship(id, type, source, target, xlnt::target_mode::internal)); while (true)
{
if (parser.peek() == xml::parser::event_type::end_element) break;
parser.next_expect(xml::parser::event_type::start_element, xmlns, "Relationship");
std::string id(parser.attribute("Id"));
std::string type_string(parser.attribute("Type"));
xlnt::uri target(parser.attribute("Target"));
relationships.emplace_back(id, from_string<xlnt::relationship::type>(type_string),
source, target, xlnt::target_mode::internal);
parser.next_expect(xml::parser::event_type::end_element,
xlnt::constants::get_namespace("relationships"), "Relationship");
} }
parser.next_expect(xml::parser::event_type::end_element, xmlns, "Relationships");
return relationships; return relationships;
} }
@ -594,56 +627,56 @@ void xlsx_consumer::populate_workbook()
for (const auto &rel : manifest.get_relationships(path("/"))) for (const auto &rel : manifest.get_relationships(path("/")))
{ {
pugi::xml_document document; std::istringstream parser_stream(source_.read(rel.get_target().get_path()));
document.load_string(source_.read(rel.get_target().get_path()).c_str()); xml::parser parser(parser_stream, rel.get_target().get_path().string());
switch (rel.get_type()) switch (rel.get_type())
{ {
case relationship::type::core_properties: case relationship::type::core_properties:
read_core_properties(document.root()); read_core_properties(parser);
break; break;
case relationship::type::extended_properties: case relationship::type::extended_properties:
read_extended_properties(document.root()); read_extended_properties(parser);
break; break;
case relationship::type::custom_properties: case relationship::type::custom_properties:
read_custom_property(document.root()); read_custom_property(parser);
break; break;
case relationship::type::office_document: case relationship::type::office_document:
check_document_type(manifest.get_content_type(rel.get_target().get_path())); check_document_type(manifest.get_content_type(rel.get_target().get_path()));
read_workbook(document.root()); read_workbook(parser);
break; break;
case relationship::type::calculation_chain: case relationship::type::calculation_chain:
read_calculation_chain(document.root()); read_calculation_chain(parser);
break; break;
case relationship::type::connections: case relationship::type::connections:
read_connections(document.root()); read_connections(parser);
break; break;
case relationship::type::custom_xml_mappings: case relationship::type::custom_xml_mappings:
read_custom_xml_mappings(document.root()); read_custom_xml_mappings(parser);
break; break;
case relationship::type::external_workbook_references: case relationship::type::external_workbook_references:
read_external_workbook_references(document.root()); read_external_workbook_references(parser);
break; break;
case relationship::type::metadata: case relationship::type::metadata:
read_metadata(document.root()); read_metadata(parser);
break; break;
case relationship::type::pivot_table: case relationship::type::pivot_table:
read_pivot_table(document.root()); read_pivot_table(parser);
break; break;
case relationship::type::shared_string_table: case relationship::type::shared_string_table:
read_shared_string_table(document.root()); read_shared_string_table(parser);
break; break;
case relationship::type::shared_workbook_revision_headers: case relationship::type::shared_workbook_revision_headers:
read_shared_workbook_revision_headers(document.root()); read_shared_workbook_revision_headers(parser);
break; break;
case relationship::type::styles: case relationship::type::styles:
read_stylesheet(document.root()); read_stylesheet(parser);
break; break;
case relationship::type::theme: case relationship::type::theme:
read_theme(document.root()); read_theme(parser);
break; break;
case relationship::type::volatile_dependencies: case relationship::type::volatile_dependencies:
read_volatile_dependencies(document.root()); read_volatile_dependencies(parser);
break; break;
default: default:
break; break;
@ -656,20 +689,20 @@ void xlsx_consumer::populate_workbook()
for (const auto &rel : manifest.get_relationships(workbook_rel.get_target().get_path())) for (const auto &rel : manifest.get_relationships(workbook_rel.get_target().get_path()))
{ {
pugi::xml_document document;
path part_path(rel.get_source().get_path().parent().append(rel.get_target().get_path())); path part_path(rel.get_source().get_path().parent().append(rel.get_target().get_path()));
document.load_string(source_.read(part_path).c_str()); std::istringstream parser_stream(source_.read(part_path));
xml::parser parser(parser_stream, rel.get_target().get_path().string());
switch (rel.get_type()) switch (rel.get_type())
{ {
case relationship::type::shared_string_table: case relationship::type::shared_string_table:
read_shared_string_table(document); read_shared_string_table(parser);
break; break;
case relationship::type::styles: case relationship::type::styles:
read_stylesheet(document); read_stylesheet(parser);
break; break;
case relationship::type::theme: case relationship::type::theme:
read_theme(document); read_theme(parser);
break; break;
default: default:
break; break;
@ -679,21 +712,21 @@ void xlsx_consumer::populate_workbook()
// Second pass, read sheets themselves // Second pass, read sheets themselves
for (const auto &rel : manifest.get_relationships(workbook_rel.get_target().get_path())) for (const auto &rel : manifest.get_relationships(workbook_rel.get_target().get_path()))
{ {
pugi::xml_document document;
path part_path(rel.get_source().get_path().parent().append(rel.get_target().get_path())); path part_path(rel.get_source().get_path().parent().append(rel.get_target().get_path()));
document.load_string(source_.read(part_path).c_str()); std::istringstream parser_stream(source_.read(part_path));
xml::parser parser(parser_stream, rel.get_target().get_path().string());
switch (rel.get_type()) switch (rel.get_type())
{ {
case relationship::type::chartsheet: case relationship::type::chartsheet:
read_chartsheet(document.root(), rel.get_id()); read_chartsheet(rel.get_id(), parser);
break; break;
case relationship::type::dialogsheet: case relationship::type::dialogsheet:
read_dialogsheet(document.root(), rel.get_id()); read_dialogsheet(rel.get_id(), parser);
break; break;
case relationship::type::worksheet: case relationship::type::worksheet:
read_worksheet(document.root(), rel.get_id()); read_worksheet(rel.get_id(), parser);
break; break;
default: default:
break; break;
@ -714,25 +747,36 @@ void xlsx_consumer::read_manifest()
if (!source_.has_file(package_rels_path)) throw invalid_file("missing package rels"); if (!source_.has_file(package_rels_path)) throw invalid_file("missing package rels");
auto package_rels = read_relationships(package_rels_path, source_); auto package_rels = read_relationships(package_rels_path, source_);
pugi::xml_document document; std::istringstream parser_stream(source_.read(path("[Content_Types].xml")));
document.load_string(source_.read(path("[Content_Types].xml")).c_str()); xml::parser parser(parser_stream, "[Content_Types].xml");
const auto root_node = document.child("Types");
auto &manifest = destination_.get_manifest(); auto &manifest = destination_.get_manifest();
const std::string xmlns = "http://schemas.openxmlformats.org/package/2006/content-types";
parser.next_expect(xml::parser::event_type::start_element, xmlns, "Types");
parser.content(xml::content::complex);
for (const auto child : root_node.children()) while (true)
{ {
if (child.name() == std::string("Default")) if (parser.peek() == xml::parser::event_type::end_element) break;
{
manifest.register_default_type(child.attribute("Extension").value(), parser.next_expect(xml::parser::event_type::start_element);
child.attribute("ContentType").value());
} if (parser.name() == "Default")
else if (child.name() == std::string("Override")) {
{ manifest.register_default_type(parser.attribute("Extension"),
path part(child.attribute("PartName").value()); parser.attribute("ContentType"));
manifest.register_override_type(part, child.attribute("ContentType").value()); parser.next_expect(xml::parser::event_type::end_element, xmlns, "Default");
} }
else if (parser.name() == "Override")
{
manifest.register_override_type(path(parser.attribute("PartName")),
parser.attribute("ContentType"));
parser.next_expect(xml::parser::event_type::end_element, xmlns, "Override");
}
} }
parser.next_expect(xml::parser::event_type::end_element, xmlns, "Types");
for (const auto &package_rel : package_rels) for (const auto &package_rel : package_rels)
{ {
@ -765,8 +809,9 @@ void xlsx_consumer::read_manifest()
} }
} }
void xlsx_consumer::read_extended_properties(const pugi::xml_node root) void xlsx_consumer::read_extended_properties(xml::parser &parser)
{ {
/*
for (auto property_node : root.child("Properties")) for (auto property_node : root.child("Properties"))
{ {
std::string name(property_node.name()); std::string name(property_node.name());
@ -781,10 +826,12 @@ void xlsx_consumer::read_extended_properties(const pugi::xml_node root)
else if (name == "AppVersion") destination_.set_app_version(value); else if (name == "AppVersion") destination_.set_app_version(value);
else if (name == "Application") destination_.set_application(value); else if (name == "Application") destination_.set_application(value);
} }
*/
} }
void xlsx_consumer::read_core_properties(const pugi::xml_node root) void xlsx_consumer::read_core_properties(xml::parser &parser)
{ {
/*
for (auto property_node : root.child("cp:coreProperties")) for (auto property_node : root.child("cp:coreProperties"))
{ {
std::string name(property_node.name()); std::string name(property_node.name());
@ -795,19 +842,23 @@ void xlsx_consumer::read_core_properties(const pugi::xml_node root)
else if (name == "dcterms:created") destination_.set_created(w3cdtf_to_datetime(value)); else if (name == "dcterms:created") destination_.set_created(w3cdtf_to_datetime(value));
else if (name == "dcterms:modified") destination_.set_modified(w3cdtf_to_datetime(value)); else if (name == "dcterms:modified") destination_.set_modified(w3cdtf_to_datetime(value));
} }
*/
} }
void xlsx_consumer::read_custom_file_properties(const pugi::xml_node root) void xlsx_consumer::read_custom_file_properties(xml::parser &parser)
{ {
/*
pugi::xml_document document; pugi::xml_document document;
document.load_string(source_.read(path("[Content Types].xml")).c_str()); document.load_string(source_.read(path("[Content Types].xml")).c_str());
/*auto root_node = */document.append_child("customFileProperties"); document.append_child("customFileProperties");
*/
} }
// Write SpreadsheetML-Specific Package Parts // Write SpreadsheetML-Specific Package Parts
void xlsx_consumer::read_workbook(const pugi::xml_node root) void xlsx_consumer::read_workbook(xml::parser &parser)
{ {
/*
auto workbook_node = root.child("workbook"); auto workbook_node = root.child("workbook");
if (workbook_node.attribute("xmlns:x15")) if (workbook_node.attribute("xmlns:x15"))
@ -887,72 +938,90 @@ void xlsx_consumer::read_workbook(const pugi::xml_node root)
{ {
destination_.d_->has_arch_id_ = true; destination_.d_->has_arch_id_ = true;
} }
*/
} }
// Write Workbook Relationship Target Parts // Write Workbook Relationship Target Parts
void xlsx_consumer::read_calculation_chain(const pugi::xml_node root) void xlsx_consumer::read_calculation_chain(xml::parser &parser)
{ {
} }
void xlsx_consumer::read_chartsheet(const pugi::xml_node root, const std::string &title) void xlsx_consumer::read_chartsheet(const std::string &title, xml::parser &parser)
{ {
/*
pugi::xml_document document; pugi::xml_document document;
document.load_string(source_.read(path("[Content Types].xml")).c_str()); document.load_string(source_.read(path("[Content Types].xml")).c_str());
/*auto root_node = */ document.append_child("chartsheet"); document.append_child("chartsheet");
*/
} }
void xlsx_consumer::read_connections(const pugi::xml_node root) void xlsx_consumer::read_connections(xml::parser &parser)
{ {
/*
pugi::xml_document document; pugi::xml_document document;
document.load_string(source_.read(path("[Content Types].xml")).c_str()); document.load_string(source_.read(path("[Content Types].xml")).c_str());
/*auto root_node = */ document.append_child("connections"); document.append_child("connections");
*/
} }
void xlsx_consumer::read_custom_property(const pugi::xml_node root) void xlsx_consumer::read_custom_property(xml::parser &parser)
{ {
/*
pugi::xml_document document; pugi::xml_document document;
document.load_string(source_.read(path("[Content Types].xml")).c_str()); document.load_string(source_.read(path("[Content Types].xml")).c_str());
/*auto root_node = */ document.append_child("customProperty"); document.append_child("customProperty");
*/
} }
void xlsx_consumer::read_custom_xml_mappings(const pugi::xml_node root) void xlsx_consumer::read_custom_xml_mappings(xml::parser &parser)
{ {
/*
pugi::xml_document document; pugi::xml_document document;
document.load_string(source_.read(path("[Content Types].xml")).c_str()); document.load_string(source_.read(path("[Content Types].xml")).c_str());
/*auto root_node = */ document.append_child("connections"); document.append_child("connections");
*/
} }
void xlsx_consumer::read_dialogsheet(const pugi::xml_node root, const std::string &title) void xlsx_consumer::read_dialogsheet(const std::string &title, xml::parser &parser)
{ {
/*
pugi::xml_document document; pugi::xml_document document;
document.load_string(source_.read(path("[Content Types].xml")).c_str()); document.load_string(source_.read(path("[Content Types].xml")).c_str());
/*auto root_node = */ document.append_child("dialogsheet"); document.append_child("dialogsheet");
*/
} }
void xlsx_consumer::read_external_workbook_references(const pugi::xml_node root) void xlsx_consumer::read_external_workbook_references(xml::parser &parser)
{ {
/*
pugi::xml_document document; pugi::xml_document document;
document.load_string(source_.read(path("[Content Types].xml")).c_str()); document.load_string(source_.read(path("[Content Types].xml")).c_str());
/*auto root_node = */ document.append_child("externalLink"); document.append_child("externalLink");
*/
} }
void xlsx_consumer::read_metadata(const pugi::xml_node root) void xlsx_consumer::read_metadata(xml::parser &parser)
{ {
/*
pugi::xml_document document; pugi::xml_document document;
document.load_string(source_.read(path("[Content Types].xml")).c_str()); document.load_string(source_.read(path("[Content Types].xml")).c_str());
/*auto root_node = */ document.append_child("metadata"); document.append_child("metadata");
*/
} }
void xlsx_consumer::read_pivot_table(const pugi::xml_node root) void xlsx_consumer::read_pivot_table(xml::parser &parser)
{ {
/*
pugi::xml_document document; pugi::xml_document document;
document.load_string(source_.read(path("[Content Types].xml")).c_str()); document.load_string(source_.read(path("[Content Types].xml")).c_str());
/*auto root_node = */ document.append_child("pivotTableDefinition"); document.append_child("pivotTableDefinition");
*/
} }
void xlsx_consumer::read_shared_string_table(const pugi::xml_node root) void xlsx_consumer::read_shared_string_table(xml::parser &parser)
{ {
/*
auto sst_node = root.child("sst"); auto sst_node = root.child("sst");
std::size_t unique_count = 0; std::size_t unique_count = 0;
@ -1025,31 +1094,39 @@ void xlsx_consumer::read_shared_string_table(const pugi::xml_node root)
{ {
throw invalid_file("sizes don't match"); throw invalid_file("sizes don't match");
} }
*/
} }
void xlsx_consumer::read_shared_workbook_revision_headers(const pugi::xml_node root) void xlsx_consumer::read_shared_workbook_revision_headers(xml::parser &parser)
{ {
/*
pugi::xml_document document; pugi::xml_document document;
document.load_string(source_.read(path("[Content Types].xml")).c_str()); document.load_string(source_.read(path("[Content Types].xml")).c_str());
/*auto root_node = */ document.append_child("headers"); document.append_child("headers");
*/
} }
void xlsx_consumer::read_shared_workbook(const pugi::xml_node root) void xlsx_consumer::read_shared_workbook(xml::parser &parser)
{ {
/*
pugi::xml_document document; pugi::xml_document document;
document.load_string(source_.read(path("[Content Types].xml")).c_str()); document.load_string(source_.read(path("[Content Types].xml")).c_str());
/*auto root_node = */ document.append_child("revisions"); document.append_child("revisions");
*/
} }
void xlsx_consumer::read_shared_workbook_user_data(const pugi::xml_node root) void xlsx_consumer::read_shared_workbook_user_data(xml::parser &parser)
{ {
/*
pugi::xml_document document; pugi::xml_document document;
document.load_string(source_.read(path("[Content Types].xml")).c_str()); document.load_string(source_.read(path("[Content Types].xml")).c_str());
/*auto root_node = */ document.append_child("users"); document.append_child("users");
*/
} }
void xlsx_consumer::read_stylesheet(const pugi::xml_node root) void xlsx_consumer::read_stylesheet(xml::parser &parser)
{ {
/*
auto stylesheet_node = root.child("styleSheet"); auto stylesheet_node = root.child("styleSheet");
auto &stylesheet = destination_.impl().stylesheet_; auto &stylesheet = destination_.impl().stylesheet_;
@ -1192,23 +1269,29 @@ void xlsx_consumer::read_stylesheet(const pugi::xml_node root)
format.style(stylesheet.get_style(style_name)); format.style(stylesheet.get_style(style_name));
} }
} }
*/
} }
void xlsx_consumer::read_theme(const pugi::xml_node root) void xlsx_consumer::read_theme(xml::parser &parser)
{ {
/*
root.child("theme"); root.child("theme");
destination_.set_theme(theme()); destination_.set_theme(theme());
*/
} }
void xlsx_consumer::read_volatile_dependencies(const pugi::xml_node root) void xlsx_consumer::read_volatile_dependencies(xml::parser &parser)
{ {
/*
pugi::xml_document document; pugi::xml_document document;
document.load_string(source_.read(path("[Content Types].xml")).c_str()); document.load_string(source_.read(path("[Content Types].xml")).c_str());
/*auto root_node = */ document.append_child("volTypes"); document.append_child("volTypes");
*/
} }
void xlsx_consumer::read_worksheet(const pugi::xml_node root, const std::string &rel_id) void xlsx_consumer::read_worksheet(const std::string &title, xml::parser &parser)
{ {
/*
auto title = std::find_if(destination_.d_->sheet_title_rel_id_map_.begin(), auto title = std::find_if(destination_.d_->sheet_title_rel_id_map_.begin(),
destination_.d_->sheet_title_rel_id_map_.end(), destination_.d_->sheet_title_rel_id_map_.end(),
[&](const std::pair<std::string, std::string> &p) [&](const std::pair<std::string, std::string> &p)
@ -1425,38 +1508,47 @@ void xlsx_consumer::read_worksheet(const pugi::xml_node root, const std::string
ws.set_page_margins(margins); ws.set_page_margins(margins);
} }
*/
} }
// Sheet Relationship Target Parts // Sheet Relationship Target Parts
void xlsx_consumer::read_comments(const pugi::xml_node root) void xlsx_consumer::read_comments(xml::parser &parser)
{ {
/*
pugi::xml_document document; pugi::xml_document document;
document.load_string(source_.read(path("[Content Types].xml")).c_str()); document.load_string(source_.read(path("[Content Types].xml")).c_str());
/*auto root_node = */ document.append_child("comments"); document.append_child("comments");
*/
} }
void xlsx_consumer::read_drawings(const pugi::xml_node root) void xlsx_consumer::read_drawings(xml::parser &parser)
{ {
/*
pugi::xml_document document; pugi::xml_document document;
document.load_string(source_.read(path("[Content Types].xml")).c_str()); document.load_string(source_.read(path("[Content Types].xml")).c_str());
/*auto root_node = */ document.append_child("wsDr"); document.append_child("wsDr");
*/
} }
// Unknown Parts // Unknown Parts
void xlsx_consumer::read_unknown_parts(const pugi::xml_node root) void xlsx_consumer::read_unknown_parts(xml::parser &parser)
{ {
/*
pugi::xml_document document; pugi::xml_document document;
document.load_string(source_.read(path("[Content Types].xml")).c_str()); document.load_string(source_.read(path("[Content Types].xml")).c_str());
/*auto root_node = */ document.append_child("Hmm"); document.append_child("Hmm");
*/
} }
void xlsx_consumer::read_unknown_relationships(const pugi::xml_node root) void xlsx_consumer::read_unknown_relationships(xml::parser &parser)
{ {
/*
pugi::xml_document document; pugi::xml_document document;
document.load_string(source_.read(path("[Content Types].xml")).c_str()); document.load_string(source_.read(path("[Content Types].xml")).c_str());
/*auto root_node = */ document.append_child("Relationships"); document.append_child("Relationships");
*/
} }
} // namespace detail } // namespace detail

View File

@ -28,7 +28,7 @@
#include <unordered_map> #include <unordered_map>
#include <vector> #include <vector>
#include <detail/include_pugixml.hpp> #include <detail/include_libstudxml.hpp>
#include <xlnt/xlnt_config.hpp> #include <xlnt/xlnt_config.hpp>
#include <xlnt/packaging/zip_file.hpp> #include <xlnt/packaging/zip_file.hpp>
@ -65,44 +65,44 @@ private:
void read_manifest(); void read_manifest();
void read_core_properties(const pugi::xml_node root); void read_core_properties(xml::parser &parser);
void read_extended_properties(const pugi::xml_node root); void read_extended_properties(xml::parser &parser);
void read_custom_file_properties(const pugi::xml_node root); void read_custom_file_properties(xml::parser &parser);
// SpreadsheetML-Specific Package Parts // SpreadsheetML-Specific Package Parts
void read_workbook(const pugi::xml_node root); void read_workbook(xml::parser &parser);
// Workbook Relationship Target Parts // Workbook Relationship Target Parts
void read_calculation_chain(const pugi::xml_node root); void read_calculation_chain(xml::parser &parser);
void read_connections(const pugi::xml_node root); void read_connections(xml::parser &parser);
void read_custom_property(const pugi::xml_node root); void read_custom_property(xml::parser &parser);
void read_custom_xml_mappings(const pugi::xml_node root); void read_custom_xml_mappings(xml::parser &parser);
void read_external_workbook_references(const pugi::xml_node root); void read_external_workbook_references(xml::parser &parser);
void read_metadata(const pugi::xml_node root); void read_metadata(xml::parser &parser);
void read_pivot_table(const pugi::xml_node root); void read_pivot_table(xml::parser &parser);
void read_shared_string_table(const pugi::xml_node root); void read_shared_string_table(xml::parser &parser);
void read_shared_workbook_revision_headers(const pugi::xml_node root); void read_shared_workbook_revision_headers(xml::parser &parser);
void read_shared_workbook(const pugi::xml_node root); void read_shared_workbook(xml::parser &parser);
void read_shared_workbook_user_data(const pugi::xml_node root); void read_shared_workbook_user_data(xml::parser &parser);
void read_stylesheet(const pugi::xml_node root); void read_stylesheet(xml::parser &parser);
void read_theme(const pugi::xml_node root); void read_theme(xml::parser &parser);
void read_volatile_dependencies(const pugi::xml_node root); void read_volatile_dependencies(xml::parser &parser);
void read_chartsheet(const pugi::xml_node root, const std::string &title); void read_chartsheet(const std::string &title, xml::parser &parser);
void read_dialogsheet(const pugi::xml_node root, const std::string &title); void read_dialogsheet(const std::string &title, xml::parser &parser);
void read_worksheet(const pugi::xml_node root, const std::string &title); void read_worksheet(const std::string &title, xml::parser &parser);
// Sheet Relationship Target Parts // Sheet Relationship Target Parts
void read_comments(const pugi::xml_node root); void read_comments(xml::parser &parser);
void read_drawings(const pugi::xml_node root); void read_drawings(xml::parser &parser);
// Unknown Parts // Unknown Parts
void read_unknown_parts(const pugi::xml_node root); void read_unknown_parts(xml::parser &parser);
void read_unknown_relationships(const pugi::xml_node root); void read_unknown_relationships(xml::parser &parser);
/// <summary> /// <summary>
/// A reference to the archive from which files representing the workbook /// A reference to the archive from which files representing the workbook

View File

@ -2,7 +2,6 @@
#include <detail/xlsx_producer.hpp> #include <detail/xlsx_producer.hpp>
#include <detail/constants.hpp> #include <detail/constants.hpp>
#include <detail/include_pugixml.hpp>
#include <detail/workbook_impl.hpp> #include <detail/workbook_impl.hpp>
#include <xlnt/cell/cell.hpp> #include <xlnt/cell/cell.hpp>
#include <xlnt/utils/path.hpp> #include <xlnt/utils/path.hpp>
@ -23,17 +22,6 @@ bool is_integral(long double d)
return d == static_cast<long long int>(d); return d == static_cast<long long int>(d);
} }
/// <summary>
/// Serializes document and writes to to the archive at archive_path.
/// </summary>
void write_document_to_archive(const pugi::xml_document &document,
const xlnt::path &archive_path, xlnt::zip_file &archive)
{
std::ostringstream out_stream;
document.save(out_stream);
archive.write_string(out_stream.str(), archive_path);
}
std::string fill(const std::string &string, std::size_t length = 2) std::string fill(const std::string &string, std::size_t length = 2)
{ {
if (string.size() >= length) if (string.size() >= length)
@ -195,78 +183,78 @@ std::string to_string(xlnt::border_side side)
} }
} }
void write_relationships(const std::vector<xlnt::relationship> &relationships, pugi::xml_node root) void write_relationships(const std::vector<xlnt::relationship> &relationships, xml::serializer &serializer)
{ {
auto relationships_node = root.append_child("Relationships"); const auto xmlns = xlnt::constants::get_namespace("relationships");
relationships_node.append_attribute("xmlns").set_value(xlnt::constants::get_namespace("relationships").c_str());
serializer.start_element(xmlns, "Relationships");
serializer.namespace_decl(xmlns, "");
for (const auto &relationship : relationships) for (const auto &relationship : relationships)
{ {
auto relationship_node = relationships_node.append_child("Relationship"); serializer.start_element(xmlns, "Relationship");
relationship_node.append_attribute("Id").set_value(relationship.get_id().c_str()); serializer.attribute("Id", relationship.get_id());
relationship_node.append_attribute("Type").set_value(to_string(relationship.get_type()).c_str()); serializer.attribute("Type", to_string(relationship.get_type()));
relationship_node.append_attribute("Target").set_value(relationship.get_target().get_path().string().c_str()); serializer.attribute("Target", relationship.get_target().get_path().string());
if (relationship.get_target_mode() == xlnt::target_mode::external) if (relationship.get_target_mode() == xlnt::target_mode::external)
{ {
relationship_node.append_attribute("TargetMode").set_value("External"); serializer.attribute("TargetMode", "External");
} }
serializer.end_element(xmlns, "Relationship");
} }
serializer.end_element(xmlns, "Relationships");
} }
bool write_color(const xlnt::color &color, pugi::xml_node color_node) bool write_color(const xlnt::color &color, xml::serializer &serializer)
{ {
switch (color.get_type()) switch (color.get_type())
{ {
case xlnt::color::type::theme: case xlnt::color::type::theme:
color_node.append_attribute("theme") serializer.attribute("theme", std::to_string(color.get_theme().get_index()));
.set_value(std::to_string(color.get_theme().get_index()).c_str());
break; break;
case xlnt::color::type::indexed: case xlnt::color::type::indexed:
color_node.append_attribute("indexed") serializer.attribute("indexed", std::to_string(color.get_indexed().get_index()));
.set_value(std::to_string(color.get_indexed().get_index()).c_str());
break; break;
case xlnt::color::type::rgb: case xlnt::color::type::rgb:
default: default:
color_node.append_attribute("rgb") serializer.attribute("rgb", color.get_rgb().get_hex_string());
.set_value(color.get_rgb().get_hex_string().c_str());
break; break;
} }
return true; return true;
} }
bool write_dxfs(pugi::xml_node &dxfs_node) void write_dxfs(xml::serializer &serializer)
{ {
dxfs_node.append_attribute("count").set_value("0"); serializer.attribute("count", "0");
return true;
} }
bool write_table_styles(pugi::xml_node &table_styles_node) void write_table_styles(xml::serializer &serializer)
{ {
table_styles_node.append_attribute("count").set_value("0"); serializer.attribute("count", "0");
table_styles_node.append_attribute("defaultTableStyle").set_value("TableStyleMedium9"); serializer.attribute("defaultTableStyle", "TableStyleMedium9");
table_styles_node.append_attribute("defaultPivotStyle").set_value("PivotStyleMedium7"); serializer.attribute("defaultPivotStyle", "PivotStyleMedium7");
return true;
} }
bool write_colors(const std::vector<xlnt::color> &colors, pugi::xml_node &colors_node) void write_colors(const std::vector<xlnt::color> &colors, xml::serializer &serializer)
{ {
auto indexed_colors_node = colors_node.append_child("indexedColors"); serializer.start_element("indexedColors");
for (auto &c : colors) for (auto &c : colors)
{ {
auto rgb_color_node = indexed_colors_node.append_child("rgbColor"); serializer.start_element("rgbColor");
auto rgb_attribute = rgb_color_node.append_attribute("rgb"); serializer.attribute("rgb", c.get_rgb().get_hex_string());
rgb_attribute.set_value(c.get_rgb().get_hex_string().c_str()); serializer.end_element();
} }
return true; serializer.end_element();
} }
} // namespace } // namespace
@ -304,25 +292,27 @@ void xlsx_producer::populate_archive()
for (auto &rel : source_.impl().manifest_.get_relationships(path("/"))) for (auto &rel : source_.impl().manifest_.get_relationships(path("/")))
{ {
pugi::xml_document document; std::ostringstream serializer_stream;
xml::serializer serializer(serializer_stream, rel.get_target().get_path().string());
bool write_document = true; bool write_document = true;
switch (rel.get_type()) switch (rel.get_type())
{ {
case relationship::type::core_properties: case relationship::type::core_properties:
write_core_properties(rel, document.root()); write_core_properties(rel, serializer);
break; break;
case relationship::type::extended_properties: case relationship::type::extended_properties:
write_extended_properties(rel, document.root()); write_extended_properties(rel, serializer);
break; break;
case relationship::type::custom_properties: case relationship::type::custom_properties:
write_custom_properties(rel, document.root()); write_custom_properties(rel, serializer);
break; break;
case relationship::type::office_document: case relationship::type::office_document:
write_workbook(rel, document.root()); write_workbook(rel, serializer);
break; break;
case relationship::type::thumbnail: case relationship::type::thumbnail:
@ -336,7 +326,7 @@ void xlsx_producer::populate_archive()
if (write_document) if (write_document)
{ {
write_document_to_archive(document, rel.get_target().get_path(), destination_); destination_.write_string(serializer_stream.str(), rel.get_target().get_path());
} }
} }
@ -350,26 +340,33 @@ void xlsx_producer::populate_archive()
void xlsx_producer::write_manifest() void xlsx_producer::write_manifest()
{ {
pugi::xml_document content_types_document; std::ostringstream content_types_stream;
xml::serializer content_types_serializer(content_types_stream, "[Content_Types].xml");
auto types_node = content_types_document.append_child("Types"); const auto xmlns = std::string("http://schemas.openxmlformats.org/package/2006/content-types");
types_node.append_attribute("xmlns").set_value("http://schemas.openxmlformats.org/package/2006/content-types");
content_types_serializer.start_element(xmlns, "Types");
content_types_serializer.namespace_decl(xmlns, "");
for (const auto &extension : source_.get_manifest().get_extensions_with_default_types()) for (const auto &extension : source_.get_manifest().get_extensions_with_default_types())
{ {
auto default_node = types_node.append_child("Default"); content_types_serializer.start_element(xmlns, "Default");
default_node.append_attribute("Extension").set_value(extension.c_str()); content_types_serializer.attribute("Extension", extension);
auto content_type = source_.get_manifest().get_default_type(extension); content_types_serializer.attribute("ContentType",
default_node.append_attribute("ContentType").set_value(content_type.c_str()); source_.get_manifest().get_default_type(extension));
content_types_serializer.end_element(xmlns, "Default");
} }
for (const auto &part : source_.get_manifest().get_parts_with_overriden_types()) for (const auto &part : source_.get_manifest().get_parts_with_overriden_types())
{ {
auto override_node = types_node.append_child("Override"); content_types_serializer.start_element(xmlns, "Override");
override_node.append_attribute("PartName").set_value(part.resolve(path("/")).string().c_str()); content_types_serializer.attribute("PartName", part.resolve(path("/")).string());
auto content_type = source_.get_manifest().get_override_type(part); content_types_serializer.attribute("ContentType",
override_node.append_attribute("ContentType").set_value(content_type.c_str()); source_.get_manifest().get_override_type(part));
content_types_serializer.end_element(xmlns, "Override");
} }
content_types_serializer.end_element(xmlns, "Types");
for (const auto &part : source_.get_manifest().get_parts()) for (const auto &part : source_.get_manifest().get_parts())
{ {
@ -377,8 +374,6 @@ void xlsx_producer::write_manifest()
if (part_rels.empty()) continue; if (part_rels.empty()) continue;
pugi::xml_document part_rels_document;
write_relationships(part_rels, part_rels_document.root());
path parent = part.parent(); path parent = part.parent();
if (parent.is_absolute()) if (parent.is_absolute())
@ -386,24 +381,29 @@ void xlsx_producer::write_manifest()
parent = path(parent.string().substr(1)); parent = path(parent.string().substr(1));
} }
std::ostringstream rels_stream;
path rels_path(parent.append("_rels").append(part.filename() + ".rels").string()); path rels_path(parent.append("_rels").append(part.filename() + ".rels").string());
write_document_to_archive(part_rels_document, rels_path, destination_); xml::serializer rels_serializer(rels_stream, rels_path.string());
write_relationships(part_rels, rels_serializer);
destination_.write_string(rels_stream.str(), rels_path);
} }
write_document_to_archive(content_types_document, path("[Content_Types].xml"), destination_); destination_.write_string(content_types_stream.str(), path("[Content_Types].xml"));
} }
void xlsx_producer::write_extended_properties(const relationship &rel, pugi::xml_node root) void xlsx_producer::write_extended_properties(const relationship &rel, xml::serializer &serializer)
{ {
auto properties_node = root.append_child("Properties"); serializer.start_element("Properties");
properties_node.append_attribute("xmlns").set_value("http://schemas.openxmlformats.org/officeDocument/2006/extended-properties"); serializer.namespace_decl("http://schemas.openxmlformats.org/officeDocument/2006/extended-properties", "xmlns");
properties_node.append_attribute("xmlns:vt").set_value("http://schemas.openxmlformats.org/officeDocument/2006/docPropsVTypes"); serializer.namespace_decl("http://schemas.openxmlformats.org/officeDocument/2006/docPropsVTypes", "vt");
properties_node.append_child("Application").text().set(source_.get_application().c_str());
properties_node.append_child("DocSecurity").text().set(std::to_string(source_.get_doc_security()).c_str());
properties_node.append_child("ScaleCrop").text().set(source_.get_scale_crop() ? "true" : "false");
serializer.element("Application", source_.get_application());
serializer.element("DocSecurity", std::to_string(source_.get_doc_security()));
serializer.element("ScaleCrop", source_.get_scale_crop() ? "true" : "false");
/*
auto heading_pairs_node = properties_node.append_child("HeadingPairs"); auto heading_pairs_node = properties_node.append_child("HeadingPairs");
auto heading_pairs_vector_node = heading_pairs_node.append_child("vt:vector"); auto heading_pairs_vector_node = heading_pairs_node.append_child("vt:vector");
heading_pairs_vector_node.append_attribute("size").set_value("2"); heading_pairs_vector_node.append_attribute("size").set_value("2");
@ -434,10 +434,12 @@ void xlsx_producer::write_extended_properties(const relationship &rel, pugi::xml
properties_node.append_child("SharedDoc").text().set(source_.is_shared_doc() ? "true" : "false"); properties_node.append_child("SharedDoc").text().set(source_.is_shared_doc() ? "true" : "false");
properties_node.append_child("HyperlinksChanged").text().set(source_.hyperlinks_changed() ? "true" : "false"); properties_node.append_child("HyperlinksChanged").text().set(source_.hyperlinks_changed() ? "true" : "false");
properties_node.append_child("AppVersion").text().set(source_.get_app_version().c_str()); properties_node.append_child("AppVersion").text().set(source_.get_app_version().c_str());
*/
} }
void xlsx_producer::write_core_properties(const relationship &rel, pugi::xml_node root) void xlsx_producer::write_core_properties(const relationship &rel, xml::serializer &serializer)
{ {
/*
auto core_properties_node = root.append_child("cp:coreProperties"); auto core_properties_node = root.append_child("cp:coreProperties");
core_properties_node.append_attribute("xmlns:cp").set_value("http://schemas.openxmlformats.org/package/2006/metadata/core-properties"); core_properties_node.append_attribute("xmlns:cp").set_value("http://schemas.openxmlformats.org/package/2006/metadata/core-properties");
@ -457,7 +459,7 @@ void xlsx_producer::write_core_properties(const relationship &rel, pugi::xml_nod
{ {
core_properties_node.append_child("dc:title").text().set(source_.get_title().c_str()); core_properties_node.append_child("dc:title").text().set(source_.get_title().c_str());
} }
*/
/* /*
core_properties_node.append_child("dc:description"); core_properties_node.append_child("dc:description");
core_properties_node.append_child("dc:subject"); core_properties_node.append_child("dc:subject");
@ -466,14 +468,14 @@ void xlsx_producer::write_core_properties(const relationship &rel, pugi::xml_nod
*/ */
} }
void xlsx_producer::write_custom_properties(const relationship &rel, pugi::xml_node root) void xlsx_producer::write_custom_properties(const relationship &rel, xml::serializer &serializer)
{ {
/*auto properties_node = */root.append_child("Properties"); serializer.element("Properties");
} }
// Write SpreadsheetML-Specific Package Parts // Write SpreadsheetML-Specific Package Parts
void xlsx_producer::write_workbook(const relationship &rel, pugi::xml_node root) void xlsx_producer::write_workbook(const relationship &rel, xml::serializer &serializer)
{ {
std::size_t num_visible = 0; std::size_t num_visible = 0;
bool any_defined_names = false; bool any_defined_names = false;
@ -496,18 +498,19 @@ void xlsx_producer::write_workbook(const relationship &rel, pugi::xml_node root)
throw no_visible_worksheets(); throw no_visible_worksheets();
} }
auto workbook_node = root.append_child("workbook"); const auto xmlns = std::string("http://schemas.openxmlformats.org/spreadsheetml/2006/main");
workbook_node.append_attribute("xmlns").set_value("http://schemas.openxmlformats.org/spreadsheetml/2006/main"); serializer.start_element(xmlns, "workbook");
workbook_node.append_attribute("xmlns:r").set_value("http://schemas.openxmlformats.org/officeDocument/2006/relationships"); serializer.namespace_decl(xmlns, "");
serializer.namespace_decl("http://schemas.openxmlformats.org/officeDocument/2006/relationships", "r");
if (source_.x15_enabled()) if (source_.x15_enabled())
{ {
workbook_node.append_attribute("xmlns:mc").set_value("http://schemas.openxmlformats.org/markup-compatibility/2006"); serializer.namespace_decl("http://schemas.openxmlformats.org/markup-compatibility/2006", "mc");
workbook_node.append_attribute("mc:Ignorable").set_value("x15"); serializer.attribute("mc:Ignorable", "x15");
workbook_node.append_attribute("xmlns:x15").set_value("http://schemas.microsoft.com/office/spreadsheetml/2010/11/main"); serializer.namespace_decl("http://schemas.microsoft.com/office/spreadsheetml/2010/11/main", "x15");
} }
/*
if (source_.has_file_version()) if (source_.has_file_version())
{ {
auto file_version_node = workbook_node.append_child("fileVersion"); auto file_version_node = workbook_node.append_child("fileVersion");
@ -527,10 +530,8 @@ void xlsx_producer::write_workbook(const relationship &rel, pugi::xml_node root)
workbook_pr_node.append_attribute("codeName").set_value(source_.get_code_name().c_str()); workbook_pr_node.append_attribute("codeName").set_value(source_.get_code_name().c_str());
} }
/* // workbook_pr_node.append_attribute("defaultThemeVersion").set_value("124226");
workbook_pr_node.append_attribute("defaultThemeVersion").set_value("124226"); // workbook_pr_node.append_attribute("date1904").set_value(source_.get_base_date() == calendar::mac_1904 ? "1" : "0");
workbook_pr_node.append_attribute("date1904").set_value(source_.get_base_date() == calendar::mac_1904 ? "1" : "0");
*/
} }
if (source_.has_absolute_path()) if (source_.has_absolute_path())
@ -570,31 +571,32 @@ void xlsx_producer::write_workbook(const relationship &rel, pugi::xml_node root)
workbook_view_node.append_attribute("windowHeight").set_value(std::to_string(view.window_height).c_str()); workbook_view_node.append_attribute("windowHeight").set_value(std::to_string(view.window_height).c_str());
workbook_view_node.append_attribute("tabRatio").set_value(std::to_string(view.tab_ratio).c_str()); workbook_view_node.append_attribute("tabRatio").set_value(std::to_string(view.tab_ratio).c_str());
} }
*/
auto sheets_node = workbook_node.append_child("sheets"); serializer.start_element(xmlns, "sheets");
pugi::xml_node defined_names_node; /*
if (any_defined_names) if (any_defined_names)
{ {
defined_names_node = workbook_node.append_child("definedNames"); defined_names_node = workbook_node.append_child("definedNames");
} }
*/
for (const auto ws : source_) for (const auto ws : source_)
{ {
auto sheet_rel_id = source_.d_->sheet_title_rel_id_map_[ws.get_title()]; auto sheet_rel_id = source_.d_->sheet_title_rel_id_map_[ws.get_title()];
auto sheet_rel = source_.d_->manifest_.get_relationship(rel.get_source().get_path(), sheet_rel_id); auto sheet_rel = source_.d_->manifest_.get_relationship(rel.get_source().get_path(), sheet_rel_id);
auto sheet_node = sheets_node.append_child("sheet"); serializer.start_element(xmlns, "sheet");
sheet_node.append_attribute("name").set_value(ws.get_title().c_str()); serializer.attribute("name", ws.get_title());
sheet_node.append_attribute("sheetId").set_value(std::to_string(ws.get_id()).c_str()); serializer.attribute("sheetId", std::to_string(ws.get_id()));
if (ws.has_page_setup() && ws.get_sheet_state() == xlnt::sheet_state::hidden) if (ws.has_page_setup() && ws.get_sheet_state() == xlnt::sheet_state::hidden)
{ {
sheet_node.append_attribute("state").set_value("hidden"); serializer.attribute("state", "hidden");
} }
sheet_node.append_attribute("r:id").set_value(sheet_rel_id.c_str()); serializer.attribute("http://schemas.openxmlformats.org/officeDocument/2006/relationships", "id", sheet_rel_id);
/*
if (ws.has_auto_filter()) if (ws.has_auto_filter())
{ {
auto defined_name_node = defined_names_node.append_child("definedName"); auto defined_name_node = defined_names_node.append_child("definedName");
@ -605,8 +607,11 @@ void xlsx_producer::write_workbook(const relationship &rel, pugi::xml_node root)
"'" + ws.get_title() + "'!" + range_reference::make_absolute(ws.get_auto_filter()).to_string(); "'" + ws.get_title() + "'!" + range_reference::make_absolute(ws.get_auto_filter()).to_string();
defined_name_node.text().set(name.c_str()); defined_name_node.text().set(name.c_str());
} }
*/
serializer.end_element(xmlns, "sheet");
} }
/*
if (source_.has_calculation_properties()) if (source_.has_calculation_properties())
{ {
auto calc_pr_node = workbook_node.append_child("calcPr"); auto calc_pr_node = workbook_node.append_child("calcPr");
@ -643,67 +648,72 @@ void xlsx_producer::write_workbook(const relationship &rel, pugi::xml_node root)
auto arch_id_node = ext_node.append_child("mx:ArchID"); auto arch_id_node = ext_node.append_child("mx:ArchID");
arch_id_node.append_attribute("Flags").set_value("2"); arch_id_node.append_attribute("Flags").set_value("2");
} }
*/
serializer.end_element(xmlns, "sheets");
serializer.end_element(xmlns, "workbook");
for (const auto &child_rel : source_.get_manifest().get_relationships(rel.get_target().get_path())) for (const auto &child_rel : source_.get_manifest().get_relationships(rel.get_target().get_path()))
{ {
pugi::xml_document document; std::ostringstream child_stream;
xml::serializer child_serializer(child_stream, child_rel.get_target().get_path().string());
switch (child_rel.get_type()) switch (child_rel.get_type())
{ {
case relationship::type::calculation_chain: case relationship::type::calculation_chain:
write_calculation_chain(child_rel, document.root()); write_calculation_chain(child_rel, child_serializer);
break; break;
case relationship::type::chartsheet: case relationship::type::chartsheet:
write_chartsheet(child_rel, document.root()); write_chartsheet(child_rel, child_serializer);
break; break;
case relationship::type::connections: case relationship::type::connections:
write_connections(child_rel, document.root()); write_connections(child_rel, child_serializer);
break; break;
case relationship::type::custom_xml_mappings: case relationship::type::custom_xml_mappings:
write_custom_xml_mappings(child_rel, document.root()); write_custom_xml_mappings(child_rel, child_serializer);
break; break;
case relationship::type::dialogsheet: case relationship::type::dialogsheet:
write_dialogsheet(child_rel, document.root()); write_dialogsheet(child_rel, child_serializer);
break; break;
case relationship::type::external_workbook_references: case relationship::type::external_workbook_references:
write_external_workbook_references(child_rel, document.root()); write_external_workbook_references(child_rel, child_serializer);
break; break;
case relationship::type::metadata: case relationship::type::metadata:
write_metadata(child_rel, document.root()); write_metadata(child_rel, child_serializer);
break; break;
case relationship::type::pivot_table: case relationship::type::pivot_table:
write_pivot_table(child_rel, document.root()); write_pivot_table(child_rel, child_serializer);
break; break;
case relationship::type::shared_string_table: case relationship::type::shared_string_table:
write_shared_string_table(child_rel, document.root()); write_shared_string_table(child_rel, child_serializer);
break; break;
case relationship::type::shared_workbook_revision_headers: case relationship::type::shared_workbook_revision_headers:
write_shared_workbook_revision_headers(child_rel, document.root()); write_shared_workbook_revision_headers(child_rel, child_serializer);
break; break;
case relationship::type::styles: case relationship::type::styles:
write_styles(child_rel, document.root()); write_styles(child_rel, child_serializer);
break; break;
case relationship::type::theme: case relationship::type::theme:
write_theme(child_rel, document.root()); write_theme(child_rel, child_serializer);
break; break;
case relationship::type::volatile_dependencies: case relationship::type::volatile_dependencies:
write_volatile_dependencies(child_rel, document.root()); write_volatile_dependencies(child_rel, child_serializer);
break; break;
case relationship::type::worksheet: case relationship::type::worksheet:
write_worksheet(child_rel, document.root()); write_worksheet(child_rel, child_serializer);
break; break;
default: default:
@ -711,56 +721,56 @@ void xlsx_producer::write_workbook(const relationship &rel, pugi::xml_node root)
} }
path archive_path(child_rel.get_source().get_path().parent().append(child_rel.get_target().get_path())); path archive_path(child_rel.get_source().get_path().parent().append(child_rel.get_target().get_path()));
write_document_to_archive(document, archive_path, destination_); destination_.write_string(child_stream.str(), archive_path);
} }
} }
// Write Workbook Relationship Target Parts // Write Workbook Relationship Target Parts
void xlsx_producer::write_calculation_chain(const relationship &rel, pugi::xml_node root) void xlsx_producer::write_calculation_chain(const relationship &rel, xml::serializer &serializer)
{ {
/*auto calc_chain_node = */root.append_child("calcChain"); serializer.start_element("calcChain");
} }
void xlsx_producer::write_chartsheet(const relationship &rel, pugi::xml_node root) void xlsx_producer::write_chartsheet(const relationship &rel, xml::serializer &serializer)
{ {
/*auto chartsheet_node = */root.append_child("chartsheet"); serializer.start_element("chartsheet");
} }
void xlsx_producer::write_connections(const relationship &rel, pugi::xml_node root) void xlsx_producer::write_connections(const relationship &rel, xml::serializer &serializer)
{ {
/*auto connections_node = */root.append_child("connections"); serializer.start_element("connections");
} }
void xlsx_producer::write_custom_xml_mappings(const relationship &rel, pugi::xml_node root) void xlsx_producer::write_custom_xml_mappings(const relationship &rel, xml::serializer &serializer)
{ {
/*auto map_info_node = */root.append_child("MapInfo"); serializer.start_element("MapInfo");
} }
void xlsx_producer::write_dialogsheet(const relationship &rel, pugi::xml_node root) void xlsx_producer::write_dialogsheet(const relationship &rel, xml::serializer &serializer)
{ {
/*auto dialogsheet_node = */root.append_child("dialogsheet"); serializer.start_element("dialogsheet");
} }
void xlsx_producer::write_external_workbook_references(const relationship &rel, pugi::xml_node root) void xlsx_producer::write_external_workbook_references(const relationship &rel, xml::serializer &serializer)
{ {
/*auto external_link_node = */root.append_child("externalLink"); serializer.start_element("externalLink");
} }
void xlsx_producer::write_metadata(const relationship &rel, pugi::xml_node root) void xlsx_producer::write_metadata(const relationship &rel, xml::serializer &serializer)
{ {
/*auto metadata_node = */root.append_child("metadata"); serializer.start_element("metadata");
} }
void xlsx_producer::write_pivot_table(const relationship &rel, pugi::xml_node root) void xlsx_producer::write_pivot_table(const relationship &rel, xml::serializer &serializer)
{ {
/*auto pivot_table_definition_node = */root.append_child("pivotTableDefinition"); serializer.start_element("pivotTableDefinition");
} }
void xlsx_producer::write_shared_string_table(const relationship &rel, pugi::xml_node root) void xlsx_producer::write_shared_string_table(const relationship &rel, xml::serializer &serializer)
{ {
auto sst_node = root.append_child("sst"); serializer.start_element("sst");
/*
sst_node.append_attribute("xmlns").set_value("http://schemas.openxmlformats.org/spreadsheetml/2006/main"); sst_node.append_attribute("xmlns").set_value("http://schemas.openxmlformats.org/spreadsheetml/2006/main");
std::size_t string_count = 0; std::size_t string_count = 0;
@ -830,27 +840,28 @@ void xlsx_producer::write_shared_string_table(const relationship &rel, pugi::xml
} }
} }
} }
*/
} }
void xlsx_producer::write_shared_workbook_revision_headers(const relationship &rel, pugi::xml_node root) void xlsx_producer::write_shared_workbook_revision_headers(const relationship &rel, xml::serializer &serializer)
{ {
/*auto headers_node = */root.append_child("headers"); serializer.start_element("headers");
} }
void xlsx_producer::write_shared_workbook(const relationship &rel, pugi::xml_node root) void xlsx_producer::write_shared_workbook(const relationship &rel, xml::serializer &serializer)
{ {
/*auto revisions_node = */root.append_child("revisions"); serializer.start_element("revisions");
} }
void xlsx_producer::write_shared_workbook_user_data(const relationship &rel, pugi::xml_node root) void xlsx_producer::write_shared_workbook_user_data(const relationship &rel, xml::serializer &serializer)
{ {
/*auto users_node = */root.append_child("users"); serializer.start_element("users");
} }
void xlsx_producer::write_styles(const relationship &rel, pugi::xml_node root) void xlsx_producer::write_styles(const relationship &rel, xml::serializer &serializer)
{ {
auto stylesheet_node = root.append_child("styleSheet"); serializer.start_element("styleSheet");
/*
// Namespaces // Namespaces
stylesheet_node.append_attribute("xmlns").set_value("http://schemas.openxmlformats.org/spreadsheetml/2006/main"); stylesheet_node.append_attribute("xmlns").set_value("http://schemas.openxmlformats.org/spreadsheetml/2006/main");
@ -1295,11 +1306,13 @@ void xlsx_producer::write_styles(const relationship &rel, pugi::xml_node root)
ext_node.append_attribute("xmlns:x14").set_value("http://schemas.microsoft.com/office/spreadsheetml/2009/9/main"); ext_node.append_attribute("xmlns:x14").set_value("http://schemas.microsoft.com/office/spreadsheetml/2009/9/main");
auto slicer_styles_node = ext_node.append_child("x14:slicerStyles"); auto slicer_styles_node = ext_node.append_child("x14:slicerStyles");
slicer_styles_node.append_attribute("defaultSlicerStyle").set_value("SlicerStyleLight1"); slicer_styles_node.append_attribute("defaultSlicerStyle").set_value("SlicerStyleLight1");
*/
} }
void xlsx_producer::write_theme(const relationship &rel, pugi::xml_node root) void xlsx_producer::write_theme(const relationship &rel, xml::serializer &serializer)
{ {
auto theme_node = root.append_child("a:theme"); serializer.start_element("a:theme");
/*
theme_node.append_attribute("xmlns:a").set_value(constants::get_namespace("drawingml").c_str()); theme_node.append_attribute("xmlns:a").set_value(constants::get_namespace("drawingml").c_str());
theme_node.append_attribute("name").set_value("Office Theme"); theme_node.append_attribute("name").set_value("Office Theme");
@ -1602,14 +1615,15 @@ void xlsx_producer::write_theme(const relationship &rel, pugi::xml_node root)
theme_family_node.append_attribute("name").set_value("Office Theme"); theme_family_node.append_attribute("name").set_value("Office Theme");
theme_family_node.append_attribute("id").set_value("{62F939B6-93AF-4DB8-9C6B-D6C7DFDC589F}"); theme_family_node.append_attribute("id").set_value("{62F939B6-93AF-4DB8-9C6B-D6C7DFDC589F}");
theme_family_node.append_attribute("vid").set_value("{4A3C46E8-61CC-4603-A589-7422A47A8E4A}"); theme_family_node.append_attribute("vid").set_value("{4A3C46E8-61CC-4603-A589-7422A47A8E4A}");
*/
} }
void xlsx_producer::write_volatile_dependencies(const relationship &rel, pugi::xml_node root) void xlsx_producer::write_volatile_dependencies(const relationship &rel, xml::serializer &serializer)
{ {
/*auto vol_types_node = */root.append_child("volTypes"); serializer.start_element("volTypes");
} }
void xlsx_producer::write_worksheet(const relationship &rel, pugi::xml_node root) void xlsx_producer::write_worksheet(const relationship &rel, xml::serializer &serializer)
{ {
auto title = std::find_if(source_.d_->sheet_title_rel_id_map_.begin(), auto title = std::find_if(source_.d_->sheet_title_rel_id_map_.begin(),
source_.d_->sheet_title_rel_id_map_.end(), source_.d_->sheet_title_rel_id_map_.end(),
@ -1620,17 +1634,19 @@ void xlsx_producer::write_worksheet(const relationship &rel, pugi::xml_node root
auto ws = source_.get_sheet_by_title(title); auto ws = source_.get_sheet_by_title(title);
auto worksheet_node = root.append_child("worksheet"); const auto xmlns = std::string("http://schemas.openxmlformats.org/spreadsheetml/2006/main");
worksheet_node.append_attribute("xmlns").set_value("http://schemas.openxmlformats.org/spreadsheetml/2006/main");
worksheet_node.append_attribute("xmlns:r").set_value("http://schemas.openxmlformats.org/officeDocument/2006/relationships"); serializer.start_element(xmlns, "worksheet");
serializer.namespace_decl(xmlns, "");
serializer.namespace_decl("http://schemas.openxmlformats.org/officeDocument/2006/relationships", "r");
if (ws.x14ac_enabled()) if (ws.x14ac_enabled())
{ {
worksheet_node.append_attribute("xmlns:mc").set_value("http://schemas.openxmlformats.org/markup-compatibility/2006"); serializer.namespace_decl("http://schemas.openxmlformats.org/markup-compatibility/2006", "mc");
worksheet_node.append_attribute("mc:Ignorable").set_value("x14ac"); serializer.attribute("mc:Ignorable", "x14ac");
worksheet_node.append_attribute("xmlns:x14ac").set_value("http://schemas.microsoft.com/office/spreadsheetml/2009/9/ac"); serializer.namespace_decl("http://schemas.microsoft.com/office/spreadsheetml/2009/9/ac", "x14ac");
} }
/*
if (ws.has_page_setup()) if (ws.has_page_setup())
{ {
auto sheet_pr_node = worksheet_node.append_child("sheetPr"); auto sheet_pr_node = worksheet_node.append_child("sheetPr");
@ -1766,12 +1782,13 @@ void xlsx_producer::write_worksheet(const relationship &rel, pugi::xml_node root
col_node.append_attribute("customWidth").set_value(props.custom ? "1" : "0"); col_node.append_attribute("customWidth").set_value(props.custom ? "1" : "0");
} }
} }
*/
std::unordered_map<std::string, std::string> hyperlink_references; std::unordered_map<std::string, std::string> hyperlink_references;
auto sheet_data_node = worksheet_node.append_child("sheetData"); serializer.start_element(xmlns, "sheetData");
const auto &shared_strings = ws.get_workbook().get_shared_strings(); const auto &shared_strings = ws.get_workbook().get_shared_strings();
/*
for (auto row : ws.rows()) for (auto row : ws.rows())
{ {
auto min = static_cast<xlnt::row_t>(row.num_cells()); auto min = static_cast<xlnt::row_t>(row.num_cells());
@ -1916,7 +1933,9 @@ void xlsx_producer::write_worksheet(const relationship &rel, pugi::xml_node root
} }
} }
} }
*/
serializer.end_element();
/*
if (ws.has_auto_filter()) if (ws.has_auto_filter())
{ {
auto auto_filter_node = worksheet_node.append_child("autoFilter"); auto auto_filter_node = worksheet_node.append_child("autoFilter");
@ -2034,31 +2053,34 @@ void xlsx_producer::write_worksheet(const relationship &rel, pugi::xml_node root
"Text &P of &N"; "Text &P of &N";
odd_footer_node.text().set(footer_text.c_str()); odd_footer_node.text().set(footer_text.c_str());
} }
*/
serializer.end_element();
} }
// Sheet Relationship Target Parts // Sheet Relationship Target Parts
void xlsx_producer::write_comments(const relationship &rel, pugi::xml_node root) void xlsx_producer::write_comments(const relationship &rel, xml::serializer &serializer)
{ {
/*auto comments_node = */root.append_child("comments"); serializer.start_element("comments");
} }
void xlsx_producer::write_drawings(const relationship &rel, pugi::xml_node root) void xlsx_producer::write_drawings(const relationship &rel, xml::serializer &serializer)
{ {
/*auto ws_dr_node = */root.append_child("wsDr"); serializer.start_element("wsDr");
} }
// Other Parts // Other Parts
void xlsx_producer::write_custom_property() void xlsx_producer::write_custom_property(xml::serializer &serializer)
{ {
} }
void xlsx_producer::write_unknown_parts() void xlsx_producer::write_unknown_parts(xml::serializer &serializer)
{ {
} }
void xlsx_producer::write_unknown_relationships() void xlsx_producer::write_unknown_relationships(xml::serializer &serializer)
{ {
} }

View File

@ -27,7 +27,7 @@
#include <iostream> #include <iostream>
#include <vector> #include <vector>
#include <detail/include_pugixml.hpp> #include <detail/include_libstudxml.hpp>
#include <xlnt/xlnt_config.hpp> #include <xlnt/xlnt_config.hpp>
#include <xlnt/packaging/zip_file.hpp> #include <xlnt/packaging/zip_file.hpp>
@ -63,45 +63,45 @@ private:
// Package Parts // Package Parts
void write_manifest(); void write_manifest();
void write_core_properties(const relationship &rel, pugi::xml_node root); void write_core_properties(const relationship &rel, xml::serializer &serializer);
void write_extended_properties(const relationship &rel, pugi::xml_node root); void write_extended_properties(const relationship &rel, xml::serializer &serializer);
void write_custom_properties(const relationship &rel, pugi::xml_node root); void write_custom_properties(const relationship &rel, xml::serializer &serializer);
void write_thumbnail(const relationship &rel); void write_thumbnail(const relationship &rel);
// SpreadsheetML-Specific Package Parts // SpreadsheetML-Specific Package Parts
void write_workbook(const relationship &rel, pugi::xml_node root); void write_workbook(const relationship &rel, xml::serializer &serializer);
// Workbook Relationship Target Parts // Workbook Relationship Target Parts
void write_calculation_chain(const relationship &rel, pugi::xml_node root); void write_calculation_chain(const relationship &rel, xml::serializer &serializer);
void write_connections(const relationship &rel, pugi::xml_node root); void write_connections(const relationship &rel, xml::serializer &serializer);
void write_custom_xml_mappings(const relationship &rel, pugi::xml_node root); void write_custom_xml_mappings(const relationship &rel, xml::serializer &serializer);
void write_external_workbook_references(const relationship &rel, pugi::xml_node root); void write_external_workbook_references(const relationship &rel, xml::serializer &serializer);
void write_metadata(const relationship &rel, pugi::xml_node root); void write_metadata(const relationship &rel, xml::serializer &serializer);
void write_pivot_table(const relationship &rel, pugi::xml_node root); void write_pivot_table(const relationship &rel, xml::serializer &serializer);
void write_shared_string_table(const relationship &rel, pugi::xml_node root); void write_shared_string_table(const relationship &rel, xml::serializer &serializer);
void write_shared_workbook_revision_headers(const relationship &rel, pugi::xml_node root); void write_shared_workbook_revision_headers(const relationship &rel, xml::serializer &serializer);
void write_shared_workbook(const relationship &rel, pugi::xml_node root); void write_shared_workbook(const relationship &rel, xml::serializer &serializer);
void write_shared_workbook_user_data(const relationship &rel, pugi::xml_node root); void write_shared_workbook_user_data(const relationship &rel, xml::serializer &serializer);
void write_styles(const relationship &rel, pugi::xml_node root); void write_styles(const relationship &rel, xml::serializer &serializer);
void write_theme(const relationship &rel, pugi::xml_node root); void write_theme(const relationship &rel, xml::serializer &serializer);
void write_volatile_dependencies(const relationship &rel, pugi::xml_node root); void write_volatile_dependencies(const relationship &rel, xml::serializer &serializer);
void write_chartsheet(const relationship &rel, pugi::xml_node root); void write_chartsheet(const relationship &rel, xml::serializer &serializer);
void write_dialogsheet(const relationship &rel, pugi::xml_node root); void write_dialogsheet(const relationship &rel, xml::serializer &serializer);
void write_worksheet(const relationship &rel, pugi::xml_node root); void write_worksheet(const relationship &rel, xml::serializer &serializer);
// Sheet Relationship Target Parts // Sheet Relationship Target Parts
void write_comments(const relationship &rel, pugi::xml_node root); void write_comments(const relationship &rel, xml::serializer &serializer);
void write_drawings(const relationship &rel, pugi::xml_node root); void write_drawings(const relationship &rel, xml::serializer &serializer);
// Other Parts // Other Parts
void write_custom_property(); void write_custom_property(xml::serializer &serializer);
void write_unknown_parts(); void write_unknown_parts(xml::serializer &serializer);
void write_unknown_relationships(); void write_unknown_relationships(xml::serializer &serializer);
// Helpers // Helpers

View File

@ -0,0 +1,15 @@
/* file : xml/details/config.h.in
* copyright : Copyright (c) 2013-2014 Code Synthesis Tools CC
* license : MIT; see accompanying LICENSE file
*/
/* This file is automatically processed by configure. */
#ifndef XML_DETAILS_CONFIG_H
#define XML_DETAILS_CONFIG_H
#undef LIBSTUDXML_STATIC_LIB
#undef LIBSTUDXML_EXTERNAL_EXPAT
#undef LIBSTUDXML_BYTEORDER
#endif /* XML_DETAILS_CONFIG_H */

View File

@ -1,7 +1,6 @@
#pragma once #pragma once
#include <iostream> #include <iostream>
#include <pugixml.hpp>
#include <cxxtest/TestSuite.h> #include <cxxtest/TestSuite.h>
#include <xlnt/xlnt.hpp> #include <xlnt/xlnt.hpp>

View File

@ -16,6 +16,8 @@ public:
{ {
std::vector<std::uint8_t> buffer; std::vector<std::uint8_t> buffer;
wb.save(buffer); wb.save(buffer);
wb.save("a.xlsx");
xlnt::zip_file wb_archive(buffer); xlnt::zip_file wb_archive(buffer);
xlnt::zip_file file_archive(file); xlnt::zip_file file_archive(file);

1
third-party/pugixml vendored Submodule

@ -0,0 +1 @@
Subproject commit dfe9360cdf038c0ecf53d45bfc75cf8fd34604b8