Skip to content

Commit 3ebc0ee

Browse files
authored
Merge pull request #2387 from SCIInstitute/2386-xlsx-speed
Speed up XLSX load and save by caching values rather than calling XLNT functions for each row.
2 parents 62e0988 + 0d0ef08 commit 3ebc0ee

File tree

2 files changed

+19
-4
lines changed

2 files changed

+19
-4
lines changed

Libs/Project/ExcelProjectReader.cpp

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,8 @@ class ExcelProjectReader::Container {
3232
auto rows = ws.rows(false);
3333
auto headers = rows[0];
3434

35-
for (int i = ws.lowest_row(); i < ws.highest_row(); i++) {
35+
int highest_row = ws.highest_row();
36+
for (int i = ws.lowest_row(); i < highest_row; i++) {
3637
StringMap map;
3738
bool empty = true;
3839
for (int h = 0; h < headers.length(); h++) {

Libs/Project/ExcelProjectWriter.cpp

Lines changed: 17 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
#include "ExcelProjectWriter.h"
22

33
#include <Logging.h>
4+
45
#include <xlnt/workbook/workbook_view.hpp>
56
#include <xlnt/xlnt.hpp>
67

@@ -28,8 +29,8 @@ static int get_index_for_column(xlnt::worksheet& ws, const std::string& name) {
2829
}
2930

3031
//---------------------------------------------------------------------------
31-
static void set_value(xlnt::worksheet& ws, int column, int subject_id, const std::string& value) {
32-
ws.cell(xlnt::cell_reference(column, subject_id)).value(value);
32+
static void set_value(xlnt::worksheet& ws, int column, int row, const std::string& value) {
33+
ws.cell(xlnt::cell_reference(column, row)).value(value);
3334
}
3435

3536
//---------------------------------------------------------------------------
@@ -38,18 +39,31 @@ static void set_value(xlnt::worksheet& ws, const std::string& column_name, int s
3839
set_value(ws, column_index, subject_id + 2, value); // +1 for header, +1 for 1-indexed
3940
}
4041

42+
//---------------------------------------------------------------------------
43+
static void set_subject_value(xlnt::worksheet& ws, int column_index, int subject_id, const std::string& value) {
44+
set_value(ws, column_index, subject_id + 2, value); // +1 for header, +1 for 1-indexed
45+
}
46+
4147
//---------------------------------------------------------------------------
4248
static void store_subjects(Project& project, xlnt::workbook& wb) {
4349
xlnt::worksheet ws = wb.sheet_by_index(0);
4450
ws.title("data");
4551

52+
// cache column indices for performance, get_index_for_column can be expensive
53+
std::map<std::string, int> column_map;
54+
4655
auto subjects = project.get_subjects();
4756
for (int i = 0; i < subjects.size(); i++) {
4857
auto subject = subjects[i];
4958
auto map = ProjectUtils::convert_subject_to_map(&project, subject.get());
5059

5160
for (auto& [key, value] : map) {
52-
set_value(ws, key, i, value);
61+
if (column_map.find(key) == column_map.end()) {
62+
int column_index = get_index_for_column(ws, key);
63+
column_map[key] = column_index;
64+
}
65+
66+
set_subject_value(ws, column_map[key], i, value);
5367
}
5468
}
5569
}

0 commit comments

Comments
 (0)