react-native-nitro-xlsx 0.1.1 → 0.1.2

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 CHANGED
@@ -30,18 +30,77 @@ Version: 0.58.3
30
30
  License: MIT License
31
31
  Copyright (c) 2024 Marc Rousavy
32
32
 
33
+ Full MIT License text:
34
+
35
+ MIT License
36
+
37
+ Copyright (c) 2024 Marc Rousavy
38
+ Permission is hereby granted, free of charge, to any person obtaining a copy
39
+ of this software and associated documentation files (the "Software"), to deal
40
+ in the Software without restriction, including without limitation the rights
41
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
42
+ copies of the Software, and to permit persons to whom the Software is
43
+ furnished to do so, subject to the following conditions:
44
+
45
+ The above copyright notice and this permission notice shall be included in all
46
+ copies or substantial portions of the Software.
47
+
48
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
49
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
50
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
51
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
52
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
53
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
54
+ SOFTWARE.
55
+
33
56
  ================================================================================
34
57
  3. pugixml (OpenXLSX dependency)
35
58
  Repository: https://github.com/zeux/pugixml
36
59
  License: MIT License
37
60
  Copyright (c) 2006-2024 Arseny Kapoulkine
38
61
 
62
+ Full MIT License text:
63
+
64
+ MIT License
65
+
66
+ Copyright (c) 2006-2026 Arseny Kapoulkine
67
+
68
+ Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
69
+
70
+ The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
71
+
72
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
73
+
39
74
  ================================================================================
40
75
  4. Zippy (OpenXLSX dependency)
41
76
  Repository: https://github.com/troldal/Zippy
42
77
  License: MIT License
43
78
  Copyright (c) 2019 Kenneth Troldal Balslev
44
79
 
80
+ Full MIT License text:
81
+
82
+ MIT License
83
+
84
+ Copyright (c) 2019 Kenneth Troldal Balslev
85
+
86
+ Permission is hereby granted, free of charge, to any person obtaining a copy
87
+ of this software and associated documentation files (the "Software"), to deal
88
+ in the Software without restriction, including without limitation the rights
89
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
90
+ copies of the Software, and to permit persons to whom the Software is
91
+ furnished to do so, subject to the following conditions:
92
+
93
+ The above copyright notice and this permission notice shall be included in all
94
+ copies or substantial portions of the Software.
95
+
96
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
97
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
98
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
99
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
100
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
101
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
102
+ SOFTWARE.
103
+
45
104
  ================================================================================
46
105
  5. miniz (OpenXLSX dependency)
47
106
  Repository: https://github.com/richgel999/miniz
@@ -49,11 +108,13 @@ License: MIT License
49
108
  Copyright (c) 2013-2014 RAD Game Tools and Valve Software
50
109
  Copyright (c) 2010-2014 Rich Geldreich and Tenacious Software LLC
51
110
 
52
- Full standard MIT License text:
111
+ Full MIT License text:
53
112
 
54
- MIT License
113
+ Copyright 2013-2014 RAD Game Tools and Valve Software
114
+ Copyright 2010-2014 Rich Geldreich and Tenacious Software LLC
115
+
116
+ All Rights Reserved.
55
117
 
56
- Copyright (c) 2024 Marc Rousavy
57
118
  Permission is hereby granted, free of charge, to any person obtaining a copy
58
119
  of this software and associated documentation files (the "Software"), to deal
59
120
  in the Software without restriction, including without limitation the rights
@@ -61,13 +122,13 @@ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
61
122
  copies of the Software, and to permit persons to whom the Software is
62
123
  furnished to do so, subject to the following conditions:
63
124
 
64
- The above copyright notice and this permission notice shall be included in all
65
- copies or substantial portions of the Software.
125
+ The above copyright notice and this permission notice shall be included in
126
+ all copies or substantial portions of the Software.
66
127
 
67
128
  THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
68
129
  IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
69
130
  FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
70
131
  AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
71
132
  LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
