Skip to content

Commit b338298

Browse files
committed
Add new functions: join_cell_name and split_cell_name
- Update unit tests
1 parent 0bda115 commit b338298

File tree

5 files changed

+118
-1
lines changed

5 files changed

+118
-1
lines changed

excelize.py

Lines changed: 55 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2716,7 +2716,7 @@ def get_active_sheet_index(self) -> int:
27162716
Returns:
27172717
int: The active sheet index
27182718
"""
2719-
lib.GetActiveSheetIndex.restype = c_int
2719+
lib.GetActiveSheetIndex.restype = c_longlong
27202720
res = lib.GetActiveSheetIndex(self.file_index)
27212721
return res
27222722

@@ -6134,6 +6134,27 @@ def coordinates_to_cell_name(col: int, row: int, *is_absolute: bool) -> str:
61346134
raise RuntimeError(err)
61356135

61366136

6137+
def join_cell_name(col: str, row: int) -> str:
6138+
"""
6139+
Joins cell name from column name and row number.
6140+
6141+
Args:
6142+
col (str): The column name
6143+
row (int): The row number
6144+
6145+
Returns:
6146+
str: Return a cell name if no error occurred, otherwise raise a
6147+
RuntimeError with the message.
6148+
"""
6149+
prepare_args([col, row], [argsRule("col", [str]), argsRule("row", [int])])
6150+
lib.JoinCellName.restype = types_go._StringErrorResult
6151+
res = lib.JoinCellName(col.encode(ENCODE), c_longlong(row))
6152+
err = res.err.decode(ENCODE)
6153+
if not err:
6154+
return res.val.decode(ENCODE)
6155+
raise RuntimeError(err)
6156+
6157+
61376158
def new_file() -> File:
61386159
"""
61396160
Create new file by default template.
@@ -6201,3 +6222,36 @@ def open_reader(buffer: bytes, *opts: Options) -> Optional[File]:
62016222
if err == "":
62026223
return File(res.val)
62036224
raise RuntimeError(err)
6225+
6226+
6227+
def split_cell_name(cell: str) -> Tuple[str, int]:
6228+
"""
6229+
Splits cell name to column name and row number.
6230+
6231+
Args:
6232+
cell (str): The cell reference
6233+
6234+
Returns:
6235+
Tuple[str, int]: Return a tuple containing column name and row number if
6236+
no error occurred, otherwise raise a RuntimeError with the message.
6237+
6238+
Example:
6239+
For example:
6240+
6241+
```python
6242+
try:
6243+
col, row = excelize.split_cell_name("AK74") # return "AK", 74
6244+
except (RuntimeError, TypeError) as err:
6245+
print(err)
6246+
```
6247+
"""
6248+
prepare_args([cell], [argsRule("cell", [str])])
6249+
lib.SplitCellName.restype = types_go._StringIntErrorResult
6250+
res = lib.SplitCellName(cell.encode(ENCODE))
6251+
err = res.err.decode(ENCODE)
6252+
if not err:
6253+
return (
6254+
res.strVal.decode(ENCODE),
6255+
res.intVal,
6256+
)
6257+
raise RuntimeError(err)

main.go

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1636,6 +1636,17 @@ func InsertRows(idx int, sheet *C.char, row, n int) *C.char {
16361636
return C.CString(emptyString)
16371637
}
16381638

1639+
// JoinCellName joins cell name from column name and row number.
1640+
//
1641+
//export JoinCellName
1642+
func JoinCellName(col *C.char, row int) C.struct_StringErrorResult {
1643+
result, err := excelize.JoinCellName(C.GoString(col), row)
1644+
if err != nil {
1645+
return C.struct_StringErrorResult{err: C.CString(err.Error())}
1646+
}
1647+
return C.struct_StringErrorResult{val: C.CString(result), err: C.CString(emptyString)}
1648+
}
1649+
16391650
// MergeCell provides a function to merge cells by given range reference and
16401651
// sheet name. Merging cells only keeps the upper-left cell value, and
16411652
// discards the other values.
@@ -2918,6 +2929,17 @@ func SetWorkbookProps(idx int, opts *C.struct_WorkbookPropsOptions) *C.char {
29182929
return C.CString(emptyString)
29192930
}
29202931

2932+
// SplitCellName splits cell name to column name and row number.
2933+
//
2934+
//export SplitCellName
2935+
func SplitCellName(cell *C.char, row int) C.struct_StringIntErrorResult {
2936+
col, row, err := excelize.SplitCellName(C.GoString(cell))
2937+
if err != nil {
2938+
return C.struct_StringIntErrorResult{err: C.CString(err.Error())}
2939+
}
2940+
return C.struct_StringIntErrorResult{intVal: C.int(row), strVal: C.CString(col), err: C.CString(emptyString)}
2941+
}
2942+
29212943
// UngroupSheets provides a function to ungroup worksheets.
29222944
//
29232945
//export UngroupSheets

test_excelize.py

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2227,6 +2227,18 @@ def test_doc_props(self):
22272227
self.assertIsNone(f.save_as(os.path.join("test", "TestDocProps.xlsx")))
22282228
self.assertIsNone(f.close())
22292229

2230+
def test_join_cell_name(self):
2231+
self.assertEqual(excelize.join_cell_name("A", 1), "A1")
2232+
with self.assertRaises(RuntimeError) as context:
2233+
excelize.join_cell_name("", 0)
2234+
self.assertEqual(str(context.exception), 'invalid column name ""')
2235+
with self.assertRaises(TypeError) as context:
2236+
excelize.join_cell_name(1, 1)
2237+
self.assertEqual(
2238+
str(context.exception),
2239+
"expected type str for argument 'col', but got int",
2240+
)
2241+
22302242
def test_merge_cell(self):
22312243
f = excelize.new_file()
22322244
self.assertIsNone(f.set_sheet_row("Sheet1", "A1", ["A1", "B1"]))
@@ -2393,6 +2405,20 @@ def test_sheet_visible(self):
23932405
self.assertIsNone(f.save_as(os.path.join("test", "TestSheetVisible.xlsx")))
23942406
self.assertIsNone(f.close())
23952407

2408+
def test_split_cell_name(self):
2409+
col, row = excelize.split_cell_name("AK74")
2410+
self.assertEqual(col, "AK")
2411+
self.assertEqual(row, 74)
2412+
with self.assertRaises(RuntimeError) as context:
2413+
excelize.split_cell_name("")
2414+
self.assertEqual(str(context.exception), 'invalid cell name ""')
2415+
with self.assertRaises(TypeError) as context:
2416+
excelize.split_cell_name(1)
2417+
self.assertEqual(
2418+
str(context.exception),
2419+
"expected type str for argument 'cell', but got int",
2420+
)
2421+
23962422
def test_workbook_props(self):
23972423
f = excelize.new_file()
23982424
expected = excelize.WorkbookPropsOptions(

types_c.h

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -748,6 +748,13 @@ struct StringErrorResult
748748
char *err;
749749
};
750750

751+
struct StringIntErrorResult
752+
{
753+
char *strVal;
754+
int intVal;
755+
char *err;
756+
};
757+
751758
struct IntErrorResult
752759
{
753760
int val;

types_go.py

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -719,6 +719,14 @@ class _StringErrorResult(Structure):
719719
]
720720

721721

722+
class _StringIntErrorResult(Structure):
723+
_fields_ = [
724+
("strVal", c_char_p),
725+
("intVal", c_int),
726+
("err", c_char_p),
727+
]
728+
729+
722730
class _IntErrorResult(Structure):
723731
_fields_ = [
724732
("val", c_int),

0 commit comments

Comments
 (0)