73 const export_ports::ExportRequest &request)
const {
74 export_ports::ExportResult result;
76 result.resolvedOutputPath = request.outputPath;
78 if (shouldStop(request)) {
79 return canceledResult(request);
82 if (request.outputPath.empty()) {
83 result.status = export_ports::ExportStatus::InvalidInput;
92 char decimalSeparator =
'.';
93 if (request.locale.starts_with(kGermanLocalePrefix)) {
94 decimalSeparator =
',';
96 constexpr char separator =
';';
98 std::ofstream output(request.outputPath, std::ios::binary);
100 result.status = export_ports::ExportStatus::WriteFailed;
108 const unsigned char bom[] = {0xEF, 0xBB, 0xBF};
109 output.write(
reinterpret_cast<const char *
>(bom),
sizeof(bom));
111 const auto formatAmount = [&](
double value) {
112 std::ostringstream stream;
113 stream << std::fixed << std::setprecision(2) << value;
114 std::string text = stream.str();
115 if (decimalSeparator !=
'.') {
116 for (
auto &c : text) {
118 c = decimalSeparator;
126 for (
const auto &contractType : matrix.contractTypes) {
127 output << separator << escapeCsv(contractType, separator);
132 for (
const auto &propertyName : matrix.propertyNames) {
133 if (shouldStop(request)) {
134 return canceledResult(request);
136 output << escapeCsv(propertyName, separator);
138 const auto propertyIt = matrix.amountsByProperty.find(propertyName);
139 for (
const auto &contractType : matrix.contractTypes) {
141 if (propertyIt != matrix.amountsByProperty.end()) {
142 const auto contractIt = propertyIt->second.find(contractType);
143 if (contractIt != propertyIt->second.end()) {
144 value = contractIt->second;
147 output << separator << formatAmount(value);
150 output << separator << formatAmount(rowSum) <<
"\n";
155 result.status = export_ports::ExportStatus::WriteFailed;
163 result.status = export_ports::ExportStatus::Ok;
164 result.success =
true;