react-native-nitro-xlsx 0.1.2 → 0.2.5
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/NOTICE +8 -35
- package/NitroXlsx.podspec +21 -57
- package/Package.swift +35 -0
- package/README.md +243 -36
- package/android/CMakeLists.txt +17 -23
- package/android/build.gradle +6 -0
- package/android/cpp-adapter.cpp +12 -0
- package/android/src/main/java/com/margelo/nitro/xlsx/NitroXlsxPackage.kt +9 -0
- package/cpp/HybridNitroXlsx.cpp +32 -9
- package/cpp/HybridNitroXlsx.hpp +2 -1
- package/cpp/HybridXlsxConditionalFormat.cpp +252 -0
- package/cpp/HybridXlsxConditionalFormat.hpp +62 -0
- package/cpp/HybridXlsxConditionalFormats.cpp +46 -0
- package/cpp/HybridXlsxConditionalFormats.hpp +28 -0
- package/cpp/HybridXlsxWorkbook.cpp +162 -87
- package/cpp/HybridXlsxWorkbook.hpp +7 -1
- package/cpp/HybridXlsxWorksheet.cpp +456 -61
- package/cpp/HybridXlsxWorksheet.hpp +73 -26
- package/cpp/XlsxCacheDir.cpp +76 -0
- package/cpp/XlsxCacheDir.hpp +27 -0
- package/cpp/XlsxError.hpp +68 -0
- package/cpp/XlsxJson.cpp +185 -0
- package/cpp/XlsxJson.hpp +36 -0
- package/ios/XlsxCacheDir.mm +60 -0
- package/nitrogen/generated/android/NitroXlsx+autolinking.cmake +2 -0
- package/nitrogen/generated/shared/c++/HybridNitroXlsxSpec.cpp +1 -0
- package/nitrogen/generated/shared/c++/HybridNitroXlsxSpec.hpp +5 -2
- package/nitrogen/generated/shared/c++/HybridXlsxConditionalFormatSpec.cpp +54 -0
- package/nitrogen/generated/shared/c++/HybridXlsxConditionalFormatSpec.hpp +95 -0
- package/nitrogen/generated/shared/c++/HybridXlsxConditionalFormatsSpec.cpp +24 -0
- package/nitrogen/generated/shared/c++/HybridXlsxConditionalFormatsSpec.hpp +68 -0
- package/nitrogen/generated/shared/c++/HybridXlsxWorkbookSpec.cpp +4 -0
- package/nitrogen/generated/shared/c++/HybridXlsxWorkbookSpec.hpp +7 -0
- package/nitrogen/generated/shared/c++/HybridXlsxWorksheetSpec.cpp +47 -19
- package/nitrogen/generated/shared/c++/HybridXlsxWorksheetSpec.hpp +52 -20
- package/package.json +5 -2
- package/scripts/prepare-openxlsx.js +126 -0
- package/scripts/run-cpp-tests.sh +14 -0
- package/src/__mocks__/react-native-nitro-modules.ts +1 -0
- package/src/__tests__/index.test.ts +76 -7
- package/src/index.ts +110 -9
- package/src/specs/NitroXlsx.nitro.ts +141 -42
package/android/cpp-adapter.cpp
CHANGED
|
@@ -1,9 +1,21 @@
|
|
|
1
1
|
#include <jni.h>
|
|
2
2
|
#include <fbjni/fbjni.h>
|
|
3
3
|
#include "NitroXlsxOnLoad.hpp"
|
|
4
|
+
#include "XlsxCacheDir.hpp"
|
|
4
5
|
|
|
5
6
|
JNIEXPORT jint JNICALL JNI_OnLoad(JavaVM* vm, void*) {
|
|
6
7
|
return facebook::jni::initialize(vm, []() {
|
|
7
8
|
margelo::nitro::xlsx::registerAllNatives();
|
|
8
9
|
});
|
|
9
10
|
}
|
|
11
|
+
|
|
12
|
+
// Called from NitroXlsxPackage with Context.getCacheDir().absolutePath
|
|
13
|
+
extern "C" JNIEXPORT void JNICALL
|
|
14
|
+
Java_com_margelo_nitro_xlsx_NitroXlsxPackage_nativeSetCacheDir(JNIEnv* env, jclass, jstring dir) {
|
|
15
|
+
if (dir == nullptr) return;
|
|
16
|
+
const char* chars = env->GetStringUTFChars(dir, nullptr);
|
|
17
|
+
if (chars != nullptr) {
|
|
18
|
+
margelo::nitro::xlsx::setCacheDir(std::string(chars));
|
|
19
|
+
env->ReleaseStringUTFChars(dir, chars);
|
|
20
|
+
}
|
|
21
|
+
}
|
|
@@ -10,10 +10,19 @@ class NitroXlsxPackage : ReactPackage {
|
|
|
10
10
|
init {
|
|
11
11
|
NitroXlsxOnLoad.initializeNative()
|
|
12
12
|
}
|
|
13
|
+
|
|
14
|
+
/** Pass the app cache directory to the native layer for temp XLSX files. */
|
|
15
|
+
@JvmStatic
|
|
16
|
+
private external fun nativeSetCacheDir(dir: String)
|
|
13
17
|
}
|
|
14
18
|
|
|
15
19
|
@Suppress("OVERRIDE_DEPRECATION")
|
|
16
20
|
override fun createNativeModules(reactContext: ReactApplicationContext): List<NativeModule> {
|
|
21
|
+
try {
|
|
22
|
+
nativeSetCacheDir(reactContext.cacheDir.absolutePath)
|
|
23
|
+
} catch (_: Throwable) {
|
|
24
|
+
// native resolver falls back to Context.getCacheDir() via JNI
|
|
25
|
+
}
|
|
17
26
|
return emptyList()
|
|
18
27
|
}
|
|
19
28
|
|
package/cpp/HybridNitroXlsx.cpp
CHANGED
|
@@ -1,5 +1,9 @@
|
|
|
1
1
|
#include "HybridNitroXlsx.hpp"
|
|
2
|
+
#include "XlsxError.hpp"
|
|
2
3
|
#include <fstream>
|
|
4
|
+
#include <stdexcept>
|
|
5
|
+
#include <cstring>
|
|
6
|
+
#include <cstdlib>
|
|
3
7
|
|
|
4
8
|
namespace margelo::nitro::xlsx {
|
|
5
9
|
|
|
@@ -10,20 +14,39 @@ HybridNitroXlsx::HybridNitroXlsx()
|
|
|
10
14
|
HybridNitroXlsx::~HybridNitroXlsx() {
|
|
11
15
|
}
|
|
12
16
|
|
|
13
|
-
std::shared_ptr<HybridXlsxWorkbookSpec> HybridNitroXlsx::createWorkbook(
|
|
14
|
-
return std::
|
|
17
|
+
std::shared_ptr<HybridXlsxWorkbookSpec> HybridNitroXlsx::createWorkbook() {
|
|
18
|
+
return withXlsxError(xlsx_error::IO_ERROR, [&]() -> std::shared_ptr<HybridXlsxWorkbookSpec> {
|
|
19
|
+
return std::make_shared<HybridXlsxWorkbook>();
|
|
20
|
+
});
|
|
15
21
|
}
|
|
16
22
|
|
|
17
23
|
std::shared_ptr<HybridXlsxWorkbookSpec> HybridNitroXlsx::openWorkbook(const std::string& path) {
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
24
|
+
return withXlsxError(xlsx_error::IO_ERROR, [&]() -> std::shared_ptr<HybridXlsxWorkbookSpec> {
|
|
25
|
+
auto workbook = std::make_shared<HybridXlsxWorkbook>();
|
|
26
|
+
workbook->openFromFile(path);
|
|
27
|
+
return workbook;
|
|
28
|
+
});
|
|
21
29
|
}
|
|
22
30
|
|
|
23
31
|
std::shared_ptr<HybridXlsxWorkbookSpec> HybridNitroXlsx::openWorkbookFromBuffer(const std::shared_ptr<ArrayBuffer>& buffer) {
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
32
|
+
return withXlsxError(xlsx_error::IO_ERROR, [&]() -> std::shared_ptr<HybridXlsxWorkbookSpec> {
|
|
33
|
+
auto workbook = std::make_shared<HybridXlsxWorkbook>();
|
|
34
|
+
workbook->openFromBuffer(buffer->data(), buffer->size());
|
|
35
|
+
return workbook;
|
|
36
|
+
});
|
|
27
37
|
}
|
|
28
38
|
|
|
29
|
-
|
|
39
|
+
std::shared_ptr<HybridXlsxWorkbookSpec> HybridNitroXlsx::fromJSON(const std::unordered_map<std::string, std::vector<std::shared_ptr<AnyMap>>>& data) {
|
|
40
|
+
return withXlsxError(xlsx_error::INVALID_ARGUMENT, [&]() -> std::shared_ptr<HybridXlsxWorkbookSpec> {
|
|
41
|
+
auto workbook = std::make_shared<HybridXlsxWorkbook>();
|
|
42
|
+
if (data.empty()) return workbook;
|
|
43
|
+
|
|
44
|
+
for (const auto& [sheetName, rows] : data) {
|
|
45
|
+
auto sheet = workbook->addWorksheet(sheetName);
|
|
46
|
+
sheet->fromJSON(rows);
|
|
47
|
+
}
|
|
48
|
+
return workbook;
|
|
49
|
+
});
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
}
|
package/cpp/HybridNitroXlsx.hpp
CHANGED
|
@@ -11,9 +11,10 @@ public:
|
|
|
11
11
|
HybridNitroXlsx();
|
|
12
12
|
~HybridNitroXlsx() override;
|
|
13
13
|
|
|
14
|
-
std::shared_ptr<HybridXlsxWorkbookSpec> createWorkbook(
|
|
14
|
+
std::shared_ptr<HybridXlsxWorkbookSpec> createWorkbook() override;
|
|
15
15
|
std::shared_ptr<HybridXlsxWorkbookSpec> openWorkbook(const std::string& path) override;
|
|
16
16
|
std::shared_ptr<HybridXlsxWorkbookSpec> openWorkbookFromBuffer(const std::shared_ptr<ArrayBuffer>& buffer) override;
|
|
17
|
+
std::shared_ptr<HybridXlsxWorkbookSpec> fromJSON(const std::unordered_map<std::string, std::vector<std::shared_ptr<AnyMap>>>& data) override;
|
|
17
18
|
};
|
|
18
19
|
|
|
19
20
|
}
|
|
@@ -0,0 +1,252 @@
|
|
|
1
|
+
#include "HybridXlsxConditionalFormat.hpp"
|
|
2
|
+
#include "XlsxError.hpp"
|
|
3
|
+
|
|
4
|
+
namespace margelo::nitro::xlsx {
|
|
5
|
+
|
|
6
|
+
HybridXlsxConditionalFormat::HybridXlsxConditionalFormat(OpenXLSX::XLConditionalFormat format)
|
|
7
|
+
: HybridObject("XlsxConditionalFormat"), HybridXlsxConditionalFormatSpec(), _format(std::move(format)) {
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
HybridXlsxConditionalFormat::~HybridXlsxConditionalFormat() = default;
|
|
11
|
+
|
|
12
|
+
OpenXLSX::XLCfRules HybridXlsxConditionalFormat::rules() {
|
|
13
|
+
return _format.cfRules();
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
OpenXLSX::XLCfRule HybridXlsxConditionalFormat::ruleAt(double index) {
|
|
17
|
+
size_t idx = static_cast<size_t>(index);
|
|
18
|
+
auto cfRules = _format.cfRules();
|
|
19
|
+
if (idx >= cfRules.count()) {
|
|
20
|
+
throw XlsxError(xlsx_error::INDEX_OUT_OF_RANGE,
|
|
21
|
+
"cfRule index " + std::to_string(idx) + " out of range (count=" + std::to_string(cfRules.count()) + ")");
|
|
22
|
+
}
|
|
23
|
+
return cfRules.cfRuleByIndex(idx);
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
std::string HybridXlsxConditionalFormat::getSqref() {
|
|
27
|
+
return withXlsxError(xlsx_error::XLSX_ERROR, [&] { return _format.sqref(); });
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
void HybridXlsxConditionalFormat::setSqref(const std::string& sqref) {
|
|
31
|
+
withXlsxError(xlsx_error::XLSX_ERROR, [&] {
|
|
32
|
+
if (!_format.setSqref(sqref)) {
|
|
33
|
+
throw XlsxError(xlsx_error::XLSX_ERROR, "Failed to set sqref: " + sqref);
|
|
34
|
+
}
|
|
35
|
+
});
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
double HybridXlsxConditionalFormat::getRuleCount() {
|
|
39
|
+
return withXlsxError(xlsx_error::XLSX_ERROR, [&] {
|
|
40
|
+
return static_cast<double>(_format.cfRules().count());
|
|
41
|
+
});
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
double HybridXlsxConditionalFormat::createRule() {
|
|
45
|
+
return withXlsxError(xlsx_error::XLSX_ERROR, [&] {
|
|
46
|
+
auto cfRules = _format.cfRules();
|
|
47
|
+
return static_cast<double>(cfRules.create());
|
|
48
|
+
});
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
bool HybridXlsxConditionalFormat::deleteRule(double index) {
|
|
52
|
+
// OpenXLSX does not expose cfRule deletion
|
|
53
|
+
(void)index;
|
|
54
|
+
return false;
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
double HybridXlsxConditionalFormat::getRuleType(double index) {
|
|
58
|
+
return withXlsxError(xlsx_error::XLSX_ERROR, [&] {
|
|
59
|
+
return static_cast<double>(ruleAt(index).type());
|
|
60
|
+
});
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
void HybridXlsxConditionalFormat::setRuleType(double index, double type) {
|
|
64
|
+
withXlsxError(xlsx_error::XLSX_ERROR, [&] {
|
|
65
|
+
if (!ruleAt(index).setType(static_cast<OpenXLSX::XLCfType>(static_cast<uint8_t>(type)))) {
|
|
66
|
+
throw XlsxError(xlsx_error::XLSX_ERROR, "Failed to set rule type");
|
|
67
|
+
}
|
|
68
|
+
});
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
double HybridXlsxConditionalFormat::getRuleDxfId(double index) {
|
|
72
|
+
return withXlsxError(xlsx_error::XLSX_ERROR, [&] {
|
|
73
|
+
return static_cast<double>(ruleAt(index).dxfId());
|
|
74
|
+
});
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
void HybridXlsxConditionalFormat::setRuleDxfId(double index, double dxfId) {
|
|
78
|
+
withXlsxError(xlsx_error::XLSX_ERROR, [&] {
|
|
79
|
+
if (!ruleAt(index).setDxfId(static_cast<OpenXLSX::XLStyleIndex>(dxfId))) {
|
|
80
|
+
throw XlsxError(xlsx_error::XLSX_ERROR, "Failed to set rule dxfId");
|
|
81
|
+
}
|
|
82
|
+
});
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
std::string HybridXlsxConditionalFormat::getRuleFormula(double index, double formulaIndex) {
|
|
86
|
+
return withXlsxError(xlsx_error::XLSX_ERROR, [&] {
|
|
87
|
+
// OpenXLSX only supports the primary <formula> node
|
|
88
|
+
if (formulaIndex != 0) return std::string();
|
|
89
|
+
return ruleAt(index).formula();
|
|
90
|
+
});
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
void HybridXlsxConditionalFormat::setRuleFormula(double index, double formulaIndex, const std::string& formula) {
|
|
94
|
+
withXlsxError(xlsx_error::XLSX_ERROR, [&] {
|
|
95
|
+
if (formulaIndex != 0) {
|
|
96
|
+
throw XlsxError(xlsx_error::UNSUPPORTED,
|
|
97
|
+
"OpenXLSX only supports a single formula per cfRule (formulaIndex must be 0)");
|
|
98
|
+
}
|
|
99
|
+
if (!ruleAt(index).setFormula(formula)) {
|
|
100
|
+
throw XlsxError(xlsx_error::XLSX_ERROR, "Failed to set rule formula");
|
|
101
|
+
}
|
|
102
|
+
});
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
double HybridXlsxConditionalFormat::getRuleOperator(double index) {
|
|
106
|
+
return withXlsxError(xlsx_error::XLSX_ERROR, [&] {
|
|
107
|
+
return static_cast<double>(ruleAt(index).Operator());
|
|
108
|
+
});
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
void HybridXlsxConditionalFormat::setRuleOperator(double index, double op) {
|
|
112
|
+
withXlsxError(xlsx_error::XLSX_ERROR, [&] {
|
|
113
|
+
if (!ruleAt(index).setOperator(static_cast<OpenXLSX::XLCfOperator>(static_cast<uint8_t>(op)))) {
|
|
114
|
+
throw XlsxError(xlsx_error::XLSX_ERROR, "Failed to set rule operator");
|
|
115
|
+
}
|
|
116
|
+
});
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
std::string HybridXlsxConditionalFormat::getRuleText(double index) {
|
|
120
|
+
return withXlsxError(xlsx_error::XLSX_ERROR, [&] { return ruleAt(index).text(); });
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
void HybridXlsxConditionalFormat::setRuleText(double index, const std::string& text) {
|
|
124
|
+
withXlsxError(xlsx_error::XLSX_ERROR, [&] {
|
|
125
|
+
if (!ruleAt(index).setText(text)) {
|
|
126
|
+
throw XlsxError(xlsx_error::XLSX_ERROR, "Failed to set rule text");
|
|
127
|
+
}
|
|
128
|
+
});
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
double HybridXlsxConditionalFormat::getRulePriority(double index) {
|
|
132
|
+
return withXlsxError(xlsx_error::XLSX_ERROR, [&] {
|
|
133
|
+
return static_cast<double>(ruleAt(index).priority());
|
|
134
|
+
});
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
void HybridXlsxConditionalFormat::setRulePriority(double index, double priority) {
|
|
138
|
+
withXlsxError(xlsx_error::XLSX_ERROR, [&] {
|
|
139
|
+
auto cfRules = _format.cfRules();
|
|
140
|
+
if (!cfRules.setPriority(static_cast<size_t>(index), static_cast<uint16_t>(priority))) {
|
|
141
|
+
throw XlsxError(xlsx_error::INDEX_OUT_OF_RANGE, "Failed to set rule priority");
|
|
142
|
+
}
|
|
143
|
+
});
|
|
144
|
+
}
|
|
145
|
+
|
|
146
|
+
bool HybridXlsxConditionalFormat::getRuleStopIfTrue(double index) {
|
|
147
|
+
return withXlsxError(xlsx_error::XLSX_ERROR, [&] { return ruleAt(index).stopIfTrue(); });
|
|
148
|
+
}
|
|
149
|
+
|
|
150
|
+
void HybridXlsxConditionalFormat::setRuleStopIfTrue(double index, bool stop) {
|
|
151
|
+
withXlsxError(xlsx_error::XLSX_ERROR, [&] {
|
|
152
|
+
if (!ruleAt(index).setStopIfTrue(stop)) {
|
|
153
|
+
throw XlsxError(xlsx_error::XLSX_ERROR, "Failed to set stopIfTrue");
|
|
154
|
+
}
|
|
155
|
+
});
|
|
156
|
+
}
|
|
157
|
+
|
|
158
|
+
double HybridXlsxConditionalFormat::getRuleTimePeriod(double index) {
|
|
159
|
+
return withXlsxError(xlsx_error::XLSX_ERROR, [&] {
|
|
160
|
+
return static_cast<double>(ruleAt(index).timePeriod());
|
|
161
|
+
});
|
|
162
|
+
}
|
|
163
|
+
|
|
164
|
+
void HybridXlsxConditionalFormat::setRuleTimePeriod(double index, double period) {
|
|
165
|
+
withXlsxError(xlsx_error::XLSX_ERROR, [&] {
|
|
166
|
+
if (!ruleAt(index).setTimePeriod(static_cast<OpenXLSX::XLCfTimePeriod>(static_cast<uint8_t>(period)))) {
|
|
167
|
+
throw XlsxError(xlsx_error::XLSX_ERROR, "Failed to set timePeriod");
|
|
168
|
+
}
|
|
169
|
+
});
|
|
170
|
+
}
|
|
171
|
+
|
|
172
|
+
double HybridXlsxConditionalFormat::getRuleRank(double index) {
|
|
173
|
+
return withXlsxError(xlsx_error::XLSX_ERROR, [&] {
|
|
174
|
+
return static_cast<double>(ruleAt(index).rank());
|
|
175
|
+
});
|
|
176
|
+
}
|
|
177
|
+
|
|
178
|
+
void HybridXlsxConditionalFormat::setRuleRank(double index, double rank) {
|
|
179
|
+
withXlsxError(xlsx_error::XLSX_ERROR, [&] {
|
|
180
|
+
if (!ruleAt(index).setRank(static_cast<uint16_t>(rank))) {
|
|
181
|
+
throw XlsxError(xlsx_error::XLSX_ERROR, "Failed to set rank");
|
|
182
|
+
}
|
|
183
|
+
});
|
|
184
|
+
}
|
|
185
|
+
|
|
186
|
+
double HybridXlsxConditionalFormat::getRuleStdDev(double index) {
|
|
187
|
+
return withXlsxError(xlsx_error::XLSX_ERROR, [&] {
|
|
188
|
+
return static_cast<double>(ruleAt(index).stdDev());
|
|
189
|
+
});
|
|
190
|
+
}
|
|
191
|
+
|
|
192
|
+
void HybridXlsxConditionalFormat::setRuleStdDev(double index, double stdDev) {
|
|
193
|
+
withXlsxError(xlsx_error::XLSX_ERROR, [&] {
|
|
194
|
+
if (!ruleAt(index).setStdDev(static_cast<int16_t>(stdDev))) {
|
|
195
|
+
throw XlsxError(xlsx_error::XLSX_ERROR, "Failed to set stdDev");
|
|
196
|
+
}
|
|
197
|
+
});
|
|
198
|
+
}
|
|
199
|
+
|
|
200
|
+
bool HybridXlsxConditionalFormat::getRuleAboveAverage(double index) {
|
|
201
|
+
return withXlsxError(xlsx_error::XLSX_ERROR, [&] { return ruleAt(index).aboveAverage(); });
|
|
202
|
+
}
|
|
203
|
+
|
|
204
|
+
void HybridXlsxConditionalFormat::setRuleAboveAverage(double index, bool set) {
|
|
205
|
+
withXlsxError(xlsx_error::XLSX_ERROR, [&] {
|
|
206
|
+
if (!ruleAt(index).setAboveAverage(set)) {
|
|
207
|
+
throw XlsxError(xlsx_error::XLSX_ERROR, "Failed to set aboveAverage");
|
|
208
|
+
}
|
|
209
|
+
});
|
|
210
|
+
}
|
|
211
|
+
|
|
212
|
+
bool HybridXlsxConditionalFormat::getRulePercent(double index) {
|
|
213
|
+
return withXlsxError(xlsx_error::XLSX_ERROR, [&] { return ruleAt(index).percent(); });
|
|
214
|
+
}
|
|
215
|
+
|
|
216
|
+
void HybridXlsxConditionalFormat::setRulePercent(double index, bool set) {
|
|
217
|
+
withXlsxError(xlsx_error::XLSX_ERROR, [&] {
|
|
218
|
+
if (!ruleAt(index).setPercent(set)) {
|
|
219
|
+
throw XlsxError(xlsx_error::XLSX_ERROR, "Failed to set percent");
|
|
220
|
+
}
|
|
221
|
+
});
|
|
222
|
+
}
|
|
223
|
+
|
|
224
|
+
bool HybridXlsxConditionalFormat::getRuleBottom(double index) {
|
|
225
|
+
return withXlsxError(xlsx_error::XLSX_ERROR, [&] { return ruleAt(index).bottom(); });
|
|
226
|
+
}
|
|
227
|
+
|
|
228
|
+
void HybridXlsxConditionalFormat::setRuleBottom(double index, bool set) {
|
|
229
|
+
withXlsxError(xlsx_error::XLSX_ERROR, [&] {
|
|
230
|
+
if (!ruleAt(index).setBottom(set)) {
|
|
231
|
+
throw XlsxError(xlsx_error::XLSX_ERROR, "Failed to set bottom");
|
|
232
|
+
}
|
|
233
|
+
});
|
|
234
|
+
}
|
|
235
|
+
|
|
236
|
+
bool HybridXlsxConditionalFormat::getRuleEqualAverage(double index) {
|
|
237
|
+
return withXlsxError(xlsx_error::XLSX_ERROR, [&] { return ruleAt(index).equalAverage(); });
|
|
238
|
+
}
|
|
239
|
+
|
|
240
|
+
void HybridXlsxConditionalFormat::setRuleEqualAverage(double index, bool set) {
|
|
241
|
+
withXlsxError(xlsx_error::XLSX_ERROR, [&] {
|
|
242
|
+
if (!ruleAt(index).setEqualAverage(set)) {
|
|
243
|
+
throw XlsxError(xlsx_error::XLSX_ERROR, "Failed to set equalAverage");
|
|
244
|
+
}
|
|
245
|
+
});
|
|
246
|
+
}
|
|
247
|
+
|
|
248
|
+
std::string HybridXlsxConditionalFormat::summary() {
|
|
249
|
+
return withXlsxError(xlsx_error::XLSX_ERROR, [&] { return _format.summary(); });
|
|
250
|
+
}
|
|
251
|
+
|
|
252
|
+
} // namespace margelo::nitro::xlsx
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
#pragma once
|
|
2
|
+
|
|
3
|
+
#include "HybridXlsxConditionalFormatSpec.hpp"
|
|
4
|
+
#include <OpenXLSX/XLSheet.hpp>
|
|
5
|
+
#include <memory>
|
|
6
|
+
#include <string>
|
|
7
|
+
|
|
8
|
+
namespace margelo::nitro::xlsx {
|
|
9
|
+
|
|
10
|
+
class HybridXlsxConditionalFormat : public HybridXlsxConditionalFormatSpec {
|
|
11
|
+
public:
|
|
12
|
+
explicit HybridXlsxConditionalFormat(OpenXLSX::XLConditionalFormat format);
|
|
13
|
+
~HybridXlsxConditionalFormat() override;
|
|
14
|
+
|
|
15
|
+
std::string getSqref() override;
|
|
16
|
+
void setSqref(const std::string& sqref) override;
|
|
17
|
+
|
|
18
|
+
double getRuleCount() override;
|
|
19
|
+
double createRule() override;
|
|
20
|
+
bool deleteRule(double index) override;
|
|
21
|
+
|
|
22
|
+
double getRuleType(double index) override;
|
|
23
|
+
void setRuleType(double index, double type) override;
|
|
24
|
+
double getRuleDxfId(double index) override;
|
|
25
|
+
void setRuleDxfId(double index, double dxfId) override;
|
|
26
|
+
|
|
27
|
+
std::string getRuleFormula(double index, double formulaIndex) override;
|
|
28
|
+
void setRuleFormula(double index, double formulaIndex, const std::string& formula) override;
|
|
29
|
+
|
|
30
|
+
double getRuleOperator(double index) override;
|
|
31
|
+
void setRuleOperator(double index, double op) override;
|
|
32
|
+
std::string getRuleText(double index) override;
|
|
33
|
+
void setRuleText(double index, const std::string& text) override;
|
|
34
|
+
double getRulePriority(double index) override;
|
|
35
|
+
void setRulePriority(double index, double priority) override;
|
|
36
|
+
bool getRuleStopIfTrue(double index) override;
|
|
37
|
+
void setRuleStopIfTrue(double index, bool stop) override;
|
|
38
|
+
double getRuleTimePeriod(double index) override;
|
|
39
|
+
void setRuleTimePeriod(double index, double period) override;
|
|
40
|
+
double getRuleRank(double index) override;
|
|
41
|
+
void setRuleRank(double index, double rank) override;
|
|
42
|
+
double getRuleStdDev(double index) override;
|
|
43
|
+
void setRuleStdDev(double index, double stdDev) override;
|
|
44
|
+
bool getRuleAboveAverage(double index) override;
|
|
45
|
+
void setRuleAboveAverage(double index, bool set) override;
|
|
46
|
+
bool getRulePercent(double index) override;
|
|
47
|
+
void setRulePercent(double index, bool set) override;
|
|
48
|
+
bool getRuleBottom(double index) override;
|
|
49
|
+
void setRuleBottom(double index, bool set) override;
|
|
50
|
+
bool getRuleEqualAverage(double index) override;
|
|
51
|
+
void setRuleEqualAverage(double index, bool set) override;
|
|
52
|
+
|
|
53
|
+
std::string summary() override;
|
|
54
|
+
|
|
55
|
+
private:
|
|
56
|
+
OpenXLSX::XLConditionalFormat _format;
|
|
57
|
+
|
|
58
|
+
OpenXLSX::XLCfRule ruleAt(double index);
|
|
59
|
+
OpenXLSX::XLCfRules rules();
|
|
60
|
+
};
|
|
61
|
+
|
|
62
|
+
} // namespace margelo::nitro::xlsx
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
#include "HybridXlsxConditionalFormats.hpp"
|
|
2
|
+
#include "XlsxError.hpp"
|
|
3
|
+
|
|
4
|
+
namespace margelo::nitro::xlsx {
|
|
5
|
+
|
|
6
|
+
HybridXlsxConditionalFormats::HybridXlsxConditionalFormats(OpenXLSX::XLConditionalFormats formats)
|
|
7
|
+
: HybridObject("XlsxConditionalFormats"), HybridXlsxConditionalFormatsSpec(), _formats(std::move(formats)) {
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
HybridXlsxConditionalFormats::~HybridXlsxConditionalFormats() = default;
|
|
11
|
+
|
|
12
|
+
double HybridXlsxConditionalFormats::getCount() {
|
|
13
|
+
return withXlsxError(xlsx_error::XLSX_ERROR, [&] {
|
|
14
|
+
return static_cast<double>(_formats.count());
|
|
15
|
+
});
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
std::shared_ptr<HybridXlsxConditionalFormatSpec> HybridXlsxConditionalFormats::create(const std::string& sqref) {
|
|
19
|
+
return withXlsxError(xlsx_error::XLSX_ERROR, [&] {
|
|
20
|
+
size_t index = _formats.create();
|
|
21
|
+
OpenXLSX::XLConditionalFormat format = _formats.conditionalFormatByIndex(index);
|
|
22
|
+
format.setSqref(sqref);
|
|
23
|
+
auto hybrid = std::make_shared<HybridXlsxConditionalFormat>(format);
|
|
24
|
+
_created.push_back(hybrid);
|
|
25
|
+
return std::static_pointer_cast<HybridXlsxConditionalFormatSpec>(hybrid);
|
|
26
|
+
});
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
std::shared_ptr<HybridXlsxConditionalFormatSpec> HybridXlsxConditionalFormats::getByIndex(double index) {
|
|
30
|
+
return withXlsxError(xlsx_error::XLSX_ERROR, [&] {
|
|
31
|
+
size_t idx = static_cast<size_t>(index);
|
|
32
|
+
if (idx >= _formats.count()) {
|
|
33
|
+
throw XlsxError(xlsx_error::INDEX_OUT_OF_RANGE,
|
|
34
|
+
"conditionalFormat index " + std::to_string(idx) + " out of range (count=" + std::to_string(_formats.count()) + ")");
|
|
35
|
+
}
|
|
36
|
+
auto hybrid = std::make_shared<HybridXlsxConditionalFormat>(_formats.conditionalFormatByIndex(idx));
|
|
37
|
+
_created.push_back(hybrid);
|
|
38
|
+
return std::static_pointer_cast<HybridXlsxConditionalFormatSpec>(hybrid);
|
|
39
|
+
});
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
std::string HybridXlsxConditionalFormats::summary() {
|
|
43
|
+
return withXlsxError(xlsx_error::XLSX_ERROR, [&] { return _formats.summary(); });
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
} // namespace margelo::nitro::xlsx
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
#pragma once
|
|
2
|
+
|
|
3
|
+
#include "HybridXlsxConditionalFormatsSpec.hpp"
|
|
4
|
+
#include "HybridXlsxConditionalFormat.hpp"
|
|
5
|
+
#include <OpenXLSX/XLSheet.hpp>
|
|
6
|
+
#include <memory>
|
|
7
|
+
#include <string>
|
|
8
|
+
#include <vector>
|
|
9
|
+
|
|
10
|
+
namespace margelo::nitro::xlsx {
|
|
11
|
+
|
|
12
|
+
class HybridXlsxConditionalFormats : public HybridXlsxConditionalFormatsSpec {
|
|
13
|
+
public:
|
|
14
|
+
explicit HybridXlsxConditionalFormats(OpenXLSX::XLConditionalFormats formats);
|
|
15
|
+
~HybridXlsxConditionalFormats() override;
|
|
16
|
+
|
|
17
|
+
double getCount() override;
|
|
18
|
+
std::shared_ptr<HybridXlsxConditionalFormatSpec> create(const std::string& sqref) override;
|
|
19
|
+
std::shared_ptr<HybridXlsxConditionalFormatSpec> getByIndex(double index) override;
|
|
20
|
+
std::string summary() override;
|
|
21
|
+
|
|
22
|
+
private:
|
|
23
|
+
OpenXLSX::XLConditionalFormats _formats;
|
|
24
|
+
// Keep hybrid wrappers alive so JS holds stay valid
|
|
25
|
+
std::vector<std::shared_ptr<HybridXlsxConditionalFormat>> _created;
|
|
26
|
+
};
|
|
27
|
+
|
|
28
|
+
} // namespace margelo::nitro::xlsx
|