react-native-nitro-xlsx 0.2.5 → 0.2.7
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/NitroXlsx.podspec +26 -27
- package/Package.swift +31 -10
- package/README.md +21 -9
- package/android/CMakeLists.txt +20 -27
- package/cpp/HybridNitroXlsx.cpp +25 -1
- package/cpp/HybridXlsxCellFormat.cpp +46 -146
- package/cpp/HybridXlsxCellFormat.hpp +9 -41
- package/cpp/HybridXlsxConditionalFormat.cpp +4 -1
- package/cpp/HybridXlsxConditionalFormats.cpp +5 -1
- package/cpp/HybridXlsxWorkbook.cpp +38 -8
- package/cpp/HybridXlsxWorkbook.hpp +10 -1
- package/cpp/HybridXlsxWorksheet.cpp +422 -141
- package/cpp/HybridXlsxWorksheet.hpp +4 -1
- package/cpp/XlsxCacheDir.cpp +25 -2
- package/cpp/XlsxCacheDir.hpp +3 -1
- package/cpp/XlsxCellStyle.hpp +360 -0
- package/cpp/XlsxJson.cpp +29 -8
- package/package.json +2 -2
- package/scripts/run-cpp-tests.sh +1 -1
- package/scripts/sync-openxlsx-headers.sh +34 -0
- package/src/__mocks__/react-native-nitro-modules.ts +523 -20
- package/src/__tests__/index.test.ts +124 -16
- package/src/index.ts +13 -13
- package/thirdparty/OpenXLSX/.clang-format +118 -0
- package/thirdparty/OpenXLSX/.clang-tidy +28 -0
- package/thirdparty/OpenXLSX/.gitignore +130 -0
- package/thirdparty/OpenXLSX/Benchmarks/2024-07-29-benchmarks_before_XMLNode_wrappers +46 -0
- package/thirdparty/OpenXLSX/Benchmarks/2024-07-29-benchmarks_with_XMLNode_wrappers_and_namespace_and_stripping +49 -0
- package/thirdparty/OpenXLSX/Benchmarks/2024-07-29-benchmarks_with_XMLNode_wrappers_and_namespace_char_support +49 -0
- package/thirdparty/OpenXLSX/Benchmarks/2024-07-29-benchmarks_with_XMLNode_wrappers_and_namespace_support +49 -0
- package/thirdparty/OpenXLSX/Benchmarks/2024-07-29-benchmarks_with_XMLNode_wrappers_and_namespaced_name_disabled +49 -0
- package/thirdparty/OpenXLSX/Benchmarks/2024-08-11-benchmarks_post-XLCellIterator-Rework +46 -0
- package/thirdparty/OpenXLSX/Benchmarks/2024-08-14-benchmarks_post-default-row-column-style-support +46 -0
- package/thirdparty/OpenXLSX/Benchmarks/2024-09-02-benchmarks +46 -0
- package/thirdparty/OpenXLSX/Benchmarks/2024-12-19-benchmarks +46 -0
- package/thirdparty/OpenXLSX/Benchmarks/2024-12-30-benchmarks-post-XLSharedStrings-by-ref +46 -0
- package/thirdparty/OpenXLSX/Benchmarks/2025-01-09-benchmarks-post-conditionalFormatsAndSheetProtection +46 -0
- package/thirdparty/OpenXLSX/Benchmarks/2025-01-10-benchmarks-post-XLCellValue-bugfix +46 -0
- package/thirdparty/OpenXLSX/Benchmarks/2025-01-31-benchmarks-post-XLComments-implementation +46 -0
- package/thirdparty/OpenXLSX/Benchmarks/2025-02-02-benchmarks-post-XLRowIterator-Rework +46 -0
- package/thirdparty/OpenXLSX/Benchmarks/2025-07-20-benchmarks-after-hiding-pugixml-internals +46 -0
- package/thirdparty/OpenXLSX/Benchmarks/2025-08-29-benchmarks-after-code-review-with-libzip +46 -0
- package/thirdparty/OpenXLSX/Benchmarks/Benchmark.cpp +249 -0
- package/thirdparty/OpenXLSX/Benchmarks/CMakeLists.txt +19 -0
- package/thirdparty/OpenXLSX/CMakeLists.txt +466 -0
- package/thirdparty/OpenXLSX/Documentation/CMakeLists.txt +31 -0
- package/thirdparty/OpenXLSX/Documentation/Doxyfile.in +2471 -0
- package/thirdparty/OpenXLSX/Documentation/DoxygenLayout.xml +194 -0
- package/thirdparty/OpenXLSX/Documentation/customdoxygen.css +1355 -0
- package/thirdparty/OpenXLSX/Examples/CMakeLists.txt +103 -0
- package/thirdparty/OpenXLSX/Examples/Demo1.cpp +279 -0
- package/thirdparty/OpenXLSX/Examples/Demo10.cpp +545 -0
- package/thirdparty/OpenXLSX/Examples/Demo1A.cpp +137 -0
- package/thirdparty/OpenXLSX/Examples/Demo2.cpp +65 -0
- package/thirdparty/OpenXLSX/Examples/Demo3.cpp +89 -0
- package/thirdparty/OpenXLSX/Examples/Demo4.cpp +86 -0
- package/thirdparty/OpenXLSX/Examples/Demo5.cpp +77 -0
- package/thirdparty/OpenXLSX/Examples/Demo6.cpp +103 -0
- package/thirdparty/OpenXLSX/Examples/Demo7.cpp +79 -0
- package/thirdparty/OpenXLSX/Examples/Demo8.cpp +117 -0
- package/thirdparty/OpenXLSX/Examples/Demo9.cpp +363 -0
- package/thirdparty/OpenXLSX/Examples/cmake/FindLIBZIP.cmake +61 -0
- package/thirdparty/OpenXLSX/Examples/external/CustomZip/CustomZip.hpp +256 -0
- package/thirdparty/OpenXLSX/LICENSE.md +29 -0
- package/thirdparty/OpenXLSX/Makefile.GNU +530 -0
- package/thirdparty/OpenXLSX/Notes/TBDs.txt +16 -0
- package/thirdparty/OpenXLSX/Notes/confirmed-TBCs.txt +8 -0
- package/thirdparty/OpenXLSX/Notes/styles-missing-support.xml +12 -0
- package/thirdparty/OpenXLSX/Notes/todo-list.txt +108 -0
- package/thirdparty/OpenXLSX/OpenXLSX/CMakeLists.txt +631 -0
- package/thirdparty/OpenXLSX/OpenXLSX/OpenXLSX.hpp +63 -0
- package/thirdparty/OpenXLSX/OpenXLSX/OpenXLSXConfig.cmake +11 -0
- package/thirdparty/OpenXLSX/OpenXLSX/cmake/bundle_static_library.cmake +198 -0
- package/thirdparty/OpenXLSX/OpenXLSX/cmake/patch_pkg_config.cmake +69 -0
- package/thirdparty/OpenXLSX/OpenXLSX/headers/IZipArchive.hpp +361 -0
- package/thirdparty/OpenXLSX/OpenXLSX/headers/OpenXLSX/IZipArchive.hpp +361 -0
- package/thirdparty/OpenXLSX/OpenXLSX/headers/OpenXLSX/OpenXLSX-Exports.hpp +12 -0
- package/thirdparty/OpenXLSX/OpenXLSX/headers/OpenXLSX/XLCell.hpp +367 -0
- package/thirdparty/OpenXLSX/OpenXLSX/headers/OpenXLSX/XLCellIterator.hpp +252 -0
- package/thirdparty/OpenXLSX/OpenXLSX/headers/OpenXLSX/XLCellRange.hpp +223 -0
- package/thirdparty/OpenXLSX/OpenXLSX/headers/OpenXLSX/XLCellReference.hpp +317 -0
- package/thirdparty/OpenXLSX/OpenXLSX/headers/OpenXLSX/XLCellValue.hpp +793 -0
- package/thirdparty/OpenXLSX/OpenXLSX/headers/OpenXLSX/XLColor.hpp +232 -0
- package/thirdparty/OpenXLSX/OpenXLSX/headers/OpenXLSX/XLColumn.hpp +159 -0
- package/thirdparty/OpenXLSX/OpenXLSX/headers/OpenXLSX/XLCommandQuery.hpp +228 -0
- package/thirdparty/OpenXLSX/OpenXLSX/headers/OpenXLSX/XLComments.hpp +270 -0
- package/thirdparty/OpenXLSX/OpenXLSX/headers/OpenXLSX/XLConstants.hpp +18 -0
- package/thirdparty/OpenXLSX/OpenXLSX/headers/OpenXLSX/XLContentTypes.hpp +264 -0
- package/thirdparty/OpenXLSX/OpenXLSX/headers/OpenXLSX/XLDateTime.hpp +175 -0
- package/thirdparty/OpenXLSX/OpenXLSX/headers/OpenXLSX/XLDocument.hpp +505 -0
- package/thirdparty/OpenXLSX/OpenXLSX/headers/OpenXLSX/XLDrawing.hpp +452 -0
- package/thirdparty/OpenXLSX/OpenXLSX/headers/OpenXLSX/XLException.hpp +161 -0
- package/thirdparty/OpenXLSX/OpenXLSX/headers/OpenXLSX/XLFormula.hpp +375 -0
- package/thirdparty/OpenXLSX/OpenXLSX/headers/OpenXLSX/XLIterator.hpp +40 -0
- package/thirdparty/OpenXLSX/OpenXLSX/headers/OpenXLSX/XLMergeCells.hpp +216 -0
- package/thirdparty/OpenXLSX/OpenXLSX/headers/OpenXLSX/XLProperties.hpp +348 -0
- package/thirdparty/OpenXLSX/OpenXLSX/headers/OpenXLSX/XLRelationships.hpp +348 -0
- package/thirdparty/OpenXLSX/OpenXLSX/headers/OpenXLSX/XLRow.hpp +721 -0
- package/thirdparty/OpenXLSX/OpenXLSX/headers/OpenXLSX/XLRowData.hpp +488 -0
- package/thirdparty/OpenXLSX/OpenXLSX/headers/OpenXLSX/XLSharedStrings.hpp +204 -0
- package/thirdparty/OpenXLSX/OpenXLSX/headers/OpenXLSX/XLSheet.hpp +1640 -0
- package/thirdparty/OpenXLSX/OpenXLSX/headers/OpenXLSX/XLStyles.hpp +2390 -0
- package/thirdparty/OpenXLSX/OpenXLSX/headers/OpenXLSX/XLTables.hpp +132 -0
- package/thirdparty/OpenXLSX/OpenXLSX/headers/OpenXLSX/XLWorkbook.hpp +404 -0
- package/thirdparty/OpenXLSX/OpenXLSX/headers/OpenXLSX/XLXmlData.hpp +283 -0
- package/thirdparty/OpenXLSX/OpenXLSX/headers/OpenXLSX/XLXmlFile.hpp +194 -0
- package/thirdparty/OpenXLSX/OpenXLSX/headers/OpenXLSX/XLXmlParser.hpp +282 -0
- package/thirdparty/OpenXLSX/OpenXLSX/headers/OpenXLSX/XLXmlParserForwardDeclarations.hpp +85 -0
- package/thirdparty/OpenXLSX/OpenXLSX/headers/OpenXLSX/XLZipArchive.hpp +232 -0
- package/thirdparty/OpenXLSX/OpenXLSX/headers/OpenXLSX/detail/LibZip.hpp +447 -0
- package/thirdparty/OpenXLSX/OpenXLSX/headers/OpenXLSX/detail/OpenXLSXFileSystemTools.hpp +207 -0
- package/thirdparty/OpenXLSX/OpenXLSX/headers/OpenXLSX/detail/Zippy.hpp +1375 -0
- package/thirdparty/OpenXLSX/OpenXLSX/headers/OpenXLSX-Exports.hpp +12 -0
- package/thirdparty/OpenXLSX/OpenXLSX/headers/XLCell.hpp +367 -0
- package/thirdparty/OpenXLSX/OpenXLSX/headers/XLCellIterator.hpp +252 -0
- package/thirdparty/OpenXLSX/OpenXLSX/headers/XLCellRange.hpp +223 -0
- package/thirdparty/OpenXLSX/OpenXLSX/headers/XLCellReference.hpp +317 -0
- package/thirdparty/OpenXLSX/OpenXLSX/headers/XLCellValue.hpp +793 -0
- package/thirdparty/OpenXLSX/OpenXLSX/headers/XLColor.hpp +232 -0
- package/thirdparty/OpenXLSX/OpenXLSX/headers/XLColumn.hpp +159 -0
- package/thirdparty/OpenXLSX/OpenXLSX/headers/XLCommandQuery.hpp +228 -0
- package/thirdparty/OpenXLSX/OpenXLSX/headers/XLComments.hpp +270 -0
- package/thirdparty/OpenXLSX/OpenXLSX/headers/XLConstants.hpp +18 -0
- package/thirdparty/OpenXLSX/OpenXLSX/headers/XLContentTypes.hpp +264 -0
- package/thirdparty/OpenXLSX/OpenXLSX/headers/XLDateTime.hpp +175 -0
- package/thirdparty/OpenXLSX/OpenXLSX/headers/XLDocument.hpp +505 -0
- package/thirdparty/OpenXLSX/OpenXLSX/headers/XLDrawing.hpp +452 -0
- package/thirdparty/OpenXLSX/OpenXLSX/headers/XLException.hpp +161 -0
- package/thirdparty/OpenXLSX/OpenXLSX/headers/XLFormula.hpp +375 -0
- package/thirdparty/OpenXLSX/OpenXLSX/headers/XLIterator.hpp +40 -0
- package/thirdparty/OpenXLSX/OpenXLSX/headers/XLMergeCells.hpp +216 -0
- package/thirdparty/OpenXLSX/OpenXLSX/headers/XLProperties.hpp +348 -0
- package/thirdparty/OpenXLSX/OpenXLSX/headers/XLRelationships.hpp +348 -0
- package/thirdparty/OpenXLSX/OpenXLSX/headers/XLRow.hpp +721 -0
- package/thirdparty/OpenXLSX/OpenXLSX/headers/XLRowData.hpp +488 -0
- package/thirdparty/OpenXLSX/OpenXLSX/headers/XLSharedStrings.hpp +204 -0
- package/thirdparty/OpenXLSX/OpenXLSX/headers/XLSheet.hpp +1640 -0
- package/thirdparty/OpenXLSX/OpenXLSX/headers/XLStyles.hpp +2390 -0
- package/thirdparty/OpenXLSX/OpenXLSX/headers/XLTables.hpp +132 -0
- package/thirdparty/OpenXLSX/OpenXLSX/headers/XLWorkbook.hpp +404 -0
- package/thirdparty/OpenXLSX/OpenXLSX/headers/XLXmlData.hpp +283 -0
- package/thirdparty/OpenXLSX/OpenXLSX/headers/XLXmlFile.hpp +194 -0
- package/thirdparty/OpenXLSX/OpenXLSX/headers/XLXmlParser.hpp +282 -0
- package/thirdparty/OpenXLSX/OpenXLSX/headers/XLXmlParserForwardDeclarations.hpp +85 -0
- package/thirdparty/OpenXLSX/OpenXLSX/headers/XLZipArchive.hpp +232 -0
- package/thirdparty/OpenXLSX/OpenXLSX/headers/detail/LibZip.hpp +447 -0
- package/thirdparty/OpenXLSX/OpenXLSX/headers/detail/OpenXLSXFileSystemTools.hpp +207 -0
- package/thirdparty/OpenXLSX/OpenXLSX/headers/detail/Zippy.hpp +1375 -0
- package/thirdparty/OpenXLSX/OpenXLSX/sources/XLCell.cpp +340 -0
- package/thirdparty/OpenXLSX/OpenXLSX/sources/XLCellIterator.cpp +427 -0
- package/thirdparty/OpenXLSX/OpenXLSX/sources/XLCellRange.cpp +221 -0
- package/thirdparty/OpenXLSX/OpenXLSX/sources/XLCellReference.cpp +408 -0
- package/thirdparty/OpenXLSX/OpenXLSX/sources/XLCellValue.cpp +519 -0
- package/thirdparty/OpenXLSX/OpenXLSX/sources/XLColor.cpp +202 -0
- package/thirdparty/OpenXLSX/OpenXLSX/sources/XLColumn.cpp +141 -0
- package/thirdparty/OpenXLSX/OpenXLSX/sources/XLComments.cpp +637 -0
- package/thirdparty/OpenXLSX/OpenXLSX/sources/XLContentTypes.cpp +329 -0
- package/thirdparty/OpenXLSX/OpenXLSX/sources/XLDateTime.cpp +269 -0
- package/thirdparty/OpenXLSX/OpenXLSX/sources/XLDocument.cpp +1678 -0
- package/thirdparty/OpenXLSX/OpenXLSX/sources/XLDrawing.cpp +784 -0
- package/thirdparty/OpenXLSX/OpenXLSX/sources/XLFormula.cpp +201 -0
- package/thirdparty/OpenXLSX/OpenXLSX/sources/XLMergeCells.cpp +357 -0
- package/thirdparty/OpenXLSX/OpenXLSX/sources/XLProperties.cpp +810 -0
- package/thirdparty/OpenXLSX/OpenXLSX/sources/XLRelationships.cpp +529 -0
- package/thirdparty/OpenXLSX/OpenXLSX/sources/XLRow.cpp +918 -0
- package/thirdparty/OpenXLSX/OpenXLSX/sources/XLRowData.cpp +508 -0
- package/thirdparty/OpenXLSX/OpenXLSX/sources/XLSharedStrings.cpp +220 -0
- package/thirdparty/OpenXLSX/OpenXLSX/sources/XLSheet.cpp +1970 -0
- package/thirdparty/OpenXLSX/OpenXLSX/sources/XLStyles.cpp +3014 -0
- package/thirdparty/OpenXLSX/OpenXLSX/sources/XLTables.cpp +125 -0
- package/thirdparty/OpenXLSX/OpenXLSX/sources/XLWorkbook.cpp +784 -0
- package/thirdparty/OpenXLSX/OpenXLSX/sources/XLXmlData.cpp +247 -0
- package/thirdparty/OpenXLSX/OpenXLSX/sources/XLXmlFile.cpp +160 -0
- package/thirdparty/OpenXLSX/OpenXLSX/sources/XLXmlParser.cpp +261 -0
- package/thirdparty/OpenXLSX/OpenXLSX/sources/XLZipArchive.cpp +266 -0
- package/thirdparty/OpenXLSX/OpenXLSX/sources/utilities/XLUtilities.hpp +478 -0
- package/thirdparty/OpenXLSX/README.md +1279 -0
- package/thirdparty/OpenXLSX/Scripts/cmake-cleanup.sh +102 -0
- package/thirdparty/OpenXLSX/Scripts/compile.sh +23 -0
- package/thirdparty/OpenXLSX/Scripts/demos-cleanup.sh +25 -0
- package/thirdparty/OpenXLSX/Scripts/demos-run-all.sh +60 -0
- package/thirdparty/OpenXLSX/Scripts/guarded-xml-format.sh +47 -0
- package/thirdparty/OpenXLSX/Scripts/make-gnu.sh +11 -0
- package/thirdparty/OpenXLSX/Scripts/uninstall-manifest.sh +48 -0
- package/thirdparty/OpenXLSX/Scripts/xml-format-all.sh +19 -0
- package/thirdparty/OpenXLSX/Scripts/xml-format.sh +38 -0
- package/thirdparty/OpenXLSX/Tests/CMakeLists.txt +37 -0
- package/thirdparty/OpenXLSX/Tests/catch/catch.hpp +17799 -0
- package/thirdparty/OpenXLSX/Tests/catch/catch_reporter_automake.hpp +68 -0
- package/thirdparty/OpenXLSX/Tests/catch/catch_reporter_sonarqube.hpp +182 -0
- package/thirdparty/OpenXLSX/Tests/catch/catch_reporter_tap.hpp +278 -0
- package/thirdparty/OpenXLSX/Tests/catch/catch_reporter_teamcity.hpp +212 -0
- package/thirdparty/OpenXLSX/Tests/main.cpp +55 -0
- package/thirdparty/OpenXLSX/Tests/testXLCell.cpp +176 -0
- package/thirdparty/OpenXLSX/Tests/testXLCellRange.cpp +180 -0
- package/thirdparty/OpenXLSX/Tests/testXLCellReference.cpp +160 -0
- package/thirdparty/OpenXLSX/Tests/testXLCellValue.cpp +366 -0
- package/thirdparty/OpenXLSX/Tests/testXLCellValueProxy.cpp +255 -0
- package/thirdparty/OpenXLSX/Tests/testXLColor.cpp +75 -0
- package/thirdparty/OpenXLSX/Tests/testXLDateTime.cpp +229 -0
- package/thirdparty/OpenXLSX/Tests/testXLDocument.cpp +197 -0
- package/thirdparty/OpenXLSX/Tests/testXLFormula.cpp +131 -0
- package/thirdparty/OpenXLSX/Tests/testXLRow.cpp +597 -0
- package/thirdparty/OpenXLSX/Tests/testXLSheet.cpp +77 -0
- package/thirdparty/OpenXLSX/Tests/ziptest-with-libs.cpp +88 -0
- package/thirdparty/OpenXLSX/Tests/ziptest.cpp +735 -0
- package/thirdparty/OpenXLSX/cmake/get-git-HEAD-ID.cmake +45 -0
- package/thirdparty/OpenXLSX/cmake/libopenxlsxCPackOptions.cmake.in +20 -0
- package/thirdparty/OpenXLSX/cmake/manage_dependency.cmake +813 -0
- package/thirdparty/OpenXLSX/cmake/recursive_library_type_test.cmake +52 -0
- package/thirdparty/OpenXLSX/gnu-make-crutch/OpenXLSX-Exports-shared.hpp +42 -0
- package/thirdparty/OpenXLSX/gnu-make-crutch/OpenXLSX-Exports-static.hpp +42 -0
- package/thirdparty/OpenXLSX/vcpkg.json +24 -0
- package/thirdparty/README.md +46 -0
- package/thirdparty/miniz/.clang-format +47 -0
- package/thirdparty/miniz/.travis.yml +2 -0
- package/thirdparty/miniz/CMakeLists.txt +333 -0
- package/thirdparty/miniz/CMakePresets.json +31 -0
- package/thirdparty/miniz/ChangeLog.md +272 -0
- package/thirdparty/miniz/Config.cmake.in +1 -0
- package/thirdparty/miniz/LICENSE +22 -0
- package/thirdparty/miniz/amalgamate.sh +57 -0
- package/thirdparty/miniz/examples/example1.c +105 -0
- package/thirdparty/miniz/examples/example2.c +164 -0
- package/thirdparty/miniz/examples/example3.c +269 -0
- package/thirdparty/miniz/examples/example4.c +102 -0
- package/thirdparty/miniz/examples/example5.c +327 -0
- package/thirdparty/miniz/examples/example6.c +189 -0
- package/thirdparty/miniz/meson.build +21 -0
- package/thirdparty/miniz/miniz.c +646 -0
- package/thirdparty/miniz/miniz.h +615 -0
- package/thirdparty/miniz/miniz.pc.in +13 -0
- package/thirdparty/miniz/miniz_common.h +89 -0
- package/thirdparty/miniz/miniz_export.h +20 -0
- package/thirdparty/miniz/miniz_tdef.c +1602 -0
- package/thirdparty/miniz/miniz_tdef.h +199 -0
- package/thirdparty/miniz/miniz_tinfl.c +778 -0
- package/thirdparty/miniz/miniz_tinfl.h +150 -0
- package/thirdparty/miniz/miniz_zip.c +4895 -0
- package/thirdparty/miniz/miniz_zip.h +454 -0
- package/thirdparty/miniz/readme.md +46 -0
- package/thirdparty/miniz/test.sh +36 -0
- package/thirdparty/miniz/tests/add_in_place_fuzzer.c +87 -0
- package/thirdparty/miniz/tests/catch_amalgamated.cpp +10795 -0
- package/thirdparty/miniz/tests/catch_amalgamated.hpp +13143 -0
- package/thirdparty/miniz/tests/checksum_fuzzer.c +26 -0
- package/thirdparty/miniz/tests/compress_fuzzer.c +91 -0
- package/thirdparty/miniz/tests/flush_fuzzer.c +88 -0
- package/thirdparty/miniz/tests/fuzz_main.c +55 -0
- package/thirdparty/miniz/tests/large_fuzzer.c +133 -0
- package/thirdparty/miniz/tests/main.cpp +185 -0
- package/thirdparty/miniz/tests/miniz_tdefl_fuzzer.cc +115 -0
- package/thirdparty/miniz/tests/miniz_tester.cpp +1881 -0
- package/thirdparty/miniz/tests/miniz_zip_validate_fuzzer.cc +71 -0
- package/thirdparty/miniz/tests/miniz_zip_writer_fuzzer.cc +96 -0
- package/thirdparty/miniz/tests/ossfuzz.sh +48 -0
- package/thirdparty/miniz/tests/small_fuzzer.c +126 -0
- package/thirdparty/miniz/tests/timer.cpp +152 -0
- package/thirdparty/miniz/tests/timer.h +40 -0
- package/thirdparty/miniz/tests/uncompress2_fuzzer.c +21 -0
- package/thirdparty/miniz/tests/uncompress_fuzzer.c +30 -0
- package/thirdparty/miniz/tests/zip.dict +9 -0
- package/thirdparty/miniz/tests/zip_fuzzer.c +63 -0
- package/thirdparty/pugixml/.codecov.yml +7 -0
- package/thirdparty/pugixml/.gitattributes +1 -0
- package/thirdparty/pugixml/CMakeLists.txt +330 -0
- package/thirdparty/pugixml/LICENSE.md +24 -0
- package/thirdparty/pugixml/Makefile +98 -0
- package/thirdparty/pugixml/README.md +81 -0
- package/thirdparty/pugixml/SECURITY.md +9 -0
- package/thirdparty/pugixml/appveyor.yml +50 -0
- package/thirdparty/pugixml/docs/config.adoc +7 -0
- package/thirdparty/pugixml/docs/images/dom_tree.png +0 -0
- package/thirdparty/pugixml/docs/images/vs2005_link1.png +0 -0
- package/thirdparty/pugixml/docs/images/vs2005_link2.png +0 -0
- package/thirdparty/pugixml/docs/images/vs2005_pch1.png +0 -0
- package/thirdparty/pugixml/docs/images/vs2005_pch2.png +0 -0
- package/thirdparty/pugixml/docs/images/vs2005_pch3.png +0 -0
- package/thirdparty/pugixml/docs/images/vs2005_pch4.png +0 -0
- package/thirdparty/pugixml/docs/images/vs2010_link1.png +0 -0
- package/thirdparty/pugixml/docs/images/vs2010_link2.png +0 -0
- package/thirdparty/pugixml/docs/manual.adoc +3326 -0
- package/thirdparty/pugixml/docs/manual.html +6395 -0
- package/thirdparty/pugixml/docs/quickstart.adoc +287 -0
- package/thirdparty/pugixml/docs/quickstart.html +1107 -0
- package/thirdparty/pugixml/docs/samples/character.xml +8 -0
- package/thirdparty/pugixml/docs/samples/custom_memory_management.cpp +27 -0
- package/thirdparty/pugixml/docs/samples/include.cpp +64 -0
- package/thirdparty/pugixml/docs/samples/load_error_handling.cpp +33 -0
- package/thirdparty/pugixml/docs/samples/load_file.cpp +16 -0
- package/thirdparty/pugixml/docs/samples/load_memory.cpp +66 -0
- package/thirdparty/pugixml/docs/samples/load_options.cpp +30 -0
- package/thirdparty/pugixml/docs/samples/load_stream.cpp +97 -0
- package/thirdparty/pugixml/docs/samples/modify_add.cpp +29 -0
- package/thirdparty/pugixml/docs/samples/modify_base.cpp +43 -0
- package/thirdparty/pugixml/docs/samples/modify_remove.cpp +27 -0
- package/thirdparty/pugixml/docs/samples/save_custom_writer.cpp +116 -0
- package/thirdparty/pugixml/docs/samples/save_declaration.cpp +27 -0
- package/thirdparty/pugixml/docs/samples/save_file.cpp +17 -0
- package/thirdparty/pugixml/docs/samples/save_options.cpp +48 -0
- package/thirdparty/pugixml/docs/samples/save_stream.cpp +18 -0
- package/thirdparty/pugixml/docs/samples/save_subtree.cpp +26 -0
- package/thirdparty/pugixml/docs/samples/text.cpp +35 -0
- package/thirdparty/pugixml/docs/samples/transitions.xml +7 -0
- package/thirdparty/pugixml/docs/samples/traverse_base.cpp +51 -0
- package/thirdparty/pugixml/docs/samples/traverse_iter.cpp +27 -0
- package/thirdparty/pugixml/docs/samples/traverse_predicate.cpp +48 -0
- package/thirdparty/pugixml/docs/samples/traverse_rangefor.cpp +32 -0
- package/thirdparty/pugixml/docs/samples/traverse_walker.cpp +35 -0
- package/thirdparty/pugixml/docs/samples/tree.xml +12 -0
- package/thirdparty/pugixml/docs/samples/weekly-shift_jis.xml +78 -0
- package/thirdparty/pugixml/docs/samples/weekly-utf-16.xml +0 -0
- package/thirdparty/pugixml/docs/samples/weekly-utf-8.xml +78 -0
- package/thirdparty/pugixml/docs/samples/xgconsole.xml +12 -0
- package/thirdparty/pugixml/docs/samples/xpath_error.cpp +43 -0
- package/thirdparty/pugixml/docs/samples/xpath_query.cpp +36 -0
- package/thirdparty/pugixml/docs/samples/xpath_select.cpp +28 -0
- package/thirdparty/pugixml/docs/samples/xpath_variables.cpp +38 -0
- package/thirdparty/pugixml/readme.txt +50 -0
- package/thirdparty/pugixml/scripts/archive.py +54 -0
- package/thirdparty/pugixml/scripts/cocoapods_push.sh +4 -0
- package/thirdparty/pugixml/scripts/natvis/pugixml.natvis +77 -0
- package/thirdparty/pugixml/scripts/natvis/pugixml_compact.natvis +506 -0
- package/thirdparty/pugixml/scripts/nuget/build/native/pugixml-propertiesui.xml +17 -0
- package/thirdparty/pugixml/scripts/nuget/build/native/pugixml.targets +28 -0
- package/thirdparty/pugixml/scripts/nuget/pugixml.nuspec +20 -0
- package/thirdparty/pugixml/scripts/nuget_build.ps1 +60 -0
- package/thirdparty/pugixml/scripts/premake4.lua +92 -0
- package/thirdparty/pugixml/scripts/pugixml-config.cmake.in +12 -0
- package/thirdparty/pugixml/scripts/pugixml.pc.in +11 -0
- package/thirdparty/pugixml/scripts/pugixml.podspec +14 -0
- package/thirdparty/pugixml/scripts/pugixml.xcodeproj/project.pbxproj +212 -0
- package/thirdparty/pugixml/scripts/pugixml_airplay.mkf +13 -0
- package/thirdparty/pugixml/scripts/pugixml_codeblocks.cbp +44 -0
- package/thirdparty/pugixml/scripts/pugixml_codelite.project +56 -0
- package/thirdparty/pugixml/scripts/pugixml_dll.rc +45 -0
- package/thirdparty/pugixml/scripts/pugixml_vs2005.vcproj +343 -0
- package/thirdparty/pugixml/scripts/pugixml_vs2005_static.vcproj +343 -0
- package/thirdparty/pugixml/scripts/pugixml_vs2008.vcproj +339 -0
- package/thirdparty/pugixml/scripts/pugixml_vs2008_static.vcproj +339 -0
- package/thirdparty/pugixml/scripts/pugixml_vs2010.vcxproj +191 -0
- package/thirdparty/pugixml/scripts/pugixml_vs2010_static.vcxproj +191 -0
- package/thirdparty/pugixml/scripts/pugixml_vs2013.vcxproj +199 -0
- package/thirdparty/pugixml/scripts/pugixml_vs2013_static.vcxproj +199 -0
- package/thirdparty/pugixml/scripts/pugixml_vs2015.vcxproj +172 -0
- package/thirdparty/pugixml/scripts/pugixml_vs2015_static.vcxproj +176 -0
- package/thirdparty/pugixml/scripts/pugixml_vs2017.vcxproj +172 -0
- package/thirdparty/pugixml/scripts/pugixml_vs2017_static.vcxproj +176 -0
- package/thirdparty/pugixml/scripts/pugixml_vs2019.vcxproj +176 -0
- package/thirdparty/pugixml/scripts/pugixml_vs2019_static.vcxproj +180 -0
- package/thirdparty/pugixml/scripts/pugixml_vs2022.vcxproj +176 -0
- package/thirdparty/pugixml/scripts/pugixml_vs2022_static.vcxproj +180 -0
- package/thirdparty/pugixml/scripts/pugixml_vs2026.vcxproj +176 -0
- package/thirdparty/pugixml/scripts/pugixml_vs2026_static.vcxproj +180 -0
- package/thirdparty/pugixml/scripts/sbom.cdx.json +47 -0
- package/thirdparty/pugixml/src/pugiconfig.hpp +81 -0
- package/thirdparty/pugixml/src/pugixml.cpp +13776 -0
- package/thirdparty/pugixml/src/pugixml.hpp +1604 -0
- package/thirdparty/pugixml/tests/allocator.cpp +175 -0
- package/thirdparty/pugixml/tests/allocator.hpp +10 -0
- package/thirdparty/pugixml/tests/autotest-appveyor.ps1 +93 -0
- package/thirdparty/pugixml/tests/cmake-appveyor.ps1 +57 -0
- package/thirdparty/pugixml/tests/data/empty.xml +0 -0
- package/thirdparty/pugixml/tests/data/large.xml +1 -0
- package/thirdparty/pugixml/tests/data/latintest_latin1.xml +1 -0
- package/thirdparty/pugixml/tests/data/latintest_utf8.xml +1 -0
- package/thirdparty/pugixml/tests/data/multiline.xml +3 -0
- package/thirdparty/pugixml/tests/data/small.xml +1 -0
- package/thirdparty/pugixml/tests/data/truncation.xml +19 -0
- package/thirdparty/pugixml/tests/data/utftest_utf16_be.xml +0 -0
- package/thirdparty/pugixml/tests/data/utftest_utf16_be_bom.xml +0 -0
- package/thirdparty/pugixml/tests/data/utftest_utf16_be_clean.xml +0 -0
- package/thirdparty/pugixml/tests/data/utftest_utf16_be_nodecl.xml +0 -0
- package/thirdparty/pugixml/tests/data/utftest_utf16_le.xml +0 -0
- package/thirdparty/pugixml/tests/data/utftest_utf16_le_bom.xml +0 -0
- package/thirdparty/pugixml/tests/data/utftest_utf16_le_clean.xml +0 -0
- package/thirdparty/pugixml/tests/data/utftest_utf16_le_nodecl.xml +0 -0
- package/thirdparty/pugixml/tests/data/utftest_utf32_be.xml +0 -0
- package/thirdparty/pugixml/tests/data/utftest_utf32_be_bom.xml +0 -0
- package/thirdparty/pugixml/tests/data/utftest_utf32_be_clean.xml +0 -0
- package/thirdparty/pugixml/tests/data/utftest_utf32_be_nodecl.xml +0 -0
- package/thirdparty/pugixml/tests/data/utftest_utf32_le.xml +0 -0
- package/thirdparty/pugixml/tests/data/utftest_utf32_le_bom.xml +0 -0
- package/thirdparty/pugixml/tests/data/utftest_utf32_le_clean.xml +0 -0
- package/thirdparty/pugixml/tests/data/utftest_utf32_le_nodecl.xml +0 -0
- package/thirdparty/pugixml/tests/data/utftest_utf8.xml +87 -0
- package/thirdparty/pugixml/tests/data/utftest_utf8_bom.xml +87 -0
- package/thirdparty/pugixml/tests/data/utftest_utf8_clean.xml +84 -0
- package/thirdparty/pugixml/tests/data/utftest_utf8_nodecl.xml +86 -0
- package/thirdparty/pugixml/tests/data//321/202/320/265/321/201/321/202.xml +1 -0
- package/thirdparty/pugixml/tests/data_fuzz_parse/basic.xml +1 -0
- package/thirdparty/pugixml/tests/data_fuzz_parse/doctype.xml +1 -0
- package/thirdparty/pugixml/tests/data_fuzz_parse/refs.xml +1 -0
- package/thirdparty/pugixml/tests/data_fuzz_parse/types.xml +1 -0
- package/thirdparty/pugixml/tests/data_fuzz_parse/utf16.xml +0 -0
- package/thirdparty/pugixml/tests/data_fuzz_parse/utf32.xml +0 -0
- package/thirdparty/pugixml/tests/data_fuzz_xpath/basic.xpath +1 -0
- package/thirdparty/pugixml/tests/data_fuzz_xpath/functions.xpath +1 -0
- package/thirdparty/pugixml/tests/data_fuzz_xpath/math.xpath +1 -0
- package/thirdparty/pugixml/tests/data_fuzz_xpath/path.xpath +1 -0
- package/thirdparty/pugixml/tests/data_fuzz_xpath/predicate.xpath +1 -0
- package/thirdparty/pugixml/tests/fuzz_parse.cpp +14 -0
- package/thirdparty/pugixml/tests/fuzz_parse.dict +72 -0
- package/thirdparty/pugixml/tests/fuzz_setup.sh +11 -0
- package/thirdparty/pugixml/tests/fuzz_xpath.cpp +46 -0
- package/thirdparty/pugixml/tests/fuzz_xpath.dict +72 -0
- package/thirdparty/pugixml/tests/helpers.hpp +114 -0
- package/thirdparty/pugixml/tests/main.cpp +218 -0
- package/thirdparty/pugixml/tests/test.cpp +220 -0
- package/thirdparty/pugixml/tests/test.hpp +175 -0
- package/thirdparty/pugixml/tests/test_compact.cpp +150 -0
- package/thirdparty/pugixml/tests/test_deprecated.cpp +25 -0
- package/thirdparty/pugixml/tests/test_document.cpp +1910 -0
- package/thirdparty/pugixml/tests/test_dom_modify.cpp +2122 -0
- package/thirdparty/pugixml/tests/test_dom_text.cpp +601 -0
- package/thirdparty/pugixml/tests/test_dom_traverse.cpp +1481 -0
- package/thirdparty/pugixml/tests/test_header_guard.cpp +3 -0
- package/thirdparty/pugixml/tests/test_header_iosfwd_1.cpp +3 -0
- package/thirdparty/pugixml/tests/test_header_iosfwd_2.cpp +3 -0
- package/thirdparty/pugixml/tests/test_header_iostream_1.cpp +3 -0
- package/thirdparty/pugixml/tests/test_header_iostream_2.cpp +3 -0
- package/thirdparty/pugixml/tests/test_header_only_1.cpp +21 -0
- package/thirdparty/pugixml/tests/test_header_only_2.cpp +21 -0
- package/thirdparty/pugixml/tests/test_header_string_1.cpp +3 -0
- package/thirdparty/pugixml/tests/test_header_string_2.cpp +3 -0
- package/thirdparty/pugixml/tests/test_header_string_iostream.cpp +5 -0
- package/thirdparty/pugixml/tests/test_memory.cpp +303 -0
- package/thirdparty/pugixml/tests/test_parse.cpp +1463 -0
- package/thirdparty/pugixml/tests/test_parse_doctype.cpp +366 -0
- package/thirdparty/pugixml/tests/test_unicode.cpp +152 -0
- package/thirdparty/pugixml/tests/test_version.cpp +5 -0
- package/thirdparty/pugixml/tests/test_write.cpp +757 -0
- package/thirdparty/pugixml/tests/test_xpath.cpp +833 -0
- package/thirdparty/pugixml/tests/test_xpath_api.cpp +646 -0
- package/thirdparty/pugixml/tests/test_xpath_functions.cpp +844 -0
- package/thirdparty/pugixml/tests/test_xpath_operators.cpp +566 -0
- package/thirdparty/pugixml/tests/test_xpath_parse.cpp +428 -0
- package/thirdparty/pugixml/tests/test_xpath_paths.cpp +787 -0
- package/thirdparty/pugixml/tests/test_xpath_paths_abbrev_w3c.cpp +219 -0
- package/thirdparty/pugixml/tests/test_xpath_paths_w3c.cpp +312 -0
- package/thirdparty/pugixml/tests/test_xpath_variables.cpp +683 -0
- package/thirdparty/pugixml/tests/test_xpath_xalan_1.cpp +411 -0
- package/thirdparty/pugixml/tests/test_xpath_xalan_2.cpp +417 -0
- package/thirdparty/pugixml/tests/test_xpath_xalan_3.cpp +321 -0
- package/thirdparty/pugixml/tests/test_xpath_xalan_4.cpp +300 -0
- package/thirdparty/pugixml/tests/test_xpath_xalan_5.cpp +295 -0
- package/thirdparty/pugixml/tests/writer_string.cpp +79 -0
- package/thirdparty/pugixml/tests/writer_string.hpp +27 -0
- package/scripts/prepare-openxlsx.js +0 -126
|
@@ -0,0 +1,784 @@
|
|
|
1
|
+
/*
|
|
2
|
+
|
|
3
|
+
____ ____ ___ ____ ____ ____ ___
|
|
4
|
+
6MMMMb `MM( )M' `MM' 6MMMMb\`MM( )M'
|
|
5
|
+
8P Y8 `MM. d' MM 6M' ` `MM. d'
|
|
6
|
+
6M Mb __ ____ ____ ___ __ `MM. d' MM MM `MM. d'
|
|
7
|
+
MM MM `M6MMMMb 6MMMMb `MM 6MMb `MM. d' MM YM. `MM. d'
|
|
8
|
+
MM MM MM' `Mb 6M' `Mb MMM9 `Mb `MMd MM YMMMMb `MMd
|
|
9
|
+
MM MM MM MM MM MM MM' MM dMM. MM `Mb dMM.
|
|
10
|
+
MM MM MM MM MMMMMMMM MM MM d'`MM. MM MM d'`MM.
|
|
11
|
+
YM M9 MM MM MM MM MM d' `MM. MM MM d' `MM.
|
|
12
|
+
8b d8 MM. ,M9 YM d9 MM MM d' `MM. MM / L ,M9 d' `MM.
|
|
13
|
+
YMMMM9 MMYMMM9 YMMMM9 _MM_ _MM_M(_ _)MM_ _MMMMMMM MYMMMM9 _M(_ _)MM_
|
|
14
|
+
MM
|
|
15
|
+
MM
|
|
16
|
+
_MM_
|
|
17
|
+
|
|
18
|
+
Copyright (c) 2018, Kenneth Troldal Balslev
|
|
19
|
+
|
|
20
|
+
All rights reserved.
|
|
21
|
+
|
|
22
|
+
Redistribution and use in source and binary forms, with or without
|
|
23
|
+
modification, are permitted provided that the following conditions are met:
|
|
24
|
+
- Redistributions of source code must retain the above copyright
|
|
25
|
+
notice, this list of conditions and the following disclaimer.
|
|
26
|
+
- Redistributions in binary form must reproduce the above copyright
|
|
27
|
+
notice, this list of conditions and the following disclaimer in the
|
|
28
|
+
documentation and/or other materials provided with the distribution.
|
|
29
|
+
- Neither the name of the author nor the
|
|
30
|
+
names of any contributors may be used to endorse or promote products
|
|
31
|
+
derived from this software without specific prior written permission.
|
|
32
|
+
|
|
33
|
+
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
|
34
|
+
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
|
35
|
+
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
|
36
|
+
DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
|
|
37
|
+
DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
|
38
|
+
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
|
39
|
+
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
|
40
|
+
ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
|
41
|
+
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
|
42
|
+
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|
43
|
+
|
|
44
|
+
*/
|
|
45
|
+
|
|
46
|
+
// ===== External Includes ===== //
|
|
47
|
+
#include <algorithm>
|
|
48
|
+
#include <iterator>
|
|
49
|
+
#include <vector>
|
|
50
|
+
|
|
51
|
+
// ===== OpenXLSX Includes ===== //
|
|
52
|
+
#include "XLDocument.hpp"
|
|
53
|
+
#include "XLSheet.hpp"
|
|
54
|
+
#include "XLWorkbook.hpp"
|
|
55
|
+
#include "XLXmlParser.hpp" // pugixml wrapper
|
|
56
|
+
#include "utilities/XLUtilities.hpp" // appendAndGetAttribute
|
|
57
|
+
|
|
58
|
+
using namespace OpenXLSX;
|
|
59
|
+
|
|
60
|
+
namespace
|
|
61
|
+
{
|
|
62
|
+
/**
|
|
63
|
+
* @brief
|
|
64
|
+
* @param doc
|
|
65
|
+
* @return
|
|
66
|
+
*/
|
|
67
|
+
XMLNode sheetsNode(const XMLDocument& doc) { return doc.document_element().child("sheets"); }
|
|
68
|
+
} // namespace
|
|
69
|
+
|
|
70
|
+
/**
|
|
71
|
+
* @details Default constructor
|
|
72
|
+
*/
|
|
73
|
+
XLWorkbook::XLWorkbook() = default;
|
|
74
|
+
|
|
75
|
+
/**
|
|
76
|
+
* @details The constructor initializes the member variables and calls the loadXMLData from the
|
|
77
|
+
* XLAbstractXMLFile base class.
|
|
78
|
+
*/
|
|
79
|
+
XLWorkbook::XLWorkbook(XLXmlData* xmlData) : XLXmlFile(xmlData)
|
|
80
|
+
{
|
|
81
|
+
// 2026-06-10: ensure that XML namespaces are defined in existing documents, too
|
|
82
|
+
XMLNode rootNode = xmlDocument().document_element();
|
|
83
|
+
appendAndGetAttribute(rootNode, "xmlns", "http://schemas.openxmlformats.org/spreadsheetml/2006/main");
|
|
84
|
+
appendAndGetAttribute(rootNode, "xmlns:r", "http://schemas.openxmlformats.org/officeDocument/2006/relationships");
|
|
85
|
+
appendAndGetAttribute(rootNode, "xmlns:mc", "http://schemas.openxmlformats.org/markup-compatibility/2006");
|
|
86
|
+
appendAndGetAttribute(rootNode, "xmlns:x15", "http://schemas.microsoft.com/office/spreadsheetml/2010/11/main");
|
|
87
|
+
appendAndGetAttribute(rootNode, "xmlns:xr", "http://schemas.microsoft.com/office/spreadsheetml/2014/revision");
|
|
88
|
+
appendAndGetAttribute(rootNode, "xmlns:xr6", "http://schemas.microsoft.com/office/spreadsheetml/2016/revision6");
|
|
89
|
+
appendAndGetAttribute(rootNode, "xmlns:xr10", "http://schemas.microsoft.com/office/spreadsheetml/2016/revision10");
|
|
90
|
+
appendAndGetAttribute(rootNode, "xmlns:xr2", "http://schemas.microsoft.com/office/spreadsheetml/2015/revision2");
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
/**
|
|
94
|
+
* @details Copy constructor
|
|
95
|
+
*/
|
|
96
|
+
XLWorkbook::XLWorkbook(const XLWorkbook& other) = default;
|
|
97
|
+
|
|
98
|
+
/**
|
|
99
|
+
* @details Move constructor
|
|
100
|
+
*/
|
|
101
|
+
XLWorkbook::XLWorkbook(XLWorkbook&& other) = default;
|
|
102
|
+
|
|
103
|
+
/**
|
|
104
|
+
* @details
|
|
105
|
+
*/
|
|
106
|
+
XLWorkbook::~XLWorkbook() = default;
|
|
107
|
+
|
|
108
|
+
/**
|
|
109
|
+
* @brief Copy assignment operator
|
|
110
|
+
*/
|
|
111
|
+
XLWorkbook& XLWorkbook::operator=(const XLWorkbook& other) = default;
|
|
112
|
+
|
|
113
|
+
/**
|
|
114
|
+
* @brief Move assignment operator
|
|
115
|
+
*/
|
|
116
|
+
XLWorkbook& XLWorkbook::operator=(XLWorkbook&& other) = default;
|
|
117
|
+
|
|
118
|
+
/**
|
|
119
|
+
* @details
|
|
120
|
+
*/
|
|
121
|
+
XLSheet XLWorkbook::sheet(const std::string& sheetName)
|
|
122
|
+
{
|
|
123
|
+
// ===== First determine if the sheet exists.
|
|
124
|
+
if (xmlDocument().document_element().child("sheets").find_child_by_attribute("name", sheetName.c_str()) == nullptr)
|
|
125
|
+
throw XLInputError("Sheet \"" + sheetName + "\" does not exist");
|
|
126
|
+
|
|
127
|
+
// ===== Find the sheet data corresponding to the sheet with the requested name
|
|
128
|
+
const std::string xmlID =
|
|
129
|
+
xmlDocument().document_element().child("sheets").find_child_by_attribute("name", sheetName.c_str()).attribute("r:id").value();
|
|
130
|
+
|
|
131
|
+
XLQuery pathQuery(XLQueryType::QuerySheetRelsTarget);
|
|
132
|
+
pathQuery.setParam("sheetID", xmlID);
|
|
133
|
+
auto xmlPath = parentDoc().execQuery(pathQuery).result<std::string>();
|
|
134
|
+
|
|
135
|
+
// Some spreadsheets use absolute rather than relative paths in relationship items.
|
|
136
|
+
if (xmlPath.substr(0, 4) == "/xl/") xmlPath = xmlPath.substr(4);
|
|
137
|
+
|
|
138
|
+
XLQuery xmlQuery(XLQueryType::QueryXmlData);
|
|
139
|
+
xmlQuery.setParam("xmlPath", "xl/" + xmlPath);
|
|
140
|
+
return XLSheet(parentDoc().execQuery(xmlQuery).result<XLXmlData*>());
|
|
141
|
+
}
|
|
142
|
+
|
|
143
|
+
/**
|
|
144
|
+
* @details iterate over sheetsNode and count element nodes until index, get sheet name and return the corresponding sheet object
|
|
145
|
+
*
|
|
146
|
+
* @old-details Create a vector with sheet nodes, retrieve the node at the requested index, get sheet name and return the
|
|
147
|
+
* corresponding sheet object.
|
|
148
|
+
*/
|
|
149
|
+
XLSheet XLWorkbook::sheet(uint16_t index) // 2024-04-30: whitespace support
|
|
150
|
+
{
|
|
151
|
+
if (index < 1 || index > sheetCount()) throw XLInputError("Sheet index is out of bounds");
|
|
152
|
+
|
|
153
|
+
// ===== Find the n-th node_element that corresponds to index
|
|
154
|
+
uint16_t curIndex = 0;
|
|
155
|
+
for (XMLNode node = sheetsNode(xmlDocument()).first_child_of_type(pugi::node_element);
|
|
156
|
+
not node.empty();
|
|
157
|
+
node = node.next_sibling_of_type(pugi::node_element))
|
|
158
|
+
{
|
|
159
|
+
if (++curIndex == index) return sheet(node.attribute("name").as_string());
|
|
160
|
+
}
|
|
161
|
+
|
|
162
|
+
// ===== If execution gets here, there are less element nodes than index in sheetsNode, this should never happen
|
|
163
|
+
using namespace std::literals::string_literals;
|
|
164
|
+
throw XLInternalError("Sheet index "s + std::to_string(index) + " is out of bounds"s);
|
|
165
|
+
}
|
|
166
|
+
|
|
167
|
+
/**
|
|
168
|
+
* @details
|
|
169
|
+
*/
|
|
170
|
+
XLWorksheet XLWorkbook::worksheet(const std::string& sheetName) { return sheet(sheetName).get<XLWorksheet>(); }
|
|
171
|
+
|
|
172
|
+
/**
|
|
173
|
+
* @details
|
|
174
|
+
*/
|
|
175
|
+
XLWorksheet XLWorkbook::worksheet(uint16_t index) { return sheet(index).get<XLWorksheet>(); }
|
|
176
|
+
|
|
177
|
+
/**
|
|
178
|
+
* @details
|
|
179
|
+
*/
|
|
180
|
+
XLChartsheet XLWorkbook::chartsheet(const std::string& sheetName) { return sheet(sheetName).get<XLChartsheet>(); }
|
|
181
|
+
|
|
182
|
+
/**
|
|
183
|
+
* @details
|
|
184
|
+
*/
|
|
185
|
+
XLChartsheet XLWorkbook::chartsheet(uint16_t index) { return sheet(index).get<XLChartsheet>(); }
|
|
186
|
+
|
|
187
|
+
// /**
|
|
188
|
+
// * @details
|
|
189
|
+
// */
|
|
190
|
+
// bool XLWorkbook::hasSharedStrings() const
|
|
191
|
+
// {
|
|
192
|
+
// return true; // always true
|
|
193
|
+
// }
|
|
194
|
+
//
|
|
195
|
+
// /**
|
|
196
|
+
// * @details
|
|
197
|
+
// */
|
|
198
|
+
// XLSharedStrings XLWorkbook::sharedStrings()
|
|
199
|
+
// {
|
|
200
|
+
// const XLQuery query(XLQueryType::QuerySharedStrings);
|
|
201
|
+
// return parentDoc().execQuery(query).result<XLSharedStrings>();
|
|
202
|
+
// }
|
|
203
|
+
//
|
|
204
|
+
/**
|
|
205
|
+
* @details
|
|
206
|
+
*/
|
|
207
|
+
void XLWorkbook::deleteNamedRanges()
|
|
208
|
+
{
|
|
209
|
+
xmlDocument()
|
|
210
|
+
.document_element()
|
|
211
|
+
.child("definedNames")
|
|
212
|
+
.remove_children(); // 2024-05-02: why loop if pugixml has a function for "delete all children"?
|
|
213
|
+
// for (auto& child : xmlDocument().document_element().child("definedNames").children()) child.parent().remove_child(child);
|
|
214
|
+
}
|
|
215
|
+
|
|
216
|
+
/**
|
|
217
|
+
* @details
|
|
218
|
+
*/
|
|
219
|
+
void XLWorkbook::deleteSheet(const std::string& sheetName) // 2024-05-02: whitespace support
|
|
220
|
+
// CAUTION: execCommand on underlying XML with whitespaces not verified
|
|
221
|
+
{
|
|
222
|
+
// ===== Determine ID and type of sheet, as well as current worksheet count.
|
|
223
|
+
std::string sheetID = sheetsNode(xmlDocument()).find_child_by_attribute("name", sheetName.c_str()).attribute("r:id").value(); // NOLINT
|
|
224
|
+
if (sheetID.length() == 0) { // 2025-01-12 BUGFIX: prevent segfault by throwing
|
|
225
|
+
using namespace std::literals::string_literals;
|
|
226
|
+
throw XLException("XLWorkbook::deleteSheet: workbook has no sheet with name \""s + sheetName + "\""s);
|
|
227
|
+
}
|
|
228
|
+
XLQuery sheetTypeQuery(XLQueryType::QuerySheetType);
|
|
229
|
+
sheetTypeQuery.setParam("sheetID", std::string(sheetID)); // BUGFIX 2024-05-02: was using relationshipID() instead of sheetID,
|
|
230
|
+
// leading to a bad sheetType & a failed check to not delete last worksheet
|
|
231
|
+
const auto sheetType = parentDoc().execQuery(sheetTypeQuery).result<XLContentType>();
|
|
232
|
+
|
|
233
|
+
// 2024-04-30: this should be whitespace-safe due to lambda expression checking for an attribute that non element nodes can not have
|
|
234
|
+
const auto worksheetCount =
|
|
235
|
+
std::count_if(sheetsNode(xmlDocument()).children().begin(), sheetsNode(xmlDocument()).children().end(), [&](const XMLNode& item) {
|
|
236
|
+
if (item.type() != pugi::node_element) return false; // 2024-05-02 this avoids the unnecessary query below
|
|
237
|
+
XLQuery query(XLQueryType::QuerySheetType);
|
|
238
|
+
query.setParam("sheetID", std::string(item.attribute("r:id").value()));
|
|
239
|
+
return parentDoc().execQuery(query).result<XLContentType>() == XLContentType::Worksheet;
|
|
240
|
+
});
|
|
241
|
+
|
|
242
|
+
// ===== If this is the last worksheet in the workbook, throw an exception.
|
|
243
|
+
if (worksheetCount == 1 && sheetType == XLContentType::Worksheet)
|
|
244
|
+
throw XLInputError("Invalid operation. There must be at least one worksheet in the workbook.");
|
|
245
|
+
|
|
246
|
+
// ===== Delete the sheet data as well as the sheet node from Workbook.xml
|
|
247
|
+
parentDoc().execCommand(
|
|
248
|
+
XLCommand(XLCommandType::DeleteSheet).setParam("sheetID", std::string(sheetID)).setParam("sheetName", sheetName));
|
|
249
|
+
XMLNode sheet = sheetsNode(xmlDocument()).find_child_by_attribute("name", sheetName.c_str());
|
|
250
|
+
if (not sheet.empty()) {
|
|
251
|
+
// ===== Delete all non element nodes (comments, whitespaces) following the sheet being deleted from workbook.xml <sheets> node
|
|
252
|
+
XMLNode nonElementNode = sheet.next_sibling();
|
|
253
|
+
while (not nonElementNode.empty() && nonElementNode.type() != pugi::node_element) {
|
|
254
|
+
sheetsNode(xmlDocument()).remove_child(nonElementNode);
|
|
255
|
+
nonElementNode = nonElementNode.next_sibling();
|
|
256
|
+
}
|
|
257
|
+
sheetsNode(xmlDocument()).remove_child(sheet); // delete the actual sheet entry
|
|
258
|
+
}
|
|
259
|
+
|
|
260
|
+
if (sheetIsActive(sheetID))
|
|
261
|
+
xmlDocument().document_element().child("bookViews").first_child_of_type(pugi::node_element).remove_attribute("activeTab");
|
|
262
|
+
}
|
|
263
|
+
|
|
264
|
+
/**
|
|
265
|
+
* @details
|
|
266
|
+
*/
|
|
267
|
+
void XLWorkbook::addWorksheet(const std::string& sheetName)
|
|
268
|
+
{
|
|
269
|
+
// ===== If a sheet with the given name already exists, throw an exception.
|
|
270
|
+
if (xmlDocument().document_element().child("sheets").find_child_by_attribute("name", sheetName.c_str()))
|
|
271
|
+
throw XLInputError("Sheet named \"" + sheetName + "\" already exists.");
|
|
272
|
+
|
|
273
|
+
// ===== Create new internal (workbook) ID for the sheet
|
|
274
|
+
auto internalID = createInternalSheetID();
|
|
275
|
+
|
|
276
|
+
// ===== Create xml file for new worksheet and add metadata to the workbook file.
|
|
277
|
+
parentDoc().execCommand(XLCommand(XLCommandType::AddWorksheet)
|
|
278
|
+
.setParam("sheetName", sheetName)
|
|
279
|
+
.setParam("sheetPath", "/xl/worksheets/sheet" + std::to_string(internalID) + ".xml"));
|
|
280
|
+
prepareSheetMetadata(sheetName, internalID);
|
|
281
|
+
}
|
|
282
|
+
|
|
283
|
+
/**
|
|
284
|
+
* @details
|
|
285
|
+
* @todo If the original sheet's tabSelected attribute is set, ensure it is un-set in the clone.
|
|
286
|
+
* TBD: See comment in XLWorkbook::setSheetActive - should the tabSelected actually be un-set? It's not the same as the active tab,
|
|
287
|
+
* which does not need to be selected
|
|
288
|
+
*/
|
|
289
|
+
void XLWorkbook::cloneSheet(const std::string& existingName, const std::string& newName)
|
|
290
|
+
{
|
|
291
|
+
parentDoc().execCommand(XLCommand(XLCommandType::CloneSheet).setParam("sheetID", sheetID(existingName)).setParam("cloneName", newName));
|
|
292
|
+
}
|
|
293
|
+
|
|
294
|
+
/**
|
|
295
|
+
* @details
|
|
296
|
+
*/
|
|
297
|
+
uint16_t XLWorkbook::createInternalSheetID() // 2024-04-30: whitespace support
|
|
298
|
+
{
|
|
299
|
+
XMLNode sheet = xmlDocument().document_element().child("sheets").first_child_of_type(pugi::node_element);
|
|
300
|
+
uint32_t maxSheetIdFound = 0;
|
|
301
|
+
while (not sheet.empty()) {
|
|
302
|
+
uint32_t thisSheetId = sheet.attribute("sheetId").as_uint();
|
|
303
|
+
if (thisSheetId > maxSheetIdFound) maxSheetIdFound = thisSheetId;
|
|
304
|
+
sheet = sheet.next_sibling_of_type(pugi::node_element);
|
|
305
|
+
}
|
|
306
|
+
return maxSheetIdFound + 1;
|
|
307
|
+
}
|
|
308
|
+
|
|
309
|
+
/**
|
|
310
|
+
* @details
|
|
311
|
+
*/
|
|
312
|
+
std::string XLWorkbook::sheetID(const std::string& sheetName)
|
|
313
|
+
{
|
|
314
|
+
return xmlDocument().document_element().child("sheets").find_child_by_attribute("name", sheetName.c_str()).attribute("r:id").value();
|
|
315
|
+
}
|
|
316
|
+
|
|
317
|
+
/**
|
|
318
|
+
* @details
|
|
319
|
+
*/
|
|
320
|
+
std::string XLWorkbook::sheetName(const std::string& sheetID) const
|
|
321
|
+
{
|
|
322
|
+
return xmlDocument().document_element().child("sheets").find_child_by_attribute("r:id", sheetID.c_str()).attribute("name").value();
|
|
323
|
+
}
|
|
324
|
+
|
|
325
|
+
/**
|
|
326
|
+
* @details
|
|
327
|
+
*/
|
|
328
|
+
std::string XLWorkbook::sheetVisibility(const std::string& sheetID) const
|
|
329
|
+
{
|
|
330
|
+
return xmlDocument().document_element().child("sheets").find_child_by_attribute("r:id", sheetID.c_str()).attribute("state").value();
|
|
331
|
+
}
|
|
332
|
+
|
|
333
|
+
/**
|
|
334
|
+
* @details
|
|
335
|
+
*/
|
|
336
|
+
void XLWorkbook::prepareSheetMetadata(const std::string& sheetName, uint16_t internalID)
|
|
337
|
+
{
|
|
338
|
+
// ===== Add new child node to the "sheets" node.
|
|
339
|
+
auto node = sheetsNode(xmlDocument()).append_child("sheet");
|
|
340
|
+
|
|
341
|
+
// ===== append the required attributes to the newly created sheet node.
|
|
342
|
+
std::string sheetPath = "/xl/worksheets/sheet" + std::to_string(internalID) + ".xml";
|
|
343
|
+
node.append_attribute("name") = sheetName.c_str();
|
|
344
|
+
node.append_attribute("sheetId") = std::to_string(internalID).c_str();
|
|
345
|
+
|
|
346
|
+
XLQuery query(XLQueryType::QuerySheetRelsID);
|
|
347
|
+
query.setParam("sheetPath", sheetPath);
|
|
348
|
+
node.append_attribute("r:id") = parentDoc().execQuery(query).result<std::string>().c_str();
|
|
349
|
+
}
|
|
350
|
+
|
|
351
|
+
/**
|
|
352
|
+
* @details
|
|
353
|
+
*/
|
|
354
|
+
void XLWorkbook::setSheetName(const std::string& sheetRID, const std::string& newName)
|
|
355
|
+
{
|
|
356
|
+
auto sheetName = xmlDocument().document_element().child("sheets").find_child_by_attribute("r:id", sheetRID.c_str()).attribute("name");
|
|
357
|
+
|
|
358
|
+
updateSheetReferences(sheetName.value(), newName);
|
|
359
|
+
sheetName.set_value(newName.c_str());
|
|
360
|
+
}
|
|
361
|
+
|
|
362
|
+
/**
|
|
363
|
+
* @details
|
|
364
|
+
*/
|
|
365
|
+
void XLWorkbook::setSheetVisibility(const std::string& sheetRID, const std::string& state) // 2024-04-30: whitespace support
|
|
366
|
+
{
|
|
367
|
+
// ===== First, determine if there are other sheets that are visible
|
|
368
|
+
int visibleSheets = 0;
|
|
369
|
+
// for (const auto& item : xmlDocument().document_element().child("sheets").children()) {
|
|
370
|
+
XMLNode item = xmlDocument().document_element().child("sheets").first_child_of_type(pugi::node_element);
|
|
371
|
+
while (not item.empty()) {
|
|
372
|
+
if (std::string(item.attribute("r:id").value()) != sheetRID) {
|
|
373
|
+
if (isVisible(item)) ++visibleSheets;
|
|
374
|
+
}
|
|
375
|
+
item = item.next_sibling_of_type(pugi::node_element);
|
|
376
|
+
}
|
|
377
|
+
|
|
378
|
+
bool hideSheet = not isVisibleState(state); // 2024-04-30: save for later use on activating another sheet if needed
|
|
379
|
+
|
|
380
|
+
// ===== If there are no other visible sheets, and the current sheet is to be made hidden, throw an exception.
|
|
381
|
+
if (hideSheet && visibleSheets == 0) throw XLSheetError("At least one sheet must be visible.");
|
|
382
|
+
|
|
383
|
+
// ===== Then, retrieve or create the visibility ("state") attribute for the sheet, and set it to the "state" value
|
|
384
|
+
auto stateAttribute =
|
|
385
|
+
xmlDocument().document_element().child("sheets").find_child_by_attribute("r:id", sheetRID.c_str()).attribute("state");
|
|
386
|
+
if (stateAttribute.empty()) {
|
|
387
|
+
stateAttribute =
|
|
388
|
+
xmlDocument().document_element().child("sheets").find_child_by_attribute("r:id", sheetRID.c_str()).prepend_attribute("state");
|
|
389
|
+
}
|
|
390
|
+
stateAttribute.set_value(state.c_str());
|
|
391
|
+
|
|
392
|
+
// Next, find the index of the sheet...
|
|
393
|
+
std::string name =
|
|
394
|
+
xmlDocument().document_element().child("sheets").find_child_by_attribute("r:id", sheetRID.c_str()).attribute("name").value();
|
|
395
|
+
auto index = indexOfSheet(name) - 1; // 2024-05-01: activeTab property stores an array index, NOT the value of r_ID?
|
|
396
|
+
|
|
397
|
+
// ...and determine the index of the active sheet
|
|
398
|
+
XMLNode workbookView = xmlDocument().document_element().child("bookViews").first_child_of_type(pugi::node_element);
|
|
399
|
+
auto activeTabAttribute = workbookView.attribute("activeTab");
|
|
400
|
+
if (activeTabAttribute.empty()) {
|
|
401
|
+
activeTabAttribute = workbookView.append_attribute("activeTab");
|
|
402
|
+
activeTabAttribute.set_value(0);
|
|
403
|
+
}
|
|
404
|
+
const auto activeTabIndex = activeTabAttribute.as_uint();
|
|
405
|
+
|
|
406
|
+
// Finally, if the current sheet is the active one, set the "activeTab" attribute to the first visible sheet in the workbook
|
|
407
|
+
if (hideSheet && activeTabIndex == index) { // BUGFIX 2024-04-30: previously, the active tab was re-set even if the current sheet was
|
|
408
|
+
// being set to "visible" (when already being visible)
|
|
409
|
+
XMLNode item = xmlDocument().document_element().child("sheets").first_child_of_type(pugi::node_element);
|
|
410
|
+
while (not item.empty()) {
|
|
411
|
+
if (isVisible(item))
|
|
412
|
+
{ // BUGFIX 2024-05-01: old check was testing state != "hidden" || != "veryHidden", which was always true
|
|
413
|
+
activeTabAttribute.set_value(indexOfSheet(item.attribute("name").value()) - 1);
|
|
414
|
+
break;
|
|
415
|
+
}
|
|
416
|
+
item = item.next_sibling_of_type(pugi::node_element);
|
|
417
|
+
}
|
|
418
|
+
}
|
|
419
|
+
}
|
|
420
|
+
|
|
421
|
+
/**
|
|
422
|
+
* @details
|
|
423
|
+
* @done In some cases (eg. if a sheet is moved to the position before the selected sheet), multiple sheets are selected when opened
|
|
424
|
+
* in Excel.
|
|
425
|
+
*/
|
|
426
|
+
void XLWorkbook::setSheetIndex(const std::string& sheetName, unsigned int index) // 2024-05-01: whitespace support
|
|
427
|
+
{
|
|
428
|
+
// ===== Determine the index of the active tab, if any
|
|
429
|
+
const XMLNode workbookView = xmlDocument().document_element().child("bookViews").first_child_of_type(pugi::node_element);
|
|
430
|
+
const uint32_t activeSheetIndex = 1 + workbookView.attribute("activeTab").as_uint(0); // use index in the 1.. range
|
|
431
|
+
|
|
432
|
+
// ===== Attempt to locate the sheet with sheetName, and look out for the sheet @index, and the sheet @activeIndex while iterating over
|
|
433
|
+
// the sheets
|
|
434
|
+
XMLNode sheetToMove {}; // determine the sheet matching sheetName, if any
|
|
435
|
+
unsigned int sheetToMoveIndex = 0;
|
|
436
|
+
XMLNode existingSheet {}; // determine the sheet at index, if any
|
|
437
|
+
std::string activeSheet_rId {}; // determine the r:id of the sheet at activeIndex, if any
|
|
438
|
+
|
|
439
|
+
unsigned int sheetIndex = 1;
|
|
440
|
+
XMLNode curSheet = sheetsNode(xmlDocument()).first_child_of_type(pugi::node_element);
|
|
441
|
+
int thingsToFind = (activeSheetIndex > 0) ? 3 : 2; // if there is no active tab configured, no need to search for its name
|
|
442
|
+
|
|
443
|
+
while (not curSheet.empty() && thingsToFind > 0) { // permit early loop exit when all sheets are located
|
|
444
|
+
if (sheetToMove.empty() && (curSheet.attribute("name").value() == sheetName)) {
|
|
445
|
+
sheetToMoveIndex = sheetIndex;
|
|
446
|
+
sheetToMove = curSheet;
|
|
447
|
+
--thingsToFind;
|
|
448
|
+
}
|
|
449
|
+
if (existingSheet.empty() && (sheetIndex == index)) {
|
|
450
|
+
existingSheet = curSheet;
|
|
451
|
+
--thingsToFind;
|
|
452
|
+
}
|
|
453
|
+
if (activeSheet_rId.empty() && (sheetIndex == activeSheetIndex)) { // if no active sheet: activeSheetIndex 0 never matches
|
|
454
|
+
activeSheet_rId = curSheet.attribute("r:id").value();
|
|
455
|
+
--thingsToFind;
|
|
456
|
+
}
|
|
457
|
+
++sheetIndex;
|
|
458
|
+
curSheet = curSheet.next_sibling_of_type(pugi::node_element);
|
|
459
|
+
}
|
|
460
|
+
|
|
461
|
+
// ===== If a sheet with sheetName was not found
|
|
462
|
+
if (sheetToMove.empty()) throw XLInputError(std::string(__func__) + std::string(": no worksheet exists with name ") + sheetName);
|
|
463
|
+
|
|
464
|
+
// ==== name was matched
|
|
465
|
+
|
|
466
|
+
// ===== If the new index is equal to the current, don't do anything
|
|
467
|
+
if (index == sheetToMoveIndex) return;
|
|
468
|
+
|
|
469
|
+
// ===== Modify the node in the XML file
|
|
470
|
+
if (existingSheet.empty()) // new index is beyond last sheet
|
|
471
|
+
sheetsNode(xmlDocument()).append_move(sheetToMove);
|
|
472
|
+
else { // existingSheet was found
|
|
473
|
+
if (sheetToMoveIndex < index)
|
|
474
|
+
sheetsNode(xmlDocument()).insert_move_after(sheetToMove, existingSheet);
|
|
475
|
+
else // sheetToMoveIndex > index, because if equal, function never gets here
|
|
476
|
+
sheetsNode(xmlDocument()).insert_move_before(sheetToMove, existingSheet);
|
|
477
|
+
}
|
|
478
|
+
|
|
479
|
+
// ===== Updated defined names with worksheet scopes. TBD what this does
|
|
480
|
+
XMLNode definedName = xmlDocument().document_element().child("definedNames").first_child_of_type(pugi::node_element);
|
|
481
|
+
while (not definedName.empty()) {
|
|
482
|
+
// TBD: is the current definedName actually associated with the sheet that was moved?
|
|
483
|
+
definedName.attribute("localSheetId").set_value(sheetToMoveIndex - 1);
|
|
484
|
+
definedName = definedName.next_sibling_of_type(pugi::node_element);
|
|
485
|
+
}
|
|
486
|
+
|
|
487
|
+
// ===== Update the activeTab attribute.
|
|
488
|
+
if ((activeSheetIndex < std::min(index, sheetToMoveIndex)) ||
|
|
489
|
+
(activeSheetIndex > std::max(index, sheetToMoveIndex))) // if active sheet was not within the set of sheets affected by the move
|
|
490
|
+
return; // nothing to do
|
|
491
|
+
|
|
492
|
+
if (activeSheet_rId.length() > 0) setSheetActive(activeSheet_rId);
|
|
493
|
+
}
|
|
494
|
+
|
|
495
|
+
/**
|
|
496
|
+
* @details
|
|
497
|
+
*/
|
|
498
|
+
unsigned int XLWorkbook::indexOfSheet(const std::string& sheetName) const // 2024-05-01: whitespace support
|
|
499
|
+
{
|
|
500
|
+
// ===== Iterate through sheet nodes. When a match is found, return the index;
|
|
501
|
+
unsigned int index = 1;
|
|
502
|
+
for (XMLNode sheet = sheetsNode(xmlDocument()).first_child_of_type(pugi::node_element);
|
|
503
|
+
not sheet.empty();
|
|
504
|
+
sheet = sheet.next_sibling_of_type(pugi::node_element))
|
|
505
|
+
{
|
|
506
|
+
if (sheetName == sheet.attribute("name").value()) return index;
|
|
507
|
+
index++;
|
|
508
|
+
}
|
|
509
|
+
|
|
510
|
+
// ===== If a match is not found, throw an exception.
|
|
511
|
+
throw XLInputError("Sheet does not exist");
|
|
512
|
+
}
|
|
513
|
+
|
|
514
|
+
/**
|
|
515
|
+
* @details
|
|
516
|
+
*/
|
|
517
|
+
XLSheetType XLWorkbook::typeOfSheet(const std::string& sheetName) const
|
|
518
|
+
{
|
|
519
|
+
if (!sheetExists(sheetName)) throw XLInputError("Sheet with name \"" + sheetName + "\" doesn't exist.");
|
|
520
|
+
|
|
521
|
+
if (worksheetExists(sheetName)) return XLSheetType::Worksheet;
|
|
522
|
+
return XLSheetType::Chartsheet;
|
|
523
|
+
}
|
|
524
|
+
|
|
525
|
+
/**
|
|
526
|
+
* @details
|
|
527
|
+
*/
|
|
528
|
+
XLSheetType XLWorkbook::typeOfSheet(unsigned int index) const // 2024-05-01: whitespace support
|
|
529
|
+
{
|
|
530
|
+
unsigned int thisIndex = 1;
|
|
531
|
+
for (XMLNode sheet = sheetsNode(xmlDocument()).first_child_of_type(pugi::node_element);
|
|
532
|
+
not sheet.empty();
|
|
533
|
+
sheet = sheet.next_sibling_of_type(pugi::node_element))
|
|
534
|
+
{
|
|
535
|
+
if (thisIndex == index) return typeOfSheet(sheet.attribute("name").as_string());
|
|
536
|
+
++thisIndex;
|
|
537
|
+
}
|
|
538
|
+
|
|
539
|
+
using namespace std::literals::string_literals;
|
|
540
|
+
throw XLInputError(std::string(__func__) + ": index "s + std::to_string(index) + " is out of range"s);
|
|
541
|
+
}
|
|
542
|
+
|
|
543
|
+
/**
|
|
544
|
+
* @details
|
|
545
|
+
*/
|
|
546
|
+
unsigned int XLWorkbook::sheetCount() const // 2024-04-30: whitespace support
|
|
547
|
+
{
|
|
548
|
+
unsigned int count = 0;
|
|
549
|
+
for (XMLNode node = sheetsNode(xmlDocument()).first_child_of_type(pugi::node_element);
|
|
550
|
+
not node.empty();
|
|
551
|
+
node = node.next_sibling_of_type(pugi::node_element))
|
|
552
|
+
++count;
|
|
553
|
+
return count;
|
|
554
|
+
}
|
|
555
|
+
|
|
556
|
+
/**
|
|
557
|
+
* @details
|
|
558
|
+
*/
|
|
559
|
+
unsigned int XLWorkbook::worksheetCount() const { return static_cast<unsigned int>(worksheetNames().size()); }
|
|
560
|
+
|
|
561
|
+
/**
|
|
562
|
+
* @details
|
|
563
|
+
*/
|
|
564
|
+
unsigned int XLWorkbook::chartsheetCount() const { return static_cast<unsigned int>(chartsheetNames().size()); }
|
|
565
|
+
|
|
566
|
+
/**
|
|
567
|
+
* @details
|
|
568
|
+
*/
|
|
569
|
+
std::vector<std::string> XLWorkbook::sheetNames() const // 2024-05-01: whitespace support
|
|
570
|
+
{
|
|
571
|
+
std::vector<std::string> results;
|
|
572
|
+
|
|
573
|
+
for (XMLNode item = sheetsNode(xmlDocument()).first_child_of_type(pugi::node_element);
|
|
574
|
+
not item.empty();
|
|
575
|
+
item = item.next_sibling_of_type(pugi::node_element))
|
|
576
|
+
results.emplace_back(item.attribute("name").value());
|
|
577
|
+
|
|
578
|
+
return results;
|
|
579
|
+
}
|
|
580
|
+
|
|
581
|
+
/**
|
|
582
|
+
* @details
|
|
583
|
+
*/
|
|
584
|
+
std::vector<std::string> XLWorkbook::worksheetNames() const // 2024-05-01: whitespace support
|
|
585
|
+
{
|
|
586
|
+
std::vector<std::string> results;
|
|
587
|
+
|
|
588
|
+
for (XMLNode item = sheetsNode(xmlDocument()).first_child_of_type(pugi::node_element);
|
|
589
|
+
not item.empty();
|
|
590
|
+
item = item.next_sibling_of_type(pugi::node_element))
|
|
591
|
+
{
|
|
592
|
+
XLQuery query(XLQueryType::QuerySheetType);
|
|
593
|
+
query.setParam("sheetID", std::string(item.attribute("r:id").value()));
|
|
594
|
+
if (parentDoc().execQuery(query).result<XLContentType>() == XLContentType::Worksheet)
|
|
595
|
+
results.emplace_back(item.attribute("name").value());
|
|
596
|
+
}
|
|
597
|
+
|
|
598
|
+
return results;
|
|
599
|
+
}
|
|
600
|
+
|
|
601
|
+
/**
|
|
602
|
+
* @details
|
|
603
|
+
*/
|
|
604
|
+
std::vector<std::string> XLWorkbook::chartsheetNames() const // 2024-05-01: whitespace support
|
|
605
|
+
{
|
|
606
|
+
std::vector<std::string> results;
|
|
607
|
+
|
|
608
|
+
for (XMLNode item = sheetsNode(xmlDocument()).first_child_of_type(pugi::node_element);
|
|
609
|
+
not item.empty();
|
|
610
|
+
item = item.next_sibling_of_type(pugi::node_element))
|
|
611
|
+
{
|
|
612
|
+
XLQuery query(XLQueryType::QuerySheetType);
|
|
613
|
+
query.setParam("sheetID", std::string(item.attribute("r:id").value()));
|
|
614
|
+
if (parentDoc().execQuery(query).result<XLContentType>() == XLContentType::Chartsheet)
|
|
615
|
+
results.emplace_back(item.attribute("name").value());
|
|
616
|
+
}
|
|
617
|
+
|
|
618
|
+
return results;
|
|
619
|
+
}
|
|
620
|
+
|
|
621
|
+
/**
|
|
622
|
+
* @details
|
|
623
|
+
*/
|
|
624
|
+
bool XLWorkbook::sheetExists(const std::string& sheetName) const { return chartsheetExists(sheetName) || worksheetExists(sheetName); }
|
|
625
|
+
|
|
626
|
+
/**
|
|
627
|
+
* @details
|
|
628
|
+
*/
|
|
629
|
+
bool XLWorkbook::worksheetExists(const std::string& sheetName) const
|
|
630
|
+
{
|
|
631
|
+
auto wksNames = worksheetNames();
|
|
632
|
+
return std::find(wksNames.begin(), wksNames.end(), sheetName) != wksNames.end();
|
|
633
|
+
}
|
|
634
|
+
|
|
635
|
+
/**
|
|
636
|
+
* @details
|
|
637
|
+
*/
|
|
638
|
+
bool XLWorkbook::chartsheetExists(const std::string& sheetName) const
|
|
639
|
+
{
|
|
640
|
+
auto chsNames = chartsheetNames();
|
|
641
|
+
return std::find(chsNames.begin(), chsNames.end(), sheetName) != chsNames.end();
|
|
642
|
+
}
|
|
643
|
+
|
|
644
|
+
/**
|
|
645
|
+
* @details The UpdateSheetName member function searches throug the usages of the old name and replaces with the
|
|
646
|
+
* new sheet name.
|
|
647
|
+
* @todo Currently, this function only searches through defined names. Consider using this function to update the
|
|
648
|
+
* actual sheet name as well.
|
|
649
|
+
*/
|
|
650
|
+
void XLWorkbook::updateSheetReferences(
|
|
651
|
+
const std::string& oldName,
|
|
652
|
+
const std::string& newName) // 2024-05-01: whitespace support with TBD to verify definedNames logic
|
|
653
|
+
{
|
|
654
|
+
// for (auto& sheet : m_sheets) {
|
|
655
|
+
// if (sheet.sheetType == XLSheetType::WorkSheet)
|
|
656
|
+
// Worksheet(sheet.sheetNode.attribute("name").getValue())->UpdateSheetName(oldName, newName);
|
|
657
|
+
// }
|
|
658
|
+
|
|
659
|
+
// ===== Set up temporary variables
|
|
660
|
+
std::string oldNameTemp = oldName;
|
|
661
|
+
std::string newNameTemp = newName;
|
|
662
|
+
std::string formula;
|
|
663
|
+
|
|
664
|
+
// ===== If the sheet name contains spaces, it should be enclosed in single quotes (')
|
|
665
|
+
if (oldName.find(' ') != std::string::npos) oldNameTemp = "\'" + oldName + "\'";
|
|
666
|
+
if (newName.find(' ') != std::string::npos) newNameTemp = "\'" + newName + "\'";
|
|
667
|
+
|
|
668
|
+
// ===== Ensure only sheet names are replaced (references to sheets always ends with a '!')
|
|
669
|
+
oldNameTemp += '!';
|
|
670
|
+
newNameTemp += '!';
|
|
671
|
+
|
|
672
|
+
// ===== Iterate through all defined names // TODO 2024-05-01: verify definedNames logic
|
|
673
|
+
XMLNode definedName = xmlDocument().document_element().child("definedNames").first_child_of_type(pugi::node_element);
|
|
674
|
+
for (; not definedName.empty(); definedName = definedName.next_sibling_of_type(pugi::node_element)) {
|
|
675
|
+
formula = definedName.text().get();
|
|
676
|
+
|
|
677
|
+
// ===== Skip if formula contains a '[' and ']' (means that the defined refers to external workbook)
|
|
678
|
+
if (formula.find('[') == std::string::npos && formula.find(']') == std::string::npos) {
|
|
679
|
+
// ===== For all instances of the old sheet name in the formula, replace with the new name.
|
|
680
|
+
while (formula.find(oldNameTemp) != std::string::npos) { // NOLINT
|
|
681
|
+
formula.replace(formula.find(oldNameTemp), oldNameTemp.length(), newNameTemp);
|
|
682
|
+
}
|
|
683
|
+
definedName.text().set(formula.c_str());
|
|
684
|
+
}
|
|
685
|
+
}
|
|
686
|
+
}
|
|
687
|
+
|
|
688
|
+
/**
|
|
689
|
+
* @details
|
|
690
|
+
*/
|
|
691
|
+
void XLWorkbook::setFullCalculationOnLoad()
|
|
692
|
+
{
|
|
693
|
+
XMLNode calcPr = xmlDocument().document_element().child("calcPr");
|
|
694
|
+
|
|
695
|
+
auto getOrCreateAttribute = [&calcPr](const char* attributeName) {
|
|
696
|
+
XMLAttribute attr = calcPr.attribute(attributeName);
|
|
697
|
+
if (attr.empty()) attr = calcPr.append_attribute(attributeName);
|
|
698
|
+
return attr;
|
|
699
|
+
};
|
|
700
|
+
|
|
701
|
+
getOrCreateAttribute("forceFullCalc").set_value(true);
|
|
702
|
+
getOrCreateAttribute("fullCalcOnLoad").set_value(true);
|
|
703
|
+
}
|
|
704
|
+
|
|
705
|
+
/**
|
|
706
|
+
* @details
|
|
707
|
+
*/
|
|
708
|
+
void XLWorkbook::print(std::basic_ostream<char>& ostr) const { xmlDocument().document_element().print (ostr); }
|
|
709
|
+
|
|
710
|
+
/**
|
|
711
|
+
* @details
|
|
712
|
+
*/
|
|
713
|
+
bool XLWorkbook::sheetIsActive(const std::string& sheetRID) const // 2024-04-30: whitespace support
|
|
714
|
+
{
|
|
715
|
+
const XMLNode workbookView = xmlDocument().document_element().child("bookViews").first_child_of_type(pugi::node_element);
|
|
716
|
+
const XMLAttribute activeTabAttribute = workbookView.attribute("activeTab");
|
|
717
|
+
const int32_t activeTabIndex = (not activeTabAttribute.empty() ? activeTabAttribute.as_int() : -1); // 2024-05-29 BUGFIX: activeTabAttribute was being read as_uint
|
|
718
|
+
if (activeTabIndex == -1) return false; // 2024-05-29 early exit: no need to try and match sheetRID if there *is* no active tab
|
|
719
|
+
|
|
720
|
+
int32_t index = 0; // 2024-06-04 BUGFIX: index should support -1 as 2024-05-29 change below sets it to -1 for preventing a match with activeTabIndex
|
|
721
|
+
XMLNode item = sheetsNode(xmlDocument()).first_child_of_type(pugi::node_element);
|
|
722
|
+
while (not item.empty()) {
|
|
723
|
+
if (std::string(item.attribute("r:id").value()) == sheetRID) break;
|
|
724
|
+
++index;
|
|
725
|
+
item = item.next_sibling_of_type(pugi::node_element);
|
|
726
|
+
}
|
|
727
|
+
if (item.empty()) index = -1; // 2024-05-29: prevent a match if activeTabIndex invalidly points to a non-existing sheet
|
|
728
|
+
|
|
729
|
+
return index == activeTabIndex;
|
|
730
|
+
}
|
|
731
|
+
|
|
732
|
+
/**
|
|
733
|
+
* @details
|
|
734
|
+
* @done: no exception if setSheetActive fails, instead return false
|
|
735
|
+
* @done: fail by returning false if sheetRID is either not found or belongs to a sheet that is not visible
|
|
736
|
+
* @note: this makes some bug fixes from 2024-05-29 obsolete
|
|
737
|
+
* @note: changed behavior: attempting to setSheetActive on a non-existing or non-visible sheet will no longer unselect the active sheet
|
|
738
|
+
*/
|
|
739
|
+
bool XLWorkbook::setSheetActive(const std::string& sheetRID) // 2024-04-30: whitespace support
|
|
740
|
+
{
|
|
741
|
+
XMLNode workbookView = xmlDocument().document_element().child("bookViews").first_child_of_type(pugi::node_element);
|
|
742
|
+
const XMLAttribute activeTabAttribute = workbookView.attribute("activeTab");
|
|
743
|
+
int32_t activeTabIndex = -1; // negative == no active tab identified
|
|
744
|
+
if (not activeTabAttribute.empty()) activeTabIndex = activeTabAttribute.as_int();
|
|
745
|
+
|
|
746
|
+
int32_t index = 0; // index should have the same data type as activeTabIndex for comparisons
|
|
747
|
+
XMLNode item = sheetsNode(xmlDocument()).first_child_of_type(pugi::node_element);
|
|
748
|
+
while (not item.empty() && (std::string(item.attribute("r:id").value()) != sheetRID)) {
|
|
749
|
+
++index;
|
|
750
|
+
item = item.next_sibling_of_type(pugi::node_element);
|
|
751
|
+
}
|
|
752
|
+
// ===== 2024-06-19: Fail without action if sheet is not found or sheet is not visible
|
|
753
|
+
if (item.empty() || !isVisible(item)) return false;
|
|
754
|
+
|
|
755
|
+
// NOTE: XLSheet XLWorkbook::sheet(uint16_t index) is using a 1-based index, while the workbookView attribute activeTab is using a
|
|
756
|
+
// 0-based index
|
|
757
|
+
|
|
758
|
+
// ===== If an active sheet was found, but sheetRID is not the same sheet: attempt to unselect the old active sheet.
|
|
759
|
+
if ((activeTabIndex != -1) && (index != activeTabIndex)) sheet(activeTabIndex + 1).setSelected(false); // see NOTE above
|
|
760
|
+
|
|
761
|
+
// ===== Set the activeTab property for the workbook.xml sheets node
|
|
762
|
+
if (workbookView.attribute("activeTab").empty()) workbookView.append_attribute("activeTab");
|
|
763
|
+
workbookView.attribute("activeTab").set_value(index);
|
|
764
|
+
// sheet(index + 1).setSelected(true); // it appears that an active sheet does not have to be selected
|
|
765
|
+
return true; // success
|
|
766
|
+
}
|
|
767
|
+
|
|
768
|
+
/**
|
|
769
|
+
* @details evaluate a sheet node state attribute where "hidden" or "veryHidden" means not visible
|
|
770
|
+
* @note 2024-05-01 BUGFIX: veryHidden was not checked (in setSheetActive)
|
|
771
|
+
*/
|
|
772
|
+
bool XLWorkbook::isVisibleState(std::string const& state) const { return (state != "hidden" && state != "veryHidden"); }
|
|
773
|
+
|
|
774
|
+
/**
|
|
775
|
+
* @details function only returns meaningful information when used with a sheet node
|
|
776
|
+
* (or nodes with state attribute allowing values visible, hidden, veryHidden)
|
|
777
|
+
*/
|
|
778
|
+
bool XLWorkbook::isVisible(XMLNode const& sheetNode) const
|
|
779
|
+
{
|
|
780
|
+
if (sheetNode.empty()) return false; // empty nodes can't be visible
|
|
781
|
+
if (sheetNode.attribute("state").empty()) return true; // no state attribute means no hidden-ness can be flagged
|
|
782
|
+
// ===== Attribute exists and value must be checked
|
|
783
|
+
return isVisibleState(sheetNode.attribute("state").value());
|
|
784
|
+
}
|