From 3d48021c4d57c40986d7ea050fa4d483dab86c22 Mon Sep 17 00:00:00 2001 From: LZCZ <3291119024@qq.com> Date: Sat, 19 Apr 2025 15:00:32 +0100 Subject: [PATCH 1/4] Add GetSheetList and GetSheetMap --- excelize.py | 38 ++++++++++++++++++++++++++++++++++++ main.go | 50 ++++++++++++++++++++++++++++++++++++++++++++++++ test_excelize.py | 2 ++ types_c.h | 11 +++++++++++ types_go.py | 13 +++++++++++++ types_py.py | 10 ++++++++++ 6 files changed, 124 insertions(+) diff --git a/excelize.py b/excelize.py index 382369a..eb51bdf 100644 --- a/excelize.py +++ b/excelize.py @@ -1826,6 +1826,44 @@ def get_sheet_index(self, sheet: str) -> int: if not err: return res.val raise RuntimeError(err) + + def get_sheet_list(self) -> List[str]: + """ + GetSheetList provides a function to get worksheets, chart sheets, and + dialog sheets name list of the workbook. + + Returns: + List[str]: Return the sheet name list if no error occurred, + otherwise return an empty list. + """ + + lib.GetSheetList.restype = types_go._StringArrayErrorResult + res = lib.GetSheetList( + self.file_index + ) + arr = c_value_to_py(res, StringArrayErrorResult()).arr + return arr if arr else [] + + def get_sheet_map(self) -> dict[int, str]: + """ + GetSheetMap provides a function to get worksheets, chart sheets, + dialog sheets ID, and name maps of the workbook. + + Returns: + dict[int, str]: Return the sheet ID and name map if no error occurred, + otherwise return an empty dictionary. + """ + lib.GetSheetMap.restype = types_go._GetSheetMapResult + sheet_map = dict() + res = lib.GetSheetMap(self.file_index) + err = res.Err.decode(ENCODE) + result = c_value_to_py(res, GetSheetMapResult()).arr + if result: + print(result) + for item in result: + sheet_map[item.k] = item.v + return sheet_map + def get_sheet_name(self, sheet: int) -> str: """ diff --git a/main.go b/main.go index 7c81e9e..3ecdd96 100644 --- a/main.go +++ b/main.go @@ -1302,6 +1302,56 @@ func GetSheetIndex(idx int, sheet *C.char) C.struct_IntErrorResult { return C.struct_IntErrorResult{val: C.int(idx), err: C.CString(emptyString)} } +// GetSheetList provides a function to get worksheets, chart sheets, and +// dialog sheets name list of the workbook. +// +//export GetSheetList +func GetSheetList(idx int) C.struct_StringArrayErrorResult { + f, ok := files.Load(idx) + if !ok { + return C.struct_StringArrayErrorResult{Err: C.CString(errFilePtr)} + } + result := f.(*excelize.File).GetSheetList() + cArray := C.malloc(C.size_t(len(result)) * C.size_t(unsafe.Sizeof(uintptr(0)))) + for i, v := range result { + *(*unsafe.Pointer)(unsafe.Pointer(uintptr(unsafe.Pointer(cArray)) + uintptr(i)*unsafe.Sizeof(uintptr(0)))) = unsafe.Pointer(C.CString(v)) + } + return C.struct_StringArrayErrorResult{ArrLen: C.int(len(result)), Arr: (**C.char)(cArray), Err: C.CString(emptyString)} +} + +// GetSheetMap provides a function to get worksheets, chart sheets, +// dialog sheets ID, and name maps of the workbook. +// +//export GetSheetMap +func GetSheetMap(idx int) C.struct_GetSheetMapResult { + type IntStringResult struct { + K int + V string + } + type GetSheetMapResult struct { + Arr []IntStringResult + Err string + } + var result GetSheetMapResult + f, ok := files.Load(idx) + if !ok { + return C.struct_GetSheetMapResult{ + Err: C.CString(errFilePtr), + } + } + for k, v := range f.(*excelize.File).GetSheetMap() { + result.Arr = append(result.Arr, IntStringResult{K: k, V: v}) + } + + cVal, err := goValueToC(reflect.ValueOf(result), reflect.ValueOf(&C.struct_GetSheetMapResult{})) + if err != nil { + return C.struct_GetSheetMapResult{Err: C.CString(err.Error())} + } + ret := cVal.Elem().Interface().(C.struct_GetSheetMapResult) + ret.Err = C.CString(emptyString) + return ret +} + // GetSheetName provides a function to get the sheet name by the given worksheet index. // If the given worksheet index is invalid, it will return an error. // diff --git a/test_excelize.py b/test_excelize.py index 1fc46b0..bba16b9 100644 --- a/test_excelize.py +++ b/test_excelize.py @@ -337,6 +337,8 @@ def test_style(self): with self.assertRaises(RuntimeError) as context: _ = f.get_sheet_index("") self.assertEqual(str(context.exception), "the sheet name can not be blank") + self.assertEqual(f.get_sheet_list(), ["Sheet1", "Sheet2"]) + self.assertEqual(len(f.get_sheet_map()), 2) self.assertEqual(f.get_sheet_name(index), "Sheet2") self.assertIsNone(f.set_col_outline_level("Sheet1", "D", 2)) diff --git a/types_c.h b/types_c.h index 463ac9c..5445fab 100644 --- a/types_c.h +++ b/types_c.h @@ -799,3 +799,14 @@ struct GetWorkbookPropsResult struct WorkbookPropsOptions opts; char *err; }; + +struct IntStringResult { + int K; + char* V; +}; + +struct GetSheetMapResult { + int ArrLen; + struct IntStringResult* Arr; + char* Err; +}; \ No newline at end of file diff --git a/types_go.py b/types_go.py index 7ece669..6b5cf4e 100644 --- a/types_go.py +++ b/types_go.py @@ -784,3 +784,16 @@ class _GetWorkbookPropsResult(Structure): ("opts", _WorkbookPropsOptions), ("err", c_char_p), ] + +class _IntStringResult(Structure): + _fields_ = [ + ("K", c_int), + ("V", c_char_p), + ] + +class _GetSheetMapResult(Structure): + _fields_ = [ + ("ArrLen", c_int), + ("Arr", POINTER(_IntStringResult)), + ("Err", c_char_p), + ] \ No newline at end of file diff --git a/types_py.py b/types_py.py index 5997326..f19c4af 100644 --- a/types_py.py +++ b/types_py.py @@ -796,3 +796,13 @@ class WorkbookProtectionOptions: class StringArrayErrorResult: arr: Optional[List[str]] = None err: str = "" + +@dataclass +class IntStringResult: + k: int = 0 + v: str = "" + +@dataclass +class GetSheetMapResult: + arr: Optional[List[IntStringResult]] = None + err: str = "" \ No newline at end of file From 8da08d5d198b1d792314e8097fdb9e8d145dcebd Mon Sep 17 00:00:00 2001 From: LZCZ <3291119024@qq.com> Date: Sat, 19 Apr 2025 18:11:15 +0100 Subject: [PATCH 2/4] Add GetComments --- excelize.py | 20 +++++++++++++++++++- main.go | 44 +++++++++++++++++++++++++++++++++++++++++++- test_excelize.py | 4 ++++ types_c.h | 6 ++++++ types_go.py | 7 +++++++ types_py.py | 5 +++++ 6 files changed, 84 insertions(+), 2 deletions(-) diff --git a/excelize.py b/excelize.py index eb51bdf..90c2bc8 100644 --- a/excelize.py +++ b/excelize.py @@ -1859,10 +1859,28 @@ def get_sheet_map(self) -> dict[int, str]: err = res.Err.decode(ENCODE) result = c_value_to_py(res, GetSheetMapResult()).arr if result: - print(result) for item in result: sheet_map[item.k] = item.v return sheet_map + + def get_comments(self, sheet: str) -> List[Comment]: + + """ + GetComments retrieves all comments in a worksheet by given worksheet name. + + Returns: + List[Comment]: Return the comment list if no error occurred, + otherwise raise a RuntimeError with the message. + """ + lib.GetComments.restype = types_go._GetCommentsResult + res = lib.GetComments(self.file_index, sheet.encode(ENCODE)) + if res.Err: + err = res.Err.decode(ENCODE) + if err: + raise RuntimeError(err) + result = c_value_to_py(res, GetCommentsResult()) + return result.comments if result and result.comments else [] + def get_sheet_name(self, sheet: int) -> str: diff --git a/main.go b/main.go index 3ecdd96..9cf1363 100644 --- a/main.go +++ b/main.go @@ -13,7 +13,7 @@ package main /* -#include "types_c.h" + #include "types_c.h" */ import "C" @@ -1352,6 +1352,48 @@ func GetSheetMap(idx int) C.struct_GetSheetMapResult { return ret } +// GetComments retrieves all comments in a worksheet by given worksheet name. +// +//export GetComments +func GetComments(idx int, sheet *C.char) C.struct_GetCommentsResult { + type Comment struct { + Author string + AuthorID int + Cell string + Text string + Width uint + Height uint + ParagraphLen int + Paragraph []excelize.RichTextRun + } + type GetCommentsResult struct { + CommentsLen int + Comments []Comment + Err string + } + var result GetCommentsResult + f, ok := files.Load(idx) + if !ok { + return C.struct_GetCommentsResult{Err: C.CString(errFilePtr)} + } + comments, err := f.(*excelize.File).GetComments(C.GoString(sheet)) + if err != nil { + return C.struct_GetCommentsResult{Err: C.CString(err.Error())} + } + result.CommentsLen = len(comments) + for _, c := range comments { + result.Comments = append(result.Comments, Comment{Author: c.Author, AuthorID: c.AuthorID, Cell: c.Cell, Text: c.Text, Width: c.Width, Height: c.Height, ParagraphLen: len(c.Paragraph), Paragraph: c.Paragraph}) + } + cVal, err := goValueToC(reflect.ValueOf(result), reflect.ValueOf(&C.struct_GetCommentsResult{})) + if err != nil { + return C.struct_GetCommentsResult{Err: C.CString(err.Error())} + } + ret := cVal.Elem().Interface().(C.struct_GetCommentsResult) + ret.Err = C.CString(emptyString) + return ret + +} + // GetSheetName provides a function to get the sheet name by the given worksheet index. // If the given worksheet index is invalid, it will return an error. // diff --git a/test_excelize.py b/test_excelize.py index bba16b9..0cf8df1 100644 --- a/test_excelize.py +++ b/test_excelize.py @@ -737,6 +737,10 @@ def test_comment(self): comment, ) ) + self.assertEqual(str(f.get_comments("Sheet1")), "[Comment(author='Excelize', author_id=0, cell='A5', text='', width=0, height=0, paragraph=[RichTextRun(font=Font(bold=True, italic=False, underline='', family='', size=0, strike=False, color='', color_indexed=0, color_theme=None, color_tint=0, vert_align=''), text='Excelize: '), RichTextRun(font=Font(bold=False, italic=False, underline='', family='Calibri', size=9.0, strike=False, color='', color_indexed=81, color_theme=None, color_tint=0, vert_align=''), text='This is a comment.')])]") + with self.assertRaises(RuntimeError) as context: + f.get_comments("SheetN") + self.assertEqual(str(context.exception), "sheet SheetN does not exist") with self.assertRaises(RuntimeError) as context: f.add_comment("SheetN", comment) self.assertEqual(str(context.exception), "sheet SheetN does not exist") diff --git a/types_c.h b/types_c.h index 5445fab..69a81d3 100644 --- a/types_c.h +++ b/types_c.h @@ -809,4 +809,10 @@ struct GetSheetMapResult { int ArrLen; struct IntStringResult* Arr; char* Err; +}; + +struct GetCommentsResult { + int CommentsLen; + struct Comment* Comments; + char* Err; }; \ No newline at end of file diff --git a/types_go.py b/types_go.py index 6b5cf4e..4db0d8a 100644 --- a/types_go.py +++ b/types_go.py @@ -796,4 +796,11 @@ class _GetSheetMapResult(Structure): ("ArrLen", c_int), ("Arr", POINTER(_IntStringResult)), ("Err", c_char_p), + ] + +class _GetCommentsResult(Structure): + _fields_ = [ + ("CommentsLen", c_int), + ("Comments", POINTER(_Comment)), + ("Err", c_char_p), ] \ No newline at end of file diff --git a/types_py.py b/types_py.py index f19c4af..2cd0450 100644 --- a/types_py.py +++ b/types_py.py @@ -805,4 +805,9 @@ class IntStringResult: @dataclass class GetSheetMapResult: arr: Optional[List[IntStringResult]] = None + err: str = "" + +@dataclass +class GetCommentsResult: + comments: Optional[List[Comment]] = None err: str = "" \ No newline at end of file From c6effe3263ba3922983691543817fbed2fa782a5 Mon Sep 17 00:00:00 2001 From: LZCZ <3291119024@qq.com> Date: Sun, 27 Apr 2025 13:52:27 +0100 Subject: [PATCH 3/4] fix Getcomments --- excelize.py | 36 ++++++++++++++---------------------- main.go | 23 ++++++++++++++++++++++- test_excelize.py | 7 ++++++- types_c.h | 10 +++++----- 4 files changed, 47 insertions(+), 29 deletions(-) diff --git a/excelize.py b/excelize.py index 90c2bc8..f0f45f3 100644 --- a/excelize.py +++ b/excelize.py @@ -1692,9 +1692,7 @@ def get_col_width(self, sheet: str, col: str) -> float: ``` """ lib.GetColWidth.restype = types_go._Float64ErrorResult - res = lib.GetColWidth( - self.file_index, sheet.encode(ENCODE), col.encode(ENCODE) - ) + res = lib.GetColWidth(self.file_index, sheet.encode(ENCODE), col.encode(ENCODE)) err = res.err.decode(ENCODE) if not err: return res.val @@ -1826,10 +1824,10 @@ def get_sheet_index(self, sheet: str) -> int: if not err: return res.val raise RuntimeError(err) - + def get_sheet_list(self) -> List[str]: """ - GetSheetList provides a function to get worksheets, chart sheets, and + GetSheetList provides a function to get worksheets, chart sheets, and dialog sheets name list of the workbook. Returns: @@ -1838,20 +1836,18 @@ def get_sheet_list(self) -> List[str]: """ lib.GetSheetList.restype = types_go._StringArrayErrorResult - res = lib.GetSheetList( - self.file_index - ) + res = lib.GetSheetList(self.file_index) arr = c_value_to_py(res, StringArrayErrorResult()).arr return arr if arr else [] - + def get_sheet_map(self) -> dict[int, str]: """ - GetSheetMap provides a function to get worksheets, chart sheets, + GetSheetMap provides a function to get worksheets, chart sheets, dialog sheets ID, and name maps of the workbook. Returns: - dict[int, str]: Return the sheet ID and name map if no error occurred, - otherwise return an empty dictionary. + Dict[int, str]: Return the sheet ID and name map if no error + occurred, otherwise return an empty dictionary. """ lib.GetSheetMap.restype = types_go._GetSheetMapResult sheet_map = dict() @@ -1862,11 +1858,11 @@ def get_sheet_map(self) -> dict[int, str]: for item in result: sheet_map[item.k] = item.v return sheet_map - - def get_comments(self, sheet: str) -> List[Comment]: + def get_comments(self, sheet: str) -> List[Comment]: """ - GetComments retrieves all comments in a worksheet by given worksheet name. + GetComments retrieves all comments in a worksheet by given worksheet + name. Returns: List[Comment]: Return the comment list if no error occurred, @@ -1874,15 +1870,13 @@ def get_comments(self, sheet: str) -> List[Comment]: """ lib.GetComments.restype = types_go._GetCommentsResult res = lib.GetComments(self.file_index, sheet.encode(ENCODE)) + result = c_value_to_py(res, GetCommentsResult()) if res.Err: err = res.Err.decode(ENCODE) if err: - raise RuntimeError(err) - result = c_value_to_py(res, GetCommentsResult()) + raise RuntimeError(err) return result.comments if result and result.comments else [] - - def get_sheet_name(self, sheet: int) -> str: """ Get the sheet name of the workbook by the given sheet index. @@ -3800,9 +3794,7 @@ def open_file(filename: str, *opts: Options) -> File: raise RuntimeError(err) -def open_reader( - buffer: bytes, *opts: Options -) -> Optional[File]: +def open_reader(buffer: bytes, *opts: Options) -> Optional[File]: """ Read data stream from bytes and return a populated spreadsheet file. diff --git a/main.go b/main.go index 9cf1363..bc387c5 100644 --- a/main.go +++ b/main.go @@ -1355,7 +1355,7 @@ func GetSheetMap(idx int) C.struct_GetSheetMapResult { // GetComments retrieves all comments in a worksheet by given worksheet name. // //export GetComments -func GetComments(idx int, sheet *C.char) C.struct_GetCommentsResult { +/*func GetComments(idx int, sheet *C.char) C.struct_GetCommentsResult { type Comment struct { Author string AuthorID int @@ -1392,6 +1392,27 @@ func GetComments(idx int, sheet *C.char) C.struct_GetCommentsResult { ret.Err = C.CString(emptyString) return ret +}*/ + +//export GetComments +func GetComments(idx int, sheet *C.char) C.struct_GetCommentsResult { + f, ok := files.Load(idx) + if !ok { + return C.struct_GetCommentsResult{Err: C.CString(errFilePtr)} + } + comments, err := f.(*excelize.File).GetComments(C.GoString(sheet)) + if err != nil { + return C.struct_GetCommentsResult{Err: C.CString(err.Error())} + } + cArray := C.malloc(C.size_t(len(comments)) * C.size_t(unsafe.Sizeof(C.struct_Comment{}))) + for i, r := range comments { + cVal, err := goValueToC(reflect.ValueOf(r), reflect.ValueOf(&C.struct_Comment{})) + if err != nil { + return C.struct_GetCommentsResult{Err: C.CString(err.Error())} + } + *(*C.struct_Comment)(unsafe.Pointer(uintptr(unsafe.Pointer(cArray)) + uintptr(i)*unsafe.Sizeof(C.struct_Comment{}))) = cVal.Elem().Interface().(C.struct_Comment) + } + return C.struct_GetCommentsResult{CommentsLen: C.int(len(comments)), Comments: (*C.struct_Comment)(cArray), Err: C.CString(emptyString)} } // GetSheetName provides a function to get the sheet name by the given worksheet index. diff --git a/test_excelize.py b/test_excelize.py index 0cf8df1..46fbd24 100644 --- a/test_excelize.py +++ b/test_excelize.py @@ -737,7 +737,12 @@ def test_comment(self): comment, ) ) - self.assertEqual(str(f.get_comments("Sheet1")), "[Comment(author='Excelize', author_id=0, cell='A5', text='', width=0, height=0, paragraph=[RichTextRun(font=Font(bold=True, italic=False, underline='', family='', size=0, strike=False, color='', color_indexed=0, color_theme=None, color_tint=0, vert_align=''), text='Excelize: '), RichTextRun(font=Font(bold=False, italic=False, underline='', family='Calibri', size=9.0, strike=False, color='', color_indexed=81, color_theme=None, color_tint=0, vert_align=''), text='This is a comment.')])]") + comments = f.get_comments("Sheet1") + self.assertEqual(len(comments), 1) + self.assertEqual(comments[0].cell, "A5") + self.assertEqual(comments[0].author, "Excelize") + self.assertEqual(comments[0].paragraph[0].text, comment.paragraph[0].text) + self.assertEqual(comments[0].paragraph[1].text, comment.paragraph[1].text) with self.assertRaises(RuntimeError) as context: f.get_comments("SheetN") self.assertEqual(str(context.exception), "sheet SheetN does not exist") diff --git a/types_c.h b/types_c.h index 69a81d3..e7a2f11 100644 --- a/types_c.h +++ b/types_c.h @@ -802,17 +802,17 @@ struct GetWorkbookPropsResult struct IntStringResult { int K; - char* V; + char *V; }; struct GetSheetMapResult { int ArrLen; - struct IntStringResult* Arr; - char* Err; + struct IntStringResult *Arr; + char *Err; }; struct GetCommentsResult { int CommentsLen; - struct Comment* Comments; - char* Err; + struct Comment *Comments; + char *Err; }; \ No newline at end of file From acb00b8e09a730847559582d53941bfca393dd45 Mon Sep 17 00:00:00 2001 From: xuri Date: Sun, 27 Apr 2025 21:30:53 +0800 Subject: [PATCH 4/4] Fix code review issues --- README.md | 2 +- README_zh.md | 2 +- excelize.py | 48 +++++++++++------------ main.go | 99 +++++++++++++++--------------------------------- test_excelize.py | 2 +- types_c.h | 12 +++--- types_go.py | 17 ++++++--- types_py.py | 13 ++++--- 8 files changed, 81 insertions(+), 114 deletions(-) diff --git a/README.md b/README.md index 75afb90..ebb4033 100644 --- a/README.md +++ b/README.md @@ -89,7 +89,7 @@ finally: With Excelize chart generation and management is as easy as a few lines of code. You can build charts based on data in your worksheet or generate charts without any data in your worksheet at all. -

Excelize

+

Excelize

```python import excelize diff --git a/README_zh.md b/README_zh.md index 9c985e0..1edea1a 100644 --- a/README_zh.md +++ b/README_zh.md @@ -89,7 +89,7 @@ finally: 使用 Excelize 生成图表十分简单,仅需几行代码。您可以根据工作表中的已有数据构建图表,或向工作表中添加数据并创建图表。 -

使用 Excelize 在 Excel 电子表格文档中创建图表

+

使用 Excelize 在 Excel 电子表格文档中创建图表

```python import excelize diff --git a/excelize.py b/excelize.py index f0f45f3..a14a949 100644 --- a/excelize.py +++ b/excelize.py @@ -13,7 +13,7 @@ from dataclasses import fields from datetime import datetime, date, time from enum import Enum -from typing import Tuple, get_args, get_origin, List, Optional, Union +from typing import Tuple, get_args, get_origin, Dict, List, Optional, Union from ctypes import ( byref, c_bool, @@ -1698,6 +1698,24 @@ def get_col_width(self, sheet: str, col: str) -> float: return res.val raise RuntimeError(err) + def get_comments(self, sheet: str) -> List[Comment]: + """ + GetComments retrieves all comments in a worksheet by given worksheet + name. + + Returns: + List[Comment]: Return the comment list if no error occurred, + otherwise raise a RuntimeError with the message. + """ + lib.GetComments.restype = types_go._GetCommentsResult + res = lib.GetComments(self.file_index, sheet.encode(ENCODE)) + result = c_value_to_py(res, GetCommentsResult()) + if res.Err: + err = res.Err.decode(ENCODE) + if err: + raise RuntimeError(err) + return result.comments if result and result.comments else [] + def get_default_font(self) -> str: """ Get the default font name currently set in the workbook. The spreadsheet @@ -1834,49 +1852,29 @@ def get_sheet_list(self) -> List[str]: List[str]: Return the sheet name list if no error occurred, otherwise return an empty list. """ - lib.GetSheetList.restype = types_go._StringArrayErrorResult res = lib.GetSheetList(self.file_index) arr = c_value_to_py(res, StringArrayErrorResult()).arr return arr if arr else [] - def get_sheet_map(self) -> dict[int, str]: + def get_sheet_map(self) -> Dict[int, str]: """ - GetSheetMap provides a function to get worksheets, chart sheets, - dialog sheets ID, and name maps of the workbook. + GetSheetMap provides a function to get worksheets, chart sheets, dialog + sheets ID, and name maps of the workbook. Returns: - Dict[int, str]: Return the sheet ID and name map if no error + dict[int, str]: Return the sheet ID and name map if no error occurred, otherwise return an empty dictionary. """ lib.GetSheetMap.restype = types_go._GetSheetMapResult sheet_map = dict() res = lib.GetSheetMap(self.file_index) - err = res.Err.decode(ENCODE) result = c_value_to_py(res, GetSheetMapResult()).arr if result: for item in result: sheet_map[item.k] = item.v return sheet_map - def get_comments(self, sheet: str) -> List[Comment]: - """ - GetComments retrieves all comments in a worksheet by given worksheet - name. - - Returns: - List[Comment]: Return the comment list if no error occurred, - otherwise raise a RuntimeError with the message. - """ - lib.GetComments.restype = types_go._GetCommentsResult - res = lib.GetComments(self.file_index, sheet.encode(ENCODE)) - result = c_value_to_py(res, GetCommentsResult()) - if res.Err: - err = res.Err.decode(ENCODE) - if err: - raise RuntimeError(err) - return result.comments if result and result.comments else [] - def get_sheet_name(self, sheet: int) -> str: """ Get the sheet name of the workbook by the given sheet index. diff --git a/main.go b/main.go index bc387c5..55781a0 100644 --- a/main.go +++ b/main.go @@ -13,7 +13,7 @@ package main /* - #include "types_c.h" +#include "types_c.h" */ import "C" @@ -548,9 +548,10 @@ func AddFormControl(idx int, sheet *C.char, opts *C.struct_FormControl) *C.char return C.CString(emptyString) } -// Add picture in a sheet by given picture format set (such as offset, scale, -// aspect ratio setting and print settings) and file path, supported image -// types: BMP, EMF, EMZ, GIF, JPEG, JPG, PNG, SVG, TIF, TIFF, WMF, and WMZ. +// AddPicture add picture in a sheet by given picture format set (such as +// offset, scale, aspect ratio setting and print settings) and file path, +// supported image types: BMP, EMF, EMZ, GIF, JPEG, JPG, PNG, SVG, TIF, TIFF, +// WMF, and WMZ. // //export AddPicture func AddPicture(idx int, sheet, cell, name *C.char, opts *C.struct_GraphicOptions) *C.char { @@ -1189,6 +1190,29 @@ func GetColWidth(idx int, sheet, col *C.char) C.struct_Float64ErrorResult { return C.struct_Float64ErrorResult{val: C.double(val), err: C.CString(emptyString)} } +// GetComments retrieves all comments in a worksheet by given worksheet name. +// +//export GetComments +func GetComments(idx int, sheet *C.char) C.struct_GetCommentsResult { + f, ok := files.Load(idx) + if !ok { + return C.struct_GetCommentsResult{Err: C.CString(errFilePtr)} + } + comments, err := f.(*excelize.File).GetComments(C.GoString(sheet)) + if err != nil { + return C.struct_GetCommentsResult{Err: C.CString(err.Error())} + } + cArray := C.malloc(C.size_t(len(comments)) * C.size_t(unsafe.Sizeof(C.struct_Comment{}))) + for i, r := range comments { + cVal, err := goValueToC(reflect.ValueOf(r), reflect.ValueOf(&C.struct_Comment{})) + if err != nil { + return C.struct_GetCommentsResult{Err: C.CString(err.Error())} + } + *(*C.struct_Comment)(unsafe.Pointer(uintptr(unsafe.Pointer(cArray)) + uintptr(i)*unsafe.Sizeof(C.struct_Comment{}))) = cVal.Elem().Interface().(C.struct_Comment) + } + return C.struct_GetCommentsResult{CommentsLen: C.int(len(comments)), Comments: (*C.struct_Comment)(cArray), Err: C.CString(emptyString)} +} + // GetDefaultFont provides the default font name currently set in the // workbook. The spreadsheet generated by excelize default font is Calibri. // @@ -1319,8 +1343,8 @@ func GetSheetList(idx int) C.struct_StringArrayErrorResult { return C.struct_StringArrayErrorResult{ArrLen: C.int(len(result)), Arr: (**C.char)(cArray), Err: C.CString(emptyString)} } -// GetSheetMap provides a function to get worksheets, chart sheets, -// dialog sheets ID, and name maps of the workbook. +// GetSheetMap provides a function to get worksheets, chart sheets, dialog +// sheets ID and name map of the workbook. // //export GetSheetMap func GetSheetMap(idx int) C.struct_GetSheetMapResult { @@ -1352,69 +1376,6 @@ func GetSheetMap(idx int) C.struct_GetSheetMapResult { return ret } -// GetComments retrieves all comments in a worksheet by given worksheet name. -// -//export GetComments -/*func GetComments(idx int, sheet *C.char) C.struct_GetCommentsResult { - type Comment struct { - Author string - AuthorID int - Cell string - Text string - Width uint - Height uint - ParagraphLen int - Paragraph []excelize.RichTextRun - } - type GetCommentsResult struct { - CommentsLen int - Comments []Comment - Err string - } - var result GetCommentsResult - f, ok := files.Load(idx) - if !ok { - return C.struct_GetCommentsResult{Err: C.CString(errFilePtr)} - } - comments, err := f.(*excelize.File).GetComments(C.GoString(sheet)) - if err != nil { - return C.struct_GetCommentsResult{Err: C.CString(err.Error())} - } - result.CommentsLen = len(comments) - for _, c := range comments { - result.Comments = append(result.Comments, Comment{Author: c.Author, AuthorID: c.AuthorID, Cell: c.Cell, Text: c.Text, Width: c.Width, Height: c.Height, ParagraphLen: len(c.Paragraph), Paragraph: c.Paragraph}) - } - cVal, err := goValueToC(reflect.ValueOf(result), reflect.ValueOf(&C.struct_GetCommentsResult{})) - if err != nil { - return C.struct_GetCommentsResult{Err: C.CString(err.Error())} - } - ret := cVal.Elem().Interface().(C.struct_GetCommentsResult) - ret.Err = C.CString(emptyString) - return ret - -}*/ - -//export GetComments -func GetComments(idx int, sheet *C.char) C.struct_GetCommentsResult { - f, ok := files.Load(idx) - if !ok { - return C.struct_GetCommentsResult{Err: C.CString(errFilePtr)} - } - comments, err := f.(*excelize.File).GetComments(C.GoString(sheet)) - if err != nil { - return C.struct_GetCommentsResult{Err: C.CString(err.Error())} - } - cArray := C.malloc(C.size_t(len(comments)) * C.size_t(unsafe.Sizeof(C.struct_Comment{}))) - for i, r := range comments { - cVal, err := goValueToC(reflect.ValueOf(r), reflect.ValueOf(&C.struct_Comment{})) - if err != nil { - return C.struct_GetCommentsResult{Err: C.CString(err.Error())} - } - *(*C.struct_Comment)(unsafe.Pointer(uintptr(unsafe.Pointer(cArray)) + uintptr(i)*unsafe.Sizeof(C.struct_Comment{}))) = cVal.Elem().Interface().(C.struct_Comment) - } - return C.struct_GetCommentsResult{CommentsLen: C.int(len(comments)), Comments: (*C.struct_Comment)(cArray), Err: C.CString(emptyString)} -} - // GetSheetName provides a function to get the sheet name by the given worksheet index. // If the given worksheet index is invalid, it will return an error. // diff --git a/test_excelize.py b/test_excelize.py index 46fbd24..38b3b95 100644 --- a/test_excelize.py +++ b/test_excelize.py @@ -744,7 +744,7 @@ def test_comment(self): self.assertEqual(comments[0].paragraph[0].text, comment.paragraph[0].text) self.assertEqual(comments[0].paragraph[1].text, comment.paragraph[1].text) with self.assertRaises(RuntimeError) as context: - f.get_comments("SheetN") + f.get_comments("SheetN") self.assertEqual(str(context.exception), "sheet SheetN does not exist") with self.assertRaises(RuntimeError) as context: f.add_comment("SheetN", comment) diff --git a/types_c.h b/types_c.h index e7a2f11..9962303 100644 --- a/types_c.h +++ b/types_c.h @@ -741,6 +741,11 @@ struct StringArrayErrorResult char *Err; }; +struct IntStringResult { + int K; + char *V; +}; + struct GetCellHyperLinkResult { bool link; @@ -800,11 +805,6 @@ struct GetWorkbookPropsResult char *err; }; -struct IntStringResult { - int K; - char *V; -}; - struct GetSheetMapResult { int ArrLen; struct IntStringResult *Arr; @@ -815,4 +815,4 @@ struct GetCommentsResult { int CommentsLen; struct Comment *Comments; char *Err; -}; \ No newline at end of file +}; diff --git a/types_go.py b/types_go.py index 4db0d8a..ab079ab 100644 --- a/types_go.py +++ b/types_go.py @@ -704,12 +704,21 @@ class _BoolErrorResult(Structure): ("err", c_char_p), ] + class _Float64ErrorResult(Structure): _fields_ = [ ("val", c_double), ("err", c_char_p), ] + +class _IntStringResult(Structure): + _fields_ = [ + ("K", c_int), + ("V", c_char_p), + ] + + class _StringArrayErrorResult(Structure): _fields_ = [ ("ArrLen", c_int), @@ -785,11 +794,6 @@ class _GetWorkbookPropsResult(Structure): ("err", c_char_p), ] -class _IntStringResult(Structure): - _fields_ = [ - ("K", c_int), - ("V", c_char_p), - ] class _GetSheetMapResult(Structure): _fields_ = [ @@ -798,9 +802,10 @@ class _GetSheetMapResult(Structure): ("Err", c_char_p), ] + class _GetCommentsResult(Structure): _fields_ = [ ("CommentsLen", c_int), ("Comments", POINTER(_Comment)), ("Err", c_char_p), - ] \ No newline at end of file + ] diff --git a/types_py.py b/types_py.py index 2cd0450..5a05612 100644 --- a/types_py.py +++ b/types_py.py @@ -792,22 +792,25 @@ class WorkbookProtectionOptions: lock_windows: bool = False +@dataclass +class IntStringResult: + k: int = 0 + v: str = "" + + @dataclass class StringArrayErrorResult: arr: Optional[List[str]] = None err: str = "" -@dataclass -class IntStringResult: - k: int = 0 - v: str = "" @dataclass class GetSheetMapResult: arr: Optional[List[IntStringResult]] = None err: str = "" + @dataclass class GetCommentsResult: comments: Optional[List[Comment]] = None - err: str = "" \ No newline at end of file + err: str = ""