OpenXLSX
OpenXLSX copied to clipboard
[Question] Can I iterate over the entire range by column?
@aral-matrix
Suppose I have a range, Can I iterate over the entire range by column? Thanks!
auto rng_to_write = worksheet.range(start_cell, end_cell);
int rng_rows = rng_to_write.numRows();
std::cout << "rng_rows: " << rng_rows << std::endl;
int rng_cols = rng_to_write.numColumns();
std::cout << "rng_cols: " << rng_cols << std::endl;
for (auto it = rng_to_write.begin(); it != rng_to_write.end(); ++it) {
OpenXLSX::XLCellReference cell_ref(it.address());
int row = cell_ref.row();
int col = cell_ref.column();
}
Hmm - not possible with a range iterator as far as I recall - the main reason is that the library works on the underlying XML and data is not organized by columns, but by rows, and then cells in the row. So iterating over a range by columns first would mean that going to "the next cell in the same column" requires searching a cell for that column in the next row. It would be an order of magnitude slower than using the range iterator that follows the row, and then goes into the next row.
What you can do, is instead of an iterator, using the XLWorksheet::cell methods to access a cell by column and row, and then iterate over the desired columns yourself. The functions are
XLCellAssignable XLWorksheet::cell(const std::string& ref) const;
XLCellAssignable XLWorksheet::cell(const XLCellReference& ref) const;
XLCellAssignable XLWorksheet::cell(uint32_t rowNumber, uint16_t columnNumber) const;
Please note XLCellReference::columnAsNumber and XLCellReference::columnAsString are available to convert column letters into a numeric index.
This approach would still be slower than iterating over rows, but if you have a small workbook, you can do it like this.
I see. Thank you!
The only performant implementation that I could see making sense here, would be to store a "hint" XMLNode for each row of the range (requiring a std::vector of XMLNode pointers for the next cell value that hasn't been iterated over yet. This way, a "vertical first" iterator could always check from the hint node whether the column exists in that row, and if not, insert it before the hint node (and leave the hint node unchanged).
I could see myself implementing something like that, but it's reeeaaaally low on my list of priorities right now, I hope you'll understand :)
Got it. Currently, the XLWorksheet::cell methods meet my needs : )