Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

New function add_form_control and add_shape has been added #6

Merged
merged 1 commit into from
Dec 6, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
92 changes: 91 additions & 1 deletion excelize.py
Original file line number Diff line number Diff line change
Expand Up @@ -546,6 +546,29 @@ def add_comment(self, sheet: str, opts: Comment) -> Exception | None:
).decode(ENCODE)
return None if err == "" else Exception(err)

def add_form_control(self, sheet: str, opts: FormControl) -> Exception | None:
"""
Add form control button in a worksheet by given worksheet name and form
control options. Supported form control type: button, check box, group
box, label, option button, scroll bar and spinner. If set macro for the
form control, the workbook extension should be XLSM or XLTM. Scroll
value must be between 0 and 30000.

Args:
sheet (str): The worksheet name
opts (FormControl): The form control options

Returns:
Exception | None: Returns None if no error occurred,
otherwise returns an Exception with the message.
"""
lib.AddFormControl.restype = c_char_p
options = py_value_to_c(opts, types_go._FormControl())
err = lib.AddFormControl(
self.file_index, sheet.encode(ENCODE), byref(options)
).decode(ENCODE)
return None if err == "" else Exception(err)

def add_picture(
self, sheet: str, cell: str, name: str, opts: GraphicOptions | None
) -> Exception | None:
Expand Down Expand Up @@ -655,7 +678,7 @@ def add_pivot_table(self, opts: PivotTableOptions | None) -> Exception | None:
)
if err:
print(err)
err = f.save_as("TestAddPivotTable.xlsx")
err = f.save_as("Book1.xlsx")
if err:
print(err)
err = f.close()
Expand All @@ -668,6 +691,73 @@ def add_pivot_table(self, opts: PivotTableOptions | None) -> Exception | None:
).decode(ENCODE)
return None if err == "" else Exception(err)

def add_shape(self, sheet: str, opts: Shape) -> Exception | None:
"""
Add shape in a sheet by given worksheet name and shape format set (such
as offset, scale, aspect ratio setting and print settings).

Args:
sheet (str): The worksheet name
opts (Shape): The shape options

Returns:
Exception | None: Returns None if no error occurred,
otherwise returns an Exception with the message.

Example:
For example, add text box (rect shape) in Sheet1:

.. code-block:: python

import excelize

f = excelize.new_file()
err = f.add_shape(
"Sheet1",
excelize.Shape(
cell="G6",
type="rect",
line=excelize.ShapeLine(
color="4286F4",
width=1.2,
),
fill=excelize.Fill(
color=["8EB9FF"],
pattern=1,
),
paragraph=[
excelize.RichTextRun(
text="Rectangle Shape",
font=excelize.Font(
bold=True,
italic=True,
family="Times New Roman",
size=19,
color="777777",
underline="sng",
),
)
],
width=80,
height=40,
),
)
if err:
print(err)
err = f.save_as("Book1.xlsx")
if err:
print(err)
err = f.close()
if err:
print(err)
"""
lib.AddShape.restype = c_char_p
options = py_value_to_c(opts, types_go._Shape())
err = lib.AddShape(
self.file_index, sheet.encode(ENCODE), byref(options)
).decode(ENCODE)
return None if err == "" else Exception(err)

