2015-12-25 06:10:02 +08:00
|
|
|
// Copyright (c) 2014-2016 Thomas Fussell
|
2015-12-25 04:51:11 +08:00
|
|
|
// Copyright (c) 2010-2015 openpyxl
|
|
|
|
//
|
|
|
|
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
|
|
// of this software and associated documentation files (the "Software"), to deal
|
|
|
|
// in the Software without restriction, including without limitation the rights
|
|
|
|
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
|
|
// copies of the Software, and to permit persons to whom the Software is
|
|
|
|
// furnished to do so, subject to the following conditions:
|
|
|
|
//
|
|
|
|
// The above copyright notice and this permission notice shall be included in
|
|
|
|
// all copies or substantial portions of the Software.
|
|
|
|
//
|
|
|
|
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
|
|
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
|
|
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
|
|
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
|
|
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, WRISING FROM,
|
|
|
|
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
|
|
|
// THE SOFTWARE
|
|
|
|
//
|
|
|
|
// @license: http://www.opensource.org/licenses/mit-license.php
|
|
|
|
// @author: see AUTHORS file
|
2015-10-31 18:54:41 +08:00
|
|
|
#include <algorithm>
|
2015-10-31 18:52:59 +08:00
|
|
|
#include <iterator>
|
2016-07-04 07:22:08 +08:00
|
|
|
#include <pugixml.hpp>
|
2015-10-31 18:52:59 +08:00
|
|
|
|
2016-07-04 07:22:08 +08:00
|
|
|
#include <detail/constants.hpp>
|
|
|
|
#include <detail/excel_serializer.hpp>
|
|
|
|
#include <detail/manifest_serializer.hpp>
|
|
|
|
#include <detail/relationship_serializer.hpp>
|
|
|
|
#include <detail/shared_strings_serializer.hpp>
|
|
|
|
#include <detail/style_serializer.hpp>
|
|
|
|
#include <detail/stylesheet.hpp>
|
|
|
|
#include <detail/theme_serializer.hpp>
|
|
|
|
#include <detail/workbook_impl.hpp>
|
|
|
|
#include <detail/workbook_serializer.hpp>
|
|
|
|
#include <detail/worksheet_serializer.hpp>
|
2016-05-15 03:19:08 +08:00
|
|
|
#include <xlnt/cell/text.hpp>
|
2015-11-03 22:06:01 +08:00
|
|
|
#include <xlnt/packaging/manifest.hpp>
|
2016-05-15 01:57:07 +08:00
|
|
|
#include <xlnt/styles/format.hpp>
|
|
|
|
#include <xlnt/styles/style.hpp>
|
2015-11-03 21:38:09 +08:00
|
|
|
#include <xlnt/utils/exceptions.hpp>
|
2015-10-21 11:30:10 +08:00
|
|
|
#include <xlnt/workbook/workbook.hpp>
|
2016-01-25 00:15:49 +08:00
|
|
|
#include <xlnt/workbook/worksheet_iterator.hpp>
|
|
|
|
#include <xlnt/worksheet/range_iterator.hpp>
|
2015-10-30 07:37:07 +08:00
|
|
|
#include <xlnt/worksheet/worksheet.hpp>
|
|
|
|
|
2015-10-21 11:30:10 +08:00
|
|
|
namespace {
|
2015-11-01 22:43:01 +08:00
|
|
|
|
2015-11-11 07:58:54 +08:00
|
|
|
std::string::size_type find_string_in_string(const std::string &string, const std::string &substring)
|
2015-10-21 11:30:10 +08:00
|
|
|
{
|
2015-11-11 07:58:54 +08:00
|
|
|
std::string::size_type possible_match_index = string.find(substring.at(0));
|
2015-11-01 22:43:01 +08:00
|
|
|
|
2015-11-11 07:58:54 +08:00
|
|
|
while (possible_match_index != std::string::npos)
|
2015-10-21 11:30:10 +08:00
|
|
|
{
|
2015-11-11 07:58:54 +08:00
|
|
|
if (string.substr(possible_match_index, substring.size()) == substring)
|
2015-10-21 11:30:10 +08:00
|
|
|
{
|
|
|
|
return possible_match_index;
|
|
|
|
}
|
2015-11-01 22:43:01 +08:00
|
|
|
|
2015-10-21 11:30:10 +08:00
|
|
|
possible_match_index = string.find(substring.at(0), possible_match_index + 1);
|
|
|
|
}
|
2015-11-01 22:43:01 +08:00
|
|
|
|
2015-10-21 11:30:10 +08:00
|
|
|
return possible_match_index;
|
|
|
|
}
|
|
|
|
|
2016-07-18 02:59:11 +08:00
|
|
|
bool load_workbook(xlnt::zip_file &archive, bool guess_types, bool data_only, xlnt::workbook &wb, xlnt::detail::stylesheet &stylesheet)
|
2015-10-24 02:42:36 +08:00
|
|
|
{
|
2016-07-30 05:50:33 +08:00
|
|
|
wb.clear();
|
|
|
|
|
2016-07-23 08:26:02 +08:00
|
|
|
if(!archive.has_file(xlnt::constants::part_content_types()))
|
2015-11-02 12:52:19 +08:00
|
|
|
{
|
2016-07-30 06:55:49 +08:00
|
|
|
throw xlnt::invalid_file("missing [Content Types].xml");
|
2015-11-02 12:52:19 +08:00
|
|
|
}
|
|
|
|
|
2015-10-30 07:37:07 +08:00
|
|
|
xlnt::manifest_serializer ms(wb.get_manifest());
|
2016-07-04 07:22:08 +08:00
|
|
|
pugi::xml_document manifest_xml;
|
2016-07-23 08:26:02 +08:00
|
|
|
manifest_xml.load(archive.read(xlnt::constants::part_content_types()).c_str());
|
2015-11-03 03:22:13 +08:00
|
|
|
ms.read_manifest(manifest_xml);
|
2015-11-01 22:43:01 +08:00
|
|
|
|
|
|
|
if (ms.determine_document_type() != "excel")
|
2015-10-24 02:42:36 +08:00
|
|
|
{
|
2016-07-30 06:55:49 +08:00
|
|
|
throw xlnt::invalid_file("package is not an OOXML SpreadsheetML");
|
2015-10-24 02:42:36 +08:00
|
|
|
}
|
2015-11-01 22:43:01 +08:00
|
|
|
|
2016-07-23 08:26:02 +08:00
|
|
|
if(archive.has_file(xlnt::constants::part_core()))
|
2015-11-02 12:52:19 +08:00
|
|
|
{
|
|
|
|
xlnt::workbook_serializer workbook_serializer_(wb);
|
2016-07-04 07:22:08 +08:00
|
|
|
pugi::xml_document core_properties_xml;
|
2016-07-23 08:26:02 +08:00
|
|
|
core_properties_xml.load(archive.read(xlnt::constants::part_core()).c_str());
|
2015-11-03 03:22:13 +08:00
|
|
|
workbook_serializer_.read_properties_core(core_properties_xml);
|
2015-11-02 12:52:19 +08:00
|
|
|
}
|
2015-11-04 07:26:33 +08:00
|
|
|
|
2016-07-23 08:26:02 +08:00
|
|
|
if(archive.has_file(xlnt::constants::part_app()))
|
2016-03-09 11:32:32 +08:00
|
|
|
{
|
|
|
|
xlnt::workbook_serializer workbook_serializer_(wb);
|
2016-07-04 07:22:08 +08:00
|
|
|
pugi::xml_document app_properties_xml;
|
2016-07-23 08:26:02 +08:00
|
|
|
app_properties_xml.load(archive.read(xlnt::constants::part_app()).c_str());
|
2016-03-09 11:32:32 +08:00
|
|
|
workbook_serializer_.read_properties_app(app_properties_xml);
|
|
|
|
}
|
|
|
|
|
2015-11-04 07:26:33 +08:00
|
|
|
xlnt::relationship_serializer relationship_serializer_(archive);
|
2016-05-16 03:03:02 +08:00
|
|
|
auto root_relationships = relationship_serializer_.read_relationships("");
|
|
|
|
|
|
|
|
for (const auto &relationship : root_relationships)
|
|
|
|
{
|
|
|
|
wb.create_root_relationship(relationship.get_id(), relationship.get_target_uri(), relationship.get_type());
|
|
|
|
}
|
|
|
|
|
2016-08-03 12:12:18 +08:00
|
|
|
auto workbook_relationships = relationship_serializer_.read_relationships(xlnt::constants::part_workbook().to_string('/'));
|
2015-11-01 22:43:01 +08:00
|
|
|
|
|
|
|
for (const auto &relationship : workbook_relationships)
|
2015-10-24 02:42:36 +08:00
|
|
|
{
|
|
|
|
wb.create_relationship(relationship.get_id(), relationship.get_target_uri(), relationship.get_type());
|
|
|
|
}
|
2015-11-01 22:43:01 +08:00
|
|
|
|
2016-07-04 07:22:08 +08:00
|
|
|
pugi::xml_document xml;
|
2016-07-23 08:26:02 +08:00
|
|
|
xml.load(archive.read(xlnt::constants::part_workbook()).c_str());
|
2015-11-01 22:43:01 +08:00
|
|
|
|
2016-07-04 07:22:08 +08:00
|
|
|
auto root_node = xml.child("workbook");
|
|
|
|
auto workbook_pr_node = root_node.child("workbookPr");
|
2016-08-03 12:12:18 +08:00
|
|
|
|
|
|
|
if (workbook_pr_node.attribute("date1904"))
|
|
|
|
{
|
|
|
|
std::string value = workbook_pr_node.attribute("date1904").value();
|
|
|
|
|
|
|
|
if (value == "1" || value == "true")
|
|
|
|
{
|
|
|
|
wb.set_base_date(xlnt::calendar::mac_1904);
|
|
|
|
}
|
|
|
|
}
|
2015-11-01 22:43:01 +08:00
|
|
|
|
2016-07-23 08:26:02 +08:00
|
|
|
if(archive.has_file(xlnt::constants::part_shared_strings()))
|
2015-10-31 06:54:04 +08:00
|
|
|
{
|
2016-05-15 03:19:08 +08:00
|
|
|
std::vector<xlnt::text> shared_strings;
|
2016-07-04 07:22:08 +08:00
|
|
|
pugi::xml_document shared_strings_xml;
|
2016-07-23 08:26:02 +08:00
|
|
|
shared_strings_xml.load(archive.read(xlnt::constants::part_shared_strings()).c_str());
|
2015-11-03 06:25:10 +08:00
|
|
|
xlnt::shared_strings_serializer::read_shared_strings(shared_strings_xml, shared_strings);
|
2015-11-02 12:52:19 +08:00
|
|
|
|
2016-05-15 03:19:08 +08:00
|
|
|
for (auto &shared_string : shared_strings)
|
2015-11-02 12:52:19 +08:00
|
|
|
{
|
2016-04-27 01:09:17 +08:00
|
|
|
wb.add_shared_string(shared_string, true);
|
2015-11-02 12:52:19 +08:00
|
|
|
}
|
2015-10-31 06:54:04 +08:00
|
|
|
}
|
2015-11-01 22:43:01 +08:00
|
|
|
|
2016-06-11 01:40:50 +08:00
|
|
|
xlnt::style_serializer style_serializer(stylesheet);
|
2016-07-04 07:22:08 +08:00
|
|
|
pugi::xml_document style_xml;
|
2016-07-23 08:26:02 +08:00
|
|
|
style_xml.load(archive.read(xlnt::constants::part_styles()).c_str());
|
2016-06-11 01:40:50 +08:00
|
|
|
style_serializer.read_stylesheet(style_xml);
|
2015-11-01 22:43:01 +08:00
|
|
|
|
2016-07-23 10:48:50 +08:00
|
|
|
for (auto sheet_node : root_node.child("sheets").children())
|
2015-10-24 02:42:36 +08:00
|
|
|
{
|
2016-07-04 07:22:08 +08:00
|
|
|
auto rel = wb.get_relationship(sheet_node.attribute("r:id").value());
|
2016-07-23 10:48:50 +08:00
|
|
|
|
|
|
|
// TODO impelement chartsheets
|
|
|
|
if(rel.get_type() == xlnt::relationship::type::chartsheet)
|
2015-11-03 05:45:05 +08:00
|
|
|
{
|
|
|
|
continue;
|
|
|
|
}
|
2016-07-23 10:48:50 +08:00
|
|
|
|
2016-08-02 06:33:43 +08:00
|
|
|
auto ws = wb.create_sheet_with_rel(sheet_node.attribute("name").value(), rel);
|
|
|
|
ws.set_id(static_cast<std::size_t>(sheet_node.attribute("sheetId").as_ullong()));
|
2015-10-30 07:37:07 +08:00
|
|
|
xlnt::worksheet_serializer worksheet_serializer(ws);
|
2016-07-04 07:22:08 +08:00
|
|
|
pugi::xml_document worksheet_xml;
|
2016-08-03 12:12:18 +08:00
|
|
|
auto target_uri = xlnt::constants::package_xl().append(rel.get_target_uri());
|
|
|
|
worksheet_xml.load(archive.read(target_uri).c_str());
|
2016-07-23 10:48:50 +08:00
|
|
|
|
2016-06-11 01:40:50 +08:00
|
|
|
worksheet_serializer.read_worksheet(worksheet_xml, stylesheet);
|
2015-10-24 02:42:36 +08:00
|
|
|
}
|
2015-11-01 22:43:01 +08:00
|
|
|
|
2016-08-03 12:12:18 +08:00
|
|
|
if (archive.has_file(xlnt::path("docProps/thumbnail.jpeg")))
|
2016-03-10 17:12:51 +08:00
|
|
|
{
|
2016-08-03 12:12:18 +08:00
|
|
|
auto thumbnail_data = archive.read(xlnt::path("docProps/thumbnail.jpeg"));
|
2016-03-10 17:12:51 +08:00
|
|
|
wb.set_thumbnail(std::vector<std::uint8_t>(thumbnail_data.begin(), thumbnail_data.end()));
|
|
|
|
}
|
|
|
|
|
2015-10-30 07:37:07 +08:00
|
|
|
return true;
|
2015-10-24 02:42:36 +08:00
|
|
|
}
|
2015-11-01 22:43:01 +08:00
|
|
|
|
2015-10-21 11:30:10 +08:00
|
|
|
} // namespace
|
|
|
|
|
|
|
|
namespace xlnt {
|
|
|
|
|
2015-11-11 07:58:54 +08:00
|
|
|
const std::string excel_serializer::central_directory_signature()
|
2015-10-21 11:30:10 +08:00
|
|
|
{
|
|
|
|
return "\x50\x4b\x05\x06";
|
|
|
|
}
|
|
|
|
|
2015-11-11 07:58:54 +08:00
|
|
|
std::string excel_serializer::repair_central_directory(const std::string &original)
|
2015-10-21 11:30:10 +08:00
|
|
|
{
|
2015-10-30 07:37:07 +08:00
|
|
|
auto pos = find_string_in_string(original, central_directory_signature());
|
2015-11-01 22:43:01 +08:00
|
|
|
|
2015-11-11 07:58:54 +08:00
|
|
|
if (pos != std::string::npos)
|
2015-10-21 11:30:10 +08:00
|
|
|
{
|
|
|
|
return original.substr(0, pos + 22);
|
|
|
|
}
|
2015-11-01 22:43:01 +08:00
|
|
|
|
2015-10-21 11:30:10 +08:00
|
|
|
return original;
|
|
|
|
}
|
|
|
|
|
2015-10-30 07:37:07 +08:00
|
|
|
bool excel_serializer::load_stream_workbook(std::istream &stream, bool guess_types, bool data_only)
|
2015-10-21 11:30:10 +08:00
|
|
|
{
|
2015-11-02 12:52:19 +08:00
|
|
|
std::vector<std::uint8_t> bytes;
|
|
|
|
|
2015-11-03 05:45:05 +08:00
|
|
|
//TODO: inefficient?
|
2015-11-02 12:52:19 +08:00
|
|
|
while (stream.good())
|
|
|
|
{
|
2015-11-03 05:45:05 +08:00
|
|
|
bytes.push_back(static_cast<std::uint8_t>(stream.get()));
|
2015-11-02 12:52:19 +08:00
|
|
|
}
|
|
|
|
|
2015-10-30 07:37:07 +08:00
|
|
|
return load_virtual_workbook(bytes, guess_types, data_only);
|
2015-10-21 11:30:10 +08:00
|
|
|
}
|
|
|
|
|
2016-08-03 12:12:18 +08:00
|
|
|
bool excel_serializer::load_workbook(const path &filename, bool guess_types, bool data_only)
|
2015-10-21 11:30:10 +08:00
|
|
|
{
|
2015-10-24 02:42:36 +08:00
|
|
|
try
|
|
|
|
{
|
2015-10-30 07:37:07 +08:00
|
|
|
archive_.load(filename);
|
2015-10-24 02:42:36 +08:00
|
|
|
}
|
2015-11-01 22:43:01 +08:00
|
|
|
catch (std::runtime_error)
|
2015-10-24 02:42:36 +08:00
|
|
|
{
|
2016-08-03 12:12:18 +08:00
|
|
|
throw invalid_file(filename.to_string());
|
2015-10-24 02:42:36 +08:00
|
|
|
}
|
2015-11-01 22:43:01 +08:00
|
|
|
|
2016-07-18 02:59:11 +08:00
|
|
|
return ::load_workbook(archive_, guess_types, data_only, workbook_, get_stylesheet());
|
2015-10-24 02:42:36 +08:00
|
|
|
}
|
2015-10-21 11:30:10 +08:00
|
|
|
|
2015-10-30 07:37:07 +08:00
|
|
|
bool excel_serializer::load_virtual_workbook(const std::vector<std::uint8_t> &bytes, bool guess_types, bool data_only)
|
2015-10-24 02:42:36 +08:00
|
|
|
{
|
2015-10-30 07:37:07 +08:00
|
|
|
archive_.load(bytes);
|
2015-11-01 22:43:01 +08:00
|
|
|
|
2016-07-18 02:59:11 +08:00
|
|
|
return ::load_workbook(archive_, guess_types, data_only, workbook_, get_stylesheet());
|
2015-10-21 11:30:10 +08:00
|
|
|
}
|
2015-11-01 22:43:01 +08:00
|
|
|
|
2015-10-31 06:54:04 +08:00
|
|
|
excel_serializer::excel_serializer(workbook &wb) : workbook_(wb)
|
2015-10-30 01:46:56 +08:00
|
|
|
{
|
|
|
|
}
|
|
|
|
|
2015-10-31 06:54:04 +08:00
|
|
|
void excel_serializer::write_data(bool /*as_template*/)
|
2015-10-30 01:46:56 +08:00
|
|
|
{
|
2015-11-04 07:26:33 +08:00
|
|
|
relationship_serializer relationship_serializer_(archive_);
|
|
|
|
relationship_serializer_.write_relationships(workbook_.get_root_relationships(), "");
|
2016-08-03 12:12:18 +08:00
|
|
|
relationship_serializer_.write_relationships(workbook_.get_relationships(), constants::part_workbook().to_string('/'));
|
2015-11-01 22:43:01 +08:00
|
|
|
|
2016-07-04 07:22:08 +08:00
|
|
|
pugi::xml_document properties_app_xml;
|
2015-10-31 06:54:04 +08:00
|
|
|
workbook_serializer workbook_serializer_(workbook_);
|
2016-07-04 07:22:08 +08:00
|
|
|
workbook_serializer_.write_properties_app(properties_app_xml);
|
2016-07-15 10:05:39 +08:00
|
|
|
|
|
|
|
{
|
|
|
|
std::ostringstream ss;
|
|
|
|
properties_app_xml.save(ss);
|
2016-08-03 12:12:18 +08:00
|
|
|
archive_.write_string(ss.str(), constants::part_app());
|
2016-07-15 10:05:39 +08:00
|
|
|
}
|
2016-07-04 07:22:08 +08:00
|
|
|
|
|
|
|
pugi::xml_document properties_core_xml;
|
|
|
|
workbook_serializer_.write_properties_core(properties_core_xml);
|
2016-07-15 10:05:39 +08:00
|
|
|
|
|
|
|
{
|
|
|
|
std::ostringstream ss;
|
|
|
|
properties_core_xml.save(ss);
|
2016-08-03 12:12:18 +08:00
|
|
|
archive_.write_string(ss.str(), constants::part_core());
|
2016-07-15 10:05:39 +08:00
|
|
|
}
|
2015-11-01 22:43:01 +08:00
|
|
|
|
2016-07-04 07:22:08 +08:00
|
|
|
pugi::xml_document theme_xml;
|
2015-10-30 07:37:07 +08:00
|
|
|
theme_serializer theme_serializer_;
|
2016-08-03 12:12:18 +08:00
|
|
|
theme_serializer_.write_theme(workbook_.get_theme(), theme_xml);
|
2016-07-15 10:05:39 +08:00
|
|
|
|
|
|
|
{
|
|
|
|
std::ostringstream ss;
|
|
|
|
theme_xml.save(ss);
|
2016-08-03 12:12:18 +08:00
|
|
|
archive_.write_string(ss.str(), constants::part_theme());
|
2016-07-15 10:05:39 +08:00
|
|
|
}
|
2015-11-01 22:43:01 +08:00
|
|
|
|
2016-05-16 03:03:02 +08:00
|
|
|
if (!workbook_.get_shared_strings().empty())
|
|
|
|
{
|
|
|
|
const auto &strings = workbook_.get_shared_strings();
|
2016-07-04 07:22:08 +08:00
|
|
|
pugi::xml_document shared_strings_xml;
|
2016-07-15 10:05:39 +08:00
|
|
|
shared_strings_serializer::write_shared_strings(strings, shared_strings_xml);
|
2016-07-04 07:22:08 +08:00
|
|
|
|
2016-07-15 10:05:39 +08:00
|
|
|
std::ostringstream ss;
|
|
|
|
shared_strings_xml.save(ss);
|
2016-08-03 12:12:18 +08:00
|
|
|
archive_.write_string(ss.str(), constants::part_shared_strings());
|
2016-05-16 03:03:02 +08:00
|
|
|
}
|
2015-11-01 22:43:01 +08:00
|
|
|
|
2016-07-04 07:22:08 +08:00
|
|
|
pugi::xml_document workbook_xml;
|
|
|
|
workbook_serializer_.write_workbook(workbook_xml);
|
2016-07-15 10:05:39 +08:00
|
|
|
|
|
|
|
{
|
|
|
|
std::ostringstream ss;
|
|
|
|
workbook_xml.save(ss);
|
2016-08-03 12:12:18 +08:00
|
|
|
archive_.write_string(ss.str(), constants::part_workbook());
|
2016-07-15 10:05:39 +08:00
|
|
|
}
|
2015-11-01 22:43:01 +08:00
|
|
|
|
2016-06-11 01:40:50 +08:00
|
|
|
style_serializer style_serializer(workbook_.d_->stylesheet_);
|
2016-07-04 07:22:08 +08:00
|
|
|
pugi::xml_document style_xml;
|
2016-06-11 01:40:50 +08:00
|
|
|
style_serializer.write_stylesheet(style_xml);
|
2016-07-15 10:05:39 +08:00
|
|
|
|
|
|
|
{
|
|
|
|
std::ostringstream ss;
|
|
|
|
style_xml.save(ss);
|
2016-08-03 12:12:18 +08:00
|
|
|
archive_.write_string(ss.str(), constants::part_styles());
|
2016-07-15 10:05:39 +08:00
|
|
|
}
|
2015-11-01 22:43:01 +08:00
|
|
|
|
2015-10-31 06:54:04 +08:00
|
|
|
manifest_serializer manifest_serializer_(workbook_.get_manifest());
|
2016-07-04 07:22:08 +08:00
|
|
|
pugi::xml_document manifest_xml;
|
|
|
|
manifest_serializer_.write_manifest(manifest_xml);
|
2016-07-15 10:05:39 +08:00
|
|
|
|
|
|
|
{
|
|
|
|
std::ostringstream ss;
|
|
|
|
manifest_xml.save(ss);
|
2016-08-03 12:12:18 +08:00
|
|
|
archive_.write_string(ss.str(), constants::part_content_types());
|
2016-07-15 10:05:39 +08:00
|
|
|
}
|
2015-11-01 22:43:01 +08:00
|
|
|
|
2015-10-30 07:37:07 +08:00
|
|
|
write_worksheets();
|
2016-07-15 10:05:39 +08:00
|
|
|
|
2016-03-10 17:12:51 +08:00
|
|
|
if(!workbook_.get_thumbnail().empty())
|
|
|
|
{
|
|
|
|
const auto &thumbnail = workbook_.get_thumbnail();
|
2016-08-03 12:12:18 +08:00
|
|
|
archive_.write_string(std::string(thumbnail.begin(), thumbnail.end()), path("docProps/thumbnail.jpeg"));
|
2016-03-10 17:12:51 +08:00
|
|
|
}
|
2015-10-30 01:46:56 +08:00
|
|
|
}
|
|
|
|
|
2015-10-30 07:37:07 +08:00
|
|
|
void excel_serializer::write_worksheets()
|
2015-10-30 01:46:56 +08:00
|
|
|
{
|
2016-07-27 09:57:35 +08:00
|
|
|
std::size_t index = 1;
|
2015-11-01 22:43:01 +08:00
|
|
|
|
2016-07-27 09:57:35 +08:00
|
|
|
for (const auto ws : workbook_)
|
2015-10-30 01:46:56 +08:00
|
|
|
{
|
2016-07-27 09:57:35 +08:00
|
|
|
auto target = "worksheets/sheet" + std::to_string(index++) + ".xml";
|
|
|
|
|
|
|
|
for (const auto &rel : workbook_.get_relationships())
|
2015-10-30 01:46:56 +08:00
|
|
|
{
|
2016-07-27 09:57:35 +08:00
|
|
|
if (rel.get_target_uri() != target) continue;
|
2015-11-01 22:43:01 +08:00
|
|
|
|
2016-07-27 09:57:35 +08:00
|
|
|
worksheet_serializer serializer_(ws);
|
2016-08-03 12:12:18 +08:00
|
|
|
path ws_path(rel.get_target_uri().substr(0, 3) != "xl/" ? "xl/" : "", '/');
|
|
|
|
ws_path.append(rel.get_target_uri());
|
2016-07-27 09:57:35 +08:00
|
|
|
std::ostringstream ss;
|
|
|
|
pugi::xml_document worksheet_xml;
|
|
|
|
serializer_.write_worksheet(worksheet_xml);
|
|
|
|
worksheet_xml.save(ss);
|
2016-08-03 12:12:18 +08:00
|
|
|
archive_.write_string(ss.str(), ws_path);
|
2016-07-27 09:57:35 +08:00
|
|
|
|
|
|
|
break;
|
|
|
|
}
|
2015-10-30 01:46:56 +08:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2015-10-30 07:37:07 +08:00
|
|
|
void excel_serializer::write_external_links()
|
|
|
|
{
|
|
|
|
}
|
2015-11-01 22:43:01 +08:00
|
|
|
|
2015-10-30 07:37:07 +08:00
|
|
|
bool excel_serializer::save_stream_workbook(std::ostream &stream, bool as_template)
|
2015-10-30 01:46:56 +08:00
|
|
|
{
|
2015-10-30 07:37:07 +08:00
|
|
|
write_data(as_template);
|
|
|
|
archive_.save(stream);
|
2015-11-01 22:43:01 +08:00
|
|
|
|
2015-10-30 07:37:07 +08:00
|
|
|
return true;
|
2015-10-30 01:46:56 +08:00
|
|
|
}
|
|
|
|
|
2016-08-03 12:12:18 +08:00
|
|
|
bool excel_serializer::save_workbook(const path &filename, bool as_template)
|
2015-10-30 01:46:56 +08:00
|
|
|
{
|
2015-10-30 07:37:07 +08:00
|
|
|
write_data(as_template);
|
|
|
|
archive_.save(filename);
|
|
|
|
|
2015-10-30 01:46:56 +08:00
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
2015-10-30 07:37:07 +08:00
|
|
|
bool excel_serializer::save_virtual_workbook(std::vector<std::uint8_t> &bytes, bool as_template)
|
2015-10-30 01:46:56 +08:00
|
|
|
{
|
2015-10-30 07:37:07 +08:00
|
|
|
write_data(as_template);
|
|
|
|
archive_.save(bytes);
|
2015-11-01 22:43:01 +08:00
|
|
|
|
2015-10-30 07:37:07 +08:00
|
|
|
return true;
|
2015-10-30 01:46:56 +08:00
|
|
|
}
|
2015-11-01 22:43:01 +08:00
|
|
|
|
2016-06-11 01:40:50 +08:00
|
|
|
detail::stylesheet &excel_serializer::get_stylesheet()
|
|
|
|
{
|
|
|
|
return workbook_.d_->stylesheet_;
|
|
|
|
}
|
|
|
|
|
2015-10-21 11:30:10 +08:00
|
|
|
} // namespace xlnt
|