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"},
{"x15", "http://schemas.microsoft.com/office/spreadsheetml/2010/11/main"},
{"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/"}};

View File

@ -770,18 +770,23 @@ void xlsx_producer::write_shared_string_table(const relationship & /*rel*/)
for (const auto ws : source_)
{
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();
++column)
while (current_cell.column() <= dimension.bottom_right().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 +=
(ws.cell(xlnt::cell_reference(column, row)).data_type() == cell::type::string) ? 1 : 0;
++string_count;
}
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
@ -789,12 +794,19 @@ void xlsx_producer::write_shared_string_table(const relationship & /*rel*/)
write_attribute("count", string_count);
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())
{
if (string.runs().size() == 1 && !string.runs().at(0).second.is_set())
{
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");
continue;
@ -854,7 +866,9 @@ void xlsx_producer::write_shared_string_table(const relationship & /*rel*/)
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");
}
@ -2700,7 +2714,7 @@ void xlsx_producer::write_comments(const relationship & /*rel*/, worksheet ws, c
if (run.second.is_set())
{
write_start_element(xmlns, "rPr");
if (run.second.get().bold())
{
write_start_element(xmlns, "b");

View File

@ -28,6 +28,7 @@
#include <memory>
#include <vector>
#include <detail/constants.hpp>
#include <detail/external/include_libstudxml.hpp>
namespace xml {
@ -163,8 +164,13 @@ private:
}
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);
}