def close(self) -> Exception | None:
"""
Closes and cleanup the open temporary file for the spreadsheet.
Expand Down
8 changes: 4 additions & 4 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -10,10 +10,10 @@ require (
require (
github.com/richardlehane/mscfb v1.0.4 // indirect
github.com/richardlehane/msoleps v1.0.4 // indirect
github.com/tiendc/go-deepcopy v1.1.0 // indirect
github.com/tiendc/go-deepcopy v1.2.0 // indirect
github.com/xuri/efp v0.0.0-20240408161823-9ad904a10d6d // indirect
github.com/xuri/nfp v0.0.0-20240318013403-ab9948c2c4a7 // indirect
golang.org/x/crypto v0.29.0 // indirect
golang.org/x/net v0.31.0 // indirect
golang.org/x/text v0.20.0 // indirect
golang.org/x/crypto v0.30.0 // indirect
golang.org/x/net v0.32.0 // indirect
golang.org/x/text v0.21.0 // indirect
)
16 changes: 8 additions & 8 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -6,20 +6,20 @@ github.com/richardlehane/msoleps v1.0.1/go.mod h1:BWev5JBpU9Ko2WAgmZEuiz4/u3ZYTK
github.com/richardlehane/msoleps v1.0.4 h1:WuESlvhX3gH2IHcd8UqyCuFY5yiq/GR/yqaSM/9/g00=
github.com/richardlehane/msoleps v1.0.4/go.mod h1:BWev5JBpU9Ko2WAgmZEuiz4/u3ZYTKbjLycmwiWUfWg=
github.com/stretchr/testify v1.9.0 h1:HtqpIVDClZ4nwg75+f6Lvsy/wHu+3BoSGCbBAcpTsTg=
github.com/tiendc/go-deepcopy v1.1.0 h1:rBHhm5vg7WYnGLwktbQouodWjBXDoStOL4S7v/K8S4A=
github.com/tiendc/go-deepcopy v1.1.0/go.mod h1:toXoeQoUqXOOS/X4sKuiAoSk6elIdqc0pN7MTgOOo2I=
github.com/tiendc/go-deepcopy v1.2.0 h1:6vCCs+qdLQHzFqY1fcPirsAWOmrLbuccilfp8UzD1Qo=
github.com/tiendc/go-deepcopy v1.2.0/go.mod h1:toXoeQoUqXOOS/X4sKuiAoSk6elIdqc0pN7MTgOOo2I=
github.com/xuri/efp v0.0.0-20240408161823-9ad904a10d6d h1:llb0neMWDQe87IzJLS4Ci7psK/lVsjIS2otl+1WyRyY=
github.com/xuri/efp v0.0.0-20240408161823-9ad904a10d6d/go.mod h1:ybY/Jr0T0GTCnYjKqmdwxyxn2BQf2RcQIIvex5QldPI=
github.com/xuri/excelize/v2 v2.9.1-0.20241122135638-c93618856aaf h1:bq1r31/0UyEdzizbINrZQE2AJJOJ+ZPgJwVrgt0tAsY=
github.com/xuri/excelize/v2 v2.9.1-0.20241122135638-c93618856aaf/go.mod h1:S1OQfc1yJPjtiV+cTzabidtjgLnCPmwgTooc/An6MlE=
github.com/xuri/nfp v0.0.0-20240318013403-ab9948c2c4a7 h1:hPVCafDV85blFTabnqKgNhDCkJX25eik94Si9cTER4A=
github.com/xuri/nfp v0.0.0-20240318013403-ab9948c2c4a7/go.mod h1:WwHg+CVyzlv/TX9xqBFXEZAuxOPxn2k1GNHwG41IIUQ=
golang.org/x/crypto v0.29.0 h1:L5SG1JTTXupVV3n6sUqMTeWbjAyfPwoda2DLX8J8FrQ=
golang.org/x/crypto v0.29.0/go.mod h1:+F4F4N5hv6v38hfeYwTdx20oUvLLc+QfrE9Ax9HtgRg=
golang.org/x/crypto v0.30.0 h1:RwoQn3GkWiMkzlX562cLB7OxWvjH1L8xutO2WoJcRoY=
golang.org/x/crypto v0.30.0/go.mod h1:kDsLvtWBEx7MV9tJOj9bnXsPbxwJQ6csT/x4KIN4Ssk=
golang.org/x/image v0.22.0 h1:UtK5yLUzilVrkjMAZAZ34DXGpASN8i8pj8g+O+yd10g=
golang.org/x/image v0.22.0/go.mod h1:9hPFhljd4zZ1GNSIZJ49sqbp45GKK9t6w+iXvGqZUz4=
golang.org/x/net v0.31.0 h1:68CPQngjLL0r2AlUKiSxtQFKvzRVbnzLwMUn5SzcLHo=
golang.org/x/net v0.31.0/go.mod h1:P4fl1q7dY2hnZFxEk4pPSkDHF+QqjitcnDjUQyMM+pM=
golang.org/x/text v0.20.0 h1:gK/Kv2otX8gz+wn7Rmb3vT96ZwuoxnQlY+HlJVj7Qug=
golang.org/x/text v0.20.0/go.mod h1:D4IsuqiFMhST5bX19pQ9ikHC2GsaKyk/oF+pn3ducp4=
golang.org/x/net v0.32.0 h1:ZqPmj8Kzc+Y6e0+skZsuACbx+wzMgo5MQsJh9Qd6aYI=
golang.org/x/net v0.32.0/go.mod h1:CwU0IoeOlnQQWJ6ioyFrfRuomB8GKF6KbYXZVyeXNfs=
golang.org/x/text v0.21.0 h1:zyQAAkrwaneQ066sspRyJaG9VNi/YJ1NfzcGB3hZ/qo=
golang.org/x/text v0.21.0/go.mod h1:4IBbMaMmOPCJ8SecivzSH54+73PCFmPWxNTLm+vZkEQ=
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
46 changes: 46 additions & 0 deletions main.go
Original file line number Diff line number Diff line change
Expand Up @@ -506,6 +506,30 @@ func AddComment(idx int, sheet *C.char, opts *C.struct_Comment) *C.char {
return C.CString(errNil)
}

// AddFormControl provides the method to add form control button in a worksheet
// by given worksheet name and form control options. Supported form control
// type: button, check box, group box, label, option button, scroll bar and
// spinner. If set macro for the form control, the workbook extension should be
// XLSM or XLTM. Scroll value must be between 0 and 30000.
//
//export AddFormControl
func AddFormControl(idx int, sheet *C.char, opts *C.struct_FormControl) *C.char {
var options excelize.FormControl
goVal, err := cValueToGo(reflect.ValueOf(*opts), reflect.TypeOf(excelize.FormControl{}))
if err != nil {
return C.CString(err.Error())
}
options = goVal.Elem().Interface().(excelize.FormControl)
f, ok := files.Load(idx)
if !ok {
return C.CString(errFilePtr)
}
if err := f.(*excelize.File).AddFormControl(C.GoString(sheet), options); err != nil {
return C.CString(err.Error())
}
return C.CString(errNil)
}

// 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.
Expand Down Expand Up @@ -554,6 +578,28 @@ func AddPivotTable(idx int, opts *C.struct_PivotTableOptions) *C.char {
return C.CString(errNil)
}

// AddShape provides the method to add shape in a sheet by given worksheet
// name and shape format set (such as offset, scale, aspect ratio setting and
// print settings).
//
//export AddShape
func AddShape(idx int, sheet *C.char, opts *C.struct_Shape) *C.char {
var options excelize.Shape
goVal, err := cValueToGo(reflect.ValueOf(*opts), reflect.TypeOf(excelize.Shape{}))
if err != nil {
return C.CString(err.Error())
}
options = goVal.Elem().Interface().(excelize.Shape)
f, ok := files.Load(idx)
if !ok {
return C.CString(errFilePtr)
}
if err := f.(*excelize.File).AddShape(C.GoString(sheet), &options); err != nil {
return C.CString(err.Error())
}
return C.CString(errNil)
}

// CellNameToCoordinates converts alphanumeric cell name to [X, Y] coordinates
// or returns an error.
//
Expand Down
115 changes: 115 additions & 0 deletions test_excelize.py
Original file line number Diff line number Diff line change
Expand Up @@ -359,6 +359,84 @@ def test_comment(self):
self.assertIsNone(f.save_as("TestComment.xlsx"))
self.assertIsNone(f.close())

def test_add_form_control(self):
f = excelize.new_file()
self.assertIsNone(
f.add_form_control(
"Sheet1",
excelize.FormControl(
cell="A3",
macro="Button1_Click",
width=140,
height=60,
text="Button 1\r\n",
paragraph=[
excelize.RichTextRun(
font=excelize.Font(
bold=True,
italic=True,
underline="single",
family="Times New Roman",
size=14,
color="777777",
),
text="C1=A1+B1",
)
],
type=excelize.FormControlType.FormControlButton,
format=excelize.GraphicOptions(
print_object=True,
positioning="absolute",
),
),
)
)
self.assertIsNone(
f.add_form_control(
"Sheet1",
excelize.FormControl(
cell="A1",
text="Option Button 1",
type=excelize.FormControlType.FormControlOptionButton,
),
)
)
self.assertIsNone(
f.add_form_control(
"Sheet1",
excelize.FormControl(
cell="B1",
type=excelize.FormControlType.FormControlSpinButton,
width=15,
height=40,
current_val=7,
min_val=5,
max_val=10,
inc_change=1,
cell_link="A1",
),
)
)
self.assertIsNone(
f.add_form_control(
"Sheet1",
excelize.FormControl(
cell="B3",
type=excelize.FormControlType.FormControlScrollBar,
width=140,
height=20,
current_val=50,
min_val=10,
max_val=100,
page_change=1,
cell_link="A1",
horizontally=True,
),
)
)
self.assertIsNone(f.save_as("TestAddFormControl.xlsx"))
self.assertIsNone(f.close())

def test_pivot_table(self):
f = excelize.new_file()
month = [
Expand Down Expand Up @@ -429,6 +507,43 @@ def test_pivot_table(self):
self.assertIsNone(f.save_as("TestAddPivotTable.xlsx"))
self.assertIsNone(f.close())

def test_add_shape(self):
f = excelize.new_file()
self.assertIsNone(
f.add_shape(
"Sheet1",
excelize.Shape(
cell="G6",
type="rect",
line=excelize.ShapeLine(
color="4286F4",
width=1.2,
),
fill=excelize.Fill(
color=["8EB9FF"],
pattern=1,
),
paragraph=[
excelize.RichTextRun(
text="Rectangle Shape",
font=excelize.Font(
bold=True,
italic=True,
family="Times New Roman",
size=19,
color="777777",
underline="sng",
),
)
],
width=180,
height=40,
),
)
)
self.assertIsNone(f.save_as("TestAddShape.xlsx"))
self.assertIsNone(f.close())

def test_cell_name_to_coordinates(self):
col, row, err = excelize.cell_name_to_coordinates("Z3")
self.assertEqual(col, 26)
Expand Down
Loading
Loading