72
- OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
73
- SOFTWARE.
133
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
134
+ THE SOFTWARE.
package/README.md CHANGED
@@ -34,6 +34,8 @@ No additional setup needed.
34
34
 
35
35
  ## Usage
36
36
 
37
+ > **Note**: Row and column indices are **1-based** (following Excel convention).
38
+
37
39
  ### Creating a Workbook
38
40
 
39
41
  ```typescript
@@ -53,27 +55,27 @@ headerFormat.setFgColor(Colors.BLUE);
53
55
  headerFormat.setAlign(Align.CENTER);
54
56
 
55
57
  // Write headers
56
- sheet.writeString(0, 0, 'Name', headerFormat);
57
- sheet.writeString(0, 1, 'Price', headerFormat);
58
- sheet.writeString(0, 2, 'Total', headerFormat);
58
+ sheet.writeString(1, 1, 'Name', headerFormat);
59
+ sheet.writeString(1, 2, 'Price', headerFormat);
60
+ sheet.writeString(1, 3, 'Total', headerFormat);
59
61
 
60
62
  // Write data
61
- sheet.writeString(1, 0, 'Apple');
62
- sheet.writeNumber(1, 1, 1.50);
63
- sheet.writeFormula(1, 2, '=B2*1.1');
63
+ sheet.writeString(2, 1, 'Apple');
64
+ sheet.writeNumber(2, 2, 1.50);
65
+ sheet.writeFormula(2, 3, '=B2*1.1');
64
66
 
65
- sheet.writeString(2, 0, 'Orange');
66
- sheet.writeNumber(2, 1, 2.00);
67
- sheet.writeFormula(2, 2, '=B3*1.1');
67
+ sheet.writeString(3, 1, 'Orange');
68
+ sheet.writeNumber(3, 2, 2.00);
69
+ sheet.writeFormula(3, 3, '=B3*1.1');
68
70
 
69
71
  // Date example
70
72
  const date = new Date(2024, 0, 15);
71
73
  const excelDate = (date.getTime() / 86400000) + 25569; // Convert to Excel date
72
- sheet.writeDatetime(3, 0, excelDate);
74
+ sheet.writeDatetime(4, 1, excelDate);
73
75
 
74
76
  // Set column widths
75
- sheet.setColumn(0, 0, 15);
76
- sheet.setColumn(1, 2, 12);
77
+ sheet.setColumn(1, 1, 15);
78
+ sheet.setColumn(2, 3, 12);
77
79
 
78
80
  // Get the buffer and do something with it
79
81
  const buffer = await workbook.getBuffer();
@@ -104,8 +106,8 @@ const lastRow = sheet.getLastRow();
104
106
  const lastCol = sheet.getLastColumn();
105
107
 
106
108
  // Read cell values
107
- for (let row = 0; row <= lastRow; row++) {
108
- for (let col = 0; col <= lastCol; col++) {
109
+ for (let row = 1; row <= lastRow; row++) {
110
+ for (let col = 1; col <= lastCol; col++) {
109
111
  const value = sheet.getCellValue(row, col);
110
112
  const type = sheet.getCellType(row, col);
111
113
  const strValue = sheet.getCellString(row, col);
@@ -114,7 +116,7 @@ for (let row = 0; row <= lastRow; row++) {
114
116
  }
115
117
 
116
118
  // Read cell format
117
- const format = sheet.getCellFormat(0, 0);
119
+ const format = sheet.getCellFormat(1, 1);
118
120
  const isBold = format.getIsBold();
119
121
  const fontName = format.getFontName();
120
122
  const fontSize = format.getFontSize();
@@ -124,7 +126,7 @@ const fontSize = format.getFontSize();
124
126
 
125
127
  ### NitroXlsx
126
128
 
127
- - `createWorkbook(): XlsxWorkbook` - Create a new workbook
129
+ - `createWorkbook(tempDir?: string): XlsxWorkbook` - Create a new workbook. On Android, pass the app's cache directory (e.g., `RNFS.CachesDirectoryPath`) to avoid sandbox write permission issues.
128
130
  - `openWorkbook(path: string): XlsxWorkbook` - Open workbook from file path
129
131
  - `openWorkbookFromBuffer(buffer: ArrayBuffer): XlsxWorkbook` - Open workbook from buffer
130
132
 
@@ -140,6 +142,8 @@ const fontSize = format.getFontSize();
140
142
 
141
143
  ### XlsxWorksheet
142
144
 
145
+ > **Note**: All row and column indices are **1-based** (following Excel convention).
146
+
143
147
  #### Basic Write Methods
144
148
  | Method | Description |
145
149
  |--------|-------------|
@@ -6,17 +6,40 @@ set(CMAKE_CXX_STANDARD_REQUIRED ON)
6
6
 
7
7
  set(OPENXLSX_DIR ${CMAKE_SOURCE_DIR}/../OpenXLSX)
8
8
  if(NOT EXISTS ${OPENXLSX_DIR}/CMakeLists.txt)
9
+ # Clean up incomplete directory to ensure fresh clone
10
+ if(EXISTS ${OPENXLSX_DIR})
11
+ file(REMOVE_RECURSE ${OPENXLSX_DIR})
12
+ endif()
13
+
9
14
  include(FetchContent)
10
15
  FetchContent_Declare(
11
16
  OpenXLSX
12
17
  GIT_REPOSITORY https://github.com/troldal/OpenXLSX.git
13
18
  GIT_TAG v0.5.1
19
+ SOURCE_DIR ${OPENXLSX_DIR}
20
+ GIT_SHALLOW TRUE
21
+ GIT_PROGRESS TRUE
22
+ )
23
+ FetchContent_Populate(OpenXLSX)
24
+ endif()
25
+
26
+ # Verify OpenXLSX is available
27
+ if(NOT EXISTS ${OPENXLSX_DIR}/CMakeLists.txt)
28
+ message(FATAL_ERROR
29
+ "OpenXLSX not found at ${OPENXLSX_DIR}.\n"
30
+ "Please manually clone OpenXLSX:\n"
31
+ " cd ${CMAKE_SOURCE_DIR}/.. && git clone --depth 1 --branch v0.5.1 https://github.com/troldal/OpenXLSX.git OpenXLSX\n"
32
+ "Then clean CMake cache and rebuild."
33
+ )
34
+ endif()
35
+
36
+ # Create symlink for #include <OpenXLSX/XXX.hpp> resolution
37
+ # Same as iOS podspec: cd OpenXLSX/OpenXLSX/headers && ln -sf . OpenXLSX
38
+ if(NOT EXISTS ${OPENXLSX_DIR}/OpenXLSX/headers/OpenXLSX)
39
+ execute_process(
40
+ COMMAND ${CMAKE_COMMAND} -E create_symlink . OpenXLSX
41
+ WORKING_DIRECTORY ${OPENXLSX_DIR}/OpenXLSX/headers
14
42
  )
15
- FetchContent_GetProperties(OpenXLSX)
16
- if(NOT OpenXLSX_POPULATED)
17
- FetchContent_Populate(OpenXLSX)
18
- endif()
19
- set(OPENXLSX_DIR ${openxlsx_SOURCE_DIR})
20
43
  endif()
21
44
 
22
45
  set(OPENXLSX_BUILD_SAMPLES OFF CACHE BOOL "" FORCE)
@@ -12,6 +12,7 @@ class NitroXlsxPackage : ReactPackage {
12
12
  }
13
13
  }
14
14
 
15
+ @Suppress("OVERRIDE_DEPRECATION")
15
16
  override fun createNativeModules(reactContext: ReactApplicationContext): List<NativeModule> {
16
17
  return emptyList()
17
18
  }
@@ -10,8 +10,8 @@ HybridNitroXlsx::HybridNitroXlsx()
10
10
  HybridNitroXlsx::~HybridNitroXlsx() {
11
11
  }
12
12
 
13
- std::shared_ptr<HybridXlsxWorkbookSpec> HybridNitroXlsx::createWorkbook() {
14
- return std::make_shared<HybridXlsxWorkbook>();
13
+ std::shared_ptr<HybridXlsxWorkbookSpec> HybridNitroXlsx::createWorkbook(const std::optional<std::string>& tempDir) {
14
+ return std::make_shared<HybridXlsxWorkbook>(tempDir);
15
15
  }
16
16
 
17
17
  std::shared_ptr<HybridXlsxWorkbookSpec> HybridNitroXlsx::openWorkbook(const std::string& path) {
@@ -11,7 +11,7 @@ public:
11
11
  HybridNitroXlsx();
12
12
  ~HybridNitroXlsx() override;
13
13
 
14
- std::shared_ptr<HybridXlsxWorkbookSpec> createWorkbook() override;
14
+ std::shared_ptr<HybridXlsxWorkbookSpec> createWorkbook(const std::optional<std::string>& tempDir = std::nullopt) 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
17
  };
@@ -1,6 +1,7 @@
1
1
  #include "HybridXlsxCellFormat.hpp"
2
2
  #include <sstream>
3
3
  #include <iomanip>
4
+ #include <cctype>
4
5
 
5
6
  namespace margelo::nitro::xlsx {
6
7
 
@@ -10,7 +11,12 @@ static std::string doubleToHexColor(double color) {
10
11
  uint32_t argb = c | 0xFF000000;
11
12
  std::stringstream ss;
12
13
  ss << std::hex << std::setfill('0') << std::setw(8) << argb;
13
- return ss.str();
14
+ std::string result = ss.str();
15
+ // Convert to uppercase (OpenXLSX expects uppercase hex)
16
+ for (char& ch : result) {
17
+ ch = std::toupper(ch);
18
+ }
19
+ return result;
14
20
  }
15
21
 
16
22
  HybridXlsxCellFormat::HybridXlsxCellFormat()
@@ -21,11 +27,23 @@ HybridXlsxCellFormat::~HybridXlsxCellFormat() {
21
27
  }
22
28
 
23
29
  OpenXLSX::XLStyleIndex HybridXlsxCellFormat::applyToDocument(OpenXLSX::XLStyles& styles) {
24
- OpenXLSX::XLCellFormat cellFormat;
30
+ if (_styleIndex.has_value()) {
31
+ return *_styleIndex;
32
+ }
33
+
34
+ // Create cell format in document first to get a valid XML node.
35
+ // OpenXLSX default-constructed style objects have empty XML nodes;
36
+ // setters on empty nodes silently fail. We must create the node in
37
+ // the document first, then modify the live node via operator[].
38
+ OpenXLSX::XLCellFormat emptyCellFormat;
39
+ OpenXLSX::XLStyleIndex cellFormatIndex = styles.cellFormats().create(emptyCellFormat);
40
+ OpenXLSX::XLCellFormat cellFormat = styles.cellFormats()[cellFormatIndex];
25
41
 
26
42
  // Font
27
43
  if (!_fontName.empty() || _fontSize > 0 || _fontColor > 0 || _bold || _italic || _underline > 0 || _strikeout || _fontScript > 0) {
28
- OpenXLSX::XLFont font;
44
+ OpenXLSX::XLFont emptyFont;
45
+ OpenXLSX::XLStyleIndex fontIndex = styles.fonts().create(emptyFont);
46
+ OpenXLSX::XLFont font = styles.fonts()[fontIndex];
29
47
  if (!_fontName.empty()) font.setFontName(_fontName);
30
48
  if (_fontSize > 0) font.setFontSize(static_cast<size_t>(_fontSize));
31
49
  if (_fontColor > 0) font.setFontColor(OpenXLSX::XLColor(doubleToHexColor(_fontColor)));
@@ -34,49 +52,55 @@ OpenXLSX::XLStyleIndex HybridXlsxCellFormat::applyToDocument(OpenXLSX::XLStyles&
34
52
  if (_underline > 0) font.setUnderline(static_cast<OpenXLSX::XLUnderlineStyle>(_underline));
35
53
  if (_strikeout) font.setStrikethrough();
36
54
  if (_fontScript > 0) font.setVertAlign(static_cast<OpenXLSX::XLVerticalAlignRunStyle>(_fontScript));
37
- cellFormat.setFontIndex(styles.fonts().create(font));
55
+ cellFormat.setFontIndex(fontIndex);
38
56
  cellFormat.setApplyFont(true);
39
57
  }
40
58
 
41
59
  // Alignment
42
60
  if (_textWrap || _rotation != 0 || _indent > 0 || _align > 0 || _verticalAlign > 0 || _shrink) {
43
- auto alignment = cellFormat.alignment(true);
44
- if (_align > 0) alignment.setHorizontal(static_cast<OpenXLSX::XLAlignmentStyle>(_align));
45
- if (_verticalAlign > 0) alignment.setVertical(static_cast<OpenXLSX::XLAlignmentStyle>(_verticalAlign));
46
- if (_textWrap) alignment.setWrapText();
47
- if (_rotation != 0) alignment.setTextRotation(static_cast<uint16_t>(_rotation));
48
- if (_indent > 0) alignment.setIndent(static_cast<uint32_t>(_indent));
49
- if (_shrink) alignment.setShrinkToFit();
61
+ if (_align > 0) cellFormat.alignment(true).setHorizontal(static_cast<OpenXLSX::XLAlignmentStyle>(_align));
62
+ if (_verticalAlign > 0) cellFormat.alignment(true).setVertical(static_cast<OpenXLSX::XLAlignmentStyle>(_verticalAlign));
63
+ if (_textWrap) cellFormat.alignment(true).setWrapText();
64
+ if (_rotation != 0) cellFormat.alignment(true).setTextRotation(static_cast<uint16_t>(_rotation));
65
+ if (_indent > 0) cellFormat.alignment(true).setIndent(static_cast<uint32_t>(_indent));
66
+ if (_shrink) cellFormat.alignment(true).setShrinkToFit();
50
67
  cellFormat.setApplyAlignment(true);
51
68
  }
52
69
 
53
70
  // Number format
54
71
  if (!_numFormat.empty()) {
55
- OpenXLSX::XLNumberFormat numFormat;
72
+ OpenXLSX::XLNumberFormat emptyNumFormat;
73
+ OpenXLSX::XLStyleIndex numFmtIndex = styles.numberFormats().create(emptyNumFormat);
74
+ OpenXLSX::XLNumberFormat numFormat = styles.numberFormats()[numFmtIndex];
56
75
  numFormat.setFormatCode(_numFormat);
57
- OpenXLSX::XLStyleIndex numFmtIndex = styles.numberFormats().create(numFormat);
58
- uint32_t numFmtId = styles.numberFormats().numberFormatIdFromIndex(numFmtIndex);
59
- cellFormat.setNumberFormatId(numFmtId);
76
+ // Assign a unique custom numFmtId (>= 164 for user-defined formats)
77
+ static uint32_t nextCustomNumFmtId = 164;
78
+ numFormat.setNumberFormatId(nextCustomNumFmtId++);
79
+ cellFormat.setNumberFormatId(numFormat.numberFormatId());
60
80
  cellFormat.setApplyNumberFormat(true);
61
81
  }
62
82
 
63
83
  // Fill
64
84
  if (_bgColor > 0 || _fgColor > 0 || _pattern > 0) {
65
- OpenXLSX::XLFill fill;
85
+ OpenXLSX::XLFill emptyFill;
86
+ OpenXLSX::XLStyleIndex fillIndex = styles.fills().create(emptyFill);
87
+ OpenXLSX::XLFill fill = styles.fills()[fillIndex];
66
88
  fill.setPatternType(_pattern > 0
67
89
  ? static_cast<OpenXLSX::XLPatternType>(_pattern)
68
90
  : OpenXLSX::XLPatternType::XLPatternSolid);
69
91
  if (_bgColor > 0) fill.setBackgroundColor(OpenXLSX::XLColor(doubleToHexColor(_bgColor)));
70
92
  if (_fgColor > 0) fill.setColor(OpenXLSX::XLColor(doubleToHexColor(_fgColor)));
71
- cellFormat.setFillIndex(styles.fills().create(fill));
93
+ cellFormat.setFillIndex(fillIndex);
72
94
  cellFormat.setApplyFill(true);
73
95
  }
74
96
 
75
97
  // Border
76
98
  if (_border > 0 || _bottom > 0 || _top > 0 || _left > 0 || _right > 0 || _diagonal > 0) {
77
- OpenXLSX::XLBorder border;
99
+ OpenXLSX::XLBorder emptyBorder;
100
+ OpenXLSX::XLStyleIndex borderIndex = styles.borders().create(emptyBorder);
101
+ OpenXLSX::XLBorder border = styles.borders()[borderIndex];
78
102
  // TODO: Implement border styling with OpenXLSX v0.5.1 API
79
- cellFormat.setBorderIndex(styles.borders().create(border));
103
+ cellFormat.setBorderIndex(borderIndex);
80
104
  cellFormat.setApplyBorder(true);
81
105
  }
82
106
 
@@ -86,7 +110,8 @@ OpenXLSX::XLStyleIndex HybridXlsxCellFormat::applyToDocument(OpenXLSX::XLStyles&
86
110
  cellFormat.setApplyProtection(true);
87
111
  }
88
112
 
89
- return styles.cellFormats().create(cellFormat);
113
+ _styleIndex = cellFormatIndex;
114
+ return cellFormatIndex;
90
115
  }
91
116
 
92
117
  void HybridXlsxCellFormat::applyToCell(OpenXLSX::XLCell& cell, OpenXLSX::XLStyleIndex styleIndex) {
@@ -68,6 +68,7 @@ public:
68
68
  double getBgColor() override;
69
69
 
70
70
  private:
71
+ std::optional<OpenXLSX::XLStyleIndex> _styleIndex;
71
72
  std::string _fontName;
72
73
  double _fontSize = 0;
73
74
  double _fontColor = 0;
@@ -40,10 +40,14 @@ namespace {
40
40
  }
41
41
  }
42
42
 
43
- HybridXlsxWorkbook::HybridXlsxWorkbook()
43
+ HybridXlsxWorkbook::HybridXlsxWorkbook(const std::optional<std::string>& tempDir)
44
44
  : HybridObject("XlsxWorkbook"), HybridXlsxWorkbookSpec(), _finalized(false) {
45
45
  _workbook = std::make_unique<OpenXLSX::XLDocument>();
46
- _tempDir = getTempDir();
46
+ if (tempDir.has_value()) {
47
+ _tempDir = *tempDir;
48
+ } else {
49
+ _tempDir = getTempDir();
50
+ }
47
51
  }
48
52
 
49
53
  HybridXlsxWorkbook::~HybridXlsxWorkbook() {
@@ -93,7 +97,8 @@ std::shared_ptr<HybridXlsxWorksheetSpec> HybridXlsxWorkbook::addWorksheet(const
93
97
  sheetName = *name;
94
98
  auto it = _worksheetNames.find(sheetName);
95
99
  if (it != _worksheetNames.end()) {
96
- throw std::runtime_error("Sheet named '" + sheetName + "' already exists");
100
+ // Worksheet already exists (e.g., default Sheet1 created by OpenXLSX), return it
101
+ return it->second;
97
102
  }
98
103
  } else {
99
104
  int idx = 1;
@@ -13,7 +13,7 @@ namespace margelo::nitro::xlsx {
13
13
 
14
14
  class HybridXlsxWorkbook : public HybridXlsxWorkbookSpec {
15
15
  public:
16
- HybridXlsxWorkbook();
16
+ HybridXlsxWorkbook(const std::optional<std::string>& tempDir = std::nullopt);
17
17
  ~HybridXlsxWorkbook() override;
18
18
 
19
19
  void openFromFile(const std::string& path);
@@ -104,7 +104,9 @@ void HybridXlsxWorksheet::mergeRange(double firstRow, double firstCol, double la
104
104
  OpenXLSX::XLCellReference bottomRight(static_cast<unsigned int>(lastRow), static_cast<unsigned int>(lastCol));
105
105
  OpenXLSX::XLCellRange range = _worksheet.range(topLeft, bottomRight);
106
106
  _worksheet.mergeCells(range);
107
- _worksheet.cell(static_cast<unsigned int>(firstRow), static_cast<unsigned int>(firstCol)).value() = value;
107
+ OpenXLSX::XLCell cell = _worksheet.cell(static_cast<unsigned int>(firstRow), static_cast<unsigned int>(firstCol));
108
+ cell.value() = value;
109
+ applyFormat(cell, format);
108
110
  }
109
111
 
110
112
  void HybridXlsxWorksheet::mergeRangeNum(double firstRow, double firstCol, double lastRow, double lastCol, double value, const std::optional<std::shared_ptr<HybridXlsxCellFormatSpec>>& format) {
@@ -112,7 +114,9 @@ void HybridXlsxWorksheet::mergeRangeNum(double firstRow, double firstCol, double
112
114
  OpenXLSX::XLCellReference bottomRight(static_cast<unsigned int>(lastRow), static_cast<unsigned int>(lastCol));
113
115
  OpenXLSX::XLCellRange range = _worksheet.range(topLeft, bottomRight);
114
116
  _worksheet.mergeCells(range);
115
- _worksheet.cell(static_cast<unsigned int>(firstRow), static_cast<unsigned int>(firstCol)).value() = value;
117
+ OpenXLSX::XLCell cell = _worksheet.cell(static_cast<unsigned int>(firstRow), static_cast<unsigned int>(firstCol));
118
+ cell.value() = value;
119
+ applyFormat(cell, format);
116
120
  }
117
121
 
118
122
  void HybridXlsxWorksheet::insertImage(double row, double col, const std::string& path, std::optional<double> xOffset, std::optional<double> yOffset, std::optional<double> xScale, std::optional<double> yScale) {
@@ -19,6 +19,7 @@ namespace margelo::nitro::xlsx { class HybridXlsxWorkbookSpec; }
19
19
  #include <memory>
20
20
  #include "HybridXlsxWorkbookSpec.hpp"
21
21
  #include <string>
22
+ #include <optional>
22
23
  #include <NitroModules/ArrayBuffer.hpp>
23
24
 
24
25
  namespace margelo::nitro::xlsx {
@@ -52,7 +53,7 @@ namespace margelo::nitro::xlsx {
52
53
 
53
54
  public:
54
55
  // Methods
55
- virtual std::shared_ptr<HybridXlsxWorkbookSpec> createWorkbook() = 0;
56
+ virtual std::shared_ptr<HybridXlsxWorkbookSpec> createWorkbook(const std::optional<std::string>& tempDir) = 0;
56
57
  virtual std::shared_ptr<HybridXlsxWorkbookSpec> openWorkbook(const std::string& path) = 0;
57
58
  virtual std::shared_ptr<HybridXlsxWorkbookSpec> openWorkbookFromBuffer(const std::shared_ptr<ArrayBuffer>& buffer) = 0;
58
59
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "react-native-nitro-xlsx",
3
- "version": "0.1.1",
3
+ "version": "0.1.2",
4
4
  "description": "Fast XLSX file reading and writing for React Native using OpenXLSX and Nitro Modules",
5
5
  "license": "MIT",
6
6
  "homepage": "https://github.com/zydbkqf/react-native-nitro-xlsx",
@@ -148,7 +148,7 @@ export interface XlsxCellFormat extends HybridObject<{ ios: 'c++'; android: 'c++
148
148
  }
149
149
 
150
150
  export interface NitroXlsx extends HybridObject<{ ios: 'c++'; android: 'c++' }> {
151
- createWorkbook(): XlsxWorkbook
151
+ createWorkbook(tempDir?: string): XlsxWorkbook
152
152
  openWorkbook(path: string): XlsxWorkbook
153
153
  openWorkbookFromBuffer(buffer: ArrayBuffer): XlsxWorkbook
154
154
  }