use xml:space=preserve when writing shared strings with trailing whitespace

This commit is contained in:
Thomas Fussell 2017-05-09 08:46:12 -04:00
parent 237fdcc84b
commit f0b1e789a3
3 changed files with 32 additions and 11 deletions

View File

@ -137,7 +137,8 @@ const std::unordered_map<std::string, std::string> &constants::namespaces()
{"x14ac", "http://schemas.microsoft.com/office/spreadsheetml/2009/9/ac"}, {"x14ac", "http://schemas.microsoft.com/office/spreadsheetml/2009/9/ac"},
{"x15", "http://schemas.microsoft.com/office/spreadsheetml/2010/11/main"}, {"x15", "http://schemas.microsoft.com/office/spreadsheetml/2010/11/main"},
{"x15ac", "http://schemas.microsoft.com/office/spreadsheetml/2010/11/ac"}, {"x15ac", "http://schemas.microsoft.com/office/spreadsheetml/2010/11/ac"},
{"xml", "http://www.w3.org/XML/1998/namespace"}, {"xsi", "http://www.w3.org/2001/XMLSchema-instance"}, {"xml", "http://www.w3.org/XML/1998/namespace"},
{"xsi", "http://www.w3.org/2001/XMLSchema-instance"},
{"loext", "http://schemas.libreoffice.org/"}}; {"loext", "http://schemas.libreoffice.org/"}};

View File

@ -770,18 +770,23 @@ void xlsx_producer::write_shared_string_table(const relationship & /*rel*/)
for (const auto ws : source_) for (const auto ws : source_)
{ {
auto dimension = ws.calculate_dimension(); auto dimension = ws.calculate_dimension();
auto current_cell = dimension.top_left();
for (xlnt::row_t row = dimension.top_left().row(); row <= dimension.bottom_right().row(); ++row) while (current_cell.row() <= dimension.bottom_right().row())
{ {
for (xlnt::column_t column = dimension.top_left().column(); column <= dimension.bottom_right().column(); while (current_cell.column() <= dimension.bottom_right().column())
++column)
{ {
if (ws.has_cell(xlnt::cell_reference(column, row))) if (ws.has_cell(current_cell)
&& ws.cell(current_cell).data_type() == cell::type::string)
{ {
string_count += ++string_count;
(ws.cell(xlnt::cell_reference(column, row)).data_type() == cell::type::string) ? 1 : 0;
} }
current_cell.column_index(current_cell.column_index() + 1);
} }
current_cell.row(current_cell.row() + 1);
current_cell.column_index(dimension.top_left().column_index());
} }
} }
#pragma clang diagnostic pop #pragma clang diagnostic pop
@ -789,12 +794,19 @@ void xlsx_producer::write_shared_string_table(const relationship & /*rel*/)
write_attribute("count", string_count); write_attribute("count", string_count);
write_attribute("uniqueCount", source_.shared_strings().size()); write_attribute("uniqueCount", source_.shared_strings().size());
auto has_trailing_whitespace = [](const std::string &s)
{
return !s.empty() && (s.front() == ' ' || s.back() == ' ');
};
for (const auto &string : source_.shared_strings()) for (const auto &string : source_.shared_strings())
{ {
if (string.runs().size() == 1 && !string.runs().at(0).second.is_set()) if (string.runs().size() == 1 && !string.runs().at(0).second.is_set())
{ {
write_start_element(xmlns, "si"); write_start_element(xmlns, "si");
write_element(xmlns, "t", string.plain_text()); write_start_element(xmlns, "t");
write_characters(string.plain_text(), has_trailing_whitespace(string.plain_text()));
write_end_element(xmlns, "t");
write_end_element(xmlns, "si"); write_end_element(xmlns, "si");
continue; continue;
@ -854,7 +866,9 @@ void xlsx_producer::write_shared_string_table(const relationship & /*rel*/)
write_end_element(xmlns, "rPr"); write_end_element(xmlns, "rPr");
} }
write_element(xmlns, "t", run.first); write_start_element(xmlns, "t");
write_characters(run.first, has_trailing_whitespace(run.first));
write_end_element(xmlns, "t");
write_end_element(xmlns, "r"); write_end_element(xmlns, "r");
} }
@ -2700,7 +2714,7 @@ void xlsx_producer::write_comments(const relationship & /*rel*/, worksheet ws, c
if (run.second.is_set()) if (run.second.is_set())
{ {
write_start_element(xmlns, "rPr"); write_start_element(xmlns, "rPr");
if (run.second.get().bold()) if (run.second.get().bold())
{ {
write_start_element(xmlns, "b"); write_start_element(xmlns, "b");

View File

@ -28,6 +28,7 @@
#include <memory> #include <memory>
#include <vector> #include <vector>
#include <detail/constants.hpp>
#include <detail/external/include_libstudxml.hpp> #include <detail/external/include_libstudxml.hpp>
namespace xml { namespace xml {
@ -163,8 +164,13 @@ private:
} }
template<typename T> template<typename T>
void write_characters(T characters) void write_characters(T characters, bool preserve_whitespace = false)
{ {
if (preserve_whitespace)
{
write_attribute(xml::qname(constants::ns("xml"), "space"), "preserve");
}
current_part_serializer_->characters(characters); current_part_serializer_->characters(characters);
} }