diff --git a/.gitmodules b/.gitmodules index b2b3b51feef..2c1f73cb34d 100644 --- a/.gitmodules +++ b/.gitmodules @@ -16,3 +16,6 @@ [submodule "libs/EXTERNAL/yosys-slang"] path = libs/EXTERNAL/yosys-slang url = https://github.com/povik/yosys-slang.git +[submodule "libs/EXTERNAL/yaml-cpp"] + path = libs/EXTERNAL/yaml-cpp + url = https://github.com/jbeder/yaml-cpp.git diff --git a/dev/subtree_config.xml b/dev/subtree_config.xml index c9325311770..5f88b5c58e8 100644 --- a/dev/subtree_config.xml +++ b/dev/subtree_config.xml @@ -54,4 +54,9 @@ internal_path="parmys" external_url="https://github.com/CAS-Atlantic/parmys-plugin.git" default_external_ref="v3.0"/> + diff --git a/libs/EXTERNAL/CMakeLists.txt b/libs/EXTERNAL/CMakeLists.txt index 816ea7f57c9..eab37004629 100644 --- a/libs/EXTERNAL/CMakeLists.txt +++ b/libs/EXTERNAL/CMakeLists.txt @@ -12,6 +12,8 @@ add_subdirectory(libsdcparse) add_subdirectory(libblifparse) add_subdirectory(libtatum) add_subdirectory(libcatch2) +add_subdirectory(yaml-cpp) +add_subdirectory(xlnt) #add_subdirectory(parmys) #Proc numbers diff --git a/libs/EXTERNAL/xlnt/.appveyor.yml b/libs/EXTERNAL/xlnt/.appveyor.yml new file mode 100644 index 00000000000..ca280af4202 --- /dev/null +++ b/libs/EXTERNAL/xlnt/.appveyor.yml @@ -0,0 +1,36 @@ +version: "{build}" +os: Visual Studio 2015 + +cache: + - vcpkg -> .appveyor.yml + +platform: + - x64 + +configuration: + - Debug + +environment: + matrix: + - STATIC: OFF + - STATIC: ON + +matrix: + fast_finish: true + +init: [] + +before_build: + - git submodule update --init --recursive + - mkdir build + - cd build + - cmake -G "Visual Studio 14 2015" -D CMAKE_GENERATOR_PLATFORM=%platform% -D STATIC=%STATIC% -D SAMPLES=ON -D BENCHMARKS=ON -D TESTS=ON .. + +build: + project: build/xlnt_all.sln + parallel: true + verbosity: minimal + +test_script: + - tests\%configuration%\xlnt.test.exe + - samples\%configuration%\sample-documentation.exe diff --git a/libs/EXTERNAL/xlnt/.circleci/config.yml b/libs/EXTERNAL/xlnt/.circleci/config.yml new file mode 100644 index 00000000000..e3d2a887a27 --- /dev/null +++ b/libs/EXTERNAL/xlnt/.circleci/config.yml @@ -0,0 +1,79 @@ +version: 2.1 + +jobs: + build: + docker: + - image: lycantropos/cmake:3.9.5 + parameters: + benchmarks: + default: "OFF" + type: string + build-type: + default: Release + type: string + coverage: + default: "OFF" + type: string + cxx-ver: + default: "11" + type: string + samples: + default: "OFF" + type: string + static: + default: "ON" + type: string + steps: + - checkout + - run: git submodule update --init --recursive + - run: cmake -D XLNT_CXX_LANG=<< parameters.cxx-ver >> -D STATIC=<< parameters.static >> -D BENCHMARKS=<< parameters.benchmarks >> -D TESTS=ON -D SAMPLES=<< parameters.samples >> -D COVERAGE=<< parameters.coverage >> -D CMAKE_BUILD_TYPE=<< parameters.build-type >> . + - run: cmake --build . -- -j2 + - run: ./tests/xlnt.test + - when: + condition: + equal: ["ON", << parameters.samples >>] + steps: + - run: ./samples/sample-decrypt + - run: ./samples/sample-img2xlsx ./samples/data/penguin.jpg img.xlsx + - run: ./samples/sample-documentation + - when: + condition: + equal: ["ON", << parameters.benchmarks >>] + steps: + - run: ./benchmarks/benchmark-styles + - run: ./benchmarks/benchmark-writer + - when: + condition: + equal: ["ON", << parameters.coverage >>] + steps: + - run: lcov --directory source/CMakeFiles/xlnt.dir --capture --output-file coverage.info --base-directory ../source --no-external --gcov-tool /usr/bin/gcov-6 + - run: lcov --output-file coverage.info --remove coverage.info source/detail/serialization/miniz.cpp + - run: i=$(dirname $(pwd)) + - run: sed -i "s|$i/||" coverage.info + - run: cd .. + - run: coveralls-lcov build/coverage.info + +workflows: + build: + jobs: + - build: + name: tests + matrix: + parameters: + cxx-ver: + - "11" + - "17" + build-type: + - Release + - Debug + static: + - "ON" + - "OFF" + - build: + name: samples-benchmarks-coverage + cxx-ver: "11" + build-type: Debug + static: "ON" + samples: "ON" + benchmarks: "ON" + coverage: "OFF" diff --git a/libs/EXTERNAL/xlnt/.clang-format b/libs/EXTERNAL/xlnt/.clang-format new file mode 100644 index 00000000000..f6c1ac6d06a --- /dev/null +++ b/libs/EXTERNAL/xlnt/.clang-format @@ -0,0 +1,67 @@ +--- +BasedOnStyle: LLVM +AccessModifierOffset: -4 +AlignAfterOpenBracket: DontAlign +AlignConsecutiveAssignments: false +AlignConsecutiveDeclarations: false +AlignOperands: false +AlignTrailingComments: false +AllowAllParametersOfDeclarationOnNextLine: false +AllowShortBlocksOnASingleLine: false +AllowShortCaseLabelsOnASingleLine: false +AllowShortFunctionsOnASingleLine: None +AllowShortIfStatementsOnASingleLine: true +AllowShortLoopsOnASingleLine: false +AlwaysBreakBeforeMultilineStrings: true +AlwaysBreakTemplateDeclarations: true +BraceWrapping: + AfterClass: true + AfterControlStatement: true + AfterEnum: true + AfterFunction: true + AfterNamespace: false + AfterObjCDeclaration: true + AfterStruct: true + AfterUnion: true + BeforeCatch: true + BeforeElse: true +BreakBeforeBinaryOperators: NonAssignment +BreakBeforeBraces: Custom +ColumnLimit: 0 +ConstructorInitializerAllOnOneLineOrOnePerLine: true +Cpp11BracedListStyle: true +DerivePointerAlignment: false +DisableFormat: false +IncludeCategories: + - Regex: '^$' + Priority: 2 + - Regex: '^&' + Priority: 1 + - Regex: '^".*"' + Priority: 5 +IndentCaseLabels: false +IndentWidth: 4 +KeepEmptyLinesAtTheStartOfBlocks: false +Language: Cpp +NamespaceIndentation: None +MaxEmptyLinesToKeep: 1 +PenaltyBreakComment: 1000 +PointerAlignment: Right +SortIncludes: true +SpaceAfterCStyleCast: false +SpaceBeforeParens: ControlStatements +SpaceInEmptyParentheses: false +SpacesBeforeTrailingComments: 1 +SpacesInAngles: false +SpacesInCStyleCastParentheses: false +SpacesInContainerLiterals: true +SpacesInParentheses: false +SpacesInSquareBrackets: false +Standard: Cpp11 +UseTab: Never + +... diff --git a/libs/EXTERNAL/xlnt/.gitattributes b/libs/EXTERNAL/xlnt/.gitattributes new file mode 100644 index 00000000000..2125666142e --- /dev/null +++ b/libs/EXTERNAL/xlnt/.gitattributes @@ -0,0 +1 @@ +* text=auto \ No newline at end of file diff --git a/libs/EXTERNAL/xlnt/.gitignore b/libs/EXTERNAL/xlnt/.gitignore new file mode 100644 index 00000000000..41450d729a6 --- /dev/null +++ b/libs/EXTERNAL/xlnt/.gitignore @@ -0,0 +1,25 @@ +build/ +docs/build/ +docs/doxyxml/ +node_modules/ +*.obj +*.sdf +*.suo +*.opensdf +*.vcxproj.user +*.o +#*# +*~ +.DS_Store +__pycache__/ +Win32/ +*.pyd +python/record.txt +python/xlntpyarrow.egg-info/ +/x64/ +.envrc +.vscode +/dist/ +/.vs/ +/out/ +/CMakeSettings.json diff --git a/libs/EXTERNAL/xlnt/.release-it.json b/libs/EXTERNAL/xlnt/.release-it.json new file mode 100644 index 00000000000..109f2175345 --- /dev/null +++ b/libs/EXTERNAL/xlnt/.release-it.json @@ -0,0 +1,24 @@ +{ + "git": { + "commitMessage": "release v${version}", + "requireBranch": "master", + "requireCommits": true, + "tagAnnotation": "release v${version}", + "tagName": "v${version}" + }, + "github": { + "release": true, + "releaseName": "xlnt v${version}" + }, + "npm": { + "publish": false + }, + "plugins": { + "@release-it/bumper": { + "out": { + "file": "source/CMakeLists.txt", + "type": "text/plain" + } + } + } +} diff --git a/libs/EXTERNAL/xlnt/AUTHORS.md b/libs/EXTERNAL/xlnt/AUTHORS.md new file mode 100644 index 00000000000..7f58746d0ad --- /dev/null +++ b/libs/EXTERNAL/xlnt/AUTHORS.md @@ -0,0 +1,13 @@ +This project was started by Thomas Fussell. + +It was initially inspired by the openpyxl library: https://openpyxl.readthedocs.org + +Thanks to everyone who has contributed to this project (in alphabetical order): + +* adam-nielsen +* Malvineous +* sukoi26 +* tpmccallum +* xpol + +Project logo designed by Thomas Fussell. diff --git a/libs/EXTERNAL/xlnt/CHANGELOG.md b/libs/EXTERNAL/xlnt/CHANGELOG.md new file mode 100644 index 00000000000..89ab4780b8f --- /dev/null +++ b/libs/EXTERNAL/xlnt/CHANGELOG.md @@ -0,0 +1,4 @@ +# Change Log + +This project adheres to [Semantic Versioning](http://semver.org/). +Every release is documented on the Github [Releases](https://github.com/tfussell/xlnt/releases) page. diff --git a/libs/EXTERNAL/xlnt/CMakeLists.txt b/libs/EXTERNAL/xlnt/CMakeLists.txt new file mode 100644 index 00000000000..a9ed23fd9b9 --- /dev/null +++ b/libs/EXTERNAL/xlnt/CMakeLists.txt @@ -0,0 +1,59 @@ +cmake_minimum_required(VERSION 3.1) +project(xlnt_all) + +add_compile_options("$<$:/utf-8>") +add_compile_options("$<$:/utf-8>") + +# CTest setup +# include (CTest) # Add this for valgrind support; CTest works without it +enable_testing() + +# This indicates to CMakeLists in subdirectories that they are part of a larger project +set(COMBINED_PROJECT TRUE) + +# Library type +option(STATIC "Set to ON to build xlnt as a static library instead of a shared library" OFF) + +# c++ language standard to use +set(XLNT_VALID_LANGS 11 14 17) +set(XLNT_CXX_LANG "14" CACHE STRING "c++ language features to compile with") +# enumerate allowed values for cmake gui +set_property(CACHE XLNT_CXX_LANG PROPERTY STRINGS ${XLNT_VALID_LANGS}) +# validate value is in XLNT_VALID_LANGS +list(FIND XLNT_VALID_LANGS ${XLNT_CXX_LANG} index) +if(index EQUAL -1) + message(FATAL_ERROR "XLNT_CXX_LANG must be one of ${XLNT_VALID_LANGS}") +endif() + + +# Optional components +option(TESTS "Set to ON to build test executable (in ./tests)" OFF) +option(SAMPLES "Set to ON to build executable code samples (in ./samples)" OFF) +option(BENCHMARKS "Set to ON to build performance benchmarks (in ./benchmarks)" OFF) +option(PYTHON "Set to ON to build Arrow conversion functions (in ./python)" OFF) + +# Platform specific options +if(MSVC) + option(STATIC_CRT "Link with the static version of MSVCRT (/MD[d])" OFF) +else() + option(COVERAGE "Generate coverage data using gcov" OFF) +endif() + +# Add components according to selected options +if(SAMPLES) + add_subdirectory(samples) +endif() + +if(BENCHMARKS) + add_subdirectory(benchmarks) +endif() + +if(TESTS) + add_subdirectory(tests) +endif() + +if(PYTHON) + add_subdirectory(python) +endif() + +add_subdirectory(source) diff --git a/libs/EXTERNAL/xlnt/CODE_OF_CONDUCT.md b/libs/EXTERNAL/xlnt/CODE_OF_CONDUCT.md new file mode 100644 index 00000000000..76d62a21b69 --- /dev/null +++ b/libs/EXTERNAL/xlnt/CODE_OF_CONDUCT.md @@ -0,0 +1,46 @@ +# Contributor Covenant Code of Conduct + +## Our Pledge + +In the interest of fostering an open and welcoming environment, we as contributors and maintainers pledge to making participation in our project and our community a harassment-free experience for everyone, regardless of age, body size, disability, ethnicity, gender identity and expression, level of experience, nationality, personal appearance, race, religion, or sexual identity and orientation. + +## Our Standards + +Examples of behavior that contributes to creating a positive environment include: + +* Using welcoming and inclusive language +* Being respectful of differing viewpoints and experiences +* Gracefully accepting constructive criticism +* Focusing on what is best for the community +* Showing empathy towards other community members + +Examples of unacceptable behavior by participants include: + +* The use of sexualized language or imagery and unwelcome sexual attention or advances +* Trolling, insulting/derogatory comments, and personal or political attacks +* Public or private harassment +* Publishing others' private information, such as a physical or electronic address, without explicit permission +* Other conduct which could reasonably be considered inappropriate in a professional setting + +## Our Responsibilities + +Project maintainers are responsible for clarifying the standards of acceptable behavior and are expected to take appropriate and fair corrective action in response to any instances of unacceptable behavior. + +Project maintainers have the right and responsibility to remove, edit, or reject comments, commits, code, wiki edits, issues, and other contributions that are not aligned to this Code of Conduct, or to ban temporarily or permanently any contributor for other behaviors that they deem inappropriate, threatening, offensive, or harmful. + +## Scope + +This Code of Conduct applies both within project spaces and in public spaces when an individual is representing the project or its community. Examples of representing a project or community include using an official project e-mail address, posting via an official social media account, or acting as an appointed representative at an online or offline event. Representation of a project may be further defined and clarified by project maintainers. + +## Enforcement + +Instances of abusive, harassing, or otherwise unacceptable behavior may be reported by contacting the project team at thomas.fussell@gmail.com. The project team will review and investigate all complaints, and will respond in a way that it deems appropriate to the circumstances. The project team is obligated to maintain confidentiality with regard to the reporter of an incident. Further details of specific enforcement policies may be posted separately. + +Project maintainers who do not follow or enforce the Code of Conduct in good faith may face temporary or permanent repercussions as determined by other members of the project's leadership. + +## Attribution + +This Code of Conduct is adapted from the [Contributor Covenant][homepage], version 1.4, available at [http://contributor-covenant.org/version/1/4][version] + +[homepage]: http://contributor-covenant.org +[version]: http://contributor-covenant.org/version/1/4/ diff --git a/libs/EXTERNAL/xlnt/CONTRIBUTING.md b/libs/EXTERNAL/xlnt/CONTRIBUTING.md new file mode 100644 index 00000000000..29f07242bb8 --- /dev/null +++ b/libs/EXTERNAL/xlnt/CONTRIBUTING.md @@ -0,0 +1,31 @@ +# Contributing to xlnt + +xlnt welcomes contributions from everyone regardless of skill level (provided you can write C++ or documentation). + +## Getting Started + +Look through the list of issues to find something interesting to work on. Help is appreciated with any issues, but important timely issues are labeled as "help wanted". Issues labeled "docs" might be good for those who want to contribute without having to know too much C++. You might also find something that the code is missing without an associated issue. That's fine to work on to, but it might be best to make an issue first in case someone else is working on it. + +## Contributions + +Contributions to xlnt should be made in the form of pull requests on GitHub. Each pull request will be reviewed and either merged into the current development branch or given feedback for changes that would be required to do so. + +All code in this repository is under the MIT License. You should agree to these terms before submitting any code to xlnt. + +## Pull Request Checklist + +- Branch from the head of the current development branch. Until version 1.0 is released, this the master branch. + +- Commits should be as small as possible, while ensuring that each commit is correct independently (i.e. each commit should compile and pass all tests). Commits that don't follow the coding style indicated in .clang-format (e.g. indentation) are less likely to be accepted until they are fixed. + +- If your pull request is not getting reviewed or you need a specific person to review it, you can @-reply a reviewer asking for a review in the pull request or a comment. + +- Add tests relevant to the fixed defect or new feature. It's best to do this before making any changes, make sure that the tests fail, then make changes ensuring that it ultimately passes the tests (i.e. TDD). xlnt uses cxxtest for testing. Tests are contained in a tests directory inside each module (e.g. source/workbook/tests/test_workbook.hpp) in the form of a header file. Each test is a separate function with a name that starts like "test_". See http://cxxtest.com/guide.html for information about CxxTest or take a look at existing tests. + +## Conduct + +Just try to be nice--we're all volunteers here. + +## Communication + +Add a comment to an existing issue on GitHub, open a new issue for defects or feature requests, or contact @tfussell if you want. diff --git a/libs/EXTERNAL/xlnt/LICENSE.md b/libs/EXTERNAL/xlnt/LICENSE.md new file mode 100644 index 00000000000..0ff4e1d986c --- /dev/null +++ b/libs/EXTERNAL/xlnt/LICENSE.md @@ -0,0 +1,493 @@ +# License + +## [xlnt](https://github.com/tfussell/xlnt) +>[MIT License](https://github.com/tfussell/xlnt/blob/master/LICENSE.md) + +``` +Copyright (c) 2014-2018 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, ARISING FROM, OUT OF OR IN CONNECTION WITH THE +SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +``` + +# Dependency Licences + +## [utfcpp](https://github.com/nemtrif/utfcpp) +>[Boost Software License - Version 1.0](https://github.com/nemtrif/utfcpp/blob/master/source/utf8.h) + +``` +Copyright 2006 Nemanja Trifunovic + +Permission is hereby granted, free of charge, to any person or organization +obtaining a copy of the software and accompanying documentation covered by +this license (the "Software") to use, reproduce, display, distribute, +execute, and transmit the Software, and to prepare derivative works of the +Software, and to permit third-parties to whom the Software is furnished to +do so, all subject to the following: + +The copyright notices in the Software and this entire statement, including +the above license grant, this restriction and the following disclaimer, +must be included in all copies of the Software, in whole or in part, and +all derivative works of the Software, unless such copies or derivative +works are solely in the form of machine-executable object code generated by +a source language processor. + +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, TITLE AND NON-INFRINGEMENT. IN NO EVENT +SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE +FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE, +ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER +DEALINGS IN THE SOFTWARE. +``` + +## [POLE](http://www.dimin.net/software/pole/) +>[BSD 2-Clause License](https://bitbucket.org/dimin/pole/src/c15e513bdce4c3a52b3dbc925d4d2bb520dc71d8/pole/LICENSE) + +``` +POLE - Portable C++ library to access OLE Storage +Copyright (C) 2002-2007 Ariya Hidayat (ariya@kde.org). All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions +are met: + +1. Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. +2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + +THIS SOFTWARE IS PROVIDED BY THE AUTHOR "AS IS" AND ANY EXPRESS OR +IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES +OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. +IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, +INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT +NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF +THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +``` + +## [libstudxml](http://www.codesynthesis.com/projects/libstudxml/) +>[MIT License](http://www.codesynthesis.com/licenses/mit.txt) + +``` +Summary: Everything is licensed under the MIT License (text below). + +Code found in the xml/details/expat/ directory is distributed under +the MIT License (see the xml/details/expat/LICENSE file for copyright +information). + +Code found in the xml/details/genx/ directory is distributed under +the MIT License (see the xml/details/genx/LICENSE file for copyright +information). + +The rest is Copyright (c) 2013-2014 Code Synthesis Tools CC and is +distributed under the MIT License: + +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, ARISING FROM, OUT OF OR IN CONNECTION WITH THE +SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +``` + +## [PartIO](https://www.disneyanimation.com/technology/partio.html) +>[BSD 3-Clause License (with specific non-attribution clause)](https://github.com/wdas/partio/blob/master/src/lib/io/ZIP.h) + +``` +Copyright 2010 Disney Enterprises, Inc. All rights reserved + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are +met: + +* Redistributions of source code must retain the above copyright +notice, this list of conditions and the following disclaimer. + +* Redistributions in binary form must reproduce the above copyright +notice, this list of conditions and the following disclaimer in +the documentation and/or other materials provided with the +distribution. + +* The names "Disney", "Walt Disney Pictures", "Walt Disney Animation +Studios" or the names of its contributors may NOT be used to +endorse or promote products derived from this software without +specific prior written permission from Walt Disney Pictures. + +Disclaimer: THIS SOFTWARE IS PROVIDED BY WALT DISNEY PICTURES AND +CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, +BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS +FOR A PARTICULAR PURPOSE, NONINFRINGEMENT AND TITLE ARE DISCLAIMED. +IN NO EVENT SHALL WALT DISNEY PICTURES, THE COPYRIGHT HOLDER OR +CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, +EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, +PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR +PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND BASED ON ANY +THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. +``` + +## [miniz](https://github.com/richgel999/miniz) +>[Public Domain/MIT License](https://github.com/richgel999/miniz/blob/master/LICENSE) + +``` +This is free and unencumbered software released into the public domain. + +Anyone is free to copy, modify, publish, use, compile, sell, or +distribute this software, either in source code form or as a compiled +binary, for any purpose, commercial or non-commercial, and by any +means. + +In jurisdictions that recognize copyright laws, the author or authors +of this software dedicate any and all copyright interest in the +software to the public domain. We make this dedication for the benefit +of the public at large and to the detriment of our heirs and +successors. We intend this dedication to be an overt act of +relinquishment in perpetuity of all present and future rights to this +software under copyright law. + +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 BE LIABLE FOR ANY CLAIM, DAMAGES OR +OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, +ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR +OTHER DEALINGS IN THE SOFTWARE. + +For more information, please refer to + +Copyright 2013-2014 RAD Game Tools and Valve Software +Copyright 2010-2014 Rich Geldreich and Tenacious Software LLC +All Rights Reserved. + +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, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. +``` + + +## [SHA-512 hash in C](https://www.nayuki.io/page/fast-sha2-hashes-in-x86-assembly) +>[MIT License](https://www.nayuki.io/res/fast-sha2-hashes-in-x86-assembly/sha512.c) + +``` +Copyright (c) 2016 Project Nayuki + +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, ARISING FROM, OUT OF OR IN CONNECTION WITH THE +SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +``` + +## [SHA-1 hash in C](https://www.nayuki.io/page/fast-sha1-hash-implementation-in-x86-assembly) +>[MIT License](https://www.nayuki.io/res/fast-sha1-hash-implementation-in-x86-assembly/sha1-fast.c) + +``` +Copyright (c) 2014 Project Nayuki + +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, ARISING FROM, OUT OF OR IN CONNECTION WITH THE +SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +``` + +## [LibTomCrypt](http://www.libtom.net/) +>[Public Domain](https://github.com/libtom/libtomcrypt/blob/develop/LICENSE) + +``` +LibTomCrypt is public domain. As should all quality software be. + +Tom St Denis +``` + +# Dependency Licences (Python Module) + +## [pybind11](https://github.com/pybind/pybind11) +>[BSD 3-Clause License](https://github.com/pybind/pybind11/blob/master/LICENSE) + +``` +Copyright (c) 2016 Wenzel Jakob , All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + +1. Redistributions of source code must retain the above copyright notice, this + list of conditions and the following disclaimer. + +2. Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + +3. Neither the name of the copyright holder nor the names of its contributors + may be used to endorse or promote products derived from this software + without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE +FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR +SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER +CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, +OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +You are under no obligation whatsoever to provide any bug fixes, patches, or +upgrades to the features, functionality or performance of the source code +("Enhancements") to anyone; however, if you choose to make your Enhancements +available either publicly, or directly to the author of this software, without +imposing a separate written license agreement for such Enhancements, then you +hereby grant the following license: a non-exclusive, royalty-free perpetual +license to install, use, modify, prepare derivative works, incorporate into +other computer software, distribute, and sublicense such enhancements or +derivative works thereof, in binary and source code form. +``` + + +# Dependency Licences (Testing Only) + +## [CxxTest](http://cxxtest.com/) +>[LGPL License](https://github.com/CxxTest/cxxtest/blob/master/COPYING) + +``` + GNU LESSER GENERAL PUBLIC LICENSE + Version 3, 29 June 2007 + + Copyright (C) 2007 Free Software Foundation, Inc. + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + + + This version of the GNU Lesser General Public License incorporates +the terms and conditions of version 3 of the GNU General Public +License, supplemented by the additional permissions listed below. + + 0. Additional Definitions. + + As used herein, "this License" refers to version 3 of the GNU Lesser +General Public License, and the "GNU GPL" refers to version 3 of the GNU +General Public License. + + "The Library" refers to a covered work governed by this License, +other than an Application or a Combined Work as defined below. + + An "Application" is any work that makes use of an interface provided +by the Library, but which is not otherwise based on the Library. +Defining a subclass of a class defined by the Library is deemed a mode +of using an interface provided by the Library. + + A "Combined Work" is a work produced by combining or linking an +Application with the Library. The particular version of the Library +with which the Combined Work was made is also called the "Linked +Version". + + The "Minimal Corresponding Source" for a Combined Work means the +Corresponding Source for the Combined Work, excluding any source code +for portions of the Combined Work that, considered in isolation, are +based on the Application, and not on the Linked Version. + + The "Corresponding Application Code" for a Combined Work means the +object code and/or source code for the Application, including any data +and utility programs needed for reproducing the Combined Work from the +Application, but excluding the System Libraries of the Combined Work. + + 1. Exception to Section 3 of the GNU GPL. + + You may convey a covered work under sections 3 and 4 of this License +without being bound by section 3 of the GNU GPL. + + 2. Conveying Modified Versions. + + If you modify a copy of the Library, and, in your modifications, a +facility refers to a function or data to be supplied by an Application +that uses the facility (other than as an argument passed when the +facility is invoked), then you may convey a copy of the modified +version: + + a) under this License, provided that you make a good faith effort to + ensure that, in the event an Application does not supply the + function or data, the facility still operates, and performs + whatever part of its purpose remains meaningful, or + + b) under the GNU GPL, with none of the additional permissions of + this License applicable to that copy. + + 3. Object Code Incorporating Material from Library Header Files. + + The object code form of an Application may incorporate material from +a header file that is part of the Library. You may convey such object +code under terms of your choice, provided that, if the incorporated +material is not limited to numerical parameters, data structure +layouts and accessors, or small macros, inline functions and templates +(ten or fewer lines in length), you do both of the following: + + a) Give prominent notice with each copy of the object code that the + Library is used in it and that the Library and its use are + covered by this License. + + b) Accompany the object code with a copy of the GNU GPL and this license + document. + + 4. Combined Works. + + You may convey a Combined Work under terms of your choice that, +taken together, effectively do not restrict modification of the +portions of the Library contained in the Combined Work and reverse +engineering for debugging such modifications, if you also do each of +the following: + + a) Give prominent notice with each copy of the Combined Work that + the Library is used in it and that the Library and its use are + covered by this License. + + b) Accompany the Combined Work with a copy of the GNU GPL and this license + document. + + c) For a Combined Work that displays copyright notices during + execution, include the copyright notice for the Library among + these notices, as well as a reference directing the user to the + copies of the GNU GPL and this license document. + + d) Do one of the following: + + 0) Convey the Minimal Corresponding Source under the terms of this + License, and the Corresponding Application Code in a form + suitable for, and under terms that permit, the user to + recombine or relink the Application with a modified version of + the Linked Version to produce a modified Combined Work, in the + manner specified by section 6 of the GNU GPL for conveying + Corresponding Source. + + 1) Use a suitable shared library mechanism for linking with the + Library. A suitable mechanism is one that (a) uses at run time + a copy of the Library already present on the user's computer + system, and (b) will operate properly with a modified version + of the Library that is interface-compatible with the Linked + Version. + + e) Provide Installation Information, but only if you would otherwise + be required to provide such information under section 6 of the + GNU GPL, and only to the extent that such information is + necessary to install and execute a modified version of the + Combined Work produced by recombining or relinking the + Application with a modified version of the Linked Version. (If + you use option 4d0, the Installation Information must accompany + the Minimal Corresponding Source and Corresponding Application + Code. If you use option 4d1, you must provide the Installation + Information in the manner specified by section 6 of the GNU GPL + for conveying Corresponding Source.) + + 5. Combined Libraries. + + You may place library facilities that are a work based on the +Library side by side in a single library together with other library +facilities that are not Applications and are not covered by this +License, and convey such a combined library under terms of your +choice, if you do both of the following: + + a) Accompany the combined library with a copy of the same work based + on the Library, uncombined with any other library facilities, + conveyed under the terms of this License. + + b) Give prominent notice with the combined library that part of it + is a work based on the Library, and explaining where to find the + accompanying uncombined form of the same work. + + 6. Revised Versions of the GNU Lesser General Public License. + + The Free Software Foundation may publish revised and/or new versions +of the GNU Lesser General Public License from time to time. Such new +versions will be similar in spirit to the present version, but may +differ in detail to address new problems or concerns. + + Each version is given a distinguishing version number. If the +Library as you received it specifies that a certain numbered version +of the GNU Lesser General Public License "or any later version" +applies to it, you have the option of following the terms and +conditions either of that published version or of any later version +published by the Free Software Foundation. If the Library as you +received it does not specify a version number of the GNU Lesser +General Public License, you may choose any version of the GNU Lesser +General Public License ever published by the Free Software Foundation. + + If the Library as you received it specifies that a proxy can decide +whether future versions of the GNU Lesser General Public License shall +apply, that proxy's public statement of acceptance of any version is +permanent authorization for you to choose that version for the +Library. +``` diff --git a/libs/EXTERNAL/xlnt/README.md b/libs/EXTERNAL/xlnt/README.md new file mode 100644 index 00000000000..18484d387c2 --- /dev/null +++ b/libs/EXTERNAL/xlnt/README.md @@ -0,0 +1,52 @@ +xlnt logo
+==== + +[![Travis Build Status](https://travis-ci.org/tfussell/xlnt.svg?branch=master)](https://travis-ci.org/tfussell/xlnt) +[![AppVeyor Build status](https://ci.appveyor.com/api/projects/status/2hs79a1xoxy16sol?svg=true)](https://ci.appveyor.com/project/tfussell/xlnt) +[![Coverage Status](https://coveralls.io/repos/github/tfussell/xlnt/badge.svg?branch=master)](https://coveralls.io/github/tfussell/xlnt?branch=master) +[![Documentation Status](https://legacy.gitbook.com/button/status/book/tfussell/xlnt)](https://tfussell.gitbooks.io/xlnt/content/) +[![License](http://img.shields.io/badge/license-MIT-blue.svg?style=flat)](http://opensource.org/licenses/MIT) + +## Introduction +xlnt is a modern C++ library for manipulating spreadsheets in memory and reading/writing them from/to XLSX files as described in [ECMA 376 4th edition](http://www.ecma-international.org/publications/standards/Ecma-376.htm). The first public release of xlnt version 1.0 was on May 10th, 2017. Current work is focused on increasing compatibility, improving performance, and brainstorming future development goals. For a high-level summary of what you can do with this library, see [the feature list](https://tfussell.gitbooks.io/xlnt/content/docs/introduction/Features.html). Contributions are welcome in the form of pull requests or discussions on [the repository's Issues page](https://github.com/tfussell/xlnt/issues). + +## Example + +Including xlnt in your project, creating a new spreadsheet, and saving it as "example.xlsx" + +```c++ +#include + +int main() +{ + xlnt::workbook wb; + xlnt::worksheet ws = wb.active_sheet(); + ws.cell("A1").value(5); + ws.cell("B2").value("string data"); + ws.cell("C3").formula("=RAND()"); + ws.merge_cells("C3:C4"); + ws.freeze_panes("B2"); + wb.save("example.xlsx"); + return 0; +} +// compile with -std=c++14 -Ixlnt/include -lxlnt +``` + +## Documentation + +Documentation for the current release of xlnt is available [here](https://tfussell.gitbooks.io/xlnt/content/). + +## Building xlnt - Using vcpkg + +You can download and install xlnt using the [vcpkg](https://github.com/microsoft/vcpkg) dependency manager: + + git clone https://github.com/microsoft/vcpkg.git + cd vcpkg + ./bootstrap-vcpkg.sh + ./vcpkg integrate install + ./vcpkg install xlnt + +The xlnt port in vcpkg is kept up to date by Microsoft team members and community contributors. If the version is out of date, please [create an issue or pull request](https://github.com/microsoft/vcpkg) on the vcpkg repository. + +## 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/LICENSE.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/LICENSE.md) should be distributed alongside any assemblies that use xlnt in source or compiled form. diff --git a/libs/EXTERNAL/xlnt/SUMMARY.md b/libs/EXTERNAL/xlnt/SUMMARY.md new file mode 120000 index 00000000000..0e01b4308c1 --- /dev/null +++ b/libs/EXTERNAL/xlnt/SUMMARY.md @@ -0,0 +1 @@ +docs/README.md \ No newline at end of file diff --git a/libs/EXTERNAL/xlnt/benchmarks/CMakeLists.txt b/libs/EXTERNAL/xlnt/benchmarks/CMakeLists.txt new file mode 100644 index 00000000000..3c00ccda1fa --- /dev/null +++ b/libs/EXTERNAL/xlnt/benchmarks/CMakeLists.txt @@ -0,0 +1,48 @@ +cmake_minimum_required(VERSION 3.1) +project(xlnt.benchmarks) + +# Require C++11 compiler +set(CMAKE_CXX_STANDARD 11) +set(CMAKE_CXX_STANDARD_REQUIRED ON) + +if(NOT COMBINED_PROJECT) + # Include xlnt library + add_subdirectory(${CMAKE_CURRENT_SOURCE_DIR}/../source ${CMAKE_CURRENT_BINARY_DIR}/source) +endif() + +if(STATIC_CRT) + include(${CMAKE_CURRENT_SOURCE_DIR}/../cmake/ucm.cmake) + ucm_set_runtime(STATIC) +endif() + +set(XLNT_BENCHMARK_DATA_DIR ${CMAKE_CURRENT_SOURCE_DIR}/data) + +file(GLOB BENCHMARK_SOURCES ${CMAKE_CURRENT_SOURCE_DIR}/*.cpp) + +foreach(BENCHMARK_SOURCE IN ITEMS ${BENCHMARK_SOURCES}) + # Convert .cpp to benchmark- + get_filename_component(BENCHMARK_NAME ${BENCHMARK_SOURCE} NAME_WE) + set(BENCHMARK_EXECUTABLE benchmark-${BENCHMARK_NAME}) + + add_executable(${BENCHMARK_EXECUTABLE} ${BENCHMARK_SOURCE}) + + target_link_libraries(${BENCHMARK_EXECUTABLE} PRIVATE xlnt) + # Need to use some test helpers + target_include_directories(${BENCHMARK_EXECUTABLE} + PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/../tests) + target_compile_definitions(${BENCHMARK_EXECUTABLE} + PRIVATE XLNT_BENCHMARK_DATA_DIR=${XLNT_BENCHMARK_DATA_DIR}) + + if(MSVC AND NOT STATIC) + # Copy xlnt DLL into benchmarks directory + add_custom_command(TARGET ${BENCHMARK_EXECUTABLE} POST_BUILD + COMMAND ${CMAKE_COMMAND} -E copy_if_different + $ + $) + endif() +endforeach() + +option(XLNT_MICROBENCH_ENABLED "Enable small benchmarks typically used for development" OFF) +if (XLNT_MICROBENCH_ENABLED) + add_subdirectory(microbenchmarks) +endif() \ No newline at end of file diff --git a/libs/EXTERNAL/xlnt/benchmarks/data/large.xlsx b/libs/EXTERNAL/xlnt/benchmarks/data/large.xlsx new file mode 100644 index 00000000000..22d8d9f5a0f Binary files /dev/null and b/libs/EXTERNAL/xlnt/benchmarks/data/large.xlsx differ diff --git a/libs/EXTERNAL/xlnt/benchmarks/data/very_large.xlsx b/libs/EXTERNAL/xlnt/benchmarks/data/very_large.xlsx new file mode 100644 index 00000000000..c6056db2287 Binary files /dev/null and b/libs/EXTERNAL/xlnt/benchmarks/data/very_large.xlsx differ diff --git a/libs/EXTERNAL/xlnt/benchmarks/disabled/bufzip.cpp b/libs/EXTERNAL/xlnt/benchmarks/disabled/bufzip.cpp new file mode 100644 index 00000000000..31035f7106b --- /dev/null +++ b/libs/EXTERNAL/xlnt/benchmarks/disabled/bufzip.cpp @@ -0,0 +1,23 @@ +#include +#include +#include +#include + +void standard() +{ + xlnt::xml_document doc; + + for (int i = 0; i < 1000000; i++) + { + doc.add_child("test"); + } + + xlnt::zip_file archive; + archive.writestr("sheet.xml", doc.to_string()); +} + +int main() +{ + standard(); + return 0; +} diff --git a/libs/EXTERNAL/xlnt/benchmarks/disabled/memory.cpp b/libs/EXTERNAL/xlnt/benchmarks/disabled/memory.cpp new file mode 100644 index 00000000000..a6895826ef3 --- /dev/null +++ b/libs/EXTERNAL/xlnt/benchmarks/disabled/memory.cpp @@ -0,0 +1,65 @@ +#include + +#ifdef __APPLE__ +#include +#endif + +#include + +#include "../tests/helpers/path_helper.hpp" + +int calc_memory_usage() +{ +#ifdef __APPLE__ + struct task_basic_info t_info; + mach_msg_type_number_t t_info_count = TASK_BASIC_INFO_COUNT; + + if (KERN_SUCCESS != task_info(mach_task_self(), + TASK_BASIC_INFO, (task_info_t)&t_info, + &t_info_count)) + { + return 0; + } + + return t_info.virtual_size; +#endif + return 0; +} + +void test_memory_use() +{ + // Naive test that assumes memory use will never be more than 120 % of + // that for first 50 rows + auto current_folder = PathHelper::GetExecutableDirectory(); + auto src = current_folder + "rks/files/very_large.xlsx"; + + xlnt::workbook wb; + wb.load(src); + auto ws = wb.get_active_sheet(); + + int initial_use = 0; + int n = 0; + + for (auto line : ws.rows()) + { + if (n % 50 == 0) + { + auto use = calc_memory_usage(); + + if (initial_use == 0) + { + initial_use = use; + } + + assert(use / initial_use < 1.2); + std::cout << n << " " << use << std::endl; + } + + n++; + } +} + +int main() +{ + test_memory_use(); +} diff --git a/libs/EXTERNAL/xlnt/benchmarks/disabled/profiling.cpp b/libs/EXTERNAL/xlnt/benchmarks/disabled/profiling.cpp new file mode 100644 index 00000000000..d20837e9bb4 --- /dev/null +++ b/libs/EXTERNAL/xlnt/benchmarks/disabled/profiling.cpp @@ -0,0 +1,131 @@ +from io import BytesIO +from lxml.etree import xmlfile +import os +from random import randint + +from openpyxl import Workbook +from openpyxl.xml.functions import XMLGenerator + +def make_worksheet(): + wb = Workbook() + ws = wb.active + for i in range(1000): + ws.append(list(range(100))) + return ws + + +def lxml_writer(ws=None): + from openpyxl.writer.lxml_worksheet import write_rows + if ws is None: + ws = make_worksheet() + + out = BytesIO() + with xmlfile(out) as xf: + write_rows(xf, ws) + #with open("lxml_writer.xml", "wb") as dump: + #dump.write(out.getvalue()) + #ws.parent.save("lxml_writer.xlsx") + + +def make_dump_worksheet(): + wb = Workbook(write_only=True) + ws = wb.create_sheet() + return ws + +def dump_writer(ws=None): + if ws is None: + ws = make_dump_worksheet() + for i in range(1000): + ws.append(list(range(100))) + + +COLUMNS = 100 +ROWS = 1000 +BOLD = 1 +ITALIC = 2 +UNDERLINE = 4 +RED_BG = 8 +formatData = [[None] * COLUMNS for _ in range(ROWS)] + +def generate_format_data(): + for row in range(ROWS): + for col in range(COLUMNS): + formatData[row][col] = randint(1, 15) + + +def styled_sheet(): + from openpyxl import Workbook + from openpyxl.styles import Font, Style, PatternFill, Color, colors + + wb = Workbook() + ws = wb.active + ws.title = 'Test 1' + + red_fill = PatternFill(fill_type='solid', fgColor=Color(colors.RED), bgColor=Color(colors.RED)) + empty_fill = PatternFill() + styles = [] + # pregenerate relevant styles + for row in range(ROWS): + _row = [] + for col in range(COLUMNS): + cell = ws.cell(row=row+1, column=col+1) + cell.value = 1 + font = {} + fill = PatternFill() + if formatData[row][col] & BOLD: + font['bold'] = True + if formatData[row][col] & ITALIC: + font['italic'] = True + if formatData[row][col] & UNDERLINE: + font['underline'] = 'single' + if formatData[row][col] & RED_BG: + fill = red_fill + cell.style = Style(font=Font(**font), fill=fill) + + #wb.save(get_output_path('test_openpyxl_style_std_pregen.xlsx')) + + +def read_workbook(): + from openpyxl import load_workbook + folder = os.path.split(__file__)[0] + src = os.path.join(folder, "files", "very_large.xlsx") + wb = load_workbook(src) + return wb + + +def rows(wb): + ws = wb.active + rows = ws.iter_rows() + for r, row in enumerate(rows): + for c, col in enumerate(row): + pass + print((r+1)* (c+1), "cells") + + +def col_index1(): + from openpyxl.cell import get_column_letter + for i in range(1, 18279): + c = get_column_letter(i) + + + +""" +Sample use +import cProfile +ws = make_worksheet() +cProfile.run("profiling.lxml_writer(ws)", sort="tottime") +""" + + +if __name__ == '__main__': + import cProfile + ws = make_worksheet() + #wb = read_workbook() + #cProfile.run("rows(wb)", sort="tottime") + #cProfile.run("make_worksheet()", sort="tottime") + #cProfile.run("lxml_writer(ws)", sort="tottime") + #generate_format_data() + #cProfile.run("styled_sheet()", sort="tottime") + #ws = make_dump_worksheet() + #cProfile.run("dump_writer(ws)", sort="tottime") + cProfile.run("col_index1()", sort="tottime") diff --git a/libs/EXTERNAL/xlnt/benchmarks/disabled/reader.cpp b/libs/EXTERNAL/xlnt/benchmarks/disabled/reader.cpp new file mode 100644 index 00000000000..2049e328078 --- /dev/null +++ b/libs/EXTERNAL/xlnt/benchmarks/disabled/reader.cpp @@ -0,0 +1,45 @@ +import os +import sys +import timeit + +import openpyxl + + +def reader(optimised): + """ + Loop through all cells of a workbook + """ + folder = os.path.split(__file__)[0] + src = os.path.join(folder, "files", "very_large.xlsx") + wb = openpyxl.load_workbook(src, use_iterators=optimised) + ws = wb.active + rows = ws.iter_rows() + for r, row in enumerate(rows): + for c, col in enumerate(row): + pass + print((r+1)* (c+1), "cells") + +def timer(fn): + """ + Create a timeit call to a function and pass in keyword arguments. + The function is called twice, once using the standard workbook, then with the optimised one. + Time from the best of three is taken. + """ + print("lxml", openpyxl.LXML) + result = [] + for opt in (False, True,): + print("Workbook is {0}".format(opt and "optimised" or "not optimised")) + times = timeit.repeat("{0}({1})".format(fn.__name__, opt), + setup="from __main__ import {0}".format(fn.__name__), + number = 1, + repeat = 3 + ) + print("{0:.2f}s".format(min(times))) + result.append(min(times)) + std, opt = result + print("Optimised takes {0:.2%} time\n".format(opt/std)) + return std, opt + + +if __name__ == "__main__": + timer(reader) diff --git a/libs/EXTERNAL/xlnt/benchmarks/disabled/speed.cpp b/libs/EXTERNAL/xlnt/benchmarks/disabled/speed.cpp new file mode 100644 index 00000000000..a893d5731be --- /dev/null +++ b/libs/EXTERNAL/xlnt/benchmarks/disabled/speed.cpp @@ -0,0 +1,31 @@ +"Benchmark some different implementations for cells" + +from openpyxl.compat import range + +from openpyxl.cell import Cell +from openpyxl.cell.read_only import ReadOnlyCell +from memory_profiler import memory_usage +import time + + +def standard(): + c = Cell(None, "A", "0", None) + +def iterative(): + c = ReadOnlyCell(None, None, None, 'n') + +def dictionary(): + c = {'ws':'None', 'col':'A', 'row':0, 'value':1} + + +if __name__ == '__main__': + initial_use = memory_usage(proc=-1, interval=1)[0] + for fn in (standard, iterative, dictionary): + t = time.time() + container = [] + for i in range(1000000): + container.append(fn()) + print("{0} {1} MB, {2:.2f}s".format( + fn.func_name, + memory_usage(proc=-1, interval=1)[0] - initial_use, + time.time() - t)) diff --git a/libs/EXTERNAL/xlnt/benchmarks/microbenchmarks/CMakeLists.txt b/libs/EXTERNAL/xlnt/benchmarks/microbenchmarks/CMakeLists.txt new file mode 100644 index 00000000000..745df1b82e6 --- /dev/null +++ b/libs/EXTERNAL/xlnt/benchmarks/microbenchmarks/CMakeLists.txt @@ -0,0 +1,36 @@ +# FetchContent added in cmake v3.11 +# https://cmake.org/cmake/help/v3.11/module/FetchContent.html +# this file is behind a feature flag (XLNT_MICROBENCH_ENABLED) so the primary build is not affected +cmake_minimum_required(VERSION 3.11) +project(xlnt_ubench) + +# acquire google benchmark dependency +# disable generation of the various test projects +set(BENCHMARK_ENABLE_TESTING OFF) +# gtest not required +set(BENCHMARK_ENABLE_GTEST_TESTS OFF) + +include(FetchContent) +FetchContent_Declare( + googlebenchmark + GIT_REPOSITORY https://github.com/google/benchmark + GIT_TAG v1.5.0 +) +# download if not already present +FetchContent_GetProperties(googlebenchmark) +if(NOT googlebenchmark_POPULATED) + FetchContent_Populate(googlebenchmark) + add_subdirectory(${googlebenchmark_SOURCE_DIR} ${googlebenchmark_BINARY_DIR}) +endif() +# equivalent of add_subdirectory, now available for use +FetchContent_MakeAvailable(googlebenchmark) + + +add_executable(xlnt_ubench) +target_sources(xlnt_ubench + PRIVATE + string_to_double.cpp + double_to_string.cpp +) +target_link_libraries(xlnt_ubench benchmark_main xlnt) +target_compile_features(xlnt_ubench PRIVATE cxx_std_17) \ No newline at end of file diff --git a/libs/EXTERNAL/xlnt/benchmarks/microbenchmarks/double_to_string.cpp b/libs/EXTERNAL/xlnt/benchmarks/microbenchmarks/double_to_string.cpp new file mode 100644 index 00000000000..0b82803f64f --- /dev/null +++ b/libs/EXTERNAL/xlnt/benchmarks/microbenchmarks/double_to_string.cpp @@ -0,0 +1,207 @@ +// A core part of the xlsx serialisation routine is taking doubles from memory and stringifying them +// this has a few requirements +// - expect strings in the form 1234.56 (i.e. no thousands seperator, '.' used for the decimal seperator) +// - outputs up to 15 significant figures (excel only serialises numbers up to 15sf) + +#include "benchmark/benchmark.h" +#include +#include +#include + +namespace { + +// setup a large quantity of random doubles as strings +template +class RandomFloats : public benchmark::Fixture +{ + static constexpr size_t Number_of_Elements = 1 << 20; + static_assert(Number_of_Elements > 1'000'000, "ensure a decent set of random values is generated"); + + std::vector inputs; + + size_t index = 0; + const char *locale_str = nullptr; + +public: + void SetUp(const ::benchmark::State &state) + { + if (Decimal_Locale) + { + locale_str = setlocale(LC_ALL, "C"); + } + else + { + locale_str = setlocale(LC_ALL, "de-DE"); + } + std::random_device rd; // obtain a seed for the random number engine + std::mt19937 gen(rd()); + // doing full range is stupid (::min/max()...), it just ends up generating very large numbers + // uniform is probably not the best distribution to use here, but it will do for now + std::uniform_real_distribution dis(-1'000, 1'000); + // generate a large quantity of doubles to deserialise + inputs.reserve(Number_of_Elements); + for (int i = 0; i < Number_of_Elements; ++i) + { + double d = dis(gen); + inputs.push_back(d); + } + } + + void TearDown(const ::benchmark::State &state) + { + // restore locale + setlocale(LC_ALL, locale_str); + // gbench is keeping the fixtures alive somewhere, need to clear the data after use + inputs = std::vector{}; + } + + double &get_rand() + { + return inputs[++index & (Number_of_Elements - 1)]; + } +}; + +/// Takes in a double and outputs a string form of that number which will +/// serialise and deserialise without loss of precision +std::string serialize_number_to_string(double num) +{ + // more digits and excel won't match + constexpr int Excel_Digit_Precision = 15; //sf + std::stringstream ss; + ss.precision(Excel_Digit_Precision); + ss << num; + return ss.str(); +} + +class number_serialiser +{ + static constexpr int Excel_Digit_Precision = 15; //sf + std::ostringstream ss; + +public: + explicit number_serialiser() + { + ss.precision(Excel_Digit_Precision); + ss.imbue(std::locale("C")); + } + + std::string serialise(double d) + { + ss.str(""); // reset string buffer + ss.clear(); // reset any error flags + ss << d; + return ss.str(); + } +}; + +class number_serialiser_mk2 +{ + static constexpr int Excel_Digit_Precision = 15; //sf + bool should_convert_comma; + + void convert_comma(char *buf, int len) + { + char *buf_end = buf + len; + char *decimal = std::find(buf, buf_end, ','); + if (decimal != buf_end) + { + *decimal = '.'; + } + } + +public: + explicit number_serialiser_mk2() + : should_convert_comma(std::use_facet>(std::locale{}).decimal_point() == ',') + { + } + + std::string serialise(double d) + { + char buf[Excel_Digit_Precision + 1]; // need space for trailing '\0' + int len = snprintf(buf, sizeof(buf), "%.15g", d); + if (should_convert_comma) + { + convert_comma(buf, len); + } + return std::string(buf, len); + } +}; + +using RandFloats = RandomFloats; +using RandFloatsComma = RandomFloats; +} // namespace + +BENCHMARK_F(RandFloats, string_from_double_sstream) +(benchmark::State &state) +{ + while (state.KeepRunning()) + { + benchmark::DoNotOptimize( + serialize_number_to_string(get_rand())); + } +} + +BENCHMARK_F(RandFloats, string_from_double_sstream_cached) +(benchmark::State &state) +{ + number_serialiser ser; + while (state.KeepRunning()) + { + benchmark::DoNotOptimize( + ser.serialise(get_rand())); + } +} + +BENCHMARK_F(RandFloats, string_from_double_snprintf) +(benchmark::State &state) +{ + while (state.KeepRunning()) + { + char buf[16]; + int len = snprintf(buf, sizeof(buf), "%.15g", get_rand()); + + benchmark::DoNotOptimize( + std::string(buf, len)); + } +} + +BENCHMARK_F(RandFloats, string_from_double_snprintf_fixed) +(benchmark::State &state) +{ + number_serialiser_mk2 ser; + while (state.KeepRunning()) + { + benchmark::DoNotOptimize( + ser.serialise(get_rand())); + } +} + +// locale names are different between OS's, and std::from_chars is only complete in MSVC +#ifdef _MSC_VER + +#include +BENCHMARK_F(RandFloats, string_from_double_std_to_chars) +(benchmark::State &state) +{ + while (state.KeepRunning()) + { + char buf[16]; + std::to_chars_result result = std::to_chars(buf, buf + std::size(buf), get_rand()); + + benchmark::DoNotOptimize( + std::string(buf, result.ptr)); + } +} + +BENCHMARK_F(RandFloatsComma, string_from_double_snprintf_fixed_comma) +(benchmark::State &state) +{ + number_serialiser_mk2 ser; + while (state.KeepRunning()) + { + benchmark::DoNotOptimize( + ser.serialise(get_rand())); + } +} + +#endif \ No newline at end of file diff --git a/libs/EXTERNAL/xlnt/benchmarks/microbenchmarks/string_to_double.cpp b/libs/EXTERNAL/xlnt/benchmarks/microbenchmarks/string_to_double.cpp new file mode 100644 index 00000000000..5392f0a25bb --- /dev/null +++ b/libs/EXTERNAL/xlnt/benchmarks/microbenchmarks/string_to_double.cpp @@ -0,0 +1,223 @@ +// A core part of the xlsx parsing routine is taking strings from the xml parser and parsing these to a double +// this has a few requirements +// - expect strings in the form 1234.56 (i.e. no thousands seperator, '.' used for the decimal seperator) +// - handles atleast 15 significant figures (excel only serialises numbers up to 15sf) + +#include +#include +#include +#include + +namespace { + +// setup a large quantity of random doubles as strings +template +class RandomFloatStrs : public benchmark::Fixture +{ + static constexpr size_t Number_of_Elements = 1 << 20; + static_assert(Number_of_Elements > 1'000'000, "ensure a decent set of random values is generated"); + + std::vector inputs; + + size_t index = 0; + const char *locale_str = nullptr; + +public: + void SetUp(const ::benchmark::State &state) + { + if (Decimal_Locale) + { + locale_str = setlocale(LC_ALL, "C"); + } + else + { + locale_str = setlocale(LC_ALL, "de-DE"); + } + std::random_device rd; // obtain a seed for the random number engine + std::mt19937 gen(rd()); + // doing full range is stupid (::min/max()...), it just ends up generating very large numbers + // uniform is probably not the best distribution to use here, but it will do for now + std::uniform_real_distribution dis(-1'000, 1'000); + // generate a large quantity of doubles to deserialise + inputs.reserve(Number_of_Elements); + for (int i = 0; i < Number_of_Elements; ++i) + { + double d = dis(gen); + char buf[16]; + snprintf(buf, 16, "%.15f", d); + inputs.push_back(std::string(buf)); + } + } + + void TearDown(const ::benchmark::State &state) + { + // restore locale + setlocale(LC_ALL, locale_str); + // gbench is keeping the fixtures alive somewhere, need to clear the data after use + inputs = std::vector{}; + } + + std::string &get_rand() + { + return inputs[++index & (Number_of_Elements - 1)]; + } +}; + +// method used by xlsx_consumer.cpp in commit - ba01de47a7d430764c20ec9ac9600eec0eb38bcf +// std::istringstream with the locale set to "C" +struct number_converter +{ + number_converter() + { + stream.imbue(std::locale("C")); + } + + double stold(const std::string &s) + { + stream.str(s); + stream.clear(); + stream >> result; + return result; + } + + std::istringstream stream; + double result; +}; + + +// to resolve the locale issue with strtod, a little preprocessing of the input is required +struct number_converter_mk2 +{ + explicit number_converter_mk2() + : should_convert_to_comma(std::use_facet>(std::locale{}).decimal_point() == ',') + { + } + + double stold(std::string &s) const noexcept + { + assert(!s.empty()); + if (should_convert_to_comma) + { + auto decimal_pt = std::find(s.begin(), s.end(), '.'); + if (decimal_pt != s.end()) + { + *decimal_pt = ','; + } + } + return strtod(s.c_str(), nullptr); + } + + double stold(const std::string &s) const + { + assert(!s.empty()); + if (!should_convert_to_comma) + { + return strtod(s.c_str(), nullptr); + } + std::string copy(s); + auto decimal_pt = std::find(copy.begin(), copy.end(), '.'); + if (decimal_pt != copy.end()) + { + *decimal_pt = ','; + } + return strtod(copy.c_str(), nullptr); + } + +private: + bool should_convert_to_comma = false; +}; + +using RandFloatStrs = RandomFloatStrs; +// german locale uses ',' as the seperator +using RandFloatCommaStrs = RandomFloatStrs; +} // namespace + +BENCHMARK_F(RandFloatStrs, double_from_string_sstream) +(benchmark::State &state) +{ + number_converter converter; + while (state.KeepRunning()) + { + benchmark::DoNotOptimize( + converter.stold(get_rand())); + } +} + +// using strotod +// https://en.cppreference.com/w/cpp/string/byte/strtof +// this naive usage is broken in the face of locales (fails condition 1) +#include +BENCHMARK_F(RandFloatStrs, double_from_string_strtod) +(benchmark::State &state) +{ + while (state.KeepRunning()) + { + benchmark::DoNotOptimize( + strtod(get_rand().c_str(), nullptr)); + } +} + +BENCHMARK_F(RandFloatStrs, double_from_string_strtod_fixed) +(benchmark::State &state) +{ + number_converter_mk2 converter; + while (state.KeepRunning()) + { + benchmark::DoNotOptimize( + converter.stold(get_rand())); + } +} + +BENCHMARK_F(RandFloatStrs, double_from_string_strtod_fixed_const_ref) +(benchmark::State &state) +{ + number_converter_mk2 converter; + while (state.KeepRunning()) + { + const std::string &inp = get_rand(); + benchmark::DoNotOptimize( + converter.stold(inp)); + } +} + +// locale names are different between OS's, and std::from_chars is only complete in MSVC +#ifdef _MSC_VER + +#include +BENCHMARK_F(RandFloatStrs, double_from_string_std_from_chars) +(benchmark::State &state) +{ + while (state.KeepRunning()) + { + const std::string &input = get_rand(); + double output; + benchmark::DoNotOptimize( + std::from_chars(input.data(), input.data() + input.size(), output)); + } +} + +// not using the standard "C" locale with '.' seperator +BENCHMARK_F(RandFloatCommaStrs, double_from_string_strtod_fixed_comma_ref) +(benchmark::State &state) +{ + number_converter_mk2 converter; + while (state.KeepRunning()) + { + benchmark::DoNotOptimize( + converter.stold(get_rand())); + } +} + +BENCHMARK_F(RandFloatCommaStrs, double_from_string_strtod_fixed_comma_const_ref) +(benchmark::State &state) +{ + number_converter_mk2 converter; + while (state.KeepRunning()) + { + const std::string &inp = get_rand(); + benchmark::DoNotOptimize( + converter.stold(inp)); + } +} + +#endif \ No newline at end of file diff --git a/libs/EXTERNAL/xlnt/benchmarks/spreadsheet-load.cpp b/libs/EXTERNAL/xlnt/benchmarks/spreadsheet-load.cpp new file mode 100644 index 00000000000..64318c79113 --- /dev/null +++ b/libs/EXTERNAL/xlnt/benchmarks/spreadsheet-load.cpp @@ -0,0 +1,58 @@ +#include +#include +#include + +namespace { +using milliseconds_d = std::chrono::duration; + +void run_load_test(const xlnt::path &file, int runs = 10) +{ + std::cout << file.string() << "\n\n"; + + xlnt::workbook wb; + std::vector test_timings; + + for (int i = 0; i < runs; ++i) + { + auto start = std::chrono::steady_clock::now(); + wb.load(file); + + auto end = std::chrono::steady_clock::now(); + wb.clear(); + test_timings.push_back(end - start); + + std::cout << milliseconds_d(test_timings.back()).count() << " ms\n"; + } +} + +void run_save_test(const xlnt::path &file, int runs = 10) +{ + std::cout << file.string() << "\n\n"; + + xlnt::workbook wb; + wb.load(file); + const xlnt::path save_path(file.filename()); + + std::vector test_timings; + + for (int i = 0; i < runs; ++i) + { + auto start = std::chrono::steady_clock::now(); + + wb.save(save_path); + + auto end = std::chrono::steady_clock::now(); + test_timings.push_back(end - start); + std::cout << milliseconds_d(test_timings.back()).count() << " ms\n"; + } +} +} // namespace + +int main() +{ + run_load_test(path_helper::benchmark_file("large.xlsx")); + run_load_test(path_helper::benchmark_file("very_large.xlsx")); + + run_save_test(path_helper::benchmark_file("large.xlsx")); + run_save_test(path_helper::benchmark_file("very_large.xlsx")); +} \ No newline at end of file diff --git a/libs/EXTERNAL/xlnt/benchmarks/styles.cpp b/libs/EXTERNAL/xlnt/benchmarks/styles.cpp new file mode 100644 index 00000000000..cff6314412b --- /dev/null +++ b/libs/EXTERNAL/xlnt/benchmarks/styles.cpp @@ -0,0 +1,250 @@ +// Copyright (c) 2017-2018 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, ARISING 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 +#include +#include +#include +#include +#include + +#include +#include + +namespace { + +std::size_t random_index(std::size_t max) +{ + static std::random_device rd; + static std::mt19937 gen(rd()); + + std::uniform_int_distribution<> dis(0, static_cast(max - 1)); + + return dis(gen); +} + +void generate_all_formats(xlnt::workbook &wb, std::vector& formats) +{ + const auto vertical_alignments = std::vector + { + xlnt::vertical_alignment::center, + xlnt::vertical_alignment::justify, + xlnt::vertical_alignment::top, + xlnt::vertical_alignment::bottom + }; + + const auto horizontal_alignments = std::vector + { + xlnt::horizontal_alignment::center, + xlnt::horizontal_alignment::center_continuous, + xlnt::horizontal_alignment::general, + xlnt::horizontal_alignment::justify, + xlnt::horizontal_alignment::left, + xlnt::horizontal_alignment::right + }; + + const auto font_names = std::vector + { + "Calibri", + "Tahoma", + "Arial", + "Times New Roman" + }; + + const auto font_sizes = std::vector + { + 11., + 13., + 15., + 17., + 19., + 21., + 23., + 25., + 27., + 29., + 31., + 33., + 35. + }; + + const auto underline_options = std::vector + { + xlnt::font::underline_style::single, + xlnt::font::underline_style::none + }; + + for (auto vertical_alignment : vertical_alignments) + { + for (auto horizontal_alignment : horizontal_alignments) + { + for (auto name : font_names) + { + for (auto size : font_sizes) + { + for (auto bold : { true, false }) + { + for (auto underline : underline_options) + { + for (auto italic : { true, false }) + { + auto fmt = wb.create_format(); + + xlnt::font f; + f.name(name); + f.size(size); + f.italic(italic); + f.underline(underline); + f.bold(bold); + fmt.font(f); + + xlnt::alignment a; + a.vertical(vertical_alignment); + a.horizontal(horizontal_alignment); + fmt.alignment(a); + + formats.push_back(fmt); + } + } + } + } + } + } + } +} + + +xlnt::workbook non_optimized_workbook_formats(int rows_number, int columns_number) +{ + using xlnt::benchmarks::current_time; + + xlnt::workbook wb; + std::vector formats; + auto start = current_time(); + + generate_all_formats(wb, formats); + + auto elapsed = current_time() - start; + + std::cout << "elapsed " << elapsed / 1000.0 << ". generate_all_formats. number of unique formats " << formats.size() << std::endl; + + start = current_time(); + auto worksheet = wb[random_index(wb.sheet_count())]; + auto cells_proceeded = 0; + for (int row_idx = 1; row_idx <= rows_number; row_idx++) + { + for (int col_idx = 1; col_idx <= columns_number; col_idx++) + { + auto cell = worksheet.cell(xlnt::cell_reference((xlnt::column_t)col_idx, (xlnt::row_t)row_idx)); + std::ostringstream string_stm; + string_stm << "Col: " << col_idx << "Row: " << row_idx; + cell.value(string_stm.str()); + cell.format(formats.at(random_index(formats.size()))); + cells_proceeded++; + } + } + + elapsed = current_time() - start; + + std::cout << "elapsed " << elapsed / 1000.0 << ". set values and formats for cells. cells proceeded " << cells_proceeded << std::endl; + + return wb; +} + +void to_save_profile(xlnt::workbook &wb, const std::string &f) +{ + using xlnt::benchmarks::current_time; + + auto start = current_time(); + wb.save(f); + auto elapsed = current_time() - start; + + std::cout << "elapsed " << elapsed / 1000.0 << ". save workbook." << std::endl; +} + +void to_load_profile(xlnt::workbook &wb, const std::string &f) +{ + using xlnt::benchmarks::current_time; + + auto start = current_time(); + wb.load(f); + auto elapsed = current_time() - start; + + std::cout << "elapsed " << elapsed / 1000.0 << ". load workbook." << std::endl; +} + +void read_formats_profile(xlnt::workbook &wb, int rows_number, int columns_number) +{ + using xlnt::benchmarks::current_time; + + std::vector values; + std::vector formats; + auto start = current_time(); + auto worksheet = wb[random_index(wb.sheet_count())]; + for (int row_idx = 1; row_idx <= rows_number; row_idx++) + { + for (int col_idx = 1; col_idx <= columns_number; col_idx++) + { + auto cell = worksheet.cell(xlnt::cell_reference((xlnt::column_t)col_idx, (xlnt::row_t)row_idx)); + values.push_back(cell.value()); + formats.push_back(cell.format()); + } + } + + auto elapsed = current_time() - start; + + std::cout << "elapsed " << elapsed / 1000.0 << ". read values and formats for cells. values count " << values.size() + << ". formats count " << formats.size() << std::endl; +} + +} // namespace + +int main(int argc, char * argv[]) +{ + int rows_number = 1000; + int columns_number = 10; + + try + { + if (argc > 1) + rows_number = std::stoi(argv[1]); + + if (argc > 2) + columns_number = std::stoi(argv[2]); + + std::cout << "started. number of rows " << rows_number << ", number of columns " << columns_number << std::endl; + auto wb = non_optimized_workbook_formats(rows_number, columns_number); + auto f = "temp-formats.xlsx"; + to_save_profile(wb, f); + + xlnt::workbook load_formats_wb; + to_load_profile(load_formats_wb, f); + read_formats_profile(load_formats_wb, rows_number, columns_number); + } + catch(std::exception& ex) + { + std::cout << "failed. " << ex.what() << std::endl; + } + + return 0; +} diff --git a/libs/EXTERNAL/xlnt/benchmarks/writer.cpp b/libs/EXTERNAL/xlnt/benchmarks/writer.cpp new file mode 100644 index 00000000000..f2f94b3c9f6 --- /dev/null +++ b/libs/EXTERNAL/xlnt/benchmarks/writer.cpp @@ -0,0 +1,90 @@ +// Copyright (c) 2017-2018 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, ARISING 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 +#include + +#include +#include + +namespace { + +// Create a worksheet with variable width rows. Because data must be +// serialised row by row it is often the width of the rows which is most +// important. +void writer(int cols, int rows) +{ + xlnt::workbook wb; + auto ws = wb.create_sheet(); + + for(int index = 0; index < rows; index++) + { + if (rows >= 10 && (index + 1) % (rows / 10) == 0) + { + std::string progress = std::string((index + 1) / (1 + rows / 10), '.'); + std::cout << "\r" << progress; + } + + for (int i = 0; i < cols; i++) + { + ws.cell(xlnt::cell_reference(i + 1, index + 1)).value(i); + } + } + std::cout << '\n'; + + auto filename = "benchmark.xlsx"; + wb.save(filename); +} + +// Create a timeit call to a function and pass in keyword arguments. +// The function is called twice, once using the standard workbook, then with the optimised one. +// Time from the best of three is taken. +void timer(std::function fn, int cols, int rows) +{ + const auto repeat = std::size_t(3); + std::chrono::duration time{}; + std::cout << cols << " cols " << rows << " rows" << std::endl; + fn(rows, cols); // 1 cold run + + for(int i = 0; i < repeat; i++) + { + auto start = std::chrono::high_resolution_clock::now(); + fn(cols, rows); + time += std::chrono::high_resolution_clock::now() - start; + } + + std::cout << time.count() / repeat << " ms per iteration" << '\n' << '\n'; +} + +} // namespace + +int main() +{ + timer(&writer, 10000, 1); + timer(&writer, 1000, 10); + timer(&writer, 100, 100); + timer(&writer, 10, 1000); + timer(&writer, 1, 10000); + + return 0; +} diff --git a/libs/EXTERNAL/xlnt/book.json b/libs/EXTERNAL/xlnt/book.json new file mode 100644 index 00000000000..c51052a96be --- /dev/null +++ b/libs/EXTERNAL/xlnt/book.json @@ -0,0 +1,10 @@ +{ + "plugins": ["build"], + "pluginsConfig": { + "build": { + "template": "docs/template.ejs", + "format": "man", + "output": "docs/xlnt.3" + } + } +} diff --git a/libs/EXTERNAL/xlnt/cmake/FindArrow.cmake b/libs/EXTERNAL/xlnt/cmake/FindArrow.cmake new file mode 100644 index 00000000000..c893a1aadb0 --- /dev/null +++ b/libs/EXTERNAL/xlnt/cmake/FindArrow.cmake @@ -0,0 +1,133 @@ +# Licensed to the Apache Software Foundation (ASF) under one +# or more contributor license agreements. See the NOTICE file +# distributed with this work for additional information +# regarding copyright ownership. The ASF licenses this file +# to you under the Apache License, Version 2.0 (the +# "License"); you may not use this file except in compliance +# with the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, +# software distributed under the License is distributed on an +# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +# KIND, either express or implied. See the License for the +# specific language governing permissions and limitations +# under the License. + +# - Find ARROW (arrow/api.h, libarrow.a, libarrow.so) +# This module defines +# ARROW_INCLUDE_DIR, directory containing headers +# ARROW_LIBS, directory containing arrow libraries +# ARROW_STATIC_LIB, path to libarrow.a +# ARROW_SHARED_LIB, path to libarrow's shared library +# ARROW_SHARED_IMP_LIB, path to libarrow's import library (MSVC only) +# ARROW_FOUND, whether arrow has been found + +include(FindPkgConfig) + +if ("$ENV{ARROW_HOME}" STREQUAL "") + pkg_check_modules(ARROW arrow) + if (ARROW_FOUND) + pkg_get_variable(ARROW_ABI_VERSION arrow abi_version) + message(STATUS "Arrow ABI version: ${ARROW_ABI_VERSION}") + pkg_get_variable(ARROW_SO_VERSION arrow so_version) + message(STATUS "Arrow SO version: ${ARROW_SO_VERSION}") + set(ARROW_INCLUDE_DIR ${ARROW_INCLUDE_DIRS}) + set(ARROW_LIBS ${ARROW_LIBRARY_DIRS}) + set(ARROW_SEARCH_LIB_PATH ${ARROW_LIBRARY_DIRS}) + endif() +else() + set(ARROW_HOME "$ENV{ARROW_HOME}") + + set(ARROW_SEARCH_HEADER_PATHS + ${ARROW_HOME}/include + ) + + set(ARROW_SEARCH_LIB_PATH + ${ARROW_HOME}/lib + ) + + find_path(ARROW_INCLUDE_DIR arrow/array.h PATHS + ${ARROW_SEARCH_HEADER_PATHS} + # make sure we don't accidentally pick up a different version + NO_DEFAULT_PATH + ) +endif() + +find_library(ARROW_LIB_PATH NAMES arrow + PATHS + ${ARROW_SEARCH_LIB_PATH} + NO_DEFAULT_PATH) +get_filename_component(ARROW_LIBS ${ARROW_LIB_PATH} DIRECTORY) + +find_library(ARROW_PYTHON_LIB_PATH NAMES arrow_python + PATHS + ${ARROW_SEARCH_LIB_PATH} + NO_DEFAULT_PATH) +get_filename_component(ARROW_PYTHON_LIBS ${ARROW_PYTHON_LIB_PATH} DIRECTORY) + +if (MSVC) + SET(CMAKE_FIND_LIBRARY_SUFFIXES ".lib" ".dll") + + if (MSVC AND NOT ARROW_MSVC_STATIC_LIB_SUFFIX) + set(ARROW_MSVC_STATIC_LIB_SUFFIX "_static") + endif() + + find_library(ARROW_SHARED_LIBRARIES NAMES arrow + PATHS ${ARROW_HOME} NO_DEFAULT_PATH + PATH_SUFFIXES "bin" ) + + find_library(ARROW_PYTHON_SHARED_LIBRARIES NAMES arrow_python + PATHS ${ARROW_HOME} NO_DEFAULT_PATH + PATH_SUFFIXES "bin" ) + get_filename_component(ARROW_SHARED_LIBS ${ARROW_SHARED_LIBRARIES} PATH ) + get_filename_component(ARROW_PYTHON_SHARED_LIBS ${ARROW_PYTHON_SHARED_LIBRARIES} PATH ) +endif () + +if (ARROW_INCLUDE_DIR AND ARROW_LIBS) + set(ARROW_FOUND TRUE) + set(ARROW_LIB_NAME arrow) + set(ARROW_PYTHON_LIB_NAME arrow_python) + if (MSVC) + set(ARROW_STATIC_LIB ${ARROW_LIBS}/${ARROW_LIB_NAME}${ARROW_MSVC_STATIC_LIB_SUFFIX}${CMAKE_STATIC_LIBRARY_SUFFIX}) + set(ARROW_PYTHON_STATIC_LIB ${ARROW_PYTHON_LIBS}/${ARROW_PYTHON_LIB_NAME}${ARROW_MSVC_STATIC_LIB_SUFFIX}${CMAKE_STATIC_LIBRARY_SUFFIX}) + set(ARROW_SHARED_LIB ${ARROW_SHARED_LIBS}/${ARROW_LIB_NAME}${CMAKE_SHARED_LIBRARY_SUFFIX}) + set(ARROW_PYTHON_SHARED_LIB ${ARROW_PYTHON_SHARED_LIBS}/${ARROW_PYTHON_LIB_NAME}${CMAKE_SHARED_LIBRARY_SUFFIX}) + set(ARROW_SHARED_IMP_LIB ${ARROW_LIBS}/${ARROW_LIB_NAME}.lib) + set(ARROW_PYTHON_SHARED_IMP_LIB ${ARROW_PYTHON_LIBS}/${ARROW_PYTHON_LIB_NAME}.lib) + else() + set(ARROW_STATIC_LIB ${ARROW_PYTHON_LIB_PATH}/lib${ARROW_LIB_NAME}.a) + set(ARROW_PYTHON_STATIC_LIB ${ARROW_PYTHON_LIB_PATH}/lib${ARROW_PYTHON_LIB_NAME}.a) + + set(ARROW_SHARED_LIB ${ARROW_LIBS}/lib${ARROW_LIB_NAME}${CMAKE_SHARED_LIBRARY_SUFFIX}) + set(ARROW_PYTHON_SHARED_LIB ${ARROW_LIBS}/lib${ARROW_PYTHON_LIB_NAME}${CMAKE_SHARED_LIBRARY_SUFFIX}) + endif() +endif() + +if (ARROW_FOUND) + if (NOT Arrow_FIND_QUIETLY) + message(STATUS "Found the Arrow core library: ${ARROW_LIB_PATH}") + message(STATUS "Found the Arrow Python library: ${ARROW_PYTHON_LIB_PATH}") + endif () +else () + if (NOT Arrow_FIND_QUIETLY) + set(ARROW_ERR_MSG "Could not find the Arrow library. Looked for headers") + set(ARROW_ERR_MSG "${ARROW_ERR_MSG} in ${ARROW_SEARCH_HEADER_PATHS}, and for libs") + set(ARROW_ERR_MSG "${ARROW_ERR_MSG} in ${ARROW_SEARCH_LIB_PATH}") + if (Arrow_FIND_REQUIRED) + message(FATAL_ERROR "${ARROW_ERR_MSG}") + else (Arrow_FIND_REQUIRED) + message(STATUS "${ARROW_ERR_MSG}") + endif (Arrow_FIND_REQUIRED) + endif () + set(ARROW_FOUND FALSE) +endif () + +mark_as_advanced( + ARROW_INCLUDE_DIR + ARROW_STATIC_LIB + ARROW_SHARED_LIB + ARROW_PYTHON_STATIC_LIB + ARROW_PYTHON_SHARED_LIB +) diff --git a/libs/EXTERNAL/xlnt/cmake/XlntConfig.cmake.in b/libs/EXTERNAL/xlnt/cmake/XlntConfig.cmake.in new file mode 100644 index 00000000000..2100b91ba9a --- /dev/null +++ b/libs/EXTERNAL/xlnt/cmake/XlntConfig.cmake.in @@ -0,0 +1,13 @@ +set(XLNT_VERSION "@xlnt_VERSION@") + +@PACKAGE_INIT@ + +get_filename_component(XLNT_CMAKE_DIR "${CMAKE_CURRENT_LIST_FILE}" PATH) + +set_and_check(XLNT_INCLUDE_DIR "@XLNT_INCLUDE_INSTALL_DIR@") + +check_required_components(xlnt) + +if(NOT TARGET xlnt::xlnt) + include("${XLNT_CMAKE_DIR}/XlntTargets.cmake") +endif() diff --git a/libs/EXTERNAL/xlnt/cmake/cmake_uninstall.cmake.in b/libs/EXTERNAL/xlnt/cmake/cmake_uninstall.cmake.in new file mode 100644 index 00000000000..bc37cfec8e6 --- /dev/null +++ b/libs/EXTERNAL/xlnt/cmake/cmake_uninstall.cmake.in @@ -0,0 +1,33 @@ +if(NOT EXISTS "@CMAKE_BINARY_DIR@/install_manifest.txt") + message(FATAL_ERROR "Cannot find install manifest: @CMAKE_BINARY_DIR@/install_manifest.txt") +endif(NOT EXISTS "@CMAKE_BINARY_DIR@/install_manifest.txt") + +file(READ "@CMAKE_BINARY_DIR@/install_manifest.txt" files) +string(REGEX REPLACE "\n" ";" files "${files}") +foreach(file ${files}) + message(STATUS "Uninstalling $ENV{DESTDIR}${file}") + if(IS_SYMLINK "$ENV{DESTDIR}${file}" OR EXISTS "$ENV{DESTDIR}${file}") + exec_program( + "@CMAKE_COMMAND@" ARGS "-E remove \"$ENV{DESTDIR}${file}\"" + OUTPUT_VARIABLE rm_out + RETURN_VALUE rm_retval + ) + if(NOT "${rm_retval}" STREQUAL 0) + message(FATAL_ERROR "Problem when removing $ENV{DESTDIR}${file}") + endif(NOT "${rm_retval}" STREQUAL 0) + else(IS_SYMLINK "$ENV{DESTDIR}${file}" OR EXISTS "$ENV{DESTDIR}${file}") + message(STATUS "File $ENV{DESTDIR}${file} does not exist.") + endif(IS_SYMLINK "$ENV{DESTDIR}${file}" OR EXISTS "$ENV{DESTDIR}${file}") +endforeach(file) + +message(STATUS "Uninstalling @INC_DEST_DIR@/xlnt") + +exec_program("@CMAKE_COMMAND@" + ARGS "-E remove_directory @INC_DEST_DIR@/xlnt" + OUTPUT_VARIABLE rm_out + RETURN_VALUE rm_retval +) + +if(NOT "${rm_retval}" STREQUAL 0) + message(FATAL_ERROR "Problem when removing @INC_DEST_DIR@/xlnt") +endif() \ No newline at end of file diff --git a/libs/EXTERNAL/xlnt/cmake/pkg-config.pc.cmake b/libs/EXTERNAL/xlnt/cmake/pkg-config.pc.cmake new file mode 100644 index 00000000000..207cb951aa0 --- /dev/null +++ b/libs/EXTERNAL/xlnt/cmake/pkg-config.pc.cmake @@ -0,0 +1,10 @@ +Name: ${PROJECT_NAME} +Description: ${PROJECT_DESCRIPTION} +Version: ${PROJECT_VERSION} +URL: ${PROJECT_URL} +prefix=${CMAKE_INSTALL_PREFIX} +includedir=${PKG_CONFIG_INCLUDEDIR} +libdir=${PKG_CONFIG_LIBDIR} +exec_prefix=${PKG_CONFIG_EXEC_PREFIX} +Libs: ${PKG_CONFIG_LIBS} +Cflags: ${PKG_CONFIG_CFLAGS} diff --git a/libs/EXTERNAL/xlnt/cmake/ucm.cmake b/libs/EXTERNAL/xlnt/cmake/ucm.cmake new file mode 100644 index 00000000000..5dc8e4e2570 --- /dev/null +++ b/libs/EXTERNAL/xlnt/cmake/ucm.cmake @@ -0,0 +1,634 @@ +# +# ucm.cmake - useful cmake macros +# +# Copyright (c) 2016 Viktor Kirilov +# +# Distributed under the MIT Software License +# See accompanying file LICENSE.txt or copy at +# https://opensource.org/licenses/MIT +# +# The documentation can be found at the library's page: +# https://github.com/onqtam/ucm + +cmake_minimum_required(VERSION 2.8.12) + +include(CMakeParseArguments) + +# optionally include cotire - the git submodule might not be inited (or the user might have already included it) +if(NOT COMMAND cotire) + include(${CMAKE_CURRENT_LIST_DIR}/../cotire/CMake/cotire.cmake OPTIONAL) +endif() + +if(COMMAND cotire AND "1.7.9" VERSION_LESS "${COTIRE_CMAKE_MODULE_VERSION}") + set(ucm_with_cotire 1) +else() + set(ucm_with_cotire 0) +endif() + +option(UCM_UNITY_BUILD "Enable unity build for targets registered with the ucm_add_target() macro" OFF) +option(UCM_NO_COTIRE_FOLDER "Do not use a cotire folder in the solution explorer for all unity and cotire related targets" ON) + +# ucm_add_flags +# Adds compiler flags to CMAKE__FLAGS or to a specific config +macro(ucm_add_flags) + cmake_parse_arguments(ARG "C;CXX;CLEAR_OLD" "" "CONFIG" ${ARGN}) + + if(NOT ARG_CONFIG) + set(ARG_CONFIG " ") + endif() + + foreach(CONFIG ${ARG_CONFIG}) + # determine to which flags to add + if(NOT ${CONFIG} STREQUAL " ") + string(TOUPPER ${CONFIG} CONFIG) + set(CXX_FLAGS CMAKE_CXX_FLAGS_${CONFIG}) + set(C_FLAGS CMAKE_C_FLAGS_${CONFIG}) + else() + set(CXX_FLAGS CMAKE_CXX_FLAGS) + set(C_FLAGS CMAKE_C_FLAGS) + endif() + + # clear the old flags + if(${ARG_CLEAR_OLD}) + if("${ARG_CXX}" OR NOT "${ARG_C}") + set(${CXX_FLAGS} "") + endif() + if("${ARG_C}" OR NOT "${ARG_CXX}") + set(${C_FLAGS} "") + endif() + endif() + + # add all the passed flags + foreach(flag ${ARG_UNPARSED_ARGUMENTS}) + if("${ARG_CXX}" OR NOT "${ARG_C}") + set(${CXX_FLAGS} "${${CXX_FLAGS}} ${flag}") + endif() + if("${ARG_C}" OR NOT "${ARG_CXX}") + set(${C_FLAGS} "${${C_FLAGS}} ${flag}") + endif() + endforeach() + endforeach() + +endmacro() + +# ucm_set_flags +# Sets the CMAKE__FLAGS compiler flags or for a specific config +macro(ucm_set_flags) + ucm_add_flags(CLEAR_OLD ${ARGN}) +endmacro() + +# ucm_add_linker_flags +# Adds linker flags to CMAKE__LINKER_FLAGS or to a specific config +macro(ucm_add_linker_flags) + cmake_parse_arguments(ARG "CLEAR_OLD;EXE;MODULE;SHARED;STATIC" "" "CONFIG" ${ARGN}) + + if(NOT ARG_CONFIG) + set(ARG_CONFIG " ") + endif() + + foreach(CONFIG ${ARG_CONFIG}) + string(TOUPPER "${CONFIG}" CONFIG) + + if(NOT ${ARG_EXE} AND NOT ${ARG_MODULE} AND NOT ${ARG_SHARED} AND NOT ${ARG_STATIC}) + set(ARG_EXE 1) + set(ARG_MODULE 1) + set(ARG_SHARED 1) + set(ARG_STATIC 1) + endif() + + set(flags_configs "") + if(${ARG_EXE}) + if(NOT "${CONFIG}" STREQUAL " ") + list(APPEND flags_configs CMAKE_EXE_LINKER_FLAGS_${CONFIG}) + else() + list(APPEND flags_configs CMAKE_EXE_LINKER_FLAGS) + endif() + endif() + if(${ARG_MODULE}) + if(NOT "${CONFIG}" STREQUAL " ") + list(APPEND flags_configs CMAKE_MODULE_LINKER_FLAGS_${CONFIG}) + else() + list(APPEND flags_configs CMAKE_MODULE_LINKER_FLAGS) + endif() + endif() + if(${ARG_SHARED}) + if(NOT "${CONFIG}" STREQUAL " ") + list(APPEND flags_configs CMAKE_SHARED_LINKER_FLAGS_${CONFIG}) + else() + list(APPEND flags_configs CMAKE_SHARED_LINKER_FLAGS) + endif() + endif() + if(${ARG_STATIC}) + if(NOT "${CONFIG}" STREQUAL " ") + list(APPEND flags_configs CMAKE_STATIC_LINKER_FLAGS_${CONFIG}) + else() + list(APPEND flags_configs CMAKE_STATIC_LINKER_FLAGS) + endif() + endif() + + # clear the old flags + if(${ARG_CLEAR_OLD}) + foreach(flags ${flags_configs}) + set(${flags} "") + endforeach() + endif() + + # add all the passed flags + foreach(flag ${ARG_UNPARSED_ARGUMENTS}) + foreach(flags ${flags_configs}) + set(${flags} "${${flags}} ${flag}") + endforeach() + endforeach() + endforeach() +endmacro() + +# ucm_set_linker_flags +# Sets the CMAKE__LINKER_FLAGS linker flags or for a specific config +macro(ucm_set_linker_flags) + ucm_add_linker_flags(CLEAR_OLD ${ARGN}) +endmacro() + +# ucm_gather_flags +# Gathers all lists of flags for printing or manipulation +macro(ucm_gather_flags with_linker result) + set(${result} "") + # add the main flags without a config + list(APPEND ${result} CMAKE_C_FLAGS) + list(APPEND ${result} CMAKE_CXX_FLAGS) + if(${with_linker}) + list(APPEND ${result} CMAKE_EXE_LINKER_FLAGS) + list(APPEND ${result} CMAKE_MODULE_LINKER_FLAGS) + list(APPEND ${result} CMAKE_SHARED_LINKER_FLAGS) + list(APPEND ${result} CMAKE_STATIC_LINKER_FLAGS) + endif() + + if("${CMAKE_CONFIGURATION_TYPES}" STREQUAL "" AND NOT "${CMAKE_BUILD_TYPE}" STREQUAL "") + # handle single config generators - like makefiles/ninja - when CMAKE_BUILD_TYPE is set + string(TOUPPER ${CMAKE_BUILD_TYPE} config) + list(APPEND ${result} CMAKE_C_FLAGS_${config}) + list(APPEND ${result} CMAKE_CXX_FLAGS_${config}) + if(${with_linker}) + list(APPEND ${result} CMAKE_EXE_LINKER_FLAGS_${config}) + list(APPEND ${result} CMAKE_MODULE_LINKER_FLAGS_${config}) + list(APPEND ${result} CMAKE_SHARED_LINKER_FLAGS_${config}) + list(APPEND ${result} CMAKE_STATIC_LINKER_FLAGS_${config}) + endif() + else() + # handle multi config generators (like msvc, xcode) + foreach(config ${CMAKE_CONFIGURATION_TYPES}) + string(TOUPPER ${config} config) + list(APPEND ${result} CMAKE_C_FLAGS_${config}) + list(APPEND ${result} CMAKE_CXX_FLAGS_${config}) + if(${with_linker}) + list(APPEND ${result} CMAKE_EXE_LINKER_FLAGS_${config}) + list(APPEND ${result} CMAKE_MODULE_LINKER_FLAGS_${config}) + list(APPEND ${result} CMAKE_SHARED_LINKER_FLAGS_${config}) + list(APPEND ${result} CMAKE_STATIC_LINKER_FLAGS_${config}) + endif() + endforeach() + endif() +endmacro() + +# ucm_set_runtime +# Sets the runtime (static/dynamic) for msvc/gcc +macro(ucm_set_runtime) + cmake_parse_arguments(ARG "STATIC;DYNAMIC" "" "" ${ARGN}) + + if(ARG_UNPARSED_ARGUMENTS) + message(FATAL_ERROR "unrecognized arguments: ${ARG_UNPARSED_ARGUMENTS}") + endif() + + if(CMAKE_CXX_COMPILER_ID MATCHES "Clang" STREQUAL "") + message(AUTHOR_WARNING "ucm_set_runtime() does not support clang yet!") + endif() + + ucm_gather_flags(0 flags_configs) + + # add/replace the flags + # note that if the user has messed with the flags directly this function might fail + # - for example if with MSVC and the user has removed the flags - here we just switch/replace them + if("${ARG_STATIC}") + foreach(flags ${flags_configs}) + if(CMAKE_CXX_COMPILER_ID MATCHES "GNU") + if(NOT ${flags} MATCHES "-static-libstdc\\+\\+") + set(${flags} "${${flags}} -static-libstdc++") + endif() + if(NOT ${flags} MATCHES "-static-libgcc") + set(${flags} "${${flags}} -static-libgcc") + endif() + elseif(MSVC) + if(${flags} MATCHES "/MD") + string(REGEX REPLACE "/MD" "/MT" ${flags} "${${flags}}") + endif() + endif() + endforeach() + elseif("${ARG_DYNAMIC}") + foreach(flags ${flags_configs}) + if(CMAKE_CXX_COMPILER_ID MATCHES "GNU") + if(${flags} MATCHES "-static-libstdc\\+\\+") + string(REGEX REPLACE "-static-libstdc\\+\\+" "" ${flags} "${${flags}}") + endif() + if(${flags} MATCHES "-static-libgcc") + string(REGEX REPLACE "-static-libgcc" "" ${flags} "${${flags}}") + endif() + elseif(MSVC) + if(${flags} MATCHES "/MT") + string(REGEX REPLACE "/MT" "/MD" ${flags} "${${flags}}") + endif() + endif() + endforeach() + endif() +endmacro() + +# ucm_print_flags +# Prints all compiler flags for all configurations +macro(ucm_print_flags) + ucm_gather_flags(1 flags_configs) + message("") + foreach(flags ${flags_configs}) + message("${flags}: ${${flags}}") + endforeach() + message("") +endmacro() + +# ucm_count_sources +# Counts the number of source files +macro(ucm_count_sources) + cmake_parse_arguments(ARG "" "RESULT" "" ${ARGN}) + if(${ARG_RESULT} STREQUAL "") + message(FATAL_ERROR "Need to pass RESULT and a variable name to ucm_count_sources()") + endif() + + set(result 0) + foreach(SOURCE_FILE ${ARG_UNPARSED_ARGUMENTS}) + if("${SOURCE_FILE}" MATCHES \\.\(c|C|cc|cp|cpp|CPP|c\\+\\+|cxx|i|ii\)$) + math(EXPR result "${result} + 1") + endif() + endforeach() + set(${ARG_RESULT} ${result}) +endmacro() + +# ucm_include_file_in_sources +# Includes the file to the source with compiler flags +macro(ucm_include_file_in_sources) + cmake_parse_arguments(ARG "" "HEADER" "" ${ARGN}) + if(${ARG_HEADER} STREQUAL "") + message(FATAL_ERROR "Need to pass HEADER and a header file to ucm_include_file_in_sources()") + endif() + + foreach(src ${ARG_UNPARSED_ARGUMENTS}) + if(${src} MATCHES \\.\(c|C|cc|cp|cpp|CPP|c\\+\\+|cxx\)$) + # get old flags + get_source_file_property(old_compile_flags ${src} COMPILE_FLAGS) + if(old_compile_flags STREQUAL "NOTFOUND") + set(old_compile_flags "") + endif() + + # update flags + if(MSVC) + set_source_files_properties(${src} PROPERTIES COMPILE_FLAGS + "${old_compile_flags} /FI\"${CMAKE_CURRENT_SOURCE_DIR}/${ARG_HEADER}\"") + else() + set_source_files_properties(${src} PROPERTIES COMPILE_FLAGS + "${old_compile_flags} -include \"${CMAKE_CURRENT_SOURCE_DIR}/${ARG_HEADER}\"") + endif() + endif() + endforeach() +endmacro() + +# ucm_dir_list +# Returns a list of subdirectories for a given directory +macro(ucm_dir_list thedir result) + file(GLOB sub-dir "${thedir}/*") + set(list_of_dirs "") + foreach(dir ${sub-dir}) + if(IS_DIRECTORY ${dir}) + get_filename_component(DIRNAME ${dir} NAME) + LIST(APPEND list_of_dirs ${DIRNAME}) + endif() + endforeach() + set(${result} ${list_of_dirs}) +endmacro() + +# ucm_trim_front_words +# Trims X times the front word from a string separated with "/" and removes +# the front "/" characters after that (used for filters for visual studio) +macro(ucm_trim_front_words source out num_filter_trims) + set(result "${source}") + set(counter 0) + while(${counter} LESS ${num_filter_trims}) + MATH(EXPR counter "${counter} + 1") + # removes everything at the front up to a "/" character + string(REGEX REPLACE "^([^/]+)" "" result "${result}") + # removes all consecutive "/" characters from the front + string(REGEX REPLACE "^(/+)" "" result "${result}") + endwhile() + set(${out} ${result}) +endmacro() + +# ucm_remove_files +# Removes source files from a list of sources (path is the relative path for it to be found) +macro(ucm_remove_files) + cmake_parse_arguments(ARG "" "FROM" "" ${ARGN}) + + if("${ARG_UNPARSED_ARGUMENTS}" STREQUAL "") + message(FATAL_ERROR "Need to pass some relative files to ucm_remove_files()") + endif() + if(${ARG_FROM} STREQUAL "") + message(FATAL_ERROR "Need to pass FROM and a variable name to ucm_remove_files()") + endif() + + foreach(cur_file ${ARG_UNPARSED_ARGUMENTS}) + list(REMOVE_ITEM ${ARG_FROM} ${cur_file}) + endforeach() +endmacro() + +# ucm_remove_directories +# Removes all source files from the given directories from the sources list +macro(ucm_remove_directories) + cmake_parse_arguments(ARG "" "FROM" "MATCHES" ${ARGN}) + + if("${ARG_UNPARSED_ARGUMENTS}" STREQUAL "") + message(FATAL_ERROR "Need to pass some relative directories to ucm_remove_directories()") + endif() + if(${ARG_FROM} STREQUAL "") + message(FATAL_ERROR "Need to pass FROM and a variable name to ucm_remove_directories()") + endif() + + foreach(cur_dir ${ARG_UNPARSED_ARGUMENTS}) + foreach(cur_file ${${ARG_FROM}}) + string(REGEX MATCH ${cur_dir} res ${cur_file}) + if(NOT "${res}" STREQUAL "") + if("${ARG_MATCHES}" STREQUAL "") + list(REMOVE_ITEM ${ARG_FROM} ${cur_file}) + else() + foreach(curr_ptrn ${ARG_MATCHES}) + string(REGEX MATCH ${curr_ptrn} res ${cur_file}) + if(NOT "${res}" STREQUAL "") + list(REMOVE_ITEM ${ARG_FROM} ${cur_file}) + break() + endif() + endforeach() + endif() + endif() + endforeach() + endforeach() +endmacro() + +# ucm_add_files_impl +macro(ucm_add_files_impl result trim files) + foreach(cur_file ${files}) + SET(${result} ${${result}} ${cur_file}) + get_filename_component(FILEPATH ${cur_file} PATH) + ucm_trim_front_words("${FILEPATH}" FILEPATH "${trim}") + # replacing forward slashes with back slashes so filters can be generated (back slash used in parsing...) + STRING(REPLACE "/" "\\" FILTERS "${FILEPATH}") + SOURCE_GROUP("${FILTERS}" FILES ${cur_file}) + endforeach() +endmacro() + +# ucm_add_files +# Adds files to a list of sources +macro(ucm_add_files) + cmake_parse_arguments(ARG "" "TO;FILTER_POP" "" ${ARGN}) + + if("${ARG_UNPARSED_ARGUMENTS}" STREQUAL "") + message(FATAL_ERROR "Need to pass some relative files to ucm_add_files()") + endif() + if(${ARG_TO} STREQUAL "") + message(FATAL_ERROR "Need to pass TO and a variable name to ucm_add_files()") + endif() + + if("${ARG_FILTER_POP}" STREQUAL "") + set(ARG_FILTER_POP 0) + endif() + + ucm_add_files_impl(${ARG_TO} ${ARG_FILTER_POP} "${ARG_UNPARSED_ARGUMENTS}") +endmacro() + +# ucm_add_dir_impl +macro(ucm_add_dir_impl result rec trim dirs_in additional_ext) + set(dirs "${dirs_in}") + + # handle the "" and "." cases + if("${dirs}" STREQUAL "" OR "${dirs}" STREQUAL ".") + set(dirs "./") + endif() + + foreach(cur_dir ${dirs}) + # to circumvent some linux/cmake/path issues - barely made it work... + if(cur_dir STREQUAL "./") + set(cur_dir "") + else() + set(cur_dir "${cur_dir}/") + endif() + + # since unix is case sensitive - add these valid extensions too + # we don't use "UNIX" but instead "CMAKE_HOST_UNIX" because we might be cross + # compiling (for example emscripten) under windows and UNIX may be set to 1 + # Also OSX is case insensitive like windows... + set(additional_file_extensions "") + if(CMAKE_HOST_UNIX AND NOT APPLE) + set(additional_file_extensions + "${cur_dir}*.CPP" + "${cur_dir}*.C" + "${cur_dir}*.H" + "${cur_dir}*.HPP" + ) + endif() + + foreach(ext ${additional_ext}) + list(APPEND additional_file_extensions "${cur_dir}*.${ext}") + endforeach() + + # find all sources and set them as result + FILE(GLOB found_sources RELATIVE "${CMAKE_CURRENT_SOURCE_DIR}" + # https://gcc.gnu.org/onlinedocs/gcc-4.4.1/gcc/Overall-Options.html#index-file-name-suffix-71 + # sources + "${cur_dir}*.cpp" + "${cur_dir}*.cxx" + "${cur_dir}*.c++" + "${cur_dir}*.cc" + "${cur_dir}*.cp" + "${cur_dir}*.c" + "${cur_dir}*.i" + "${cur_dir}*.ii" + # headers + "${cur_dir}*.h" + "${cur_dir}*.h++" + "${cur_dir}*.hpp" + "${cur_dir}*.hxx" + "${cur_dir}*.hh" + "${cur_dir}*.inl" + "${cur_dir}*.inc" + "${cur_dir}*.ipp" + "${cur_dir}*.ixx" + "${cur_dir}*.txx" + "${cur_dir}*.tpp" + "${cur_dir}*.tcc" + "${cur_dir}*.tpl" + ${additional_file_extensions}) + SET(${result} ${${result}} ${found_sources}) + + # set the proper filters + ucm_trim_front_words("${cur_dir}" cur_dir "${trim}") + # replacing forward slashes with back slashes so filters can be generated (back slash used in parsing...) + STRING(REPLACE "/" "\\" FILTERS "${cur_dir}") + SOURCE_GROUP("${FILTERS}" FILES ${found_sources}) + endforeach() + + if(${rec}) + foreach(cur_dir ${dirs}) + ucm_dir_list("${cur_dir}" subdirs) + foreach(subdir ${subdirs}) + ucm_add_dir_impl(${result} ${rec} ${trim} "${cur_dir}/${subdir}" "${additional_ext}") + endforeach() + endforeach() + endif() +endmacro() + +# ucm_add_dirs +# Adds all files from directories traversing them recursively to a list of sources +# and generates filters according to their location (accepts relative paths only). +# Also this macro trims X times the front word from the filter string for visual studio filters. +macro(ucm_add_dirs) + cmake_parse_arguments(ARG "RECURSIVE" "TO;FILTER_POP" "ADDITIONAL_EXT" ${ARGN}) + + if(${ARG_TO} STREQUAL "") + message(FATAL_ERROR "Need to pass TO and a variable name to ucm_add_dirs()") + endif() + + if("${ARG_FILTER_POP}" STREQUAL "") + set(ARG_FILTER_POP 0) + endif() + + ucm_add_dir_impl(${ARG_TO} ${ARG_RECURSIVE} ${ARG_FILTER_POP} "${ARG_UNPARSED_ARGUMENTS}" "${ARG_ADDITIONAL_EXT}") +endmacro() + +# ucm_add_target +# Adds a target eligible for cotiring - unity build and/or precompiled header +macro(ucm_add_target) + cmake_parse_arguments(ARG "UNITY" "NAME;TYPE;PCH_FILE;CPP_PER_UNITY" "UNITY_EXCLUDED;SOURCES" ${ARGN}) + + if(NOT "${ARG_UNPARSED_ARGUMENTS}" STREQUAL "") + message(FATAL_ERROR "Unrecognized options passed to ucm_add_target()") + endif() + if("${ARG_NAME}" STREQUAL "") + message(FATAL_ERROR "Need to pass NAME and a name for the target to ucm_add_target()") + endif() + set(valid_types EXECUTABLE STATIC SHARED MODULE) + list(FIND valid_types "${ARG_TYPE}" is_type_valid) + if(${is_type_valid} STREQUAL "-1") + message(FATAL_ERROR "Need to pass TYPE and the type for the target [EXECUTABLE/STATIC/SHARED/MODULE] to ucm_add_target()") + endif() + if("${ARG_SOURCES}" STREQUAL "") + message(FATAL_ERROR "Need to pass SOURCES and a list of source files to ucm_add_target()") + endif() + + # init with the global unity flag + set(do_unity ${UCM_UNITY_BUILD}) + + # check the UNITY argument + if(NOT ARG_UNITY) + set(do_unity FALSE) + endif() + + # if target is excluded through the exclusion list + list(FIND UCM_UNITY_BUILD_EXCLUDE_TARGETS ${ARG_NAME} is_target_excluded) + if(NOT ${is_target_excluded} STREQUAL "-1") + set(do_unity FALSE) + endif() + + # unity build only for targets with > 1 source file (otherwise there will be an additional unnecessary target) + if(do_unity) # optimization + ucm_count_sources(${ARG_SOURCES} RESULT num_sources) + if(${num_sources} LESS 2) + set(do_unity FALSE) + endif() + endif() + + set(wanted_cotire ${do_unity}) + + # if cotire cannot be used + if(do_unity AND NOT ucm_with_cotire) + set(do_unity FALSE) + endif() + + # inform the developer that the current target might benefit from a unity build + if(NOT ARG_UNITY AND ${UCM_UNITY_BUILD}) + ucm_count_sources(${ARG_SOURCES} RESULT num_sources) + if(${num_sources} GREATER 1) + message(AUTHOR_WARNING "Target '${ARG_NAME}' may benefit from a unity build.\nIt has ${num_sources} sources - enable with UNITY flag") + endif() + endif() + + # prepare for the unity build + set(orig_target ${ARG_NAME}) + if(do_unity) + # the original target will be added with a different name than the requested + set(orig_target ${ARG_NAME}_ORIGINAL) + + # exclude requested files from unity build of the current target + foreach(excluded_file "${ARG_UNITY_EXCLUDED}") + set_source_files_properties(${excluded_file} PROPERTIES COTIRE_EXCLUDED TRUE) + endforeach() + endif() + + # add the original target + if(${ARG_TYPE} STREQUAL "EXECUTABLE") + add_executable(${orig_target} ${ARG_SOURCES}) + else() + add_library(${orig_target} ${ARG_TYPE} ${ARG_SOURCES}) + endif() + + if(do_unity) + # set the number of unity cpp files to be used for the unity target + if(NOT "${ARG_CPP_PER_UNITY}" STREQUAL "") + set_property(TARGET ${orig_target} PROPERTY COTIRE_UNITY_SOURCE_MAXIMUM_NUMBER_OF_INCLUDES "${ARG_CPP_PER_UNITY}") + else() + set_property(TARGET ${orig_target} PROPERTY COTIRE_UNITY_SOURCE_MAXIMUM_NUMBER_OF_INCLUDES "100") + endif() + + if(NOT "${ARG_PCH_FILE}" STREQUAL "") + set_target_properties(${orig_target} PROPERTIES COTIRE_CXX_PREFIX_HEADER_INIT "${ARG_PCH_FILE}") + else() + set_target_properties(${orig_target} PROPERTIES COTIRE_ENABLE_PRECOMPILED_HEADER FALSE) + endif() + # add a unity target for the original one with the name intended for the original + set_target_properties(${orig_target} PROPERTIES COTIRE_UNITY_TARGET_NAME ${ARG_NAME}) + + # this is the library call that does the magic + cotire(${orig_target}) + set_target_properties(clean_cotire PROPERTIES FOLDER "CMakePredefinedTargets") + + # disable the original target and enable the unity one + get_target_property(unity_target_name ${orig_target} COTIRE_UNITY_TARGET_NAME) + set_target_properties(${orig_target} PROPERTIES EXCLUDE_FROM_ALL 1 EXCLUDE_FROM_DEFAULT_BUILD 1) + set_target_properties(${unity_target_name} PROPERTIES EXCLUDE_FROM_ALL 0 EXCLUDE_FROM_DEFAULT_BUILD 0) + + # also set the name of the target output as the original one + set_target_properties(${unity_target_name} PROPERTIES OUTPUT_NAME ${ARG_NAME}) + if(UCM_NO_COTIRE_FOLDER) + # reset the folder property so all unity targets dont end up in a single folder in the solution explorer of VS + set_target_properties(${unity_target_name} PROPERTIES FOLDER "") + endif() + set_target_properties(all_unity PROPERTIES FOLDER "CMakePredefinedTargets") + elseif(NOT "${ARG_PCH_FILE}" STREQUAL "") + set(wanted_cotire TRUE) + if(ucm_with_cotire) + set_target_properties(${orig_target} PROPERTIES COTIRE_ADD_UNITY_BUILD FALSE) + set_target_properties(${orig_target} PROPERTIES COTIRE_CXX_PREFIX_HEADER_INIT "${ARG_PCH_FILE}") + cotire(${orig_target}) + set_target_properties(clean_cotire PROPERTIES FOLDER "CMakePredefinedTargets") + endif() + endif() + + # print a message if the target was requested to be cotired but it couldn't + if(wanted_cotire AND NOT ucm_with_cotire) + if(NOT COMMAND cotire) + message(AUTHOR_WARNING "Target \"${ARG_NAME}\" not cotired because cotire isn't loaded") + else() + message(AUTHOR_WARNING "Target \"${ARG_NAME}\" not cotired because cotire is older than the required version") + endif() + endif() +endmacro() diff --git a/libs/EXTERNAL/xlnt/docs/README.md b/libs/EXTERNAL/xlnt/docs/README.md new file mode 100644 index 00000000000..22f207fdbaa --- /dev/null +++ b/libs/EXTERNAL/xlnt/docs/README.md @@ -0,0 +1,25 @@ +# Table of Contents + +* [Read Me](/README.md) +* [Introduction](/docs/introduction/README.md) + * [Motivation](/docs/introduction/Motivation.md) + * [Examples](/docs/introduction/Examples.md) + * [Features](/docs/introduction/Features.md) + * [Installation](/docs/introduction/Installation.md) +* [Basics](/docs/basics/README.md) + * [Workbook](/docs/basics/Workbook.md) + * [Worksheet](/docs/basics/Worksheet.md) + * [Cell](/docs/basics/Cell.md) + * [Iteration](/docs/basics/Iteration.md) +* [Advanced](/docs/advanced/README.md) + * [Formatting](/docs/advanced/Formatting.md) + * [Properties](/docs/advanced/Properties.md) + * [Printing](/docs/advanced/Printing.md) + * [Encryption](/docs/advanced/Encryption.md) + * [Views](/docs/advanced/Views.md) +* [API Reference](/docs/api/README.md) + * [cell](/docs/api/cell.md) + * [cell_reference](/docs/api/cell_reference.md) +* [Change Log](/CHANGELOG.md) +* [Contributing](/CONTRIBUTING.md) +* [License](/LICENSE.md) diff --git a/libs/EXTERNAL/xlnt/docs/advanced/Encryption.md b/libs/EXTERNAL/xlnt/docs/advanced/Encryption.md new file mode 100644 index 00000000000..9db6035f4d4 --- /dev/null +++ b/libs/EXTERNAL/xlnt/docs/advanced/Encryption.md @@ -0,0 +1 @@ +## Encryption diff --git a/libs/EXTERNAL/xlnt/docs/advanced/Formatting.md b/libs/EXTERNAL/xlnt/docs/advanced/Formatting.md new file mode 100644 index 00000000000..c13439352bf --- /dev/null +++ b/libs/EXTERNAL/xlnt/docs/advanced/Formatting.md @@ -0,0 +1,37 @@ + +# Formatting + +## Format vs. Style + +```c++ +#include +#include + +int main() +{ + xlnt::workbook wb; + auto cell = wb.active_sheet().cell("A1"); + return 0; +} +``` + +In the context of xlnt, format and style have specific distinct meanings. A style in xlnt corresponds to a named style created in the "Cell styles" dropdown in Excel. It must have a name and optionally any of: alignment, border, fill, font, number format, protection. A format in xlnt corresponds to the alignment, border, fill, font, number format, and protection settings applied to a cell via right-click->"Format Cells". A cell can have both a format and a style. The style properties will generally override the format properties. + +## Number Formatting + +```c++ +#include +#include + +int main() +{ + xlnt::workbook wb; + auto cell = wb.active_sheet().cell("A1"); + cell.number_format(xlnt::number_format::percentage()); + cell.value(0.513); + std::cout << cell.to_string() << std::endl; + return 0; +} +``` + +An xlnt::number_format is the format code used when displaying a value in a cell. For example, a number_format of "0.00" implies that the number 13.726 should be displayed as "13.73". Many number formats are built-in to Excel and can be access with xlnt::number_format static constructors. Other custom number formats can be created by passing a string to the [xlnt::number_format constructor](#cell-const-cell-amp). diff --git a/libs/EXTERNAL/xlnt/docs/advanced/Printing.md b/libs/EXTERNAL/xlnt/docs/advanced/Printing.md new file mode 100644 index 00000000000..a412b38dd46 --- /dev/null +++ b/libs/EXTERNAL/xlnt/docs/advanced/Printing.md @@ -0,0 +1 @@ +## Printing diff --git a/libs/EXTERNAL/xlnt/docs/advanced/Properties.md b/libs/EXTERNAL/xlnt/docs/advanced/Properties.md new file mode 100644 index 00000000000..15bf4de0521 --- /dev/null +++ b/libs/EXTERNAL/xlnt/docs/advanced/Properties.md @@ -0,0 +1,54 @@ +# 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"); +``` \ No newline at end of file diff --git a/libs/EXTERNAL/xlnt/docs/advanced/README.md b/libs/EXTERNAL/xlnt/docs/advanced/README.md new file mode 100644 index 00000000000..91d7eed0c3d --- /dev/null +++ b/libs/EXTERNAL/xlnt/docs/advanced/README.md @@ -0,0 +1,7 @@ +## Advanced + +* [Formatting](Formatting.md) +* [Properties](Properties.md) +* [Printing](Printing.md) +* [Encryption](Encryption.md) +* [Views](Views.md) \ No newline at end of file diff --git a/libs/EXTERNAL/xlnt/docs/advanced/Views.md b/libs/EXTERNAL/xlnt/docs/advanced/Views.md new file mode 100644 index 00000000000..06b4f28b893 --- /dev/null +++ b/libs/EXTERNAL/xlnt/docs/advanced/Views.md @@ -0,0 +1 @@ +## Views diff --git a/libs/EXTERNAL/xlnt/docs/api/README.md b/libs/EXTERNAL/xlnt/docs/api/README.md new file mode 100644 index 00000000000..5e11d117d4d --- /dev/null +++ b/libs/EXTERNAL/xlnt/docs/api/README.md @@ -0,0 +1,4 @@ +## API + +* [cell](cell.md) +* [cell_reference](cell_reference.md) diff --git a/libs/EXTERNAL/xlnt/docs/api/cell.md b/libs/EXTERNAL/xlnt/docs/api/cell.md new file mode 100644 index 00000000000..2e28c3907ce --- /dev/null +++ b/libs/EXTERNAL/xlnt/docs/api/cell.md @@ -0,0 +1,188 @@ +# cell +## ```using xlnt::cell::type = cell_typeundefined``` +Alias xlnt::cell_type to xlnt::cell::type since it looks nicer. +## ```friend class detail::xlsx_consumerundefined``` +## ```friend class detail::xlsx_producerundefined``` +## ```friend struct detail::cell_implundefined``` +## ```static const std::unordered_map& xlnt::cell::error_codes()``` +Returns a map of error strings such as #DIV/0! and their associated indices. +## ```xlnt::cell::cell(const cell &)=default``` +Default copy constructor. +## ```bool xlnt::cell::has_value() const``` +Returns true if value has been set and has not been cleared using cell::clear_value(). +## ```T xlnt::cell::value() const``` +Returns the value of this cell as an instance of type T. Overloads exist for most C++ fundamental types like bool, int, etc. as well as for std::string and xlnt datetime types: date, time, datetime, and timedelta. +## ```void xlnt::cell::clear_value()``` +Makes this cell have a value of type null. All other cell attributes are retained. +## ```void xlnt::cell::value(std::nullptr_t)``` +Sets the type of this cell to null. +## ```void xlnt::cell::value(bool boolean_value)``` +Sets the value of this cell to the given boolean value. +## ```void xlnt::cell::value(int int_value)``` +Sets the value of this cell to the given value. +## ```void xlnt::cell::value(unsigned int int_value)``` +Sets the value of this cell to the given value. +## ```void xlnt::cell::value(long long int int_value)``` +Sets the value of this cell to the given value. +## ```void xlnt::cell::value(unsigned long long int int_value)``` +Sets the value of this cell to the given value. +## ```void xlnt::cell::value(float float_value)``` +Sets the value of this cell to the given value. +## ```void xlnt::cell::value(double float_value)``` +Sets the value of this cell to the given value. +## ```void xlnt::cell::value(long double float_value)``` +Sets the value of this cell to the given value. +## ```void xlnt::cell::value(const date &date_value)``` +Sets the value of this cell to the given value. +## ```void xlnt::cell::value(const time &time_value)``` +Sets the value of this cell to the given value. +## ```void xlnt::cell::value(const datetime &datetime_value)``` +Sets the value of this cell to the given value. +## ```void xlnt::cell::value(const timedelta &timedelta_value)``` +Sets the value of this cell to the given value. +## ```void xlnt::cell::value(const std::string &string_value)``` +Sets the value of this cell to the given value. +## ```void xlnt::cell::value(const char *string_value)``` +Sets the value of this cell to the given value. +## ```void xlnt::cell::value(const rich_text &text_value)``` +Sets the value of this cell to the given value. +## ```void xlnt::cell::value(const cell other_cell)``` +Sets the value and formatting of this cell to that of other_cell. +## ```void xlnt::cell::value(const std::string &string_value, bool infer_type)``` +Analyzes string_value to determine its type, convert it to that type, and set the value of this cell to that converted value. +## ```type xlnt::cell::data_type() const``` +Returns the type of this cell. +## ```void xlnt::cell::data_type(type t)``` +Sets the type of this cell. This should usually be done indirectly by setting the value of the cell to a value of that type. +## ```bool xlnt::cell::garbage_collectible() const``` +There's no reason to keep a cell which has no value and is not a placeholder. Returns true if this cell has no value, style, isn't merged, etc. +## ```bool xlnt::cell::is_date() const``` +Returns true iff this cell's number format matches a date format. +## ```cell_reference xlnt::cell::reference() const``` +Returns a cell_reference that points to the location of this cell. +## ```column_t xlnt::cell::column() const``` +Returns the column of this cell. +## ```row_t xlnt::cell::row() const``` +Returns the row of this cell. +## ```std::pair xlnt::cell::anchor() const``` +Returns the location of this cell as an ordered pair (left, top). +## ```std::string xlnt::cell::hyperlink() const``` +Returns the URL of this cell's hyperlink. +## ```void xlnt::cell::hyperlink(const std::string &url)``` +Adds a hyperlink to this cell pointing to the URL of the given value. +## ```void xlnt::cell::hyperlink(const std::string &url, const std::string &display)``` +Adds a hyperlink to this cell pointing to the URI of the given value and sets the text value of the cell to the given parameter. +## ```void xlnt::cell::hyperlink(xlnt::cell target)``` +Adds an internal hyperlink to this cell pointing to the given cell. +## ```bool xlnt::cell::has_hyperlink() const``` +Returns true if this cell has a hyperlink set. +## ```class alignment xlnt::cell::computed_alignment() const``` +Returns the alignment that should be used when displaying this cell graphically based on the workbook default, the cell-level format, and the named style applied to the cell in that order. +## ```class border xlnt::cell::computed_border() const``` +Returns the border that should be used when displaying this cell graphically based on the workbook default, the cell-level format, and the named style applied to the cell in that order. +## ```class fill xlnt::cell::computed_fill() const``` +Returns the fill that should be used when displaying this cell graphically based on the workbook default, the cell-level format, and the named style applied to the cell in that order. +## ```class font xlnt::cell::computed_font() const``` +Returns the font that should be used when displaying this cell graphically based on the workbook default, the cell-level format, and the named style applied to the cell in that order. +## ```class number_format xlnt::cell::computed_number_format() const``` +Returns the number format that should be used when displaying this cell graphically based on the workbook default, the cell-level format, and the named style applied to the cell in that order. +## ```class protection xlnt::cell::computed_protection() const``` +Returns the protection that should be used when displaying this cell graphically based on the workbook default, the cell-level format, and the named style applied to the cell in that order. +## ```bool xlnt::cell::has_format() const``` +Returns true if this cell has had a format applied to it. +## ```const class format xlnt::cell::format() const``` +Returns the format applied to this cell. If this cell has no format, an invalid_attribute exception will be thrown. +## ```void xlnt::cell::format(const class format new_format)``` +Applies the cell-level formatting of new_format to this cell. +## ```void xlnt::cell::clear_format()``` +Removes the cell-level formatting from this cell. This doesn't affect the style that may also be applied to the cell. Throws an invalid_attribute exception if no format is applied. +## ```class number_format xlnt::cell::number_format() const``` +Returns the number format of this cell. +## ```void xlnt::cell::number_format(const class number_format &format)``` +Creates a new format in the workbook, sets its number_format to the given format, and applies the format to this cell. +## ```class font xlnt::cell::font() const``` +Returns the font applied to the text in this cell. +## ```void xlnt::cell::font(const class font &font_)``` +Creates a new format in the workbook, sets its font to the given font, and applies the format to this cell. +## ```class fill xlnt::cell::fill() const``` +Returns the fill applied to this cell. +## ```void xlnt::cell::fill(const class fill &fill_)``` +Creates a new format in the workbook, sets its fill to the given fill, and applies the format to this cell. +## ```class border xlnt::cell::border() const``` +Returns the border of this cell. +## ```void xlnt::cell::border(const class border &border_)``` +Creates a new format in the workbook, sets its border to the given border, and applies the format to this cell. +## ```class alignment xlnt::cell::alignment() const``` +Returns the alignment of the text in this cell. +## ```void xlnt::cell::alignment(const class alignment &alignment_)``` +Creates a new format in the workbook, sets its alignment to the given alignment, and applies the format to this cell. +## ```class protection xlnt::cell::protection() const``` +Returns the protection of this cell. +## ```void xlnt::cell::protection(const class protection &protection_)``` +Creates a new format in the workbook, sets its protection to the given protection, and applies the format to this cell. +## ```bool xlnt::cell::has_style() const``` +Returns true if this cell has had a style applied to it. +## ```class style xlnt::cell::style()``` +Returns a wrapper pointing to the named style applied to this cell. +## ```const class style xlnt::cell::style() const``` +Returns a wrapper pointing to the named style applied to this cell. +## ```void xlnt::cell::style(const class style &new_style)``` +Sets the named style applied to this cell to a style named style_name. Equivalent to style(new_style.name()). +## ```void xlnt::cell::style(const std::string &style_name)``` +Sets the named style applied to this cell to a style named style_name. If this style has not been previously created in the workbook, a key_not_found exception will be thrown. +## ```void xlnt::cell::clear_style()``` +Removes the named style from this cell. An invalid_attribute exception will be thrown if this cell has no style. This will not affect the cell format of the cell. +## ```std::string xlnt::cell::formula() const``` +Returns the string representation of the formula applied to this cell. +## ```void xlnt::cell::formula(const std::string &formula)``` +Sets the formula of this cell to the given value. This formula string should begin with '='. +## ```void xlnt::cell::clear_formula()``` +Removes the formula from this cell. After this is called, has_formula() will return false. +## ```bool xlnt::cell::has_formula() const``` +Returns true if this cell has had a formula applied to it. +## ```std::string xlnt::cell::to_string() const``` +Returns a string representing the value of this cell. If the data type is not a string, it will be converted according to the number format. +## ```bool xlnt::cell::is_merged() const``` +Returns true iff this cell has been merged with one or more surrounding cells. +## ```void xlnt::cell::merged(bool merged)``` +Makes this a merged cell iff merged is true. Generally, this shouldn't be called directly. Instead, use worksheet::merge_cells on its parent worksheet. +## ```std::string xlnt::cell::error() const``` +Returns the error string that is stored in this cell. +## ```void xlnt::cell::error(const std::string &error)``` +Directly assigns the value of this cell to be the given error. +## ```cell xlnt::cell::offset(int column, int row)``` +Returns a cell from this cell's parent workbook at a relative offset given by the parameters. +## ```class worksheet xlnt::cell::worksheet()``` +Returns the worksheet that owns this cell. +## ```const class worksheet xlnt::cell::worksheet() const``` +Returns the worksheet that owns this cell. +## ```class workbook& xlnt::cell::workbook()``` +Returns the workbook of the worksheet that owns this cell. +## ```const class workbook& xlnt::cell::workbook() const``` +Returns the workbook of the worksheet that owns this cell. +## ```calendar xlnt::cell::base_date() const``` +Returns the base date of the parent workbook. +## ```std::string xlnt::cell::check_string(const std::string &to_check)``` +Returns to_check after verifying and fixing encoding, size, and illegal characters. +## ```bool xlnt::cell::has_comment()``` +Returns true if this cell has a comment applied. +## ```void xlnt::cell::clear_comment()``` +Deletes the comment applied to this cell if it exists. +## ```class comment xlnt::cell::comment()``` +Gets the comment applied to this cell. +## ```void xlnt::cell::comment(const std::string &text, const std::string &author="Microsoft Office User")``` +Creates a new comment with the given text and optional author and applies it to the cell. +## ```void xlnt::cell::comment(const std::string &comment_text, const class font &comment_font, const std::string &author="Microsoft Office User")``` +Creates a new comment with the given text, formatting, and optional author and applies it to the cell. +## ```void xlnt::cell::comment(const class comment &new_comment)``` +Apply the comment provided as the only argument to the cell. +## ```double xlnt::cell::width() const``` +Returns the width of this cell in pixels. +## ```double xlnt::cell::height() const``` +Returns the height of this cell in pixels. +## ```cell& xlnt::cell::operator=(const cell &rhs)``` +Makes this cell interally point to rhs. The cell data originally pointed to by this cell will be unchanged. +## ```bool xlnt::cell::operator==(const cell &comparand) const``` +Returns true if this cell the same cell as comparand (compared by reference). +## ```bool xlnt::cell::operator==(std::nullptr_t) const``` +Returns true if this cell is uninitialized. diff --git a/libs/EXTERNAL/xlnt/docs/api/cell_reference.md b/libs/EXTERNAL/xlnt/docs/api/cell_reference.md new file mode 100644 index 00000000000..e4ed5645cee --- /dev/null +++ b/libs/EXTERNAL/xlnt/docs/api/cell_reference.md @@ -0,0 +1,55 @@ +# cell_reference +## ```static std::pair xlnt::cell_reference::split_reference(const std::string &reference_string)``` +Splits a coordinate string like "A1" into an equivalent pair like {"A", 1}. +## ```static std::pair xlnt::cell_reference::split_reference(const std::string &reference_string, bool &absolute_column, bool &absolute_row)``` +Splits a coordinate string like "A1" into an equivalent pair like {"A", 1}. Reference parameters absolute_column and absolute_row will be set to true if column part or row part are prefixed by a dollar-sign indicating they are absolute, otherwise false. +## ```xlnt::cell_reference::cell_reference()``` +Default constructor makes a reference to the top-left-most cell, "A1". +## ```xlnt::cell_reference::cell_reference(const char *reference_string)``` +Constructs a cell_reference from a string reprenting a cell coordinate (e.g. $B14). +## ```xlnt::cell_reference::cell_reference(const std::string &reference_string)``` +Constructs a cell_reference from a string reprenting a cell coordinate (e.g. $B14). +## ```xlnt::cell_reference::cell_reference(column_t column, row_t row)``` +Constructs a cell_reference from a 1-indexed column index and row index. +## ```cell_reference& xlnt::cell_reference::make_absolute(bool absolute_column=true, bool absolute_row=true)``` +Converts a coordinate to an absolute coordinate string (e.g. B12 -> $B$12) Defaulting to true, absolute_column and absolute_row can optionally control whether the resulting cell_reference has an absolute column (e.g. B12 -> $B12) and absolute row (e.g. B12 -> B$12) respectively. +## ```bool xlnt::cell_reference::column_absolute() const``` +Returns true if the reference refers to an absolute column, otherwise false. +## ```void xlnt::cell_reference::column_absolute(bool absolute_column)``` +Makes this reference have an absolute column if absolute_column is true, otherwise not absolute. +## ```bool xlnt::cell_reference::row_absolute() const``` +Returns true if the reference refers to an absolute row, otherwise false. +## ```void xlnt::cell_reference::row_absolute(bool absolute_row)``` +Makes this reference have an absolute row if absolute_row is true, otherwise not absolute. +## ```column_t xlnt::cell_reference::column() const``` +Returns a string that identifies the column of this reference (e.g. second column from left is "B") +## ```void xlnt::cell_reference::column(const std::string &column_string)``` +Sets the column of this reference from a string that identifies a particular column. +## ```column_t::index_t xlnt::cell_reference::column_index() const``` +Returns a 1-indexed numeric index of the column of this reference. +## ```void xlnt::cell_reference::column_index(column_t column)``` +Sets the column of this reference from a 1-indexed number that identifies a particular column. +## ```row_t xlnt::cell_reference::row() const``` +Returns a 1-indexed numeric index of the row of this reference. +## ```void xlnt::cell_reference::row(row_t row)``` +Sets the row of this reference from a 1-indexed number that identifies a particular row. +## ```cell_reference xlnt::cell_reference::make_offset(int column_offset, int row_offset) const``` +Returns a cell_reference offset from this cell_reference by the number of columns and rows specified by the parameters. A negative value for column_offset or row_offset results in a reference above or left of this cell_reference, respectively. +## ```std::string xlnt::cell_reference::to_string() const``` +Returns a string like "A1" for cell_reference(1, 1). +## ```range_reference xlnt::cell_reference::to_range() const``` +Returns a 1x1 range_reference containing only this cell_reference. +## ```range_reference xlnt::cell_reference::operator,(const cell_reference &other) const``` +I've always wanted to overload the comma operator. cell_reference("A", 1), cell_reference("B", 1) will return range_reference(cell_reference("A", 1), cell_reference("B", 1)) +## ```bool xlnt::cell_reference::operator==(const cell_reference &comparand) const``` +Returns true if this reference is identical to comparand including in absoluteness of column and row. +## ```bool xlnt::cell_reference::operator==(const std::string &reference_string) const``` +Constructs a cell_reference from reference_string and return the result of their comparison. +## ```bool xlnt::cell_reference::operator==(const char *reference_string) const``` +Constructs a cell_reference from reference_string and return the result of their comparison. +## ```bool xlnt::cell_reference::operator!=(const cell_reference &comparand) const``` +Returns true if this reference is not identical to comparand including in absoluteness of column and row. +## ```bool xlnt::cell_reference::operator!=(const std::string &reference_string) const``` +Constructs a cell_reference from reference_string and return the result of their comparison. +## ```bool xlnt::cell_reference::operator!=(const char *reference_string) const``` +Constructs a cell_reference from reference_string and return the result of their comparison. diff --git a/libs/EXTERNAL/xlnt/docs/basics/Cell.md b/libs/EXTERNAL/xlnt/docs/basics/Cell.md new file mode 100644 index 00000000000..2f13df68296 --- /dev/null +++ b/libs/EXTERNAL/xlnt/docs/basics/Cell.md @@ -0,0 +1 @@ +## Cell diff --git a/libs/EXTERNAL/xlnt/docs/basics/Iteration.md b/libs/EXTERNAL/xlnt/docs/basics/Iteration.md new file mode 100644 index 00000000000..4d3b83c4472 --- /dev/null +++ b/libs/EXTERNAL/xlnt/docs/basics/Iteration.md @@ -0,0 +1 @@ +## Iteration diff --git a/libs/EXTERNAL/xlnt/docs/basics/MemoryModel.md b/libs/EXTERNAL/xlnt/docs/basics/MemoryModel.md new file mode 100644 index 00000000000..f592addc58e --- /dev/null +++ b/libs/EXTERNAL/xlnt/docs/basics/MemoryModel.md @@ -0,0 +1,31 @@ + +# Memory Model + +```c++ +#include +#include + +void set_cell(xlnt::cell cell, int value) +{ + cell.value(value); +} + +xlnt::workbook create_wb() +{ + xlnt::workbook wb; + auto ws = wb.active_sheet(); + set_cell(wb.cell("A1"), 2); + return wb; +} + +int main() +{ + auto wb = create_wb(); + std::cout << wb.value() << std::endl; + return 0; +} +``` + +xlnt uses the pimpl idiom for most of its core data structures. This primary reason for choosing this technique was simplifying usage of the library. Instead of using pointers or references, classes can be passed around by value. Internally they hold a pointer to memory which is within the primary workbook implementation struct. Methods called on the wrapper object dereference the opaque pointer and manipulate its data directly. + +For the user, this means that workbooks, worksheets, cells, formats, and styles can be passed and stored by value. diff --git a/libs/EXTERNAL/xlnt/docs/basics/README.md b/libs/EXTERNAL/xlnt/docs/basics/README.md new file mode 100644 index 00000000000..3e3b288769a --- /dev/null +++ b/libs/EXTERNAL/xlnt/docs/basics/README.md @@ -0,0 +1,6 @@ +## Basics + +* [Workbook](/docs/basics/Workbook.md) +* [Worksheet](/docs/basics/Worksheet.md) +* [Cell](/docs/basics/Cell.md) +* [Iteration](/docs/basics/Iteration.md) diff --git a/libs/EXTERNAL/xlnt/docs/basics/Workbook.md b/libs/EXTERNAL/xlnt/docs/basics/Workbook.md new file mode 100644 index 00000000000..d4138020d29 --- /dev/null +++ b/libs/EXTERNAL/xlnt/docs/basics/Workbook.md @@ -0,0 +1 @@ +## Workbook diff --git a/libs/EXTERNAL/xlnt/docs/basics/Worksheet.md b/libs/EXTERNAL/xlnt/docs/basics/Worksheet.md new file mode 100644 index 00000000000..136663f9697 --- /dev/null +++ b/libs/EXTERNAL/xlnt/docs/basics/Worksheet.md @@ -0,0 +1 @@ +## Worksheet diff --git a/libs/EXTERNAL/xlnt/docs/introduction/Examples.md b/libs/EXTERNAL/xlnt/docs/introduction/Examples.md new file mode 100644 index 00000000000..a4680f42713 --- /dev/null +++ b/libs/EXTERNAL/xlnt/docs/introduction/Examples.md @@ -0,0 +1,195 @@ +## Examples + +### Simple - reading from an existing xlsx spread sheet. + +The following C plus plus code will read the values from an xlsx file and print the string values to the screen. This is a very simple example to get you started. + +```c++ +#include +#include + +int main() +{ + xlnt::workbook wb; + wb.load("/home/timothymccallum/test.xlsx"); + auto ws = wb.active_sheet(); + std::clog << "Processing spread sheet" << std::endl; + for (auto row : ws.rows(false)) + { + for (auto cell : row) + { + std::clog << cell.to_string() << std::endl; + } + } + std::clog << "Processing complete" << std::endl; + return 0; +} +``` +Save the contents of the above file +``` +/home/timothymccallum/process.cpp +``` +Compile by typing the following command +``` +g++ -std=c++14 -lxlnt process.cpp -o process +``` +Excecute by typing the following command +``` +./process +``` +The output of the program, in my case, is as follows +``` +Processing spread sheet +This is cell A1. +This is cell B1 +… and this is cell C1 +We are now on the second row at cell A2 +B2 +C2 +Processing complete +``` +As you can see the process.cpp file simply walks through the spread sheet values row by row and column by column (A1, B1, C1, A2, B2, C2 and so on). + +### Simple - storing a spread sheet in a 2 dimensional C++ Vector for further processing + +Loading a spread sheet into a Vector provides oppourtunities for you to perform high performance processing. There will be more examples on performing fast look-ups, merging data, performing deduplication and more. For now, let's just learn how to get the spread sheet loaded into memory. + +```c++ +#include +#include +#include + +int main() +{ + xlnt::workbook wb; + wb.load("/home/timothymccallum/test.xlsx"); + auto ws = wb.active_sheet(); + std::clog << "Processing spread sheet" << std::endl; + std::clog << "Creating a single vector which stores the whole spread sheet" << std::endl; + std::vector< std::vector > theWholeSpreadSheet; + for (auto row : ws.rows(false)) + { + std::clog << "Creating a fresh vector for just this row in the spread sheet" << std::endl; + std::vector aSingleRow; + for (auto cell : row) + { + std::clog << "Adding this cell to the row" << std::endl; + aSingleRow.push_back(cell.to_string()); + } + std::clog << "Adding this entire row to the vector which stores the whole spread sheet" << std::endl; + theWholeSpreadSheet.push_back(aSingleRow); + } + std::clog << "Processing complete" << std::endl; + std::clog << "Reading the vector and printing output to the screen" << std::endl; + for (int rowInt = 0; rowInt < theWholeSpreadSheet.size(); rowInt++) + { + for (int colInt = 0; colInt < theWholeSpreadSheet.at(rowInt).size(); colInt++) + { + std::cout << theWholeSpreadSheet.at(rowInt).at(colInt) << std::endl; + } + } + return 0; +} +``` +Save the contents of the above file +``` +/home/timothymccallum/process.cpp +``` +Compile by typing the following command +``` +g++ -std=c++14 -lxlnt process.cpp -o process +``` +Excecute by typing the following command +``` +./process +``` +The output of the program, in my case, is as follows +``` +Processing spread sheet +Creating a single vector which stores the whole spread sheet +Creating a fresh vector for just this row in the spread sheet +Adding this cell to the row +Adding this cell to the row +Adding this cell to the row +Adding this entire row to the vector which stores the whole spread sheet +Creating a fresh vector for just this row in the spread sheet +Adding this cell to the row +Adding this cell to the row +Adding this cell to the row +Adding this entire row to the vector which stores the whole spread sheet +Processing complete +Reading the vector and printing output to the screen +This is cell A1. +This is cell B1 +… and this is cell C1 +We are now on the second row at cell A2 +B2 +C2 +``` +You will have noticed that this process is very fast. If you type the "time" as shown below, you can measure just how fast loading and retrieving your spread sheet is, using xlnt; In this case only a fraction of a second. More on this later. +``` +time ./process +... +real 0m0.044s +``` +### Simple - writing values to a new xlsx spread sheet. + +```c++ +#include +#include +#include +#include + +int main() +{ + //Creating a 2 dimensional vector which we will write values to + std::vector< std::vector > wholeWorksheet; + //Looping through each row (100 rows as per the second argument in the for loop) + for (int outer = 0; outer < 100; outer++) + { + //Creating a fresh vector for a fresh row + std::vector singleRow; + //Looping through each of the columns (100 as per the second argument in the for loop) in this particular row + for(int inner = 0; inner < 100; inner++) + { + //Adding a single value in each cell of the row + std::string val = std::to_string(inner + 1); + singleRow.push_back(val); + } + //Adding the single row to the 2 dimensional vector + wholeWorksheet.push_back(singleRow); + std::clog << "Writing to row " << outer << " in the vector " << std::endl; + } + //Writing to the spread sheet + //Creating the output workbook + std::clog << "Creating workbook" << std::endl; + xlnt::workbook wbOut; + //Setting the destination output file name + std::string dest_filename = "output.xlsx"; + //Creating the output worksheet + xlnt::worksheet wsOut = wbOut.active_sheet(); + //Giving the output worksheet a title/name + wsOut.title("data"); + //We will now be looping through the 2 dimensional vector which we created above + //In this case we have two iterators one for the outer loop (row) and one for the inner loop (column) + std::clog << "Looping through vector and writing to spread sheet" << std::endl; + for (int fOut = 0; fOut < wholeWorksheet.size(); fOut++) + { + std::clog << "Row" << fOut << std::endl; + for (int fIn = 0; fIn < wholeWorksheet.at(fOut).size(); fIn++) + { + //Take notice of the difference between accessing the vector and accessing the work sheet + //As you may already know Excel spread sheets start at row 1 and column 1 (not row 0 and column 0 like you would expect from a C++ vector) + //In short the xlnt cell reference starts at column 1 row 1 (hence the + 1s below) and the vector reference starts at row 0 and column 0 + wsOut.cell(xlnt::cell_reference(fIn + 1, fOut + 1)).value(wholeWorksheet.at(fOut).at(fIn)); + //Further clarification to avoid confusion + //Cell reference arguments are (column number, row number); e.g. cell_reference(fIn + 1, fOut + 1) + //Vector arguments are (row number, column number); e.g. wholeWorksheet.at(fOut).at(fIn) + } + } + std::clog << "Finished writing spread sheet" << std::endl; + wbOut.save(dest_filename); + return 0; +} +``` +This process is also quite quick; a time command showed that xlnt was able to create and write 10, 000 values to the output spread sheet in 0.582 seconds. diff --git a/libs/EXTERNAL/xlnt/docs/introduction/Features.md b/libs/EXTERNAL/xlnt/docs/introduction/Features.md new file mode 100644 index 00000000000..82e2b53bac0 --- /dev/null +++ b/libs/EXTERNAL/xlnt/docs/introduction/Features.md @@ -0,0 +1,54 @@ + +## Features + +| Feature | Read | Edit | Write | +|---------------------------------------------------------------------|------|------|-------| +| Excel-style Workbook | ✓ | ✓ | ✓ | +| LibreOffice-style Workbook | ✓ | ✓ | ✓ | +| Numbers-style Workbook | ✓ | ✓ | ✓ | +| Encrypted Workbook (Excel 2007-2010) | ✓ | ✓ | | +| Encrypted Workbook (Excel 2013-2016) | ✓ | ✓ | | +| Excel Binary Workbook (.xlsb) | | | | +| Excel Macro-Enabled Workbook (.xlsm) | | | | +| Excel Macro-Enabled Template (.xltm) | | | | +| Document Properties | ✓ | ✓ | ✓ | +| Numeric Cell Values | ✓ | ✓ | ✓ | +| Inline String Cell Values | ✓ | ✓ | ✓ | +| Shared String Cell Values | ✓ | ✓ | ✓ | +| Shared String Text Run Formatting (e.g. varied fonts within a cell) | ✓ | ✓ | ✓ | +| Hyperlink Cell Values | | | | +| Formula Cell Values | | | | +| Formula Evaluation | | | | +| Page Margins | ✓ | ✓ | ✓ | +| Page Setup | | | | +| Print Area | | | | +| Comments | ✓ | ✓ | | +| Header and Footer | | | | +| Custom Views | | | | +| Charts | | | | +| Chartsheets | | | | +| Dialogsheets | | | | +| Themes | ✓ | | ✓ | +| Cell Styles | ✓ | ✓ | ✓ | +| Cell Formats | ✓ | ✓ | ✓ | +| Formatting->Alignment (e.g. right align) | ✓ | ✓ | ✓ | +| Formatting->Border (e.g. red cell outline) | ✓ | ✓ | ✓ | +| Formatting->Fill (e.g. green cell background) | ✓ | ✓ | ✓ | +| Formatting->Font (e.g. blue cell text) | ✓ | ✓ | ✓ | +| Formatting->Number Format (e.g. show 2 decimals) | ✓ | ✓ | ✓ | +| Formatting->Protection (e.g. hide formulas) | ✓ | ✓ | ✓ | +| Column Styles | | | | +| Row Styles | | | | +| Sheet Styles | | | | +| Conditional Formatting | | | | +| Tables | | | | +| Table Formatting | | | | +| Pivot Tables | | | | +| XLSX Thumbnail | ✓ | | ✓ | +| Custom OOXML Properties | | | | +| Custom OOXML Parts | | | | +| Drawing | | | | +| Text Box | | | | +| WordArt | | | | +| Embedded Content (e.g. images) | | | | +| Excel VBA | | | | diff --git a/libs/EXTERNAL/xlnt/docs/introduction/Installation.md b/libs/EXTERNAL/xlnt/docs/introduction/Installation.md new file mode 100644 index 00000000000..8dddf3c8ab5 --- /dev/null +++ b/libs/EXTERNAL/xlnt/docs/introduction/Installation.md @@ -0,0 +1,79 @@ +# Getting xlnt + +## Binaries + +## Homebrew + +## Arch + +xlnt can be [found](https://aur.archlinux.org/packages/xlnt/) on the AUR. + +## vcpkg +`vcpkg` installs x86 by default +``` +.\vcpkg install xlnt +``` +if you need x64 use the following command +``` +.\vcpkg install xlnt:x64-windows +``` + +## Compiling xlnt 1.x.x from Source on Ubuntu 16.04 LTS (Xenial Xerus) +Time required: Approximately 5 minutes (depending on your internet speed) +``` +sudo apt-get update +sudo apt-get upgrade +sudo apt-get install cmake +sudo apt-get install zlibc +``` +The following steps update the compiler and set the appropriate environment variables - see note [1] below for the reason why we need to update the standard available compiler +``` +sudo add-apt-repository ppa:ubuntu-toolchain-r/test +sudo apt update +sudo apt-get upgrade +sudo apt-get install gcc-6 g++-6 +export CC=/usr/bin/gcc-6 +export CXX=/usr/bin/g++-6 +``` +The following steps will intall xlnt +``` +git clone https://github.com/tfussell/xlnt.git xlnt --recurse-submodules +cd xlnt +cmake . +make -j 2 +sudo make install +``` +The following step will map the shared library names to the location of the corresponding shared library files +``` +sudo ldconfig +``` +xlnt will now be ready to use on your Ubuntu instance. + +[1] +Xlnt requires a minimum of gcc 6.2.0 +The most recent gcc version available using the standard APT repositories is gcc 5.4.0 (obtained through build-essential 12.1ubuntu2). If these older versions of gcc are used an error "workbook.cpp error 1502:31 'extended_property' is not a class, namespace or enumeration" will occur during the xlnt make command. + +## Compiling from Source + +Build configurations for Visual Studio, GNU Make, Ninja, and Xcode can be created using [cmake](https://cmake.org/) v3.2+. A full list of cmake generators can be found [here](https://cmake.org/cmake/help/v3.0/manual/cmake-generators.7.html). A basic build would look like (starting in the root xlnt directory): + +```bash +mkdir build +cd build +cmake .. +make -j8 +``` + +The resulting shared (e.g. libxlnt.dylib) library would be found in the build/lib directory. Other cmake configuration options for xlnt can be found using "cmake -LH". These options include building a static library instead of shared and whether to build sample executables or not. An example of building a static library with an Xcode project: + +```bash +mkdir build +cd build +cmake -D STATIC=ON -G Xcode .. +cmake --build . +cd bin && ./xlnt.test +``` +*Note for Windows: cmake defaults to building a 32-bit library project. To build a 64-bit library, use the Win64 generator* +```bash +cmake -G "Visual Studio 14 2015 Win64" .. +``` diff --git a/libs/EXTERNAL/xlnt/docs/introduction/Motivation.md b/libs/EXTERNAL/xlnt/docs/introduction/Motivation.md new file mode 100644 index 00000000000..266273bc674 --- /dev/null +++ b/libs/EXTERNAL/xlnt/docs/introduction/Motivation.md @@ -0,0 +1 @@ +## Motivation diff --git a/libs/EXTERNAL/xlnt/docs/introduction/README.md b/libs/EXTERNAL/xlnt/docs/introduction/README.md new file mode 100644 index 00000000000..22f14d81854 --- /dev/null +++ b/libs/EXTERNAL/xlnt/docs/introduction/README.md @@ -0,0 +1,6 @@ +## Introduction + +* [Motivation](Motivation.md) +* [Examples](Examples.md) +* [Features](Features.md) +* [Installation](Installation.md) \ No newline at end of file diff --git a/libs/EXTERNAL/xlnt/docs/template.ejs b/libs/EXTERNAL/xlnt/docs/template.ejs new file mode 100644 index 00000000000..4d03787ea18 --- /dev/null +++ b/libs/EXTERNAL/xlnt/docs/template.ejs @@ -0,0 +1,3 @@ +<% for(var i = 0; i < summary.length; i++) {%> +<%- summary[i].content %> +<% } %> diff --git a/libs/EXTERNAL/xlnt/docs/tools/Doxyfile b/libs/EXTERNAL/xlnt/docs/tools/Doxyfile new file mode 100644 index 00000000000..17f3c180284 --- /dev/null +++ b/libs/EXTERNAL/xlnt/docs/tools/Doxyfile @@ -0,0 +1,315 @@ +# Doxyfile 1.8.10 + +#--------------------------------------------------------------------------- +# Project related configuration options +#--------------------------------------------------------------------------- +DOXYFILE_ENCODING = UTF-8 +PROJECT_NAME = "xlnt" +PROJECT_NUMBER = +PROJECT_BRIEF = +PROJECT_LOGO = +OUTPUT_DIRECTORY = +CREATE_SUBDIRS = NO +ALLOW_UNICODE_NAMES = NO +OUTPUT_LANGUAGE = English +BRIEF_MEMBER_DESC = YES +REPEAT_BRIEF = YES +ABBREVIATE_BRIEF = +ALWAYS_DETAILED_SEC = NO +INLINE_INHERITED_MEMB = NO +FULL_PATH_NAMES = YES +STRIP_FROM_PATH = +STRIP_FROM_INC_PATH = +SHORT_NAMES = NO +JAVADOC_AUTOBRIEF = NO +QT_AUTOBRIEF = NO +MULTILINE_CPP_IS_BRIEF = NO +INHERIT_DOCS = YES +SEPARATE_MEMBER_PAGES = NO +TAB_SIZE = 4 +ALIASES = +TCL_SUBST = +OPTIMIZE_OUTPUT_FOR_C = NO +OPTIMIZE_OUTPUT_JAVA = NO +OPTIMIZE_FOR_FORTRAN = NO +OPTIMIZE_OUTPUT_VHDL = NO +EXTENSION_MAPPING = +MARKDOWN_SUPPORT = YES +AUTOLINK_SUPPORT = YES +BUILTIN_STL_SUPPORT = NO +CPP_CLI_SUPPORT = NO +SIP_SUPPORT = NO +IDL_PROPERTY_SUPPORT = YES +DISTRIBUTE_GROUP_DOC = NO +GROUP_NESTED_COMPOUNDS = NO +SUBGROUPING = YES +INLINE_GROUPED_CLASSES = NO +INLINE_SIMPLE_STRUCTS = NO +TYPEDEF_HIDES_STRUCT = NO +LOOKUP_CACHE_SIZE = 0 +#--------------------------------------------------------------------------- +# Build related configuration options +#--------------------------------------------------------------------------- +EXTRACT_ALL = NO +EXTRACT_PRIVATE = NO +EXTRACT_PACKAGE = NO +EXTRACT_STATIC = NO +EXTRACT_LOCAL_CLASSES = YES +EXTRACT_LOCAL_METHODS = NO +EXTRACT_ANON_NSPACES = NO +HIDE_UNDOC_MEMBERS = NO +HIDE_UNDOC_CLASSES = NO +HIDE_FRIEND_COMPOUNDS = NO +HIDE_IN_BODY_DOCS = NO +INTERNAL_DOCS = NO +CASE_SENSE_NAMES = NO +HIDE_SCOPE_NAMES = NO +HIDE_COMPOUND_REFERENCE= NO +SHOW_INCLUDE_FILES = YES +SHOW_GROUPED_MEMB_INC = NO +FORCE_LOCAL_INCLUDES = NO +INLINE_INFO = YES +SORT_MEMBER_DOCS = YES +SORT_BRIEF_DOCS = NO +SORT_MEMBERS_CTORS_1ST = NO +SORT_GROUP_NAMES = NO +SORT_BY_SCOPE_NAME = NO +STRICT_PROTO_MATCHING = NO +GENERATE_TODOLIST = YES +GENERATE_TESTLIST = YES +GENERATE_BUGLIST = YES +GENERATE_DEPRECATEDLIST= YES +ENABLED_SECTIONS = +MAX_INITIALIZER_LINES = 30 +SHOW_USED_FILES = YES +SHOW_FILES = YES +SHOW_NAMESPACES = YES +FILE_VERSION_FILTER = +LAYOUT_FILE = +CITE_BIB_FILES = +#--------------------------------------------------------------------------- +# Configuration options related to warning and progress messages +#--------------------------------------------------------------------------- +QUIET = YES +WARNINGS = YES +WARN_IF_UNDOCUMENTED = YES +WARN_IF_DOC_ERROR = YES +WARN_NO_PARAMDOC = NO +WARN_FORMAT = "$file:$line: $text" +WARN_LOGFILE = +#--------------------------------------------------------------------------- +# Configuration options related to the input files +#--------------------------------------------------------------------------- +INPUT = ../include/xlnt +INPUT_ENCODING = UTF-8 +FILE_PATTERNS = +RECURSIVE = YES +EXCLUDE = +EXCLUDE_SYMLINKS = NO +EXCLUDE_PATTERNS = +EXCLUDE_SYMBOLS = +EXAMPLE_PATH = +EXAMPLE_PATTERNS = +EXAMPLE_RECURSIVE = NO +IMAGE_PATH = +INPUT_FILTER = +FILTER_PATTERNS = +FILTER_SOURCE_FILES = NO +FILTER_SOURCE_PATTERNS = +USE_MDFILE_AS_MAINPAGE = +#--------------------------------------------------------------------------- +# Configuration options related to source browsing +#--------------------------------------------------------------------------- +SOURCE_BROWSER = NO +INLINE_SOURCES = NO +STRIP_CODE_COMMENTS = YES +REFERENCED_BY_RELATION = NO +REFERENCES_RELATION = NO +REFERENCES_LINK_SOURCE = YES +SOURCE_TOOLTIPS = YES +USE_HTAGS = NO +VERBATIM_HEADERS = YES +#--------------------------------------------------------------------------- +# Configuration options related to the alphabetical class index +#--------------------------------------------------------------------------- +ALPHABETICAL_INDEX = YES +COLS_IN_ALPHA_INDEX = 5 +IGNORE_PREFIX = +#--------------------------------------------------------------------------- +# Configuration options related to the HTML output +#--------------------------------------------------------------------------- +GENERATE_HTML = NO +HTML_OUTPUT = html +HTML_FILE_EXTENSION = .html +HTML_HEADER = +HTML_FOOTER = +HTML_STYLESHEET = +HTML_EXTRA_STYLESHEET = +HTML_EXTRA_FILES = +HTML_COLORSTYLE_HUE = 220 +HTML_COLORSTYLE_SAT = 100 +HTML_COLORSTYLE_GAMMA = 80 +HTML_TIMESTAMP = NO +HTML_DYNAMIC_SECTIONS = NO +HTML_INDEX_NUM_ENTRIES = 100 +GENERATE_DOCSET = NO +DOCSET_FEEDNAME = "Doxygen generated docs" +DOCSET_BUNDLE_ID = org.doxygen.Project +DOCSET_PUBLISHER_ID = org.doxygen.Publisher +DOCSET_PUBLISHER_NAME = Publisher +GENERATE_HTMLHELP = NO +CHM_FILE = +HHC_LOCATION = +GENERATE_CHI = NO +CHM_INDEX_ENCODING = +BINARY_TOC = NO +TOC_EXPAND = NO +GENERATE_QHP = NO +QCH_FILE = +QHP_NAMESPACE = org.doxygen.Project +QHP_VIRTUAL_FOLDER = doc +QHP_CUST_FILTER_NAME = +QHP_CUST_FILTER_ATTRS = +QHP_SECT_FILTER_ATTRS = +QHG_LOCATION = +GENERATE_ECLIPSEHELP = NO +ECLIPSE_DOC_ID = org.doxygen.Project +DISABLE_INDEX = NO +GENERATE_TREEVIEW = NO +ENUM_VALUES_PER_LINE = 4 +TREEVIEW_WIDTH = 250 +EXT_LINKS_IN_WINDOW = NO +FORMULA_FONTSIZE = 10 +FORMULA_TRANSPARENT = YES +USE_MATHJAX = NO +MATHJAX_FORMAT = HTML-CSS +MATHJAX_RELPATH = http://cdn.mathjax.org/mathjax/latest +MATHJAX_EXTENSIONS = +MATHJAX_CODEFILE = +SEARCHENGINE = YES +SERVER_BASED_SEARCH = NO +EXTERNAL_SEARCH = NO +SEARCHENGINE_URL = +SEARCHDATA_FILE = searchdata.xml +EXTERNAL_SEARCH_ID = +EXTRA_SEARCH_MAPPINGS = +#--------------------------------------------------------------------------- +# Configuration options related to the LaTeX output +#--------------------------------------------------------------------------- +GENERATE_LATEX = NO +LATEX_OUTPUT = latex +LATEX_CMD_NAME = latex +MAKEINDEX_CMD_NAME = makeindex +COMPACT_LATEX = NO +PAPER_TYPE = a4 +EXTRA_PACKAGES = +LATEX_HEADER = +LATEX_FOOTER = +LATEX_EXTRA_STYLESHEET = +LATEX_EXTRA_FILES = +PDF_HYPERLINKS = YES +USE_PDFLATEX = YES +LATEX_BATCHMODE = NO +LATEX_HIDE_INDICES = NO +LATEX_SOURCE_CODE = NO +LATEX_BIB_STYLE = plain +#--------------------------------------------------------------------------- +# Configuration options related to the RTF output +#--------------------------------------------------------------------------- +GENERATE_RTF = NO +RTF_OUTPUT = rtf +COMPACT_RTF = NO +RTF_HYPERLINKS = NO +RTF_STYLESHEET_FILE = +RTF_EXTENSIONS_FILE = +RTF_SOURCE_CODE = NO +#--------------------------------------------------------------------------- +# Configuration options related to the man page output +#--------------------------------------------------------------------------- +GENERATE_MAN = NO +MAN_OUTPUT = man +MAN_EXTENSION = .3 +MAN_SUBDIR = +MAN_LINKS = NO +#--------------------------------------------------------------------------- +# Configuration options related to the XML output +#--------------------------------------------------------------------------- +GENERATE_XML = YES +XML_OUTPUT = doxyxml +XML_PROGRAMLISTING = YES +#--------------------------------------------------------------------------- +# Configuration options related to the DOCBOOK output +#--------------------------------------------------------------------------- +GENERATE_DOCBOOK = NO +DOCBOOK_OUTPUT = docbook +DOCBOOK_PROGRAMLISTING = NO +#--------------------------------------------------------------------------- +# Configuration options for the AutoGen Definitions output +#--------------------------------------------------------------------------- +GENERATE_AUTOGEN_DEF = NO +#--------------------------------------------------------------------------- +# Configuration options related to the Perl module output +#--------------------------------------------------------------------------- +GENERATE_PERLMOD = NO +PERLMOD_LATEX = NO +PERLMOD_PRETTY = YES +PERLMOD_MAKEVAR_PREFIX = +#--------------------------------------------------------------------------- +# Configuration options related to the preprocessor +#--------------------------------------------------------------------------- +ENABLE_PREPROCESSING = YES +MACRO_EXPANSION = YES +EXPAND_ONLY_PREDEF = YES +SEARCH_INCLUDES = YES +INCLUDE_PATH = ../include +INCLUDE_FILE_PATTERNS = +PREDEFINED = XLNT_API= +EXPAND_AS_DEFINED = +SKIP_FUNCTION_MACROS = YES +#--------------------------------------------------------------------------- +# Configuration options related to external references +#--------------------------------------------------------------------------- +TAGFILES = +GENERATE_TAGFILE = +ALLEXTERNALS = NO +EXTERNAL_GROUPS = YES +EXTERNAL_PAGES = YES +PERL_PATH = /usr/bin/perl +#--------------------------------------------------------------------------- +# Configuration options related to the dot tool +#--------------------------------------------------------------------------- +CLASS_DIAGRAMS = YES +MSCGEN_PATH = +DIA_PATH = +HIDE_UNDOC_RELATIONS = YES +HAVE_DOT = NO +DOT_NUM_THREADS = 0 +DOT_FONTNAME = Helvetica +DOT_FONTSIZE = 10 +DOT_FONTPATH = +CLASS_GRAPH = YES +COLLABORATION_GRAPH = YES +GROUP_GRAPHS = YES +UML_LOOK = NO +UML_LIMIT_NUM_FIELDS = 10 +TEMPLATE_RELATIONS = NO +INCLUDE_GRAPH = YES +INCLUDED_BY_GRAPH = YES +CALL_GRAPH = NO +CALLER_GRAPH = NO +GRAPHICAL_HIERARCHY = YES +DIRECTORY_GRAPH = YES +DOT_IMAGE_FORMAT = png +INTERACTIVE_SVG = NO +DOT_PATH = +DOTFILE_DIRS = +MSCFILE_DIRS = +DIAFILE_DIRS = +PLANTUML_JAR_PATH = +PLANTUML_INCLUDE_PATH = +DOT_GRAPH_MAX_NODES = 50 +MAX_DOT_GRAPH_DEPTH = 0 +DOT_TRANSPARENT = NO +DOT_MULTI_TARGETS = NO +GENERATE_LEGEND = YES +DOT_CLEANUP = YES diff --git a/libs/EXTERNAL/xlnt/docs/tools/generate-md.js b/libs/EXTERNAL/xlnt/docs/tools/generate-md.js new file mode 100644 index 00000000000..f0528a29e5d --- /dev/null +++ b/libs/EXTERNAL/xlnt/docs/tools/generate-md.js @@ -0,0 +1,100 @@ +var xpath = require('xpath'); +var dom = require('xmldom').DOMParser; +var fs = require('fs'); +var _ = require('underscore'); +var async = require('async'); + +function generate(directory, primary_callback) { + var modules = []; + return fs.readFile(directory + 'index.xml', 'utf8', (err, xml) => { + if (err) throw err; + var doc = new dom().parseFromString(xml); + var nodes = xpath.select('/doxygenindex/compound[@kind="dir"]', doc); + for (var i = 0; i < nodes.length; i++) { + var refid = nodes[i].getAttribute('refid'); + var name = nodes[i].firstChild.firstChild.toString(); + modules.push({name: name, refid: refid}); + } + const root_module = _.find(modules, (module) => { + return _.last(module.name.split('/')) == 'xlnt'; + }); + const root_name = root_module.name; + modules = _.filter(modules, (module) => { + return module.name.indexOf(root_name) >= 0 && module.name !== root_name; + }); + return async.mapSeries(modules, (module, module_callback) => { + return fs.readFile(directory + module.refid + '.xml', 'utf8', (err, xml) => { + if (err) throw err; + var doc = new dom().parseFromString(xml); + var nodes = xpath.select('/doxygen/compounddef/innerfile', doc); + module.source_files = []; + for (var i = 0; i < nodes.length; i++) { + var refid = nodes[i].getAttribute('refid'); + var name = nodes[i].firstChild.toString(); + module.source_files.push({name: name, refid: refid}); + } + return async.map(module.source_files, (source_file, source_file_callback) => { + return fs.readFile(directory + source_file.refid + '.xml', 'utf8', (err, xml) => { + if (err) throw err; + var doc = new dom().parseFromString(xml); + var nodes = xpath.select('/doxygen/compounddef/innerclass', doc); + module.class_files = []; + for (var i = 0; i < nodes.length; i++) { + var refid = nodes[i].getAttribute('refid'); + var name = nodes[i].firstChild.toString(); + module.class_files.push({name: name, refid: refid}); + } + return async.map(module.class_files, (class_file, class_file_callback) => { + return fs.readFile(directory + class_file.refid + '.xml', 'utf8', (err, xml) => { + if (err) throw err; + var doc = new dom().parseFromString(xml); + var nodes = xpath.select('/doxygen/compounddef/sectiondef/memberdef[@prot="public"]', doc); + var members = []; + for (var i = 0; i < nodes.length; i++) { + var member_data = {id: nodes[i].getAttribute('id')}; + var child = nodes[i].firstChild; + while (child != nodes[i].lastChild) { + if (child.textContent.trim()) { + member_data[child.nodeName] = child.textContent.trim(); + } + child = child.nextSibling; + } + members.push(member_data); + } + class_file.members = members; + return class_file_callback(null, class_file); + }); + }, (err, data) => { + return source_file_callback(null, _.flatten(data, true)); + }); + }); + }, (err, data) => { + module.classes = _.flatten(data, true); + return module_callback(null, module); + }); + }); + }, (err, data) => { + return primary_callback(null, _.flatten(data, true)); + }); + }); +} + +generate('doxyxml/', function(err, data) { + console.log('# API Reference'); + for (var i = 0; i < data.length; i++) { + var module = data[i]; + var module_name = _.last(module.name.split('/')); + console.log('##', module_name.charAt(0).toUpperCase() + module_name.slice(1), 'Module'); + for (var j = 0; j < module.classes.length; j++) { + var class_ = module.classes[j]; + console.log('###', _.last(class_.name.split('::'))); + for (var k = 0; k < class_.members.length; k++) { + var member = class_.members[k]; + console.log('####', '```' + member.definition + member.argsstring + '```'); + if (member.briefdescription) { + console.log(member.briefdescription); + } + } + } + } +}); diff --git a/libs/EXTERNAL/xlnt/docs/xlnt.3 b/libs/EXTERNAL/xlnt/docs/xlnt.3 new file mode 100644 index 00000000000..2fe512e3f3b --- /dev/null +++ b/libs/EXTERNAL/xlnt/docs/xlnt.3 @@ -0,0 +1,1859 @@ +.\"t +.\" Automatically generated by Pandoc 1.19.2.2 +.\" +.TH "" "" "" "" "" +.hy +.SH [IMAGE: xlnt +logo (https://user-images.githubusercontent.com/1735211/29433390-f37fa28e-836c-11e7-8a60-f8df4c30b424.png)] +.PD 0 +.P +.PD +.PP +[IMAGE: Travis Build +Status (https://travis-ci.org/tfussell/xlnt.svg?branch=master)] (https://travis-ci.org/tfussell/xlnt) +[IMAGE: AppVeyor Build +status (https://ci.appveyor.com/api/projects/status/2hs79a1xoxy16sol?svg=true)] (https://ci.appveyor.com/project/tfussell/xlnt) +[IMAGE: Coverage +Status (https://coveralls.io/repos/github/tfussell/xlnt/badge.svg?branch=master)] (https://coveralls.io/github/tfussell/xlnt?branch=master) +[IMAGE: ReadTheDocs Documentation +Status (https://readthedocs.org/projects/xlnt/badge/?version=latest)] (http://xlnt.readthedocs.org/en/latest/?badge=latest) +[IMAGE: License (http://img.shields.io/badge/license-MIT-blue.svg?style=flat)] (http://opensource.org/licenses/MIT) +.SS Introduction +.PP +xlnt is a modern C++ library for manipulating spreadsheets in memory and +reading/writing them from/to XLSX files as described in ECMA 376 4th +edition (http://www.ecma-international.org/publications/standards/Ecma-376.htm). +The first public release of xlnt version 1.0 was on May 10th, 2017. +Current work is focused on increasing compatibility, improving +performance, and brainstorming future development goals. +For a high\-level summary of what you can do with this library, see the +feature +list (https://tfussell.gitbooks.io/xlnt/content/docs/introduction/Features.html). +Contributions are welcome in the form of pull requests or discussions on +the repository\[aq]s Issues +page (https://github.com/tfussell/xlnt/issues). +.SS Example +.PP +Including xlnt in your project, creating a new spreadsheet, and saving +it as "example.xlsx" +.IP +.nf +\f[C] +#include\ + +int\ main() +{ +\ \ \ \ xlnt::workbook\ wb; +\ \ \ \ xlnt::worksheet\ ws\ =\ wb.active_sheet(); +\ \ \ \ ws.cell("A1").value(5); +\ \ \ \ ws.cell("B2").value("string\ data"); +\ \ \ \ ws.cell("C3").formula("=RAND()"); +\ \ \ \ ws.merge_cells("C3:C4"); +\ \ \ \ ws.freeze_panes("B2"); +\ \ \ \ wb.save("example.xlsx"); +\ \ \ \ return\ 0; +} +//\ compile\ with\ \-std=c++14\ \-Ixlnt/include\ \-lxlnt +\f[] +.fi +.SS Documentation +.PP +Documentation for the current release of xlnt is available +here (https://tfussell.gitbooks.io/xlnt/content/). +.SS License +.PP +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/LICENSE.md) +for the full text of the license and the licenses of xlnt\[aq]s +third\-party dependencies. +LICENSE.md (https://github.com/tfussell/xlnt/blob/master/LICENSE.md) +should be distributed alongside any assemblies that use xlnt in source +or compiled form. +.SS Introduction +.IP \[bu] 2 +Motivation (Motivation.md) +.IP \[bu] 2 +Examples (Examples.md) +.IP \[bu] 2 +Features (Features.md) +.IP \[bu] 2 +Installation (Installation.md) +.SS Motivation +.SS Examples +.SS Simple \- reading from an existing xlsx spread sheet. +.PP +The following C plus plus code will read the values from an xlsx file +and print the string values to the screen. +This is a very simple example to get you started. +.IP +.nf +\f[C] +#include\ +#include\ + +int\ main() +{ +\ \ \ \ xlnt::workbook\ wb; +\ \ \ \ wb.load("/home/timothymccallum/test.xlsx"); +\ \ \ \ auto\ ws\ =\ wb.active_sheet(); +\ \ \ \ std::clog\ <<\ "Processing\ spread\ sheet"\ <<\ std::endl; +\ \ \ \ for\ (auto\ row\ :\ ws.rows(false))\ +\ \ \ \ {\ +\ \ \ \ \ \ \ \ for\ (auto\ cell\ :\ row)\ +\ \ \ \ {\ +\ \ \ \ \ \ \ \ std::clog\ <<\ cell.to_string()\ <<\ std::endl; +\ \ \ \ } +\ \ \ \ } +\ \ \ \ std::clog\ <<\ "Processing\ complete"\ <<\ std::endl; +\ \ \ \ return\ 0; +} +\f[] +.fi +.PP +Save the contents of the above file +.IP +.nf +\f[C] +/home/timothymccallum/process.cpp +\f[] +.fi +.PP +Compile by typing the following command +.IP +.nf +\f[C] +g++\ \-std=c++14\ \-lxlnt\ process.cpp\ \-o\ process +\f[] +.fi +.PP +Excecute by typing the following command +.IP +.nf +\f[C] +\&./process +\f[] +.fi +.PP +The output of the program, in my case, is as follows +.IP +.nf +\f[C] +Processing\ spread\ sheet +This\ is\ cell\ A1. +This\ is\ cell\ B1 +\&...\ and\ this\ is\ cell\ C1 +We\ are\ now\ on\ the\ second\ row\ at\ cell\ A2 +B2 +C2 +Processing\ complete +\f[] +.fi +.PP +As you can see the process.cpp file simply walks through the spread +sheet values row by row and column by column (A1, B1, C1, A2, B2, C2 and +so on). +.SS Simple \- storing a spread sheet in a 2 dimensional C++ Vector for +further processing +.PP +Loading a spread sheet into a Vector provides oppourtunities for you to +perform high performance processing. +There will be more examples on performing fast look\-ups, merging data, +performing deduplication and more. +For now, let\[aq]s just learn how to get the spread sheet loaded into +memory. +.IP +.nf +\f[C] +#include\ +#include\ +#include\ + +int\ main() +{ +\ \ \ \ xlnt::workbook\ wb; +\ \ \ \ wb.load("/home/timothymccallum/test.xlsx"); +\ \ \ \ auto\ ws\ =\ wb.active_sheet(); +\ \ \ \ std::clog\ <<\ "Processing\ spread\ sheet"\ <<\ std::endl; +\ \ \ \ std::clog\ <<\ "Creating\ a\ single\ vector\ which\ stores\ the\ whole\ spread\ sheet"\ <<\ std::endl; +\ \ \ \ std::vector<\ std::vector\ >\ theWholeSpreadSheet; +\ \ \ \ for\ (auto\ row\ :\ ws.rows(false))\ +\ \ \ \ {\ +\ \ \ \ \ \ \ \ std::clog\ <<\ "Creating\ a\ fresh\ vector\ for\ just\ this\ row\ in\ the\ spread\ sheet"\ <<\ std::endl; +\ \ \ \ std::vector\ aSingleRow; +\ \ \ \ for\ (auto\ cell\ :\ row)\ +\ \ \ \ {\ +\ \ \ \ \ \ \ \ std::clog\ <<\ "Adding\ this\ cell\ to\ the\ row"\ <<\ std::endl; +\ \ \ \ \ \ \ \ aSingleRow.push_back(cell.to_string()); +\ \ \ \ } +\ \ \ \ std::clog\ <<\ "Adding\ this\ entire\ row\ to\ the\ vector\ which\ stores\ the\ whole\ spread\ sheet"\ <<\ std::endl; +\ \ \ \ theWholeSpreadSheet.push_back(aSingleRow); +\ \ \ \ } +\ \ \ \ std::clog\ <<\ "Processing\ complete"\ <<\ std::endl; +\ \ \ \ std::clog\ <<\ "Reading\ the\ vector\ and\ printing\ output\ to\ the\ screen"\ <<\ std::endl; +\ \ \ \ for\ (int\ rowInt\ =\ 0;\ rowInt\ <\ theWholeSpreadSheet.size();\ rowInt++) +\ \ \ \ { +\ \ \ \ \ \ \ \ for\ (int\ colInt\ =\ 0;\ colInt\ <\ theWholeSpreadSheet.at(rowInt).size();\ colInt++) +\ \ \ \ { +\ \ \ \ \ \ \ \ std::cout\ <<\ theWholeSpreadSheet.at(rowInt).at(colInt)\ <<\ std::endl; +\ \ \ \ \ \ \ \ } +\ \ \ \ } +\ \ \ \ return\ 0; +} +\f[] +.fi +.PP +Save the contents of the above file +.IP +.nf +\f[C] +/home/timothymccallum/process.cpp +\f[] +.fi +.PP +Compile by typing the following command +.IP +.nf +\f[C] +g++\ \-std=c++14\ \-lxlnt\ process.cpp\ \-o\ process +\f[] +.fi +.PP +Excecute by typing the following command +.IP +.nf +\f[C] +\&./process +\f[] +.fi +.PP +The output of the program, in my case, is as follows +.IP +.nf +\f[C] +Processing\ spread\ sheet +Creating\ a\ single\ vector\ which\ stores\ the\ whole\ spread\ sheet +Creating\ a\ fresh\ vector\ for\ just\ this\ row\ in\ the\ spread\ sheet +Adding\ this\ cell\ to\ the\ row +Adding\ this\ cell\ to\ the\ row +Adding\ this\ cell\ to\ the\ row +Adding\ this\ entire\ row\ to\ the\ vector\ which\ stores\ the\ whole\ spread\ sheet +Creating\ a\ fresh\ vector\ for\ just\ this\ row\ in\ the\ spread\ sheet +Adding\ this\ cell\ to\ the\ row +Adding\ this\ cell\ to\ the\ row +Adding\ this\ cell\ to\ the\ row +Adding\ this\ entire\ row\ to\ the\ vector\ which\ stores\ the\ whole\ spread\ sheet +Processing\ complete +Reading\ the\ vector\ and\ printing\ output\ to\ the\ screen +This\ is\ cell\ A1. +This\ is\ cell\ B1 +\&...\ and\ this\ is\ cell\ C1 +We\ are\ now\ on\ the\ second\ row\ at\ cell\ A2 +B2 +C2 +\f[] +.fi +.PP +You will have noticed that this process is very fast. +If you type the "time" as shown below, you can measure just how fast +loading and retrieving your spread sheet is, using xlnt; In this case +only a fraction of a second. +More on this later. +.IP +.nf +\f[C] +time\ ./process\ +\&... +real\ \ \ \ 0m0.044s +\f[] +.fi +.SS Simple \- writing values to a new xlsx spread sheet. +.IP +.nf +\f[C] +#include\ +#include\ +#include\ +#include\ + +int\ main() +{ +\ \ \ \ //Creating\ a\ 2\ dimensional\ vector\ which\ we\ will\ write\ values\ to +\ \ \ \ std::vector<\ std::vector\ >\ wholeWorksheet; +\ \ \ \ //Looping\ through\ each\ row\ (100\ rows\ as\ per\ the\ second\ argument\ in\ the\ for\ loop) +\ \ \ \ for\ (int\ outer\ =\ 0;\ outer\ <\ 100;\ outer++) +\ \ \ \ { +\ \ \ \ \ \ \ \ //Creating\ a\ fresh\ vector\ for\ a\ fresh\ row +\ \ \ \ std::vector\ singleRow; +\ \ \ \ //Looping\ through\ each\ of\ the\ columns\ (100\ as\ per\ the\ second\ argument\ in\ the\ for\ loop)\ in\ this\ particular\ row +\ \ \ \ for(int\ inner\ =\ 0;\ inner\ <\ 100;\ inner++) +\ \ \ \ { +\ \ \ \ \ \ \ \ //Adding\ a\ single\ value\ in\ each\ cell\ of\ the\ row\ +\ \ \ \ \ \ \ \ std::string\ val\ =\ std::to_string(inner\ +\ 1); +\ \ \ \ \ \ \ \ singleRow.push_back(val);\ \ \ \ \ \ \ \ \ \ \ \ +\ \ \ \ } +\ \ \ \ //Adding\ the\ single\ row\ to\ the\ 2\ dimensional\ vector +\ \ \ \ wholeWorksheet.push_back(singleRow); +\ \ \ \ std::clog\ <<\ "Writing\ to\ row\ "\ <<\ outer\ <<\ "\ in\ the\ vector\ "\ <<\ std::endl; +\ \ \ \ } +\ \ \ \ //Writing\ to\ the\ spread\ sheet +\ \ \ \ //Creating\ the\ output\ workbook\ +\ \ \ \ std::clog\ <<\ "Creating\ workbook"\ <<\ std::endl; +\ \ \ \ xlnt::workbook\ wbOut; +\ \ \ \ //Setting\ the\ destination\ output\ file\ name +\ \ \ \ std::string\ dest_filename\ =\ "output.xlsx"; +\ \ \ \ //Creating\ the\ output\ worksheet +\ \ \ \ xlnt::worksheet\ wsOut\ =\ wbOut.active_sheet(); +\ \ \ \ //Giving\ the\ output\ worksheet\ a\ title/name +\ \ \ \ wsOut.title("data"); +\ \ \ \ //We\ will\ now\ be\ looping\ through\ the\ 2\ dimensional\ vector\ which\ we\ created\ above +\ \ \ \ //In\ this\ case\ we\ have\ two\ iterators\ one\ for\ the\ outer\ loop\ (row)\ and\ one\ for\ the\ inner\ loop\ (column) +\ \ \ \ std::clog\ <<\ "Looping\ through\ vector\ and\ writing\ to\ spread\ sheet"\ <<\ std::endl; +\ \ \ \ for\ (int\ fOut\ =\ 0;\ fOut\ <\ wholeWorksheet.size();\ fOut++) +\ \ \ \ { +\ \ \ \ \ \ \ \ std::clog\ <<\ "Row"\ <<\ fOut\ <<\ std::endl; +\ \ \ \ \ \ \ \ for\ (int\ fIn\ =\ 0;\ fIn\ <\ wholeWorksheet.at(fOut).size();\ fIn++) +\ \ \ \ \ \ \ \ { +\ \ \ \ \ \ \ \ \ \ \ \ //Take\ notice\ of\ the\ difference\ between\ accessing\ the\ vector\ and\ accessing\ the\ work\ sheet +\ \ \ \ \ \ \ \ //As\ you\ may\ already\ know\ Excel\ spread\ sheets\ start\ at\ row\ 1\ and\ column\ 1\ (not\ row\ 0\ and\ column\ 0\ like\ you\ would\ expect\ from\ a\ C++\ vector)\ +\ \ \ \ \ \ \ \ //In\ short\ the\ xlnt\ cell\ reference\ starts\ at\ column\ 1\ row\ 1\ (hence\ the\ +\ 1s\ below)\ and\ the\ vector\ reference\ starts\ at\ row\ 0\ and\ column\ 0 +\ \ \ \ \ \ \ \ wsOut.cell(xlnt::cell_reference(fIn\ +\ 1,\ fOut\ +\ 1)).value(wholeWorksheet.at(fOut).at(fIn)); +\ \ \ \ \ \ \ \ //Further\ clarification\ to\ avoid\ confusion +\ \ \ \ \ \ \ \ //Cell\ reference\ arguments\ are\ (column\ number,\ row\ number);\ e.g.\ cell_reference(fIn\ +\ 1,\ fOut\ +\ 1) +\ \ \ \ \ \ \ \ //Vector\ arguments\ are\ (row\ number,\ column\ number);\ e.g.\ wholeWorksheet.at(fOut).at(fIn) +\ \ \ \ } +\ \ \ \ } +\ \ \ \ std::clog\ <<\ "Finished\ writing\ spread\ sheet"\ <<\ std::endl; +\ \ \ \ wbOut.save(dest_filename);\ +\ \ \ \ return\ 0; +} +\f[] +.fi +.PP +This process is also quite quick; a time command showed that xlnt was +able to create and write 10, 000 values to the output spread sheet in +0.582 seconds. +.SS Features +.PP +.TS +tab(@); +l l l l. +T{ +Feature +T}@T{ +Read +T}@T{ +Edit +T}@T{ +Write +T} +_ +T{ +Excel\-style Workbook +T}@T{ +✓ +T}@T{ +✓ +T}@T{ +✓ +T} +T{ +LibreOffice\-style Workbook +T}@T{ +✓ +T}@T{ +✓ +T}@T{ +✓ +T} +T{ +Numbers\-style Workbook +T}@T{ +✓ +T}@T{ +✓ +T}@T{ +✓ +T} +T{ +Encrypted Workbook (Excel 2007\-2010) +T}@T{ +✓ +T}@T{ +✓ +T}@T{ +T} +T{ +Encrypted Workbook (Excel 2013\-2016) +T}@T{ +✓ +T}@T{ +✓ +T}@T{ +T} +T{ +Excel Binary Workbook (.xlsb) +T}@T{ +T}@T{ +T}@T{ +T} +T{ +Excel Macro\-Enabled Workbook (.xlsm) +T}@T{ +T}@T{ +T}@T{ +T} +T{ +Excel Macro\-Enabled Template (.xltm) +T}@T{ +T}@T{ +T}@T{ +T} +T{ +Document Properties +T}@T{ +✓ +T}@T{ +✓ +T}@T{ +✓ +T} +T{ +Numeric Cell Values +T}@T{ +✓ +T}@T{ +✓ +T}@T{ +✓ +T} +T{ +Inline String Cell Values +T}@T{ +✓ +T}@T{ +✓ +T}@T{ +✓ +T} +T{ +Shared String Cell Values +T}@T{ +✓ +T}@T{ +✓ +T}@T{ +✓ +T} +T{ +Shared String Text Run Formatting (e.g. +varied fonts within a cell) +T}@T{ +✓ +T}@T{ +✓ +T}@T{ +✓ +T} +T{ +Hyperlink Cell Values +T}@T{ +T}@T{ +T}@T{ +T} +T{ +Formula Cell Values +T}@T{ +T}@T{ +T}@T{ +T} +T{ +Formula Evaluation +T}@T{ +T}@T{ +T}@T{ +T} +T{ +Page Margins +T}@T{ +✓ +T}@T{ +✓ +T}@T{ +✓ +T} +T{ +Page Setup +T}@T{ +T}@T{ +T}@T{ +T} +T{ +Print Area +T}@T{ +T}@T{ +T}@T{ +T} +T{ +Comments +T}@T{ +✓ +T}@T{ +✓ +T}@T{ +T} +T{ +Header and Footer +T}@T{ +T}@T{ +T}@T{ +T} +T{ +Custom Views +T}@T{ +T}@T{ +T}@T{ +T} +T{ +Charts +T}@T{ +T}@T{ +T}@T{ +T} +T{ +Chartsheets +T}@T{ +T}@T{ +T}@T{ +T} +T{ +Dialogsheets +T}@T{ +T}@T{ +T}@T{ +T} +T{ +Themes +T}@T{ +✓ +T}@T{ +T}@T{ +✓ +T} +T{ +Cell Styles +T}@T{ +✓ +T}@T{ +✓ +T}@T{ +✓ +T} +T{ +Cell Formats +T}@T{ +✓ +T}@T{ +✓ +T}@T{ +✓ +T} +T{ +Formatting\->Alignment (e.g. +right align) +T}@T{ +✓ +T}@T{ +✓ +T}@T{ +✓ +T} +T{ +Formatting\->Border (e.g. +red cell outline) +T}@T{ +✓ +T}@T{ +✓ +T}@T{ +✓ +T} +T{ +Formatting\->Fill (e.g. +green cell background) +T}@T{ +✓ +T}@T{ +✓ +T}@T{ +✓ +T} +T{ +Formatting\->Font (e.g. +blue cell text) +T}@T{ +✓ +T}@T{ +✓ +T}@T{ +✓ +T} +T{ +Formatting\->Number Format (e.g. +show 2 decimals) +T}@T{ +✓ +T}@T{ +✓ +T}@T{ +✓ +T} +T{ +Formatting\->Protection (e.g. +hide formulas) +T}@T{ +✓ +T}@T{ +✓ +T}@T{ +✓ +T} +T{ +Column Styles +T}@T{ +T}@T{ +T}@T{ +T} +T{ +Row Styles +T}@T{ +T}@T{ +T}@T{ +T} +T{ +Sheet Styles +T}@T{ +T}@T{ +T}@T{ +T} +T{ +Conditional Formatting +T}@T{ +T}@T{ +T}@T{ +T} +T{ +Tables +T}@T{ +T}@T{ +T}@T{ +T} +T{ +Table Formatting +T}@T{ +T}@T{ +T}@T{ +T} +T{ +Pivot Tables +T}@T{ +T}@T{ +T}@T{ +T} +T{ +XLSX Thumbnail +T}@T{ +✓ +T}@T{ +T}@T{ +✓ +T} +T{ +Custom OOXML Properties +T}@T{ +T}@T{ +T}@T{ +T} +T{ +Custom OOXML Parts +T}@T{ +T}@T{ +T}@T{ +T} +T{ +Drawing +T}@T{ +T}@T{ +T}@T{ +T} +T{ +Text Box +T}@T{ +T}@T{ +T}@T{ +T} +T{ +WordArt +T}@T{ +T}@T{ +T}@T{ +T} +T{ +Embedded Content (e.g. +images) +T}@T{ +T}@T{ +T}@T{ +T} +T{ +Excel VBA +T}@T{ +T}@T{ +T}@T{ +T} +.TE +.SH Getting xlnt +.SS Binaries +.SS Homebrew +.SS Arch +.SS vcpkg +.SS Compiling xlnt 1.x.x from Source on Ubuntu 16.04 LTS (Xenial Xerus) +.PP +Time required: Approximately 5 minutes (depending on your internet +speed) +.IP +.nf +\f[C] +sudo\ apt\-get\ update +sudo\ apt\-get\ upgrade +sudo\ apt\-get\ install\ cmake +sudo\ apt\-get\ install\ zlibc +\f[] +.fi +.PP +The following steps update the compiler and set the appropriate +environment variables \- see note [1] below for the reason why we need +to update the standard available compiler +.IP +.nf +\f[C] +sudo\ add\-apt\-repository\ ppa:ubuntu\-toolchain\-r/test +sudo\ apt\ update +sudo\ apt\-get\ upgrade +sudo\ apt\-get\ install\ gcc\-6\ g++\-6 +export\ CC=/usr/bin/gcc\-6\ \ +export\ CXX=/usr/bin/g++\-6 +\f[] +.fi +.PP +The following steps will intall xlnt Download the zip file from the xlnt +repository +.IP +.nf +\f[C] +cd\ ~ +unzip\ Downloads/xlnt\-master.zip +cd\ xlnt\-master +cmake\ . +make\ \-j\ 2 +sudo\ make\ install +\f[] +.fi +.PP +The following step will map the shared library names to the location of +the corresponding shared library files +.IP +.nf +\f[C] +sudo\ ldconfig +\f[] +.fi +.PP +xlnt will now be ready to use on your Ubuntu instance. +.PP +[1] Xlnt requires a minimum of gcc 6.2.0 The most recent gcc version +available using the standard APT repositories is gcc 5.4.0 (obtained +through build\-essential 12.1ubuntu2). +If these older versions of gcc are used an error "workbook.cpp error +1502:31 \[aq]extended_property\[aq] is not a class, namespace or +enumeration" will occur during the xlnt make command. +.SS Compiling from Source +.PP +Build configurations for Visual Studio, GNU Make, Ninja, and Xcode can +be created using cmake (https://cmake.org/) v3.2+. +A full list of cmake generators can be found +here (https://cmake.org/cmake/help/v3.0/manual/cmake-generators.7.html). +A basic build would look like (starting in the root xlnt directory): +.IP +.nf +\f[C] +mkdir\ build +cd\ build +cmake\ .. +make\ \-j8 +\f[] +.fi +.PP +The resulting shared (e.g. +libxlnt.dylib) library would be found in the build/lib directory. +Other cmake configuration options for xlnt can be found using "cmake +\-LH". +These options include building a static library instead of shared and +whether to build sample executables or not. +An example of building a static library with an Xcode project: +.IP +.nf +\f[C] +mkdir\ build +cd\ build +cmake\ \-D\ STATIC=ON\ \-G\ Xcode\ .. +cmake\ \-\-build\ . +cd\ bin\ &&\ ./xlnt.test +\f[] +.fi +.PP +\f[I]Note for Windows: cmake defaults to building a 32\-bit library +project. To build a 64\-bit library, use the Win64 generator\f[] +.IP +.nf +\f[C] +cmake\ \-G\ "Visual\ Studio\ 14\ 2015\ Win64"\ .. +\f[] +.fi +.SS Basics +.IP \[bu] 2 +Workbook (/docs/basics/Workbook.md) +.IP \[bu] 2 +Worksheet (/docs/basics/Worksheet.md) +.IP \[bu] 2 +Cell (/docs/basics/Cell.md) +.IP \[bu] 2 +Iteration (/docs/basics/Iteration.md) +.SS Workbook +.SS Worksheet +.SS Cell +.SS Iteration +.SS Advanced +.IP \[bu] 2 +Formatting (Formatting.md) +.IP \[bu] 2 +Properties (Properties.md) +.IP \[bu] 2 +Printing (Printing.md) +.IP \[bu] 2 +Encryption (Encryption.md) +.IP \[bu] 2 +Views (Views.md) +.SH Formatting +.SS Format vs. Style +.IP +.nf +\f[C] +#include\ +#include\ + +int\ main() +{ +\ \ \ \ xlnt::workbook\ wb; +\ \ \ \ auto\ cell\ =\ wb.active_sheet().cell("A1"); +\ \ \ \ return\ 0; +} +\f[] +.fi +.PP +In the context of xlnt, format and style have specific distinct +meanings. +A style in xlnt corresponds to a named style created in the "Cell +styles" dropdown in Excel. +It must have a name and optionally any of: alignment, border, fill, +font, number format, protection. +A format in xlnt corresponds to the alignment, border, fill, font, +number format, and protection settings applied to a cell via +right\-click\->"Format Cells". +A cell can have both a format and a style. +The style properties will generally override the format properties. +.SS Number Formatting +.IP +.nf +\f[C] +#include\ +#include\ + +int\ main() +{ +\ \ \ \ xlnt::workbook\ wb; +\ \ \ \ auto\ cell\ =\ wb.active_sheet().cell("A1"); +\ \ \ \ cell.number_format(xlnt::number_format::percentage()); +\ \ \ \ cell.value(0.513); +\ \ \ \ std::cout\ <<\ cell.to_string()\ <<\ std::endl; +\ \ \ \ return\ 0; +} +\f[] +.fi +.PP +An xlnt::number_format is the format code used when displaying a value +in a cell. +For example, a number_format of "0.00" implies that the number 13.726 +should be displayed as "13.73". +Many number formats are built\-in to Excel and can be access with +xlnt::number_format static constructors. +Other custom number formats can be created by passing a string to the +xlnt::number_format constructor (#cell-const-cell-amp). +.SH Properties +.IP +.nf +\f[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"); +\f[] +.fi +.SS Printing +.SS Encryption +.SS Views +.SS API +.IP \[bu] 2 +cell (cell.md) +.IP \[bu] 2 +cell_reference (cell_reference.md) +.SH cell +.SS \f[C]using\ xlnt::cell::type\ =\ \ cell_typeundefined\f[] +.PP +Alias xlnt::cell_type to xlnt::cell::type since it looks nicer. +.SS \f[C]friend\ class\ detail::xlsx_consumerundefined\f[] +.SS \f[C]friend\ class\ detail::xlsx_producerundefined\f[] +.SS \f[C]friend\ struct\ detail::cell_implundefined\f[] +.SS \f[C]static\ const\ std::unordered_map&\ xlnt::cell::error_codes()\f[] +.PP +Returns a map of error strings such as #DIV/0! and their associated +indices. +.SS \f[C]xlnt::cell::cell(const\ cell\ &)=default\f[] +.PP +Default copy constructor. +.SS \f[C]bool\ xlnt::cell::has_value()\ const\f[] +.PP +Returns true if value has been set and has not been cleared using +cell::clear_value(). +.SS \f[C]T\ xlnt::cell::value()\ const\f[] +.PP +Returns the value of this cell as an instance of type T. +Overloads exist for most C++ fundamental types like bool, int, etc. +as well as for std::string and xlnt datetime types: date, time, +datetime, and timedelta. +.SS \f[C]void\ xlnt::cell::clear_value()\f[] +.PP +Makes this cell have a value of type null. +All other cell attributes are retained. +.SS \f[C]void\ xlnt::cell::value(std::nullptr_t)\f[] +.PP +Sets the type of this cell to null. +.SS \f[C]void\ xlnt::cell::value(bool\ boolean_value)\f[] +.PP +Sets the value of this cell to the given boolean value. +.SS \f[C]void\ xlnt::cell::value(int\ int_value)\f[] +.PP +Sets the value of this cell to the given value. +.SS \f[C]void\ xlnt::cell::value(unsigned\ int\ int_value)\f[] +.PP +Sets the value of this cell to the given value. +.SS \f[C]void\ xlnt::cell::value(long\ long\ int\ int_value)\f[] +.PP +Sets the value of this cell to the given value. +.SS \f[C]void\ xlnt::cell::value(unsigned\ long\ long\ int\ int_value)\f[] +.PP +Sets the value of this cell to the given value. +.SS \f[C]void\ xlnt::cell::value(float\ float_value)\f[] +.PP +Sets the value of this cell to the given value. +.SS \f[C]void\ xlnt::cell::value(double\ float_value)\f[] +.PP +Sets the value of this cell to the given value. +.SS \f[C]void\ xlnt::cell::value(long\ double\ float_value)\f[] +.PP +Sets the value of this cell to the given value. +.SS \f[C]void\ xlnt::cell::value(const\ date\ &date_value)\f[] +.PP +Sets the value of this cell to the given value. +.SS \f[C]void\ xlnt::cell::value(const\ time\ &time_value)\f[] +.PP +Sets the value of this cell to the given value. +.SS \f[C]void\ xlnt::cell::value(const\ datetime\ &datetime_value)\f[] +.PP +Sets the value of this cell to the given value. +.SS \f[C]void\ xlnt::cell::value(const\ timedelta\ &timedelta_value)\f[] +.PP +Sets the value of this cell to the given value. +.SS \f[C]void\ xlnt::cell::value(const\ std::string\ &string_value)\f[] +.PP +Sets the value of this cell to the given value. +.SS \f[C]void\ xlnt::cell::value(const\ char\ *string_value)\f[] +.PP +Sets the value of this cell to the given value. +.SS \f[C]void\ xlnt::cell::value(const\ rich_text\ &text_value)\f[] +.PP +Sets the value of this cell to the given value. +.SS \f[C]void\ xlnt::cell::value(const\ cell\ other_cell)\f[] +.PP +Sets the value and formatting of this cell to that of other_cell. +.SS \f[C]void\ xlnt::cell::value(const\ std::string\ &string_value,\ bool\ infer_type)\f[] +.PP +Analyzes string_value to determine its type, convert it to that type, +and set the value of this cell to that converted value. +.SS \f[C]type\ xlnt::cell::data_type()\ const\f[] +.PP +Returns the type of this cell. +.SS \f[C]void\ xlnt::cell::data_type(type\ t)\f[] +.PP +Sets the type of this cell. +This should usually be done indirectly by setting the value of the cell +to a value of that type. +.SS \f[C]bool\ xlnt::cell::garbage_collectible()\ const\f[] +.PP +There\[aq]s no reason to keep a cell which has no value and is not a +placeholder. +Returns true if this cell has no value, style, isn\[aq]t merged, etc. +.SS \f[C]bool\ xlnt::cell::is_date()\ const\f[] +.PP +Returns true iff this cell\[aq]s number format matches a date format. +.SS \f[C]cell_reference\ xlnt::cell::reference()\ const\f[] +.PP +Returns a cell_reference that points to the location of this cell. +.SS \f[C]column_t\ xlnt::cell::column()\ const\f[] +.PP +Returns the column of this cell. +.SS \f[C]row_t\ xlnt::cell::row()\ const\f[] +.PP +Returns the row of this cell. +.SS \f[C]std::pair\ xlnt::cell::anchor()\ const\f[] +.PP +Returns the location of this cell as an ordered pair (left, top). +.SS \f[C]std::string\ xlnt::cell::hyperlink()\ const\f[] +.PP +Returns the URL of this cell\[aq]s hyperlink. +.SS \f[C]void\ xlnt::cell::hyperlink(const\ std::string\ &url)\f[] +.PP +Adds a hyperlink to this cell pointing to the URL of the given value. +.SS \f[C]void\ xlnt::cell::hyperlink(const\ std::string\ &url,\ const\ std::string\ &display)\f[] +.PP +Adds a hyperlink to this cell pointing to the URI of the given value and +sets the text value of the cell to the given parameter. +.SS \f[C]void\ xlnt::cell::hyperlink(xlnt::cell\ target)\f[] +.PP +Adds an internal hyperlink to this cell pointing to the given cell. +.SS \f[C]bool\ xlnt::cell::has_hyperlink()\ const\f[] +.PP +Returns true if this cell has a hyperlink set. +.SS \f[C]class\ alignment\ xlnt::cell::computed_alignment()\ const\f[] +.PP +Returns the alignment that should be used when displaying this cell +graphically based on the workbook default, the cell\-level format, and +the named style applied to the cell in that order. +.SS \f[C]class\ border\ xlnt::cell::computed_border()\ const\f[] +.PP +Returns the border that should be used when displaying this cell +graphically based on the workbook default, the cell\-level format, and +the named style applied to the cell in that order. +.SS \f[C]class\ fill\ xlnt::cell::computed_fill()\ const\f[] +.PP +Returns the fill that should be used when displaying this cell +graphically based on the workbook default, the cell\-level format, and +the named style applied to the cell in that order. +.SS \f[C]class\ font\ xlnt::cell::computed_font()\ const\f[] +.PP +Returns the font that should be used when displaying this cell +graphically based on the workbook default, the cell\-level format, and +the named style applied to the cell in that order. +.SS \f[C]class\ number_format\ xlnt::cell::computed_number_format()\ const\f[] +.PP +Returns the number format that should be used when displaying this cell +graphically based on the workbook default, the cell\-level format, and +the named style applied to the cell in that order. +.SS \f[C]class\ protection\ xlnt::cell::computed_protection()\ const\f[] +.PP +Returns the protection that should be used when displaying this cell +graphically based on the workbook default, the cell\-level format, and +the named style applied to the cell in that order. +.SS \f[C]bool\ xlnt::cell::has_format()\ const\f[] +.PP +Returns true if this cell has had a format applied to it. +.SS \f[C]const\ class\ format\ xlnt::cell::format()\ const\f[] +.PP +Returns the format applied to this cell. +If this cell has no format, an invalid_attribute exception will be +thrown. +.SS \f[C]void\ xlnt::cell::format(const\ class\ format\ new_format)\f[] +.PP +Applies the cell\-level formatting of new_format to this cell. +.SS \f[C]void\ xlnt::cell::clear_format()\f[] +.PP +Removes the cell\-level formatting from this cell. +This doesn\[aq]t affect the style that may also be applied to the cell. +Throws an invalid_attribute exception if no format is applied. +.SS \f[C]class\ number_format\ xlnt::cell::number_format()\ const\f[] +.PP +Returns the number format of this cell. +.SS \f[C]void\ xlnt::cell::number_format(const\ class\ number_format\ &format)\f[] +.PP +Creates a new format in the workbook, sets its number_format to the +given format, and applies the format to this cell. +.SS \f[C]class\ font\ xlnt::cell::font()\ const\f[] +.PP +Returns the font applied to the text in this cell. +.SS \f[C]void\ xlnt::cell::font(const\ class\ font\ &font_)\f[] +.PP +Creates a new format in the workbook, sets its font to the given font, +and applies the format to this cell. +.SS \f[C]class\ fill\ xlnt::cell::fill()\ const\f[] +.PP +Returns the fill applied to this cell. +.SS \f[C]void\ xlnt::cell::fill(const\ class\ fill\ &fill_)\f[] +.PP +Creates a new format in the workbook, sets its fill to the given fill, +and applies the format to this cell. +.SS \f[C]class\ border\ xlnt::cell::border()\ const\f[] +.PP +Returns the border of this cell. +.SS \f[C]void\ xlnt::cell::border(const\ class\ border\ &border_)\f[] +.PP +Creates a new format in the workbook, sets its border to the given +border, and applies the format to this cell. +.SS \f[C]class\ alignment\ xlnt::cell::alignment()\ const\f[] +.PP +Returns the alignment of the text in this cell. +.SS \f[C]void\ xlnt::cell::alignment(const\ class\ alignment\ &alignment_)\f[] +.PP +Creates a new format in the workbook, sets its alignment to the given +alignment, and applies the format to this cell. +.SS \f[C]class\ protection\ xlnt::cell::protection()\ const\f[] +.PP +Returns the protection of this cell. +.SS \f[C]void\ xlnt::cell::protection(const\ class\ protection\ &protection_)\f[] +.PP +Creates a new format in the workbook, sets its protection to the given +protection, and applies the format to this cell. +.SS \f[C]bool\ xlnt::cell::has_style()\ const\f[] +.PP +Returns true if this cell has had a style applied to it. +.SS \f[C]class\ style\ xlnt::cell::style()\f[] +.PP +Returns a wrapper pointing to the named style applied to this cell. +.SS \f[C]const\ class\ style\ xlnt::cell::style()\ const\f[] +.PP +Returns a wrapper pointing to the named style applied to this cell. +.SS \f[C]void\ xlnt::cell::style(const\ class\ style\ &new_style)\f[] +.PP +Sets the named style applied to this cell to a style named style_name. +Equivalent to style(new_style.name()). +.SS \f[C]void\ xlnt::cell::style(const\ std::string\ &style_name)\f[] +.PP +Sets the named style applied to this cell to a style named style_name. +If this style has not been previously created in the workbook, a +key_not_found exception will be thrown. +.SS \f[C]void\ xlnt::cell::clear_style()\f[] +.PP +Removes the named style from this cell. +An invalid_attribute exception will be thrown if this cell has no style. +This will not affect the cell format of the cell. +.SS \f[C]std::string\ xlnt::cell::formula()\ const\f[] +.PP +Returns the string representation of the formula applied to this cell. +.SS \f[C]void\ xlnt::cell::formula(const\ std::string\ &formula)\f[] +.PP +Sets the formula of this cell to the given value. +This formula string should begin with \[aq]=\[aq]. +.SS \f[C]void\ xlnt::cell::clear_formula()\f[] +.PP +Removes the formula from this cell. +After this is called, has_formula() will return false. +.SS \f[C]bool\ xlnt::cell::has_formula()\ const\f[] +.PP +Returns true if this cell has had a formula applied to it. +.SS \f[C]std::string\ xlnt::cell::to_string()\ const\f[] +.PP +Returns a string representing the value of this cell. +If the data type is not a string, it will be converted according to the +number format. +.SS \f[C]bool\ xlnt::cell::is_merged()\ const\f[] +.PP +Returns true iff this cell has been merged with one or more surrounding +cells. +.SS \f[C]void\ xlnt::cell::merged(bool\ merged)\f[] +.PP +Makes this a merged cell iff merged is true. +Generally, this shouldn\[aq]t be called directly. +Instead, use worksheet::merge_cells on its parent worksheet. +.SS \f[C]std::string\ xlnt::cell::error()\ const\f[] +.PP +Returns the error string that is stored in this cell. +.SS \f[C]void\ xlnt::cell::error(const\ std::string\ &error)\f[] +.PP +Directly assigns the value of this cell to be the given error. +.SS \f[C]cell\ xlnt::cell::offset(int\ column,\ int\ row)\f[] +.PP +Returns a cell from this cell\[aq]s parent workbook at a relative offset +given by the parameters. +.SS \f[C]class\ worksheet\ xlnt::cell::worksheet()\f[] +.PP +Returns the worksheet that owns this cell. +.SS \f[C]const\ class\ worksheet\ xlnt::cell::worksheet()\ const\f[] +.PP +Returns the worksheet that owns this cell. +.SS \f[C]class\ workbook&\ xlnt::cell::workbook()\f[] +.PP +Returns the workbook of the worksheet that owns this cell. +.SS \f[C]const\ class\ workbook&\ xlnt::cell::workbook()\ const\f[] +.PP +Returns the workbook of the worksheet that owns this cell. +.SS \f[C]calendar\ xlnt::cell::base_date()\ const\f[] +.PP +Returns the base date of the parent workbook. +.SS \f[C]std::string\ xlnt::cell::check_string(const\ std::string\ &to_check)\f[] +.PP +Returns to_check after verifying and fixing encoding, size, and illegal +characters. +.SS \f[C]bool\ xlnt::cell::has_comment()\f[] +.PP +Returns true if this cell has a comment applied. +.SS \f[C]void\ xlnt::cell::clear_comment()\f[] +.PP +Deletes the comment applied to this cell if it exists. +.SS \f[C]class\ comment\ xlnt::cell::comment()\f[] +.PP +Gets the comment applied to this cell. +.SS \f[C]void\ xlnt::cell::comment(const\ std::string\ &text,\ const\ std::string\ &author="Microsoft\ Office\ User")\f[] +.PP +Creates a new comment with the given text and optional author and +applies it to the cell. +.SS \f[C]void\ xlnt::cell::comment(const\ std::string\ &comment_text,\ const\ class\ font\ &comment_font,\ const\ std::string\ &author="Microsoft\ Office\ User")\f[] +.PP +Creates a new comment with the given text, formatting, and optional +author and applies it to the cell. +.SS \f[C]void\ xlnt::cell::comment(const\ class\ comment\ &new_comment)\f[] +.PP +Apply the comment provided as the only argument to the cell. +.SS \f[C]double\ xlnt::cell::width()\ const\f[] +.PP +Returns the width of this cell in pixels. +.SS \f[C]double\ xlnt::cell::height()\ const\f[] +.PP +Returns the height of this cell in pixels. +.SS \f[C]cell&\ xlnt::cell::operator=(const\ cell\ &rhs)\f[] +.PP +Makes this cell interally point to rhs. +The cell data originally pointed to by this cell will be unchanged. +.SS \f[C]bool\ xlnt::cell::operator==(const\ cell\ &comparand)\ const\f[] +.PP +Returns true if this cell the same cell as comparand (compared by +reference). +.SS \f[C]bool\ xlnt::cell::operator==(std::nullptr_t)\ const\f[] +.PP +Returns true if this cell is uninitialized. +.SH cell_reference +.SS \f[C]static\ std::pair\ xlnt::cell_reference::split_reference(const\ std::string\ &reference_string)\f[] +.PP +Splits a coordinate string like "A1" into an equivalent pair like {"A", +1}. +.SS \f[C]static\ std::pair\ xlnt::cell_reference::split_reference(const\ std::string\ &reference_string,\ bool\ &absolute_column,\ bool\ &absolute_row)\f[] +.PP +Splits a coordinate string like "A1" into an equivalent pair like {"A", +1}. +Reference parameters absolute_column and absolute_row will be set to +true if column part or row part are prefixed by a dollar\-sign +indicating they are absolute, otherwise false. +.SS \f[C]xlnt::cell_reference::cell_reference()\f[] +.PP +Default constructor makes a reference to the top\-left\-most cell, "A1". +.SS \f[C]xlnt::cell_reference::cell_reference(const\ char\ *reference_string)\f[] +.PP +Constructs a cell_reference from a string reprenting a cell coordinate +(e.g. +$B14). +.SS \f[C]xlnt::cell_reference::cell_reference(const\ std::string\ &reference_string)\f[] +.PP +Constructs a cell_reference from a string reprenting a cell coordinate +(e.g. +$B14). +.SS \f[C]xlnt::cell_reference::cell_reference(column_t\ column,\ row_t\ row)\f[] +.PP +Constructs a cell_reference from a 1\-indexed column index and row +index. +.SS \f[C]cell_reference&\ xlnt::cell_reference::make_absolute(bool\ absolute_column=true,\ bool\ absolute_row=true)\f[] +.PP +Converts a coordinate to an absolute coordinate string (e.g. +B12 \-> $B$12) Defaulting to true, absolute_column and absolute_row can +optionally control whether the resulting cell_reference has an absolute +column (e.g. +B12 \-> $B12) and absolute row (e.g. +B12 \-> B$12) respectively. +.SS \f[C]bool\ xlnt::cell_reference::column_absolute()\ const\f[] +.PP +Returns true if the reference refers to an absolute column, otherwise +false. +.SS \f[C]void\ xlnt::cell_reference::column_absolute(bool\ absolute_column)\f[] +.PP +Makes this reference have an absolute column if absolute_column is true, +otherwise not absolute. +.SS \f[C]bool\ xlnt::cell_reference::row_absolute()\ const\f[] +.PP +Returns true if the reference refers to an absolute row, otherwise +false. +.SS \f[C]void\ xlnt::cell_reference::row_absolute(bool\ absolute_row)\f[] +.PP +Makes this reference have an absolute row if absolute_row is true, +otherwise not absolute. +.SS \f[C]column_t\ xlnt::cell_reference::column()\ const\f[] +.PP +Returns a string that identifies the column of this reference (e.g. +second column from left is "B") +.SS \f[C]void\ xlnt::cell_reference::column(const\ std::string\ &column_string)\f[] +.PP +Sets the column of this reference from a string that identifies a +particular column. +.SS \f[C]column_t::index_t\ xlnt::cell_reference::column_index()\ const\f[] +.PP +Returns a 1\-indexed numeric index of the column of this reference. +.SS \f[C]void\ xlnt::cell_reference::column_index(column_t\ column)\f[] +.PP +Sets the column of this reference from a 1\-indexed number that +identifies a particular column. +.SS \f[C]row_t\ xlnt::cell_reference::row()\ const\f[] +.PP +Returns a 1\-indexed numeric index of the row of this reference. +.SS \f[C]void\ xlnt::cell_reference::row(row_t\ row)\f[] +.PP +Sets the row of this reference from a 1\-indexed number that identifies +a particular row. +.SS \f[C]cell_reference\ xlnt::cell_reference::make_offset(int\ column_offset,\ int\ row_offset)\ const\f[] +.PP +Returns a cell_reference offset from this cell_reference by the number +of columns and rows specified by the parameters. +A negative value for column_offset or row_offset results in a reference +above or left of this cell_reference, respectively. +.SS \f[C]std::string\ xlnt::cell_reference::to_string()\ const\f[] +.PP +Returns a string like "A1" for cell_reference(1, 1). +.SS \f[C]range_reference\ xlnt::cell_reference::to_range()\ const\f[] +.PP +Returns a 1x1 range_reference containing only this cell_reference. +.SS \f[C]range_reference\ xlnt::cell_reference::operator,(const\ cell_reference\ &other)\ const\f[] +.PP +I\[aq]ve always wanted to overload the comma operator. +cell_reference("A", 1), cell_reference("B", 1) will return +range_reference(cell_reference("A", 1), cell_reference("B", 1)) +.SS \f[C]bool\ xlnt::cell_reference::operator==(const\ cell_reference\ &comparand)\ const\f[] +.PP +Returns true if this reference is identical to comparand including in +absoluteness of column and row. +.SS \f[C]bool\ xlnt::cell_reference::operator==(const\ std::string\ &reference_string)\ const\f[] +.PP +Constructs a cell_reference from reference_string and return the result +of their comparison. +.SS \f[C]bool\ xlnt::cell_reference::operator==(const\ char\ *reference_string)\ const\f[] +.PP +Constructs a cell_reference from reference_string and return the result +of their comparison. +.SS \f[C]bool\ xlnt::cell_reference::operator!=(const\ cell_reference\ &comparand)\ const\f[] +.PP +Returns true if this reference is not identical to comparand including +in absoluteness of column and row. +.SS \f[C]bool\ xlnt::cell_reference::operator!=(const\ std::string\ &reference_string)\ const\f[] +.PP +Constructs a cell_reference from reference_string and return the result +of their comparison. +.SS \f[C]bool\ xlnt::cell_reference::operator!=(const\ char\ *reference_string)\ const\f[] +.PP +Constructs a cell_reference from reference_string and return the result +of their comparison. +.SH Change Log +.PP +This project adheres to Semantic Versioning (http://semver.org/). +Every release is documented on the Github +Releases (https://github.com/tfussell/xlnt/releases) page. +.SH Contributing to xlnt +.PP +xlnt welcomes contributions from everyone regardless of skill level +(provided you can write C++ or documentation). +.SS Getting Started +.PP +Look through the list of issues to find something interesting to work +on. +Help is appreciated with any issues, but important timely issues are +labeled as "help wanted". +Issues labeled "docs" might be good for those who want to contribute +without having to know too much C++. +You might also find something that the code is missing without an +associated issue. +That\[aq]s fine to work on to, but it might be best to make an issue +first in case someone else is working on it. +.SS Contributions +.PP +Contributions to xlnt should be made in the form of pull requests on +GitHub. +Each pull request will be reviewed and either merged into the current +development branch or given feedback for changes that would be required +to do so. +.PP +All code in this repository is under the MIT License. +You should agree to these terms before submitting any code to xlnt. +.SS Pull Request Checklist +.IP \[bu] 2 +Branch from the head of the current development branch. +Until version 1.0 is released, this the master branch. +.IP \[bu] 2 +Commits should be as small as possible, while ensuring that each commit +is correct independently (i.e. +each commit should compile and pass all tests). +Commits that don\[aq]t follow the coding style indicated in +\&.clang\-format (e.g. +indentation) are less likely to be accepted until they are fixed. +.IP \[bu] 2 +If your pull request is not getting reviewed or you need a specific +person to review it, you can \@\-reply a reviewer asking for a review in +the pull request or a comment. +.IP \[bu] 2 +Add tests relevant to the fixed defect or new feature. +It\[aq]s best to do this before making any changes, make sure that the +tests fail, then make changes ensuring that it ultimately passes the +tests (i.e. +TDD). +xlnt uses cxxtest for testing. +Tests are contained in a tests directory inside each module (e.g. +source/workbook/tests/test\f[I]workbook.hpp) in the form of a header +file. Each test is a separate function with a name that starts like +"test\f[]". +See for information about CxxTest or +take a look at existing tests. +.SS Conduct +.PP +Just try to be nice\-\-we\[aq]re all volunteers here. +.SS Communication +.PP +Add a comment to an existing issue on GitHub, open a new issue for +defects or feature requests, or contact \@tfussell if you want. +.SH License +.SS xlnt (https://github.com/tfussell/xlnt) +.RS +.PP +MIT License (https://github.com/tfussell/xlnt/blob/master/LICENSE.md) +.RE +.IP +.nf +\f[C] +Copyright\ (c)\ 2014\-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,\ ARISING\ FROM,\ OUT\ OF\ OR\ IN\ CONNECTION\ WITH\ THE +SOFTWARE\ OR\ THE\ USE\ OR\ OTHER\ DEALINGS\ IN\ THE\ SOFTWARE. +\f[] +.fi +.SS POLE (http://www.dimin.net/software/pole/) +.RS +.PP +BSD 2\-Clause +License (https://bitbucket.org/dimin/pole/src/c15e513bdce4c3a52b3dbc925d4d2bb520dc71d8/pole/LICENSE) +.RE +.IP +.nf +\f[C] +POLE\ \-\ Portable\ C++\ library\ to\ access\ OLE\ Storage +Copyright\ (C)\ 2002\-2007\ Ariya\ Hidayat\ (ariya\@kde.org).\ All\ rights\ reserved. + +Redistribution\ and\ use\ in\ source\ and\ binary\ forms,\ with\ or\ without +modification,\ are\ permitted\ provided\ that\ the\ following\ conditions +are\ met: + +1.\ Redistributions\ of\ source\ code\ must\ retain\ the\ above\ copyright +\ \ \ notice,\ this\ list\ of\ conditions\ and\ the\ following\ disclaimer. +2.\ Redistributions\ in\ binary\ form\ must\ reproduce\ the\ above\ copyright +\ \ \ notice,\ this\ list\ of\ conditions\ and\ the\ following\ disclaimer\ in\ the +\ \ \ documentation\ and/or\ other\ materials\ provided\ with\ the\ distribution. + +THIS\ SOFTWARE\ IS\ PROVIDED\ BY\ THE\ AUTHOR\ "AS\ IS"\ AND\ ANY\ EXPRESS\ OR +IMPLIED\ WARRANTIES,\ INCLUDING,\ BUT\ NOT\ LIMITED\ TO,\ THE\ IMPLIED\ WARRANTIES +OF\ MERCHANTABILITY\ AND\ FITNESS\ FOR\ A\ PARTICULAR\ PURPOSE\ ARE\ DISCLAIMED. +IN\ NO\ EVENT\ SHALL\ THE\ AUTHOR\ BE\ LIABLE\ FOR\ ANY\ DIRECT,\ INDIRECT, +INCIDENTAL,\ SPECIAL,\ EXEMPLARY,\ OR\ CONSEQUENTIAL\ DAMAGES\ (INCLUDING,\ BUT +NOT\ LIMITED\ TO,\ PROCUREMENT\ OF\ SUBSTITUTE\ GOODS\ OR\ SERVICES;\ LOSS\ OF\ USE, +DATA,\ OR\ PROFITS;\ OR\ BUSINESS\ INTERRUPTION)\ HOWEVER\ CAUSED\ AND\ ON\ ANY +THEORY\ OF\ LIABILITY,\ WHETHER\ IN\ CONTRACT,\ STRICT\ LIABILITY,\ OR\ TORT +(INCLUDING\ NEGLIGENCE\ OR\ OTHERWISE)\ ARISING\ IN\ ANY\ WAY\ OUT\ OF\ THE\ USE\ OF +THIS\ SOFTWARE,\ EVEN\ IF\ ADVISED\ OF\ THE\ POSSIBILITY\ OF\ SUCH\ DAMAGE. +\f[] +.fi +.SS libstudxml (http://www.codesynthesis.com/projects/libstudxml/) +.RS +.PP +MIT License (http://www.codesynthesis.com/licenses/mit.txt) +.RE +.IP +.nf +\f[C] +Summary:\ Everything\ is\ licensed\ under\ the\ MIT\ License\ (text\ below). + +Code\ found\ in\ the\ xml/details/expat/\ directory\ is\ distributed\ under +the\ MIT\ License\ (see\ the\ xml/details/expat/LICENSE\ file\ for\ copyright +information). + +Code\ found\ in\ the\ xml/details/genx/\ directory\ is\ distributed\ under +the\ MIT\ License\ (see\ the\ xml/details/genx/LICENSE\ file\ for\ copyright +information). + +The\ rest\ is\ Copyright\ (c)\ 2013\-2014\ Code\ Synthesis\ Tools\ CC\ and\ is +distributed\ under\ the\ MIT\ License: + +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,\ ARISING\ FROM,\ OUT\ OF\ OR\ IN\ CONNECTION\ WITH\ THE +SOFTWARE\ OR\ THE\ USE\ OR\ OTHER\ DEALINGS\ IN\ THE\ SOFTWARE. +\f[] +.fi +.SS CxxTest (http://cxxtest.com/) +.RS +.PP +LGPL License (https://github.com/CxxTest/cxxtest/blob/master/COPYING) +.RE +.IP +.nf +\f[C] +\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ GNU\ LESSER\ GENERAL\ PUBLIC\ LICENSE +\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ Version\ 3,\ 29\ June\ 2007 + +\ Copyright\ (C)\ 2007\ Free\ Software\ Foundation,\ Inc.\ +\ Everyone\ is\ permitted\ to\ copy\ and\ distribute\ verbatim\ copies +\ of\ this\ license\ document,\ but\ changing\ it\ is\ not\ allowed. + + +\ \ This\ version\ of\ the\ GNU\ Lesser\ General\ Public\ License\ incorporates +the\ terms\ and\ conditions\ of\ version\ 3\ of\ the\ GNU\ General\ Public +License,\ supplemented\ by\ the\ additional\ permissions\ listed\ below. + +\ \ 0.\ Additional\ Definitions. + +\ \ As\ used\ herein,\ "this\ License"\ refers\ to\ version\ 3\ of\ the\ GNU\ Lesser +General\ Public\ License,\ and\ the\ "GNU\ GPL"\ refers\ to\ version\ 3\ of\ the\ GNU +General\ Public\ License. + +\ \ "The\ Library"\ refers\ to\ a\ covered\ work\ governed\ by\ this\ License, +other\ than\ an\ Application\ or\ a\ Combined\ Work\ as\ defined\ below. + +\ \ An\ "Application"\ is\ any\ work\ that\ makes\ use\ of\ an\ interface\ provided +by\ the\ Library,\ but\ which\ is\ not\ otherwise\ based\ on\ the\ Library. +Defining\ a\ subclass\ of\ a\ class\ defined\ by\ the\ Library\ is\ deemed\ a\ mode +of\ using\ an\ interface\ provided\ by\ the\ Library. + +\ \ A\ "Combined\ Work"\ is\ a\ work\ produced\ by\ combining\ or\ linking\ an +Application\ with\ the\ Library.\ \ The\ particular\ version\ of\ the\ Library +with\ which\ the\ Combined\ Work\ was\ made\ is\ also\ called\ the\ "Linked +Version". + +\ \ The\ "Minimal\ Corresponding\ Source"\ for\ a\ Combined\ Work\ means\ the +Corresponding\ Source\ for\ the\ Combined\ Work,\ excluding\ any\ source\ code +for\ portions\ of\ the\ Combined\ Work\ that,\ considered\ in\ isolation,\ are +based\ on\ the\ Application,\ and\ not\ on\ the\ Linked\ Version. + +\ \ The\ "Corresponding\ Application\ Code"\ for\ a\ Combined\ Work\ means\ the +object\ code\ and/or\ source\ code\ for\ the\ Application,\ including\ any\ data +and\ utility\ programs\ needed\ for\ reproducing\ the\ Combined\ Work\ from\ the +Application,\ but\ excluding\ the\ System\ Libraries\ of\ the\ Combined\ Work. + +\ \ 1.\ Exception\ to\ Section\ 3\ of\ the\ GNU\ GPL. + +\ \ You\ may\ convey\ a\ covered\ work\ under\ sections\ 3\ and\ 4\ of\ this\ License +without\ being\ bound\ by\ section\ 3\ of\ the\ GNU\ GPL. + +\ \ 2.\ Conveying\ Modified\ Versions. + +\ \ If\ you\ modify\ a\ copy\ of\ the\ Library,\ and,\ in\ your\ modifications,\ a +facility\ refers\ to\ a\ function\ or\ data\ to\ be\ supplied\ by\ an\ Application +that\ uses\ the\ facility\ (other\ than\ as\ an\ argument\ passed\ when\ the +facility\ is\ invoked),\ then\ you\ may\ convey\ a\ copy\ of\ the\ modified +version: + +\ \ \ a)\ under\ this\ License,\ provided\ that\ you\ make\ a\ good\ faith\ effort\ to +\ \ \ ensure\ that,\ in\ the\ event\ an\ Application\ does\ not\ supply\ the +\ \ \ function\ or\ data,\ the\ facility\ still\ operates,\ and\ performs +\ \ \ whatever\ part\ of\ its\ purpose\ remains\ meaningful,\ or + +\ \ \ b)\ under\ the\ GNU\ GPL,\ with\ none\ of\ the\ additional\ permissions\ of +\ \ \ this\ License\ applicable\ to\ that\ copy. + +\ \ 3.\ Object\ Code\ Incorporating\ Material\ from\ Library\ Header\ Files. + +\ \ The\ object\ code\ form\ of\ an\ Application\ may\ incorporate\ material\ from +a\ header\ file\ that\ is\ part\ of\ the\ Library.\ \ You\ may\ convey\ such\ object +code\ under\ terms\ of\ your\ choice,\ provided\ that,\ if\ the\ incorporated +material\ is\ not\ limited\ to\ numerical\ parameters,\ data\ structure +layouts\ and\ accessors,\ or\ small\ macros,\ inline\ functions\ and\ templates +(ten\ or\ fewer\ lines\ in\ length),\ you\ do\ both\ of\ the\ following: + +\ \ \ a)\ Give\ prominent\ notice\ with\ each\ copy\ of\ the\ object\ code\ that\ the +\ \ \ Library\ is\ used\ in\ it\ and\ that\ the\ Library\ and\ its\ use\ are +\ \ \ covered\ by\ this\ License. + +\ \ \ b)\ Accompany\ the\ object\ code\ with\ a\ copy\ of\ the\ GNU\ GPL\ and\ this\ license +\ \ \ document. + +\ \ 4.\ Combined\ Works. + +\ \ You\ may\ convey\ a\ Combined\ Work\ under\ terms\ of\ your\ choice\ that, +taken\ together,\ effectively\ do\ not\ restrict\ modification\ of\ the +portions\ of\ the\ Library\ contained\ in\ the\ Combined\ Work\ and\ reverse +engineering\ for\ debugging\ such\ modifications,\ if\ you\ also\ do\ each\ of +the\ following: + +\ \ \ a)\ Give\ prominent\ notice\ with\ each\ copy\ of\ the\ Combined\ Work\ that +\ \ \ the\ Library\ is\ used\ in\ it\ and\ that\ the\ Library\ and\ its\ use\ are +\ \ \ covered\ by\ this\ License. + +\ \ \ b)\ Accompany\ the\ Combined\ Work\ with\ a\ copy\ of\ the\ GNU\ GPL\ and\ this\ license +\ \ \ document. + +\ \ \ c)\ For\ a\ Combined\ Work\ that\ displays\ copyright\ notices\ during +\ \ \ execution,\ include\ the\ copyright\ notice\ for\ the\ Library\ among +\ \ \ these\ notices,\ as\ well\ as\ a\ reference\ directing\ the\ user\ to\ the +\ \ \ copies\ of\ the\ GNU\ GPL\ and\ this\ license\ document. + +\ \ \ d)\ Do\ one\ of\ the\ following: + +\ \ \ \ \ \ \ 0)\ Convey\ the\ Minimal\ Corresponding\ Source\ under\ the\ terms\ of\ this +\ \ \ \ \ \ \ License,\ and\ the\ Corresponding\ Application\ Code\ in\ a\ form +\ \ \ \ \ \ \ suitable\ for,\ and\ under\ terms\ that\ permit,\ the\ user\ to +\ \ \ \ \ \ \ recombine\ or\ relink\ the\ Application\ with\ a\ modified\ version\ of +\ \ \ \ \ \ \ the\ Linked\ Version\ to\ produce\ a\ modified\ Combined\ Work,\ in\ the +\ \ \ \ \ \ \ manner\ specified\ by\ section\ 6\ of\ the\ GNU\ GPL\ for\ conveying +\ \ \ \ \ \ \ Corresponding\ Source. + +\ \ \ \ \ \ \ 1)\ Use\ a\ suitable\ shared\ library\ mechanism\ for\ linking\ with\ the +\ \ \ \ \ \ \ Library.\ \ A\ suitable\ mechanism\ is\ one\ that\ (a)\ uses\ at\ run\ time +\ \ \ \ \ \ \ a\ copy\ of\ the\ Library\ already\ present\ on\ the\ user\[aq]s\ computer +\ \ \ \ \ \ \ system,\ and\ (b)\ will\ operate\ properly\ with\ a\ modified\ version +\ \ \ \ \ \ \ of\ the\ Library\ that\ is\ interface\-compatible\ with\ the\ Linked +\ \ \ \ \ \ \ Version. + +\ \ \ e)\ Provide\ Installation\ Information,\ but\ only\ if\ you\ would\ otherwise +\ \ \ be\ required\ to\ provide\ such\ information\ under\ section\ 6\ of\ the +\ \ \ GNU\ GPL,\ and\ only\ to\ the\ extent\ that\ such\ information\ is +\ \ \ necessary\ to\ install\ and\ execute\ a\ modified\ version\ of\ the +\ \ \ Combined\ Work\ produced\ by\ recombining\ or\ relinking\ the +\ \ \ Application\ with\ a\ modified\ version\ of\ the\ Linked\ Version.\ (If +\ \ \ you\ use\ option\ 4d0,\ the\ Installation\ Information\ must\ accompany +\ \ \ the\ Minimal\ Corresponding\ Source\ and\ Corresponding\ Application +\ \ \ Code.\ If\ you\ use\ option\ 4d1,\ you\ must\ provide\ the\ Installation +\ \ \ Information\ in\ the\ manner\ specified\ by\ section\ 6\ of\ the\ GNU\ GPL +\ \ \ for\ conveying\ Corresponding\ Source.) + +\ \ 5.\ Combined\ Libraries. + +\ \ You\ may\ place\ library\ facilities\ that\ are\ a\ work\ based\ on\ the +Library\ side\ by\ side\ in\ a\ single\ library\ together\ with\ other\ library +facilities\ that\ are\ not\ Applications\ and\ are\ not\ covered\ by\ this +License,\ and\ convey\ such\ a\ combined\ library\ under\ terms\ of\ your +choice,\ if\ you\ do\ both\ of\ the\ following: + +\ \ \ a)\ Accompany\ the\ combined\ library\ with\ a\ copy\ of\ the\ same\ work\ based +\ \ \ on\ the\ Library,\ uncombined\ with\ any\ other\ library\ facilities, +\ \ \ conveyed\ under\ the\ terms\ of\ this\ License. + +\ \ \ b)\ Give\ prominent\ notice\ with\ the\ combined\ library\ that\ part\ of\ it +\ \ \ is\ a\ work\ based\ on\ the\ Library,\ and\ explaining\ where\ to\ find\ the +\ \ \ accompanying\ uncombined\ form\ of\ the\ same\ work. + +\ \ 6.\ Revised\ Versions\ of\ the\ GNU\ Lesser\ General\ Public\ License. + +\ \ The\ Free\ Software\ Foundation\ may\ publish\ revised\ and/or\ new\ versions +of\ the\ GNU\ Lesser\ General\ Public\ License\ from\ time\ to\ time.\ Such\ new +versions\ will\ be\ similar\ in\ spirit\ to\ the\ present\ version,\ but\ may +differ\ in\ detail\ to\ address\ new\ problems\ or\ concerns. + +\ \ Each\ version\ is\ given\ a\ distinguishing\ version\ number.\ If\ the +Library\ as\ you\ received\ it\ specifies\ that\ a\ certain\ numbered\ version +of\ the\ GNU\ Lesser\ General\ Public\ License\ "or\ any\ later\ version" +applies\ to\ it,\ you\ have\ the\ option\ of\ following\ the\ terms\ and +conditions\ either\ of\ that\ published\ version\ or\ of\ any\ later\ version +published\ by\ the\ Free\ Software\ Foundation.\ If\ the\ Library\ as\ you +received\ it\ does\ not\ specify\ a\ version\ number\ of\ the\ GNU\ Lesser +General\ Public\ License,\ you\ may\ choose\ any\ version\ of\ the\ GNU\ Lesser +General\ Public\ License\ ever\ published\ by\ the\ Free\ Software\ Foundation. + +\ \ If\ the\ Library\ as\ you\ received\ it\ specifies\ that\ a\ proxy\ can\ decide +whether\ future\ versions\ of\ the\ GNU\ Lesser\ General\ Public\ License\ shall +apply,\ that\ proxy\[aq]s\ public\ statement\ of\ acceptance\ of\ any\ version\ is +permanent\ authorization\ for\ you\ to\ choose\ that\ version\ for\ the +Library. +\f[] +.fi +.SS PartIO (https://www.disneyanimation.com/technology/partio.html) +.RS +.PP +BSD 3\-Clause License (with specific non\-attribution +clause) (https://github.com/wdas/partio/blob/master/src/lib/io/ZIP.h) +.RE +.IP +.nf +\f[C] +Copyright\ 2010\ Disney\ Enterprises,\ Inc.\ All\ rights\ reserved + +Redistribution\ and\ use\ in\ source\ and\ binary\ forms,\ with\ or\ without +modification,\ are\ permitted\ provided\ that\ the\ following\ conditions\ are +met: + +*\ Redistributions\ of\ source\ code\ must\ retain\ the\ above\ copyright +notice,\ this\ list\ of\ conditions\ and\ the\ following\ disclaimer. + +*\ Redistributions\ in\ binary\ form\ must\ reproduce\ the\ above\ copyright +notice,\ this\ list\ of\ conditions\ and\ the\ following\ disclaimer\ in +the\ documentation\ and/or\ other\ materials\ provided\ with\ the +distribution. + +*\ The\ names\ "Disney",\ "Walt\ Disney\ Pictures",\ "Walt\ Disney\ Animation +Studios"\ or\ the\ names\ of\ its\ contributors\ may\ NOT\ be\ used\ to +endorse\ or\ promote\ products\ derived\ from\ this\ software\ without +specific\ prior\ written\ permission\ from\ Walt\ Disney\ Pictures. + +Disclaimer:\ THIS\ SOFTWARE\ IS\ PROVIDED\ BY\ WALT\ DISNEY\ PICTURES\ AND +CONTRIBUTORS\ "AS\ IS"\ AND\ ANY\ EXPRESS\ OR\ IMPLIED\ WARRANTIES,\ INCLUDING, +BUT\ NOT\ LIMITED\ TO,\ THE\ IMPLIED\ WARRANTIES\ OF\ MERCHANTABILITY,\ FITNESS +FOR\ A\ PARTICULAR\ PURPOSE,\ NONINFRINGEMENT\ AND\ TITLE\ ARE\ DISCLAIMED. +IN\ NO\ EVENT\ SHALL\ WALT\ DISNEY\ PICTURES,\ THE\ COPYRIGHT\ HOLDER\ OR +CONTRIBUTORS\ BE\ LIABLE\ FOR\ ANY\ DIRECT,\ INDIRECT,\ INCIDENTAL,\ SPECIAL, +EXEMPLARY,\ OR\ CONSEQUENTIAL\ DAMAGES\ (INCLUDING,\ BUT\ NOT\ LIMITED\ TO, +PROCUREMENT\ OF\ SUBSTITUTE\ GOODS\ OR\ SERVICES;\ LOSS\ OF\ USE,\ DATA,\ OR +PROFITS;\ OR\ BUSINESS\ INTERRUPTION)\ HOWEVER\ CAUSED\ AND\ BASED\ ON\ ANY +THEORY\ OF\ LIABILITY,\ WHETHER\ IN\ CONTRACT,\ STRICT\ LIABILITY,\ OR\ TORT +(INCLUDING\ NEGLIGENCE\ OR\ OTHERWISE)\ ARISING\ IN\ ANY\ WAY\ OUT\ OF\ THE\ USE +OF\ THIS\ SOFTWARE,\ EVEN\ IF\ ADVISED\ OF\ THE\ POSSIBILITY\ OF\ SUCH\ DAMAGES. +\f[] +.fi +.SS miniz (https://github.com/richgel999/miniz) +.RS +.PP +Public Domain/MIT +License (https://github.com/richgel999/miniz/blob/master/LICENSE) +.RE +.IP +.nf +\f[C] +This\ is\ free\ and\ unencumbered\ software\ released\ into\ the\ public\ domain. + +Anyone\ is\ free\ to\ copy,\ modify,\ publish,\ use,\ compile,\ sell,\ or +distribute\ this\ software,\ either\ in\ source\ code\ form\ or\ as\ a\ compiled +binary,\ for\ any\ purpose,\ commercial\ or\ non\-commercial,\ and\ by\ any +means. + +In\ jurisdictions\ that\ recognize\ copyright\ laws,\ the\ author\ or\ authors +of\ this\ software\ dedicate\ any\ and\ all\ copyright\ interest\ in\ the +software\ to\ the\ public\ domain.\ We\ make\ this\ dedication\ for\ the\ benefit +of\ the\ public\ at\ large\ and\ to\ the\ detriment\ of\ our\ heirs\ and +successors.\ We\ intend\ this\ dedication\ to\ be\ an\ overt\ act\ of +relinquishment\ in\ perpetuity\ of\ all\ present\ and\ future\ rights\ to\ this +software\ under\ copyright\ law. + +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\ BE\ LIABLE\ FOR\ ANY\ CLAIM,\ DAMAGES\ OR +OTHER\ LIABILITY,\ WHETHER\ IN\ AN\ ACTION\ OF\ CONTRACT,\ TORT\ OR\ OTHERWISE, +ARISING\ FROM,\ OUT\ OF\ OR\ IN\ CONNECTION\ WITH\ THE\ SOFTWARE\ OR\ THE\ USE\ OR +OTHER\ DEALINGS\ IN\ THE\ SOFTWARE. + +For\ more\ information,\ please\ refer\ to\ + +Copyright\ 2013\-2014\ RAD\ Game\ Tools\ and\ Valve\ Software +Copyright\ 2010\-2014\ Rich\ Geldreich\ and\ Tenacious\ Software\ LLC +All\ Rights\ Reserved. + +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,\ ARISING\ FROM, +OUT\ OF\ OR\ IN\ CONNECTION\ WITH\ THE\ SOFTWARE\ OR\ THE\ USE\ OR\ OTHER\ DEALINGS\ IN +THE\ SOFTWARE. +\f[] +.fi diff --git a/libs/EXTERNAL/xlnt/include/xlnt/cell/cell.hpp b/libs/EXTERNAL/xlnt/include/xlnt/cell/cell.hpp new file mode 100644 index 00000000000..5fcda9b5a22 --- /dev/null +++ b/libs/EXTERNAL/xlnt/include/xlnt/cell/cell.hpp @@ -0,0 +1,712 @@ +// Copyright (c) 2014-2021 Thomas Fussell +// 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, ARISING 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 +#include +#include + +#include +#include +#include +#include + +namespace xlnt { + +enum class calendar; + +class alignment; +class base_format; +class border; +class cell_reference; +class comment; +class fill; +class font; +class format; +class number_format; +class protection; +class range; +class relationship; +class style; +class workbook; +class worksheet; +class xlsx_consumer; +class xlsx_producer; +class phonetic_pr; + +struct date; +struct datetime; +struct time; +struct timedelta; + +namespace detail { + +class xlsx_consumer; +class xlsx_producer; + +struct cell_impl; + +} // namespace detail + +/// +/// Describes a unit of data in a worksheet at a specific coordinate and its +/// associated properties. +/// +/// +/// Properties of interest include style, type, value, and address. +/// The Cell class is required to know its value and type, display options, +/// and any other features of an Excel cell.Utilities for referencing +/// cells using Excel's 'A1' column/row nomenclature are also provided. +/// +class XLNT_API cell +{ +public: + /// + /// Alias xlnt::cell_type to xlnt::cell::type since it looks nicer. + /// + using type = cell_type; + + /// + /// Returns a map of error strings such as \#DIV/0! and their associated indices. + /// + static const std::unordered_map &error_codes(); + + /// + /// Default copy constructor. + /// + cell(const cell &) = default; + + // value + + /// + /// Returns true if value has been set and has not been cleared using cell::clear_value(). + /// + bool has_value() const; + + /// + /// Returns the value of this cell as an instance of type T. + /// Overloads exist for most C++ fundamental types like bool, int, etc. as well + /// as for std::string and xlnt datetime types: date, time, datetime, and timedelta. + /// + template + T value() const; + + /// + /// Makes this cell have a value of type null. + /// All other cell attributes are retained. + /// + void clear_value(); + + /// + /// Sets the type of this cell to null. + /// + void value(std::nullptr_t); + + /// + /// Sets the value of this cell to the given boolean value. + /// + void value(bool boolean_value); + + /// + /// Sets the value of this cell to the given value. + /// + void value(int int_value); + + /// + /// Sets the value of this cell to the given value. + /// + void value(unsigned int int_value); + + /// + /// Sets the value of this cell to the given value. + /// + void value(long long int int_value); + + /// + /// Sets the value of this cell to the given value. + /// + void value(unsigned long long int int_value); + + /// + /// Sets the value of this cell to the given value. + /// + void value(float float_value); + + /// + /// Sets the value of this cell to the given value. + /// + void value(double float_value); + + /// + /// Sets the value of this cell to the given value. + /// + void value(const date &date_value); + + /// + /// Sets the value of this cell to the given value. + /// + void value(const time &time_value); + + /// + /// Sets the value of this cell to the given value. + /// + void value(const datetime &datetime_value); + + /// + /// Sets the value of this cell to the given value. + /// + void value(const timedelta &timedelta_value); + + /// + /// Sets the value of this cell to the given value. + /// + void value(const std::string &string_value); + + /// + /// Sets the value of this cell to the given value. + /// + void value(const char *string_value); + + /// + /// Sets the value of this cell to the given value. + /// + void value(const rich_text &text_value); + + /// + /// Sets the value and formatting of this cell to that of other_cell. + /// + void value(const cell other_cell); + + /// + /// Analyzes string_value to determine its type, convert it to that type, + /// and set the value of this cell to that converted value. + /// + void value(const std::string &string_value, bool infer_type); + + /// + /// Returns the type of this cell. + /// + type data_type() const; + + /// + /// Sets the type of this cell. This should usually be done indirectly + /// by setting the value of the cell to a value of that type. + /// + void data_type(type t); + + // properties + + /// + /// There's no reason to keep a cell which has no value and is not a placeholder. + /// Returns true if this cell has no value, style, isn't merged, etc. + /// + bool garbage_collectible() const; + + /// + /// Returns true iff this cell's number format matches a date format. + /// + bool is_date() const; + + // position + + /// + /// Returns a cell_reference that points to the location of this cell. + /// + cell_reference reference() const; + + /// + /// Returns the column of this cell. + /// + column_t column() const; + + /// + /// Returns the numeric index (A == 1) of the column of this cell. + /// + column_t::index_t column_index() const; + + /// + /// Returns the row of this cell. + /// + row_t row() const; + + /// + /// Returns the location of this cell as an ordered pair (left, top). + /// + std::pair anchor() const; + + // hyperlink + + /// + /// Returns the relationship of this cell's hyperlink. + /// + class hyperlink hyperlink() const; + + /// + /// Adds a hyperlink to this cell pointing to the URI of the given value and sets + /// the text value of the cell to the given parameter. + /// + void hyperlink(const std::string &url, const std::string &display = ""); + + /// + /// Adds an internal hyperlink to this cell pointing to the given cell. + /// + void hyperlink(xlnt::cell target, const std::string &display = ""); + + /// + /// Adds an internal hyperlink to this cell pointing to the given range. + /// + void hyperlink(xlnt::range target, const std::string &display = ""); + + /// + /// Returns true if this cell has a hyperlink set. + /// + bool has_hyperlink() const; + + // computed formatting + + /// + /// Returns the alignment that should be used when displaying this cell + /// graphically based on the workbook default, the cell-level format, + /// and the named style applied to the cell in that order. + /// + class alignment computed_alignment() const; + + /// + /// Returns the border that should be used when displaying this cell + /// graphically based on the workbook default, the cell-level format, + /// and the named style applied to the cell in that order. + /// + class border computed_border() const; + + /// + /// Returns the fill that should be used when displaying this cell + /// graphically based on the workbook default, the cell-level format, + /// and the named style applied to the cell in that order. + /// + class fill computed_fill() const; + + /// + /// Returns the font that should be used when displaying this cell + /// graphically based on the workbook default, the cell-level format, + /// and the named style applied to the cell in that order. + /// + class font computed_font() const; + + /// + /// Returns the number format that should be used when displaying this cell + /// graphically based on the workbook default, the cell-level format, + /// and the named style applied to the cell in that order. + /// + class number_format computed_number_format() const; + + /// + /// Returns the protection that should be used when displaying this cell + /// graphically based on the workbook default, the cell-level format, + /// and the named style applied to the cell in that order. + /// + class protection computed_protection() const; + + // format + + /// + /// Returns true if this cell has had a format applied to it. + /// + bool has_format() const; + + /// + /// Returns the format applied to this cell. If this cell has no + /// format, an invalid_attribute exception will be thrown. + /// + const class format format() const; + + /// + /// Applies the cell-level formatting of new_format to this cell. + /// + void format(const class format new_format); + + /// + /// Removes the cell-level formatting from this cell. + /// This doesn't affect the style that may also be applied to the cell. + /// Throws an invalid_attribute exception if no format is applied. + /// + void clear_format(); + + /// + /// Returns the number format of this cell. + /// + class number_format number_format() const; + + /// + /// Creates a new format in the workbook, sets its number_format + /// to the given format, and applies the format to this cell. + /// + void number_format(const class number_format &format); + + /// + /// Returns the font applied to the text in this cell. + /// + class font font() const; + + /// + /// Creates a new format in the workbook, sets its font + /// to the given font, and applies the format to this cell. + /// + void font(const class font &font_); + + /// + /// Returns the fill applied to this cell. + /// + class fill fill() const; + + /// + /// Creates a new format in the workbook, sets its fill + /// to the given fill, and applies the format to this cell. + /// + void fill(const class fill &fill_); + + /// + /// Returns the border of this cell. + /// + class border border() const; + + /// + /// Creates a new format in the workbook, sets its border + /// to the given border, and applies the format to this cell. + /// + void border(const class border &border_); + + /// + /// Returns the alignment of the text in this cell. + /// + class alignment alignment() const; + + /// + /// Creates a new format in the workbook, sets its alignment + /// to the given alignment, and applies the format to this cell. + /// + void alignment(const class alignment &alignment_); + + /// + /// Returns the protection of this cell. + /// + class protection protection() const; + + /// + /// Creates a new format in the workbook, sets its protection + /// to the given protection, and applies the format to this cell. + /// + void protection(const class protection &protection_); + + // style + + /// + /// Returns true if this cell has had a style applied to it. + /// + bool has_style() const; + + /// + /// Returns a wrapper pointing to the named style applied to this cell. + /// + class style style(); + + /// + /// Returns a wrapper pointing to the named style applied to this cell. + /// + const class style style() const; + + /// + /// Sets the named style applied to this cell to a style named style_name. + /// Equivalent to style(new_style.name()). + /// + void style(const class style &new_style); + + /// + /// Sets the named style applied to this cell to a style named style_name. + /// If this style has not been previously created in the workbook, a + /// key_not_found exception will be thrown. + /// + void style(const std::string &style_name); + + /// + /// Removes the named style from this cell. + /// An invalid_attribute exception will be thrown if this cell has no style. + /// This will not affect the cell format of the cell. + /// + void clear_style(); + + // formula + + /// + /// Returns the string representation of the formula applied to this cell. + /// + std::string formula() const; + + /// + /// Sets the formula of this cell to the given value. + /// This formula string should begin with '='. + /// + void formula(const std::string &formula); + + /// + /// Removes the formula from this cell. After this is called, has_formula() will return false. + /// + void clear_formula(); + + /// + /// Returns true if this cell has had a formula applied to it. + /// + bool has_formula() const; + + // printing + + /// + /// Returns a string representing the value of this cell. If the data type is not a string, + /// it will be converted according to the number format. + /// + std::string to_string() const; + + // merging + + /// + /// Returns true iff this cell has been merged with one or more + /// surrounding cells. + /// + bool is_merged() const; + + /// + /// Makes this a merged cell iff merged is true. + /// Generally, this shouldn't be called directly. Instead, + /// use worksheet::merge_cells on its parent worksheet. + /// + void merged(bool merged); + + // phonetics + + /// + /// Returns true if this cell is set to show phonetic information. + /// + bool phonetics_visible() const; + + /// + /// Enables the display of phonetic information on this cell. + /// + void show_phonetics(bool phonetics); + + /// + /// Returns the error string that is stored in this cell. + /// + std::string error() const; + + /// + /// Directly assigns the value of this cell to be the given error. + /// + void error(const std::string &error); + + /// + /// Returns a cell from this cell's parent workbook at + /// a relative offset given by the parameters. + /// + cell offset(int column, int row); + + /// + /// Returns the worksheet that owns this cell. + /// + class worksheet worksheet(); + + /// + /// Returns the worksheet that owns this cell. + /// + const class worksheet worksheet() const; + + /// + /// Returns the workbook of the worksheet that owns this cell. + /// + class workbook &workbook(); + + /// + /// Returns the workbook of the worksheet that owns this cell. + /// + const class workbook &workbook() const; + + /// + /// Returns the base date of the parent workbook. + /// + calendar base_date() const; + + /// + /// Returns to_check after verifying and fixing encoding, size, and illegal characters. + /// + std::string check_string(const std::string &to_check); + + // comment + + /// + /// Returns true if this cell has a comment applied. + /// + bool has_comment(); + + /// + /// Deletes the comment applied to this cell if it exists. + /// + void clear_comment(); + + /// + /// Gets the comment applied to this cell. + /// + class comment comment(); + + /// + /// Creates a new comment with the given text and optional author and + /// applies it to the cell. + /// + void comment(const std::string &text, + const std::string &author = "Microsoft Office User"); + + /// + /// Creates a new comment with the given text, formatting, and optional + /// author and applies it to the cell. + /// + void comment(const std::string &comment_text, + const class font &comment_font, + const std::string &author = "Microsoft Office User"); + + /// + /// Apply the comment provided as the only argument to the cell. + /// + void comment(const class comment &new_comment); + + /// + /// Returns the width of this cell in pixels. + /// + double width() const; + + /// + /// Returns the height of this cell in pixels. + /// + double height() const; + + // operators + + /// + /// Makes this cell interally point to rhs. + /// The cell data originally pointed to by this cell will be unchanged. + /// + cell &operator=(const cell &rhs); + + /// + /// Returns true if this cell the same cell as comparand (compared by reference). + /// + bool operator==(const cell &comparand) const; + + /// + /// Returns false if this cell the same cell as comparand (compared by reference). + /// + bool operator!=(const cell &comparand) const; + +private: + friend class style; + friend class worksheet; + friend class detail::xlsx_consumer; + friend class detail::xlsx_producer; + friend struct detail::cell_impl; + + /// + /// Returns a non-const reference to the format of this cell. + /// This is for internal use only. + /// + class format modifiable_format(); + + /// + /// Delete the default zero-argument constructor. + /// + cell() = delete; + + /// + /// Private constructor to create a cell from its implementation. + /// + cell(detail::cell_impl *d); + + /// + /// A pointer to this cell's implementation. + /// + detail::cell_impl *d_; +}; + +/// +/// Returns true if this cell is uninitialized. +/// +XLNT_API bool operator==(std::nullptr_t, const cell &cell); + +/// +/// Returns true if this cell is uninitialized. +/// +XLNT_API bool operator==(const cell &cell, std::nullptr_t); + +/// +/// Convenience function for writing cell to an ostream. +/// Uses cell::to_string() internally. +/// +XLNT_API std::ostream &operator<<(std::ostream &stream, const xlnt::cell &cell); + +template <> +bool cell::value() const; + +template <> +int cell::value() const; + +template <> +unsigned int cell::value() const; + +template <> +long long int cell::value() const; + +template <> +unsigned long long cell::value() const; + +template <> +float cell::value() const; + +template <> +double cell::value() const; + +template <> +date cell::value() const; + +template <> +time cell::value