mirror of
https://github.com/tfussell/xlnt.git
synced 2024-03-22 13:11:17 +08:00
continue work on workbook metadata properties
This commit is contained in:
parent
f18e9dbc09
commit
571c0103b5
55
README.md
55
README.md
|
@ -72,7 +72,60 @@ git submodule update --init --remote
|
||||||
|
|
||||||
## Documentation
|
## Documentation
|
||||||
|
|
||||||
More detailed documentation with examples can be found on [Read The Docs](http://xlnt.readthedocs.org/en/latest/) (Warning: As of November 9, 2016 this is very out of date).
|
Properties
|
||||||
|
|
||||||
|
```c++
|
||||||
|
xlnt::workbook wb;
|
||||||
|
|
||||||
|
wb.core_property(xlnt::core_property::category, "hors categorie");
|
||||||
|
wb.core_property(xlnt::core_property::content_status, "good");
|
||||||
|
wb.core_property(xlnt::core_property::created, xlnt::datetime(2017, 1, 15));
|
||||||
|
wb.core_property(xlnt::core_property::creator, "me");
|
||||||
|
wb.core_property(xlnt::core_property::description, "description");
|
||||||
|
wb.core_property(xlnt::core_property::identifier, "id");
|
||||||
|
wb.core_property(xlnt::core_property::keywords, { "wow", "such" });
|
||||||
|
wb.core_property(xlnt::core_property::language, "Esperanto");
|
||||||
|
wb.core_property(xlnt::core_property::last_modified_by, "someone");
|
||||||
|
wb.core_property(xlnt::core_property::last_printed, xlnt::datetime(2017, 1, 15));
|
||||||
|
wb.core_property(xlnt::core_property::modified, xlnt::datetime(2017, 1, 15));
|
||||||
|
wb.core_property(xlnt::core_property::revision, "3");
|
||||||
|
wb.core_property(xlnt::core_property::subject, "subject");
|
||||||
|
wb.core_property(xlnt::core_property::title, "title");
|
||||||
|
wb.core_property(xlnt::core_property::version, "1.0");
|
||||||
|
|
||||||
|
wb.extended_property(xlnt::extended_property::application, "xlnt");
|
||||||
|
wb.extended_property(xlnt::extended_property::app_version, "0.9.3");
|
||||||
|
wb.extended_property(xlnt::extended_property::characters, 123);
|
||||||
|
wb.extended_property(xlnt::extended_property::characters_with_spaces, 124);
|
||||||
|
wb.extended_property(xlnt::extended_property::company, "Incorporated Inc.");
|
||||||
|
wb.extended_property(xlnt::extended_property::dig_sig, "?");
|
||||||
|
wb.extended_property(xlnt::extended_property::doc_security, 0);
|
||||||
|
wb.extended_property(xlnt::extended_property::heading_pairs, true);
|
||||||
|
wb.extended_property(xlnt::extended_property::hidden_slides, false);
|
||||||
|
wb.extended_property(xlnt::extended_property::h_links, 0);
|
||||||
|
wb.extended_property(xlnt::extended_property::hyperlink_base, 0);
|
||||||
|
wb.extended_property(xlnt::extended_property::hyperlinks_changed, true);
|
||||||
|
wb.extended_property(xlnt::extended_property::lines, 42);
|
||||||
|
wb.extended_property(xlnt::extended_property::links_up_to_date, false);
|
||||||
|
wb.extended_property(xlnt::extended_property::manager, "johnny");
|
||||||
|
wb.extended_property(xlnt::extended_property::m_m_clips, "?");
|
||||||
|
wb.extended_property(xlnt::extended_property::notes, "note");
|
||||||
|
wb.extended_property(xlnt::extended_property::pages, 19);
|
||||||
|
wb.extended_property(xlnt::extended_property::paragraphs, 18);
|
||||||
|
wb.extended_property(xlnt::extended_property::presentation_format, "format");
|
||||||
|
wb.extended_property(xlnt::extended_property::scale_crop, true);
|
||||||
|
wb.extended_property(xlnt::extended_property::shared_doc, false);
|
||||||
|
wb.extended_property(xlnt::extended_property::slides, 17);
|
||||||
|
wb.extended_property(xlnt::extended_property::template_, "template!");
|
||||||
|
wb.extended_property(xlnt::extended_property::titles_of_parts, { "title" });
|
||||||
|
wb.extended_property(xlnt::extended_property::total_time, 16);
|
||||||
|
wb.extended_property(xlnt::extended_property::words, 101);
|
||||||
|
|
||||||
|
wb.custom_property("test", { 1, 2, 3 });
|
||||||
|
wb.custom_property("Editor", "John Smith");
|
||||||
|
|
||||||
|
wb.save("lots_of_properties.xlsx");
|
||||||
|
```
|
||||||
|
|
||||||
## License
|
## License
|
||||||
xlnt is released to the public for free under the terms of the MIT License. See [LICENSE.md](https://github.com/tfussell/xlnt/blob/master/LICENCE.md) for the full text of the license and the licenses of xlnt's third-party dependencies. [LICENSE.md](https://github.com/tfussell/xlnt/blob/master/LICENCE.md) should be distributed alongside any assemblies that use xlnt in source or compiled form.
|
xlnt is released to the public for free under the terms of the MIT License. See [LICENSE.md](https://github.com/tfussell/xlnt/blob/master/LICENCE.md) for the full text of the license and the licenses of xlnt's third-party dependencies. [LICENSE.md](https://github.com/tfussell/xlnt/blob/master/LICENCE.md) should be distributed alongside any assemblies that use xlnt in source or compiled form.
|
||||||
|
|
102
include/xlnt/utils/variant.hpp
Normal file
102
include/xlnt/utils/variant.hpp
Normal file
|
@ -0,0 +1,102 @@
|
||||||
|
// Copyright (c) 2017 Thomas Fussell
|
||||||
|
//
|
||||||
|
// 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
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <string>
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
|
#include <xlnt/xlnt_config.hpp>
|
||||||
|
|
||||||
|
namespace xlnt {
|
||||||
|
|
||||||
|
struct datetime;
|
||||||
|
|
||||||
|
class XLNT_API variant
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
enum class type
|
||||||
|
{
|
||||||
|
vector,
|
||||||
|
//array,
|
||||||
|
//blob,
|
||||||
|
//oblob,
|
||||||
|
//empty,
|
||||||
|
null,
|
||||||
|
//i1,
|
||||||
|
//i2,
|
||||||
|
i4,
|
||||||
|
//i8,
|
||||||
|
//integer,
|
||||||
|
//ui1,
|
||||||
|
//ui2,
|
||||||
|
//ui4,
|
||||||
|
//ui8,
|
||||||
|
//uint,
|
||||||
|
//r4,
|
||||||
|
//r8,
|
||||||
|
//decimal,
|
||||||
|
lpstr,
|
||||||
|
//lpwstr,
|
||||||
|
//bstr,
|
||||||
|
date,
|
||||||
|
//filetime,
|
||||||
|
boolean,
|
||||||
|
//cy,
|
||||||
|
//error,
|
||||||
|
//stream,
|
||||||
|
//ostream,
|
||||||
|
//storage,
|
||||||
|
//ostorage,
|
||||||
|
//vstream,
|
||||||
|
//clsid
|
||||||
|
};
|
||||||
|
|
||||||
|
variant();
|
||||||
|
variant(const std::string &value);
|
||||||
|
variant(const char *value);
|
||||||
|
variant(int value);
|
||||||
|
variant(bool value);
|
||||||
|
variant(const datetime &value);
|
||||||
|
variant(const std::initializer_list<int> &value);
|
||||||
|
variant(const std::vector<int> &value);
|
||||||
|
variant(const std::initializer_list<const char *> &value);
|
||||||
|
variant(const std::vector<const char *> &value);
|
||||||
|
variant(const std::initializer_list<std::string> &value);
|
||||||
|
variant(const std::vector<std::string> &value);
|
||||||
|
|
||||||
|
bool is(type t) const;
|
||||||
|
|
||||||
|
template<typename T>
|
||||||
|
T get() const;
|
||||||
|
|
||||||
|
type value_type() const;
|
||||||
|
|
||||||
|
private:
|
||||||
|
type type_;
|
||||||
|
std::vector<variant> vector_value_;
|
||||||
|
std::int32_t i4_value_;
|
||||||
|
std::string lpstr_value_;
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace xlnt
|
80
include/xlnt/workbook/metadata_property.hpp
Normal file
80
include/xlnt/workbook/metadata_property.hpp
Normal file
|
@ -0,0 +1,80 @@
|
||||||
|
// Copyright (c) 2017 Thomas Fussell
|
||||||
|
//
|
||||||
|
// 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
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <xlnt/xlnt_config.hpp>
|
||||||
|
|
||||||
|
namespace xlnt {
|
||||||
|
|
||||||
|
enum class core_property
|
||||||
|
{
|
||||||
|
category,
|
||||||
|
content_status,
|
||||||
|
created,
|
||||||
|
creator,
|
||||||
|
description,
|
||||||
|
identifier,
|
||||||
|
keywords,
|
||||||
|
language,
|
||||||
|
last_modified_by,
|
||||||
|
last_printed,
|
||||||
|
modified,
|
||||||
|
revision,
|
||||||
|
subject,
|
||||||
|
title,
|
||||||
|
version
|
||||||
|
};
|
||||||
|
|
||||||
|
enum class extended_property
|
||||||
|
{
|
||||||
|
application,
|
||||||
|
app_version,
|
||||||
|
characters,
|
||||||
|
characters_with_spaces,
|
||||||
|
company,
|
||||||
|
dig_sig,
|
||||||
|
doc_security,
|
||||||
|
heading_pairs,
|
||||||
|
hidden_slides,
|
||||||
|
h_links,
|
||||||
|
hyperlink_base,
|
||||||
|
hyperlinks_changed,
|
||||||
|
lines,
|
||||||
|
links_up_to_date,
|
||||||
|
manager,
|
||||||
|
m_m_clips,
|
||||||
|
notes,
|
||||||
|
pages,
|
||||||
|
paragraphs,
|
||||||
|
presentation_format,
|
||||||
|
scale_crop,
|
||||||
|
shared_doc,
|
||||||
|
slides,
|
||||||
|
template_,
|
||||||
|
titles_of_parts,
|
||||||
|
total_time,
|
||||||
|
words
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace xlnt
|
|
@ -37,6 +37,8 @@
|
||||||
namespace xlnt {
|
namespace xlnt {
|
||||||
|
|
||||||
enum class calendar;
|
enum class calendar;
|
||||||
|
enum class core_property;
|
||||||
|
enum class extended_property;
|
||||||
enum class relationship_type;
|
enum class relationship_type;
|
||||||
|
|
||||||
class alignment;
|
class alignment;
|
||||||
|
@ -52,6 +54,7 @@ class font;
|
||||||
class format;
|
class format;
|
||||||
class rich_text;
|
class rich_text;
|
||||||
class manifest;
|
class manifest;
|
||||||
|
class metadata_property;
|
||||||
class named_range;
|
class named_range;
|
||||||
class number_format;
|
class number_format;
|
||||||
class path;
|
class path;
|
||||||
|
@ -63,6 +66,7 @@ class relationship;
|
||||||
class style;
|
class style;
|
||||||
class style_serializer;
|
class style_serializer;
|
||||||
class theme;
|
class theme;
|
||||||
|
class variant;
|
||||||
class workbook_view;
|
class workbook_view;
|
||||||
class worksheet;
|
class worksheet;
|
||||||
class worksheet_iterator;
|
class worksheet_iterator;
|
||||||
|
@ -289,46 +293,42 @@ public:
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Returns true if the workbook has the core property with the given name.
|
/// Returns true if the workbook has the core property with the given name.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
bool has_core_property(const std::string &property_name) const;
|
bool has_core_property(xlnt::core_property type) const;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
///
|
///
|
||||||
/// </summary>
|
/// </summary>
|
||||||
std::vector<std::string> core_properties() const;
|
std::vector<xlnt::core_property> core_properties() const;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
///
|
///
|
||||||
/// </summary>
|
/// </summary>
|
||||||
template <typename T = std::string>
|
variant core_property(xlnt::core_property type) const;
|
||||||
T core_property(const std::string &property_name) const;
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
///
|
///
|
||||||
/// </summary>
|
/// </summary>
|
||||||
template <typename T = std::string>
|
void core_property(xlnt::core_property type, const variant &value);
|
||||||
void core_property(const std::string &property_name, const T value);
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Returns true if the workbook has the extended property with the given name.
|
/// Returns true if the workbook has the extended property with the given name.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
bool has_extended_property(const std::string &property_name) const;
|
bool has_extended_property(xlnt::extended_property type) const;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
///
|
///
|
||||||
/// </summary>
|
/// </summary>
|
||||||
std::vector<std::string> extended_properties() const;
|
std::vector<xlnt::extended_property> extended_properties() const;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
///
|
///
|
||||||
/// </summary>
|
/// </summary>
|
||||||
template <typename T = std::string>
|
variant extended_property(xlnt::extended_property type) const;
|
||||||
T extended_property(const std::string &property_name) const;
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
///
|
///
|
||||||
/// </summary>
|
/// </summary>
|
||||||
template <typename T = std::string>
|
void extended_property(xlnt::extended_property type, const variant &value);
|
||||||
void extended_property(const std::string &property_name, const T value);
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Returns true if the workbook has the custom property with the given name.
|
/// Returns true if the workbook has the custom property with the given name.
|
||||||
|
@ -343,14 +343,12 @@ public:
|
||||||
/// <summary>
|
/// <summary>
|
||||||
///
|
///
|
||||||
/// </summary>
|
/// </summary>
|
||||||
template <typename T = std::string>
|
variant custom_property(const std::string &property_name) const;
|
||||||
T custom_property(const std::string &property_name) const;
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
///
|
///
|
||||||
/// </summary>
|
/// </summary>
|
||||||
template <typename T = std::string>
|
void custom_property(const std::string &property_name, const variant &value);
|
||||||
void custom_property(const std::string &property_name, const T value);
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
///
|
///
|
||||||
|
@ -746,32 +744,17 @@ private:
|
||||||
/// <summary>
|
/// <summary>
|
||||||
///
|
///
|
||||||
/// </summary>
|
/// </summary>
|
||||||
void register_app_properties_in_manifest();
|
void register_package_part(relationship_type type);
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
///
|
///
|
||||||
/// </summary>
|
/// </summary>
|
||||||
void register_core_properties_in_manifest();
|
void register_workbook_part(relationship_type type);
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
///
|
///
|
||||||
/// </summary>
|
/// </summary>
|
||||||
void register_shared_string_table_in_manifest();
|
void register_worksheet_part(worksheet ws, relationship_type type);
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
///
|
|
||||||
/// </summary>
|
|
||||||
void register_stylesheet_in_manifest();
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
///
|
|
||||||
/// </summary>
|
|
||||||
void register_theme_in_manifest();
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
///
|
|
||||||
/// </summary>
|
|
||||||
void register_comments_in_manifest(worksheet ws);
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Removes calcChain part from manifest if no formulae remain in workbook.
|
/// Removes calcChain part from manifest if no formulae remain in workbook.
|
||||||
|
|
|
@ -61,11 +61,13 @@
|
||||||
#include <xlnt/utils/path.hpp>
|
#include <xlnt/utils/path.hpp>
|
||||||
#include <xlnt/utils/time.hpp>
|
#include <xlnt/utils/time.hpp>
|
||||||
#include <xlnt/utils/timedelta.hpp>
|
#include <xlnt/utils/timedelta.hpp>
|
||||||
|
#include <xlnt/utils/variant.hpp>
|
||||||
|
|
||||||
// workbook
|
// workbook
|
||||||
#include <xlnt/workbook/const_worksheet_iterator.hpp>
|
#include <xlnt/workbook/const_worksheet_iterator.hpp>
|
||||||
#include <xlnt/workbook/document_security.hpp>
|
#include <xlnt/workbook/document_security.hpp>
|
||||||
#include <xlnt/workbook/external_book.hpp>
|
#include <xlnt/workbook/external_book.hpp>
|
||||||
|
#include <xlnt/workbook/metadata_property.hpp>
|
||||||
#include <xlnt/workbook/named_range.hpp>
|
#include <xlnt/workbook/named_range.hpp>
|
||||||
#include <xlnt/workbook/theme.hpp>
|
#include <xlnt/workbook/theme.hpp>
|
||||||
#include <xlnt/workbook/workbook.hpp>
|
#include <xlnt/workbook/workbook.hpp>
|
||||||
|
|
|
@ -262,5 +262,128 @@ std::string to_string(border_side side)
|
||||||
default_case("top");
|
default_case("top");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
std::string to_string(core_property prop)
|
||||||
|
{
|
||||||
|
switch (prop)
|
||||||
|
{
|
||||||
|
case core_property::category:
|
||||||
|
return "category";
|
||||||
|
case core_property::content_status:
|
||||||
|
return "contentStatus";
|
||||||
|
case core_property::created:
|
||||||
|
return "created";
|
||||||
|
case core_property::creator:
|
||||||
|
return "creator";
|
||||||
|
case core_property::description:
|
||||||
|
return "description";
|
||||||
|
case core_property::identifier:
|
||||||
|
return "identifier";
|
||||||
|
case core_property::keywords:
|
||||||
|
return "keywords";
|
||||||
|
case core_property::language:
|
||||||
|
return "language";
|
||||||
|
case core_property::last_modified_by:
|
||||||
|
return "lastModifiedBy";
|
||||||
|
case core_property::last_printed:
|
||||||
|
return "lastPrinted";
|
||||||
|
case core_property::modified:
|
||||||
|
return "modified";
|
||||||
|
case core_property::revision:
|
||||||
|
return "revision";
|
||||||
|
case core_property::subject:
|
||||||
|
return "subject";
|
||||||
|
case core_property::title:
|
||||||
|
return "title";
|
||||||
|
case core_property::version:
|
||||||
|
return "version";
|
||||||
|
}
|
||||||
|
|
||||||
|
default_case("category");
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string to_string(extended_property prop)
|
||||||
|
{
|
||||||
|
switch (prop)
|
||||||
|
{
|
||||||
|
case extended_property::application:
|
||||||
|
return "Application";
|
||||||
|
case extended_property::app_version:
|
||||||
|
return "AppVersion";
|
||||||
|
case extended_property::characters:
|
||||||
|
return "Characters";
|
||||||
|
case extended_property::characters_with_spaces:
|
||||||
|
return "CharactersWithSpaces";
|
||||||
|
case extended_property::company:
|
||||||
|
return "Company";
|
||||||
|
case extended_property::dig_sig:
|
||||||
|
return "DigSig";
|
||||||
|
case extended_property::doc_security:
|
||||||
|
return "DocSecurity";
|
||||||
|
case extended_property::heading_pairs:
|
||||||
|
return "HeadingPairs";
|
||||||
|
case extended_property::hidden_slides:
|
||||||
|
return "HiddenSlides";
|
||||||
|
case extended_property::hyperlinks_changed:
|
||||||
|
return "HyperlinksChanged";
|
||||||
|
case extended_property::hyperlink_base:
|
||||||
|
return "HyperlinkBase";
|
||||||
|
case extended_property::h_links:
|
||||||
|
return "HLinks";
|
||||||
|
case extended_property::lines:
|
||||||
|
return "Lines";
|
||||||
|
case extended_property::links_up_to_date:
|
||||||
|
return "LinksUpToDate";
|
||||||
|
case extended_property::manager:
|
||||||
|
return "Manager";
|
||||||
|
case extended_property::m_m_clips:
|
||||||
|
return "MMClips";
|
||||||
|
case extended_property::notes:
|
||||||
|
return "Notes";
|
||||||
|
case extended_property::pages:
|
||||||
|
return "Pages";
|
||||||
|
case extended_property::paragraphs:
|
||||||
|
return "Paragraphs";
|
||||||
|
case extended_property::presentation_format:
|
||||||
|
return "PresentationFormat";
|
||||||
|
case extended_property::scale_crop:
|
||||||
|
return "ScaleCrop";
|
||||||
|
case extended_property::shared_doc:
|
||||||
|
return "SharedDoc";
|
||||||
|
case extended_property::slides:
|
||||||
|
return "Slides";
|
||||||
|
case extended_property::template_:
|
||||||
|
return "Template";
|
||||||
|
case extended_property::titles_of_parts:
|
||||||
|
return "TitlesOfParts";
|
||||||
|
case extended_property::total_time:
|
||||||
|
return "TotalTime";
|
||||||
|
case extended_property::words:
|
||||||
|
return "Words";
|
||||||
|
}
|
||||||
|
|
||||||
|
default_case("Application");
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string to_string(variant::type type)
|
||||||
|
{
|
||||||
|
switch (type)
|
||||||
|
{
|
||||||
|
case variant::type::boolean:
|
||||||
|
return "bool";
|
||||||
|
case variant::type::date:
|
||||||
|
return "date";
|
||||||
|
case variant::type::i4:
|
||||||
|
return "i4";
|
||||||
|
case variant::type::lpstr:
|
||||||
|
return "lpstr";
|
||||||
|
case variant::type::null:
|
||||||
|
return "null";
|
||||||
|
case variant::type::vector:
|
||||||
|
return "vector";
|
||||||
|
}
|
||||||
|
|
||||||
|
default_case("null");
|
||||||
|
}
|
||||||
|
|
||||||
} // namespace detail
|
} // namespace detail
|
||||||
} // namespace xlnt
|
} // namespace xlnt
|
||||||
|
|
|
@ -9,7 +9,9 @@
|
||||||
#include <xlnt/styles/horizontal_alignment.hpp>
|
#include <xlnt/styles/horizontal_alignment.hpp>
|
||||||
#include <xlnt/styles/vertical_alignment.hpp>
|
#include <xlnt/styles/vertical_alignment.hpp>
|
||||||
#include <xlnt/utils/exceptions.hpp>
|
#include <xlnt/utils/exceptions.hpp>
|
||||||
|
#include <xlnt/utils/variant.hpp>
|
||||||
#include <xlnt/worksheet/pane.hpp>
|
#include <xlnt/worksheet/pane.hpp>
|
||||||
|
#include <xlnt/workbook/metadata_property.hpp>
|
||||||
|
|
||||||
namespace xlnt {
|
namespace xlnt {
|
||||||
namespace detail {
|
namespace detail {
|
||||||
|
@ -36,6 +38,12 @@ std::string to_string(horizontal_alignment horizontal_alignment);
|
||||||
|
|
||||||
std::string to_string(border_side side);
|
std::string to_string(border_side side);
|
||||||
|
|
||||||
|
std::string to_string(core_property prop);
|
||||||
|
|
||||||
|
std::string to_string(extended_property prop);
|
||||||
|
|
||||||
|
std::string to_string(variant::type type);
|
||||||
|
|
||||||
} // namespace detail
|
} // namespace detail
|
||||||
} // namespace xlnt
|
} // namespace xlnt
|
||||||
|
|
||||||
|
|
|
@ -31,6 +31,7 @@
|
||||||
#include <detail/worksheet_impl.hpp>
|
#include <detail/worksheet_impl.hpp>
|
||||||
#include <xlnt/packaging/manifest.hpp>
|
#include <xlnt/packaging/manifest.hpp>
|
||||||
#include <xlnt/utils/datetime.hpp>
|
#include <xlnt/utils/datetime.hpp>
|
||||||
|
#include <xlnt/utils/variant.hpp>
|
||||||
#include <xlnt/workbook/calculation_properties.hpp>
|
#include <xlnt/workbook/calculation_properties.hpp>
|
||||||
#include <xlnt/workbook/theme.hpp>
|
#include <xlnt/workbook/theme.hpp>
|
||||||
#include <xlnt/workbook/workbook_view.hpp>
|
#include <xlnt/workbook/workbook_view.hpp>
|
||||||
|
@ -94,9 +95,9 @@ struct workbook_impl
|
||||||
optional<theme> theme_;
|
optional<theme> theme_;
|
||||||
std::unordered_map<std::string, std::vector<std::uint8_t>> images_;
|
std::unordered_map<std::string, std::vector<std::uint8_t>> images_;
|
||||||
|
|
||||||
std::unordered_map<std::string, std::string> core_properties_;
|
std::unordered_map<xlnt::core_property, variant, xlnt::scoped_enum_hash<xlnt::core_property>> core_properties_;
|
||||||
std::unordered_map<std::string, std::string> extended_properties_;
|
std::unordered_map<xlnt::extended_property, variant, xlnt::scoped_enum_hash<xlnt::extended_property>> extended_properties_;
|
||||||
std::unordered_map<std::string, std::string> custom_properties_;
|
std::unordered_map<std::string, variant> custom_properties_;
|
||||||
|
|
||||||
std::unordered_map<std::string, std::string> sheet_title_rel_id_map_;
|
std::unordered_map<std::string, std::string> sheet_title_rel_id_map_;
|
||||||
|
|
||||||
|
|
|
@ -20,9 +20,11 @@
|
||||||
//
|
//
|
||||||
// @license: http://www.opensource.org/licenses/mit-license.php
|
// @license: http://www.opensource.org/licenses/mit-license.php
|
||||||
// @author: see AUTHORS file
|
// @author: see AUTHORS file
|
||||||
|
|
||||||
#include <cmath>
|
#include <cmath>
|
||||||
#include <numeric> // for std::accumulate
|
#include <numeric> // for std::accumulate
|
||||||
#include <string>
|
#include <string>
|
||||||
|
#include <unordered_set>
|
||||||
|
|
||||||
#include <xlnt/cell/cell.hpp>
|
#include <xlnt/cell/cell.hpp>
|
||||||
#include <xlnt/packaging/manifest.hpp>
|
#include <xlnt/packaging/manifest.hpp>
|
||||||
|
@ -91,15 +93,15 @@ void xlsx_producer::populate_archive()
|
||||||
|
|
||||||
if (rel.type() == relationship_type::core_properties)
|
if (rel.type() == relationship_type::core_properties)
|
||||||
{
|
{
|
||||||
write_properties(rel);
|
write_core_properties(rel);
|
||||||
}
|
}
|
||||||
else if (rel.type() == relationship_type::extended_properties)
|
else if (rel.type() == relationship_type::extended_properties)
|
||||||
{
|
{
|
||||||
write_properties(rel);
|
write_extended_properties(rel);
|
||||||
}
|
}
|
||||||
else if (rel.type() == relationship_type::custom_properties)
|
else if (rel.type() == relationship_type::custom_properties)
|
||||||
{
|
{
|
||||||
write_properties(rel);
|
write_custom_properties(rel);
|
||||||
}
|
}
|
||||||
else if (rel.type() == relationship_type::office_document)
|
else if (rel.type() == relationship_type::office_document)
|
||||||
{
|
{
|
||||||
|
@ -164,177 +166,207 @@ void xlsx_producer::write_content_types()
|
||||||
write_end_element(xmlns, "Types");
|
write_end_element(xmlns, "Types");
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
void xlsx_producer::write_property(const std::string &name, const variant &value, const std::string &ns, bool custom)
|
||||||
Core Properties:
|
|
||||||
- category
|
|
||||||
- contentStatus
|
|
||||||
- dcterms:created
|
|
||||||
- dc:creator
|
|
||||||
- dc:description
|
|
||||||
- dc:identifier
|
|
||||||
- keywords
|
|
||||||
- dc:language
|
|
||||||
- lastModifiedBy
|
|
||||||
- lastPrinted
|
|
||||||
- dcterms:modified
|
|
||||||
- revision
|
|
||||||
- dc:subject
|
|
||||||
- dc:title
|
|
||||||
- version
|
|
||||||
|
|
||||||
Extended Properties (SpreadsheetML):
|
|
||||||
|
|
||||||
|
|
||||||
Custom Properties:
|
|
||||||
|
|
||||||
*/
|
|
||||||
void xlsx_producer::write_properties(const relationship &rel)
|
|
||||||
{
|
{
|
||||||
std::vector<std::pair<std::string, std::string>> properties;
|
if (custom)
|
||||||
std::unordered_map<std::string, std::string> namespaces;
|
|
||||||
|
|
||||||
xml::qname root_element;
|
|
||||||
auto xmlns = ""s;
|
|
||||||
|
|
||||||
if (rel.type() == relationship_type::core_properties)
|
|
||||||
{
|
{
|
||||||
xmlns = "http://schemas.openxmlformats.org/officeDocument/2006/core-properties";
|
write_start_element(ns, "property");
|
||||||
root_element = xml::qname(constants::ns("core-properties"), "coreProperties");
|
write_attribute("name", name);
|
||||||
|
|
||||||
for (const auto &property_name : source_.core_properties())
|
|
||||||
{
|
|
||||||
properties.emplace_back(property_name, source_.core_property(property_name));
|
|
||||||
|
|
||||||
if (property_name == "created" || property_name == "modified")
|
|
||||||
{
|
|
||||||
namespaces.emplace(constants::ns("dcterms"), "dcterms");
|
|
||||||
namespaces.emplace(constants::ns("xsi"), "xsi");
|
|
||||||
}
|
|
||||||
else if (property_name == "creator" || property_name == "description"
|
|
||||||
|| property_name == "identifier" || property_name == "language"
|
|
||||||
|| property_name == "subject" || property_name == "title")
|
|
||||||
{
|
|
||||||
namespaces.emplace(constants::ns("dc"), "dc");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
else if (rel.type() == relationship_type::extended_properties)
|
else
|
||||||
{
|
{
|
||||||
xmlns = "http://schemas.openxmlformats.org/officeDocument/2006/extended-properties";
|
write_start_element(ns, name);
|
||||||
root_element = xml::qname(xmlns, "Properties");
|
|
||||||
|
|
||||||
namespaces.emplace(xmlns, "");
|
|
||||||
|
|
||||||
for (const auto &property_name : source_.extended_properties())
|
|
||||||
{
|
|
||||||
properties.emplace_back(property_name, source_.extended_property(property_name));
|
|
||||||
|
|
||||||
if (property_name == "HeadingsOfParts" || property_name == "TitlesOfParts")
|
|
||||||
{
|
|
||||||
namespaces.emplace(constants::ns("vt"), "vt");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else if (rel.type() == relationship_type::custom_properties)
|
|
||||||
{
|
|
||||||
xmlns = "http://schemas.openxmlformats.org/officeDocument/2006/custom-properties";
|
|
||||||
root_element = xml::qname(xmlns, "Properties");
|
|
||||||
|
|
||||||
namespaces.emplace(xmlns, "");
|
|
||||||
namespaces.emplace(constants::ns("vt"), "vt");
|
|
||||||
|
|
||||||
for (const auto &property_name : source_.custom_properties())
|
|
||||||
{
|
|
||||||
properties.emplace_back(property_name, source_.custom_property(property_name));
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
write_start_element(root_element.namespace_(), root_element.name());
|
switch (value.value_type())
|
||||||
|
|
||||||
for (const auto &ns : namespaces)
|
|
||||||
{
|
{
|
||||||
write_namespace(ns.first, ns.second);
|
case variant::type::null:
|
||||||
}
|
break;
|
||||||
|
|
||||||
for (const auto &prop : properties)
|
case variant::type::boolean:
|
||||||
{
|
if (custom)
|
||||||
auto property_type = "normal"s;
|
|
||||||
auto property_ns = xmlns;
|
|
||||||
|
|
||||||
if (rel.type() == relationship_type::core_properties)
|
|
||||||
{
|
{
|
||||||
if (prop.first == "keywords")
|
write_attribute("fmtid", "{D5CDD505-2E9C-101B-9397-08002B2CF9AE}");
|
||||||
{
|
write_attribute("pid", 2);
|
||||||
property_type = "keywords";
|
|
||||||
}
|
|
||||||
else if (prop.first == "modified" || prop.first == "created")
|
|
||||||
{
|
|
||||||
property_type = "w3cdtf";
|
|
||||||
property_ns = constants::ns("dcterms");
|
|
||||||
}
|
|
||||||
else if (prop.first == "creator" || prop.first == "description"
|
|
||||||
|| prop.first == "identifier" || prop.first == "language"
|
|
||||||
|| prop.first == "subject" || prop.first == "title")
|
|
||||||
{
|
|
||||||
property_ns = constants::ns("dc");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else if (rel.type() == relationship_type::extended_properties)
|
|
||||||
{
|
|
||||||
if (prop.first == "HeadingsOfParts" || prop.first == "TitlesOfParts")
|
|
||||||
{
|
|
||||||
property_type = "vt:vector";
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
write_start_element(property_ns, prop.first);
|
write_characters(write_bool(value.get<bool>()));
|
||||||
|
break;
|
||||||
|
|
||||||
if (property_type == "vt:vector")
|
case variant::type::i4:
|
||||||
|
if (custom)
|
||||||
{
|
{
|
||||||
write_start_element(constants::ns("vt"), "vector");
|
write_attribute("fmtid", "{D5CDD505-2E9C-101B-9397-08002B2CF9AE}");
|
||||||
|
write_attribute("pid", 2);
|
||||||
|
}
|
||||||
|
|
||||||
auto split = std::vector<std::string>();
|
write_characters(value.get<std::int32_t>());
|
||||||
auto delim = ' ';
|
break;
|
||||||
auto previous_index = std::size_t(0);
|
|
||||||
auto delim_index = prop.second.find(delim);
|
|
||||||
|
|
||||||
while (delim_index != std::string::npos)
|
case variant::type::lpstr:
|
||||||
|
if (custom)
|
||||||
|
{
|
||||||
|
write_attribute("fmtid", "{D5CDD505-2E9C-101B-9397-08002B2CF9AE}");
|
||||||
|
write_attribute("pid", 2);
|
||||||
|
write_start_element(constants::ns("vt"), "lpwstr");
|
||||||
|
}
|
||||||
|
|
||||||
|
write_characters(value.get<std::string>());
|
||||||
|
|
||||||
|
if (custom)
|
||||||
|
{
|
||||||
|
write_end_element(constants::ns("vt"), "lpwstr");
|
||||||
|
}
|
||||||
|
|
||||||
|
break;
|
||||||
|
|
||||||
|
case variant::type::date:
|
||||||
|
write_attribute(xml::qname(constants::ns("xsi"), "type"), "dcterms:W3CDTF");
|
||||||
|
write_characters(value.get<datetime>().to_iso_string());
|
||||||
|
break;
|
||||||
|
|
||||||
|
case variant::type::vector:
|
||||||
|
{
|
||||||
|
write_start_element(constants::ns("vt"), "vector");
|
||||||
|
|
||||||
|
auto vector = value.get<std::vector<variant>>();
|
||||||
|
std::unordered_set<variant::type> types;
|
||||||
|
|
||||||
|
for (const auto &element : vector)
|
||||||
|
{
|
||||||
|
types.insert(element.value_type());
|
||||||
|
}
|
||||||
|
|
||||||
|
const auto is_mixed = types.size() > 1;
|
||||||
|
const auto vector_type = !is_mixed ? to_string(*types.begin()) : "variant";
|
||||||
|
|
||||||
|
write_attribute("size", vector.size());
|
||||||
|
write_attribute("baseType", vector_type);
|
||||||
|
|
||||||
|
for (std::size_t i = 0; i < vector.size(); ++i)
|
||||||
|
{
|
||||||
|
const auto &vector_element = vector.at(i);
|
||||||
|
|
||||||
|
if (is_mixed)
|
||||||
{
|
{
|
||||||
split.push_back(prop.second.substr(previous_index, delim_index - previous_index));
|
|
||||||
previous_index = delim_index;
|
|
||||||
delim_index = prop.second.find(delim);
|
|
||||||
}
|
|
||||||
|
|
||||||
split.push_back(prop.second.substr(previous_index));
|
|
||||||
|
|
||||||
write_attribute("size", split.size() / 2);
|
|
||||||
write_attribute("baseType", "variant");
|
|
||||||
|
|
||||||
for (std::size_t i = 0; i < split.size() / 2; ++i)
|
|
||||||
{
|
|
||||||
auto vt_type = split[i * 2];
|
|
||||||
auto vt_value = split[i * 2 + 1];
|
|
||||||
write_start_element(constants::ns("vt"), "variant");
|
write_start_element(constants::ns("vt"), "variant");
|
||||||
write_element(constants::ns("vt"), vt_type, vt_value);
|
}
|
||||||
|
|
||||||
|
switch (vector_element.value_type())
|
||||||
|
{
|
||||||
|
case variant::type::lpstr:
|
||||||
|
write_element(constants::ns("vt"), "lpstr", vector_element.get<std::string>());
|
||||||
|
break;
|
||||||
|
case variant::type::i4:
|
||||||
|
write_element(constants::ns("vt"), "i4", vector_element.get<std::int32_t>());
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (is_mixed)
|
||||||
|
{
|
||||||
write_end_element(constants::ns("vt"), "variant");
|
write_end_element(constants::ns("vt"), "variant");
|
||||||
}
|
}
|
||||||
|
|
||||||
write_end_element(constants::ns("vt"), "vector");
|
|
||||||
}
|
|
||||||
else if (property_type == "w3cdtf")
|
|
||||||
{
|
|
||||||
write_attribute(xml::qname(constants::ns("xsi"), "type"), "dcterms:W3CDTF");
|
|
||||||
write_characters(prop.second);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
write_characters(prop.second);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
write_end_element(property_ns, prop.first);
|
write_end_element(constants::ns("vt"), "vector");
|
||||||
}
|
}
|
||||||
|
|
||||||
write_end_element(root_element.namespace_(), root_element.name());
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (custom)
|
||||||
|
{
|
||||||
|
write_end_element(ns, "property");
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
write_end_element(ns, name);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
std::vector<std::pair<std::string, std::string>> core_property_namespace(core_property type)
|
||||||
|
{
|
||||||
|
if (type == core_property::created
|
||||||
|
|| type == core_property::modified)
|
||||||
|
{
|
||||||
|
return {{constants::ns("dcterms"), "dcterms"},
|
||||||
|
{constants::ns("xsi"), "xsi"}};
|
||||||
|
}
|
||||||
|
else if (type == core_property::title
|
||||||
|
|| type == core_property::subject
|
||||||
|
|| type == core_property::creator
|
||||||
|
|| type == core_property::description)
|
||||||
|
{
|
||||||
|
return {{constants::ns("dc"), "dc"}};
|
||||||
|
}
|
||||||
|
else if (type == core_property::keywords)
|
||||||
|
{
|
||||||
|
return {{constants::ns("core-properties"), "cp"},
|
||||||
|
{constants::ns("vt"), "vt"}};
|
||||||
|
}
|
||||||
|
|
||||||
|
return {{constants::ns("core-properties"), "cp"}};
|
||||||
|
}
|
||||||
|
|
||||||
|
void xlsx_producer::write_core_properties(const relationship &/*rel*/)
|
||||||
|
{
|
||||||
|
write_start_element(constants::ns("core-properties"), "coreProperties");
|
||||||
|
|
||||||
|
auto core_properties = source_.core_properties();
|
||||||
|
std::unordered_map<std::string, std::string> namespaces;
|
||||||
|
|
||||||
|
for (const auto &prop : core_properties)
|
||||||
|
{
|
||||||
|
for (const auto &ns : core_property_namespace(prop))
|
||||||
|
{
|
||||||
|
if (namespaces.count(ns.first) > 0) continue;
|
||||||
|
write_namespace(ns.first, ns.second);
|
||||||
|
namespaces.emplace(ns);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for (const auto &prop : core_properties)
|
||||||
|
{
|
||||||
|
write_property(to_string(prop), source_.core_property(prop),
|
||||||
|
core_property_namespace(prop).front().first, false);
|
||||||
|
}
|
||||||
|
|
||||||
|
write_end_element(constants::ns("core-properties"), "coreProperties");
|
||||||
|
}
|
||||||
|
|
||||||
|
void xlsx_producer::write_extended_properties(const relationship &/*rel*/)
|
||||||
|
{
|
||||||
|
write_start_element(constants::ns("extended-properties"), "Properties");
|
||||||
|
write_namespace(constants::ns("extended-properties"), "");
|
||||||
|
|
||||||
|
if (source_.has_extended_property(extended_property::heading_pairs)
|
||||||
|
|| source_.has_extended_property(extended_property::titles_of_parts))
|
||||||
|
{
|
||||||
|
write_namespace(constants::ns("vt"), "vt");
|
||||||
|
}
|
||||||
|
|
||||||
|
for (const auto &prop : source_.extended_properties())
|
||||||
|
{
|
||||||
|
write_property(to_string(prop), source_.extended_property(prop),
|
||||||
|
constants::ns("extended-properties"), false);
|
||||||
|
}
|
||||||
|
|
||||||
|
write_end_element(constants::ns("extended-properties"), "Properties");
|
||||||
|
}
|
||||||
|
|
||||||
|
void xlsx_producer::write_custom_properties(const relationship &/*rel*/)
|
||||||
|
{
|
||||||
|
write_start_element(constants::ns("custom-properties"), "Properties");
|
||||||
|
write_namespace(constants::ns("custom-properties"), "");
|
||||||
|
write_namespace(constants::ns("vt"), "vt");
|
||||||
|
|
||||||
|
for (const auto &prop : source_.custom_properties())
|
||||||
|
{
|
||||||
|
write_property(prop, source_.custom_property(prop),
|
||||||
|
constants::ns("custom-properties"), true);
|
||||||
|
}
|
||||||
|
|
||||||
|
write_end_element(constants::ns("custom-properties"), "Properties");
|
||||||
}
|
}
|
||||||
|
|
||||||
// Write SpreadsheetML-Specific Package Parts
|
// Write SpreadsheetML-Specific Package Parts
|
||||||
|
|
|
@ -71,7 +71,10 @@ private:
|
||||||
// Package Parts
|
// Package Parts
|
||||||
|
|
||||||
void write_content_types();
|
void write_content_types();
|
||||||
void write_properties(const relationship &rel);
|
void write_property(const std::string &name, const variant &value, const std::string &ns, bool custom);
|
||||||
|
void write_core_properties(const relationship &rel);
|
||||||
|
void write_extended_properties(const relationship &rel);
|
||||||
|
void write_custom_properties(const relationship &rel);
|
||||||
void write_image(const path &image_path);
|
void write_image(const path &image_path);
|
||||||
|
|
||||||
// SpreadsheetML-Specific Package Parts
|
// SpreadsheetML-Specific Package Parts
|
||||||
|
|
|
@ -214,8 +214,8 @@ std::vector<path> manifest::parts() const
|
||||||
return std::vector<path>(parts.begin(), parts.end());
|
return std::vector<path>(parts.begin(), parts.end());
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string manifest::register_relationship(
|
std::string manifest::register_relationship(const uri &source,
|
||||||
const uri &source, relationship_type type, const uri &target, target_mode mode)
|
relationship_type type, const uri &target, target_mode mode)
|
||||||
{
|
{
|
||||||
xlnt::relationship rel(next_relationship_id(source.path()), type, source, target, mode);
|
xlnt::relationship rel(next_relationship_id(source.path()), type, source, target, mode);
|
||||||
return register_relationship(rel);
|
return register_relationship(rel);
|
||||||
|
|
159
source/utils/variant.cpp
Normal file
159
source/utils/variant.cpp
Normal file
|
@ -0,0 +1,159 @@
|
||||||
|
// Copyright (c) 2017 Thomas Fussell
|
||||||
|
//
|
||||||
|
// 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
|
||||||
|
|
||||||
|
#include <xlnt/utils/variant.hpp>
|
||||||
|
#include <xlnt/utils/datetime.hpp>
|
||||||
|
|
||||||
|
namespace xlnt {
|
||||||
|
|
||||||
|
variant::variant()
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
variant::variant(const std::string &value)
|
||||||
|
: type_(type::lpstr),
|
||||||
|
lpstr_value_(value)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
variant::variant(const char *value) : variant(std::string(value))
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
variant::variant(int value)
|
||||||
|
: type_(type::i4),
|
||||||
|
i4_value_(value)
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
variant::variant(bool value)
|
||||||
|
: type_(type::boolean),
|
||||||
|
i4_value_(value ? 1 : 0)
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
variant::variant(const datetime &value)
|
||||||
|
: type_(type::date),
|
||||||
|
lpstr_value_(value.to_iso_string())
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
variant::variant(const std::initializer_list<int> &value)
|
||||||
|
: type_(type::vector)
|
||||||
|
{
|
||||||
|
for (const auto &v : value)
|
||||||
|
{
|
||||||
|
vector_value_.emplace_back(v);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
variant::variant(const std::vector<int> &value)
|
||||||
|
: type_(type::vector)
|
||||||
|
{
|
||||||
|
for (const auto &v : value)
|
||||||
|
{
|
||||||
|
vector_value_.emplace_back(v);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
variant::variant(const std::initializer_list<const char *> &value)
|
||||||
|
: type_(type::vector)
|
||||||
|
{
|
||||||
|
for (const auto &v : value)
|
||||||
|
{
|
||||||
|
vector_value_.emplace_back(v);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
variant::variant(const std::vector<const char *> &value)
|
||||||
|
: type_(type::vector)
|
||||||
|
{
|
||||||
|
for (const auto &v : value)
|
||||||
|
{
|
||||||
|
vector_value_.emplace_back(v);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
variant::variant(const std::initializer_list<std::string> &value)
|
||||||
|
: type_(type::vector)
|
||||||
|
{
|
||||||
|
for (const auto &v : value)
|
||||||
|
{
|
||||||
|
vector_value_.emplace_back(v);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
variant::variant(const std::vector<std::string> &value)
|
||||||
|
: type_(type::vector)
|
||||||
|
{
|
||||||
|
for (const auto &v : value)
|
||||||
|
{
|
||||||
|
vector_value_.emplace_back(v);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
bool variant::is(type t) const
|
||||||
|
{
|
||||||
|
return type_ == t;
|
||||||
|
}
|
||||||
|
|
||||||
|
template<>
|
||||||
|
XLNT_API std::string variant::get() const
|
||||||
|
{
|
||||||
|
return lpstr_value_;
|
||||||
|
}
|
||||||
|
|
||||||
|
template<>
|
||||||
|
XLNT_API std::vector<variant> variant::get() const
|
||||||
|
{
|
||||||
|
return vector_value_;
|
||||||
|
}
|
||||||
|
|
||||||
|
template<>
|
||||||
|
XLNT_API bool variant::get() const
|
||||||
|
{
|
||||||
|
return i4_value_ != 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
template<>
|
||||||
|
XLNT_API std::int32_t variant::get() const
|
||||||
|
{
|
||||||
|
return i4_value_;
|
||||||
|
}
|
||||||
|
|
||||||
|
template<>
|
||||||
|
XLNT_API datetime variant::get() const
|
||||||
|
{
|
||||||
|
return datetime::from_iso_string(lpstr_value_);
|
||||||
|
}
|
||||||
|
|
||||||
|
variant::type variant::value_type() const
|
||||||
|
{
|
||||||
|
return type_;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -110,7 +110,7 @@ public:
|
||||||
xlnt::workbook wb;
|
xlnt::workbook wb;
|
||||||
wb.load("data/21_custom_properties.xlsx");
|
wb.load("data/21_custom_properties.xlsx");
|
||||||
TS_ASSERT(wb.has_custom_property("Client"));
|
TS_ASSERT(wb.has_custom_property("Client"));
|
||||||
TS_ASSERT_EQUALS(wb.custom_property("Client"), "me!");
|
TS_ASSERT_EQUALS(wb.custom_property("Client").get<std::string>(), "me!");
|
||||||
}
|
}
|
||||||
|
|
||||||
void test_read_formulae()
|
void test_read_formulae()
|
||||||
|
|
|
@ -45,7 +45,9 @@
|
||||||
#include <xlnt/styles/style.hpp>
|
#include <xlnt/styles/style.hpp>
|
||||||
#include <xlnt/utils/exceptions.hpp>
|
#include <xlnt/utils/exceptions.hpp>
|
||||||
#include <xlnt/utils/path.hpp>
|
#include <xlnt/utils/path.hpp>
|
||||||
|
#include <xlnt/utils/variant.hpp>
|
||||||
#include <xlnt/workbook/const_worksheet_iterator.hpp>
|
#include <xlnt/workbook/const_worksheet_iterator.hpp>
|
||||||
|
#include <xlnt/workbook/metadata_property.hpp>
|
||||||
#include <xlnt/workbook/named_range.hpp>
|
#include <xlnt/workbook/named_range.hpp>
|
||||||
#include <xlnt/workbook/theme.hpp>
|
#include <xlnt/workbook/theme.hpp>
|
||||||
#include <xlnt/workbook/workbook.hpp>
|
#include <xlnt/workbook/workbook.hpp>
|
||||||
|
@ -104,9 +106,9 @@ void open_stream(std::ofstream &stream, const std::string &path)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
template<typename T>
|
template<typename T>
|
||||||
std::vector<std::string> keys(const T &container)
|
std::vector<typename T::key_type> keys(const T &container)
|
||||||
{
|
{
|
||||||
auto result = std::vector<std::string>();
|
auto result = std::vector<typename T::key_type>();
|
||||||
auto iter = container.begin();
|
auto iter = container.begin();
|
||||||
|
|
||||||
while (iter != container.end())
|
while (iter != container.end())
|
||||||
|
@ -121,72 +123,46 @@ std::vector<std::string> keys(const T &container)
|
||||||
|
|
||||||
namespace xlnt {
|
namespace xlnt {
|
||||||
|
|
||||||
bool workbook::has_core_property(const std::string &property_name) const
|
bool workbook::has_core_property(xlnt::core_property type) const
|
||||||
{
|
{
|
||||||
return d_->core_properties_.count(property_name) > 0;
|
return d_->core_properties_.count(type) > 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::vector<std::string> workbook::core_properties() const
|
std::vector<xlnt::core_property> workbook::core_properties() const
|
||||||
{
|
{
|
||||||
return keys(d_->core_properties_);
|
return keys(d_->core_properties_);
|
||||||
}
|
}
|
||||||
|
|
||||||
template <>
|
variant workbook::core_property(xlnt::core_property type) const
|
||||||
XLNT_API std::string workbook::core_property(const std::string &property_name) const
|
|
||||||
{
|
{
|
||||||
return d_->core_properties_.at(property_name);
|
return d_->core_properties_.at(type);
|
||||||
}
|
}
|
||||||
|
|
||||||
template <>
|
void workbook::core_property(xlnt::core_property type, const variant &value)
|
||||||
XLNT_API void workbook::core_property(const std::string &property_name, const std::string value)
|
|
||||||
{
|
{
|
||||||
d_->core_properties_[property_name] = value;
|
register_package_part(relationship_type::core_properties);
|
||||||
|
d_->core_properties_[type] = value;
|
||||||
}
|
}
|
||||||
|
|
||||||
template <>
|
bool workbook::has_extended_property(xlnt::extended_property type) const
|
||||||
XLNT_API void workbook::core_property(const std::string &property_name, const char *value)
|
|
||||||
{
|
{
|
||||||
d_->core_properties_[property_name] = value;
|
return d_->extended_properties_.count(type) > 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
template <>
|
std::vector<xlnt::extended_property> workbook::extended_properties() const
|
||||||
XLNT_API void workbook::core_property(const std::string &property_name, const datetime value)
|
|
||||||
{
|
|
||||||
d_->core_properties_[property_name] = value.to_iso_string();
|
|
||||||
}
|
|
||||||
|
|
||||||
bool workbook::has_extended_property(const std::string &property_name) const
|
|
||||||
{
|
|
||||||
return d_->extended_properties_.count(property_name) > 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
std::vector<std::string> workbook::extended_properties() const
|
|
||||||
{
|
{
|
||||||
return keys(d_->extended_properties_);
|
return keys(d_->extended_properties_);
|
||||||
}
|
}
|
||||||
|
|
||||||
template <>
|
void workbook::extended_property(xlnt::extended_property type, const variant &value)
|
||||||
XLNT_API void workbook::extended_property(const std::string &property_name, const std::string value)
|
|
||||||
{
|
{
|
||||||
d_->extended_properties_[property_name] = value;
|
register_package_part(relationship_type::extended_properties);
|
||||||
|
d_->extended_properties_[type] = value;
|
||||||
}
|
}
|
||||||
|
|
||||||
template <>
|
variant workbook::extended_property(xlnt::extended_property type) const
|
||||||
XLNT_API void workbook::extended_property(const std::string &property_name, const char *value)
|
|
||||||
{
|
{
|
||||||
d_->extended_properties_[property_name] = value;
|
return d_->extended_properties_.at(type);
|
||||||
}
|
|
||||||
|
|
||||||
template <>
|
|
||||||
XLNT_API void workbook::extended_property(const std::string &property_name, const datetime value)
|
|
||||||
{
|
|
||||||
d_->extended_properties_[property_name] = value.to_iso_string();
|
|
||||||
}
|
|
||||||
|
|
||||||
template <>
|
|
||||||
XLNT_API std::string workbook::extended_property(const std::string &property_name) const
|
|
||||||
{
|
|
||||||
return d_->extended_properties_.at(property_name);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool workbook::has_custom_property(const std::string &property_name) const
|
bool workbook::has_custom_property(const std::string &property_name) const
|
||||||
|
@ -199,20 +175,13 @@ std::vector<std::string> workbook::custom_properties() const
|
||||||
return keys(d_->custom_properties_);
|
return keys(d_->custom_properties_);
|
||||||
}
|
}
|
||||||
|
|
||||||
template <>
|
void workbook::custom_property(const std::string &property_name, const variant &value)
|
||||||
XLNT_API void workbook::custom_property(const std::string &property_name, const std::string value)
|
|
||||||
{
|
{
|
||||||
|
register_package_part(relationship_type::custom_properties);
|
||||||
d_->custom_properties_[property_name] = value;
|
d_->custom_properties_[property_name] = value;
|
||||||
}
|
}
|
||||||
|
|
||||||
template <>
|
variant workbook::custom_property(const std::string &property_name) const
|
||||||
XLNT_API void workbook::custom_property(const std::string &property_name, const char *value)
|
|
||||||
{
|
|
||||||
d_->custom_properties_[property_name] = value;
|
|
||||||
}
|
|
||||||
|
|
||||||
template <>
|
|
||||||
XLNT_API std::string workbook::custom_property(const std::string &property_name) const
|
|
||||||
{
|
{
|
||||||
return d_->custom_properties_.at(property_name);
|
return d_->custom_properties_.at(property_name);
|
||||||
}
|
}
|
||||||
|
@ -222,10 +191,7 @@ workbook workbook::empty()
|
||||||
auto impl = new detail::workbook_impl();
|
auto impl = new detail::workbook_impl();
|
||||||
workbook wb(impl);
|
workbook wb(impl);
|
||||||
|
|
||||||
wb.d_->manifest_.register_override_type(path("/xl/workbook.xml"),
|
wb.register_package_part(relationship_type::office_document);
|
||||||
"application/vnd.openxmlformats-officedocument.spreadsheetml.sheet.main+xml");
|
|
||||||
wb.d_->manifest_.register_relationship(uri("/"), relationship_type::office_document,
|
|
||||||
uri("xl/workbook.xml"), target_mode::internal);
|
|
||||||
|
|
||||||
wb.d_->manifest_.register_default_type("rels",
|
wb.d_->manifest_.register_default_type("rels",
|
||||||
"application/vnd.openxmlformats-package.relationships+xml");
|
"application/vnd.openxmlformats-package.relationships+xml");
|
||||||
|
@ -234,29 +200,19 @@ workbook workbook::empty()
|
||||||
|
|
||||||
wb.thumbnail(excel_thumbnail(), "jpeg", "image/jpeg");
|
wb.thumbnail(excel_thumbnail(), "jpeg", "image/jpeg");
|
||||||
|
|
||||||
wb.d_->manifest_.register_override_type(path("/docProps/core.xml"),
|
wb.core_property(xlnt::core_property::creator, "Microsoft Office User");
|
||||||
"application/vnd.openxmlformats-package.core-properties+xml");
|
wb.core_property(xlnt::core_property::last_modified_by, "Microsoft Office User");
|
||||||
wb.d_->manifest_.register_relationship(uri("/"), relationship_type::core_properties,
|
wb.core_property(xlnt::core_property::created, datetime(2016, 8, 12, 3, 16, 56));
|
||||||
uri("docProps/core.xml"), target_mode::internal);
|
wb.core_property(xlnt::core_property::modified, datetime(2016, 8, 12, 3, 17, 16));
|
||||||
|
|
||||||
wb.d_->manifest_.register_override_type(path("/docProps/app.xml"),
|
wb.extended_property(xlnt::extended_property::application, "Microsoft Macintosh Excel");
|
||||||
"application/vnd.openxmlformats-officedocument.extended-properties+xml");
|
wb.extended_property(xlnt::extended_property::doc_security, 0);
|
||||||
wb.d_->manifest_.register_relationship(uri("/"), relationship_type::extended_properties,
|
wb.extended_property(xlnt::extended_property::scale_crop, "false");
|
||||||
uri("docProps/app.xml"), target_mode::internal);
|
wb.extended_property(xlnt::extended_property::company, "");
|
||||||
|
wb.extended_property(xlnt::extended_property::links_up_to_date, false);
|
||||||
wb.core_property("creator", "Microsoft Office User");
|
wb.extended_property(xlnt::extended_property::shared_doc, false);
|
||||||
wb.core_property("lastModifiedBy", "Microsoft Office User");
|
wb.extended_property(xlnt::extended_property::hyperlinks_changed, false);
|
||||||
wb.core_property("created", datetime(2016, 8, 12, 3, 16, 56));
|
wb.extended_property(xlnt::extended_property::app_version, "15.0300");
|
||||||
wb.core_property("modified", datetime(2016, 8, 12, 3, 17, 16));
|
|
||||||
|
|
||||||
wb.extended_property("Application", "Microsoft Macintosh Excel");
|
|
||||||
wb.extended_property("DocSecurity", "0");
|
|
||||||
wb.extended_property("ScaleCrop", "false");
|
|
||||||
wb.extended_property("Company", "");
|
|
||||||
wb.extended_property("LinksUpToDate", "false");
|
|
||||||
wb.extended_property("SharedDoc", "false");
|
|
||||||
wb.extended_property("HyperlinksChanged", "false");
|
|
||||||
wb.extended_property("AppVersion", "15.0300");
|
|
||||||
|
|
||||||
auto file_version = detail::workbook_impl::file_version_t{"xl", 6, 6, 26709};
|
auto file_version = detail::workbook_impl::file_version_t{"xl", 6, 6, 26709};
|
||||||
wb.d_->file_version_ = file_version;
|
wb.d_->file_version_ = file_version;
|
||||||
|
@ -352,82 +308,182 @@ workbook::workbook(detail::workbook_impl *impl)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void workbook::register_app_properties_in_manifest()
|
path default_path(relationship_type type, std::size_t index = 0)
|
||||||
{
|
{
|
||||||
auto wb_rel = manifest().relationship(path("/"),
|
switch (type)
|
||||||
relationship_type::office_document);
|
|
||||||
|
|
||||||
if (!manifest().has_relationship(wb_rel.target().path(),
|
|
||||||
relationship_type::extended_properties))
|
|
||||||
{
|
{
|
||||||
manifest().register_override_type(path("/docProps/app.xml"),
|
case relationship_type::calculation_chain:
|
||||||
"application/vnd.openxmlformats-officedocument.extended-properties+xml");
|
return path("/xl/calcChain.xml");
|
||||||
manifest().register_relationship(uri("/"), relationship_type::extended_properties,
|
case relationship_type::chartsheet:
|
||||||
uri("docProps/app.xml"), target_mode::internal);
|
return path("/xl/sheets/.xml");
|
||||||
|
case relationship_type::comments:
|
||||||
|
return path("/xl/comments.xml");
|
||||||
|
case relationship_type::connections:
|
||||||
|
return path("/xl/connections.xml");
|
||||||
|
case relationship_type::core_properties:
|
||||||
|
return path("/docProps/core.xml");
|
||||||
|
case relationship_type::custom_properties:
|
||||||
|
return path("/docProps/custom.xml");
|
||||||
|
case relationship_type::custom_property:
|
||||||
|
return path("/xl/customProperty.xml");
|
||||||
|
case relationship_type::custom_xml_mappings:
|
||||||
|
return path("/xl/customXmlMappings.xml");
|
||||||
|
case relationship_type::dialogsheet:
|
||||||
|
return path("/xl/dialogsheets/sheet.xml");
|
||||||
|
case relationship_type::drawings:
|
||||||
|
return path("/xl/drawings/drawing.xml");
|
||||||
|
case relationship_type::extended_properties:
|
||||||
|
return path("/docProps/app.xml");
|
||||||
|
case relationship_type::external_workbook_references:
|
||||||
|
return path("/xl/external.xml");
|
||||||
|
case relationship_type::hyperlink:
|
||||||
|
return path("/xl/hyperlink.xml");
|
||||||
|
case relationship_type::image:
|
||||||
|
return path("?");
|
||||||
|
case relationship_type::office_document:
|
||||||
|
return path("/xl/workbook.xml");
|
||||||
|
case relationship_type::pivot_table:
|
||||||
|
return path("/xl/pivotTable.xml");
|
||||||
|
case relationship_type::pivot_table_cache_definition:
|
||||||
|
return path("?");
|
||||||
|
case relationship_type::pivot_table_cache_records:
|
||||||
|
return path("?");
|
||||||
|
case relationship_type::printer_settings:
|
||||||
|
return path("/xl/printerSettings.xml");
|
||||||
|
case relationship_type::query_table:
|
||||||
|
return path("/xl/queryTable.xml");
|
||||||
|
case relationship_type::revision_log:
|
||||||
|
return path("/xl/revisionLog.xml");
|
||||||
|
case relationship_type::shared_string_table:
|
||||||
|
return path("/xl/sharedStrings.xml");
|
||||||
|
case relationship_type::shared_workbook:
|
||||||
|
return path("/xl/sharedWorkbook.xml");
|
||||||
|
case relationship_type::shared_workbook_revision_headers:
|
||||||
|
return path("?");
|
||||||
|
case relationship_type::shared_workbook_user_data:
|
||||||
|
return path("?");
|
||||||
|
case relationship_type::single_cell_table_definitions:
|
||||||
|
return path("?");
|
||||||
|
case relationship_type::stylesheet:
|
||||||
|
return path("/xl/styles.xml");
|
||||||
|
case relationship_type::table_definition:
|
||||||
|
return path("/xl/tableDefinition.xml");
|
||||||
|
case relationship_type::theme:
|
||||||
|
return path("/xl/theme/theme1.xml");
|
||||||
|
case relationship_type::thumbnail:
|
||||||
|
return path("/docProps/thumbnail.jpg");
|
||||||
|
case relationship_type::unknown:
|
||||||
|
return path("/xl/unknown.xml");
|
||||||
|
case relationship_type::vml_drawing:
|
||||||
|
return path("/xl/vmlDrawing.xml");
|
||||||
|
case relationship_type::volatile_dependencies:
|
||||||
|
return path("/xl/volatileDependencies.xml");
|
||||||
|
case relationship_type::worksheet:
|
||||||
|
return path("/xl/worksheets/sheet" + std::to_string(index) + ".xml");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void workbook::register_core_properties_in_manifest()
|
std::string content_type(relationship_type type)
|
||||||
{
|
{
|
||||||
auto wb_rel = manifest().relationship(path("/"),
|
switch (type)
|
||||||
relationship_type::office_document);
|
|
||||||
|
|
||||||
if (!manifest().has_relationship(wb_rel.target().path(),
|
|
||||||
relationship_type::core_properties))
|
|
||||||
{
|
{
|
||||||
manifest().register_override_type(path("/docProps/core.xml"),
|
case relationship_type::calculation_chain:
|
||||||
"application/vnd.openxmlformats-package.core-properties+xml");
|
return "application/vnd.openxmlformats-officedocument.spreadsheetml.calcChain+xml";
|
||||||
manifest().register_relationship(uri("/"), relationship_type::core_properties,
|
case relationship_type::chartsheet:
|
||||||
uri("docProps/core.xml"), target_mode::internal);
|
return "application/vnd.openxmlformats-officedocument.spreadsheetml.chartsheet+xml";
|
||||||
|
case relationship_type::comments:
|
||||||
|
return "application/vnd.openxmlformats-officedocument.spreadsheetml.comments+xml";
|
||||||
|
case relationship_type::connections:
|
||||||
|
return "application/vnd.openxmlformats-officedocument.spreadsheetml.connections+xml";
|
||||||
|
case relationship_type::core_properties:
|
||||||
|
return "application/vnd.openxmlformats-package.core-properties+xml";
|
||||||
|
case relationship_type::custom_properties:
|
||||||
|
return "application/vnd.openxmlformats-officedocument.custom-properties+xml";
|
||||||
|
case relationship_type::custom_property:
|
||||||
|
return "";
|
||||||
|
case relationship_type::custom_xml_mappings:
|
||||||
|
return "application/xml";
|
||||||
|
case relationship_type::dialogsheet:
|
||||||
|
return "application/vnd.openxmlformats-officedocument.spreadsheetml.dialogsheet+xml";
|
||||||
|
case relationship_type::drawings:
|
||||||
|
return "application/vnd.openxmlformats-officedocument.drawing+xml";
|
||||||
|
case relationship_type::extended_properties:
|
||||||
|
return "application/vnd.openxmlformats-officedocument.extended-properties+xml";
|
||||||
|
case relationship_type::external_workbook_references:
|
||||||
|
return "application/vnd.openxmlformats-officedocument.spreadsheetml.externalLink+xml";
|
||||||
|
case relationship_type::hyperlink:
|
||||||
|
return "";
|
||||||
|
case relationship_type::image:
|
||||||
|
return "";
|
||||||
|
case relationship_type::office_document:
|
||||||
|
return "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet.main+xml";
|
||||||
|
case relationship_type::pivot_table:
|
||||||
|
return "application/vnd.openxmlformats-officedocument.spreadsheetml.pivotTable+xml";
|
||||||
|
case relationship_type::pivot_table_cache_definition:
|
||||||
|
return "application/vnd.openxmlformats-officedocument.spreadsheetml.pivotCacheDefinition+xml";
|
||||||
|
case relationship_type::pivot_table_cache_records:
|
||||||
|
return "application/vnd.openxmlformats-officedocument.spreadsheetml.pivotCacheRecords+xml";
|
||||||
|
case relationship_type::printer_settings:
|
||||||
|
return "application/vnd.openxmlformats-officedocument.spreadsheetml.printerSettings";
|
||||||
|
case relationship_type::query_table:
|
||||||
|
return "application/vnd.openxmlformats-officedocument.spreadsheetml.queryTable+xml";
|
||||||
|
case relationship_type::revision_log:
|
||||||
|
return "application/vnd.openxmlformats-officedocument.spreadsheetml.revisionLog+xml";
|
||||||
|
case relationship_type::shared_string_table:
|
||||||
|
return "application/vnd.openxmlformats-officedocument.spreadsheetml.sharedStrings+xml";
|
||||||
|
case relationship_type::shared_workbook:
|
||||||
|
return "";
|
||||||
|
case relationship_type::shared_workbook_revision_headers:
|
||||||
|
return "application/vnd.openxmlformats-officedocument.spreadsheetml.revisionHeaders+xml";
|
||||||
|
case relationship_type::shared_workbook_user_data:
|
||||||
|
return "application/vnd.openxmlformats-officedocument.spreadsheetml.userNames+xml";
|
||||||
|
case relationship_type::single_cell_table_definitions:
|
||||||
|
return "application/vnd.openxmlformats-officedocument.spreadsheetml.tableSingleCells+xml";
|
||||||
|
case relationship_type::stylesheet:
|
||||||
|
return "application/vnd.openxmlformats-officedocument.spreadsheetml.styles+xml";
|
||||||
|
case relationship_type::table_definition:
|
||||||
|
return "application/vnd.openxmlformats-officedocument.spreadsheetml.table+xml";
|
||||||
|
case relationship_type::theme:
|
||||||
|
return "application/vnd.openxmlformats-officedocument.theme+xml";
|
||||||
|
case relationship_type::thumbnail:
|
||||||
|
return "image/jpeg";
|
||||||
|
case relationship_type::unknown:
|
||||||
|
return "";
|
||||||
|
case relationship_type::vml_drawing:
|
||||||
|
return "application/vnd.openxmlformats-officedocument.vmlDrawing";
|
||||||
|
case relationship_type::volatile_dependencies:
|
||||||
|
return "application/vnd.openxmlformats-officedocument.spreadsheetml.volatileDependencies+xml";
|
||||||
|
case relationship_type::worksheet:
|
||||||
|
return "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet.main+xml";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void workbook::register_shared_string_table_in_manifest()
|
void workbook::register_package_part(relationship_type type)
|
||||||
{
|
{
|
||||||
auto wb_rel = manifest().relationship(path("/"),
|
if (!manifest().has_relationship(path("/"), type))
|
||||||
relationship_type::office_document);
|
|
||||||
|
|
||||||
if (!manifest().has_relationship(wb_rel.target().path(),
|
|
||||||
relationship_type::shared_string_table))
|
|
||||||
{
|
{
|
||||||
manifest().register_override_type(constants::part_shared_strings(),
|
manifest().register_override_type(default_path(type), content_type(type));
|
||||||
"application/vnd.openxmlformats-officedocument.spreadsheetml.sharedStrings+xml");
|
manifest().register_relationship(uri("/"), type,
|
||||||
manifest().register_relationship(wb_rel.target(), relationship_type::shared_string_table,
|
uri(default_path(type).relative_to(path("/")).string()),
|
||||||
uri("sharedStrings.xml"), target_mode::internal);
|
target_mode::internal);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void workbook::register_stylesheet_in_manifest()
|
void workbook::register_workbook_part(relationship_type type)
|
||||||
{
|
{
|
||||||
auto wb_rel = manifest().relationship(path("/"),
|
auto wb_rel = manifest().relationship(path("/"), relationship_type::office_document);
|
||||||
relationship_type::office_document);
|
auto wb_path = manifest().canonicalize({ wb_rel });
|
||||||
|
|
||||||
if (!manifest().has_relationship(wb_rel.target().path(),
|
if (!manifest().has_relationship(wb_path, type))
|
||||||
relationship_type::stylesheet))
|
|
||||||
{
|
{
|
||||||
manifest().register_override_type(constants::part_styles(),
|
manifest().register_override_type(default_path(type), content_type(type));
|
||||||
"application/vnd.openxmlformats-officedocument.spreadsheetml.styles+xml");
|
manifest().register_relationship(uri(wb_path.string()), type,
|
||||||
manifest().register_relationship(wb_rel.target(), relationship_type::stylesheet,
|
uri(default_path(type).relative_to(wb_path.resolve(path("/"))).string()),
|
||||||
uri("styles.xml"), target_mode::internal);
|
target_mode::internal);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void workbook::register_theme_in_manifest()
|
void workbook::register_worksheet_part(worksheet ws, relationship_type type)
|
||||||
{
|
|
||||||
auto wb_rel = manifest().relationship(path("/"),
|
|
||||||
relationship_type::office_document);
|
|
||||||
|
|
||||||
if (!manifest().has_relationship(wb_rel.target().path(),
|
|
||||||
relationship_type::theme))
|
|
||||||
{
|
|
||||||
manifest().register_override_type(constants::part_theme(),
|
|
||||||
"application/vnd.openxmlformats-officedocument.theme+xml");
|
|
||||||
manifest().register_relationship(wb_rel.target(), relationship_type::theme,
|
|
||||||
uri("theme/theme1.xml"), target_mode::internal);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void workbook::register_comments_in_manifest(worksheet ws)
|
|
||||||
{
|
{
|
||||||
auto wb_rel = manifest().relationship(path("/"),
|
auto wb_rel = manifest().relationship(path("/"),
|
||||||
relationship_type::office_document);
|
relationship_type::office_document);
|
||||||
|
@ -435,67 +491,70 @@ void workbook::register_comments_in_manifest(worksheet ws)
|
||||||
d_->sheet_title_rel_id_map_.at(ws.title()));
|
d_->sheet_title_rel_id_map_.at(ws.title()));
|
||||||
path ws_path(ws_rel.source().path().parent().append(ws_rel.target().path()));
|
path ws_path(ws_rel.source().path().parent().append(ws_rel.target().path()));
|
||||||
|
|
||||||
if (!manifest().has_relationship(ws_path, relationship_type::vml_drawing))
|
if (type == relationship_type::comments)
|
||||||
{
|
{
|
||||||
std::size_t file_number = 1;
|
if (!manifest().has_relationship(ws_path, relationship_type::vml_drawing))
|
||||||
path filename("vmlDrawing1.vml");
|
|
||||||
bool filename_exists = true;
|
|
||||||
|
|
||||||
while (filename_exists)
|
|
||||||
{
|
{
|
||||||
filename_exists = false;
|
std::size_t file_number = 1;
|
||||||
|
path filename("vmlDrawing1.vml");
|
||||||
|
bool filename_exists = true;
|
||||||
|
|
||||||
for (auto current_ws_rel :
|
while (filename_exists)
|
||||||
manifest().relationships(wb_rel.target().path(), xlnt::relationship_type::worksheet))
|
|
||||||
{
|
{
|
||||||
path current_ws_path(current_ws_rel.source().path().parent().append(current_ws_rel.target().path()));
|
filename_exists = false;
|
||||||
if (!manifest().has_relationship(current_ws_path, xlnt::relationship_type::vml_drawing)) continue;
|
|
||||||
|
|
||||||
for (auto current_ws_child_rel :
|
for (auto current_ws_rel :
|
||||||
manifest().relationships(current_ws_path, xlnt::relationship_type::vml_drawing))
|
manifest().relationships(wb_rel.target().path(), xlnt::relationship_type::worksheet))
|
||||||
{
|
{
|
||||||
if (current_ws_child_rel.target().path() == path("../drawings").append(filename))
|
path current_ws_path(current_ws_rel.source().path().parent().append(current_ws_rel.target().path()));
|
||||||
|
if (!manifest().has_relationship(current_ws_path, xlnt::relationship_type::vml_drawing)) continue;
|
||||||
|
|
||||||
|
for (auto current_ws_child_rel :
|
||||||
|
manifest().relationships(current_ws_path, xlnt::relationship_type::vml_drawing))
|
||||||
{
|
{
|
||||||
filename_exists = true;
|
if (current_ws_child_rel.target().path() == path("../drawings").append(filename))
|
||||||
break;
|
{
|
||||||
|
filename_exists = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (filename_exists)
|
||||||
|
{
|
||||||
|
file_number++;
|
||||||
|
filename = path("vmlDrawing" + std::to_string(file_number) + ".vml");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (filename_exists)
|
manifest().register_default_type("vml", "application/vnd.openxmlformats-officedocument.vmlDrawing");
|
||||||
{
|
|
||||||
file_number++;
|
const path relative_path(path("../drawings").append(filename));
|
||||||
filename = path("vmlDrawing" + std::to_string(file_number) + ".vml");
|
manifest().register_relationship(
|
||||||
}
|
uri(ws_path.string()), relationship_type::vml_drawing, uri(relative_path.string()), target_mode::internal);
|
||||||
}
|
}
|
||||||
|
|
||||||
manifest().register_default_type("vml", "application/vnd.openxmlformats-officedocument.vmlDrawing");
|
if (!manifest().has_relationship(ws_path, relationship_type::comments))
|
||||||
|
|
||||||
const path relative_path(path("../drawings").append(filename));
|
|
||||||
manifest().register_relationship(
|
|
||||||
uri(ws_path.string()), relationship_type::vml_drawing, uri(relative_path.string()), target_mode::internal);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!manifest().has_relationship(ws_path, relationship_type::comments))
|
|
||||||
{
|
|
||||||
std::size_t file_number = 1;
|
|
||||||
path filename("comments1.xml");
|
|
||||||
|
|
||||||
while (true)
|
|
||||||
{
|
{
|
||||||
if (!manifest().has_override_type(constants::package_xl().append(filename))) break;
|
std::size_t file_number = 1;
|
||||||
|
path filename("comments1.xml");
|
||||||
|
|
||||||
file_number++;
|
while (true)
|
||||||
filename = path("comments" + std::to_string(file_number) + ".xml");
|
{
|
||||||
|
if (!manifest().has_override_type(constants::package_xl().append(filename))) break;
|
||||||
|
|
||||||
|
file_number++;
|
||||||
|
filename = path("comments" + std::to_string(file_number) + ".xml");
|
||||||
|
}
|
||||||
|
|
||||||
|
const path absolute_path(constants::package_xl().append(filename));
|
||||||
|
manifest().register_override_type(
|
||||||
|
absolute_path, "application/vnd.openxmlformats-officedocument.spreadsheetml.comments+xml");
|
||||||
|
|
||||||
|
const path relative_path(path("..").append(filename));
|
||||||
|
manifest().register_relationship(
|
||||||
|
uri(ws_path.string()), relationship_type::comments, uri(relative_path.string()), target_mode::internal);
|
||||||
}
|
}
|
||||||
|
|
||||||
const path absolute_path(constants::package_xl().append(filename));
|
|
||||||
manifest().register_override_type(
|
|
||||||
absolute_path, "application/vnd.openxmlformats-officedocument.spreadsheetml.comments+xml");
|
|
||||||
|
|
||||||
const path relative_path(path("..").append(filename));
|
|
||||||
manifest().register_relationship(
|
|
||||||
uri(ws_path.string()), relationship_type::comments, uri(relative_path.string()), target_mode::internal);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1043,8 +1102,8 @@ const theme &workbook::theme() const
|
||||||
|
|
||||||
void workbook::theme(const class theme &value)
|
void workbook::theme(const class theme &value)
|
||||||
{
|
{
|
||||||
register_theme_in_manifest();
|
|
||||||
d_->theme_ = value;
|
d_->theme_ = value;
|
||||||
|
register_workbook_part(relationship_type::theme);
|
||||||
}
|
}
|
||||||
|
|
||||||
std::vector<named_range> workbook::named_ranges() const
|
std::vector<named_range> workbook::named_ranges() const
|
||||||
|
@ -1064,7 +1123,7 @@ std::vector<named_range> workbook::named_ranges() const
|
||||||
|
|
||||||
format workbook::create_format(bool default_format)
|
format workbook::create_format(bool default_format)
|
||||||
{
|
{
|
||||||
register_stylesheet_in_manifest();
|
register_workbook_part(relationship_type::stylesheet);
|
||||||
return d_->stylesheet_.get().create_format(default_format);
|
return d_->stylesheet_.get().create_format(default_format);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1132,7 +1191,7 @@ const std::vector<rich_text> &workbook::shared_strings() const
|
||||||
|
|
||||||
void workbook::add_shared_string(const rich_text &shared, bool allow_duplicates)
|
void workbook::add_shared_string(const rich_text &shared, bool allow_duplicates)
|
||||||
{
|
{
|
||||||
register_shared_string_table_in_manifest();
|
register_workbook_part(relationship_type::shared_string_table);
|
||||||
|
|
||||||
if (!allow_duplicates)
|
if (!allow_duplicates)
|
||||||
{
|
{
|
||||||
|
@ -1156,8 +1215,8 @@ bool workbook::contains(const std::string &sheet_title) const
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
void workbook::thumbnail(
|
void workbook::thumbnail(const std::vector<std::uint8_t> &thumbnail,
|
||||||
const std::vector<std::uint8_t> &thumbnail, const std::string &extension, const std::string &content_type)
|
const std::string &extension, const std::string &content_type)
|
||||||
{
|
{
|
||||||
if (!d_->manifest_.has_relationship(path("/"), relationship_type::thumbnail))
|
if (!d_->manifest_.has_relationship(path("/"), relationship_type::thumbnail))
|
||||||
{
|
{
|
||||||
|
|
|
@ -1007,7 +1007,7 @@ void worksheet::add_view(const sheet_view &new_view)
|
||||||
|
|
||||||
void worksheet::register_comments_in_manifest()
|
void worksheet::register_comments_in_manifest()
|
||||||
{
|
{
|
||||||
workbook().register_comments_in_manifest(*this);
|
workbook().register_worksheet_part(*this, relationship_type::comments);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool worksheet::has_header_footer() const
|
bool worksheet::has_header_footer() const
|
||||||
|
|
Loading…
Reference in New Issue
Block a user