How do I select a range of cells? #2508
Replies: 15 comments
-
so....I'm guessing this is not a problem for anyone else.... sigh |
Beta Was this translation helpful? Give feedback.
-
I have the same problem...Did you solve it? |
Beta Was this translation helpful? Give feedback.
-
I didn't. I accidentally clicked the close button, but I reopened it again. lol |
Beta Was this translation helpful? Give feedback.
-
@JediYozh @offg777 |
Beta Was this translation helpful? Give feedback.
-
@Siemienik Thanks for the advice but I'm working on another project already so I don't need it anymore... |
Beta Was this translation helpful? Give feedback.
-
Same need here. Iteration may work, but overcomplicates the code. |
Beta Was this translation helpful? Give feedback.
-
I'm fairly surprised that this hasn't been a more commonly requested feature; is it something that we could see support for in the near future? Here's what I've come up with in the mean time, not quite fully error-proof (missing a few checks) but close enough: /**
* Select a range of cells
* @param {string} startCell - Range start cell (top-left)
* @param {string} endCell - Range end cell (bottom-right)
* @return {Object[]} - Selected cells
*/
const selectRange = (sheet, startCell, endCell) => {
const [endCellColumn, endRow] = endCell.split(":", 2);
const [startCellColumn, startRow] = startCell.split(":", 2);
let endColumn = sheet.getColumn(endCellColumn);
let startColumn = sheet.getColumn(startCellColumn);
if (!endColumn) throw new Error("End column not found");
if (!startColumn) throw new Error("Start column not found");
endColumn = endColumn._number;
startColumn = startColumn._number;
const cells = [];
for (let y = startRow; y <= endRow; y++) {
const row = sheet.getRow(y);
for (let x = startColumn; x <= endColumn; x++) {
cells.push(row.getCell(x));
}
}
return cells;
}; Sample Usage const lastRow = worksheet.lastRow._number;
const row = selectRange(worksheet, `startColumnKey:${lastRow}`, `endColumnKey:${lastRow + 4}`);
row.forEach(cell => {
// TODO: Do something with each cell
}); |
Beta Was this translation helpful? Give feedback.
-
@kendallroth is will be really nice to show PR created by You 👍 If only want you to create one, please add me as a pending reviewer |
Beta Was this translation helpful? Give feedback.
-
@kendallroth post work as expected for me, but i have to parse startRow and endRow to integer like so |
Beta Was this translation helpful? Give feedback.
-
@Siemienik I have no idea why I never responded to your comment previously (although I was overseas for most of this year...), my apologies for that! Our use case for this was relatively minor so we never expanded upon this; for example, we didn't run into what @RizkiNfs mentioned above (a good observation). I sadly do not have the necessary context to create a PR at this point (or to determine if the approach taken matches the repo, such as throwing errors...). However, I do hope this example can continue to be useful to others in the future! |
Beta Was this translation helpful? Give feedback.
-
This is the first time I am using excelJs and everything looks good but I am stuck with one problem. I did worksheet protect first that means none of the cells are editable. That’s good. Is there any function like getRange or something ? |
Beta Was this translation helpful? Give feedback.
-
@Bvc0326 Here's example ws.getRows(1, 9999).forEach((row) => {
for(let i = 1; i <= 7; i++) {
row.getCell(i).value = 'hello';
}
}); |
Beta Was this translation helpful? Give feedback.
-
Thank you for the code, we just did some change using param like "A1:C4" instead of working with two params import ExcelJS from "exceljs"
export const selectRange = (sheet: ExcelJS.Worksheet, rangeCell: string) => {
const [startCell, endCell] = rangeCell.split(":")
const [endCellColumn, endRow] = endCell.match(/[a-z]+|[^a-z]+/gi) as string[]
const [startCellColumn, startRow] = startCell.match(
/[a-z]+|[^a-z]+/gi
) as string[]
let endColumn = sheet.getColumn(endCellColumn)
let startColumn = sheet.getColumn(startCellColumn)
if (!endColumn) throw new Error("End column not found")
if (!startColumn) throw new Error("Start column not found")
const endColumnNumber = endColumn.number
const startColumnNumber = startColumn.number
const cells = []
for (let y = parseInt(startRow); y <= parseInt(endRow); y++) {
const row = sheet.getRow(y)
for (let x = startColumnNumber; x <= endColumnNumber; x++) {
cells.push(row.getCell(x))
}
}
return cells
} const lastRow = worksheet.lastRow._number;
const row = selectRange(worksheet, `A${lastRow}:C${lastRow + 4}`);
row.forEach(cell => {
// TODO: Do something with each cell
}); |
Beta Was this translation helpful? Give feedback.
-
Just a small adjustment to brnyza's code in case unexpected cell endpoints are given (like the bottom left and top right of the range to be selected instead of the top left and bottom right). This is a bit easier to use with peace of mind in my opinion. Edit: This only works as long as you're within the columns A through Z, it fails when you try to select something like Z1:AB120 for example because my code here recognizes AB as less than Z alphabetically, and incorrectly recalculates. If someone knows a fix for that I'd appreciate it! If you want something that works for all cells, use brnyza's code but just be sure to only select starting from the top left to the bottom right. /**
*
* @param {Exceljs.Worksheet} sheet
* @param {String} rangeCell
* @returns Cell[] References
*/
const selectRange = (sheet, rangeCell) => {
let [startCell, endCell] = rangeCell.split(':')
// Recalculate in case bottom left and top right are given
if (endCell < startCell) {
let temp = endCell
endCell = startCell
startCell = temp
}
let [endCellColumn, endRow] = endCell.match(/[a-z]+|[^a-z]+/gi)
let [startCellColumn, startRow] = startCell.match(/[a-z]+|[^a-z]+/gi)
// Recalculate in case bottom left and top right are given
if (endCellColumn < startCellColumn) {
let temp = endCellColumn
endCellColumn = startCellColumn
startCellColumn = temp
}
// Recalculate in case bottom left and top right are given
if (endRow < startRow) {
let temp = endRow
endRow = startRow
startRow = temp
}
let endColumn = sheet.getColumn(endCellColumn)
let startColumn = sheet.getColumn(startCellColumn)
if (!endColumn) throw new Error('End column not found')
if (!startColumn) throw new Error('Start column not found')
const endColumnNumber = endColumn.number
const startColumnNumber = startColumn.number
const cells = []
for (let y = parseInt(startRow); y <= parseInt(endRow); y++) {
const row = sheet.getRow(y)
for (let x = startColumnNumber; x <= endColumnNumber; x++) {
cells.push(row.getCell(x))
}
}
return cells
} |
Beta Was this translation helpful? Give feedback.
-
Any update on this? |
Beta Was this translation helpful? Give feedback.
-
Something like this would be nice:
but I don't see anything like it in the readme.
Ultimately, I am trying to add a border around a range like so:
Beta Was this translation helpful? Give feedback.
All reactions