Commit c526786c authored by Elen.Subbotina's avatar Elen.Subbotina Committed by Alexander Trofimov

именованные диапазоны, выражения. Привязка оных к книге или листам. Использование их в формулах.


git-svn-id: svn://fileserver/activex/AVS/Sources/TeamlabOffice/trunk/ServerComponents@56311 954022d7-b5bf-4e40-9824-e11837661b57
parent 5190dd5a
......@@ -53,6 +53,8 @@ public:
// 1!$A$1 -> $1.$A$1
std::wstring convert_named_ref(std::wstring const & expr);
std::wstring find_base_cell(std::wstring const & expr);
//Sheet2!C3:C19 -> Sheet2.C3:Sheet2.C19
std::wstring convert_chart_distance(std::wstring const & expr);
......
......@@ -26,6 +26,9 @@ public:
std::wstring replace_arguments1(std::wstring & workstr);
void replace_named_ref(std::wstring & expr);
std::wstring find_base_cell(const std::wstring & expr);
// bool find_first_ref(std::wstring const & expr, std::wstring & table, std::wstring & ref);
//bool find_first_last_ref(std::wstring const & expr, std::wstring & table, std::wstring & ref_first,std::wstring & ref_last);
};
......@@ -109,26 +112,31 @@ public:
// [$'Sheet2 A'.$B2] -> 'Sheet2 A'!$B2
void oox2odf_converter::Impl::replace_cells_range(std::wstring& expr)
{
boost::wregex re(L"([:$!])+");
boost::wregex re1(L"(\\$?\\w+)?\\!?([a-zA-Z$]+\\d{1,2})\\:?([a-zA-Z$]+\\d{1,2})?");
boost::wregex re2(L"([a-zA-Z$]+\\d{1,2})\\:?([a-zA-Z$]+\\d{1,2})?");
//boost::wregex re2(L"([a-zA-Z$]+\\d{1,2})\\:?([a-zA-Z$]+\\d{1,2})?");
// $ Sheet2 ! $ A1 : $ B5
//boost::wsmatch result;
//bool b = boost::regex_search(expr, result, re);
std::wstring workstr = expr;
boost::wsmatch result;
bool b = boost::regex_search(expr, result, re);
std::wstring res = boost::regex_replace(
workstr,
re1,
&replace_cells_range_formater1,
boost::match_default | boost::format_all);
//workstr = res;
//res = boost::regex_replace(
//workstr,
//re2,
//&replace_cells_range_formater2,
//boost::match_default | boost::format_all);
expr = res;
if (b)
{
std::wstring workstr = expr;
std::wstring res = boost::regex_replace(
workstr,
re1,
&replace_cells_range_formater1,
boost::match_default | boost::format_all);
//workstr = res;
//res = boost::regex_replace(
//workstr,
//re2,
//&replace_cells_range_formater2,
//boost::match_default | boost::format_all);
expr = res;
}
return;
}
......@@ -138,12 +146,14 @@ std::wstring oox2odf_converter::Impl::replace_cells_range_formater1(boost::wsmat
if (sz>3)
{
std::wstring sheet1 = what[1].str();
boost::algorithm::replace_all(sheet1, L"$", L"");
std::wstring sheet1 = what[1].matched ? what[1].str() : L"";
//boost::algorithm::replace_all(sheet1, L"$", L"");
std::wstring c1 = what[2].str();
std::wstring c2 = what[3].str();
const std::wstring s = std::wstring(L"[") + sheet1 + L"." + c1 + (c2.empty() ? L"" : (L":" + sheet1 + L"." + c2) ) + std::wstring(L"]");
const std::wstring s = std::wstring(L"[")/* + (sheet1.length() > 0 ? L"$" : L"" ) */+ sheet1 + L"." +
c1 +
(c2.empty() ? L"" : (L":" + sheet1 + L"." + c2) ) + std::wstring(L"]");
return s;
}
else
......@@ -207,31 +217,42 @@ std::wstring oox2odf_converter::Impl::replace_cells_range_formater2(boost::wsmat
// Ëèñò1!$A$1 -> $Ëèñò1.$A$1
void oox2odf_converter::Impl::replace_named_ref(std::wstring & expr)
{
std::wstring workstr = expr, out;
replace_vertical(workstr);
replace_semicolons(workstr);
std::vector<std::wstring> distance;
boost::algorithm::split(distance,workstr, boost::algorithm::is_any_of(L";"), boost::algorithm::token_compress_on);
BOOST_FOREACH(std::wstring &d, distance)
{
replace_cells_range(d);
out = out + d + std::wstring(L";");
}
if (out.length()>0) expr = out.substr(0,out.length()-1);
}
std::wstring oox2odf_converter::Impl::find_base_cell(const std::wstring & expr)
{
std::vector< std::wstring > splitted;
boost::algorithm::split(splitted, expr, boost::algorithm::is_any_of(L"!"), boost::algorithm::token_compress_on);
boost::algorithm::split(splitted, expr, boost::algorithm::is_any_of(L"."), boost::algorithm::token_compress_on);
std::wstring table;
std::wstring ref;
if (splitted.size()>1)
{
table= splitted[0];
ref = splitted[1];
boost::algorithm::replace_all(table, L"$", L"");
expr = table +std::wstring(L"!") + ref;
return splitted[0] + L".$A$1";
}
else if (splitted.size()==1)
{
ref = splitted[0];
expr = ref;
}
else return L"";
}
namespace
{
......@@ -447,12 +468,19 @@ std::wstring oox2odf_converter::Impl::convert_formula(const std::wstring& expr)
std::wstring workstr = expr;
const std::wstring res = boost::regex_replace(
std::wstring res = boost::regex_replace(
workstr,
boost::wregex(L"(?:(?=[()])(.*?)(?=[)]))|(\".*?\")|('.*?')"),
&oox2odf_converter::Impl::replace_arguments,
boost::match_default | boost::format_all);
if (res == expr)
{
//âîçìîæíî íå êîíâåðòàíóëîñü
res= convert(workstr);
}
return std::wstring(L"of:=") + res;
}
//Sheet2!C3:C19,Sheet2!L27:L34
......@@ -542,6 +570,10 @@ std::wstring oox2odf_converter::convert_named_ref(const std::wstring& expr)
impl_->replace_named_ref(workstr);
return workstr;
}
std::wstring oox2odf_converter::find_base_cell(const std::wstring& expr)
{
return impl_->find_base_cell(expr);
}
std::wstring oox2odf_converter::convert_ref(std::wstring const & expr)
......
......@@ -974,6 +974,14 @@
RelativePath=".\OdfFormat\table.h"
>
</File>
<File
RelativePath=".\OdfFormat\table_named_expressions.cpp"
>
</File>
<File
RelativePath=".\OdfFormat\table_named_expressions.h"
>
</File>
<File
RelativePath=".\OdfFormat\text_elements.cpp"
>
......
......@@ -101,8 +101,21 @@ void ods_conversion_context::start_document()
root_spreadsheet_ = dynamic_cast<office_spreadsheet*>(get_current_object_element().get());
}
void ods_conversion_context::start_defined_expressions()
{
create_element(L"table", L"named-expressions",root_spreadsheet_->getContent(),this);
table_context_.start_defined_expressions(root_spreadsheet_->getContent().back());
}
void ods_conversion_context::add_defined_range(std::wstring & name,std::wstring & cell_range, int sheet_id)
{
table_context_.add_defined_range(name,cell_range, sheet_id);
}
void ods_conversion_context::add_defined_expression(std::wstring & name,std::wstring & value, int sheet_id)
{
table_context_.add_defined_expression(name,value, sheet_id);
}
void ods_conversion_context::start_sheet(std::wstring & name)
{
create_element(L"table", L"table",root_spreadsheet_->getContent(),this);
......
......@@ -73,7 +73,11 @@ public:
void end_image(){drawing_context()->end_image();}
double convert_symbol_width(double val) {return val * font_metrix_.approx_symbol_size;}
void start_defined_expressions();
void add_defined_range(std::wstring & name,std::wstring & cell_range, int sheet_id);
void add_defined_expression(std::wstring & name,std::wstring & value, int sheet_id);
void end_defined_expressions(){}
private:
_font_metrix font_metrix_;
ods_table_context table_context_;
......
#include "precompiled_cpodf.h"
#include "ods_table_context.h"
#include "table.h"
#include "ods_conversion_context.h"
#include "logging.h"
#include <boost/foreach.hpp>
#include <iostream>
#include <cpdoccore/formulasconvert.h>
namespace cpdoccore {
namespace odf {
......@@ -18,7 +22,86 @@ ods_table_state & ods_table_context::state()
{
return table_state_list_.back();
}
void ods_table_context::start_defined_expressions(office_element_ptr & root_elm)
{
table_defined_expressions_.root = root_elm;
}
void ods_table_context::add_defined_range(std::wstring & name,std::wstring & cell_range, int sheet_id)
{
office_element_ptr elm;
create_element(L"table", L"named-range",elm, &context_);
table_named_range* named_range = dynamic_cast<table_named_range*>(elm.get());
if (named_range == NULL)return;
static formulasconvert::oox2odf_converter formulas_converter;
std::wstring odf_cell_range = formulas_converter.convert_named_ref(cell_range);
std::wstring odf_base_cell = formulas_converter.find_base_cell(cell_range);
named_range->table_name_ = name;
named_range->table_cell_range_address_ = odf_cell_range;
if (odf_base_cell.length() > 0)
named_range->table_base_cell_address_ = odf_base_cell;
table_defined_expressions_.defined.push_back(elm);
if (sheet_id >=0)
{
int i=0;
for (std::list<ods_table_state>::iterator iter = table_state_list_.begin(); iter != table_state_list_.end(); iter++)
{
if (i == sheet_id)
{
iter->add_definded_expression(elm);
break;
}
i++;
}
}
else
table_defined_expressions_.root->add_child_element(elm);
}
void ods_table_context::add_defined_expression(std::wstring & name,std::wstring & value, int sheet_id)
{
office_element_ptr elm;
create_element(L"table", L"named-expression",elm, &context_);
table_named_expression* named_expression = dynamic_cast<table_named_expression*>(elm.get());
if (named_expression == NULL)return;
static formulasconvert::oox2odf_converter formulas_converter;
std::wstring odf_value = formulas_converter.convert_named_ref(value);
std::wstring odf_base_cell = formulas_converter.find_base_cell(value);
named_expression->table_name_ = name;
named_expression->table_expression_ = odf_value;
if (sheet_id >=0)
{
int i=0;
for (std::list<ods_table_state>::iterator iter = table_state_list_.begin(); iter != table_state_list_.end(); iter++)
{
if (i == sheet_id)
{
odf_base_cell = iter->office_table_name_ + L".$A$1";
iter->add_definded_expression(elm);
break;
}
i++;
}
}
else
table_defined_expressions_.root->add_child_element(elm);
if (odf_base_cell.length() > 0)
named_expression->table_base_cell_address_ = odf_base_cell;
table_defined_expressions_.defined.push_back(elm);
}
void ods_table_context::start_table(office_element_ptr & elm, std::wstring & name)
{
table_state_list_.push_back( ods_table_state(context_, elm) );
......
......@@ -15,6 +15,12 @@ class ods_text_context;
class office_element;
typedef shared_ptr<office_element>::Type office_element_ptr;
struct table_defined_expressions_state
{
office_element_ptr root;
std::vector<office_element_ptr> defined;
};
/// \class ods_table_context
class ods_table_context
{
......@@ -28,11 +34,17 @@ public:
unsigned int columns_count();
ods_table_state & state();
private:
void start_defined_expressions(office_element_ptr & root_elm);
void add_defined_range(std::wstring & name,std::wstring & cell_range, int sheet_id);
void add_defined_expression(std::wstring & name,std::wstring & value, int sheet_id);
private:
ods_conversion_context & context_;
std::list<ods_table_state> table_state_list_;
std::list<ods_table_state> table_state_list_;
table_defined_expressions_state table_defined_expressions_;
};
......
......@@ -109,6 +109,7 @@ ods_table_state::ods_table_state(ods_conversion_context & Context, office_elemen
void ods_table_state::set_table_name(std::wstring name)
{
office_table_name_ = name;
table_table* table = dynamic_cast<table_table*>(office_table_.get());
if (table == NULL)return;
......@@ -441,6 +442,16 @@ void ods_table_state::set_cell_type(int type)
// - - numFmt
}
}
void ods_table_state::add_definded_expression(office_element_ptr & elm)
{
if (!table_defined_expressions_)
{
create_element(L"table", L"named-expressions",table_defined_expressions_,&context_);
office_table_->add_child_element(table_defined_expressions_);
}
if (!table_defined_expressions_)return;
table_defined_expressions_->add_child_element(elm);
}
void ods_table_state::add_hyperlink(std::wstring & ref,int col, int row, std::wstring & link)
{
ods_hyperlink_state state;
......@@ -648,8 +659,15 @@ void ods_table_state::set_cell_value(std::wstring & value)
{
//general !!
}
// !!!!
//
//
context_.start_text_context();
context_.text_context()->start_paragraph();
context_.text_context()->add_text_content(value);
context_.text_context()->end_paragraph();
set_cell_text(context_.text_context());
context_.end_text_context();
}
void ods_table_state::end_cell()
......
......@@ -16,6 +16,7 @@
#include "officevaluetype.h"
namespace cpdoccore {
struct oox_table_position
......@@ -113,6 +114,7 @@ public:
///////////////////////////////
void add_hyperlink(std::wstring & ref,int col, int row, std::wstring & link);
void add_definded_expression(office_element_ptr & elm);
void start_comment(int col, int row, std::wstring & author);
void set_comment_rect(double l, double t, double w, double h);
......@@ -143,19 +145,14 @@ public:
odf_drawing_context * drawing_context(){return &drawing_context_;}
//
// xlsx_table_metrics & get_table_metrics() { return xlsx_table_metrics_; }
// xlsx_comments_context & get_comments_context() { return xlsx_comments_context_; }
// void table_column_last_width(double w) { table_column_last_width_ = w; }
// double table_column_last_width() const { return table_column_last_width_; };
private:
ods_conversion_context & context_;
std::wstring office_table_name_;
office_element_ptr office_table_;
style* office_table_style_;//??? office_element_ptr ???
office_element_ptr table_defined_expressions_;
std::wstring row_default_cell_style_name_;
......@@ -174,12 +171,8 @@ private:
odf_drawing_context drawing_context_;
// xlsx_merge_cells merge_cells_;
// xlsx_table_metrics xlsx_table_metrics_;
// xlsx_comments_context xlsx_comments_context_;
// xlsx_hyperlinks xlsx_hyperlinks_;
friend class ods_table_context;
// double table_column_last_width_;
};
......
......@@ -139,7 +139,11 @@ void table_table::create_child_element(const ::std::wstring & Ns, const ::std::w
{
CP_CREATE_ELEMENT(table_shapes_);
}
else
else if CP_CHECK_NAME(L"table", L"named-expressions")
{
CP_CREATE_ELEMENT(table_named_expressions_);
}
else
CP_NOT_APPLICABLE_ELM();
}
......@@ -170,6 +174,10 @@ void table_table::add_child_element(office_element_ptr & child_element)
{
table_shapes_ = child_element;
}
else if (type == typeTableNamedExpressions)
{
table_named_expressions_ = child_element;
}
}
void table_table::serialize(std::wostream & _Wostream)
......@@ -184,6 +192,8 @@ void table_table::serialize(std::wostream & _Wostream)
table_columns_and_groups_.serialize(CP_XML_STREAM());
table_rows_and_groups_.serialize(CP_XML_STREAM());
if (table_named_expressions_)table_named_expressions_->serialize(CP_XML_STREAM());
}
}
}
......
......@@ -12,7 +12,7 @@
#include "common_attlists.h"
#include "tablemode.h"
//#include "table_named_expressions.h"
#include "table_named_expressions.h"
namespace cpdoccore {
namespace odf {
......@@ -613,6 +613,7 @@ public:
//office-dde-source
//table-scenario
//office-forms
office_element_ptr table_named_expressions_;
office_element_ptr table_shapes_;
table_columns_and_groups table_columns_and_groups_;//table-columns-and-groups
table_rows_and_groups table_rows_and_groups_;
......
#include "precompiled_cpodf.h"
#include "table_named_expressions.h"
#include <boost/make_shared.hpp>
#include <cpdoccore/xml/xmlchar.h>
#include <cpdoccore/xml/attributes.h>
#include <cpdoccore/xml/simple_xml_writer.h>
namespace cpdoccore {
namespace odf {
using xml::xml_char_wc;
// table:table-source
//////////////////////////////////////////////////////////////////////////////////////////////////
const wchar_t * table_named_expressions::ns = L"table";
const wchar_t * table_named_expressions::name = L"named-expressions";
void table_named_expressions::create_child_element(const ::std::wstring & Ns, const ::std::wstring & Name)
{
if CP_CHECK_NAME(L"table", L"named-range")
{
CP_CREATE_ELEMENT(named_range_);
}
else if CP_CHECK_NAME(L"table", L"named-expression")
{
CP_CREATE_ELEMENT(named_expression_);
}
else
{
}
}
void table_named_expressions::add_child_element(office_element_ptr & child_element)
{
ElementType type = child_element->get_type();
if (type == typeTableNamedRange)
{
named_range_.push_back(child_element);
}
else if (type == typeTableNamedExpression)
{
named_expression_.push_back(child_element);
}
else
{
}
}
void table_named_expressions::serialize(std::wostream & _Wostream)
{
CP_XML_WRITER(_Wostream)
{
CP_XML_NODE_SIMPLE()
{
BOOST_FOREACH(const office_element_ptr & elm, named_expression_)
{
elm->serialize(CP_XML_STREAM());
}
BOOST_FOREACH(const office_element_ptr & elm, named_range_)
{
elm->serialize(CP_XML_STREAM());
}
}
}
}
// table:named-range
//////////////////////////////////////////////////////////////////////////////////////////////////
const wchar_t * table_named_range::ns = L"table";
const wchar_t * table_named_range::name = L"named-range";
void table_named_range::serialize(std::wostream & _Wostream)
{
CP_XML_WRITER(_Wostream)
{
CP_XML_NODE_SIMPLE()
{
CP_XML_ATTR_OPT(L"table:name", table_name_);
CP_XML_ATTR_OPT(L"table:cell-range-address", table_cell_range_address_);
CP_XML_ATTR_OPT(L"table:base-cell-address", table_base_cell_address_);
}
}
}
// table:named-expression
//////////////////////////////////////////////////////////////////////////////////////////////////
const wchar_t * table_named_expression::ns = L"table";
const wchar_t * table_named_expression::name = L"named-expression";
void table_named_expression::serialize(std::wostream & _Wostream)
{
CP_XML_WRITER(_Wostream)
{
CP_XML_NODE_SIMPLE()
{
CP_XML_ATTR_OPT(L"table:name", table_name_);
CP_XML_ATTR_OPT(L"table:expression", table_expression_);
CP_XML_ATTR_OPT(L"table:base-cell-address", table_base_cell_address_);
}
}
}
}
}
#pragma once
#include <iosfwd>
#include <cpdoccore/CPOptional.h>
#include <cpdoccore/xml/xmlelement.h>
#include <cpdoccore/xml/nodetype.h>
#include "office_elements.h"
#include "office_elements_create.h"
#include "style_ref.h"
namespace cpdoccore {
namespace odf {
/// \brief table:named-expressions
class table_named_expressions : public office_element_impl<table_named_expressions>
{
public:
static const wchar_t * ns;
static const wchar_t * name;
static const xml::NodeType xml_type = xml::typeElement;
static const ElementType type = typeTableNamedExpressions;
CPDOCCORE_DEFINE_VISITABLE();
virtual void create_child_element(const ::std::wstring & Ns, const ::std::wstring & Name);
virtual void add_child_element( office_element_ptr & child_element);
virtual void serialize(std::wostream & _Wostream);
office_element_ptr_array named_range_;
office_element_ptr_array named_expression_;
};
CP_REGISTER_OFFICE_ELEMENT2(table_named_expressions);
/// \brief table:named-range
class table_named_range : public office_element_impl<table_named_range>
{
public:
static const wchar_t * ns;
static const wchar_t * name;
static const xml::NodeType xml_type = xml::typeElement;
static const ElementType type = typeTableNamedRange;
CPDOCCORE_DEFINE_VISITABLE();
virtual void create_child_element(const ::std::wstring & Ns, const ::std::wstring & Name){}
virtual void add_child_element( office_element_ptr & child_element){}
virtual void serialize(std::wostream & _Wostream);
_CP_OPT(std::wstring) table_name_;
_CP_OPT(std::wstring) table_cell_range_address_;
_CP_OPT(std::wstring) table_base_cell_address_;
};
CP_REGISTER_OFFICE_ELEMENT2(table_named_range);
/// \brief table:named-expression
class table_named_expression : public office_element_impl<table_named_expression>
{
public:
static const wchar_t * ns;
static const wchar_t * name;
static const xml::NodeType xml_type = xml::typeElement;
static const ElementType type = typeTableNamedExpression;
CPDOCCORE_DEFINE_VISITABLE();
virtual void create_child_element(const ::std::wstring & Ns, const ::std::wstring & Name){}
virtual void add_child_element( office_element_ptr & child_element){}
virtual void serialize(std::wostream & _Wostream);
_CP_OPT(std::wstring) table_name_;
_CP_OPT(std::wstring) table_expression_;
_CP_OPT(std::wstring) table_base_cell_address_;
};
CP_REGISTER_OFFICE_ELEMENT2(table_named_expression);
}
}
......@@ -138,6 +138,28 @@ void XlsxConverter::convert_sheets()
}
}
}
if (Workbook->m_oDefinedNames.IsInit())
{
ods_context->start_defined_expressions();
for (int i = 0; i < Workbook->m_oDefinedNames->m_arrItems.GetSize(); i++)
{
convert(Workbook->m_oDefinedNames->m_arrItems[i]);
}
ods_context->end_defined_expressions();
}
}
void XlsxConverter::convert(OOX::Spreadsheet::CDefinedName *oox_defined)
{
if (oox_defined == NULL) return;
int sheet_id = -1;
if (oox_defined->m_oLocalSheetId.IsInit())
sheet_id = oox_defined->m_oLocalSheetId->GetValue();
if (oox_defined->m_oName.IsInit() && oox_defined->m_oRef.IsInit())
ods_context->add_defined_expression (string2std_string(oox_defined->m_oName.get2()),
string2std_string(oox_defined->m_oRef.get2()), sheet_id);
}
void XlsxConverter::convert(OOX::Spreadsheet::CWorksheet *oox_sheet)
{
......@@ -988,7 +1010,8 @@ void XlsxConverter::convert(OOX::Spreadsheet::CColor *color, _CP_OPT(odf::color)
int ind = color->m_oIndexed->GetValue();
if(xlsx_styles->m_oColors.IsInit() && xlsx_styles->m_oColors->m_oIndexedColors.IsInit())
if(xlsx_styles->m_oColors.IsInit() && xlsx_styles->m_oColors->m_oIndexedColors.IsInit() &&
ind < xlsx_styles->m_oColors->m_oIndexedColors->m_arrItems.GetSize())
{
if ((xlsx_styles->m_oColors->m_oIndexedColors->m_arrItems[ind]) &&
(xlsx_styles->m_oColors->m_oIndexedColors->m_arrItems[ind]->m_oRgb.IsInit()))
......
......@@ -44,6 +44,7 @@ namespace OOX
class CConnShape;
class CCommentItem;
class CGraphicFrame;
class CDefinedName;
}
}
......@@ -110,6 +111,7 @@ namespace Oox2Odf
void convert(OOX::Spreadsheet::WritingElement *oox_unknown);
void convert(OOX::Spreadsheet::CWorksheet *oox_sheet);
void convert(OOX::Spreadsheet::CDefinedName *oox_defined);
void convert(OOX::Spreadsheet::CCol *oox_column);
void convert(OOX::Spreadsheet::CRow *oox_row);
......
......@@ -2,6 +2,6 @@
//1
//2
//0
//44
#define INTVER 1,2,0,44
#define STRVER "1,2,0,44\0"
//45
#define INTVER 1,2,0,45
#define STRVER "1,2,0,45\0"
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment