FOSSredder 0.5.0
Loading...
Searching...
No Matches
XlsxExporter.cpp
Go to the documentation of this file.
1
5
7
9#include "ExportConstants.h"
11
12#include <vector>
13
15
16namespace export_ports = core::ports::exporting;
17
18namespace {
19
20bool shouldStop(const export_ports::ExportRequest &request) {
21 if (request.waitIfPaused) {
22 request.waitIfPaused();
23 }
24 return request.shouldCancel && request.shouldCancel();
25}
26
27export_ports::ExportResult canceledResult(
28 const export_ports::ExportRequest &request) {
29 export_ports::ExportResult result;
30 result.actualFormat = export_ports::ExportFormat::Xlsx;
31 result.resolvedOutputPath = request.outputPath;
32 result.status = export_ports::ExportStatus::Canceled;
33 result.message = "Canceled";
34 return result;
35}
36
37std::string columnRef(int column) {
38 std::string ref;
39 while (column > 0) {
40 const int remainder = (column - 1) % 26;
41 ref.insert(ref.begin(), static_cast<char>('A' + remainder));
42 column = (column - 1) / 26;
43 }
44 return ref;
45}
46
47std::vector<std::vector<std::string>>
48buildRows(const internal::PropertyContractMatrix &matrix,
49 bool includeFormulas) {
50 std::vector<std::vector<std::string>> rows;
51 std::vector<std::string> header;
52 header.push_back(
54 header.insert(header.end(), matrix.propertyNames.begin(),
55 matrix.propertyNames.end());
57 rows.push_back(std::move(header));
58
59 std::vector<double> columnSums(matrix.propertyNames.size(), 0.0);
60 int rowIndex = 2;
61 for (const auto &contractType : matrix.contractTypes) {
62 std::vector<std::string> row;
63 row.reserve(matrix.propertyNames.size() + 2);
64 row.push_back(contractType);
65
66 double rowSum = 0.0;
67 for (size_t column = 0; column < matrix.propertyNames.size(); ++column) {
68 double value = 0.0;
69 const auto propertyIt =
70 matrix.amountsByProperty.find(matrix.propertyNames[column]);
71 if (propertyIt != matrix.amountsByProperty.end()) {
72 const auto contractIt = propertyIt->second.find(contractType);
73 if (contractIt != propertyIt->second.end()) {
74 value = contractIt->second;
75 }
76 }
77 row.push_back(std::to_string(value));
78 columnSums[column] += value;
79 rowSum += value;
80 }
81 if (includeFormulas && !matrix.propertyNames.empty()) {
82 row.push_back(
83 "=SUM(" + columnRef(2) + std::to_string(rowIndex) + ":" +
84 columnRef(static_cast<int>(1 + matrix.propertyNames.size())) +
85 std::to_string(rowIndex) + ")");
86 } else {
87 row.push_back(std::to_string(rowSum));
88 }
89 rows.push_back(std::move(row));
90 ++rowIndex;
91 }
92
93 if (!matrix.propertyNames.empty()) {
94 std::vector<std::string> totalRow;
95 totalRow.reserve(matrix.propertyNames.size() + 2);
96 totalRow.push_back(
98
99 double grandTotal = 0.0;
100 for (double value : columnSums) {
101 totalRow.push_back(std::to_string(value));
102 grandTotal += value;
103 }
104 if (includeFormulas && !matrix.contractTypes.empty()) {
105 totalRow.push_back(
106 "=SUM(" +
107 columnRef(static_cast<int>(2 + matrix.propertyNames.size())) +
108 "2:" + columnRef(static_cast<int>(2 + matrix.propertyNames.size())) +
109 std::to_string(rowIndex - 1) + ")");
110 } else {
111 totalRow.push_back(std::to_string(grandTotal));
112 }
113 rows.push_back(std::move(totalRow));
114 }
115
116 return rows;
117}
118
119} // namespace
120
122 std::shared_ptr<core::ports::xlsx_writer::IXlsxWriter> writer)
123 : writer_(std::move(writer)) {}
124
125export_ports::ExportResult
128 const export_ports::ExportRequest &request) const {
129 export_ports::ExportResult result;
130 result.actualFormat = export_ports::ExportFormat::Xlsx;
131 result.resolvedOutputPath = request.outputPath;
132
133 try {
134 if (shouldStop(request)) {
135 return canceledResult(request);
136 }
137 if (request.outputPath.empty()) {
138 result.status = export_ports::ExportStatus::InvalidInput;
139 result.errorCode =
141 result.message =
143 return result;
144 }
145 if (!writer_) {
146 result.status = export_ports::ExportStatus::XlsxGenerationFailed;
147 result.errorCode = std::string(
149 result.message = std::string(
151 return result;
152 }
153
154 const auto matrix = internal::buildPropertyContractMatrix(state);
155 if (shouldStop(request)) {
156 return canceledResult(request);
157 }
158 const auto rows = buildRows(matrix, request.includeFormulas);
159 if (shouldStop(request)) {
160 return canceledResult(request);
161 }
162
163 if (!writer_->writeTable(request.outputPath, rows, "Export")) {
164 result.status = export_ports::ExportStatus::XlsxGenerationFailed;
165 result.errorCode = std::string(
167 result.message = std::string(
169 return result;
170 }
171
172 result.status = export_ports::ExportStatus::Ok;
173 result.success = true;
174 } catch (...) {
175 result.status = export_ports::ExportStatus::XlsxGenerationFailed;
176 result.errorCode =
178 result.message = std::string(
180 }
181
182 return result;
183}
184
185} // namespace core::application::exporting
Defines private constants shared by core export implementations.
Declares the XLSX writing port used by the export layer.
Declares private helpers for building export matrix data from workspace state.
Declares XLSX export for the property/contract-type matrix.
XlsxExporter(std::shared_ptr< core::ports::xlsx_writer::IXlsxWriter > writer={})
core::ports::exporting::ExportResult exportData(const core::domain::catalog::WorkspaceCatalog &state, const core::ports::exporting::ExportRequest &request) const
Exports the property/contract matrix to an XLSX file.
PropertyContractMatrix buildPropertyContractMatrix(const core::domain::catalog::WorkspaceCatalog &state)
Builds the property/contract matrix from the current workspace snapshot.