Compare commits

...

2 Commits

Author SHA1 Message Date
3cde3a4444 OdfFormatReader - fix after testing 2018-11-22 19:27:58 +03:00
eb2221f006 Fix previous commit 2018-11-22 11:30:02 +03:00
14 changed files with 143 additions and 69 deletions

View File

@ -508,10 +508,8 @@ namespace formulasconvert {
void odf2oox_converter::Impl::split_distance_by(const std::wstring& expr, const std::wstring& by, std::vector<std::wstring>& out)
{
std::wstring workstr = expr;
boost::regex_replace(
workstr,
std::wstring workstr = boost::regex_replace(
expr,
boost::wregex(L"('.*?')|(\".*?\")"),
&convert_scobci, boost::match_default | boost::format_all);
@ -529,10 +527,8 @@ namespace formulasconvert {
std::wstring odf2oox_converter::Impl::convert_chart_distance(const std::wstring& expr)
{
std::wstring workstr = is_forbidden(expr);
boost::regex_replace(
workstr,
std::wstring workstr = boost::regex_replace(
is_forbidden(expr),
boost::wregex(L"('.*?')|(\".*?\")"),
&convert_scobci, boost::match_default | boost::format_all);

View File

@ -46,7 +46,6 @@ namespace oox {
xlsx_defined_names();
~xlsx_defined_names();
public:
void add(std::wstring const & name, std::wstring const & ref, bool formula, int tableId);
void xlsx_serialize(std::wostream & _Wostream);

View File

@ -302,12 +302,24 @@ void xlsx_pivots_context::Impl::calc_headers()
std::map<size_t, size_t>::iterator pFind;
//current_.bAxisCol = false;
//current_.bAxisRow = false;
size_t min_col = 0xffffff, min_row = 0xffffff;
size_t prev_col, prev_row;
for (size_t i = 0; i < current_.headers.size(); i++)//("F18","F19","F23","G21","H21")
{
size_t row = 0, col = 0;
oox::getCellAddressInv(current_.headers[i], col, row);
//if (i > 0)
//{
// if (col != prev_col)current_.bAxisCol = true;
// if (row != prev_row)current_.bAxisRow = true;
//}
prev_col = col;
prev_row = row;
if (col < min_col) min_col = col;
if (row < min_row) min_row = row;
@ -578,10 +590,10 @@ void xlsx_pivots_context::Impl::sort_fields()
i--;
}
}
if ((bAddRepeateCol || (count_items_col == 0 && current_.bAxisCol))/* && bShowEmptyCol*/) ///* || (bEmptyColCache && current_.grand_total < 0)*/?? Financial Execution (template).ods
if ((bAddRepeateCol || (count_items_col == 0 && current_.bAxisCol)) && (current_.grand_total == 1 || current_.grand_total == 2))/* && bShowEmptyCol*/ ///* || (bEmptyColCache && current_.grand_total < 0)*/?? Financial Execution (template).ods
current_.col_fields.push_back(-2);
if ((bAddRepeateRow || (count_items_row == 0 && current_.bAxisRow))/* && bShowEmptyRow*/)
if ((bAddRepeateRow || (count_items_row == 0 && current_.bAxisRow)) && (current_.grand_total == 1 || current_.grand_total == 3))/* && bShowEmptyRow*/
current_.row_fields.push_back(-2);
}
void xlsx_pivots_context::Impl::serialize_view(std::wostream & strm)

View File

@ -87,15 +87,17 @@ public:
class xlsx_data_range
{
public:
xlsx_data_range() : byRow(true), filter(false), withHeader(false), cell_start(0,0), cell_end(0,0) {}
xlsx_data_range() : byRow(true), filter(false), bTablePart(true), withHeader(false), cell_start(0,0), cell_end(0,0) {}
std::wstring table_name;
std::wstring name;
std::wstring ref;
std::pair<int, int> cell_start;
std::pair<int, int> cell_end;
bool bTablePart;
bool byRow;
bool filter;
bool withHeader;

View File

@ -60,23 +60,20 @@ xlsx_table_state_ptr xlsx_table_context::state()
return xlsx_table_state_ptr();
}
void xlsx_table_context::start_database_range(std::wstring tableName, std::wstring ref)
bool xlsx_table_context::start_database_range(const std::wstring & name, const std::wstring & ref)
{
formulasconvert::odf2oox_converter convert;
ref = convert.convert_named_ref(ref);
std::wstring odf_ref = convert.convert_named_ref(ref);
std::wstring ref1, ref2;
size_t pos = ref.find(L":");
size_t pos = odf_ref.find(L":");
std::wstring xlsx_table_name;
if (pos != std::wstring::npos)
{
xlsx_data_ranges_.push_back(xlsx_data_range_ptr(new xlsx_data_range()));
xlsx_data_ranges_.back()->table_name = tableName;
ref1 = ref.substr(0, pos );
ref2 = ref.substr(pos + 1);
ref1 = odf_ref.substr(0, pos );
ref2 = odf_ref.substr(pos + 1);
pos = ref1.find(L"!");
if (pos > 0)
@ -88,14 +85,22 @@ void xlsx_table_context::start_database_range(std::wstring tableName, std::wstri
pos = ref2.find(L"!");
if (pos > 0) ref2 = ref2.substr(pos + 1);
xlsx_data_ranges_.back()->ref = ref1 + L":" + ref2;
size_t col1, col2, row1, row2;
getCellAddressInv(ref1, col1, row1);
xlsx_data_ranges_.back()->cell_start = std::pair<int, int>(col1, row1);
XmlUtils::replace_all( xlsx_table_name, L"'", L"");
getCellAddressInv(ref1, col1, row1);
getCellAddressInv(ref2, col2, row2);
xlsx_data_ranges_.push_back(xlsx_data_range_ptr(new xlsx_data_range()));
if (name.find(L"__Anonymous_Sheet_DB__") != std::wstring::npos || col1 == col2)
{
xlsx_data_ranges_.back()->bTablePart = false;
}
xlsx_data_ranges_.back()->name = name;
xlsx_data_ranges_.back()->table_name = xlsx_table_name;
xlsx_data_ranges_.back()->ref = ref1 + L":" + ref2;
xlsx_data_ranges_.back()->cell_start = std::pair<int, int>(col1, row1);
xlsx_data_ranges_.back()->cell_end = std::pair<int, int>(col2, row2);
xlsx_data_ranges_values_.push_back(xlsx_data_range_values_ptr(new xlsx_data_range_values(row1, col1, col2)));
@ -103,10 +108,9 @@ void xlsx_table_context::start_database_range(std::wstring tableName, std::wstri
if (!xlsx_table_name.empty())
{
XmlUtils::replace_all( xlsx_table_name, L"'", L"");
xlsx_data_ranges_map_.insert(std::pair<std::wstring, int> (xlsx_table_name, xlsx_data_ranges_.size() - 1));
}
return true;
}
void xlsx_table_context::set_database_orientation (bool val)
{
@ -147,8 +151,10 @@ int xlsx_table_context::in_database_range()
for (size_t i = 0; i < xlsx_data_ranges_values_.size(); i++)
{
if ((xlsx_data_ranges_values_[i]->withHeader || xlsx_data_ranges_values_[i]->filter)
&& xlsx_data_ranges_values_[i]->in_range(col, row))
if (xlsx_data_ranges_[i]->table_name != state()->get_table_name()) continue;
if (/*(xlsx_data_ranges_values_[i]->withHeader || xlsx_data_ranges_values_[i]->filter)&& */
xlsx_data_ranges_values_[i]->in_range(col, row)) //header row only
{
return (int)i;
}
@ -282,6 +288,8 @@ void xlsx_table_context::serialize_sort(std::wostream & _Wostream)
for (std::multimap<std::wstring, int>::iterator it = range.first; it != range.second; ++it)
{
if (xlsx_data_ranges_[it->second]->bTablePart) continue;
xlsx_data_ranges_[it->second]->serialize_sort(_Wostream);
}
}
@ -291,10 +299,12 @@ void xlsx_table_context::serialize_tableParts(std::wostream & _Wostream, rels &
std::pair<std::multimap<std::wstring, int>::iterator, std::multimap<std::wstring, int>::iterator> range;
range = xlsx_data_ranges_map_.equal_range(state()->tableName_);
range = xlsx_data_ranges_map_.equal_range(state()->get_table_name());
for (std::multimap<std::wstring, int>::iterator it = range.first; it != range.second; ++it)
{
if (false == xlsx_data_ranges_[it->second]->bTablePart) continue;
size_t id = xlsx_conversion_context_->get_table_parts_size() + 1;
std::wstring rId = L"tprtId" + std::to_wstring(id);
@ -317,15 +327,15 @@ void xlsx_table_context::serialize_tableParts(std::wostream & _Wostream, rels &
CP_XML_ATTR(L"xmlns", L"http://schemas.openxmlformats.org/spreadsheetml/2006/main");
CP_XML_ATTR(L"id", id);
CP_XML_ATTR(L"name", xlsx_data_ranges_[it->second]->table_name);
CP_XML_ATTR(L"displayName", xlsx_data_ranges_[it->second]->table_name);
CP_XML_ATTR(L"name", xlsx_data_ranges_[it->second]->name);
CP_XML_ATTR(L"displayName", xlsx_data_ranges_[it->second]->name);
CP_XML_ATTR(L"ref", xlsx_data_ranges_[it->second]->ref);
if (xlsx_data_ranges_[it->second]->withHeader == false &&
xlsx_data_ranges_[it->second]->filter == false)
CP_XML_ATTR(L"headerRowCount", 0);
CP_XML_ATTR(L"totalsRowCount", 0);
//CP_XML_ATTR(L"totalsRowCount", 0);
CP_XML_ATTR(L"totalsRowShown", 0);
xlsx_data_ranges_[it->second]->serialize_autofilter(CP_XML_STREAM());
@ -377,6 +387,8 @@ void xlsx_table_context::serialize_autofilter(std::wostream & _Wostream)
for (std::multimap<std::wstring, int>::iterator it = range.first; it != range.second; ++it)
{
if (xlsx_data_ranges_[it->second]->bTablePart) continue;
if (xlsx_data_ranges_[it->second]->filter)
{
if (cell_start.first < 0 || xlsx_data_ranges_[it->second]->cell_start.first < cell_start.first )
@ -402,7 +414,7 @@ void xlsx_table_context::serialize_autofilter(std::wostream & _Wostream)
{
CP_XML_NODE(L"autoFilter")
{
//в автофильтре тока простые диапазоны .. для сложных нужно выделять tablePart - todooo
//в автофильтре тока простые диапазоны .. для сложных - tablePart
CP_XML_ATTR(L"ref", getCellAddress(cell_start.first, cell_start.second) + L":" + getCellAddress(cell_end.first, cell_end.second));
//CP_XML_ATTR(L"ref", ref);
}

View File

@ -112,7 +112,7 @@ public:
void dump_rels_hyperlinks (rels & Rels);
void dump_rels_ole_objects (rels & Rels);
void start_database_range(std::wstring table_name, std::wstring ref);
bool start_database_range(const std::wstring &table_name, const std::wstring &ref);
void set_database_orientation (bool val);
void set_database_header (bool val);
void set_database_filter (bool val);

View File

@ -477,8 +477,8 @@ void xlsx_conversion_context::end_table()
get_table_context().serialize_page_properties (current_sheet().page_properties());
get_table_context().serialize_conditionalFormatting (current_sheet().conditionalFormatting());
get_table_context().serialize_tableParts (current_sheet().tableParts(), current_sheet().sheet_rels());
//get_table_context().serialize_autofilter (current_sheet().autofilter());
//get_table_context().serialize_sort (current_sheet().sort());
get_table_context().serialize_autofilter (current_sheet().autofilter());
get_table_context().serialize_sort (current_sheet().sort());
get_table_context().serialize_merge_cells (current_sheet().mergeCells());
get_table_context().serialize_data_validation (current_sheet().dataValidations());

View File

@ -201,6 +201,7 @@ public:
mediaitems & get_mediaitems() { return mediaitems_; }
static std::unordered_map<std::wstring, int> mapExternalLink_;
std::map<std::wstring, int> mapUsedNames_;
private:
void create_new_sheet (std::wstring const & name);

View File

@ -284,6 +284,7 @@ void form_button::docx_convert(oox::docx_conversion_context & Context)
void form_button::xlsx_convert(oox::xlsx_conversion_context & Context)
{
Context.get_forms_context().start_element(1);
Context.get_forms_context().set_element(dynamic_cast<form_element*>(this));
form_element::xlsx_convert(Context);
}

View File

@ -87,6 +87,7 @@ void table_data_pilot_table::add_child_element( xml::sax * Reader, const std::ws
CP_CREATE_ELEMENT (source_);
}
void table_data_pilot_table::xlsx_convert(oox::xlsx_conversion_context & Context)
{
if (!source_) return;

View File

@ -88,24 +88,43 @@ void table_database_range::add_child_element( xml::sax * Reader, const std::wstr
void table_database_range::xlsx_convert(oox::xlsx_conversion_context & Context)
{
if (!table_target_range_address_) return;
if (!table_name_) return;
Context.get_table_context().start_database_range(table_name_.get_value_or(L""), *table_target_range_address_);
if (table_display_filter_buttons_)
Context.get_table_context().set_database_filter(table_display_filter_buttons_->get());
std::wstring name = table_name_.get();
if (table_orientation_)
Context.get_table_context().set_database_orientation(table_orientation_->get_type() == table_orientation::row ? true : false);
if (table_contains_header_)
Context.get_table_context().set_database_header(table_contains_header_->get());
for (size_t i = 0; i < content_.size(); i++)
std::map<std::wstring, int>::iterator pFind = Context.mapUsedNames_.find(name);
if (pFind == Context.mapUsedNames_.end())
{
content_[i]->xlsx_convert(Context);
Context.mapUsedNames_.insert(std::make_pair(name, 1));
}
else
{
name += L"_" + std::to_wstring(pFind->second);
pFind->second++;
}
if (Context.get_table_context().start_database_range(name, *table_target_range_address_))
{
if (table_display_filter_buttons_)
Context.get_table_context().set_database_filter(table_display_filter_buttons_->get());
Context.get_table_context().end_database_range();
if (table_orientation_)
Context.get_table_context().set_database_orientation(table_orientation_->get_type() == table_orientation::row ? true : false);
if (table_contains_header_)
Context.get_table_context().set_database_header(table_contains_header_->get());
for (size_t i = 0; i < content_.size(); i++)
{
content_[i]->xlsx_convert(Context);
}
Context.get_table_context().end_database_range();
}
else
{
Context.get_xlsx_defined_names().add(name, table_target_range_address_.get(), false, -1);
}
}
//--------------------------------------------------------------------------------------------------

View File

@ -94,8 +94,19 @@ void table_named_range::xlsx_convert(oox::xlsx_conversion_context & Context)
{
tableId = Context.get_table_context().state()->get_table_id();
}
oox::xlsx_defined_names & ctx = Context.get_xlsx_defined_names();
ctx.add(table_name_.get(), table_cell_range_address_.get(), false, tableId);
std::wstring name = table_name_.get();
std::map<std::wstring, int>::iterator pFind = Context.mapUsedNames_.find(name);
if (pFind == Context.mapUsedNames_.end())
{
Context.mapUsedNames_.insert(std::make_pair(name, 1));
}
else
{
name += L"_" + std::to_wstring(pFind->second);
pFind->second++;
}
Context.get_xlsx_defined_names().add(name, table_cell_range_address_.get(), false, tableId);
}
}
@ -130,8 +141,18 @@ void table_named_expression::xlsx_convert(oox::xlsx_conversion_context & Context
{
tableId = Context.get_table_context().state()->get_table_id();
}
oox::xlsx_defined_names & ctx = Context.get_xlsx_defined_names();
ctx.add(table_name_.get(), table_expression_.get(), true, tableId);
std::wstring name = table_name_.get();
std::map<std::wstring, int>::iterator pFind = Context.mapUsedNames_.find(name);
if (pFind == Context.mapUsedNames_.end())
{
Context.mapUsedNames_.insert(std::make_pair(name, 1));
}
else
{
name += L"_" + std::to_wstring(pFind->second);
pFind->second++;
}
Context.get_xlsx_defined_names().add(name, table_expression_.get(), true, tableId);
}
}

View File

@ -73,18 +73,6 @@ int table_table_cell_content::xlsx_convert(oox::xlsx_conversion_context & Contex
const int sharedStrId = Context.get_table_context().end_cell_content();
int index = Context.get_table_context().in_database_range();
if (index >= 0)
{
std::wstringstream strm;
for (size_t i = 0 ; i < elements_.size(); i++)
{
elements_[i]->text_to_stream(strm);
}
Context.get_table_context().set_database_range_value(index, strm.str());
}
return sharedStrId;
}
@ -853,9 +841,31 @@ void table_table_cell::xlsx_convert(oox::xlsx_conversion_context & Context)
const int sharedStringId = content_.xlsx_convert(Context, &textFormatProperties);
if (t_val == oox::XlsxCellType::str && sharedStringId >= 0)
t_val = oox::XlsxCellType::s;//в случае текста, если он есть берем кэшированное значение
//---------------------------------------------------------------------------------------------------------
if (t_val == oox::XlsxCellType::str || t_val == oox::XlsxCellType::inlineStr)
{
int index = Context.get_table_context().in_database_range();
if (index >= 0)
{
if (sharedStringId >= 0)
{
std::wstringstream strm;
content_.text_to_stream(strm);
Context.get_table_context().set_database_range_value(index, strm.str());
}
else if (str_val)
{
Context.get_table_context().set_database_range_value(index, str_val.get());
}
}
}
if (t_val == oox::XlsxCellType::str && sharedStringId >= 0)
{
t_val = oox::XlsxCellType::s;//в случае текста, если он есть берем кэшированное значение
}
//---------------------------------------------------------------------------------------------------------
if (skip_next_cell)break;
// пустые ячейки пропускаем.
@ -1138,7 +1148,7 @@ void table_covered_table_cell::xlsx_convert(oox::xlsx_conversion_context & Conte
const int sharedStringId = content_.xlsx_convert(Context, &textFormatProperties);
if (t_val == oox::XlsxCellType::str && sharedStringId >=0)
if (t_val == oox::XlsxCellType::str && sharedStringId >= 0)
t_val = oox::XlsxCellType::s;//в случае текста, если он есть берем кэшированное значение
if (skip_next_cell)break;

View File

@ -408,7 +408,7 @@ static const struct ActionNamesEmf
m_oStream.Skip(ulHeaderSize + lBitsOffset);
BYTE* pBitsBuffer = m_oStream.GetCurPtr();
unsigned int ulBitsSizeSkip = std::ceil(ulBitsSize / 4 + 0.5) * 4;
unsigned int ulBitsSizeSkip = 0 == ulBitsSize ? 0 : ((int)(((double)ulBitsSize - 0.5) / 4) + 1) * 4;
m_oStream.Skip(ulBitsSizeSkip);
MetaFile::ReadImage(pHeaderBuffer, ulHeaderSize, pBitsBuffer, ulBitsSize, ppBgraBuffer, pulWidth, pulHeight);