xlnt/source/worksheet.cpp

494 lines
10 KiB
C++
Raw Normal View History

2014-05-22 05:48:51 +08:00
#include <algorithm>
2014-06-06 04:19:31 +08:00
#include "worksheet/worksheet.hpp"
#include "cell/cell.hpp"
#include "common/datetime.hpp"
#include "worksheet/range.hpp"
#include "worksheet/range_reference.hpp"
#include "common/relationship.hpp"
#include "workbook/workbook.hpp"
#include "detail/worksheet_impl.hpp"
2014-05-21 22:20:30 +08:00
namespace xlnt {
2014-05-22 05:48:51 +08:00
worksheet::worksheet() : d_(nullptr)
{
2014-05-21 22:20:30 +08:00
}
2014-05-21 22:20:30 +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
{
}
worksheet::worksheet(const worksheet &rhs) : d_(rhs.d_)
2014-05-21 22:20:30 +08:00
{
2014-05-21 22:20:30 +08:00
}
worksheet::worksheet(workbook &parent, const std::string &title) : 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
{
return get_frozen_panes() != cell_reference("A1");
2014-05-21 22:20:30 +08:00
}
void worksheet::create_named_range(const std::string &name, const range_reference &reference)
2014-05-21 22:20:30 +08:00
{
d_->named_ranges_[name] = reference;
2014-05-21 22:20:30 +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
{
return d_->merged_cells_;
2014-05-21 22:20:30 +08:00
}
margins &worksheet::get_page_margins()
{
return d_->page_margins_;
2014-05-21 22:20:30 +08:00
}
2014-06-05 06:42:17 +08:00
void worksheet::auto_filter(const range_reference &reference)
2014-05-21 22:20:30 +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
{
return d_->auto_filter_;
2014-05-21 22:20:30 +08:00
}
bool worksheet::has_auto_filter() const
{
return d_->auto_filter_.get_width() > 0;
2014-05-21 22:20:30 +08:00
}
void worksheet::unset_auto_filter()
{
d_->auto_filter_ = range_reference(0, 0, 0, 0);
2014-05-21 22:20:30 +08:00
}
page_setup &worksheet::get_page_setup()
{
return d_->page_setup_;
2014-05-21 22:20:30 +08:00
}
std::string worksheet::to_string() const
{
return "<Worksheet \"" + d_->title_ + "\">";
2014-05-21 22:20:30 +08:00
}
workbook &worksheet::get_parent() const
{
return *d_->parent_;
2014-05-21 22:20:30 +08:00
}
void worksheet::garbage_collect()
{
auto cell_map_iter = d_->cell_map_.begin();
while(cell_map_iter != d_->cell_map_.end())
{
auto cell_iter = cell_map_iter->second.begin();
while(cell_iter != cell_map_iter->second.end())
{
if(cell(&cell_iter->second).get_data_type() == cell::type::null)
{
cell_iter = cell_map_iter->second.erase(cell_iter);
continue;
}
cell_iter++;
}
if(cell_map_iter->second.empty())
{
cell_map_iter = d_->cell_map_.erase(cell_map_iter);
continue;
}
cell_map_iter++;
}
2014-05-21 22:20:30 +08:00
}
std::list<cell> worksheet::get_cell_collection()
{
std::list<cell> cells;
for(auto &c : d_->cell_map_)
{
for(auto &d : c.second)
{
cells.push_back(cell(&d.second));
}
}
return cells;
2014-05-21 22:20:30 +08:00
}
std::string worksheet::get_title() const
{
if(d_ == nullptr)
2014-05-21 22:20:30 +08:00
{
throw std::runtime_error("null worksheet");
}
return d_->title_;
2014-05-21 22:20:30 +08:00
}
void worksheet::set_title(const std::string &title)
{
d_->title_ = title;
2014-05-21 22:20:30 +08:00
}
cell_reference worksheet::get_frozen_panes() const
{
return d_->freeze_panes_;
2014-05-21 22:20:30 +08:00
}
void worksheet::freeze_panes(xlnt::cell top_left_cell)
{
d_->freeze_panes_ = top_left_cell.get_reference();
2014-05-21 22:20:30 +08:00
}
void worksheet::freeze_panes(const std::string &top_left_coordinate)
{
d_->freeze_panes_ = cell_reference(top_left_coordinate);
2014-05-21 22:20:30 +08:00
}
void worksheet::unfreeze_panes()
{
d_->freeze_panes_ = cell_reference("A1");
2014-05-21 22:20:30 +08:00
}
cell worksheet::get_cell(const cell_reference &reference)
{
if(d_->cell_map_.find(reference.get_row_index()) == d_->cell_map_.end())
{
2014-05-31 06:42:25 +08:00
d_->cell_map_[reference.get_row_index()] = std::unordered_map<int, detail::cell_impl>();
}
auto &row = d_->cell_map_[reference.get_row_index()];
if(row.find(reference.get_column_index()) == row.end())
{
2014-06-06 05:42:15 +08:00
row[reference.get_column_index()] = detail::cell_impl(d_, reference.get_column_index(), reference.get_row_index());
}
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
{
return cell(&d_->cell_map_.at(reference.get_row_index()).at(reference.get_column_index()));
2014-05-22 05:48:51 +08:00
}
2014-06-05 06:42:17 +08:00
row_properties &worksheet::get_row_properties(row_t row)
{
return d_->row_properties_[row];
}
2014-05-21 22:20:30 +08:00
range worksheet::get_named_range(const std::string &name)
{
if(!has_named_range(name))
{
throw std::runtime_error("named range not found for this worksheet");
}
return get_range(d_->named_ranges_[name]);
}
column_t worksheet::get_lowest_column() const
{
if(d_->cell_map_.empty())
{
return 1;
}
column_t lowest = std::numeric_limits<column_t>::max();
for(auto &row : d_->cell_map_)
{
for(auto &c : row.second)
{
lowest = std::min(lowest, (column_t)c.first);
}
}
return lowest + 1;
}
row_t worksheet::get_lowest_row() const
{
if(d_->cell_map_.empty())
{
return 1;
}
row_t lowest = std::numeric_limits<row_t>::max();
for(auto &row : d_->cell_map_)
{
lowest = std::min(lowest, (row_t)row.first);
}
return lowest + 1;
2014-05-21 22:20:30 +08:00
}
row_t worksheet::get_highest_row() const
2014-05-21 22:20:30 +08:00
{
row_t highest = 0;
for(auto &row : d_->cell_map_)
{
highest = std::max(highest, (row_t)row.first);
}
return highest + 1;
2014-05-21 22:20:30 +08:00
}
column_t worksheet::get_highest_column() const
2014-05-21 22:20:30 +08:00
{
column_t highest = 0;
for(auto &row : d_->cell_map_)
{
for(auto &c : row.second)
{
highest = std::max(highest, (column_t)c.first);
}
}
return highest + 1;
2014-05-21 22:20:30 +08:00
}
range_reference worksheet::calculate_dimension() const
{
int lowest_column = get_lowest_column();
int lowest_row = get_lowest_row();
int highest_column = get_highest_column();
int highest_row = get_highest_row();
return range_reference(lowest_column - 1, lowest_row - 1, highest_column - 1, highest_row - 1);
2014-05-21 22:20:30 +08:00
}
range worksheet::get_range(const range_reference &reference)
{
return range(*this, reference);
}
const range worksheet::get_range(const range_reference &reference) const
{
return range(*this, reference);
2014-05-21 22:20:30 +08:00
}
std::vector<relationship> worksheet::get_relationships()
{
return d_->relationships_;
2014-05-21 22:20:30 +08:00
}
relationship worksheet::create_relationship(const std::string &relationship_type, const std::string &target_uri)
{
std::string r_id = "rId" + std::to_string(d_->relationships_.size() + 1);
d_->relationships_.push_back(relationship(relationship_type, r_id, target_uri));
return d_->relationships_.back();
2014-05-21 22:20:30 +08:00
}
void worksheet::merge_cells(const range_reference &reference)
{
d_->merged_cells_.push_back(reference);
bool first = true;
for(auto row : get_range(reference))
{
for(auto cell : row)
{
cell.set_merged(true);
if(!first)
{
2014-05-31 06:42:25 +08:00
cell.set_null();
}
first = false;
}
}
2014-05-21 22:20:30 +08:00
}
void worksheet::unmerge_cells(const range_reference &reference)
{
auto match = std::find(d_->merged_cells_.begin(), d_->merged_cells_.end(), reference);
if(match == d_->merged_cells_.end())
{
throw std::runtime_error("cells not merged");
}
d_->merged_cells_.erase(match);
for(auto row : get_range(reference))
{
for(auto cell : row)
{
cell.set_merged(false);
}
}
2014-05-21 22:20:30 +08:00
}
void worksheet::append(const std::vector<std::string> &cells)
{
int row = get_highest_row();
2014-05-31 06:42:25 +08:00
if(d_->cell_map_.size() == 0)
{
row--;
}
int column = 0;
for(auto cell : cells)
{
this->get_cell(cell_reference(column++, row)) = cell;
}
}
void worksheet::append(const std::vector<int> &cells)
{
int row = get_highest_row();
if(d_->cell_map_.size() == 0)
{
row--;
}
int column = 0;
for(auto cell : cells)
{
this->get_cell(cell_reference(column++, row)) = cell;
}
}
void worksheet::append(const std::vector<date> &cells)
{
int row = get_highest_row();
if(d_->cell_map_.size() == 0)
{
row--;
}
int column = 0;
for(auto cell : cells)
{
this->get_cell(cell_reference(column++, row)) = cell;
}
2014-05-21 22:20:30 +08:00
}
void worksheet::append(const std::unordered_map<std::string, std::string> &cells)
{
int row = get_highest_row() - 1;
if(d_->cell_map_.size() != 0)
{
row++;
}
for(auto cell : cells)
{
this->get_cell(cell_reference(cell.first, row + 1)) = cell.second;
}
2014-05-21 22:20:30 +08:00
}
void worksheet::append(const std::unordered_map<int, std::string> &cells)
{
int row = get_highest_row() - 1;
if(d_->cell_map_.size() != 0)
{
row++;
}
for(auto cell : cells)
{
this->get_cell(cell_reference(cell.first, row)) = cell.second;
}
2014-05-21 22:20:30 +08:00
}
xlnt::range worksheet::rows() const
{
return get_range(calculate_dimension());
2014-05-21 22:20:30 +08:00
}
bool worksheet::operator==(const worksheet &other) const
{
return d_ == other.d_;
2014-05-21 22:20:30 +08:00
}
bool worksheet::operator!=(const worksheet &other) const
{
return d_ != other.d_;
2014-05-21 22:20:30 +08:00
}
bool worksheet::operator==(std::nullptr_t) const
{
return d_ == nullptr;
2014-05-21 22:20:30 +08:00
}
bool worksheet::operator!=(std::nullptr_t) const
{
return d_ != nullptr;
2014-05-21 22:20:30 +08:00
}
void worksheet::operator=(const worksheet &other)
{
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);
}
range worksheet::operator[](const std::string &name)
{
if(has_named_range(name))
2014-05-21 22:20:30 +08:00
{
return get_named_range(name);
}
return get_range(range_reference(name));
}
bool worksheet::has_named_range(const std::string &name)
2014-05-21 22:20:30 +08:00
{
return d_->named_ranges_.find(name) != d_->named_ranges_.end();
2014-05-21 22:20:30 +08:00
}
void worksheet::remove_named_range(const std::string &name)
2014-05-21 22:20:30 +08:00
{
if(!has_named_range(name))
{
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)
{
d_->cell_map_.reserve(n);
2014-05-22 05:48:51 +08:00
}
2014-05-21 22:20:30 +08:00
} // namespace xlnt