2014-05-22 05:48:51 +08:00
|
|
|
#include <algorithm>
|
2015-11-02 14:07:43 +08:00
|
|
|
#include <limits>
|
2014-05-22 05:48:51 +08:00
|
|
|
|
2014-08-14 06:56:34 +08:00
|
|
|
#include <xlnt/cell/cell.hpp>
|
2015-11-02 14:07:43 +08:00
|
|
|
#include <xlnt/cell/cell_reference.hpp>
|
2015-11-03 21:38:09 +08:00
|
|
|
#include <xlnt/cell/types.hpp>
|
|
|
|
#include <xlnt/packaging/relationship.hpp>
|
|
|
|
#include <xlnt/utils/datetime.hpp>
|
|
|
|
#include <xlnt/utils/exceptions.hpp>
|
2015-10-15 06:05:13 +08:00
|
|
|
#include <xlnt/workbook/named_range.hpp>
|
2014-08-14 06:56:34 +08:00
|
|
|
#include <xlnt/workbook/workbook.hpp>
|
2015-10-15 06:05:13 +08:00
|
|
|
#include <xlnt/worksheet/range.hpp>
|
|
|
|
#include <xlnt/worksheet/range_reference.hpp>
|
|
|
|
#include <xlnt/worksheet/worksheet.hpp>
|
2014-08-14 06:56:34 +08:00
|
|
|
|
2015-11-02 14:07:43 +08:00
|
|
|
#include <detail/cell_impl.hpp>
|
2015-11-04 03:53:48 +08:00
|
|
|
#include <detail/constants.hpp>
|
2015-11-02 14:07:43 +08:00
|
|
|
#include <detail/worksheet_impl.hpp>
|
2014-05-21 22:20:30 +08:00
|
|
|
|
|
|
|
namespace xlnt {
|
2014-05-22 05:48:51 +08:00
|
|
|
|
2014-05-30 08:52:14 +08:00
|
|
|
worksheet::worksheet() : d_(nullptr)
|
|
|
|
{
|
|
|
|
}
|
2015-11-01 22:43:01 +08:00
|
|
|
|
2014-05-31 06:42:25 +08:00
|
|
|
worksheet::worksheet(detail::worksheet_impl *d) : d_(d)
|
2014-05-21 22:20:30 +08:00
|
|
|
{
|
|
|
|
}
|
|
|
|
|
2014-05-30 08:52:14 +08:00
|
|
|
worksheet::worksheet(const worksheet &rhs) : d_(rhs.d_)
|
2014-05-21 22:20:30 +08:00
|
|
|
{
|
|
|
|
}
|
2015-11-01 22:43:01 +08:00
|
|
|
|
2015-11-11 07:58:54 +08:00
|
|
|
worksheet::worksheet(workbook &parent, const std::string &title)
|
2015-11-01 22:43:01 +08:00
|
|
|
: d_(title == "" ? parent.create_sheet().d_ : parent.create_sheet(title).d_)
|
2014-05-21 22:20:30 +08:00
|
|
|
{
|
|
|
|
}
|
|
|
|
|
|
|
|
bool worksheet::has_frozen_panes() const
|
|
|
|
{
|
2014-05-30 08:52:14 +08:00
|
|
|
return get_frozen_panes() != cell_reference("A1");
|
2014-05-21 22:20:30 +08:00
|
|
|
}
|
|
|
|
|
2015-11-11 07:58:54 +08:00
|
|
|
std::string worksheet::unique_sheet_name(const std::string &value) const
|
2014-08-02 04:46:54 +08:00
|
|
|
{
|
|
|
|
auto names = get_parent().get_sheet_names();
|
|
|
|
auto match = std::find(names.begin(), names.end(), value);
|
|
|
|
std::size_t append = 0;
|
2015-11-01 22:43:01 +08:00
|
|
|
while (match != names.end())
|
2014-08-02 04:46:54 +08:00
|
|
|
{
|
|
|
|
append++;
|
2015-11-11 07:58:54 +08:00
|
|
|
match = std::find(names.begin(), names.end(), value + std::to_string(append));
|
2014-08-02 04:46:54 +08:00
|
|
|
}
|
2015-11-11 07:58:54 +08:00
|
|
|
return append == 0 ? value : value + std::to_string(append);
|
2014-08-02 04:46:54 +08:00
|
|
|
}
|
|
|
|
|
2015-11-11 08:47:31 +08:00
|
|
|
void worksheet::create_named_range(const std::string &name, const std::string &reference_string)
|
|
|
|
{
|
|
|
|
create_named_range(name, range_reference(reference_string));
|
|
|
|
}
|
|
|
|
|
2015-11-11 07:58:54 +08:00
|
|
|
void worksheet::create_named_range(const std::string &name, const range_reference &reference)
|
2014-05-21 22:20:30 +08:00
|
|
|
{
|
2015-10-15 06:05:13 +08:00
|
|
|
std::vector<named_range::target> targets;
|
2015-11-01 22:43:01 +08:00
|
|
|
targets.push_back({ *this, reference });
|
2015-10-15 06:05:13 +08:00
|
|
|
d_->named_ranges_[name] = named_range(name, targets);
|
2014-05-21 22:20:30 +08:00
|
|
|
}
|
|
|
|
|
2014-07-27 04:19:15 +08:00
|
|
|
range worksheet::operator()(const xlnt::cell_reference &top_left, const xlnt::cell_reference &bottom_right)
|
|
|
|
{
|
2015-11-11 08:47:31 +08:00
|
|
|
return get_range(range_reference(top_left, bottom_right));
|
2014-07-27 04:19:15 +08:00
|
|
|
}
|
|
|
|
|
2014-05-22 05:48:51 +08:00
|
|
|
cell worksheet::operator[](const cell_reference &ref)
|
|
|
|
{
|
|
|
|
return get_cell(ref);
|
|
|
|
}
|
|
|
|
|
2014-05-21 22:20:30 +08:00
|
|
|
std::vector<range_reference> worksheet::get_merged_ranges() const
|
|
|
|
{
|
2014-05-30 08:52:14 +08:00
|
|
|
return d_->merged_cells_;
|
2014-05-21 22:20:30 +08:00
|
|
|
}
|
|
|
|
|
2015-10-31 06:54:04 +08:00
|
|
|
margins &worksheet::get_page_margins()
|
|
|
|
{
|
|
|
|
return d_->page_margins_;
|
|
|
|
}
|
|
|
|
|
2015-10-30 01:46:56 +08:00
|
|
|
const margins &worksheet::get_page_margins() const
|
2014-05-21 22:20:30 +08:00
|
|
|
{
|
2014-05-30 08:52:14 +08:00
|
|
|
return d_->page_margins_;
|
2014-05-21 22:20:30 +08:00
|
|
|
}
|
|
|
|
|
2015-11-11 08:47:31 +08:00
|
|
|
void worksheet::auto_filter(const std::string &reference_string)
|
|
|
|
{
|
|
|
|
auto_filter(range_reference(reference_string));
|
|
|
|
}
|
|
|
|
|
2014-06-05 06:42:17 +08:00
|
|
|
void worksheet::auto_filter(const range_reference &reference)
|
2014-05-21 22:20:30 +08:00
|
|
|
{
|
2014-05-30 08:52:14 +08:00
|
|
|
d_->auto_filter_ = reference;
|
2014-05-21 22:20:30 +08:00
|
|
|
}
|
|
|
|
|
2014-06-05 06:42:17 +08:00
|
|
|
void worksheet::auto_filter(const xlnt::range &range)
|
2014-05-21 22:20:30 +08:00
|
|
|
{
|
2014-06-05 06:42:17 +08:00
|
|
|
auto_filter(range.get_reference());
|
2014-05-21 22:20:30 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
range_reference worksheet::get_auto_filter() const
|
|
|
|
{
|
2014-05-30 08:52:14 +08:00
|
|
|
return d_->auto_filter_;
|
2014-05-21 22:20:30 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
bool worksheet::has_auto_filter() const
|
|
|
|
{
|
2014-05-30 08:52:14 +08:00
|
|
|
return d_->auto_filter_.get_width() > 0;
|
2014-05-21 22:20:30 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
void worksheet::unset_auto_filter()
|
|
|
|
{
|
2015-10-15 06:05:13 +08:00
|
|
|
d_->auto_filter_ = range_reference(1, 1, 1, 1);
|
2014-05-21 22:20:30 +08:00
|
|
|
}
|
|
|
|
|
2015-10-31 06:54:04 +08:00
|
|
|
page_setup &worksheet::get_page_setup()
|
|
|
|
{
|
|
|
|
return d_->page_setup_;
|
|
|
|
}
|
|
|
|
|
2015-10-30 01:46:56 +08:00
|
|
|
const page_setup &worksheet::get_page_setup() const
|
2014-05-21 22:20:30 +08:00
|
|
|
{
|
2014-05-30 08:52:14 +08:00
|
|
|
return d_->page_setup_;
|
2014-05-21 22:20:30 +08:00
|
|
|
}
|
|
|
|
|
2015-11-11 07:58:54 +08:00
|
|
|
std::string worksheet::to_string() const
|
2014-05-21 22:20:30 +08:00
|
|
|
{
|
2014-05-30 08:52:14 +08:00
|
|
|
return "<Worksheet \"" + d_->title_ + "\">";
|
2014-05-21 22:20:30 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
workbook &worksheet::get_parent() const
|
|
|
|
{
|
2014-05-30 08:52:14 +08:00
|
|
|
return *d_->parent_;
|
2014-05-21 22:20:30 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
void worksheet::garbage_collect()
|
|
|
|
{
|
2014-05-30 08:52:14 +08:00
|
|
|
auto cell_map_iter = d_->cell_map_.begin();
|
2014-07-25 05:31:46 +08:00
|
|
|
|
2015-11-01 22:43:01 +08:00
|
|
|
while (cell_map_iter != d_->cell_map_.end())
|
2014-05-30 08:52:14 +08:00
|
|
|
{
|
|
|
|
auto cell_iter = cell_map_iter->second.begin();
|
2014-07-25 05:31:46 +08:00
|
|
|
|
2015-11-01 22:43:01 +08:00
|
|
|
while (cell_iter != cell_map_iter->second.end())
|
2014-05-30 08:52:14 +08:00
|
|
|
{
|
2014-07-25 05:31:46 +08:00
|
|
|
cell current_cell(&cell_iter->second);
|
|
|
|
|
2015-11-01 22:43:01 +08:00
|
|
|
if (current_cell.garbage_collectible())
|
2014-05-30 08:52:14 +08:00
|
|
|
{
|
|
|
|
cell_iter = cell_map_iter->second.erase(cell_iter);
|
|
|
|
continue;
|
|
|
|
}
|
2014-07-25 05:31:46 +08:00
|
|
|
|
2014-05-30 08:52:14 +08:00
|
|
|
cell_iter++;
|
|
|
|
}
|
2014-07-25 05:31:46 +08:00
|
|
|
|
2015-11-01 22:43:01 +08:00
|
|
|
if (cell_map_iter->second.empty())
|
2014-05-30 08:52:14 +08:00
|
|
|
{
|
|
|
|
cell_map_iter = d_->cell_map_.erase(cell_map_iter);
|
|
|
|
continue;
|
|
|
|
}
|
2014-07-25 05:31:46 +08:00
|
|
|
|
2014-05-30 08:52:14 +08:00
|
|
|
cell_map_iter++;
|
|
|
|
}
|
2014-05-21 22:20:30 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
std::list<cell> worksheet::get_cell_collection()
|
|
|
|
{
|
2014-05-30 08:52:14 +08:00
|
|
|
std::list<cell> cells;
|
2015-11-01 22:43:01 +08:00
|
|
|
for (auto &c : d_->cell_map_)
|
2014-05-30 08:52:14 +08:00
|
|
|
{
|
2015-11-01 22:43:01 +08:00
|
|
|
for (auto &d : c.second)
|
2014-05-30 08:52:14 +08:00
|
|
|
{
|
|
|
|
cells.push_back(cell(&d.second));
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return cells;
|
2014-05-21 22:20:30 +08:00
|
|
|
}
|
|
|
|
|
2015-11-11 07:58:54 +08:00
|
|
|
std::string worksheet::get_title() const
|
2014-05-21 22:20:30 +08:00
|
|
|
{
|
2015-11-01 22:43:01 +08:00
|
|
|
if (d_ == nullptr)
|
2014-05-21 22:20:30 +08:00
|
|
|
{
|
|
|
|
throw std::runtime_error("null worksheet");
|
|
|
|
}
|
2014-05-30 08:52:14 +08:00
|
|
|
return d_->title_;
|
2014-05-21 22:20:30 +08:00
|
|
|
}
|
|
|
|
|
2015-11-11 07:58:54 +08:00
|
|
|
void worksheet::set_title(const std::string &title)
|
2014-05-21 22:20:30 +08:00
|
|
|
{
|
2014-05-30 08:52:14 +08:00
|
|
|
d_->title_ = title;
|
2014-05-21 22:20:30 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
cell_reference worksheet::get_frozen_panes() const
|
|
|
|
{
|
2014-05-30 08:52:14 +08:00
|
|
|
return d_->freeze_panes_;
|
2014-05-21 22:20:30 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
void worksheet::freeze_panes(xlnt::cell top_left_cell)
|
|
|
|
{
|
2014-05-30 08:52:14 +08:00
|
|
|
d_->freeze_panes_ = top_left_cell.get_reference();
|
2014-05-21 22:20:30 +08:00
|
|
|
}
|
|
|
|
|
2015-11-11 07:58:54 +08:00
|
|
|
void worksheet::freeze_panes(const std::string &top_left_coordinate)
|
2014-05-21 22:20:30 +08:00
|
|
|
{
|
2014-05-30 08:52:14 +08:00
|
|
|
d_->freeze_panes_ = cell_reference(top_left_coordinate);
|
2014-05-21 22:20:30 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
void worksheet::unfreeze_panes()
|
|
|
|
{
|
2014-05-30 08:52:14 +08:00
|
|
|
d_->freeze_panes_ = cell_reference("A1");
|
2014-05-21 22:20:30 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
cell worksheet::get_cell(const cell_reference &reference)
|
|
|
|
{
|
2015-11-01 22:43:01 +08:00
|
|
|
if (d_->cell_map_.find(reference.get_row()) == d_->cell_map_.end())
|
2014-05-30 08:52:14 +08:00
|
|
|
{
|
2015-10-14 01:56:07 +08:00
|
|
|
d_->cell_map_[reference.get_row()] = std::unordered_map<column_t, detail::cell_impl>();
|
2014-05-30 08:52:14 +08:00
|
|
|
}
|
2015-11-01 22:43:01 +08:00
|
|
|
|
2015-10-14 01:56:07 +08:00
|
|
|
auto &row = d_->cell_map_[reference.get_row()];
|
2015-11-01 22:43:01 +08:00
|
|
|
|
|
|
|
if (row.find(reference.get_column_index()) == row.end())
|
2014-05-30 08:52:14 +08:00
|
|
|
{
|
2015-10-14 01:56:07 +08:00
|
|
|
row[reference.get_column_index()] = detail::cell_impl(d_, reference.get_column_index(), reference.get_row());
|
2014-05-30 08:52:14 +08:00
|
|
|
}
|
2015-11-01 22:43:01 +08:00
|
|
|
|
2014-05-30 08:52:14 +08:00
|
|
|
return cell(&row[reference.get_column_index()]);
|
2014-05-21 22:20:30 +08:00
|
|
|
}
|
|
|
|
|
2014-05-22 05:48:51 +08:00
|
|
|
const cell worksheet::get_cell(const cell_reference &reference) const
|
|
|
|
{
|
2015-10-14 01:56:07 +08:00
|
|
|
return cell(&d_->cell_map_.at(reference.get_row()).at(reference.get_column_index()));
|
2014-05-22 05:48:51 +08:00
|
|
|
}
|
|
|
|
|
2014-06-11 05:12:15 +08:00
|
|
|
bool worksheet::has_row_properties(row_t row) const
|
|
|
|
{
|
|
|
|
return d_->row_properties_.find(row) != d_->row_properties_.end();
|
|
|
|
}
|
|
|
|
|
2015-11-11 07:58:54 +08:00
|
|
|
range worksheet::get_named_range(const std::string &name)
|
2014-05-21 22:20:30 +08:00
|
|
|
{
|
2015-11-01 22:43:01 +08:00
|
|
|
if (!has_named_range(name))
|
2014-05-30 08:52:14 +08:00
|
|
|
{
|
2014-07-24 04:00:09 +08:00
|
|
|
throw named_range_exception();
|
2014-05-30 08:52:14 +08:00
|
|
|
}
|
2015-11-01 22:43:01 +08:00
|
|
|
|
2015-10-15 06:05:13 +08:00
|
|
|
return get_range(d_->named_ranges_[name].get_targets()[0].second);
|
2014-05-30 08:52:14 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
column_t worksheet::get_lowest_column() const
|
|
|
|
{
|
2015-11-01 22:43:01 +08:00
|
|
|
if (d_->cell_map_.empty())
|
2014-05-30 08:52:14 +08:00
|
|
|
{
|
2015-11-04 03:53:48 +08:00
|
|
|
return constants::MinColumn();
|
2014-05-30 08:52:14 +08:00
|
|
|
}
|
2015-11-01 22:43:01 +08:00
|
|
|
|
2015-11-04 03:53:48 +08:00
|
|
|
column_t lowest = constants::MaxColumn();
|
2015-11-01 22:43:01 +08:00
|
|
|
|
|
|
|
for (auto &row : d_->cell_map_)
|
2014-05-30 08:52:14 +08:00
|
|
|
{
|
2015-11-01 22:43:01 +08:00
|
|
|
for (auto &c : row.second)
|
2014-05-30 08:52:14 +08:00
|
|
|
{
|
2015-11-04 03:53:48 +08:00
|
|
|
lowest = std::min(lowest, c.first);
|
2014-05-30 08:52:14 +08:00
|
|
|
}
|
|
|
|
}
|
2015-11-01 22:43:01 +08:00
|
|
|
|
2015-10-14 01:56:07 +08:00
|
|
|
return lowest;
|
2014-05-30 08:52:14 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
row_t worksheet::get_lowest_row() const
|
|
|
|
{
|
2015-11-01 22:43:01 +08:00
|
|
|
if (d_->cell_map_.empty())
|
2014-05-30 08:52:14 +08:00
|
|
|
{
|
2015-11-04 03:53:48 +08:00
|
|
|
return constants::MinRow();
|
2014-05-30 08:52:14 +08:00
|
|
|
}
|
2015-11-01 22:43:01 +08:00
|
|
|
|
2015-11-04 03:53:48 +08:00
|
|
|
row_t lowest = constants::MaxRow();
|
2015-11-01 22:43:01 +08:00
|
|
|
|
|
|
|
for (auto &row : d_->cell_map_)
|
2014-05-30 08:52:14 +08:00
|
|
|
{
|
2015-11-04 03:53:48 +08:00
|
|
|
lowest = std::min(lowest, row.first);
|
2014-05-30 08:52:14 +08:00
|
|
|
}
|
2015-11-01 22:43:01 +08:00
|
|
|
|
2015-10-14 01:56:07 +08:00
|
|
|
return lowest;
|
2014-05-21 22:20:30 +08:00
|
|
|
}
|
|
|
|
|
2014-05-30 08:52:14 +08:00
|
|
|
row_t worksheet::get_highest_row() const
|
2014-05-21 22:20:30 +08:00
|
|
|
{
|
2015-11-04 03:53:48 +08:00
|
|
|
row_t highest = constants::MinRow();
|
2015-11-01 22:43:01 +08:00
|
|
|
|
|
|
|
for (auto &row : d_->cell_map_)
|
2014-05-30 08:52:14 +08:00
|
|
|
{
|
2015-11-04 03:53:48 +08:00
|
|
|
highest = std::max(highest, row.first);
|
2014-05-30 08:52:14 +08:00
|
|
|
}
|
2015-11-01 22:43:01 +08:00
|
|
|
|
2015-10-14 01:56:07 +08:00
|
|
|
return highest;
|
2014-05-21 22:20:30 +08:00
|
|
|
}
|
|
|
|
|
2014-05-30 08:52:14 +08:00
|
|
|
column_t worksheet::get_highest_column() const
|
2014-05-21 22:20:30 +08:00
|
|
|
{
|
2015-11-04 03:53:48 +08:00
|
|
|
column_t highest = constants::MinColumn();
|
2015-11-01 22:43:01 +08:00
|
|
|
|
|
|
|
for (auto &row : d_->cell_map_)
|
2014-05-30 08:52:14 +08:00
|
|
|
{
|
2015-11-01 22:43:01 +08:00
|
|
|
for (auto &c : row.second)
|
2014-05-30 08:52:14 +08:00
|
|
|
{
|
2015-11-04 03:53:48 +08:00
|
|
|
highest = std::max(highest, c.first);
|
2014-05-30 08:52:14 +08:00
|
|
|
}
|
|
|
|
}
|
2015-11-01 22:43:01 +08:00
|
|
|
|
2015-10-14 01:56:07 +08:00
|
|
|
return highest;
|
2014-05-21 22:20:30 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
range_reference worksheet::calculate_dimension() const
|
|
|
|
{
|
2015-10-15 06:05:13 +08:00
|
|
|
auto lowest_column = get_lowest_column();
|
|
|
|
auto lowest_row = get_lowest_row();
|
2015-11-01 22:43:01 +08:00
|
|
|
|
2015-10-15 06:05:13 +08:00
|
|
|
auto highest_column = get_highest_column();
|
|
|
|
auto highest_row = get_highest_row();
|
2015-11-01 22:43:01 +08:00
|
|
|
|
2015-10-14 01:56:07 +08:00
|
|
|
return range_reference(lowest_column, lowest_row, highest_column, highest_row);
|
2014-05-21 22:20:30 +08:00
|
|
|
}
|
|
|
|
|
2015-11-11 08:47:31 +08:00
|
|
|
range worksheet::get_range(const std::string &reference_string)
|
|
|
|
{
|
|
|
|
return get_range(range_reference(reference_string));
|
|
|
|
}
|
|
|
|
|
2014-05-21 22:20:30 +08:00
|
|
|
range worksheet::get_range(const range_reference &reference)
|
|
|
|
{
|
2014-05-30 08:52:14 +08:00
|
|
|
return range(*this, reference);
|
|
|
|
}
|
|
|
|
|
2015-11-11 08:47:31 +08:00
|
|
|
const range worksheet::get_range(const std::string &reference_string) const
|
|
|
|
{
|
|
|
|
return get_range(range_reference(reference_string));
|
|
|
|
}
|
|
|
|
|
2014-05-30 08:52:14 +08:00
|
|
|
const range worksheet::get_range(const range_reference &reference) const
|
|
|
|
{
|
|
|
|
return range(*this, reference);
|
2014-05-21 22:20:30 +08:00
|
|
|
}
|
|
|
|
|
2015-10-14 01:56:07 +08:00
|
|
|
range worksheet::get_squared_range(column_t min_col, row_t min_row, column_t max_col, row_t max_row)
|
|
|
|
{
|
|
|
|
range_reference reference(min_col, min_row, max_col, max_row);
|
|
|
|
return get_range(reference);
|
|
|
|
}
|
|
|
|
|
|
|
|
const range worksheet::get_squared_range(column_t min_col, row_t min_row, column_t max_col, row_t max_row) const
|
|
|
|
{
|
|
|
|
range_reference reference(min_col, min_row, max_col, max_row);
|
|
|
|
return get_range(reference);
|
|
|
|
}
|
|
|
|
|
2015-10-30 07:37:07 +08:00
|
|
|
const std::vector<relationship> &worksheet::get_relationships() const
|
2014-05-21 22:20:30 +08:00
|
|
|
{
|
2014-05-30 08:52:14 +08:00
|
|
|
return d_->relationships_;
|
2014-05-21 22:20:30 +08:00
|
|
|
}
|
|
|
|
|
2015-11-11 07:58:54 +08:00
|
|
|
relationship worksheet::create_relationship(relationship::type type, const std::string &target_uri)
|
2014-05-21 22:20:30 +08:00
|
|
|
{
|
2015-11-11 07:58:54 +08:00
|
|
|
std::string r_id = "rId" + std::to_string(d_->relationships_.size() + 1);
|
2014-07-20 02:43:48 +08:00
|
|
|
d_->relationships_.push_back(relationship(type, r_id, target_uri));
|
2014-05-30 08:52:14 +08:00
|
|
|
return d_->relationships_.back();
|
2014-05-21 22:20:30 +08:00
|
|
|
}
|
|
|
|
|
2015-11-11 08:47:31 +08:00
|
|
|
void worksheet::merge_cells(const std::string &reference_string)
|
|
|
|
{
|
|
|
|
merge_cells(range_reference(reference_string));
|
|
|
|
}
|
|
|
|
|
|
|
|
void worksheet::unmerge_cells(const std::string &reference_string)
|
|
|
|
{
|
|
|
|
unmerge_cells(range_reference(reference_string));
|
|
|
|
}
|
|
|
|
|
2014-05-21 22:20:30 +08:00
|
|
|
void worksheet::merge_cells(const range_reference &reference)
|
|
|
|
{
|
2014-05-30 08:52:14 +08:00
|
|
|
d_->merged_cells_.push_back(reference);
|
|
|
|
bool first = true;
|
|
|
|
|
2015-11-01 22:43:01 +08:00
|
|
|
for (auto row : get_range(reference))
|
2014-05-30 08:52:14 +08:00
|
|
|
{
|
2015-11-01 22:43:01 +08:00
|
|
|
for (auto cell : row)
|
2014-05-30 08:52:14 +08:00
|
|
|
{
|
|
|
|
cell.set_merged(true);
|
2014-07-26 04:39:25 +08:00
|
|
|
|
2015-11-01 22:43:01 +08:00
|
|
|
if (!first)
|
2014-05-30 08:52:14 +08:00
|
|
|
{
|
2015-11-01 22:43:01 +08:00
|
|
|
if (cell.get_data_type() == cell::type::string)
|
2014-07-26 04:39:25 +08:00
|
|
|
{
|
2015-10-14 01:56:07 +08:00
|
|
|
cell.set_value("");
|
2014-07-26 04:39:25 +08:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2015-10-14 01:56:07 +08:00
|
|
|
cell.clear_value();
|
2014-07-26 04:39:25 +08:00
|
|
|
}
|
2014-05-30 08:52:14 +08:00
|
|
|
}
|
2014-07-26 04:39:25 +08:00
|
|
|
|
2014-05-30 08:52:14 +08:00
|
|
|
first = false;
|
|
|
|
}
|
|
|
|
}
|
2014-05-21 22:20:30 +08:00
|
|
|
}
|
|
|
|
|
2015-10-14 01:56:07 +08:00
|
|
|
void worksheet::merge_cells(column_t start_column, row_t start_row, column_t end_column, row_t end_row)
|
|
|
|
{
|
|
|
|
merge_cells(xlnt::range_reference(start_column, start_row, end_column, end_row));
|
|
|
|
}
|
|
|
|
|
2014-05-21 22:20:30 +08:00
|
|
|
void worksheet::unmerge_cells(const range_reference &reference)
|
|
|
|
{
|
2014-05-30 08:52:14 +08:00
|
|
|
auto match = std::find(d_->merged_cells_.begin(), d_->merged_cells_.end(), reference);
|
2015-11-01 22:43:01 +08:00
|
|
|
|
|
|
|
if (match == d_->merged_cells_.end())
|
2014-05-30 08:52:14 +08:00
|
|
|
{
|
|
|
|
throw std::runtime_error("cells not merged");
|
|
|
|
}
|
2015-11-01 22:43:01 +08:00
|
|
|
|
2014-05-30 08:52:14 +08:00
|
|
|
d_->merged_cells_.erase(match);
|
2015-11-01 22:43:01 +08:00
|
|
|
|
|
|
|
for (auto row : get_range(reference))
|
2014-05-30 08:52:14 +08:00
|
|
|
{
|
2015-11-01 22:43:01 +08:00
|
|
|
for (auto cell : row)
|
2014-05-30 08:52:14 +08:00
|
|
|
{
|
|
|
|
cell.set_merged(false);
|
|
|
|
}
|
|
|
|
}
|
2014-05-21 22:20:30 +08:00
|
|
|
}
|
2015-11-01 22:43:01 +08:00
|
|
|
|
2015-10-14 01:56:07 +08:00
|
|
|
void worksheet::unmerge_cells(column_t start_column, row_t start_row, column_t end_column, row_t end_row)
|
|
|
|
{
|
|
|
|
unmerge_cells(xlnt::range_reference(start_column, start_row, end_column, end_row));
|
|
|
|
}
|
2014-05-21 22:20:30 +08:00
|
|
|
|
2015-10-14 04:35:22 +08:00
|
|
|
void worksheet::append()
|
|
|
|
{
|
|
|
|
get_cell(cell_reference(1, get_next_row()));
|
|
|
|
}
|
|
|
|
|
2015-11-11 07:58:54 +08:00
|
|
|
void worksheet::append(const std::vector<std::string> &cells)
|
2014-05-21 22:20:30 +08:00
|
|
|
{
|
2015-10-14 04:35:22 +08:00
|
|
|
xlnt::cell_reference next(1, get_next_row());
|
2015-11-01 22:43:01 +08:00
|
|
|
|
|
|
|
for (auto cell : cells)
|
2014-05-31 06:42:25 +08:00
|
|
|
{
|
2015-10-14 04:35:22 +08:00
|
|
|
get_cell(next).set_value(cell);
|
|
|
|
next.set_column_index(next.get_column_index() + 1);
|
2014-05-31 06:42:25 +08:00
|
|
|
}
|
2015-10-14 04:35:22 +08:00
|
|
|
}
|
2015-11-01 22:43:01 +08:00
|
|
|
|
2015-10-14 04:35:22 +08:00
|
|
|
row_t worksheet::get_next_row() const
|
|
|
|
{
|
2015-10-15 06:05:13 +08:00
|
|
|
auto row = get_highest_row() + 1;
|
2015-11-01 22:43:01 +08:00
|
|
|
|
|
|
|
if (row == 2 && d_->cell_map_.size() == 0)
|
2014-05-31 06:42:25 +08:00
|
|
|
{
|
2015-10-14 04:35:22 +08:00
|
|
|
row = 1;
|
2014-05-31 06:42:25 +08:00
|
|
|
}
|
2015-11-01 22:43:01 +08:00
|
|
|
|
2015-10-14 04:35:22 +08:00
|
|
|
return row;
|
2014-05-31 06:42:25 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
void worksheet::append(const std::vector<int> &cells)
|
|
|
|
{
|
2015-10-14 04:35:22 +08:00
|
|
|
xlnt::cell_reference next(1, get_next_row());
|
2015-11-01 22:43:01 +08:00
|
|
|
|
|
|
|
for (auto cell : cells)
|
2014-05-31 06:42:25 +08:00
|
|
|
{
|
2015-10-14 04:35:22 +08:00
|
|
|
get_cell(next).set_value(cell);
|
|
|
|
next.set_column_index(next.get_column_index() + 1);
|
2014-05-31 06:42:25 +08:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void worksheet::append(const std::vector<date> &cells)
|
|
|
|
{
|
2015-10-14 04:35:22 +08:00
|
|
|
xlnt::cell_reference next(1, get_next_row());
|
2015-11-01 22:43:01 +08:00
|
|
|
|
|
|
|
for (auto cell : cells)
|
2014-05-30 08:52:14 +08:00
|
|
|
{
|
2015-10-14 04:35:22 +08:00
|
|
|
get_cell(next).set_value(cell);
|
|
|
|
next.set_column_index(next.get_column_index() + 1);
|
2014-05-30 08:52:14 +08:00
|
|
|
}
|
2014-05-21 22:20:30 +08:00
|
|
|
}
|
|
|
|
|
2015-10-14 01:56:07 +08:00
|
|
|
void worksheet::append(const std::vector<cell> &cells)
|
2014-05-21 22:20:30 +08:00
|
|
|
{
|
2015-10-14 04:35:22 +08:00
|
|
|
xlnt::cell_reference next(1, get_next_row());
|
2015-11-01 22:43:01 +08:00
|
|
|
|
|
|
|
for (auto cell : cells)
|
2014-05-30 08:52:14 +08:00
|
|
|
{
|
2015-10-14 04:35:22 +08:00
|
|
|
get_cell(next).set_value(cell);
|
|
|
|
next.set_column_index(next.get_column_index() + 1);
|
2014-05-30 08:52:14 +08:00
|
|
|
}
|
2015-10-14 01:56:07 +08:00
|
|
|
}
|
2015-11-01 22:43:01 +08:00
|
|
|
|
2015-11-11 07:58:54 +08:00
|
|
|
void worksheet::append(const std::unordered_map<std::string, std::string> &cells)
|
2015-10-14 01:56:07 +08:00
|
|
|
{
|
2015-10-14 04:35:22 +08:00
|
|
|
auto row = get_next_row();
|
2015-11-01 22:43:01 +08:00
|
|
|
|
|
|
|
for (auto cell : cells)
|
2014-05-30 08:52:14 +08:00
|
|
|
{
|
2015-10-14 01:56:07 +08:00
|
|
|
get_cell(cell_reference(cell.first, row)).set_value(cell.second);
|
2014-05-30 08:52:14 +08:00
|
|
|
}
|
2014-05-21 22:20:30 +08:00
|
|
|
}
|
|
|
|
|
2015-11-11 07:58:54 +08:00
|
|
|
void worksheet::append(const std::unordered_map<int, std::string> &cells)
|
2014-05-21 22:20:30 +08:00
|
|
|
{
|
2015-10-14 04:35:22 +08:00
|
|
|
auto row = get_next_row();
|
2015-11-01 22:43:01 +08:00
|
|
|
|
|
|
|
for (auto cell : cells)
|
2014-05-30 08:52:14 +08:00
|
|
|
{
|
2015-10-15 06:05:13 +08:00
|
|
|
get_cell(cell_reference(static_cast<column_t>(cell.first), row)).set_value(cell.second);
|
2014-05-30 08:52:14 +08:00
|
|
|
}
|
2015-10-14 01:56:07 +08:00
|
|
|
}
|
2015-11-01 22:43:01 +08:00
|
|
|
|
2015-10-14 01:56:07 +08:00
|
|
|
void worksheet::append(const std::vector<int>::const_iterator begin, const std::vector<int>::const_iterator end)
|
|
|
|
{
|
2015-10-14 04:35:22 +08:00
|
|
|
xlnt::cell_reference next(1, get_next_row());
|
2014-05-30 08:52:14 +08:00
|
|
|
|
2015-11-01 22:43:01 +08:00
|
|
|
for (auto i = begin; i != end; i++)
|
2014-05-30 08:52:14 +08:00
|
|
|
{
|
2015-10-14 04:35:22 +08:00
|
|
|
get_cell(next).set_value(*i);
|
|
|
|
next.set_column_index(next.get_column_index() + 1);
|
2014-05-30 08:52:14 +08:00
|
|
|
}
|
2014-05-21 22:20:30 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
xlnt::range worksheet::rows() const
|
|
|
|
{
|
2014-05-30 08:52:14 +08:00
|
|
|
return get_range(calculate_dimension());
|
2014-05-21 22:20:30 +08:00
|
|
|
}
|
|
|
|
|
2015-11-11 07:58:54 +08:00
|
|
|
xlnt::range worksheet::rows(const std::string &range_string) const
|
2015-10-14 01:56:07 +08:00
|
|
|
{
|
|
|
|
return get_range(range_reference(range_string));
|
|
|
|
}
|
|
|
|
|
2015-11-11 07:58:54 +08:00
|
|
|
xlnt::range worksheet::rows(const std::string &range_string, int row_offset, int column_offset) const
|
2015-10-14 01:56:07 +08:00
|
|
|
{
|
|
|
|
range_reference reference(range_string);
|
|
|
|
return get_range(reference.make_offset(column_offset, row_offset));
|
|
|
|
}
|
|
|
|
|
2014-07-20 04:59:05 +08:00
|
|
|
xlnt::range worksheet::columns() const
|
|
|
|
{
|
2014-07-20 05:42:04 +08:00
|
|
|
return range(*this, calculate_dimension(), major_order::column);
|
2014-07-20 04:59:05 +08:00
|
|
|
}
|
|
|
|
|
2014-05-21 22:20:30 +08:00
|
|
|
bool worksheet::operator==(const worksheet &other) const
|
|
|
|
{
|
2014-05-30 08:52:14 +08:00
|
|
|
return d_ == other.d_;
|
2014-05-21 22:20:30 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
bool worksheet::operator!=(const worksheet &other) const
|
|
|
|
{
|
2014-05-30 08:52:14 +08:00
|
|
|
return d_ != other.d_;
|
2014-05-21 22:20:30 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
bool worksheet::operator==(std::nullptr_t) const
|
|
|
|
{
|
2014-05-30 08:52:14 +08:00
|
|
|
return d_ == nullptr;
|
2014-05-21 22:20:30 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
bool worksheet::operator!=(std::nullptr_t) const
|
|
|
|
{
|
2014-05-30 08:52:14 +08:00
|
|
|
return d_ != nullptr;
|
2014-05-21 22:20:30 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
void worksheet::operator=(const worksheet &other)
|
|
|
|
{
|
2014-05-30 08:52:14 +08:00
|
|
|
d_ = other.d_;
|
2014-05-21 22:20:30 +08:00
|
|
|
}
|
|
|
|
|
2014-05-22 05:48:51 +08:00
|
|
|
const cell worksheet::operator[](const cell_reference &ref) const
|
2014-05-21 22:20:30 +08:00
|
|
|
{
|
|
|
|
return get_cell(ref);
|
|
|
|
}
|
|
|
|
|
|
|
|
range worksheet::operator[](const range_reference &ref)
|
|
|
|
{
|
|
|
|
return get_range(ref);
|
|
|
|
}
|
|
|
|
|
2015-11-11 07:58:54 +08:00
|
|
|
range worksheet::operator[](const std::string &name)
|
2014-05-21 22:20:30 +08:00
|
|
|
{
|
2015-11-01 22:43:01 +08:00
|
|
|
if (has_named_range(name))
|
2014-05-21 22:20:30 +08:00
|
|
|
{
|
|
|
|
return get_named_range(name);
|
|
|
|
}
|
|
|
|
return get_range(range_reference(name));
|
|
|
|
}
|
|
|
|
|
2015-11-11 07:58:54 +08:00
|
|
|
bool worksheet::has_named_range(const std::string &name)
|
2014-05-21 22:20:30 +08:00
|
|
|
{
|
2014-05-30 08:52:14 +08:00
|
|
|
return d_->named_ranges_.find(name) != d_->named_ranges_.end();
|
2014-05-21 22:20:30 +08:00
|
|
|
}
|
2014-05-30 08:52:14 +08:00
|
|
|
|
2015-11-11 07:58:54 +08:00
|
|
|
void worksheet::remove_named_range(const std::string &name)
|
2014-05-21 22:20:30 +08:00
|
|
|
{
|
2015-11-01 22:43:01 +08:00
|
|
|
if (!has_named_range(name))
|
2014-05-30 08:52:14 +08:00
|
|
|
{
|
|
|
|
throw std::runtime_error("worksheet doesn't have named range");
|
|
|
|
}
|
|
|
|
|
|
|
|
d_->named_ranges_.erase(name);
|
2014-05-21 22:20:30 +08:00
|
|
|
}
|
2014-05-22 05:48:51 +08:00
|
|
|
|
|
|
|
void worksheet::reserve(std::size_t n)
|
|
|
|
{
|
2014-05-30 08:52:14 +08:00
|
|
|
d_->cell_map_.reserve(n);
|
2014-05-22 05:48:51 +08:00
|
|
|
}
|
2015-11-01 22:43:01 +08:00
|
|
|
|
2014-07-21 21:34:57 +08:00
|
|
|
void worksheet::increment_comments()
|
2014-07-20 02:43:48 +08:00
|
|
|
{
|
2014-07-21 21:34:57 +08:00
|
|
|
d_->comment_count_++;
|
2014-07-20 02:43:48 +08:00
|
|
|
}
|
|
|
|
|
2014-07-21 21:34:57 +08:00
|
|
|
void worksheet::decrement_comments()
|
2014-07-20 02:43:48 +08:00
|
|
|
{
|
2014-07-21 21:34:57 +08:00
|
|
|
d_->comment_count_--;
|
2014-07-20 02:43:48 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
std::size_t worksheet::get_comment_count() const
|
|
|
|
{
|
2014-07-21 21:34:57 +08:00
|
|
|
return d_->comment_count_;
|
2014-07-20 02:43:48 +08:00
|
|
|
}
|
2014-07-20 04:59:05 +08:00
|
|
|
|
|
|
|
header_footer &worksheet::get_header_footer()
|
|
|
|
{
|
|
|
|
return d_->header_footer_;
|
|
|
|
}
|
|
|
|
|
|
|
|
const header_footer &worksheet::get_header_footer() const
|
|
|
|
{
|
|
|
|
return d_->header_footer_;
|
|
|
|
}
|
|
|
|
|
|
|
|
header_footer::header_footer()
|
|
|
|
{
|
|
|
|
}
|
|
|
|
|
2014-07-24 08:51:28 +08:00
|
|
|
header::header() : default_(true), font_size_(12)
|
2014-07-20 04:59:05 +08:00
|
|
|
{
|
|
|
|
}
|
|
|
|
|
2014-07-24 08:51:28 +08:00
|
|
|
footer::footer() : default_(true), font_size_(12)
|
2014-07-20 04:59:05 +08:00
|
|
|
{
|
|
|
|
}
|
|
|
|
|
2014-07-24 08:51:28 +08:00
|
|
|
void worksheet::set_parent(xlnt::workbook &wb)
|
|
|
|
{
|
|
|
|
d_->parent_ = &wb;
|
|
|
|
}
|
|
|
|
|
2015-11-11 07:58:54 +08:00
|
|
|
std::vector<std::string> worksheet::get_formula_attributes() const
|
2014-07-25 05:31:46 +08:00
|
|
|
{
|
|
|
|
return {};
|
|
|
|
}
|
|
|
|
|
2014-07-26 04:39:25 +08:00
|
|
|
cell_reference worksheet::get_point_pos(int left, int top) const
|
|
|
|
{
|
|
|
|
static const double DefaultColumnWidth = 51.85;
|
|
|
|
static const double DefaultRowHeight = 15.0;
|
|
|
|
|
2015-11-03 05:45:05 +08:00
|
|
|
auto points_to_pixels = [](long double value, long double dpi)
|
|
|
|
{
|
|
|
|
return static_cast<int>(std::ceil(value * dpi / 72));
|
|
|
|
};
|
2015-11-01 22:43:01 +08:00
|
|
|
|
2014-07-26 04:39:25 +08:00
|
|
|
auto default_height = points_to_pixels(DefaultRowHeight, 96.0);
|
|
|
|
auto default_width = points_to_pixels(DefaultColumnWidth, 96.0);
|
|
|
|
|
2015-10-14 01:56:07 +08:00
|
|
|
column_t current_column = 1;
|
|
|
|
row_t current_row = 1;
|
2014-07-26 04:39:25 +08:00
|
|
|
|
|
|
|
int left_pos = 0;
|
|
|
|
int top_pos = 0;
|
|
|
|
|
2015-11-01 22:43:01 +08:00
|
|
|
while (left_pos <= left)
|
2014-07-26 04:39:25 +08:00
|
|
|
{
|
|
|
|
current_column++;
|
|
|
|
|
2015-11-01 22:43:01 +08:00
|
|
|
if (has_column_properties(current_column))
|
2014-07-26 04:39:25 +08:00
|
|
|
{
|
2015-10-29 03:08:54 +08:00
|
|
|
auto cdw = get_column_properties(current_column).width;
|
2014-07-26 04:39:25 +08:00
|
|
|
|
2015-11-01 22:43:01 +08:00
|
|
|
if (cdw >= 0)
|
2014-07-26 04:39:25 +08:00
|
|
|
{
|
|
|
|
left_pos += points_to_pixels(cdw, 96.0);
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
left_pos += default_width;
|
|
|
|
}
|
|
|
|
|
2015-11-01 22:43:01 +08:00
|
|
|
while (top_pos <= top)
|
2014-07-26 04:39:25 +08:00
|
|
|
{
|
|
|
|
current_row++;
|
|
|
|
|
2015-11-01 22:43:01 +08:00
|
|
|
if (has_row_properties(current_row))
|
2014-07-26 04:39:25 +08:00
|
|
|
{
|
2015-10-29 03:08:54 +08:00
|
|
|
auto cdh = get_row_properties(current_row).height;
|
2014-07-26 04:39:25 +08:00
|
|
|
|
2015-11-01 22:43:01 +08:00
|
|
|
if (cdh >= 0)
|
2014-07-26 04:39:25 +08:00
|
|
|
{
|
|
|
|
top_pos += points_to_pixels(cdh, 96.0);
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
top_pos += default_height;
|
|
|
|
}
|
|
|
|
|
2015-11-01 22:43:01 +08:00
|
|
|
return { current_column - 1, current_row - 1 };
|
2014-07-26 04:39:25 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
cell_reference worksheet::get_point_pos(const std::pair<int, int> &point) const
|
|
|
|
{
|
|
|
|
return get_point_pos(point.first, point.second);
|
|
|
|
}
|
2015-11-01 22:43:01 +08:00
|
|
|
|
2015-10-14 12:03:48 +08:00
|
|
|
void worksheet::set_sheet_state(page_setup::sheet_state state)
|
|
|
|
{
|
|
|
|
get_page_setup().set_sheet_state(state);
|
|
|
|
}
|
2014-07-26 04:39:25 +08:00
|
|
|
|
2015-10-29 03:08:54 +08:00
|
|
|
void worksheet::add_column_properties(column_t column, const xlnt::column_properties &props)
|
|
|
|
{
|
|
|
|
d_->column_properties_[column] = props;
|
|
|
|
}
|
|
|
|
|
|
|
|
bool worksheet::has_column_properties(column_t column) const
|
|
|
|
{
|
|
|
|
return d_->column_properties_.find(column) != d_->column_properties_.end();
|
|
|
|
}
|
|
|
|
|
|
|
|
column_properties &worksheet::get_column_properties(column_t column)
|
|
|
|
{
|
|
|
|
return d_->column_properties_[column];
|
|
|
|
}
|
|
|
|
|
|
|
|
const column_properties &worksheet::get_column_properties(column_t column) const
|
|
|
|
{
|
|
|
|
return d_->column_properties_.at(column);
|
|
|
|
}
|
|
|
|
|
|
|
|
row_properties &worksheet::get_row_properties(row_t row)
|
|
|
|
{
|
|
|
|
return d_->row_properties_[row];
|
|
|
|
}
|
|
|
|
|
|
|
|
const row_properties &worksheet::get_row_properties(row_t row) const
|
|
|
|
{
|
|
|
|
return d_->row_properties_.at(row);
|
|
|
|
}
|
|
|
|
|
2014-05-21 22:20:30 +08:00
|
|
|
} // namespace xlnt
|